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,625 @@
1
+ /* ============================================================
2
+ ELEGANT MINIMALIST UI KIT — Input & Textarea Components
3
+ input.css
4
+
5
+ ANATOMY — INPUT GROUP
6
+ ─────────────────────────────────────────────────────────────
7
+ Structure:
8
+ <div class="input-group">
9
+ <label class="input-label" for="...">
10
+ Email <span class="input-required">*</span>
11
+ </label>
12
+ <div class="input-wrapper">
13
+ <!-- optional: icon/Addon prefix -->
14
+ <svg class="input-icon-leading">...</svg>
15
+ <span class="input-addon">https://</span>
16
+
17
+ <!-- The actual input -->
18
+ <input class="input input-md" id="..." type="text" />
19
+
20
+ <!-- optional: icon/button suffix -->
21
+ <button class="input-icon-trailing input-clear">...</button>
22
+ <span class="input-addon">.com</span>
23
+ </div>
24
+ <!-- optional: helper / error / counter text -->
25
+ <span class="input-helper">Helper text</span>
26
+ <span class="input-message input-message-error">Error msg</span>
27
+ <span class="input-counter">0 / 50</span>
28
+ </div>
29
+
30
+ Class layers:
31
+ 1. .input-group → Wrapper for label + input + helper
32
+ 2. .input → Base reset, layout, typography
33
+ 3. .input-{variant} → Style (default/filled/underline)
34
+ 4. .input-{size} → Height, padding, font-size
35
+ 5. .input-{state} → Error/success/warning/disabled/readonly
36
+ 6. .input-wrapper → Flex container for addons + input
37
+ 7. .input-icon-leading → Prefix icon (SVG)
38
+ 8. .input-icon-trailing → Suffix icon/button (eye toggle, clear)
39
+ 9. .input-addon → Text prefix/suffix
40
+ 10. .input-label → Label above input
41
+ 11. .input-helper → Helper text below input
42
+ 12. .input-message → Validation message (error/success/warning)
43
+ 13. .input-counter → Character counter
44
+ ─────────────────────────────────────────────────────────────
45
+
46
+ ANATOMY — TEXTAREA
47
+ ─────────────────────────────────────────────────────────────
48
+ Structure: same as input but uses .textarea class instead.
49
+ <div class="input-group">
50
+ <label class="input-label" for="...">Bio</label>
51
+ <textarea class="textarea textarea-md" id="..."></textarea>
52
+ <span class="input-helper">Optional helper</span>
53
+ </div>
54
+ ─────────────────────────────────────────────────────────────
55
+ ============================================================ */
56
+
57
+ /* ═══════════════════════════════════════════════════════════
58
+ INPUT GROUP — Wrapper
59
+ ═══════════════════════════════════════════════════════════ */
60
+
61
+ .input-group {
62
+ display: flex;
63
+ flex-direction: column;
64
+ gap: var(--space-1-5);
65
+ width: 100%;
66
+ }
67
+
68
+ /* ═══════════════════════════════════════════════════════════
69
+ INPUT LABEL
70
+ ═══════════════════════════════════════════════════════════ */
71
+
72
+ .input-label {
73
+ font-family: var(--font-sans);
74
+ font-size: var(--text-sm);
75
+ font-weight: var(--font-medium);
76
+ color: var(--input-label-color);
77
+ line-height: var(--leading-tight);
78
+ }
79
+
80
+ .input-label .input-required {
81
+ color: var(--color-error);
82
+ margin-left: var(--space-0-5);
83
+ }
84
+
85
+ /* ═══════════════════════════════════════════════════════════
86
+ INPUT WRAPPER — flex container for addons + input
87
+ ═══════════════════════════════════════════════════════════ */
88
+
89
+ .input-wrapper {
90
+ display: flex;
91
+ align-items: center;
92
+ position: relative;
93
+ width: 100%;
94
+ border-radius: var(--radius-sm);
95
+ border: var(--border-width) solid var(--border-color);
96
+ background-color: var(--input-bg);
97
+ transition: border-color var(--duration-fast) var(--ease-in-out),
98
+ box-shadow var(--duration-fast) var(--ease-out);
99
+ overflow: hidden;
100
+ }
101
+
102
+ /* Focus state on wrapper (triggered when child input:focus) */
103
+ .input-wrapper:has(.input:focus),
104
+ .input-wrapper:has(.textarea:focus) {
105
+ border-color: var(--input-focus-color);
106
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--input-focus-color);
107
+ }
108
+
109
+ /* ═══════════════════════════════════════════════════════════
110
+ INPUT — Base
111
+ ═══════════════════════════════════════════════════════════ */
112
+
113
+ .input {
114
+ display: block;
115
+ width: 100%;
116
+ border: none;
117
+ outline: none;
118
+ background: transparent;
119
+ font-family: var(--font-sans);
120
+ font-size: var(--text-sm);
121
+ font-weight: var(--font-regular);
122
+ color: var(--input-text-color);
123
+ line-height: var(--leading-none);
124
+ padding: 0;
125
+ -webkit-appearance: none;
126
+ appearance: none;
127
+ }
128
+
129
+ .input::placeholder {
130
+ color: var(--input-placeholder-color);
131
+ }
132
+
133
+ .input:focus {
134
+ outline: none;
135
+ }
136
+
137
+ /* Disabled */
138
+ .input:disabled {
139
+ opacity: var(--input-disabled-opacity);
140
+ cursor: var(--input-disabled-cursor);
141
+ }
142
+
143
+ /* Readonly */
144
+ .input:read-only {
145
+ background-color: var(--input-addon-bg);
146
+ }
147
+
148
+ /* ═══════════════════════════════════════════════════════════
149
+ INPUT — Sizes
150
+ ═══════════════════════════════════════════════════════════ */
151
+
152
+ .input-sm {
153
+ min-height: var(--input-sm-height);
154
+ font-size: var(--text-sm);
155
+ padding: var(--space-1) var(--space-3);
156
+ }
157
+
158
+ .input-md {
159
+ min-height: var(--input-md-height);
160
+ font-size: var(--text-sm);
161
+ padding: var(--space-2) var(--space-4);
162
+ }
163
+
164
+ .input-lg {
165
+ min-height: var(--input-lg-height);
166
+ font-size: var(--text-base);
167
+ padding: var(--space-2-5) var(--space-4);
168
+ }
169
+
170
+ /* ═══════════════════════════════════════════════════════════
171
+ INPUT — Variants
172
+ ═══════════════════════════════════════════════════════════ */
173
+
174
+ /* Default (bordered) — base style is already this */
175
+
176
+ /* Filled (subtle background, no border) */
177
+ .input-filled {
178
+ border-color: transparent;
179
+ background-color: var(--input-filled-bg);
180
+ }
181
+
182
+ .input-filled.input-wrapper {
183
+ border-color: transparent;
184
+ background-color: var(--input-filled-bg);
185
+ }
186
+
187
+ .input-filled.input-wrapper:has(.input:focus),
188
+ .input-filled.input-wrapper:has(.textarea:focus) {
189
+ border-color: transparent;
190
+ background-color: var(--input-bg);
191
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--input-focus-color);
192
+ }
193
+
194
+ /* Underline (only bottom border) */
195
+ .input-underline.input-wrapper {
196
+ border-top-color: transparent;
197
+ border-left-color: transparent;
198
+ border-right-color: transparent;
199
+ border-bottom-color: var(--border-color);
200
+ border-radius: var(--radius-none);
201
+ background-color: transparent;
202
+ }
203
+
204
+ .input-underline.input-wrapper:has(.input:focus),
205
+ .input-underline.input-wrapper:has(.textarea:focus) {
206
+ border-top-color: transparent;
207
+ border-left-color: transparent;
208
+ border-right-color: transparent;
209
+ border-bottom-color: var(--input-focus-color);
210
+ box-shadow: none;
211
+ }
212
+
213
+ .input-underline .input {
214
+ padding-left: 0;
215
+ padding-right: 0;
216
+ }
217
+
218
+ /* ═══════════════════════════════════════════════════════════
219
+ INPUT — Semantic States (Error, Success, Warning)
220
+ Applied on the .input-wrapper
221
+ ═══════════════════════════════════════════════════════════ */
222
+
223
+ /* Error */
224
+ .input-error.input-wrapper {
225
+ border-color: var(--color-error);
226
+ }
227
+
228
+ .input-error.input-wrapper:has(.input:focus),
229
+ .input-error.input-wrapper:has(.textarea:focus) {
230
+ border-color: var(--input-focus-error);
231
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--input-focus-error);
232
+ }
233
+
234
+ .input-error.input-filled.input-wrapper {
235
+ border-color: transparent;
236
+ }
237
+
238
+ .input-error.input-filled.input-wrapper:has(.input:focus),
239
+ .input-error.input-filled.input-wrapper:has(.textarea:focus) {
240
+ border-color: transparent;
241
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--input-focus-error);
242
+ }
243
+
244
+ .input-error.input-underline.input-wrapper {
245
+ border-bottom-color: var(--color-error);
246
+ }
247
+
248
+ .input-error.input-underline.input-wrapper:has(.input:focus),
249
+ .input-error.input-underline.input-wrapper:has(.textarea:focus) {
250
+ border-bottom-color: var(--input-focus-error);
251
+ box-shadow: none;
252
+ }
253
+
254
+ /* Success */
255
+ .input-success.input-wrapper {
256
+ border-color: var(--color-success);
257
+ }
258
+
259
+ .input-success.input-wrapper:has(.input:focus),
260
+ .input-success.input-wrapper:has(.textarea:focus) {
261
+ border-color: var(--input-focus-success);
262
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--input-focus-success);
263
+ }
264
+
265
+ .input-success.input-filled.input-wrapper {
266
+ border-color: transparent;
267
+ }
268
+
269
+ .input-success.input-filled.input-wrapper:has(.input:focus),
270
+ .input-success.input-filled.input-wrapper:has(.textarea:focus) {
271
+ border-color: transparent;
272
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--input-focus-success);
273
+ }
274
+
275
+ .input-success.input-underline.input-wrapper {
276
+ border-bottom-color: var(--color-success);
277
+ }
278
+
279
+ .input-success.input-underline.input-wrapper:has(.input:focus),
280
+ .input-success.input-underline.input-wrapper:has(.textarea:focus) {
281
+ border-bottom-color: var(--input-focus-success);
282
+ box-shadow: none;
283
+ }
284
+
285
+ /* Warning */
286
+ .input-warning.input-wrapper {
287
+ border-color: var(--color-warning);
288
+ }
289
+
290
+ .input-warning.input-wrapper:has(.input:focus),
291
+ .input-warning.input-wrapper:has(.textarea:focus) {
292
+ border-color: var(--input-focus-warning);
293
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--input-focus-warning);
294
+ }
295
+
296
+ .input-warning.input-filled.input-wrapper {
297
+ border-color: transparent;
298
+ }
299
+
300
+ .input-warning.input-filled.input-wrapper:has(.input:focus),
301
+ .input-warning.input-filled.input-wrapper:has(.textarea:focus) {
302
+ border-color: transparent;
303
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--input-focus-warning);
304
+ }
305
+
306
+ .input-warning.input-underline.input-wrapper {
307
+ border-bottom-color: var(--color-warning);
308
+ }
309
+
310
+ .input-warning.input-underline.input-wrapper:has(.input:focus),
311
+ .input-warning.input-underline.input-wrapper:has(.textarea:focus) {
312
+ border-bottom-color: var(--input-focus-warning);
313
+ box-shadow: none;
314
+ }
315
+
316
+ /* ═══════════════════════════════════════════════════════════
317
+ INPUT — Icons (Leading & Trailing)
318
+ ═══════════════════════════════════════════════════════════ */
319
+
320
+ .input-icon-leading {
321
+ display: inline-flex;
322
+ align-items: center;
323
+ justify-content: center;
324
+ flex-shrink: 0;
325
+ color: var(--input-icon-color);
326
+ margin-left: var(--space-3);
327
+ width: var(--space-4);
328
+ height: var(--space-4);
329
+ }
330
+
331
+ .input-icon-leading svg {
332
+ width: var(--space-4);
333
+ height: var(--space-4);
334
+ }
335
+
336
+ .input-icon-trailing {
337
+ display: inline-flex;
338
+ align-items: center;
339
+ justify-content: center;
340
+ flex-shrink: 0;
341
+ color: var(--input-icon-color);
342
+ background: transparent;
343
+ border: none;
344
+ cursor: pointer;
345
+ padding: 0;
346
+ width: var(--space-4);
347
+ height: var(--space-4);
348
+ margin-right: var(--space-3);
349
+ transition: color var(--duration-fast) var(--ease-in-out);
350
+ }
351
+
352
+ .input-icon-trailing svg {
353
+ width: var(--space-4);
354
+ height: var(--space-4);
355
+ }
356
+
357
+ .input-icon-trailing:hover {
358
+ color: var(--color-neutral-600);
359
+ }
360
+
361
+ /* Password eye toggle */
362
+ .input-icon-trailing:focus-visible {
363
+ outline: var(--focus-ring-width) solid var(--focus-ring-color);
364
+ outline-offset: var(--focus-ring-offset);
365
+ border-radius: var(--radius-sm);
366
+ }
367
+
368
+ /* Clear button (X) — hidden by default, shown via JS */
369
+ .input-clear {
370
+ display: none;
371
+ opacity: 0;
372
+ transition: opacity var(--duration-fast) var(--ease-in-out),
373
+ color var(--duration-fast) var(--ease-in-out);
374
+ }
375
+
376
+ .input-clear.is-visible {
377
+ display: inline-flex;
378
+ opacity: 1;
379
+ }
380
+
381
+ .input-clear:hover {
382
+ color: var(--color-neutral-700);
383
+ }
384
+
385
+ /* ═══════════════════════════════════════════════════════════
386
+ INPUT — Addon (text prefix/suffix)
387
+ ═══════════════════════════════════════════════════════════ */
388
+
389
+ .input-addon {
390
+ display: inline-flex;
391
+ align-items: center;
392
+ justify-content: center;
393
+ flex-shrink: 0;
394
+ font-family: var(--font-sans);
395
+ font-size: var(--text-sm);
396
+ font-weight: var(--font-regular);
397
+ color: var(--input-addon-text-color);
398
+ background-color: var(--input-addon-bg);
399
+ line-height: var(--leading-none);
400
+ padding: var(--space-1) var(--space-2-5);
401
+ white-space: nowrap;
402
+ user-select: none;
403
+ -webkit-user-select: none;
404
+ }
405
+
406
+ .input-addon:first-child {
407
+ border-radius: var(--radius-sm) 0 0 var(--radius-sm);
408
+ border-right: var(--border-width) solid var(--border-color);
409
+ padding-right: var(--space-2);
410
+ }
411
+
412
+ .input-addon:last-child {
413
+ border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
414
+ border-left: var(--border-width) solid var(--border-color);
415
+ padding-left: var(--space-2);
416
+ }
417
+
418
+ /* Adjust input padding when addons present */
419
+ .input-wrapper:has(.input-icon-leading) .input {
420
+ padding-left: var(--space-1);
421
+ }
422
+
423
+ .input-wrapper:has(.input-icon-trailing) .input {
424
+ padding-right: var(--space-1);
425
+ }
426
+
427
+ .input-wrapper:has(.input-addon:first-child) .input,
428
+ .input-wrapper .input-addon + .input {
429
+ padding-left: var(--space-1);
430
+ }
431
+
432
+ .input-wrapper:has(.input-addon:last-child) .input,
433
+ .input-wrapper .input + .input-addon {
434
+ padding-right: var(--space-1);
435
+ }
436
+
437
+ /* ═══════════════════════════════════════════════════════════
438
+ INPUT — Helper text
439
+ ═══════════════════════════════════════════════════════════ */
440
+
441
+ .input-helper {
442
+ font-family: var(--font-sans);
443
+ font-size: var(--text-xs);
444
+ color: var(--input-helper-color);
445
+ line-height: var(--leading-tight);
446
+ }
447
+
448
+ /* ═══════════════════════════════════════════════════════════
449
+ INPUT — Validation messages (error/success/warning)
450
+ ═══════════════════════════════════════════════════════════ */
451
+
452
+ .input-message {
453
+ display: flex;
454
+ align-items: center;
455
+ gap: var(--space-1);
456
+ font-family: var(--font-sans);
457
+ font-size: var(--text-xs);
458
+ font-weight: var(--font-medium);
459
+ line-height: var(--leading-tight);
460
+ }
461
+
462
+ .input-message svg {
463
+ width: var(--space-3);
464
+ height: var(--space-3);
465
+ flex-shrink: 0;
466
+ }
467
+
468
+ .input-message-error {
469
+ color: var(--color-error);
470
+ }
471
+
472
+ .input-message-error svg {
473
+ color: var(--color-error);
474
+ }
475
+
476
+ .input-message-success {
477
+ color: var(--color-success);
478
+ }
479
+
480
+ .input-message-success svg {
481
+ color: var(--color-success);
482
+ }
483
+
484
+ .input-message-warning {
485
+ color: var(--color-warning);
486
+ }
487
+
488
+ .input-message-warning svg {
489
+ color: var(--color-warning);
490
+ }
491
+
492
+ /* ═══════════════════════════════════════════════════════════
493
+ INPUT — Character counter
494
+ ═══════════════════════════════════════════════════════════ */
495
+
496
+ .input-counter {
497
+ font-family: var(--font-sans);
498
+ font-size: var(--text-xs);
499
+ color: var(--input-helper-color);
500
+ line-height: var(--leading-tight);
501
+ text-align: right;
502
+ font-variant-numeric: tabular-nums;
503
+ -moz-font-feature-settings: 'tnum';
504
+ font-feature-settings: 'tnum';
505
+ }
506
+
507
+ .input-counter.limit-near {
508
+ color: var(--color-warning);
509
+ }
510
+
511
+ .input-counter.limit-reached {
512
+ color: var(--color-error);
513
+ font-weight: var(--font-semibold);
514
+ }
515
+
516
+ /* ═══════════════════════════════════════════════════════════
517
+ TEXTAREA
518
+ ═══════════════════════════════════════════════════════════ */
519
+
520
+ .textarea {
521
+ display: block;
522
+ width: 100%;
523
+ border: var(--border-width) solid var(--border-color);
524
+ border-radius: var(--radius-sm);
525
+ background-color: var(--input-bg);
526
+ font-family: var(--font-sans);
527
+ font-size: var(--text-sm);
528
+ font-weight: var(--font-regular);
529
+ color: var(--input-text-color);
530
+ line-height: var(--leading-relaxed);
531
+ padding: var(--space-2) var(--space-3);
532
+ outline: none;
533
+ resize: vertical;
534
+ min-height: calc(var(--textarea-min-rows) * 1.625 * var(--text-sm) + var(--space-4));
535
+ max-height: calc(var(--textarea-max-rows) * 1.625 * var(--text-sm) + var(--space-4));
536
+ transition: border-color var(--duration-fast) var(--ease-in-out),
537
+ box-shadow var(--duration-fast) var(--ease-out);
538
+ overflow-y: auto;
539
+ }
540
+
541
+ .textarea::placeholder {
542
+ color: var(--input-placeholder-color);
543
+ }
544
+
545
+ .textarea:focus {
546
+ outline: none;
547
+ border-color: var(--input-focus-color);
548
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--input-focus-color);
549
+ }
550
+
551
+ .textarea:disabled {
552
+ opacity: var(--input-disabled-opacity);
553
+ cursor: var(--input-disabled-cursor);
554
+ resize: none;
555
+ }
556
+
557
+ .textarea:read-only {
558
+ background-color: var(--input-addon-bg);
559
+ }
560
+
561
+ /* Textarea sizes */
562
+ .textarea-sm {
563
+ font-size: var(--text-sm);
564
+ padding: var(--space-1-5) var(--space-3);
565
+ }
566
+
567
+ .textarea-md {
568
+ font-size: var(--text-sm);
569
+ padding: var(--space-2) var(--space-3);
570
+ }
571
+
572
+ .textarea-lg {
573
+ font-size: var(--text-base);
574
+ padding: var(--space-2-5) var(--space-4);
575
+ }
576
+
577
+ /* Textarea semantic states */
578
+ .textarea-error {
579
+ border-color: var(--color-error);
580
+ }
581
+
582
+ .textarea-error:focus {
583
+ border-color: var(--input-focus-error);
584
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--input-focus-error);
585
+ }
586
+
587
+ .textarea-success {
588
+ border-color: var(--color-success);
589
+ }
590
+
591
+ .textarea-success:focus {
592
+ border-color: var(--input-focus-success);
593
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--input-focus-success);
594
+ }
595
+
596
+ .textarea-warning {
597
+ border-color: var(--color-warning);
598
+ }
599
+
600
+ .textarea-warning:focus {
601
+ border-color: var(--input-focus-warning);
602
+ box-shadow: 0 0 0 var(--focus-ring-width) var(--input-focus-warning);
603
+ }
604
+
605
+ /* ═══════════════════════════════════════════════════════════
606
+ DISABLED STATE ON GROUP
607
+ ═══════════════════════════════════════════════════════════ */
608
+
609
+ .input-group.is-disabled {
610
+ opacity: var(--input-disabled-opacity);
611
+ pointer-events: none;
612
+ }
613
+
614
+ .input-group.is-disabled .input-wrapper {
615
+ cursor: var(--input-disabled-cursor);
616
+ }
617
+
618
+ /* ═══════════════════════════════════════════════════════════
619
+ READONLY STATE ON GROUP
620
+ ═══════════════════════════════════════════════════════════ */
621
+
622
+ .input-group.is-readonly .input-wrapper {
623
+ background-color: var(--input-addon-bg);
624
+ cursor: default;
625
+ }