zero-query 0.9.7 → 0.9.9

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 (72) hide show
  1. package/README.md +55 -4
  2. package/cli/commands/build.js +50 -3
  3. package/cli/commands/create.js +58 -11
  4. package/cli/help.js +4 -0
  5. package/cli/scaffold/default/app/app.js +211 -0
  6. package/cli/scaffold/default/app/components/about.js +201 -0
  7. package/cli/scaffold/default/app/components/api-demo.js +143 -0
  8. package/cli/scaffold/default/app/components/contact-card.js +231 -0
  9. package/cli/scaffold/default/app/components/contacts/contacts.css +706 -0
  10. package/cli/scaffold/default/app/components/contacts/contacts.html +200 -0
  11. package/cli/scaffold/default/app/components/contacts/contacts.js +196 -0
  12. package/cli/scaffold/default/app/components/counter.js +127 -0
  13. package/cli/scaffold/default/app/components/home.js +249 -0
  14. package/cli/scaffold/{app → default/app}/components/not-found.js +2 -2
  15. package/cli/scaffold/default/app/components/playground/playground.css +116 -0
  16. package/cli/scaffold/default/app/components/playground/playground.html +162 -0
  17. package/cli/scaffold/default/app/components/playground/playground.js +117 -0
  18. package/cli/scaffold/default/app/components/todos.js +225 -0
  19. package/cli/scaffold/default/app/components/toolkit/toolkit.css +97 -0
  20. package/cli/scaffold/default/app/components/toolkit/toolkit.html +146 -0
  21. package/cli/scaffold/default/app/components/toolkit/toolkit.js +280 -0
  22. package/cli/scaffold/default/app/routes.js +15 -0
  23. package/cli/scaffold/{app → default/app}/store.js +15 -10
  24. package/cli/scaffold/{global.css → default/global.css} +238 -252
  25. package/cli/scaffold/{index.html → default/index.html} +35 -0
  26. package/cli/scaffold/{app → minimal/app}/app.js +37 -39
  27. package/cli/scaffold/minimal/app/components/about.js +68 -0
  28. package/cli/scaffold/minimal/app/components/counter.js +122 -0
  29. package/cli/scaffold/minimal/app/components/home.js +68 -0
  30. package/cli/scaffold/minimal/app/components/not-found.js +16 -0
  31. package/cli/scaffold/minimal/app/routes.js +9 -0
  32. package/cli/scaffold/minimal/app/store.js +36 -0
  33. package/cli/scaffold/minimal/assets/.gitkeep +0 -0
  34. package/cli/scaffold/minimal/global.css +291 -0
  35. package/cli/scaffold/minimal/index.html +44 -0
  36. package/cli/scaffold/ssr/app/app.js +30 -0
  37. package/cli/scaffold/ssr/app/components/about.js +28 -0
  38. package/cli/scaffold/ssr/app/components/home.js +37 -0
  39. package/cli/scaffold/ssr/app/components/not-found.js +15 -0
  40. package/cli/scaffold/ssr/app/routes.js +6 -0
  41. package/cli/scaffold/ssr/global.css +113 -0
  42. package/cli/scaffold/ssr/index.html +31 -0
  43. package/cli/scaffold/ssr/package.json +8 -0
  44. package/cli/scaffold/ssr/server/index.js +118 -0
  45. package/dist/zquery.dist.zip +0 -0
  46. package/dist/zquery.js +2006 -1933
  47. package/dist/zquery.min.js +2 -2
  48. package/index.d.ts +20 -1
  49. package/index.js +8 -5
  50. package/package.json +8 -2
  51. package/src/component.js +6 -3
  52. package/src/diff.js +15 -2
  53. package/src/errors.js +59 -5
  54. package/src/package.json +1 -0
  55. package/src/ssr.js +116 -22
  56. package/tests/cli.test.js +304 -0
  57. package/tests/errors.test.js +423 -145
  58. package/tests/ssr.test.js +435 -3
  59. package/types/errors.d.ts +34 -2
  60. package/types/ssr.d.ts +21 -1
  61. package/cli/scaffold/app/components/about.js +0 -131
  62. package/cli/scaffold/app/components/api-demo.js +0 -103
  63. package/cli/scaffold/app/components/contacts/contacts.css +0 -246
  64. package/cli/scaffold/app/components/contacts/contacts.html +0 -140
  65. package/cli/scaffold/app/components/contacts/contacts.js +0 -153
  66. package/cli/scaffold/app/components/counter.js +0 -85
  67. package/cli/scaffold/app/components/home.js +0 -137
  68. package/cli/scaffold/app/components/todos.js +0 -131
  69. package/cli/scaffold/app/routes.js +0 -13
  70. /package/cli/scaffold/{LICENSE → default/LICENSE} +0 -0
  71. /package/cli/scaffold/{assets → default/assets}/.gitkeep +0 -0
  72. /package/cli/scaffold/{favicon.ico → default/favicon.ico} +0 -0
@@ -0,0 +1,706 @@
1
+ /* contacts.css — scoped styles for contacts-page component
2
+ *
3
+ * Loaded via styleUrl — these styles are automatically scoped
4
+ * to the contacts-page component by zQuery.
5
+ */
6
+
7
+ /* ── Toolbar ── */
8
+ .ct-bar {
9
+ display: flex;
10
+ align-items: center;
11
+ justify-content: space-between;
12
+ gap: 0.75rem;
13
+ flex-wrap: wrap;
14
+ margin-bottom: 1rem;
15
+ }
16
+
17
+ .ct-bar-left {
18
+ display: flex;
19
+ align-items: center;
20
+ gap: 0.75rem;
21
+ }
22
+
23
+ .ct-bar-right {
24
+ display: flex;
25
+ align-items: center;
26
+ gap: 0.5rem;
27
+ }
28
+
29
+ .ct-badges {
30
+ display: flex;
31
+ gap: 0.4rem;
32
+ }
33
+
34
+ .ct-badge {
35
+ display: inline-flex;
36
+ align-items: center;
37
+ gap: 0.25rem;
38
+ padding: 0.2rem 0.55rem;
39
+ border-radius: 999px;
40
+ font-size: 0.75rem;
41
+ color: var(--text-muted);
42
+ background: var(--bg-hover);
43
+ border: 1px solid var(--border);
44
+ }
45
+
46
+ .ct-badge strong {
47
+ color: var(--text);
48
+ font-variant-numeric: tabular-nums;
49
+ }
50
+
51
+ .ct-badge-accent {
52
+ border-color: rgba(88, 166, 255, 0.2);
53
+ background: rgba(88, 166, 255, 0.06);
54
+ }
55
+
56
+ .ct-badge-accent strong {
57
+ color: var(--accent);
58
+ }
59
+
60
+ .ct-search {
61
+ padding: 0.4rem 0.75rem;
62
+ font-size: 0.82rem;
63
+ background: var(--bg-surface);
64
+ border: 1px solid var(--border);
65
+ border-radius: var(--radius);
66
+ color: var(--text);
67
+ outline: none;
68
+ width: 160px;
69
+ font-family: inherit;
70
+ transition: border-color 0.15s ease, box-shadow 0.15s ease;
71
+ }
72
+
73
+ .ct-search:focus {
74
+ border-color: var(--accent);
75
+ box-shadow: 0 0 0 2px rgba(88, 166, 255, 0.1);
76
+ }
77
+
78
+ /* ── Filter chips ── */
79
+ .ct-chips {
80
+ display: flex;
81
+ gap: 0.35rem;
82
+ margin-bottom: 1rem;
83
+ flex-wrap: wrap;
84
+ }
85
+
86
+ .ct-chip {
87
+ padding: 0.25rem 0.7rem;
88
+ font-size: 0.75rem;
89
+ font-weight: 500;
90
+ border-radius: 999px;
91
+ border: 1px solid var(--border);
92
+ background: transparent;
93
+ color: var(--text-muted);
94
+ cursor: pointer;
95
+ font-family: inherit;
96
+ transition: all 0.12s ease;
97
+ }
98
+
99
+ .ct-chip:hover {
100
+ border-color: var(--accent);
101
+ color: var(--text);
102
+ }
103
+
104
+ .ct-chip.active {
105
+ background: var(--accent-soft);
106
+ border-color: var(--accent);
107
+ color: var(--accent);
108
+ font-weight: 600;
109
+ }
110
+
111
+ /* ── Buttons ── */
112
+ .ct-btn {
113
+ display: inline-flex;
114
+ align-items: center;
115
+ gap: 0.3rem;
116
+ padding: 0.45rem 1rem;
117
+ font-size: 0.82rem;
118
+ font-weight: 500;
119
+ font-family: inherit;
120
+ border: none;
121
+ border-radius: var(--radius);
122
+ cursor: pointer;
123
+ transition: all 0.12s ease;
124
+ }
125
+
126
+ .ct-btn:active { transform: scale(0.97); }
127
+
128
+ .ct-btn-accent {
129
+ background: var(--accent);
130
+ color: #fff;
131
+ }
132
+
133
+ .ct-btn-accent:hover {
134
+ background: var(--accent-hover);
135
+ box-shadow: 0 0 16px rgba(88, 166, 255, 0.15);
136
+ }
137
+
138
+ .ct-btn-add {
139
+ white-space: nowrap;
140
+ flex-shrink: 0;
141
+ }
142
+
143
+ .ct-btn-ghost {
144
+ background: transparent;
145
+ color: var(--text-muted);
146
+ border: 1px solid var(--border);
147
+ }
148
+
149
+ .ct-btn-ghost:hover {
150
+ color: var(--text);
151
+ border-color: var(--text-muted);
152
+ background: var(--bg-hover);
153
+ }
154
+
155
+ .ct-btn-danger {
156
+ background: var(--danger);
157
+ color: #fff;
158
+ }
159
+
160
+ .ct-btn-danger:hover {
161
+ opacity: 0.85;
162
+ }
163
+
164
+ .ct-btn-sm {
165
+ padding: 0.3rem 0.7rem;
166
+ font-size: 0.78rem;
167
+ }
168
+
169
+ /* ── Contact Grid ── */
170
+ .ct-grid {
171
+ display: grid;
172
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
173
+ gap: 0.85rem;
174
+ }
175
+
176
+ .ct-card {
177
+ position: relative;
178
+ display: flex;
179
+ flex-direction: column;
180
+ align-items: center;
181
+ text-align: center;
182
+ padding: 1.5rem 1rem 1.15rem;
183
+ background: var(--bg-card);
184
+ border: 1px solid var(--border);
185
+ border-radius: var(--radius-lg);
186
+ cursor: pointer;
187
+ transition: all 0.18s ease;
188
+ overflow: hidden;
189
+ backdrop-filter: blur(8px);
190
+ -webkit-backdrop-filter: blur(8px);
191
+ }
192
+
193
+ .ct-card:hover {
194
+ border-color: rgba(88, 166, 255, 0.25);
195
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18), 0 0 0 1px rgba(88, 166, 255, 0.06);
196
+ transform: translateY(-2px);
197
+ }
198
+
199
+ .ct-card-fav {
200
+ border-color: rgba(88, 166, 255, 0.15);
201
+ }
202
+
203
+ /* Status bar at top */
204
+ .ct-card-status {
205
+ position: absolute;
206
+ top: 0;
207
+ left: 0;
208
+ right: 0;
209
+ height: 3px;
210
+ background: var(--text-muted);
211
+ opacity: 0.3;
212
+ transition: background 0.3s ease, box-shadow 0.3s ease, opacity 0.3s ease;
213
+ }
214
+
215
+ .ct-card-status-online {
216
+ background: var(--success);
217
+ opacity: 1;
218
+ box-shadow: 0 0 8px rgba(63, 185, 80, 0.4);
219
+ }
220
+
221
+ .ct-card-status-away {
222
+ background: var(--warning);
223
+ opacity: 0.8;
224
+ }
225
+
226
+ .ct-card-status-offline {
227
+ background: var(--text-muted);
228
+ opacity: 0.2;
229
+ }
230
+
231
+ /* Card avatar */
232
+ .ct-card-avatar {
233
+ width: 52px;
234
+ height: 52px;
235
+ border-radius: 50%;
236
+ display: flex;
237
+ align-items: center;
238
+ justify-content: center;
239
+ font-weight: 700;
240
+ font-size: 1.15rem;
241
+ color: #fff;
242
+ text-transform: uppercase;
243
+ margin-bottom: 0.65rem;
244
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
245
+ }
246
+
247
+ /* Card text */
248
+ .ct-card-info {
249
+ display: contents;
250
+ }
251
+
252
+ .ct-card-name {
253
+ font-size: 0.9rem;
254
+ font-weight: 600;
255
+ margin-bottom: 0.1rem;
256
+ white-space: nowrap;
257
+ overflow: hidden;
258
+ text-overflow: ellipsis;
259
+ max-width: 100%;
260
+ }
261
+
262
+ .ct-card-email {
263
+ font-size: 0.75rem;
264
+ color: var(--text-muted);
265
+ margin-bottom: 0.6rem;
266
+ white-space: nowrap;
267
+ overflow: hidden;
268
+ text-overflow: ellipsis;
269
+ max-width: 100%;
270
+ }
271
+
272
+ .ct-card-role {
273
+ font-size: 0.68rem;
274
+ font-weight: 600;
275
+ padding: 0.18rem 0.55rem;
276
+ border-radius: 999px;
277
+ text-transform: uppercase;
278
+ letter-spacing: 0.04em;
279
+ }
280
+
281
+ /* Role colors */
282
+ .ct-role-developer { background: rgba(96, 165, 250, 0.12); color: #60a5fa; }
283
+ .ct-role-designer { background: rgba(168, 85, 247, 0.12); color: #a855f7; }
284
+ .ct-role-manager { background: rgba(52, 211, 153, 0.12); color: #34d399; }
285
+ .ct-role-qa { background: rgba(251, 191, 36, 0.12); color: #fbbf24; }
286
+
287
+ /* Fav button on card */
288
+ .ct-card-fav-btn {
289
+ position: absolute;
290
+ top: 0.55rem;
291
+ right: 0.55rem;
292
+ background: none;
293
+ border: none;
294
+ font-size: 1rem;
295
+ cursor: pointer;
296
+ color: var(--text-muted);
297
+ opacity: 0;
298
+ transition: all 0.12s ease;
299
+ line-height: 1;
300
+ padding: 0.15rem;
301
+ }
302
+
303
+ .ct-card:hover .ct-card-fav-btn {
304
+ opacity: 0.6;
305
+ }
306
+
307
+ .ct-card-fav-btn:hover {
308
+ opacity: 1 !important;
309
+ transform: scale(1.2);
310
+ }
311
+
312
+ .ct-card-fav-btn.is-fav {
313
+ color: var(--accent);
314
+ opacity: 1;
315
+ }
316
+
317
+ /* ── Empty ── */
318
+ .ct-empty-card {
319
+ text-align: center;
320
+ padding: 3rem 1rem;
321
+ color: var(--text-muted);
322
+ }
323
+
324
+ .ct-empty-icon {
325
+ margin-bottom: 0.75rem;
326
+ }
327
+
328
+ .ct-empty-card p {
329
+ font-size: 0.9rem;
330
+ }
331
+
332
+ /* ═══ Modal (shared) ═══ */
333
+ .ct-overlay {
334
+ position: fixed;
335
+ inset: 0;
336
+ background: rgba(0, 0, 0, 0.55);
337
+ backdrop-filter: blur(4px);
338
+ -webkit-backdrop-filter: blur(4px);
339
+ z-index: 200;
340
+ display: flex;
341
+ align-items: center;
342
+ justify-content: center;
343
+ animation: ct-fade-in 0.15s ease;
344
+ }
345
+
346
+ @keyframes ct-fade-in {
347
+ from { opacity: 0; }
348
+ to { opacity: 1; }
349
+ }
350
+
351
+ .ct-modal {
352
+ position: relative;
353
+ width: 420px;
354
+ max-width: calc(100vw - 2rem);
355
+ max-height: calc(100vh - 4rem);
356
+ overflow-y: auto;
357
+ background: var(--bg-surface);
358
+ border: 1px solid var(--border);
359
+ border-radius: var(--radius-lg);
360
+ box-shadow: 0 24px 64px rgba(0, 0, 0, 0.35);
361
+ animation: ct-modal-in 0.2s var(--ease-out);
362
+ }
363
+
364
+ .ct-modal-form {
365
+ width: 480px;
366
+ }
367
+
368
+ @keyframes ct-modal-in {
369
+ from { opacity: 0; transform: scale(0.95) translateY(10px); }
370
+ to { opacity: 1; transform: scale(1) translateY(0); }
371
+ }
372
+
373
+ .ct-modal-strip {
374
+ height: 4px;
375
+ border-radius: var(--radius-lg) var(--radius-lg) 0 0;
376
+ transition: background 0.3s ease, box-shadow 0.3s ease, opacity 0.3s ease;
377
+ }
378
+
379
+ .ct-modal-strip-online { background: var(--success); box-shadow: 0 0 12px rgba(63, 185, 80, 0.3); }
380
+ .ct-modal-strip-away { background: var(--warning); }
381
+ .ct-modal-strip-offline { background: var(--text-muted); opacity: 0.3; }
382
+ .ct-modal-strip-accent { background: var(--accent); box-shadow: 0 0 12px rgba(88, 166, 255, 0.2); }
383
+
384
+ .ct-modal-close {
385
+ position: absolute;
386
+ top: 0.75rem;
387
+ right: 0.75rem;
388
+ width: 28px;
389
+ height: 28px;
390
+ border-radius: 50%;
391
+ border: none;
392
+ background: var(--bg-hover);
393
+ color: var(--text-muted);
394
+ font-size: 0.85rem;
395
+ cursor: pointer;
396
+ display: flex;
397
+ align-items: center;
398
+ justify-content: center;
399
+ transition: all 0.12s ease;
400
+ z-index: 1;
401
+ }
402
+
403
+ .ct-modal-close:hover {
404
+ background: var(--danger);
405
+ color: #fff;
406
+ }
407
+
408
+ /* ── Add-contact modal heading ── */
409
+ .ct-modal-heading {
410
+ padding: 1.25rem 1.5rem 0;
411
+ }
412
+
413
+ .ct-modal-heading h2 {
414
+ font-size: 1.1rem;
415
+ font-weight: 700;
416
+ margin: 0 0 0.2rem;
417
+ }
418
+
419
+ .ct-modal-heading .muted {
420
+ font-size: 0.82rem;
421
+ color: var(--text-muted);
422
+ }
423
+
424
+ /* ── Form inside modal ── */
425
+ .ct-form {
426
+ display: flex;
427
+ flex-direction: column;
428
+ gap: 0.85rem;
429
+ padding: 1rem 1.5rem 1.25rem;
430
+ }
431
+
432
+ .ct-form-row {
433
+ display: flex;
434
+ gap: 0.75rem;
435
+ }
436
+
437
+ .ct-form-grow {
438
+ flex: 1;
439
+ }
440
+
441
+ .ct-form-field {
442
+ display: flex;
443
+ flex-direction: column;
444
+ gap: 0.3rem;
445
+ position: relative;
446
+ }
447
+
448
+ .ct-form-field label {
449
+ font-size: 0.75rem;
450
+ font-weight: 600;
451
+ color: var(--text-muted);
452
+ text-transform: uppercase;
453
+ letter-spacing: 0.04em;
454
+ }
455
+
456
+ .ct-req { color: var(--danger); }
457
+ .ct-opt { font-weight: 400; text-transform: none; font-size: 0.7rem; letter-spacing: 0; opacity: 0.6; }
458
+
459
+ .ct-input {
460
+ padding: 0.5rem 0.75rem;
461
+ font-size: 0.85rem;
462
+ background: var(--bg);
463
+ border: 1px solid var(--border);
464
+ border-radius: var(--radius);
465
+ color: var(--text);
466
+ font-family: inherit;
467
+ outline: none;
468
+ transition: border-color 0.15s ease, box-shadow 0.15s ease;
469
+ }
470
+
471
+ .ct-input:focus {
472
+ border-color: var(--accent);
473
+ box-shadow: 0 0 0 2px rgba(88, 166, 255, 0.1);
474
+ }
475
+
476
+ .ct-err {
477
+ color: var(--danger);
478
+ font-size: 0.72rem;
479
+ position: absolute;
480
+ bottom: -0.95rem;
481
+ left: 0;
482
+ }
483
+
484
+ .ct-form-actions {
485
+ display: flex;
486
+ gap: 0.5rem;
487
+ justify-content: flex-end;
488
+ padding-top: 0.35rem;
489
+ }
490
+
491
+ /* ── Detail modal: profile ── */
492
+ .ct-modal-profile {
493
+ display: flex;
494
+ flex-direction: column;
495
+ align-items: center;
496
+ padding: 1.75rem 1.5rem 1rem;
497
+ position: relative;
498
+ }
499
+
500
+ .ct-modal-avatar {
501
+ width: 72px;
502
+ height: 72px;
503
+ border-radius: 50%;
504
+ display: flex;
505
+ align-items: center;
506
+ justify-content: center;
507
+ font-weight: 700;
508
+ font-size: 1.6rem;
509
+ color: #fff;
510
+ text-transform: uppercase;
511
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
512
+ margin-bottom: 0.75rem;
513
+ position: relative;
514
+ }
515
+
516
+ .ct-modal-status-dot {
517
+ width: 14px;
518
+ height: 14px;
519
+ border-radius: 50%;
520
+ border: 3px solid var(--bg-surface);
521
+ position: absolute;
522
+ top: calc(1.75rem + 56px);
523
+ left: calc(50% + 22px);
524
+ transition: background 0.3s ease, box-shadow 0.3s ease;
525
+ }
526
+
527
+ .ct-dot-online { background: var(--success); box-shadow: 0 0 8px rgba(63, 185, 80, 0.5); }
528
+ .ct-dot-away { background: var(--warning); }
529
+ .ct-dot-offline { background: var(--text-muted); }
530
+
531
+ .ct-modal-profile h2 {
532
+ font-size: 1.2rem;
533
+ font-weight: 700;
534
+ margin: 0 0 0.25rem;
535
+ }
536
+
537
+ .ct-modal-role {
538
+ font-size: 0.72rem;
539
+ font-weight: 600;
540
+ padding: 0.2rem 0.6rem;
541
+ border-radius: 999px;
542
+ text-transform: uppercase;
543
+ letter-spacing: 0.04em;
544
+ }
545
+
546
+ /* Detail fields */
547
+ .ct-modal-details {
548
+ display: grid;
549
+ grid-template-columns: 1fr 1fr;
550
+ gap: 0.75rem;
551
+ padding: 0 1.5rem;
552
+ margin-top: 0.5rem;
553
+ }
554
+
555
+ .ct-modal-field {
556
+ display: flex;
557
+ flex-direction: column;
558
+ gap: 0.15rem;
559
+ }
560
+
561
+ .ct-modal-label {
562
+ font-size: 0.68rem;
563
+ font-weight: 600;
564
+ text-transform: uppercase;
565
+ letter-spacing: 0.04em;
566
+ color: var(--text-muted);
567
+ }
568
+
569
+ .ct-modal-value {
570
+ font-size: 0.85rem;
571
+ color: var(--text);
572
+ word-break: break-word;
573
+ }
574
+
575
+ .ct-modal-status-text {
576
+ text-transform: capitalize;
577
+ transition: color 0.3s ease;
578
+ }
579
+
580
+ .ct-modal-bio {
581
+ padding: 0.75rem 1.5rem 0;
582
+ }
583
+
584
+ .ct-modal-bio p {
585
+ font-size: 0.85rem;
586
+ color: var(--text-muted);
587
+ line-height: 1.5;
588
+ margin-top: 0.2rem;
589
+ }
590
+
591
+ /* Modal actions */
592
+ .ct-modal-actions {
593
+ display: flex;
594
+ gap: 0.4rem;
595
+ padding: 1rem 1.5rem 1.25rem;
596
+ flex-wrap: wrap;
597
+ }
598
+
599
+ .ct-confirm-group {
600
+ display: inline-flex;
601
+ align-items: center;
602
+ gap: 0.3rem;
603
+ }
604
+
605
+ .ct-confirm-text {
606
+ font-size: 0.78rem;
607
+ color: var(--danger);
608
+ font-weight: 500;
609
+ }
610
+
611
+ /* ── Responsive ── */
612
+ @media (max-width: 768px) {
613
+ .ct-bar {
614
+ flex-direction: column;
615
+ align-items: stretch;
616
+ }
617
+
618
+ .ct-bar-left,
619
+ .ct-bar-right {
620
+ justify-content: space-between;
621
+ }
622
+
623
+ .ct-search {
624
+ flex: 1;
625
+ }
626
+
627
+ .ct-form-row {
628
+ flex-direction: column;
629
+ }
630
+
631
+ .ct-grid {
632
+ grid-template-columns: 1fr;
633
+ gap: 0.5rem;
634
+ }
635
+
636
+ /* Compact horizontal card layout */
637
+ .ct-card {
638
+ flex-direction: row;
639
+ align-items: center;
640
+ text-align: left;
641
+ padding: 0.75rem 1rem;
642
+ gap: 0.75rem;
643
+ }
644
+
645
+ .ct-card:hover {
646
+ transform: none;
647
+ }
648
+
649
+ .ct-card-status {
650
+ top: 0;
651
+ bottom: 0;
652
+ left: 0;
653
+ right: auto;
654
+ width: 3px;
655
+ height: auto;
656
+ }
657
+
658
+ .ct-card-avatar {
659
+ width: 40px;
660
+ height: 40px;
661
+ font-size: 0.95rem;
662
+ margin-bottom: 0;
663
+ flex-shrink: 0;
664
+ }
665
+
666
+ .ct-card-info {
667
+ display: flex;
668
+ flex-direction: column;
669
+ align-items: flex-start;
670
+ min-width: 0;
671
+ flex: 1;
672
+ }
673
+
674
+ .ct-card-name {
675
+ font-size: 0.88rem;
676
+ margin-bottom: 0;
677
+ }
678
+
679
+ .ct-card-email {
680
+ margin-bottom: 0.25rem;
681
+ }
682
+
683
+ .ct-card-fav-btn {
684
+ position: static;
685
+ opacity: 1;
686
+ flex-shrink: 0;
687
+ margin-left: auto;
688
+ }
689
+
690
+ .ct-modal,
691
+ .ct-modal-form {
692
+ width: calc(100vw - 1.5rem);
693
+ }
694
+
695
+ .ct-modal-details {
696
+ grid-template-columns: 1fr;
697
+ }
698
+ }
699
+
700
+ @media (max-width: 480px) {
701
+ .ct-card-avatar {
702
+ width: 36px;
703
+ height: 36px;
704
+ font-size: 0.85rem;
705
+ }
706
+ }