minora 0.1.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.
@@ -0,0 +1,457 @@
1
+ /* ============================================================
2
+ ELEGANT MINIMALIST UI KIT — Toggle / Switch Component
3
+ toggle.css
4
+
5
+ ANATOMY — SWITCH
6
+ ─────────────────────────────────────────────────────────────
7
+ Structure:
8
+ <label class="switch switch-md">
9
+ <input type="checkbox" class="switch-native" />
10
+ <span class="switch-track">
11
+ <span class="switch-thumb">
12
+ <!-- optional icon inside thumb -->
13
+ </span>
14
+ <!-- optional ON/OFF labels inside track -->
15
+ </span>
16
+ <span class="switch-label">Label text</span>
17
+ </label>
18
+
19
+ Class layers:
20
+ 1. .switch → Wrapper label, flex layout
21
+ 2. .switch-{size} → Track & thumb sizes (sm/md/lg)
22
+ 3. .switch-{variant} → Style (card/icon/labels)
23
+ 4. .switch-label-{pos} → Label position (right/left/top)
24
+ 5. .switch-native → Hidden native checkbox (accessible)
25
+ 6. .switch-track → Pill-shaped background
26
+ 7. .switch-thumb → Circle that slides via translateX
27
+ ─────────────────────────────────────────────────────────────
28
+
29
+ ANATOMY — SWITCH GROUP
30
+ ─────────────────────────────────────────────────────────────
31
+ <div class="switch-group">
32
+ <span class="switch-group-label">Settings</span>
33
+ <div class="switch-group-item">
34
+ <label class="switch switch-md">...</label>
35
+ </div>
36
+ <div class="switch-separator"></div>
37
+ <div class="switch-group-item">
38
+ <label class="switch switch-md">...</label>
39
+ </div>
40
+ </div>
41
+ ─────────────────────────────────────────────────────────────
42
+ ============================================================ */
43
+
44
+ /* ═══════════════════════════════════════════════════════════
45
+ SWITCH — Base wrapper (label)
46
+ ═══════════════════════════════════════════════════════════ */
47
+
48
+ .switch {
49
+ display: inline-flex;
50
+ align-items: center;
51
+ gap: var(--control-gap);
52
+ cursor: pointer;
53
+ font-family: var(--font-sans);
54
+ font-size: var(--text-sm);
55
+ color: var(--input-text-color);
56
+ line-height: var(--leading-tight);
57
+ position: relative;
58
+ }
59
+
60
+ /* Hide native input — accessible but invisible */
61
+ .switch-native {
62
+ position: absolute;
63
+ width: var(--space-0);
64
+ height: var(--space-0);
65
+ opacity: 0;
66
+ pointer-events: none;
67
+ }
68
+
69
+ /* ── Track (pill shape) ─────────────────────────────────── */
70
+ .switch-track {
71
+ display: inline-flex;
72
+ align-items: center;
73
+ justify-content: space-between;
74
+ flex-shrink: 0;
75
+ width: var(--switch-md-track-w);
76
+ height: var(--switch-md-track-h);
77
+ border-radius: var(--radius-pill);
78
+ background-color: var(--switch-track-off);
79
+ transition: background-color var(--duration-normal) var(--ease-in-out),
80
+ box-shadow var(--duration-fast) var(--ease-out);
81
+ position: relative;
82
+ padding: var(--space-0-5);
83
+ box-sizing: border-box;
84
+ overflow: hidden;
85
+ }
86
+
87
+ /* ── Thumb (circle that slides) ─────────────────────────── */
88
+ .switch-thumb {
89
+ display: inline-flex;
90
+ align-items: center;
91
+ justify-content: center;
92
+ width: var(--switch-md-thumb);
93
+ height: var(--switch-md-thumb);
94
+ border-radius: var(--radius-pill);
95
+ background-color: var(--switch-thumb);
96
+ box-shadow: var(--switch-thumb-shadow);
97
+ transform: translateX(0);
98
+ transition: transform var(--duration-normal) var(--ease-out);
99
+ position: relative;
100
+ flex-shrink: 0;
101
+ }
102
+
103
+ /* Checked: slide thumb to right, change track color */
104
+ .switch-native:checked ~ .switch-track {
105
+ background-color: var(--switch-track-on);
106
+ }
107
+
108
+ .switch-native:checked ~ .switch-track .switch-thumb {
109
+ transform: translateX(var(--switch-md-translate));
110
+ }
111
+
112
+ /* ── Sizes ──────────────────────────────────────────────── */
113
+
114
+ /* Small */
115
+ .switch-sm .switch-track {
116
+ width: var(--switch-sm-track-w);
117
+ height: var(--switch-sm-track-h);
118
+ }
119
+
120
+ .switch-sm .switch-thumb {
121
+ width: var(--switch-sm-thumb);
122
+ height: var(--switch-sm-thumb);
123
+ }
124
+
125
+ .switch-sm .switch-native:checked ~ .switch-track .switch-thumb {
126
+ transform: translateX(var(--switch-sm-translate));
127
+ }
128
+
129
+ /* Medium (default) — sizes already set on base */
130
+
131
+ /* Large */
132
+ .switch-lg .switch-track {
133
+ width: var(--switch-lg-track-w);
134
+ height: var(--switch-lg-track-h);
135
+ }
136
+
137
+ .switch-lg .switch-thumb {
138
+ width: var(--switch-lg-thumb);
139
+ height: var(--switch-lg-thumb);
140
+ }
141
+
142
+ .switch-lg .switch-native:checked ~ .switch-track .switch-thumb {
143
+ transform: translateX(var(--switch-lg-translate));
144
+ }
145
+
146
+ /* ═══════════════════════════════════════════════════════════
147
+ SWITCH — Icon inside thumb
148
+ ═══════════════════════════════════════════════════════════ */
149
+
150
+ .switch-thumb-icon {
151
+ width: 55%;
152
+ height: 55%;
153
+ stroke: var(--color-accent-500);
154
+ fill: none;
155
+ stroke-width: 2.5;
156
+ stroke-linecap: round;
157
+ stroke-linejoin: round;
158
+ opacity: 0;
159
+ transform: scale(0.7);
160
+ transition: opacity var(--duration-fast) var(--ease-in-out),
161
+ transform var(--duration-fast) var(--ease-out);
162
+ }
163
+
164
+ /* Show icon when on */
165
+ .switch-native:checked ~ .switch-track .switch-thumb-icon.is-on {
166
+ opacity: 1;
167
+ transform: scale(1);
168
+ }
169
+
170
+ /* Show off icon when off */
171
+ .switch-track .switch-thumb-icon.is-off {
172
+ opacity: 0.4;
173
+ stroke: var(--color-neutral-400);
174
+ transform: scale(1);
175
+ }
176
+
177
+ .switch-native:checked ~ .switch-track .switch-thumb-icon.is-off {
178
+ opacity: 0;
179
+ transform: scale(0.7);
180
+ }
181
+
182
+ /* ═══════════════════════════════════════════════════════════
183
+ SWITCH — ON/OFF labels inside track
184
+ ═══════════════════════════════════════════════════════════ */
185
+
186
+ .switch-track .switch-label-on,
187
+ .switch-track .switch-label-off {
188
+ font-family: var(--font-sans);
189
+ font-size: var(--switch-label-font-size);
190
+ font-weight: var(--font-semibold);
191
+ line-height: 1;
192
+ text-transform: uppercase;
193
+ letter-spacing: var(--tracking-wider);
194
+ position: absolute;
195
+ top: 50%;
196
+ transform: translateY(-50%);
197
+ user-select: none;
198
+ -webkit-user-select: none;
199
+ pointer-events: none;
200
+ }
201
+
202
+ .switch-track .switch-label-off {
203
+ left: var(--space-1-5);
204
+ color: var(--color-neutral-500);
205
+ }
206
+
207
+ .switch-track .switch-label-on {
208
+ right: var(--space-1-5);
209
+ color: var(--color-neutral-50);
210
+ opacity: 0;
211
+ transition: opacity var(--duration-fast) var(--ease-in-out);
212
+ }
213
+
214
+ .switch-native:checked ~ .switch-track .switch-label-on {
215
+ opacity: 1;
216
+ }
217
+
218
+ /* Hide labels when thumb covers them */
219
+ .switch-track .switch-label-off {
220
+ transition: opacity var(--duration-fast) var(--ease-in-out);
221
+ }
222
+
223
+ .switch-native:checked ~ .switch-track .switch-label-off {
224
+ opacity: 0;
225
+ }
226
+
227
+ /* ═══════════════════════════════════════════════════════════
228
+ SWITCH — Variant: Card
229
+ Entire row clickable, like a settings item.
230
+ ═══════════════════════════════════════════════════════════ */
231
+
232
+ .switch-card {
233
+ display: flex;
234
+ align-items: center;
235
+ justify-content: space-between;
236
+ gap: var(--space-4);
237
+ padding: var(--space-4);
238
+ border: var(--border-width) solid var(--border-color);
239
+ border-radius: var(--radius-md);
240
+ background-color: var(--select-bg);
241
+ transition: border-color var(--duration-normal) var(--ease-in-out),
242
+ background-color var(--duration-fast) var(--ease-in-out),
243
+ box-shadow var(--duration-fast) var(--ease-out);
244
+ width: 100%;
245
+ cursor: pointer;
246
+ }
247
+
248
+ .switch-card:hover {
249
+ border-color: var(--border-color-strong);
250
+ background-color: var(--color-neutral-50);
251
+ }
252
+
253
+ .switch-card .switch-content {
254
+ display: flex;
255
+ align-items: center;
256
+ gap: var(--space-3);
257
+ min-width: 0;
258
+ flex: 1;
259
+ }
260
+
261
+ .switch-card-icon {
262
+ flex-shrink: 0;
263
+ width: var(--space-5);
264
+ height: var(--space-5);
265
+ color: var(--color-neutral-500);
266
+ }
267
+
268
+ .switch-card-text {
269
+ display: flex;
270
+ flex-direction: column;
271
+ gap: var(--space-0-5);
272
+ min-width: 0;
273
+ }
274
+
275
+ .switch-card-title {
276
+ font-size: var(--text-sm);
277
+ font-weight: var(--font-medium);
278
+ color: var(--input-text-color);
279
+ }
280
+
281
+ .switch-card-desc {
282
+ font-size: var(--text-xs);
283
+ color: var(--input-helper-color);
284
+ line-height: var(--leading-tight);
285
+ }
286
+
287
+ .switch-card .switch-track {
288
+ flex-shrink: 0;
289
+ }
290
+
291
+ .switch-card .switch-native:checked ~ .switch-track {
292
+ background-color: var(--switch-track-on);
293
+ }
294
+
295
+ /* ═══════════════════════════════════════════════════════════
296
+ SWITCH — Label positions
297
+ ═══════════════════════════════════════════════════════════ */
298
+
299
+ /* Label left (switch on right) */
300
+ .switch-label-left {
301
+ flex-direction: row-reverse;
302
+ }
303
+
304
+ /* Label top (switch below) */
305
+ .switch-label-top {
306
+ flex-direction: column;
307
+ align-items: flex-start;
308
+ }
309
+
310
+ .switch-label-top .switch-track {
311
+ margin-top: var(--space-1-5);
312
+ }
313
+
314
+ /* ═══════════════════════════════════════════════════════════
315
+ SWITCH — States
316
+ ═══════════════════════════════════════════════════════════ */
317
+
318
+ /* Focus visible */
319
+ .switch-native:focus-visible ~ .switch-track {
320
+ outline: var(--focus-ring-width) solid var(--focus-ring-color);
321
+ outline-offset: var(--focus-ring-offset);
322
+ }
323
+
324
+ /* Disabled */
325
+ .switch.is-disabled {
326
+ opacity: var(--switch-disabled-opacity);
327
+ cursor: var(--input-disabled-cursor);
328
+ pointer-events: none;
329
+ }
330
+
331
+ .switch-card.is-disabled {
332
+ opacity: var(--switch-disabled-opacity);
333
+ cursor: var(--input-disabled-cursor);
334
+ pointer-events: none;
335
+ }
336
+
337
+ /* Loading state — thumb spins */
338
+ .switch.is-loading .switch-thumb {
339
+ animation: switch-spin var(--anim-spin-duration) linear infinite;
340
+ background-image: none;
341
+ position: relative;
342
+ }
343
+
344
+ .switch.is-loading .switch-thumb::before {
345
+ content: '';
346
+ position: absolute;
347
+ inset: var(--switch-spinner-inset);
348
+ border-radius: var(--radius-pill);
349
+ border: var(--border-width-2) solid var(--color-neutral-300);
350
+ border-top-color: var(--color-accent-500);
351
+ animation: switch-spinner-ring var(--anim-spinner-fast) linear infinite;
352
+ }
353
+
354
+ .switch.is-loading .switch-track {
355
+ background-color: var(--color-neutral-200);
356
+ cursor: wait;
357
+ }
358
+
359
+ @keyframes switch-spin {
360
+ 0% { transform: rotate(0deg); }
361
+ 100% { transform: rotate(360deg); }
362
+ }
363
+
364
+ @keyframes switch-spinner-ring {
365
+ 0% { transform: rotate(0deg); }
366
+ 100% { transform: rotate(360deg); }
367
+ }
368
+
369
+ /* Override translate during loading so thumb stays centered */
370
+ .switch.is-loading .switch-native:checked ~ .switch-track .switch-thumb {
371
+ animation: switch-spin var(--anim-spin-duration) linear infinite;
372
+ transform: translateX(var(--switch-md-translate));
373
+ }
374
+
375
+ .switch-sm.is-loading .switch-native:checked ~ .switch-track .switch-thumb {
376
+ transform: translateX(var(--switch-sm-translate));
377
+ }
378
+
379
+ .switch-lg.is-loading .switch-native:checked ~ .switch-track .switch-thumb {
380
+ transform: translateX(var(--switch-lg-translate));
381
+ }
382
+
383
+ /* ═══════════════════════════════════════════════════════════
384
+ SWITCH GROUP — Container with separators
385
+ ═══════════════════════════════════════════════════════════ */
386
+
387
+ .switch-group {
388
+ display: flex;
389
+ flex-direction: column;
390
+ border: var(--border-width) solid var(--border-color);
391
+ border-radius: var(--radius-md);
392
+ background-color: var(--select-bg);
393
+ overflow: hidden;
394
+ }
395
+
396
+ .switch-group-label {
397
+ font-family: var(--font-sans);
398
+ font-size: var(--text-sm);
399
+ font-weight: var(--font-semibold);
400
+ color: var(--input-label-color);
401
+ padding: var(--space-4) var(--space-4) var(--space-2);
402
+ display: block;
403
+ }
404
+
405
+ .switch-group-helper {
406
+ font-family: var(--font-sans);
407
+ font-size: var(--text-xs);
408
+ color: var(--input-helper-color);
409
+ padding: var(--space-2) var(--space-4) var(--space-4);
410
+ display: block;
411
+ }
412
+
413
+ .switch-group-item {
414
+ display: flex;
415
+ align-items: center;
416
+ justify-content: space-between;
417
+ padding: var(--space-3) var(--space-4);
418
+ transition: background-color var(--duration-fast) var(--ease-in-out);
419
+ }
420
+
421
+ .switch-group-item:hover {
422
+ background-color: var(--color-neutral-50);
423
+ }
424
+
425
+ /* Separator between items */
426
+ .switch-separator {
427
+ height: var(--border-width);
428
+ background-color: var(--color-neutral-100);
429
+ margin: 0 var(--space-4);
430
+ }
431
+
432
+ /* ═══════════════════════════════════════════════════════════
433
+ SWITCH GROUP — Error state
434
+ ═══════════════════════════════════════════════════════════ */
435
+
436
+ .switch-group-error .switch-group {
437
+ border-color: var(--color-error);
438
+ }
439
+
440
+ .switch-group-error-msg {
441
+ display: flex;
442
+ align-items: center;
443
+ gap: var(--space-1);
444
+ margin-top: var(--space-2);
445
+ font-family: var(--font-sans);
446
+ font-size: var(--text-xs);
447
+ font-weight: var(--font-medium);
448
+ color: var(--color-error);
449
+ line-height: var(--leading-tight);
450
+ }
451
+
452
+ .switch-group-error-msg svg {
453
+ width: var(--space-3);
454
+ height: var(--space-3);
455
+ flex-shrink: 0;
456
+ color: var(--color-error);
457
+ }