@duskmoon-dev/core 1.15.0 → 1.16.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.
Files changed (126) hide show
  1. package/dist/cjs/tailwind-plugin.cjs +38 -79
  2. package/dist/components/accordion.css +7 -7
  3. package/dist/components/alert.css +2 -2
  4. package/dist/components/appbar.css +5 -5
  5. package/dist/components/autocomplete.css +7 -7
  6. package/dist/components/avatar.css +5 -5
  7. package/dist/components/badge.css +3 -3
  8. package/dist/components/bottom-navigation.css +7 -7
  9. package/dist/components/bottomsheet.css +12 -12
  10. package/dist/components/button.css +19 -19
  11. package/dist/components/card.css +9 -2
  12. package/dist/components/cascader.css +9 -9
  13. package/dist/components/checkbox.css +1 -1
  14. package/dist/components/chip.css +12 -10
  15. package/dist/components/circle-menu.css +324 -0
  16. package/dist/components/code-block.css +133 -0
  17. package/dist/components/collapse.css +9 -9
  18. package/dist/components/datepicker.css +22 -22
  19. package/dist/components/dialog.css +5 -5
  20. package/dist/components/drawer.css +13 -13
  21. package/dist/components/file-upload.css +12 -12
  22. package/dist/components/form-group.css +162 -1
  23. package/dist/components/form.css +159 -22
  24. package/dist/components/index.css +1026 -385
  25. package/dist/components/input.css +23 -14
  26. package/dist/components/list.css +3 -3
  27. package/dist/components/markdown-body.css +6 -6
  28. package/dist/components/modal.css +7 -7
  29. package/dist/components/multi-select.css +16 -16
  30. package/dist/components/navigation.css +20 -20
  31. package/dist/components/nested-menu.css +5 -5
  32. package/dist/components/otp-input.css +5 -5
  33. package/dist/components/pin-input.css +5 -5
  34. package/dist/components/popover.css +15 -15
  35. package/dist/components/progress.css +2 -2
  36. package/dist/components/radio.css +2 -2
  37. package/dist/components/rating.css +1 -1
  38. package/dist/components/segment-control.css +6 -6
  39. package/dist/components/select.css +7 -7
  40. package/dist/components/skeleton.css +11 -11
  41. package/dist/components/slider.css +16 -16
  42. package/dist/components/snackbar.css +5 -5
  43. package/dist/components/stepper.css +9 -9
  44. package/dist/components/switch.css +1 -1
  45. package/dist/components/table.css +3 -3
  46. package/dist/components/textarea.css +5 -5
  47. package/dist/components/theme-controller.css +4 -4
  48. package/dist/components/time-input.css +10 -10
  49. package/dist/components/timeline.css +6 -6
  50. package/dist/components/toast.css +3 -3
  51. package/dist/components/toggle.css +8 -8
  52. package/dist/components/tooltip.css +1 -1
  53. package/dist/components/tree-select.css +14 -14
  54. package/dist/esm/components/accordion.js +7 -7
  55. package/dist/esm/components/alert.js +2 -2
  56. package/dist/esm/components/appbar.js +5 -5
  57. package/dist/esm/components/autocomplete.js +7 -7
  58. package/dist/esm/components/avatar.js +5 -5
  59. package/dist/esm/components/badge.js +3 -3
  60. package/dist/esm/components/bottom-navigation.js +7 -7
  61. package/dist/esm/components/bottomsheet.js +12 -12
  62. package/dist/esm/components/button.js +19 -19
  63. package/dist/esm/components/card.js +9 -2
  64. package/dist/esm/components/cascader.js +9 -9
  65. package/dist/esm/components/checkbox.js +1 -1
  66. package/dist/esm/components/chip.js +12 -10
  67. package/dist/esm/components/circle-menu.js +331 -0
  68. package/dist/esm/components/code-block.js +140 -0
  69. package/dist/esm/components/collapse.js +9 -9
  70. package/dist/esm/components/datepicker.js +22 -22
  71. package/dist/esm/components/dialog.js +5 -5
  72. package/dist/esm/components/drawer.js +13 -13
  73. package/dist/esm/components/file-upload.js +12 -12
  74. package/dist/esm/components/form-group.js +162 -1
  75. package/dist/esm/components/form.js +159 -22
  76. package/dist/esm/components/input.js +23 -14
  77. package/dist/esm/components/list.js +3 -3
  78. package/dist/esm/components/markdown-body.js +6 -6
  79. package/dist/esm/components/modal.js +7 -7
  80. package/dist/esm/components/multi-select.js +16 -16
  81. package/dist/esm/components/navigation.js +20 -20
  82. package/dist/esm/components/nested-menu.js +5 -5
  83. package/dist/esm/components/otp-input.js +5 -5
  84. package/dist/esm/components/pin-input.js +5 -5
  85. package/dist/esm/components/popover.js +15 -15
  86. package/dist/esm/components/progress.js +2 -2
  87. package/dist/esm/components/radio.js +2 -2
  88. package/dist/esm/components/rating.js +1 -1
  89. package/dist/esm/components/segment-control.js +6 -6
  90. package/dist/esm/components/select.js +7 -7
  91. package/dist/esm/components/skeleton.js +11 -11
  92. package/dist/esm/components/slider.js +16 -16
  93. package/dist/esm/components/snackbar.js +5 -5
  94. package/dist/esm/components/stepper.js +9 -9
  95. package/dist/esm/components/switch.js +1 -1
  96. package/dist/esm/components/table.js +3 -3
  97. package/dist/esm/components/textarea.js +5 -5
  98. package/dist/esm/components/theme-controller.js +4 -4
  99. package/dist/esm/components/time-input.js +10 -10
  100. package/dist/esm/components/timeline.js +6 -6
  101. package/dist/esm/components/toast.js +3 -3
  102. package/dist/esm/components/toggle.js +8 -8
  103. package/dist/esm/components/tooltip.js +1 -1
  104. package/dist/esm/components/tree-select.js +14 -14
  105. package/dist/esm/tailwind-plugin.js +38 -79
  106. package/dist/index.css +1435 -1137
  107. package/dist/index.min.css +1 -1
  108. package/dist/themes/{forest.css → generated/forest.css} +26 -94
  109. package/dist/themes/generated/moonlight.css +77 -0
  110. package/dist/themes/{ocean.css → generated/ocean.css} +26 -103
  111. package/dist/themes/generated/spacing.css +36 -0
  112. package/dist/themes/{sunset.css → generated/sunset.css} +26 -95
  113. package/dist/themes/generated/sunshine.css +77 -0
  114. package/dist/types/tailwind-plugin.d.ts +1 -0
  115. package/dist/types/tailwind-plugin.d.ts.map +1 -1
  116. package/dist/types/themes/generated/ts/types.d.ts +76 -0
  117. package/dist/types/themes/generated/ts/types.d.ts.map +1 -0
  118. package/dist/types/types/index.d.ts +1 -1
  119. package/dist/types/types/index.d.ts.map +1 -1
  120. package/dist/types/types/plugin.d.ts +1 -1
  121. package/dist/types/types/plugin.d.ts.map +1 -1
  122. package/dist/types/types/theme.d.ts +5 -152
  123. package/dist/types/types/theme.d.ts.map +1 -1
  124. package/package.json +11 -6
  125. package/dist/themes/moonlight.css +0 -271
  126. package/dist/themes/sunshine.css +0 -252
@@ -10,7 +10,7 @@
10
10
  flex-direction: column;
11
11
  position: relative;
12
12
  overflow: hidden;
13
- border-radius: 1rem;
13
+ border-radius: var(--radius-lg);
14
14
  background-color: var(--color-surface);
15
15
  color: var(--color-on-surface);
16
16
  box-shadow: var(--shadow-sm);
@@ -244,7 +244,7 @@
244
244
  .card-full-image .card-body {
245
245
  position: relative;
246
246
  z-index: 1;
247
- background: linear-gradient(to top, rgb(0 0 0 / 0.7), transparent);
247
+ background: linear-gradient(to top, color-mix(in srgb, var(--color-shadow) 70%, transparent), transparent);
248
248
  color: white;
249
249
  margin-top: auto;
250
250
  min-height: 50%;
@@ -253,4 +253,11 @@
253
253
  .card-full-image .card-title {
254
254
  color: white;
255
255
  }
256
+
257
+ /* Reduce Motion */
258
+ @media (prefers-reduced-motion: reduce) {
259
+ .card {
260
+ transition: none;
261
+ }
262
+ }
256
263
  }
@@ -24,7 +24,7 @@
24
24
  color: var(--color-on-surface);
25
25
  background-color: var(--color-surface);
26
26
  border: 1px solid currentColor;
27
- border-radius: 0.5rem;
27
+ border-radius: var(--radius-sm);
28
28
  cursor: pointer;
29
29
  transition: border-color 150ms ease-in-out, box-shadow 150ms ease-in-out;
30
30
  }
@@ -103,7 +103,7 @@
103
103
  color: var(--color-on-surface-variant);
104
104
  background-color: transparent;
105
105
  border: none;
106
- border-radius: 50%;
106
+ border-radius: var(--radius-full);
107
107
  cursor: pointer;
108
108
  flex-shrink: 0;
109
109
  transition: background-color 150ms ease-in-out;
@@ -123,7 +123,7 @@
123
123
  margin-top: 0.25rem;
124
124
  background-color: var(--color-surface);
125
125
  border: 1px solid var(--color-outline-variant);
126
- border-radius: 0.5rem;
126
+ border-radius: var(--radius-sm);
127
127
  box-shadow: var(--shadow-md);
128
128
  overflow: hidden;
129
129
  }
@@ -224,7 +224,7 @@
224
224
  color: var(--color-on-surface);
225
225
  background-color: transparent;
226
226
  border: none;
227
- border-radius: 0.375rem;
227
+ border-radius: var(--radius-xs);
228
228
  cursor: pointer;
229
229
  text-align: left;
230
230
  width: 100%;
@@ -294,7 +294,7 @@
294
294
  color: var(--color-on-surface);
295
295
  background-color: var(--color-surface-container);
296
296
  border: none;
297
- border-radius: 0.375rem;
297
+ border-radius: var(--radius-xs);
298
298
  outline: none;
299
299
  }
300
300
 
@@ -318,7 +318,7 @@
318
318
  .cascader-sm .cascader-trigger {
319
319
  padding: 0.5rem 0.75rem;
320
320
  font-size: 0.875rem;
321
- border-radius: 0.375rem;
321
+ border-radius: var(--radius-xs);
322
322
  }
323
323
 
324
324
  .cascader-sm .cascader-panel {
@@ -334,7 +334,7 @@
334
334
  .cascader-lg .cascader-trigger {
335
335
  padding: 1rem 1.25rem;
336
336
  font-size: 1.125rem;
337
- border-radius: 0.625rem;
337
+ border-radius: var(--radius-sm);
338
338
  }
339
339
 
340
340
  .cascader-lg .cascader-panel {
@@ -358,7 +358,7 @@
358
358
  background-color: var(--color-surface-container);
359
359
  border: none;
360
360
  border-bottom: 2px solid var(--color-outline);
361
- border-radius: 0.5rem 0.5rem 0 0;
361
+ border-radius: var(--radius-sm) var(--radius-sm) 0 0;
362
362
  }
363
363
 
364
364
  .cascader-filled .cascader-trigger:focus {
@@ -445,7 +445,7 @@
445
445
  height: 1rem;
446
446
  border: 2px solid var(--color-outline);
447
447
  border-top-color: var(--color-primary);
448
- border-radius: 50%;
448
+ border-radius: var(--radius-full);
449
449
  animation: cascader-spin 0.8s linear infinite;
450
450
  }
451
451
 
@@ -24,7 +24,7 @@
24
24
  appearance: none;
25
25
  background-color: transparent;
26
26
  border: 2px solid var(--checkbox-border-color);
27
- border-radius: 0.125rem;
27
+ border-radius: var(--radius-xs);
28
28
  transition: background-color 150ms ease-in-out, border-color 150ms ease-in-out;
29
29
  }
30
30
 
@@ -13,10 +13,10 @@
13
13
  font-size: 0.875rem;
14
14
  font-weight: 500;
15
15
  line-height: 1.25rem;
16
- border-radius: 0.5rem;
16
+ border-radius: var(--radius-sm);
17
17
  background-color: var(--color-surface-container);
18
18
  color: var(--color-on-surface);
19
- border: 1px solid transparent;
19
+ border: 1px solid currentColor;
20
20
  cursor: default;
21
21
  transition: all 150ms ease-in-out;
22
22
  }
@@ -43,6 +43,7 @@
43
43
  .chip-primary {
44
44
  background-color: var(--color-primary);
45
45
  color: var(--color-primary-content);
46
+ border-color: var(--color-primary);
46
47
  }
47
48
 
48
49
  .chip-primary:hover {
@@ -52,6 +53,7 @@
52
53
  .chip-secondary {
53
54
  background-color: var(--color-secondary);
54
55
  color: var(--color-secondary-content);
56
+ border-color: var(--color-secondary);
55
57
  }
56
58
 
57
59
  .chip-secondary:hover {
@@ -61,6 +63,7 @@
61
63
  .chip-tertiary {
62
64
  background-color: var(--color-tertiary);
63
65
  color: var(--color-tertiary-content);
66
+ border-color: var(--color-tertiary);
64
67
  }
65
68
 
66
69
  .chip-tertiary:hover {
@@ -70,6 +73,7 @@
70
73
  .chip-info {
71
74
  background-color: var(--color-info);
72
75
  color: var(--color-info-content);
76
+ border-color: var(--color-info);
73
77
  }
74
78
 
75
79
  .chip-info:hover {
@@ -79,6 +83,7 @@
79
83
  .chip-success {
80
84
  background-color: var(--color-success);
81
85
  color: var(--color-success-content);
86
+ border-color: var(--color-success);
82
87
  }
83
88
 
84
89
  .chip-success:hover {
@@ -88,6 +93,7 @@
88
93
  .chip-warning {
89
94
  background-color: var(--color-warning);
90
95
  color: var(--color-warning-content);
96
+ border-color: var(--color-warning);
91
97
  }
92
98
 
93
99
  .chip-warning:hover {
@@ -97,6 +103,7 @@
97
103
  .chip-error {
98
104
  background-color: var(--color-error);
99
105
  color: var(--color-error-content);
106
+ border-color: var(--color-error);
100
107
  }
101
108
 
102
109
  .chip-error:hover {
@@ -114,7 +121,6 @@
114
121
  }
115
122
 
116
123
  .chip-outlined.chip-primary {
117
- border-color: var(--color-primary);
118
124
  color: var(--color-primary);
119
125
  }
120
126
 
@@ -123,7 +129,6 @@
123
129
  }
124
130
 
125
131
  .chip-outlined.chip-secondary {
126
- border-color: var(--color-secondary);
127
132
  color: var(--color-secondary);
128
133
  }
129
134
 
@@ -132,7 +137,6 @@
132
137
  }
133
138
 
134
139
  .chip-outlined.chip-tertiary {
135
- border-color: var(--color-tertiary);
136
140
  color: var(--color-tertiary);
137
141
  }
138
142
 
@@ -141,7 +145,6 @@
141
145
  }
142
146
 
143
147
  .chip-outlined.chip-info {
144
- border-color: var(--color-info);
145
148
  color: var(--color-info);
146
149
  }
147
150
 
@@ -150,7 +153,6 @@
150
153
  }
151
154
 
152
155
  .chip-outlined.chip-success {
153
- border-color: var(--color-success);
154
156
  color: var(--color-success);
155
157
  }
156
158
 
@@ -159,7 +161,6 @@
159
161
  }
160
162
 
161
163
  .chip-outlined.chip-warning {
162
- border-color: var(--color-warning);
163
164
  color: var(--color-warning);
164
165
  }
165
166
 
@@ -168,7 +169,6 @@
168
169
  }
169
170
 
170
171
  .chip-outlined.chip-error {
171
- border-color: var(--color-error);
172
172
  color: var(--color-error);
173
173
  }
174
174
 
@@ -179,6 +179,7 @@
179
179
  /* Tonal/Soft Variant */
180
180
  .chip-tonal {
181
181
  background-color: var(--color-surface-container-high);
182
+ border-color: transparent;
182
183
  }
183
184
 
184
185
  .chip-tonal.chip-primary {
@@ -285,7 +286,7 @@
285
286
  opacity: 0.7;
286
287
  background-color: transparent;
287
288
  border: none;
288
- border-radius: 50%;
289
+ border-radius: var(--radius-full);
289
290
  cursor: pointer;
290
291
  transition: opacity 150ms ease-in-out;
291
292
  }
@@ -298,6 +299,7 @@
298
299
  .chip-selected {
299
300
  background-color: var(--color-primary);
300
301
  color: var(--color-primary-content);
302
+ border-color: var(--color-primary);
301
303
  }
302
304
 
303
305
  .chip-selected.chip-outlined {
@@ -0,0 +1,324 @@
1
+ /**
2
+ * Circle Menu Component Styles
3
+ * DuskMoonUI - Radial circular navigation menu with CSS-only checkbox toggle
4
+ *
5
+ * Usage:
6
+ * <nav class="circle-menu">
7
+ * <input type="checkbox" class="circle-menu-toggler" id="cm-1">
8
+ * <label class="circle-menu-label" for="cm-1"></label>
9
+ * <ul class="circle-menu-list">
10
+ * <li class="circle-menu-item"><a href="#">icon</a></li>
11
+ * </ul>
12
+ * </nav>
13
+ */
14
+
15
+ @layer components {
16
+ /* === Container === */
17
+ .circle-menu {
18
+ --circle-menu-size: 3rem;
19
+ --circle-menu-item-size: 3rem;
20
+ --circle-menu-radius: 5.5rem;
21
+ --circle-menu-icon-size: 1.25rem;
22
+ --circle-menu-bar-width: 1.125rem;
23
+ --circle-menu-bar-height: 0.1875rem;
24
+ --circle-menu-bar-gap: 0.375rem;
25
+
26
+ /* Color tokens (overridden by variants) */
27
+ --circle-menu-btn-bg: var(--color-primary-container);
28
+ --circle-menu-bar-color: var(--color-on-primary-container);
29
+ --circle-menu-item-bg: var(--color-primary-container);
30
+ --circle-menu-item-color: var(--color-on-primary-container);
31
+ --circle-menu-item-ring: color-mix(in oklch, var(--color-primary) 30%, transparent);
32
+
33
+ position: relative;
34
+ display: inline-flex;
35
+ align-items: center;
36
+ justify-content: center;
37
+ width: var(--circle-menu-size);
38
+ height: var(--circle-menu-size);
39
+ }
40
+
41
+ /* === Hidden checkbox toggler === */
42
+ .circle-menu-toggler {
43
+ position: absolute;
44
+ inset: 0;
45
+ margin: auto;
46
+ width: var(--circle-menu-size);
47
+ height: var(--circle-menu-size);
48
+ z-index: 10;
49
+ opacity: 0;
50
+ cursor: pointer;
51
+ }
52
+
53
+ /* === Circular toggle button (label) === */
54
+ .circle-menu-label {
55
+ position: absolute;
56
+ inset: 0;
57
+ margin: auto;
58
+ display: block;
59
+ width: var(--circle-menu-size);
60
+ height: var(--circle-menu-size);
61
+ border-radius: var(--radius-full);
62
+ background-color: var(--circle-menu-btn-bg);
63
+ z-index: 1;
64
+ pointer-events: none;
65
+ transition: background-color 0.3s ease;
66
+ }
67
+
68
+ /* Top bar of hamburger icon */
69
+ .circle-menu-label::before {
70
+ content: '';
71
+ position: absolute;
72
+ top: 50%;
73
+ left: 50%;
74
+ width: var(--circle-menu-bar-width);
75
+ height: var(--circle-menu-bar-height);
76
+ border-radius: var(--radius-full);
77
+ background-color: var(--circle-menu-bar-color);
78
+ /* Box-shadow creates middle + bottom bars */
79
+ box-shadow:
80
+ 0 var(--circle-menu-bar-gap) 0 var(--circle-menu-bar-color),
81
+ 0 calc(-1 * var(--circle-menu-bar-gap)) 0 var(--circle-menu-bar-color);
82
+ transform: translate(-50%, -50%);
83
+ transition:
84
+ transform 0.35s cubic-bezier(0.4, 0, 0.2, 1),
85
+ box-shadow 0.35s cubic-bezier(0.4, 0, 0.2, 1);
86
+ }
87
+
88
+ /* Second diagonal of X (hidden by default) */
89
+ .circle-menu-label::after {
90
+ content: '';
91
+ position: absolute;
92
+ top: 50%;
93
+ left: 50%;
94
+ width: var(--circle-menu-bar-width);
95
+ height: var(--circle-menu-bar-height);
96
+ border-radius: var(--radius-full);
97
+ background-color: var(--circle-menu-bar-color);
98
+ transform: translate(-50%, -50%) rotate(-45deg);
99
+ opacity: 0;
100
+ transition: opacity 0.25s ease;
101
+ }
102
+
103
+ /* Hover: lighten the toggle button */
104
+ .circle-menu-toggler:hover + .circle-menu-label {
105
+ background-color: color-mix(in oklch, var(--circle-menu-btn-bg) 80%, var(--circle-menu-bar-color));
106
+ }
107
+
108
+ /* Focus visible ring on toggle button */
109
+ .circle-menu-toggler:focus-visible + .circle-menu-label {
110
+ outline: none;
111
+ box-shadow: 0 0 0 3px var(--circle-menu-item-ring);
112
+ }
113
+
114
+ /* === Checked: hamburger → X === */
115
+ .circle-menu-toggler:checked + .circle-menu-label::before {
116
+ box-shadow: none;
117
+ transform: translate(-50%, -50%) rotate(45deg);
118
+ }
119
+
120
+ .circle-menu-toggler:checked + .circle-menu-label::after {
121
+ opacity: 1;
122
+ }
123
+
124
+ /* === Menu list === */
125
+ .circle-menu-list {
126
+ position: absolute;
127
+ inset: 0;
128
+ margin: 0;
129
+ padding: 0;
130
+ list-style: none;
131
+ pointer-events: none;
132
+ }
133
+
134
+ /* === Menu items (collapsed at center) === */
135
+ .circle-menu-item {
136
+ position: absolute;
137
+ inset: 0;
138
+ margin: auto;
139
+ width: var(--circle-menu-item-size);
140
+ height: var(--circle-menu-item-size);
141
+ opacity: 0;
142
+ transition:
143
+ transform 0.4s cubic-bezier(0.4, 0, 0.2, 1),
144
+ opacity 0.3s ease;
145
+ }
146
+
147
+ /* Item anchor/button — circular shape */
148
+ .circle-menu-item a,
149
+ .circle-menu-item button {
150
+ display: flex;
151
+ align-items: center;
152
+ justify-content: center;
153
+ width: 100%;
154
+ height: 100%;
155
+ border-radius: var(--radius-full);
156
+ text-decoration: none;
157
+ font-size: var(--circle-menu-icon-size);
158
+ color: var(--circle-menu-item-color);
159
+ background-color: var(--circle-menu-item-bg);
160
+ border: none;
161
+ cursor: pointer;
162
+ pointer-events: none;
163
+ transition:
164
+ box-shadow 0.2s ease,
165
+ background-color 0.2s ease;
166
+ }
167
+
168
+ .circle-menu-item a:hover,
169
+ .circle-menu-item button:hover {
170
+ background-color: color-mix(in oklch, var(--circle-menu-item-bg) 80%, var(--circle-menu-item-color));
171
+ box-shadow: 0 0 0 3px var(--circle-menu-item-ring);
172
+ }
173
+
174
+ .circle-menu-item a:focus-visible,
175
+ .circle-menu-item button:focus-visible {
176
+ outline: none;
177
+ box-shadow: 0 0 0 3px var(--circle-menu-item-ring);
178
+ }
179
+
180
+ /* Counter-rotate icons to stay upright as item container rotates */
181
+ .circle-menu-item:nth-child(1) a,
182
+ .circle-menu-item:nth-child(1) button { transform: rotate(0deg); }
183
+ .circle-menu-item:nth-child(2) a,
184
+ .circle-menu-item:nth-child(2) button { transform: rotate(-60deg); }
185
+ .circle-menu-item:nth-child(3) a,
186
+ .circle-menu-item:nth-child(3) button { transform: rotate(-120deg); }
187
+ .circle-menu-item:nth-child(4) a,
188
+ .circle-menu-item:nth-child(4) button { transform: rotate(-180deg); }
189
+ .circle-menu-item:nth-child(5) a,
190
+ .circle-menu-item:nth-child(5) button { transform: rotate(-240deg); }
191
+ .circle-menu-item:nth-child(6) a,
192
+ .circle-menu-item:nth-child(6) button { transform: rotate(-300deg); }
193
+
194
+ /* === Checked: fan items out in a circle === */
195
+ .circle-menu-toggler:checked ~ .circle-menu-list {
196
+ pointer-events: auto;
197
+ }
198
+
199
+ .circle-menu-toggler:checked ~ .circle-menu-list .circle-menu-item {
200
+ opacity: 1;
201
+ }
202
+
203
+ .circle-menu-toggler:checked ~ .circle-menu-list .circle-menu-item a,
204
+ .circle-menu-toggler:checked ~ .circle-menu-list .circle-menu-item button {
205
+ pointer-events: auto;
206
+ }
207
+
208
+ /* Radial positions for up to 6 items (rotate + translate along rotated X axis) */
209
+ .circle-menu-toggler:checked ~ .circle-menu-list .circle-menu-item:nth-child(1) {
210
+ transform: rotate(0deg) translateX(calc(-1 * var(--circle-menu-radius)));
211
+ }
212
+ .circle-menu-toggler:checked ~ .circle-menu-list .circle-menu-item:nth-child(2) {
213
+ transform: rotate(60deg) translateX(calc(-1 * var(--circle-menu-radius)));
214
+ }
215
+ .circle-menu-toggler:checked ~ .circle-menu-list .circle-menu-item:nth-child(3) {
216
+ transform: rotate(120deg) translateX(calc(-1 * var(--circle-menu-radius)));
217
+ }
218
+ .circle-menu-toggler:checked ~ .circle-menu-list .circle-menu-item:nth-child(4) {
219
+ transform: rotate(180deg) translateX(calc(-1 * var(--circle-menu-radius)));
220
+ }
221
+ .circle-menu-toggler:checked ~ .circle-menu-list .circle-menu-item:nth-child(5) {
222
+ transform: rotate(240deg) translateX(calc(-1 * var(--circle-menu-radius)));
223
+ }
224
+ .circle-menu-toggler:checked ~ .circle-menu-list .circle-menu-item:nth-child(6) {
225
+ transform: rotate(300deg) translateX(calc(-1 * var(--circle-menu-radius)));
226
+ }
227
+
228
+ /* === Size variants === */
229
+ .circle-menu-sm {
230
+ --circle-menu-size: 2.5rem;
231
+ --circle-menu-item-size: 2.5rem;
232
+ --circle-menu-radius: 4.5rem;
233
+ --circle-menu-icon-size: 1rem;
234
+ --circle-menu-bar-width: 0.9375rem;
235
+ --circle-menu-bar-gap: 0.3125rem;
236
+ }
237
+
238
+ .circle-menu-lg {
239
+ --circle-menu-size: 3.5rem;
240
+ --circle-menu-item-size: 3.5rem;
241
+ --circle-menu-radius: 6.5rem;
242
+ --circle-menu-icon-size: 1.5rem;
243
+ --circle-menu-bar-width: 1.3125rem;
244
+ --circle-menu-bar-gap: 0.4375rem;
245
+ }
246
+
247
+ /* === Color variants === */
248
+ .circle-menu-primary {
249
+ --circle-menu-btn-bg: var(--color-primary);
250
+ --circle-menu-bar-color: var(--color-primary-content);
251
+ --circle-menu-item-bg: var(--color-primary);
252
+ --circle-menu-item-color: var(--color-primary-content);
253
+ --circle-menu-item-ring: color-mix(in oklch, var(--color-primary) 40%, transparent);
254
+ }
255
+
256
+ .circle-menu-secondary {
257
+ --circle-menu-btn-bg: var(--color-secondary);
258
+ --circle-menu-bar-color: var(--color-secondary-content);
259
+ --circle-menu-item-bg: var(--color-secondary);
260
+ --circle-menu-item-color: var(--color-secondary-content);
261
+ --circle-menu-item-ring: color-mix(in oklch, var(--color-secondary) 40%, transparent);
262
+ }
263
+
264
+ .circle-menu-tertiary {
265
+ --circle-menu-btn-bg: var(--color-tertiary);
266
+ --circle-menu-bar-color: var(--color-tertiary-content);
267
+ --circle-menu-item-bg: var(--color-tertiary);
268
+ --circle-menu-item-color: var(--color-tertiary-content);
269
+ --circle-menu-item-ring: color-mix(in oklch, var(--color-tertiary) 40%, transparent);
270
+ }
271
+
272
+ .circle-menu-info {
273
+ --circle-menu-btn-bg: var(--color-info);
274
+ --circle-menu-bar-color: var(--color-info-content);
275
+ --circle-menu-item-bg: var(--color-info);
276
+ --circle-menu-item-color: var(--color-info-content);
277
+ --circle-menu-item-ring: color-mix(in oklch, var(--color-info) 40%, transparent);
278
+ }
279
+
280
+ .circle-menu-success {
281
+ --circle-menu-btn-bg: var(--color-success);
282
+ --circle-menu-bar-color: var(--color-success-content);
283
+ --circle-menu-item-bg: var(--color-success);
284
+ --circle-menu-item-color: var(--color-success-content);
285
+ --circle-menu-item-ring: color-mix(in oklch, var(--color-success) 40%, transparent);
286
+ }
287
+
288
+ .circle-menu-warning {
289
+ --circle-menu-btn-bg: var(--color-warning);
290
+ --circle-menu-bar-color: var(--color-warning-content);
291
+ --circle-menu-item-bg: var(--color-warning);
292
+ --circle-menu-item-color: var(--color-warning-content);
293
+ --circle-menu-item-ring: color-mix(in oklch, var(--color-warning) 40%, transparent);
294
+ }
295
+
296
+ .circle-menu-error {
297
+ --circle-menu-btn-bg: var(--color-error);
298
+ --circle-menu-bar-color: var(--color-error-content);
299
+ --circle-menu-item-bg: var(--color-error);
300
+ --circle-menu-item-color: var(--color-error-content);
301
+ --circle-menu-item-ring: color-mix(in oklch, var(--color-error) 40%, transparent);
302
+ }
303
+
304
+ /* === Reduced motion === */
305
+ @media (prefers-reduced-motion: reduce) {
306
+ .circle-menu-label {
307
+ transition: none;
308
+ }
309
+
310
+ .circle-menu-label::before,
311
+ .circle-menu-label::after {
312
+ transition: none;
313
+ }
314
+
315
+ .circle-menu-item {
316
+ transition: none;
317
+ }
318
+
319
+ .circle-menu-item a,
320
+ .circle-menu-item button {
321
+ transition: none;
322
+ }
323
+ }
324
+ }
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Code Block Component
3
+ * Styled container for displaying code with optional header, language badge, and copy button
4
+ * Uses DuskMoonUI color tokens for automatic theme switching
5
+ */
6
+
7
+ @layer components {
8
+ /* ============================================
9
+ * BASE CONTAINER
10
+ * ============================================ */
11
+
12
+ .code-block {
13
+ border: 1px solid var(--color-outline);
14
+ border-radius: var(--radius-sm);
15
+ overflow: hidden;
16
+ }
17
+
18
+ /* ============================================
19
+ * HEADER
20
+ * ============================================ */
21
+
22
+ .code-header {
23
+ display: flex;
24
+ align-items: center;
25
+ gap: 0.5rem;
26
+ padding: 0.5rem 1rem;
27
+ background-color: var(--color-surface-container-highest);
28
+ border-bottom: 1px solid var(--color-outline);
29
+ font-size: 0.75rem;
30
+ }
31
+
32
+ .code-title {
33
+ color: var(--color-on-surface);
34
+ font-weight: 600;
35
+ margin-right: auto;
36
+ }
37
+
38
+ .code-language {
39
+ color: var(--color-on-surface-variant);
40
+ text-transform: uppercase;
41
+ letter-spacing: 0.05em;
42
+ font-weight: 500;
43
+ }
44
+
45
+ /* Push language badge to the left when no title precedes it */
46
+ .code-language:first-child {
47
+ margin-right: auto;
48
+ }
49
+
50
+ /* ============================================
51
+ * COPY BUTTON
52
+ * ============================================ */
53
+
54
+ .code-block .copy-button {
55
+ display: flex;
56
+ align-items: center;
57
+ gap: 0.375rem;
58
+ padding: 0.25rem 0.5rem;
59
+ border: none;
60
+ border-radius: var(--radius-xs);
61
+ background: transparent;
62
+ color: var(--color-on-surface-variant);
63
+ font-size: 0.75rem;
64
+ cursor: pointer;
65
+ transition: background-color 0.15s ease, color 0.15s ease;
66
+ }
67
+
68
+ .code-block .copy-button:hover {
69
+ background-color: var(--color-outline-variant);
70
+ color: var(--color-on-surface);
71
+ }
72
+
73
+ .code-block .copy-icon {
74
+ flex-shrink: 0;
75
+ }
76
+
77
+ /* ============================================
78
+ * CODE CONTENT
79
+ * ============================================ */
80
+
81
+ .code-content {
82
+ background-color: var(--color-surface-container);
83
+ overflow-x: auto;
84
+ }
85
+
86
+ .code-content pre {
87
+ margin: 0;
88
+ padding: 1rem;
89
+ background: transparent;
90
+ border-radius: 0;
91
+ overflow-x: auto;
92
+ }
93
+
94
+ .code-content code {
95
+ background: transparent;
96
+ padding: 0;
97
+ font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
98
+ font-size: 0.875rem;
99
+ line-height: 1.6;
100
+ }
101
+
102
+ /* ============================================
103
+ * VARIANTS
104
+ * ============================================ */
105
+
106
+ /* Compact variant — reduced padding */
107
+ .code-block-compact .code-header {
108
+ padding: 0.375rem 0.75rem;
109
+ }
110
+
111
+ .code-block-compact .code-content pre {
112
+ padding: 0.75rem;
113
+ }
114
+
115
+ /* Borderless variant */
116
+ .code-block-borderless {
117
+ border: none;
118
+ }
119
+
120
+ .code-block-borderless .code-header {
121
+ border-bottom: none;
122
+ }
123
+
124
+ /* ============================================
125
+ * REDUCED MOTION
126
+ * ============================================ */
127
+
128
+ @media (prefers-reduced-motion: reduce) {
129
+ .code-block .copy-button {
130
+ transition: none;
131
+ }
132
+ }
133
+ }