@thl-ui/styles 0.0.0-stage → 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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +42 -2
  3. package/dist/components/alert.css +1 -0
  4. package/dist/components/app.css +1 -0
  5. package/dist/components/avatar.css +1 -0
  6. package/dist/components/badge.css +1 -0
  7. package/dist/components/button.css +1 -0
  8. package/dist/components/card.css +1 -0
  9. package/dist/components/form.css +1 -0
  10. package/dist/components/nav.css +1 -0
  11. package/dist/components/overlay.css +1 -0
  12. package/dist/components/pages.css +1 -0
  13. package/dist/components/progress.css +1 -0
  14. package/dist/components/ribbon.css +1 -0
  15. package/dist/components/table.css +1 -0
  16. package/dist/components/widgets.css +1 -0
  17. package/dist/fonts/OFL.txt +93 -0
  18. package/dist/fonts/open-sans-cyrillic-ext-wght-normal.woff2 +0 -0
  19. package/dist/fonts/open-sans-cyrillic-wght-normal.woff2 +0 -0
  20. package/dist/fonts/open-sans-greek-ext-wght-normal.woff2 +0 -0
  21. package/dist/fonts/open-sans-greek-wght-normal.woff2 +0 -0
  22. package/dist/fonts/open-sans-latin-ext-wght-normal.woff2 +0 -0
  23. package/dist/fonts/open-sans-latin-wght-normal.woff2 +0 -0
  24. package/dist/fonts/open-sans-vietnamese-wght-normal.woff2 +0 -0
  25. package/dist/fonts.css +70 -0
  26. package/dist/thl-ui.css +447 -0
  27. package/dist/tokens.css +376 -0
  28. package/package.json +48 -4
  29. package/src/_base.scss +408 -0
  30. package/src/_mixins.scss +53 -0
  31. package/src/components/_alert.scss +183 -0
  32. package/src/components/_avatar.scss +75 -0
  33. package/src/components/_badge.scss +112 -0
  34. package/src/components/_button.scss +242 -0
  35. package/src/components/_card.scss +211 -0
  36. package/src/components/_form.scss +959 -0
  37. package/src/components/_nav.scss +738 -0
  38. package/src/components/_overlay.scss +382 -0
  39. package/src/components/_progress.scss +103 -0
  40. package/src/components/_ribbon.scss +136 -0
  41. package/src/components/_table.scss +215 -0
  42. package/src/components/_widgets.scss +1050 -0
  43. package/src/index.scss +16 -0
  44. package/src/layout/_app.scss +804 -0
  45. package/src/pages/_pages.scss +691 -0
@@ -0,0 +1,1050 @@
1
+ @use '../mixins' as *;
2
+
3
+ /* info-box */
4
+ .#{$p}-info-box {
5
+ --_c: #{v(theme)};
6
+ --_on: #{v(on-theme)};
7
+ --_t: #{v(theme-text)};
8
+ display: flex;
9
+ gap: 20px;
10
+ align-items: flex-start;
11
+ background: v(surface);
12
+ padding: 30px 25px;
13
+ border: 1px solid v(border-color);
14
+ border-radius: v(radius);
15
+ height: 100%;
16
+ /* the box is a size container so icon and value can shrink when four boxes share a narrow row */
17
+ container-type: inline-size;
18
+ @each $c in $colors {
19
+ &--#{$c} {
20
+ --_c: #{v(color-#{$c})};
21
+ --_on: #{on($c)};
22
+ --_t: #{tx($c)};
23
+ }
24
+ }
25
+ &__icon {
26
+ width: 60px;
27
+ height: 60px;
28
+ flex-shrink: 0;
29
+ border-radius: 50%;
30
+ display: inline-flex;
31
+ align-items: center;
32
+ justify-content: center;
33
+ font-size: 26px;
34
+ color: var(--_on);
35
+ background: var(--_c);
36
+ }
37
+ &__body {
38
+ flex: 1;
39
+ min-width: 0;
40
+ }
41
+ &__value {
42
+ font-size: 30px !important;
43
+ line-height: 1.1 !important;
44
+ margin: 0 0 4px !important;
45
+ color: var(--_t) !important;
46
+ font-weight: 400;
47
+ }
48
+ &__title {
49
+ font-size: 12px;
50
+ text-transform: uppercase;
51
+ color: v(text);
52
+ margin: 0;
53
+ letter-spacing: 0.03em;
54
+ }
55
+ &__line {
56
+ display: block;
57
+ height: 1px;
58
+ background: v(border-color);
59
+ margin: 12px 0;
60
+ }
61
+ &__foot {
62
+ display: flex;
63
+ flex-wrap: wrap;
64
+ justify-content: space-between;
65
+ align-items: center;
66
+ gap: 4px 8px;
67
+ font-size: 14px;
68
+ color: v(text-strong);
69
+ margin: 0;
70
+ }
71
+ @container (max-width: 230px) {
72
+ &__icon {
73
+ width: 44px;
74
+ height: 44px;
75
+ font-size: 20px;
76
+ }
77
+ &__value {
78
+ font-size: 24px !important;
79
+ }
80
+ }
81
+ &--filled {
82
+ background: var(--_c);
83
+ border-color: var(--_c);
84
+ color: var(--_on);
85
+ .#{$p}-info-box__icon {
86
+ background: rgba(255, 255, 255, 0.2);
87
+ }
88
+ .#{$p}-info-box__value,
89
+ .#{$p}-info-box__title,
90
+ .#{$p}-info-box__foot {
91
+ color: var(--_on) !important;
92
+ }
93
+ .#{$p}-info-box__line {
94
+ background: rgba(255, 255, 255, 0.3);
95
+ }
96
+ }
97
+ &--soft .#{$p}-info-box__icon {
98
+ background: color-mix(in srgb, var(--_c) 15%, transparent);
99
+ color: var(--_t);
100
+ }
101
+ }
102
+ /* stat-widget with progress (index2–4) */
103
+ .#{$p}-stat {
104
+ --_c: #{v(theme)};
105
+ --_t: #{v(theme-text)};
106
+ background: v(surface);
107
+ border: 1px solid v(border-color);
108
+ border-radius: v(radius);
109
+ padding: 25px;
110
+ height: 100%;
111
+ @each $c in $colors {
112
+ &--#{$c} {
113
+ --_c: #{v(color-#{$c})};
114
+ --_t: #{tx($c)};
115
+ }
116
+ }
117
+ &__head {
118
+ display: flex;
119
+ justify-content: space-between;
120
+ align-items: center;
121
+ gap: 10px;
122
+ }
123
+ &__title {
124
+ margin: 0 !important;
125
+ font-size: 14px !important;
126
+ line-height: 22px !important;
127
+ text-transform: uppercase;
128
+ font-weight: 600;
129
+ color: v(heading);
130
+ letter-spacing: 0.03em;
131
+ }
132
+ &__icon {
133
+ font-size: 30px;
134
+ color: var(--_t);
135
+ }
136
+ &__value {
137
+ font-size: 28px;
138
+ color: v(heading);
139
+ margin: 12px 0 6px;
140
+ font-weight: 300;
141
+ display: flex;
142
+ align-items: baseline;
143
+ gap: 10px;
144
+ }
145
+ &__delta {
146
+ font-size: 13px;
147
+ font-weight: 600;
148
+ &--up {
149
+ color: v(color-success-text);
150
+ }
151
+ &--down {
152
+ color: v(color-danger-text);
153
+ }
154
+ }
155
+ .#{$p}-progress {
156
+ margin: 10px 0 0;
157
+ }
158
+ }
159
+ /* color-box / small box */
160
+ .#{$p}-color-box {
161
+ --_c: #{v(theme)};
162
+ --_on: #{v(on-theme)};
163
+ background: var(--_c);
164
+ color: var(--_on);
165
+ padding: 25px;
166
+ border-radius: v(radius);
167
+ position: relative;
168
+ overflow: hidden;
169
+ height: 100%;
170
+ @each $c in $colors {
171
+ &--#{$c} {
172
+ --_c: #{v(color-#{$c})};
173
+ --_on: #{on($c)};
174
+ }
175
+ }
176
+ h3,
177
+ h4,
178
+ h1,
179
+ h2,
180
+ &__value {
181
+ color: var(--_on) !important;
182
+ margin: 0 !important;
183
+ }
184
+ &__value {
185
+ font-size: v(h2);
186
+ line-height: 36px;
187
+ font-weight: 400;
188
+ }
189
+ &__icon {
190
+ position: absolute;
191
+ inset-inline-end: 20px;
192
+ top: 50%;
193
+ transform: translateY(-50%);
194
+ font-size: 60px;
195
+ opacity: 0.25;
196
+ }
197
+ &__label {
198
+ font-size: 13px;
199
+ text-transform: uppercase;
200
+ }
201
+ }
202
+
203
+ /* analytics row (stats-row / stat-item) */
204
+ .#{$p}-stats-row {
205
+ display: flex;
206
+ flex-wrap: wrap;
207
+ gap: 0;
208
+ border-top: 1px solid v(border-color);
209
+ &__item {
210
+ flex: 1;
211
+ min-width: 100px;
212
+ padding: 15px 10px;
213
+ text-align: center;
214
+ border-inline-end: 1px solid v(border-color);
215
+ &:last-child {
216
+ border: 0;
217
+ }
218
+ h6,
219
+ .#{$p}-stats-row__label {
220
+ margin: 0 0 4px !important;
221
+ color: v(text) !important;
222
+ text-transform: uppercase;
223
+ font-size: 12px !important;
224
+ }
225
+ b {
226
+ font-size: 18px;
227
+ color: v(heading);
228
+ font-weight: 600;
229
+ }
230
+ }
231
+ }
232
+
233
+ /* feed / list widgets */
234
+ .#{$p}-list {
235
+ list-style: none;
236
+ margin: 0;
237
+ padding: 0;
238
+ &__item {
239
+ display: flex;
240
+ gap: 14px;
241
+ align-items: center;
242
+ padding: 14px 0;
243
+ border-bottom: 1px solid v(border-color);
244
+ &:last-child {
245
+ border-bottom: 0;
246
+ }
247
+ }
248
+ &__body {
249
+ flex: 1;
250
+ min-width: 0;
251
+ }
252
+ &__title {
253
+ color: v(text-strong);
254
+ font-weight: 500;
255
+ margin: 0 0 2px;
256
+ overflow: hidden;
257
+ text-overflow: ellipsis;
258
+ white-space: nowrap;
259
+ }
260
+ &__desc {
261
+ font-size: 13px;
262
+ color: v(text);
263
+ margin: 0;
264
+ }
265
+ &__meta {
266
+ font-size: 12px;
267
+ color: v(text);
268
+ white-space: nowrap;
269
+ }
270
+ &__icon {
271
+ --_c: #{v(theme)};
272
+ --_on: #{v(on-theme)};
273
+ width: 40px;
274
+ height: 40px;
275
+ flex-shrink: 0;
276
+ border-radius: 50%;
277
+ display: inline-flex;
278
+ align-items: center;
279
+ justify-content: center;
280
+ color: var(--_on);
281
+ background: var(--_c);
282
+ @each $c in $colors {
283
+ &--#{$c} {
284
+ --_c: #{v(color-#{$c})};
285
+ --_on: #{on($c)};
286
+ }
287
+ }
288
+ }
289
+ &--hover &__item {
290
+ cursor: pointer;
291
+ padding-inline: 10px;
292
+ &:hover {
293
+ background: v(surface-muted);
294
+ }
295
+ }
296
+ }
297
+
298
+ /* chat (chat-widget / chat listing) */
299
+ .#{$p}-chat {
300
+ list-style: none;
301
+ margin: 0;
302
+ padding: 0;
303
+ display: flex;
304
+ flex-direction: column;
305
+ gap: 18px;
306
+ &__msg {
307
+ display: flex;
308
+ gap: 12px;
309
+ align-items: flex-end;
310
+ max-width: 85%;
311
+ &--me {
312
+ flex-direction: row-reverse;
313
+ align-self: flex-end;
314
+ .#{$p}-chat__bubble {
315
+ background: v(theme);
316
+ color: v(on-theme);
317
+ border-end-end-radius: 0;
318
+ border-end-start-radius: v(radius-lg);
319
+ }
320
+ }
321
+ }
322
+ &__bubble {
323
+ padding: 10px 14px;
324
+ border-radius: v(radius-lg);
325
+ border-end-start-radius: 0;
326
+ background: v(surface-muted);
327
+ color: v(text-strong);
328
+ font-size: 14px;
329
+ }
330
+ &__name {
331
+ font-size: 12px;
332
+ font-weight: 600;
333
+ color: v(heading);
334
+ margin-bottom: 2px;
335
+ }
336
+ &__time {
337
+ font-size: 11px;
338
+ color: v(text);
339
+ margin-top: 4px;
340
+ }
341
+ &__composer {
342
+ display: flex;
343
+ gap: 8px;
344
+ margin-top: 15px;
345
+ padding-top: 15px;
346
+ border-top: 1px solid v(border-color);
347
+ }
348
+ }
349
+
350
+ /* todo / task widget */
351
+ .#{$p}-todo {
352
+ list-style: none;
353
+ margin: 0;
354
+ padding: 0;
355
+ &__item {
356
+ display: flex;
357
+ align-items: center;
358
+ gap: 10px;
359
+ padding: 12px 14px;
360
+ margin-bottom: 8px;
361
+ background: v(surface-muted);
362
+ border-radius: v(radius);
363
+ border-inline-start: 4px solid v(color-warning);
364
+ &.is-done {
365
+ border-inline-start-color: v(theme);
366
+ .#{$p}-todo__text {
367
+ text-decoration: line-through;
368
+ color: v(text);
369
+ }
370
+ }
371
+ }
372
+ &__text {
373
+ flex: 1;
374
+ color: v(text-strong);
375
+ }
376
+ &__remove {
377
+ background: none;
378
+ border: 0;
379
+ cursor: pointer;
380
+ color: v(text);
381
+ opacity: 0;
382
+ &:hover {
383
+ color: v(color-danger-text);
384
+ }
385
+ }
386
+ &__item:hover &__remove,
387
+ &__remove:focus-visible {
388
+ opacity: 1;
389
+ }
390
+ }
391
+
392
+ /* profile widget / user-bg */
393
+ .#{$p}-profile-card {
394
+ background: v(surface);
395
+ border: 1px solid v(border-color);
396
+ border-radius: v(radius);
397
+ overflow: hidden;
398
+ margin-bottom: v(space-7);
399
+ &__cover {
400
+ position: relative;
401
+ height: 230px;
402
+ overflow: hidden;
403
+ background: linear-gradient(to right, #{v(topbar-1)}, #{v(topbar-2)});
404
+ > img {
405
+ width: 100%;
406
+ height: 100%;
407
+ object-fit: cover;
408
+ filter: blur(3px);
409
+ transform: scale(1.1);
410
+ opacity: 0.7;
411
+ }
412
+ }
413
+ &__overlay {
414
+ position: absolute;
415
+ inset: 0;
416
+ display: flex;
417
+ flex-direction: column;
418
+ align-items: center;
419
+ justify-content: center;
420
+ gap: 8px;
421
+ color: #fff;
422
+ text-align: center;
423
+ h4,
424
+ h5,
425
+ h2 {
426
+ color: #fff !important;
427
+ margin: 0 !important;
428
+ }
429
+ h2 {
430
+ font-size: v(h4) !important;
431
+ line-height: 22px;
432
+ }
433
+ > div {
434
+ font-size: v(h5);
435
+ }
436
+ }
437
+ &__stats {
438
+ display: grid;
439
+ grid-template-columns: repeat(3, 1fr);
440
+ text-align: center;
441
+ border-bottom: 1px solid v(border-color);
442
+ > div {
443
+ padding: 15px 8px;
444
+ border-inline-end: 1px solid v(border-color);
445
+ &:last-child {
446
+ border: 0;
447
+ }
448
+ }
449
+ b {
450
+ display: block;
451
+ font-size: 20px;
452
+ color: v(heading);
453
+ font-weight: 400;
454
+ }
455
+ small {
456
+ color: v(text);
457
+ }
458
+ }
459
+ &__body {
460
+ padding: 20px 25px;
461
+ }
462
+ }
463
+
464
+ /* user card with hover overlay */
465
+ .#{$p}-user-card {
466
+ background: v(surface);
467
+ border: 1px solid v(border-color);
468
+ border-radius: v(radius);
469
+ overflow: hidden;
470
+ margin-bottom: v(space-7);
471
+ text-align: center;
472
+ &__media {
473
+ position: relative;
474
+ overflow: hidden;
475
+ aspect-ratio: 1 / 1;
476
+ img {
477
+ width: 100%;
478
+ height: 100%;
479
+ object-fit: cover;
480
+ display: block;
481
+ transition: transform 0.4s;
482
+ }
483
+ }
484
+ &__overlay {
485
+ position: absolute;
486
+ inset: 0;
487
+ display: flex;
488
+ align-items: center;
489
+ justify-content: center;
490
+ gap: 8px;
491
+ background: rgba(0, 0, 0, 0.6);
492
+ opacity: 0;
493
+ transition: opacity 0.3s;
494
+ .#{$p}-btn {
495
+ transform: translateY(-20px);
496
+ transition: transform 0.3s;
497
+ }
498
+ }
499
+ &__media:hover img,
500
+ &__media:focus-within img {
501
+ transform: scale(1.12);
502
+ }
503
+ &__media:hover &__overlay,
504
+ &__media:focus-within &__overlay {
505
+ opacity: 1;
506
+ .#{$p}-btn {
507
+ transform: none;
508
+ }
509
+ }
510
+ &__content {
511
+ padding: 15px;
512
+ h2,
513
+ h3,
514
+ h4 {
515
+ margin: 0 0 2px !important;
516
+ font-size: 18px !important;
517
+ color: v(heading);
518
+ }
519
+ small {
520
+ color: v(text);
521
+ }
522
+ }
523
+ }
524
+
525
+ /* pricing */
526
+ .#{$p}-pricing {
527
+ display: grid;
528
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
529
+ gap: 0;
530
+ align-items: center;
531
+ }
532
+ .#{$p}-pricing-plan {
533
+ position: relative;
534
+ background: v(surface);
535
+ border: 1px solid v(border-color);
536
+ text-align: center;
537
+ transition: all 0.3s;
538
+ & + & {
539
+ margin-inline-start: -1px;
540
+ }
541
+ &__header {
542
+ padding: 30px 20px 15px;
543
+ border-bottom: 1px solid v(border-color);
544
+ h2,
545
+ h4 {
546
+ margin: 0 0 10px !important;
547
+ font-weight: 500;
548
+ color: v(heading);
549
+ text-transform: uppercase;
550
+ font-size: 18px !important;
551
+ line-height: 22px;
552
+ }
553
+ }
554
+ &__price {
555
+ font-size: 60px;
556
+ font-weight: 600;
557
+ color: v(heading);
558
+ line-height: 1;
559
+ margin: 10px 0;
560
+ display: flex;
561
+ justify-content: center;
562
+ align-items: flex-start;
563
+ gap: 2px;
564
+ sup {
565
+ font-size: 24px;
566
+ margin-top: 8px;
567
+ color: v(text);
568
+ }
569
+ }
570
+ &__period {
571
+ text-transform: uppercase;
572
+ color: v(text);
573
+ font-size: 13px;
574
+ margin: 0;
575
+ }
576
+ &__features {
577
+ list-style: none;
578
+ margin: 0;
579
+ padding: 0;
580
+ }
581
+ &__feature {
582
+ padding: 14px 20px;
583
+ border-bottom: 1px solid v(border-color);
584
+ color: v(text-strong);
585
+ display: flex;
586
+ gap: 8px;
587
+ justify-content: center;
588
+ align-items: center;
589
+ }
590
+ &__action {
591
+ padding: 25px 20px;
592
+ }
593
+ &__tag {
594
+ position: absolute;
595
+ top: 0;
596
+ inset-inline: 0;
597
+ background: v(color-danger);
598
+ color: v(on-danger);
599
+ padding: 4px;
600
+ font-size: 12px;
601
+ text-transform: uppercase;
602
+ letter-spacing: 0.05em;
603
+ }
604
+ &--featured {
605
+ z-index: 1;
606
+ transform: scale(1.06);
607
+ box-shadow: v(shadow-lg);
608
+ border-color: transparent;
609
+ .#{$p}-pricing-plan__header {
610
+ padding-top: 46px;
611
+ }
612
+ .#{$p}-pricing-plan__price {
613
+ color: v(theme-text);
614
+ }
615
+ }
616
+ @include down(sm) {
617
+ & + & {
618
+ margin: 0 0 20px;
619
+ }
620
+ &--featured {
621
+ transform: none;
622
+ }
623
+ }
624
+ }
625
+
626
+ /* weather (temp-widget) */
627
+ .#{$p}-weather {
628
+ --_c1: #{v(topbar-1)};
629
+ --_c2: #{v(topbar-2)};
630
+ background: linear-gradient(135deg, var(--_c1), var(--_c2));
631
+ color: #fff;
632
+ border-radius: v(radius);
633
+ padding: 25px;
634
+ height: 100%;
635
+ &__temp {
636
+ font-size: 54px;
637
+ font-weight: 300;
638
+ line-height: 1;
639
+ sup {
640
+ font-size: 24px;
641
+ }
642
+ }
643
+ &__icon {
644
+ font-size: 50px;
645
+ }
646
+ &__days {
647
+ display: grid;
648
+ grid-auto-flow: column;
649
+ grid-auto-columns: minmax(0, 1fr);
650
+ gap: 4px;
651
+ margin-top: 20px;
652
+ padding-top: 15px;
653
+ border-top: 1px solid rgba(255, 255, 255, 0.25);
654
+ text-align: center;
655
+ font-size: 13px;
656
+ b {
657
+ display: block;
658
+ font-size: 16px;
659
+ }
660
+ }
661
+ }
662
+
663
+ /* counter / mini chart host */
664
+ .#{$p}-chart {
665
+ position: relative;
666
+ width: 100%;
667
+ min-height: 60px;
668
+ svg {
669
+ display: block;
670
+ width: 100%;
671
+ overflow: visible;
672
+ }
673
+ }
674
+ .#{$p}-chart-legend {
675
+ display: flex;
676
+ flex-wrap: wrap;
677
+ gap: 14px;
678
+ list-style: none;
679
+ margin: 0 0 10px;
680
+ padding: 0;
681
+ font-size: 13px;
682
+ color: v(text-strong);
683
+ li {
684
+ display: inline-flex;
685
+ align-items: center;
686
+ gap: 6px;
687
+ }
688
+ i {
689
+ width: 10px;
690
+ height: 10px;
691
+ border-radius: 50%;
692
+ display: inline-block;
693
+ }
694
+ }
695
+ .#{$p}-chart-tooltip {
696
+ position: absolute;
697
+ pointer-events: none;
698
+ z-index: 5;
699
+ background: v(color-inverse);
700
+ color: #fff;
701
+ font-size: 12px;
702
+ padding: 6px 10px;
703
+ border-radius: v(radius-sm);
704
+ white-space: nowrap;
705
+ transform: translate(-50%, calc(-100% - 10px));
706
+ }
707
+
708
+ /* carousel */
709
+ .#{$p}-carousel {
710
+ position: relative;
711
+ overflow: hidden;
712
+ border-radius: v(radius);
713
+ &__track {
714
+ display: flex;
715
+ transition: transform 0.5s ease;
716
+ }
717
+ &__slide {
718
+ flex: 0 0 100%;
719
+ min-width: 0;
720
+ position: relative;
721
+ img {
722
+ width: 100%;
723
+ display: block;
724
+ }
725
+ }
726
+ &__caption {
727
+ position: absolute;
728
+ inset-inline: 15%;
729
+ bottom: 20px;
730
+ text-align: center;
731
+ color: #fff;
732
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
733
+ background: rgba(0, 0, 0, 0.55);
734
+ padding: 6px 14px;
735
+ border-radius: v(radius);
736
+ h3,
737
+ h4 {
738
+ color: #fff !important;
739
+ }
740
+ }
741
+ &__arrow {
742
+ position: absolute;
743
+ top: 50%;
744
+ transform: translateY(-50%);
745
+ width: 44px;
746
+ height: 44px;
747
+ border-radius: 50%;
748
+ border: 0;
749
+ background: rgba(0, 0, 0, 0.35);
750
+ color: #fff;
751
+ font-size: 22px;
752
+ cursor: pointer;
753
+ z-index: 2;
754
+ &:hover {
755
+ background: rgba(0, 0, 0, 0.6);
756
+ }
757
+ &--prev {
758
+ inset-inline-start: 12px;
759
+ }
760
+ &--next {
761
+ inset-inline-end: 12px;
762
+ }
763
+ }
764
+ &__dots {
765
+ position: absolute;
766
+ bottom: 10px;
767
+ inset-inline: 0;
768
+ display: flex;
769
+ justify-content: center;
770
+ gap: 6px;
771
+ z-index: 2;
772
+ button {
773
+ width: 10px;
774
+ height: 10px;
775
+ border-radius: 50%;
776
+ border: 0;
777
+ background: rgba(255, 255, 255, 0.5);
778
+ cursor: pointer;
779
+ padding: 0;
780
+ &.is-active {
781
+ background: #fff;
782
+ width: 22px;
783
+ border-radius: 5px;
784
+ }
785
+ }
786
+ }
787
+ &--fade &__track {
788
+ display: grid;
789
+ }
790
+ &--fade &__slide {
791
+ grid-area: 1 / 1;
792
+ opacity: 0;
793
+ transition: opacity 0.6s;
794
+ &.is-active {
795
+ opacity: 1;
796
+ }
797
+ }
798
+ }
799
+ [dir='rtl'] .#{$p}-carousel__track {
800
+ flex-direction: row-reverse;
801
+ }
802
+
803
+ /* gallery */
804
+ .#{$p}-gallery {
805
+ display: grid;
806
+ gap: 15px;
807
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
808
+ &__item {
809
+ position: relative;
810
+ overflow: hidden;
811
+ border-radius: v(radius);
812
+ cursor: zoom-in;
813
+ aspect-ratio: 4 / 3;
814
+ border: 0;
815
+ padding: 0;
816
+ background: none;
817
+ img {
818
+ width: 100%;
819
+ height: 100%;
820
+ object-fit: cover;
821
+ display: block;
822
+ transition: transform 0.4s;
823
+ }
824
+ &:hover img {
825
+ transform: scale(1.08);
826
+ }
827
+ }
828
+ }
829
+ .#{$p}-lightbox {
830
+ position: fixed;
831
+ inset: 0;
832
+ z-index: v(z-modal);
833
+ background: rgba(0, 0, 0, 0.9);
834
+ display: flex;
835
+ align-items: center;
836
+ justify-content: center;
837
+ animation: #{$p}-fade-in 0.2s;
838
+ img {
839
+ max-width: 90vw;
840
+ max-height: 85vh;
841
+ box-shadow: 0 0 30px rgba(0, 0, 0, 0.6);
842
+ animation: #{$p}-zoom-in 0.25s;
843
+ }
844
+ &__close,
845
+ &__nav {
846
+ position: absolute;
847
+ background: none;
848
+ border: 0;
849
+ color: #fff;
850
+ font-size: 34px;
851
+ cursor: pointer;
852
+ padding: 10px;
853
+ opacity: 0.8;
854
+ &:hover {
855
+ opacity: 1;
856
+ }
857
+ }
858
+ &__close {
859
+ top: 10px;
860
+ inset-inline-end: 16px;
861
+ }
862
+ &__nav--prev {
863
+ inset-inline-start: 10px;
864
+ }
865
+ &__nav--next {
866
+ inset-inline-end: 10px;
867
+ }
868
+ &__caption {
869
+ position: absolute;
870
+ bottom: 16px;
871
+ inset-inline: 0;
872
+ text-align: center;
873
+ color: #fff;
874
+ }
875
+ }
876
+
877
+ /* calendar (month view) */
878
+ .#{$p}-calendar {
879
+ &__toolbar {
880
+ display: flex;
881
+ align-items: center;
882
+ justify-content: space-between;
883
+ gap: 10px;
884
+ flex-wrap: wrap;
885
+ margin-bottom: 15px;
886
+ h2,
887
+ h3 {
888
+ margin: 0 !important;
889
+ font-size: v(h3);
890
+ line-height: 30px;
891
+ }
892
+ }
893
+ &__grid {
894
+ display: grid;
895
+ grid-template-columns: repeat(7, minmax(0, 1fr));
896
+ border-top: 1px solid v(border-color);
897
+ border-inline-start: 1px solid v(border-color);
898
+ }
899
+ &__dow {
900
+ padding: 10px 6px;
901
+ text-align: center;
902
+ font-weight: 600;
903
+ color: v(heading);
904
+ border-inline-end: 1px solid v(border-color);
905
+ border-bottom: 1px solid v(border-color);
906
+ background: v(surface-muted);
907
+ font-size: 13px;
908
+ }
909
+ &__cell {
910
+ min-height: 110px;
911
+ padding: 6px;
912
+ border-inline-end: 1px solid v(border-color);
913
+ border-bottom: 1px solid v(border-color);
914
+ position: relative;
915
+ cursor: pointer;
916
+ transition: background 0.2s;
917
+ &:hover {
918
+ background: v(surface-muted);
919
+ }
920
+ &.is-outside {
921
+ background: v(surface-muted);
922
+ .#{$p}-calendar__date {
923
+ color: v(text);
924
+ }
925
+ }
926
+ &.is-today {
927
+ background: color-mix(in srgb, #{v(color-warning)} 10%, transparent);
928
+ }
929
+ &.is-drop {
930
+ outline: 2px dashed v(theme);
931
+ outline-offset: -2px;
932
+ }
933
+ }
934
+ &__date {
935
+ font-size: 13px;
936
+ color: v(text-strong);
937
+ text-align: end;
938
+ display: block;
939
+ margin-bottom: 4px;
940
+ }
941
+ &__event {
942
+ --_c: #{v(theme)};
943
+ --_on: #{v(on-theme)};
944
+ display: block;
945
+ width: 100%;
946
+ padding: 3px 6px;
947
+ margin-bottom: 3px;
948
+ font-size: 12px;
949
+ color: var(--_on);
950
+ background: var(--_c);
951
+ border-radius: v(radius-sm);
952
+ border: 0;
953
+ text-align: start;
954
+ overflow: hidden;
955
+ text-overflow: ellipsis;
956
+ white-space: nowrap;
957
+ cursor: grab;
958
+ @each $c in $colors {
959
+ &--#{$c} {
960
+ --_c: #{v(color-#{$c})};
961
+ --_on: #{on($c)};
962
+ }
963
+ }
964
+ }
965
+ @include down(sm) {
966
+ &__cell {
967
+ min-height: 64px;
968
+ }
969
+ &__event {
970
+ font-size: 0;
971
+ height: 6px;
972
+ padding: 0;
973
+ }
974
+ }
975
+ }
976
+
977
+ /* map placeholder */
978
+ .#{$p}-map {
979
+ position: relative;
980
+ width: 100%;
981
+ min-height: 360px;
982
+ border-radius: v(radius);
983
+ overflow: hidden;
984
+ background: v(surface-muted);
985
+ iframe {
986
+ position: absolute;
987
+ inset: 0;
988
+ width: 100%;
989
+ height: 100%;
990
+ border: 0;
991
+ }
992
+ svg {
993
+ width: 100%;
994
+ height: auto;
995
+ display: block;
996
+ }
997
+ &__region {
998
+ fill: v(color-light);
999
+ stroke: v(surface);
1000
+ stroke-width: 0.5;
1001
+ transition: fill 0.2s;
1002
+ cursor: pointer;
1003
+ &:hover,
1004
+ &.is-active {
1005
+ fill: v(theme);
1006
+ }
1007
+ }
1008
+ }
1009
+
1010
+ /* icon grid */
1011
+ .#{$p}-icon-grid {
1012
+ display: grid;
1013
+ grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
1014
+ gap: 4px;
1015
+ &__item {
1016
+ display: flex;
1017
+ align-items: center;
1018
+ gap: 10px;
1019
+ padding: 10px;
1020
+ border-radius: v(radius-sm);
1021
+ color: v(text-strong);
1022
+ font-size: 13px;
1023
+ cursor: pointer;
1024
+ border: 0;
1025
+ background: none;
1026
+ text-align: start;
1027
+ &:hover {
1028
+ background: v(theme);
1029
+ color: v(on-theme);
1030
+ }
1031
+ svg {
1032
+ flex-shrink: 0;
1033
+ }
1034
+ }
1035
+ }
1036
+
1037
+ /* dashboard widgets stack like cards: rows rely on each block's bottom margin for vertical rhythm.
1038
+ They fill the column height (equal-height boxes in a row), so subtract the margin from 100%. */
1039
+ .#{$p}-info-box,
1040
+ .#{$p}-stat,
1041
+ .#{$p}-color-box,
1042
+ .#{$p}-weather {
1043
+ margin-bottom: v(space-7);
1044
+ }
1045
+ .#{$p}-info-box,
1046
+ .#{$p}-stat,
1047
+ .#{$p}-color-box,
1048
+ .#{$p}-weather {
1049
+ height: calc(100% - #{v(space-7)});
1050
+ }