fivo_cookie_consent 0.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,654 @@
1
+ /**
2
+ * GDPR Cookie Consent Styles
3
+ * Color scheme: #1E858B (brand green), #626465 (neutral grey)
4
+ * Responsive design with WCAG-AA contrast compliance
5
+ */
6
+
7
+ // Color variables
8
+ $brand-green: #1E858B;
9
+ $neutral-grey: #626465;
10
+ $white: #ffffff;
11
+ $black: #000000;
12
+ $light-grey: #f8f9fa;
13
+ $border-grey: #e9ecef;
14
+ $shadow-color: rgba(0, 0, 0, 0.15);
15
+
16
+ // Typography and spacing
17
+ $font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
18
+ $font-size-base: 16px;
19
+ $font-size-small: 14px;
20
+ $font-size-large: 18px;
21
+ $line-height: 1.5;
22
+ $border-radius: 8px;
23
+ $spacing-xs: 0.5rem;
24
+ $spacing-sm: 1rem;
25
+ $spacing-md: 1.5rem;
26
+ $spacing-lg: 2rem;
27
+ $max-width: 1024px;
28
+
29
+ // Z-index values
30
+ $z-banner: 9999;
31
+ $z-modal: 10000;
32
+
33
+ // Animation settings
34
+ $transition-fast: 0.2s ease;
35
+ $transition-medium: 0.3s ease;
36
+
37
+ // Banner styles
38
+ .gdpr-banner {
39
+ position: fixed;
40
+ bottom: 0;
41
+ left: 0;
42
+ right: 0;
43
+ z-index: $z-banner;
44
+ background: $white;
45
+ border-top: 1px solid $border-grey;
46
+ box-shadow: 0 -4px 20px $shadow-color;
47
+ transform: translateY(100%);
48
+ transition: transform $transition-medium;
49
+
50
+ &--visible {
51
+ transform: translateY(0);
52
+ }
53
+
54
+ &__container {
55
+ max-width: $max-width;
56
+ margin: 0 auto;
57
+ padding: $spacing-md $spacing-sm;
58
+
59
+ @media (min-width: 768px) {
60
+ padding: $spacing-md $spacing-lg;
61
+ }
62
+
63
+ @media (max-width: 767px) {
64
+ padding: $spacing-xs;
65
+ }
66
+ }
67
+
68
+ &__content {
69
+ display: flex;
70
+ flex-direction: column;
71
+ gap: $spacing-md;
72
+
73
+ @media (min-width: 768px) {
74
+ flex-direction: row;
75
+ align-items: center;
76
+ justify-content: space-between;
77
+ }
78
+ }
79
+
80
+ &__text {
81
+ flex: 1;
82
+ }
83
+
84
+ &__title {
85
+ margin: 0 0 $spacing-xs 0;
86
+ font-size: $font-size-large;
87
+ font-weight: 600;
88
+ color: $black;
89
+ line-height: $line-height;
90
+ }
91
+
92
+ &__description {
93
+ margin: 0;
94
+ font-size: $font-size-base;
95
+ color: $neutral-grey;
96
+ line-height: $line-height;
97
+ }
98
+
99
+ &__actions {
100
+ display: flex;
101
+ flex-direction: column;
102
+ gap: $spacing-xs;
103
+
104
+ @media (min-width: 576px) {
105
+ flex-direction: row;
106
+ }
107
+ }
108
+
109
+ &__btn {
110
+ padding: $spacing-xs $spacing-md;
111
+ border: 1px solid transparent;
112
+ border-radius: $border-radius;
113
+ font-size: $font-size-base;
114
+ font-weight: 500;
115
+ cursor: pointer;
116
+ transition: all $transition-fast;
117
+ text-decoration: none;
118
+ display: inline-flex;
119
+ align-items: center;
120
+ justify-content: center;
121
+ min-height: 44px; // Touch target size for accessibility
122
+ white-space: nowrap;
123
+
124
+ &:focus {
125
+ outline: 2px solid $brand-green;
126
+ outline-offset: 2px;
127
+ }
128
+
129
+ &--primary {
130
+ background: $brand-green;
131
+ color: $white;
132
+ border-color: $brand-green;
133
+
134
+ &:hover {
135
+ background: darken($brand-green, 8%);
136
+ border-color: darken($brand-green, 8%);
137
+ }
138
+
139
+ &:active {
140
+ background: darken($brand-green, 12%);
141
+ border-color: darken($brand-green, 12%);
142
+ }
143
+ }
144
+
145
+ &--secondary {
146
+ background: $light-grey;
147
+ color: $neutral-grey;
148
+ border-color: $border-grey;
149
+
150
+ &:hover {
151
+ background: darken($light-grey, 5%);
152
+ border-color: darken($border-grey, 10%);
153
+ }
154
+
155
+ &:active {
156
+ background: darken($light-grey, 10%);
157
+ border-color: darken($border-grey, 15%);
158
+ }
159
+ }
160
+
161
+ &--link {
162
+ background: transparent;
163
+ color: $brand-green;
164
+ border-color: transparent;
165
+ text-decoration: underline;
166
+
167
+ &:hover {
168
+ background: rgba($brand-green, 0.1);
169
+ text-decoration: none;
170
+ }
171
+
172
+ &:active {
173
+ background: rgba($brand-green, 0.2);
174
+ }
175
+ }
176
+
177
+ @media (max-width: 767px) {
178
+ font-size: 0.8125rem; // ~13px for better compactness on mobile
179
+ padding: $spacing-xs $spacing-xs;
180
+ }
181
+ }
182
+ }
183
+
184
+ // Modal styles
185
+ .gdpr-modal {
186
+ position: fixed;
187
+ top: 0;
188
+ left: 0;
189
+ right: 0;
190
+ bottom: 0;
191
+ z-index: $z-modal;
192
+ display: flex;
193
+ align-items: center;
194
+ justify-content: center;
195
+ padding: $spacing-sm;
196
+
197
+ &__backdrop {
198
+ position: absolute;
199
+ top: 0;
200
+ left: 0;
201
+ right: 0;
202
+ bottom: 0;
203
+ background: rgba($black, 0.5);
204
+ cursor: pointer;
205
+ }
206
+
207
+ &__container {
208
+ position: relative;
209
+ background: $white;
210
+ border-radius: $border-radius;
211
+ box-shadow: 0 20px 40px rgba($black, 0.3);
212
+ max-width: 600px;
213
+ width: 100%;
214
+ max-height: 90vh;
215
+ overflow: hidden;
216
+ display: flex;
217
+ flex-direction: column;
218
+
219
+ @media (max-width: 767px) {
220
+ margin: $spacing-xs;
221
+ max-height: calc(100vh - #{$spacing-xs * 2});
222
+ }
223
+ }
224
+
225
+ &__header {
226
+ display: flex;
227
+ align-items: center;
228
+ justify-content: space-between;
229
+ padding: $spacing-md;
230
+ border-bottom: 1px solid $border-grey;
231
+ flex-shrink: 0;
232
+
233
+ @media (max-width: 767px) {
234
+ padding: $spacing-xs;
235
+ }
236
+ }
237
+
238
+ &__title {
239
+ margin: 0;
240
+ font-size: $font-size-large;
241
+ font-weight: 600;
242
+ color: $black;
243
+ }
244
+
245
+ &__close {
246
+ background: none;
247
+ border: none;
248
+ font-size: 24px;
249
+ color: $neutral-grey;
250
+ cursor: pointer;
251
+ padding: $spacing-xs;
252
+ border-radius: $border-radius;
253
+ transition: all $transition-fast;
254
+ min-width: 32px;
255
+ min-height: 32px;
256
+ display: flex;
257
+ align-items: center;
258
+ justify-content: center;
259
+
260
+ &:hover {
261
+ background: $light-grey;
262
+ color: $black;
263
+ }
264
+
265
+ &:focus {
266
+ outline: 2px solid $brand-green;
267
+ outline-offset: 2px;
268
+ }
269
+ }
270
+
271
+ &__body {
272
+ padding: $spacing-md;
273
+ overflow-y: auto;
274
+ flex: 1;
275
+
276
+ @media (max-width: 767px) {
277
+ padding: $spacing-xs;
278
+ }
279
+ }
280
+
281
+ &__description {
282
+ margin: 0 0 $spacing-lg 0;
283
+ font-size: $font-size-base;
284
+ color: $neutral-grey;
285
+ line-height: $line-height;
286
+
287
+ a {
288
+ color: $brand-green;
289
+ text-decoration: underline;
290
+
291
+ &:hover {
292
+ text-decoration: none;
293
+ }
294
+
295
+ &:focus {
296
+ outline: 2px solid $brand-green;
297
+ outline-offset: 2px;
298
+ }
299
+ }
300
+ }
301
+
302
+ &__categories {
303
+ display: flex;
304
+ flex-direction: column;
305
+ gap: $spacing-md;
306
+ }
307
+
308
+ &__category {
309
+ border: 1px solid $border-grey;
310
+ border-radius: $border-radius;
311
+ padding: $spacing-md;
312
+ }
313
+
314
+ &__category-header {
315
+ display: flex;
316
+ justify-content: space-between;
317
+ align-items: center;
318
+ margin-bottom: 0.75rem;
319
+ }
320
+
321
+ &__category-title-wrapper {
322
+ display: flex;
323
+ align-items: center;
324
+ gap: 0.5rem;
325
+ cursor: pointer; // whole header clickable
326
+ transition: background-color $transition-fast;
327
+
328
+ &:hover {
329
+ background-color: rgba(0,0,0,0.04);
330
+ }
331
+ }
332
+
333
+ &__category-title {
334
+ font-size: 1.1rem;
335
+ font-weight: 600;
336
+ color: var(--gdpr-text-color);
337
+ margin: 0;
338
+ }
339
+
340
+ &__chevron {
341
+ display: inline-block;
342
+ width: 0.875rem;
343
+ height: 0.875rem;
344
+ font-size: 0.75rem;
345
+ line-height: 0.875rem;
346
+ text-align: center;
347
+ cursor: inherit; // decorative only; actual click handled on header
348
+ color: var(--gdpr-text-color);
349
+ transition: transform 0.2s ease;
350
+ user-select: none;
351
+
352
+ &[aria-expanded="true"] {
353
+ transform: rotate(90deg);
354
+ }
355
+ }
356
+
357
+ &__category-description {
358
+ margin: 0;
359
+ font-size: $font-size-small;
360
+ color: $neutral-grey;
361
+ line-height: $line-height;
362
+ }
363
+
364
+ &__empty-state {
365
+ margin-top: 0.75rem;
366
+ padding: 0.75rem;
367
+ background-color: var(--gdpr-background-light, #f8f9fa);
368
+ border-radius: 4px;
369
+ border-left: 3px solid var(--gdpr-border-color, #e5e7eb);
370
+ }
371
+
372
+ &__empty-text {
373
+ margin: 0;
374
+ font-size: 0.875rem;
375
+ color: var(--gdpr-text-muted, #6b7280);
376
+ font-style: italic;
377
+ }
378
+
379
+ &__cookie-list {
380
+ margin-top: 0.75rem;
381
+ border: 1px solid var(--gdpr-border-color, #e5e7eb);
382
+ border-radius: 4px;
383
+ overflow: hidden;
384
+ }
385
+
386
+ &__cookie-table {
387
+ width: 100%;
388
+ border-collapse: collapse;
389
+ font-size: 0.875rem;
390
+
391
+ th {
392
+ background-color: var(--gdpr-background-light, #f8f9fa);
393
+ padding: 0.75rem;
394
+ text-align: left;
395
+ font-weight: 600;
396
+ color: var(--gdpr-text-color);
397
+ border-bottom: 1px solid var(--gdpr-border-color, #e5e7eb);
398
+ }
399
+
400
+ td {
401
+ padding: 0.75rem;
402
+ border-bottom: 1px solid var(--gdpr-border-color, #e5e7eb);
403
+ color: var(--gdpr-text-color);
404
+
405
+ &:first-child {
406
+ font-weight: 500;
407
+ }
408
+ }
409
+
410
+ tbody tr:last-child td {
411
+ border-bottom: none;
412
+ }
413
+
414
+ tbody tr:nth-child(even) {
415
+ background-color: var(--gdpr-background-stripe, #f9fafb);
416
+ }
417
+ }
418
+
419
+ &__toggle {
420
+ position: relative;
421
+ display: inline-block;
422
+ width: 50px;
423
+ height: 24px;
424
+
425
+ input[type="checkbox"] {
426
+ opacity: 0;
427
+ width: 0;
428
+ height: 0;
429
+ position: absolute;
430
+
431
+ &:checked + .gdpr-modal__toggle-label .gdpr-modal__toggle-slider {
432
+ background-color: $brand-green;
433
+
434
+ &:before {
435
+ transform: translateX(26px);
436
+ }
437
+ }
438
+
439
+ &:focus + .gdpr-modal__toggle-label {
440
+ outline: 2px solid $brand-green;
441
+ outline-offset: 2px;
442
+ }
443
+
444
+ &:disabled + .gdpr-modal__toggle-label {
445
+ opacity: 0.6;
446
+ cursor: not-allowed;
447
+
448
+ .gdpr-modal__toggle-slider {
449
+ background-color: $neutral-grey;
450
+ }
451
+ }
452
+ }
453
+
454
+ &--disabled {
455
+ opacity: 0.6;
456
+ pointer-events: none;
457
+ }
458
+
459
+ &-label {
460
+ position: absolute;
461
+ cursor: pointer;
462
+ top: 0;
463
+ left: 0;
464
+ right: 0;
465
+ bottom: 0;
466
+ border-radius: 24px;
467
+ transition: all $transition-fast;
468
+ }
469
+
470
+ &-slider {
471
+ position: absolute;
472
+ cursor: pointer;
473
+ top: 0;
474
+ left: 0;
475
+ right: 0;
476
+ bottom: 0;
477
+ background-color: #ccc;
478
+ transition: all $transition-fast;
479
+ border-radius: 24px;
480
+
481
+ &:before {
482
+ position: absolute;
483
+ content: "";
484
+ height: 18px;
485
+ width: 18px;
486
+ left: 3px;
487
+ bottom: 3px;
488
+ background-color: $white;
489
+ transition: all $transition-fast;
490
+ border-radius: 50%;
491
+ }
492
+ }
493
+
494
+ // Disabled toggle styles
495
+ &--disabled {
496
+ opacity: 0.6;
497
+
498
+ .gdpr-modal__toggle-label {
499
+ cursor: not-allowed;
500
+
501
+ &:before {
502
+ cursor: not-allowed;
503
+ }
504
+ }
505
+
506
+ input[type="checkbox"]:disabled + .gdpr-modal__toggle-label {
507
+ cursor: not-allowed;
508
+ opacity: 0.7;
509
+
510
+ &:before {
511
+ cursor: not-allowed;
512
+ }
513
+ }
514
+ }
515
+ }
516
+
517
+ &__footer {
518
+ display: flex;
519
+ gap: $spacing-sm;
520
+ padding: $spacing-md;
521
+ border-top: 1px solid $border-grey;
522
+ justify-content: flex-end;
523
+ flex-shrink: 0;
524
+
525
+ @media (max-width: 576px) {
526
+ flex-direction: column;
527
+ }
528
+ }
529
+
530
+ &__btn {
531
+ padding: $spacing-xs $spacing-md;
532
+ border: 1px solid transparent;
533
+ border-radius: $border-radius;
534
+ font-size: $font-size-base;
535
+ font-weight: 500;
536
+ cursor: pointer;
537
+ transition: all $transition-fast;
538
+ text-decoration: none;
539
+ display: inline-flex;
540
+ align-items: center;
541
+ justify-content: center;
542
+ min-height: 44px;
543
+ white-space: nowrap;
544
+
545
+ &:focus {
546
+ outline: 2px solid $brand-green;
547
+ outline-offset: 2px;
548
+ }
549
+
550
+ &--primary {
551
+ background: $brand-green;
552
+ color: $white;
553
+ border-color: $brand-green;
554
+
555
+ &:hover {
556
+ background: darken($brand-green, 8%);
557
+ border-color: darken($brand-green, 8%);
558
+ }
559
+
560
+ &:active {
561
+ background: darken($brand-green, 12%);
562
+ border-color: darken($brand-green, 12%);
563
+ }
564
+ }
565
+
566
+ &--secondary {
567
+ background: $light-grey;
568
+ color: $neutral-grey;
569
+ border-color: $border-grey;
570
+
571
+ &:hover {
572
+ background: darken($light-grey, 5%);
573
+ border-color: darken($border-grey, 10%);
574
+ }
575
+
576
+ &:active {
577
+ background: darken($light-grey, 10%);
578
+ border-color: darken($border-grey, 15%);
579
+ }
580
+ }
581
+
582
+ &--link {
583
+ background: transparent;
584
+ color: $brand-green;
585
+ border-color: transparent;
586
+ text-decoration: underline;
587
+
588
+ &:hover {
589
+ background: rgba($brand-green, 0.1);
590
+ text-decoration: none;
591
+ }
592
+
593
+ &:active {
594
+ background: rgba($brand-green, 0.2);
595
+ }
596
+ }
597
+ }
598
+ }
599
+
600
+ // Responsive adjustments
601
+ @media (max-width: 767px) {
602
+ .gdpr-banner {
603
+ &__container {
604
+ padding: $spacing-xs;
605
+ }
606
+
607
+ &__actions {
608
+ .gdpr-banner__btn {
609
+ font-size: 0.8125rem; // ~13px for better compactness on mobile
610
+ padding: $spacing-xs $spacing-xs;
611
+ }
612
+ }
613
+ }
614
+
615
+ .gdpr-modal {
616
+ &__container {
617
+ margin: $spacing-xs;
618
+ max-height: calc(100vh - #{$spacing-xs * 2});
619
+ }
620
+
621
+ &__header,
622
+ &__body,
623
+ &__footer {
624
+ padding: $spacing-xs;
625
+ }
626
+ }
627
+ }
628
+
629
+ // Accessibility improvements
630
+ @media (prefers-reduced-motion: reduce) {
631
+ .gdpr-banner,
632
+ .gdpr-banner__btn,
633
+ .gdpr-modal__btn,
634
+ .gdpr-modal__toggle-slider,
635
+ .gdpr-modal__close {
636
+ transition: none;
637
+ }
638
+ }
639
+
640
+ // High contrast mode support
641
+ @media (prefers-contrast: high) {
642
+ .gdpr-banner {
643
+ border-top-width: 2px;
644
+ }
645
+
646
+ .gdpr-modal__category {
647
+ border-width: 2px;
648
+ }
649
+
650
+ .gdpr-banner__btn,
651
+ .gdpr-modal__btn {
652
+ border-width: 2px;
653
+ }
654
+ }