zenkit-css 1.0.7 → 1.2.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,343 @@
1
+ // ========================================
2
+ // ZenKit - Password Input Component
3
+ // ========================================
4
+
5
+ @use '../abstracts/variables' as *;
6
+
7
+ // ----------------------------------------
8
+ // Password Input Container
9
+ // ----------------------------------------
10
+ .password-input {
11
+ position: relative;
12
+ display: flex;
13
+ align-items: center;
14
+ }
15
+
16
+ // ----------------------------------------
17
+ // Password Input Field
18
+ // ----------------------------------------
19
+ .password-input-field {
20
+ width: 100%;
21
+ padding: 0.625rem 2.75rem 0.625rem 0.875rem;
22
+ font-size: var(--text-sm);
23
+ font-family: inherit;
24
+ color: var(--text);
25
+ background-color: var(--bg);
26
+ border: 1px solid var(--border);
27
+ border-radius: $border-radius;
28
+ transition: border-color $transition-fast $transition-timing,
29
+ box-shadow $transition-fast $transition-timing;
30
+
31
+ &:focus {
32
+ outline: none;
33
+ border-color: var(--primary);
34
+ box-shadow: 0 0 0 3px rgba($primary, 0.15);
35
+ }
36
+
37
+ &::placeholder {
38
+ color: var(--text-muted);
39
+ }
40
+
41
+ &:disabled {
42
+ background-color: var(--bg-muted);
43
+ cursor: not-allowed;
44
+ opacity: 0.6;
45
+ }
46
+ }
47
+
48
+ // ----------------------------------------
49
+ // Password Toggle Button
50
+ // ----------------------------------------
51
+ .password-toggle {
52
+ position: absolute;
53
+ right: 0.5rem;
54
+ top: 50%;
55
+ transform: translateY(-50%);
56
+ display: flex;
57
+ align-items: center;
58
+ justify-content: center;
59
+ width: 2rem;
60
+ height: 2rem;
61
+ padding: 0;
62
+ color: var(--text-muted);
63
+ background: transparent;
64
+ border: none;
65
+ border-radius: $border-radius;
66
+ cursor: pointer;
67
+ transition: color $transition-fast $transition-timing,
68
+ background-color $transition-fast $transition-timing;
69
+
70
+ &:hover {
71
+ color: var(--text);
72
+ background-color: var(--gray-100);
73
+ }
74
+
75
+ &:focus {
76
+ outline: none;
77
+ color: var(--primary);
78
+ }
79
+
80
+ svg {
81
+ width: 1.125rem;
82
+ height: 1.125rem;
83
+ }
84
+ }
85
+
86
+ // Show/hide icons
87
+ .password-icon-show,
88
+ .password-icon-hide {
89
+ display: none;
90
+ }
91
+
92
+ .password-input-field[type="password"] ~ .password-toggle {
93
+ .password-icon-show {
94
+ display: block;
95
+ }
96
+ .password-icon-hide {
97
+ display: none;
98
+ }
99
+ }
100
+
101
+ .password-input-field[type="text"] ~ .password-toggle {
102
+ .password-icon-show {
103
+ display: none;
104
+ }
105
+ .password-icon-hide {
106
+ display: block;
107
+ }
108
+ }
109
+
110
+ // ----------------------------------------
111
+ // Password Input Sizes
112
+ // ----------------------------------------
113
+ .password-input-sm {
114
+ .password-input-field {
115
+ padding: 0.5rem 2.5rem 0.5rem 0.75rem;
116
+ font-size: var(--text-xs);
117
+ }
118
+
119
+ .password-toggle {
120
+ width: 1.75rem;
121
+ height: 1.75rem;
122
+
123
+ svg {
124
+ width: 1rem;
125
+ height: 1rem;
126
+ }
127
+ }
128
+ }
129
+
130
+ .password-input-lg {
131
+ .password-input-field {
132
+ padding: 0.75rem 3rem 0.75rem 1rem;
133
+ font-size: var(--text-base);
134
+ }
135
+
136
+ .password-toggle {
137
+ width: 2.25rem;
138
+ height: 2.25rem;
139
+ right: 0.625rem;
140
+
141
+ svg {
142
+ width: 1.25rem;
143
+ height: 1.25rem;
144
+ }
145
+ }
146
+ }
147
+
148
+ // ----------------------------------------
149
+ // Password Strength Indicator
150
+ // ----------------------------------------
151
+ .password-strength {
152
+ display: flex;
153
+ gap: 0.25rem;
154
+ margin-top: 0.5rem;
155
+ }
156
+
157
+ .password-strength-bar {
158
+ flex: 1;
159
+ height: 4px;
160
+ background-color: var(--gray-200);
161
+ border-radius: 2px;
162
+ transition: background-color $transition-fast $transition-timing;
163
+ }
164
+
165
+ // Strength levels
166
+ .password-strength-weak .password-strength-bar:nth-child(1) {
167
+ background-color: var(--danger);
168
+ }
169
+
170
+ .password-strength-fair .password-strength-bar:nth-child(-n+2) {
171
+ background-color: var(--warning);
172
+ }
173
+
174
+ .password-strength-good .password-strength-bar:nth-child(-n+3) {
175
+ background-color: var(--info);
176
+ }
177
+
178
+ .password-strength-strong .password-strength-bar {
179
+ background-color: var(--success);
180
+ }
181
+
182
+ // ----------------------------------------
183
+ // Password Strength Text
184
+ // ----------------------------------------
185
+ .password-strength-text {
186
+ font-size: var(--text-xs);
187
+ margin-top: 0.375rem;
188
+ }
189
+
190
+ .password-strength-weak .password-strength-text {
191
+ color: var(--danger);
192
+ }
193
+
194
+ .password-strength-fair .password-strength-text {
195
+ color: var(--warning-700);
196
+ }
197
+
198
+ .password-strength-good .password-strength-text {
199
+ color: var(--info);
200
+ }
201
+
202
+ .password-strength-strong .password-strength-text {
203
+ color: var(--success);
204
+ }
205
+
206
+ // ----------------------------------------
207
+ // Password Requirements
208
+ // ----------------------------------------
209
+ .password-requirements {
210
+ margin-top: 0.75rem;
211
+ font-size: var(--text-xs);
212
+ }
213
+
214
+ .password-requirement {
215
+ display: flex;
216
+ align-items: center;
217
+ gap: 0.375rem;
218
+ margin-bottom: 0.25rem;
219
+ color: var(--text-muted);
220
+
221
+ svg {
222
+ width: 0.875rem;
223
+ height: 0.875rem;
224
+ flex-shrink: 0;
225
+ }
226
+ }
227
+
228
+ .password-requirement-met {
229
+ color: var(--success);
230
+
231
+ svg {
232
+ color: var(--success);
233
+ }
234
+ }
235
+
236
+ .password-requirement-unmet {
237
+ color: var(--text-muted);
238
+
239
+ svg {
240
+ color: var(--gray-400);
241
+ }
242
+ }
243
+
244
+ // ----------------------------------------
245
+ // Password Input States
246
+ // ----------------------------------------
247
+ .password-input-error {
248
+ .password-input-field {
249
+ border-color: var(--danger);
250
+
251
+ &:focus {
252
+ border-color: var(--danger);
253
+ box-shadow: 0 0 0 3px rgba($danger, 0.15);
254
+ }
255
+ }
256
+ }
257
+
258
+ .password-input-success {
259
+ .password-input-field {
260
+ border-color: var(--success);
261
+
262
+ &:focus {
263
+ border-color: var(--success);
264
+ box-shadow: 0 0 0 3px rgba($success, 0.15);
265
+ }
266
+ }
267
+ }
268
+
269
+ // ----------------------------------------
270
+ // Password Input with Icon
271
+ // ----------------------------------------
272
+ .password-input-icon {
273
+ .password-input-field {
274
+ padding-left: 2.5rem;
275
+ }
276
+ }
277
+
278
+ .password-icon-left {
279
+ position: absolute;
280
+ left: 0.75rem;
281
+ top: 50%;
282
+ transform: translateY(-50%);
283
+ color: var(--text-muted);
284
+ pointer-events: none;
285
+
286
+ svg {
287
+ width: 1rem;
288
+ height: 1rem;
289
+ }
290
+ }
291
+
292
+ // ----------------------------------------
293
+ // Password Confirm
294
+ // ----------------------------------------
295
+ .password-confirm-wrapper {
296
+ display: flex;
297
+ flex-direction: column;
298
+ gap: 1rem;
299
+ }
300
+
301
+ .password-match-indicator {
302
+ display: flex;
303
+ align-items: center;
304
+ gap: 0.375rem;
305
+ font-size: var(--text-xs);
306
+ margin-top: 0.25rem;
307
+ }
308
+
309
+ .password-match {
310
+ color: var(--success);
311
+ }
312
+
313
+ .password-mismatch {
314
+ color: var(--danger);
315
+ }
316
+
317
+ // ----------------------------------------
318
+ // Dark Mode
319
+ // ----------------------------------------
320
+ [data-theme="dark"] {
321
+ .password-input-field {
322
+ background-color: var(--gray-900);
323
+ border-color: var(--gray-700);
324
+ color: var(--gray-100);
325
+
326
+ &:focus {
327
+ border-color: var(--primary);
328
+ }
329
+ }
330
+
331
+ .password-toggle {
332
+ color: var(--gray-500);
333
+
334
+ &:hover {
335
+ color: var(--gray-300);
336
+ background-color: var(--gray-800);
337
+ }
338
+ }
339
+
340
+ .password-strength-bar {
341
+ background-color: var(--gray-700);
342
+ }
343
+ }
@@ -0,0 +1,329 @@
1
+ // ========================================
2
+ // ZenKit - QR Code Component
3
+ // ========================================
4
+
5
+ @use '../abstracts/variables' as *;
6
+
7
+ // ----------------------------------------
8
+ // QR Code Container
9
+ // ----------------------------------------
10
+ .qrcode {
11
+ display: inline-flex;
12
+ flex-direction: column;
13
+ align-items: center;
14
+ gap: 0.75rem;
15
+ }
16
+
17
+ .qrcode-canvas {
18
+ display: block;
19
+ border-radius: $border-radius;
20
+ }
21
+
22
+ // ----------------------------------------
23
+ // QR Code Wrapper
24
+ // ----------------------------------------
25
+ .qrcode-wrapper {
26
+ position: relative;
27
+ display: inline-block;
28
+ padding: 1rem;
29
+ background-color: var(--white);
30
+ border: 1px solid var(--border);
31
+ border-radius: $border-radius-lg;
32
+ }
33
+
34
+ // ----------------------------------------
35
+ // QR Code Sizes
36
+ // ----------------------------------------
37
+ .qrcode-sm .qrcode-canvas {
38
+ width: 100px;
39
+ height: 100px;
40
+ }
41
+
42
+ .qrcode-md .qrcode-canvas {
43
+ width: 150px;
44
+ height: 150px;
45
+ }
46
+
47
+ .qrcode-lg .qrcode-canvas {
48
+ width: 200px;
49
+ height: 200px;
50
+ }
51
+
52
+ .qrcode-xl .qrcode-canvas {
53
+ width: 256px;
54
+ height: 256px;
55
+ }
56
+
57
+ // ----------------------------------------
58
+ // QR Code with Logo
59
+ // ----------------------------------------
60
+ .qrcode-logo {
61
+ position: absolute;
62
+ top: 50%;
63
+ left: 50%;
64
+ transform: translate(-50%, -50%);
65
+ background-color: var(--white);
66
+ padding: 4px;
67
+ border-radius: $border-radius;
68
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
69
+
70
+ img {
71
+ display: block;
72
+ width: 32px;
73
+ height: 32px;
74
+ object-fit: contain;
75
+ }
76
+ }
77
+
78
+ .qrcode-lg .qrcode-logo img {
79
+ width: 40px;
80
+ height: 40px;
81
+ }
82
+
83
+ .qrcode-xl .qrcode-logo img {
84
+ width: 48px;
85
+ height: 48px;
86
+ }
87
+
88
+ // ----------------------------------------
89
+ // QR Code Label
90
+ // ----------------------------------------
91
+ .qrcode-label {
92
+ font-size: var(--text-sm);
93
+ color: var(--text-muted);
94
+ text-align: center;
95
+ max-width: 200px;
96
+ word-break: break-all;
97
+ }
98
+
99
+ // ----------------------------------------
100
+ // QR Code Actions
101
+ // ----------------------------------------
102
+ .qrcode-actions {
103
+ display: flex;
104
+ gap: 0.5rem;
105
+ margin-top: 0.5rem;
106
+ }
107
+
108
+ .qrcode-download,
109
+ .qrcode-copy {
110
+ display: inline-flex;
111
+ align-items: center;
112
+ justify-content: center;
113
+ gap: 0.375rem;
114
+ padding: 0.375rem 0.75rem;
115
+ font-size: var(--text-xs);
116
+ color: var(--text-muted);
117
+ background-color: var(--gray-100);
118
+ border: 1px solid var(--border);
119
+ border-radius: $border-radius;
120
+ cursor: pointer;
121
+ transition: all $transition-fast $transition-timing;
122
+
123
+ &:hover {
124
+ background-color: var(--gray-200);
125
+ color: var(--text);
126
+ }
127
+
128
+ svg {
129
+ width: 0.875rem;
130
+ height: 0.875rem;
131
+ }
132
+ }
133
+
134
+ // ----------------------------------------
135
+ // QR Code States
136
+ // ----------------------------------------
137
+ .qrcode-loading {
138
+ .qrcode-canvas {
139
+ opacity: 0.3;
140
+ }
141
+
142
+ &::after {
143
+ content: "";
144
+ position: absolute;
145
+ top: 50%;
146
+ left: 50%;
147
+ transform: translate(-50%, -50%);
148
+ width: 24px;
149
+ height: 24px;
150
+ border: 2px solid var(--primary);
151
+ border-top-color: transparent;
152
+ border-radius: 50%;
153
+ animation: spin 0.8s linear infinite;
154
+ }
155
+ }
156
+
157
+ .qrcode-expired {
158
+ .qrcode-canvas {
159
+ filter: blur(3px);
160
+ opacity: 0.5;
161
+ }
162
+ }
163
+
164
+ .qrcode-expired-overlay {
165
+ position: absolute;
166
+ top: 50%;
167
+ left: 50%;
168
+ transform: translate(-50%, -50%);
169
+ display: flex;
170
+ flex-direction: column;
171
+ align-items: center;
172
+ gap: 0.5rem;
173
+ color: var(--text);
174
+ font-size: var(--text-sm);
175
+ text-align: center;
176
+ }
177
+
178
+ .qrcode-refresh {
179
+ padding: 0.375rem 0.75rem;
180
+ font-size: var(--text-xs);
181
+ color: var(--primary);
182
+ background: transparent;
183
+ border: 1px solid var(--primary);
184
+ border-radius: $border-radius;
185
+ cursor: pointer;
186
+ transition: all $transition-fast $transition-timing;
187
+
188
+ &:hover {
189
+ background-color: var(--primary);
190
+ color: var(--white);
191
+ }
192
+ }
193
+
194
+ .qrcode-error {
195
+ .qrcode-canvas {
196
+ opacity: 0.3;
197
+ }
198
+ }
199
+
200
+ .qrcode-error-message {
201
+ color: var(--danger);
202
+ font-size: var(--text-sm);
203
+ }
204
+
205
+ // ----------------------------------------
206
+ // QR Code Variants
207
+ // ----------------------------------------
208
+
209
+ // Bordered
210
+ .qrcode-bordered .qrcode-wrapper {
211
+ border: 2px solid var(--gray-300);
212
+ }
213
+
214
+ // Shadow
215
+ .qrcode-shadow .qrcode-wrapper {
216
+ border: none;
217
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
218
+ }
219
+
220
+ // Rounded
221
+ .qrcode-rounded .qrcode-wrapper {
222
+ border-radius: $border-radius-xl;
223
+ }
224
+
225
+ .qrcode-rounded .qrcode-canvas {
226
+ border-radius: $border-radius;
227
+ }
228
+
229
+ // ----------------------------------------
230
+ // QR Code Colors
231
+ // ----------------------------------------
232
+ .qrcode-primary .qrcode-wrapper {
233
+ border-color: var(--primary);
234
+ }
235
+
236
+ .qrcode-success .qrcode-wrapper {
237
+ border-color: var(--success);
238
+ }
239
+
240
+ .qrcode-warning .qrcode-wrapper {
241
+ border-color: var(--warning);
242
+ }
243
+
244
+ .qrcode-danger .qrcode-wrapper {
245
+ border-color: var(--danger);
246
+ }
247
+
248
+ // ----------------------------------------
249
+ // QR Code Card
250
+ // ----------------------------------------
251
+ .qrcode-card {
252
+ padding: 1.5rem;
253
+ background-color: var(--bg);
254
+ border: 1px solid var(--border);
255
+ border-radius: $border-radius-lg;
256
+ text-align: center;
257
+ }
258
+
259
+ .qrcode-card-title {
260
+ font-size: var(--text-lg);
261
+ font-weight: $font-weight-semibold;
262
+ margin-bottom: 0.5rem;
263
+ }
264
+
265
+ .qrcode-card-description {
266
+ font-size: var(--text-sm);
267
+ color: var(--text-muted);
268
+ margin-bottom: 1rem;
269
+ }
270
+
271
+ // ----------------------------------------
272
+ // Scan Animation
273
+ // ----------------------------------------
274
+ .qrcode-scan-line {
275
+ position: absolute;
276
+ left: 1rem;
277
+ right: 1rem;
278
+ height: 2px;
279
+ background: linear-gradient(90deg, transparent, var(--primary), transparent);
280
+ animation: qrcode-scan 2s ease-in-out infinite;
281
+ }
282
+
283
+ @keyframes qrcode-scan {
284
+ 0%, 100% {
285
+ top: 1rem;
286
+ opacity: 0;
287
+ }
288
+ 10% {
289
+ opacity: 1;
290
+ }
291
+ 90% {
292
+ opacity: 1;
293
+ }
294
+ 100% {
295
+ top: calc(100% - 1rem);
296
+ opacity: 0;
297
+ }
298
+ }
299
+
300
+ // ----------------------------------------
301
+ // Dark Mode
302
+ // ----------------------------------------
303
+ [data-theme="dark"] {
304
+ .qrcode-wrapper {
305
+ background-color: var(--white);
306
+ border-color: var(--gray-600);
307
+ }
308
+
309
+ .qrcode-logo {
310
+ background-color: var(--white);
311
+ }
312
+
313
+ .qrcode-download,
314
+ .qrcode-copy {
315
+ background-color: var(--gray-800);
316
+ border-color: var(--gray-600);
317
+ color: var(--gray-300);
318
+
319
+ &:hover {
320
+ background-color: var(--gray-700);
321
+ color: var(--gray-100);
322
+ }
323
+ }
324
+
325
+ .qrcode-card {
326
+ background-color: var(--gray-800);
327
+ border-color: var(--gray-700);
328
+ }
329
+ }