@duskmoon-dev/core 1.10.0 → 1.11.0
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/README.md +3 -3
- package/dist/components/index.css +281 -0
- package/dist/components/theme-controller.css +281 -0
- package/dist/components/toggle.css +274 -0
- package/dist/esm/components/theme-controller.js +288 -0
- package/dist/esm/components/toggle.js +281 -0
- package/dist/index.css +281 -0
- package/dist/index.min.css +1 -1
- package/dist/types/types/plugin.d.ts +1 -1
- package/package.json +21 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @duskmoon-dev/core
|
|
2
2
|
|
|
3
|
-
> DuskMoonUI - A Tailwind CSS v4 plugin with Material Design 3 color system and
|
|
3
|
+
> DuskMoonUI - A Tailwind CSS v4 plugin with Material Design 3 color system and 49 component styles
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@duskmoon-dev/core)
|
|
6
6
|
[](https://www.npmjs.com/package/@duskmoon-dev/core)
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
- 🎨 **Three-color system** - Primary, secondary, and tertiary brand colors with automatic content colors
|
|
13
13
|
- 🌓 **Built-in themes** - Sunshine (light) and Moonlight (dark) themes ready to use
|
|
14
14
|
- 📦 **55+ Material Design 3 color tokens** - Full MD3 color system with OKLCH format
|
|
15
|
-
- 🧩 **
|
|
15
|
+
- 🧩 **49 UI components** - Complete component library with consistent styling
|
|
16
16
|
- 🚀 **Zero runtime JS** - Pure CSS with CSS custom properties for theme switching
|
|
17
17
|
- ♿ **Accessible by default** - WCAG AA compliant contrast ratios (4.5:1 minimum)
|
|
18
18
|
- 🎯 **Tailwind v4 native** - Pure CSS using `@import`, no JavaScript configuration
|
|
@@ -96,7 +96,7 @@ Theme switching is instant and uses pure CSS custom properties.
|
|
|
96
96
|
|
|
97
97
|
## Components
|
|
98
98
|
|
|
99
|
-
@duskmoon-dev/core includes **
|
|
99
|
+
@duskmoon-dev/core includes **49 components** organized into 7 categories:
|
|
100
100
|
|
|
101
101
|
### Core Components (6)
|
|
102
102
|
|
|
@@ -8355,6 +8355,287 @@
|
|
|
8355
8355
|
}
|
|
8356
8356
|
}
|
|
8357
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
|
+
}
|
|
8358
8639
|
|
|
8359
8640
|
/**
|
|
8360
8641
|
* Toggle Button Component Styles
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Controller Component Styles
|
|
3
|
+
* DuskMoonUI - Two display modes for theme switching:
|
|
4
|
+
*
|
|
5
|
+
* 1. Switch (.theme-controller) — inline pill-shaped radio group, all options visible
|
|
6
|
+
* 2. Dropdown (.theme-controller-dropdown) — <details>/<summary> with floating menu
|
|
7
|
+
*
|
|
8
|
+
* Both modes reuse .theme-controller-item (hidden radio) and .theme-controller-label
|
|
9
|
+
* for CSS-only active state via :checked + label.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
@layer components {
|
|
13
|
+
/* ========================================
|
|
14
|
+
* SHARED — Radio input & label (used in both modes)
|
|
15
|
+
* ======================================== */
|
|
16
|
+
|
|
17
|
+
/* Hidden Radio Input — visually hidden but accessible */
|
|
18
|
+
.theme-controller-item {
|
|
19
|
+
position: absolute;
|
|
20
|
+
width: 1px;
|
|
21
|
+
height: 1px;
|
|
22
|
+
padding: 0;
|
|
23
|
+
margin: -1px;
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
clip: rect(0, 0, 0, 0);
|
|
26
|
+
white-space: nowrap;
|
|
27
|
+
border: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Visible Label — the clickable option */
|
|
31
|
+
.theme-controller-label {
|
|
32
|
+
display: inline-flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
justify-content: center;
|
|
35
|
+
gap: 0.5rem;
|
|
36
|
+
padding: 0.5rem 1rem;
|
|
37
|
+
font-size: 0.875rem;
|
|
38
|
+
font-weight: 500;
|
|
39
|
+
line-height: 1.25rem;
|
|
40
|
+
color: var(--color-on-surface-variant);
|
|
41
|
+
background-color: transparent;
|
|
42
|
+
border-radius: calc(var(--radius-box, 1.5rem) - 0.25rem);
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
transition: background-color 150ms ease-in-out, color 150ms ease-in-out,
|
|
45
|
+
box-shadow 150ms ease-in-out;
|
|
46
|
+
user-select: none;
|
|
47
|
+
white-space: nowrap;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Hover state */
|
|
51
|
+
.theme-controller-label:hover {
|
|
52
|
+
background-color: var(--color-surface-container-high);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Focus-visible ring on the label when its radio is focused */
|
|
56
|
+
.theme-controller-item:focus-visible + .theme-controller-label {
|
|
57
|
+
outline: 2px solid var(--color-primary);
|
|
58
|
+
outline-offset: 2px;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* Active/checked state */
|
|
62
|
+
.theme-controller-item:checked + .theme-controller-label {
|
|
63
|
+
background-color: var(--color-primary-container);
|
|
64
|
+
color: var(--color-on-primary-container);
|
|
65
|
+
box-shadow: var(--shadow-xs);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.theme-controller-item:checked + .theme-controller-label:hover {
|
|
69
|
+
background-color: color-mix(in oklch, var(--color-primary-container), black 5%);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* ========================================
|
|
73
|
+
* SWITCH MODE — inline pill radio group
|
|
74
|
+
* ======================================== */
|
|
75
|
+
|
|
76
|
+
.theme-controller {
|
|
77
|
+
display: inline-flex;
|
|
78
|
+
align-items: stretch;
|
|
79
|
+
background-color: var(--color-surface-container);
|
|
80
|
+
border: 1px solid var(--color-outline-variant);
|
|
81
|
+
border-radius: var(--radius-box, 1.5rem);
|
|
82
|
+
padding: 0.25rem;
|
|
83
|
+
gap: 0.125rem;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* ── Switch Size Variants ── */
|
|
87
|
+
|
|
88
|
+
.theme-controller-sm {
|
|
89
|
+
padding: 0.125rem;
|
|
90
|
+
border-radius: calc(var(--radius-box, 1.5rem) * 0.75);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.theme-controller-sm .theme-controller-label {
|
|
94
|
+
padding: 0.375rem 0.75rem;
|
|
95
|
+
font-size: 0.75rem;
|
|
96
|
+
line-height: 1rem;
|
|
97
|
+
border-radius: calc(var(--radius-box, 1.5rem) * 0.75 - 0.125rem);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.theme-controller-lg {
|
|
101
|
+
padding: 0.375rem;
|
|
102
|
+
gap: 0.25rem;
|
|
103
|
+
border-radius: calc(var(--radius-box, 1.5rem) * 1.25);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.theme-controller-lg .theme-controller-label {
|
|
107
|
+
padding: 0.75rem 1.5rem;
|
|
108
|
+
font-size: 1rem;
|
|
109
|
+
line-height: 1.5rem;
|
|
110
|
+
border-radius: calc(var(--radius-box, 1.5rem) * 1.25 - 0.375rem);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* ── Switch Icon-only Variant ── */
|
|
114
|
+
|
|
115
|
+
.theme-controller-icon .theme-controller-label {
|
|
116
|
+
padding: 0.5rem;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.theme-controller-icon.theme-controller-sm .theme-controller-label {
|
|
120
|
+
padding: 0.375rem;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.theme-controller-icon.theme-controller-lg .theme-controller-label {
|
|
124
|
+
padding: 0.75rem;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/* ========================================
|
|
128
|
+
* DROPDOWN MODE — <details>/<summary> with floating menu
|
|
129
|
+
* ======================================== */
|
|
130
|
+
|
|
131
|
+
.theme-controller-dropdown {
|
|
132
|
+
position: relative;
|
|
133
|
+
display: inline-block;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* Trigger button (<summary>) */
|
|
137
|
+
.theme-controller-trigger {
|
|
138
|
+
display: inline-flex;
|
|
139
|
+
align-items: center;
|
|
140
|
+
gap: 0.5rem;
|
|
141
|
+
padding: 0.5rem 0.75rem;
|
|
142
|
+
font-size: 0.875rem;
|
|
143
|
+
font-weight: 500;
|
|
144
|
+
line-height: 1.25rem;
|
|
145
|
+
color: var(--color-on-surface);
|
|
146
|
+
background-color: var(--color-surface-container);
|
|
147
|
+
border: 1px solid var(--color-outline-variant);
|
|
148
|
+
border-radius: var(--radius-field, 0.5rem);
|
|
149
|
+
cursor: pointer;
|
|
150
|
+
user-select: none;
|
|
151
|
+
transition: background-color 150ms ease-in-out;
|
|
152
|
+
list-style: none;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.theme-controller-trigger::-webkit-details-marker {
|
|
156
|
+
display: none;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.theme-controller-trigger:hover {
|
|
160
|
+
background-color: var(--color-surface-container-high);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.theme-controller-trigger:focus-visible {
|
|
164
|
+
outline: 2px solid var(--color-primary);
|
|
165
|
+
outline-offset: 2px;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* Chevron indicator */
|
|
169
|
+
.theme-controller-trigger::after {
|
|
170
|
+
content: '';
|
|
171
|
+
display: inline-block;
|
|
172
|
+
width: 0.5rem;
|
|
173
|
+
height: 0.5rem;
|
|
174
|
+
border-right: 2px solid currentColor;
|
|
175
|
+
border-bottom: 2px solid currentColor;
|
|
176
|
+
transform: rotate(45deg);
|
|
177
|
+
margin-top: -0.125rem;
|
|
178
|
+
transition: transform 150ms ease-in-out;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.theme-controller-dropdown[open] .theme-controller-trigger::after {
|
|
182
|
+
transform: rotate(-135deg);
|
|
183
|
+
margin-top: 0.125rem;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* Floating menu */
|
|
187
|
+
.theme-controller-menu {
|
|
188
|
+
position: absolute;
|
|
189
|
+
top: calc(100% + 0.25rem);
|
|
190
|
+
left: 0;
|
|
191
|
+
z-index: 50;
|
|
192
|
+
min-width: 100%;
|
|
193
|
+
background-color: var(--color-surface-container);
|
|
194
|
+
border: 1px solid var(--color-outline-variant);
|
|
195
|
+
border-radius: var(--radius-field, 0.5rem);
|
|
196
|
+
padding: 0.25rem;
|
|
197
|
+
box-shadow: var(--shadow-md);
|
|
198
|
+
display: flex;
|
|
199
|
+
flex-direction: column;
|
|
200
|
+
gap: 0.125rem;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* Menu labels are full-width and left-aligned */
|
|
204
|
+
.theme-controller-menu .theme-controller-label {
|
|
205
|
+
width: 100%;
|
|
206
|
+
justify-content: flex-start;
|
|
207
|
+
border-radius: calc(var(--radius-field, 0.5rem) - 0.25rem);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/* ── Dropdown Size Variants ── */
|
|
211
|
+
|
|
212
|
+
.theme-controller-dropdown-sm .theme-controller-trigger {
|
|
213
|
+
padding: 0.375rem 0.625rem;
|
|
214
|
+
font-size: 0.75rem;
|
|
215
|
+
line-height: 1rem;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.theme-controller-dropdown-sm .theme-controller-menu {
|
|
219
|
+
padding: 0.125rem;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.theme-controller-dropdown-sm .theme-controller-menu .theme-controller-label {
|
|
223
|
+
padding: 0.375rem 0.75rem;
|
|
224
|
+
font-size: 0.75rem;
|
|
225
|
+
line-height: 1rem;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.theme-controller-dropdown-lg .theme-controller-trigger {
|
|
229
|
+
padding: 0.75rem 1rem;
|
|
230
|
+
font-size: 1rem;
|
|
231
|
+
line-height: 1.5rem;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.theme-controller-dropdown-lg .theme-controller-menu {
|
|
235
|
+
padding: 0.375rem;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.theme-controller-dropdown-lg .theme-controller-menu .theme-controller-label {
|
|
239
|
+
padding: 0.75rem 1.5rem;
|
|
240
|
+
font-size: 1rem;
|
|
241
|
+
line-height: 1.5rem;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/* ── Dropdown Icon-only Trigger ── */
|
|
245
|
+
|
|
246
|
+
.theme-controller-dropdown-icon .theme-controller-trigger {
|
|
247
|
+
padding: 0.5rem;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/* Hide chevron for icon-only trigger */
|
|
251
|
+
.theme-controller-dropdown-icon .theme-controller-trigger::after {
|
|
252
|
+
display: none;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.theme-controller-dropdown-icon.theme-controller-dropdown-sm .theme-controller-trigger {
|
|
256
|
+
padding: 0.375rem;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.theme-controller-dropdown-icon.theme-controller-dropdown-lg .theme-controller-trigger {
|
|
260
|
+
padding: 0.75rem;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/* ── Dropdown Alignment ── */
|
|
264
|
+
|
|
265
|
+
.theme-controller-dropdown-end .theme-controller-menu {
|
|
266
|
+
left: auto;
|
|
267
|
+
right: 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/* ========================================
|
|
271
|
+
* REDUCED MOTION
|
|
272
|
+
* ======================================== */
|
|
273
|
+
|
|
274
|
+
@media (prefers-reduced-motion: reduce) {
|
|
275
|
+
.theme-controller-label,
|
|
276
|
+
.theme-controller-trigger,
|
|
277
|
+
.theme-controller-trigger::after {
|
|
278
|
+
transition: none;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|