@slashgear/gdpr-cookie-scanner 3.6.0 → 3.7.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 (113) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/CLAUDE.md +12 -1
  3. package/NEXT_STEPS.md +37 -3
  4. package/README.md +23 -0
  5. package/dist/analyzers/colour.d.ts +36 -0
  6. package/dist/analyzers/colour.d.ts.map +1 -0
  7. package/dist/analyzers/colour.js +75 -0
  8. package/dist/analyzers/colour.js.map +1 -0
  9. package/dist/analyzers/compliance.d.ts.map +1 -1
  10. package/dist/analyzers/compliance.js +24 -6
  11. package/dist/analyzers/compliance.js.map +1 -1
  12. package/dist/analyzers/tcf-decoder.d.ts +9 -0
  13. package/dist/analyzers/tcf-decoder.d.ts.map +1 -0
  14. package/dist/analyzers/tcf-decoder.js +123 -0
  15. package/dist/analyzers/tcf-decoder.js.map +1 -0
  16. package/dist/analyzers/wording.d.ts +1 -0
  17. package/dist/analyzers/wording.d.ts.map +1 -1
  18. package/dist/analyzers/wording.js +39 -0
  19. package/dist/analyzers/wording.js.map +1 -1
  20. package/dist/report/generator.d.ts +1 -0
  21. package/dist/report/generator.d.ts.map +1 -1
  22. package/dist/report/generator.js +71 -1
  23. package/dist/report/generator.js.map +1 -1
  24. package/dist/report/html.d.ts.map +1 -1
  25. package/dist/report/html.js +123 -0
  26. package/dist/report/html.js.map +1 -1
  27. package/dist/scanner/consent-modal.d.ts.map +1 -1
  28. package/dist/scanner/consent-modal.js +4 -2
  29. package/dist/scanner/consent-modal.js.map +1 -1
  30. package/dist/scanner/index.d.ts.map +1 -1
  31. package/dist/scanner/index.js +4 -0
  32. package/dist/scanner/index.js.map +1 -1
  33. package/dist/scanner/tcf.d.ts +9 -0
  34. package/dist/scanner/tcf.d.ts.map +1 -0
  35. package/dist/scanner/tcf.js +72 -0
  36. package/dist/scanner/tcf.js.map +1 -0
  37. package/dist/types.d.ts +26 -0
  38. package/dist/types.d.ts.map +1 -1
  39. package/docs/index.html +37 -49
  40. package/docs/reports/www.arte.tv/after-accept.png +0 -0
  41. package/docs/reports/www.arte.tv/after-reject.png +0 -0
  42. package/docs/reports/www.arte.tv/gdpr-report-arte.tv-2026-02-24.html +997 -0
  43. package/docs/reports/www.deezer.com/after-accept.png +0 -0
  44. package/docs/reports/www.deezer.com/after-reject.png +0 -0
  45. package/docs/reports/www.deezer.com/gdpr-report-deezer.com-2026-02-22.html +1667 -0
  46. package/docs/reports/www.impots.gouv.fr/after-accept.png +0 -0
  47. package/docs/reports/www.impots.gouv.fr/after-reject.png +0 -0
  48. package/docs/reports/www.impots.gouv.fr/gdpr-report-impots.gouv.fr-2026-02-22.html +751 -0
  49. package/docs/reports/www.leboncoin.fr/after-accept.png +0 -0
  50. package/docs/reports/www.leboncoin.fr/after-reject.png +0 -0
  51. package/docs/reports/www.leboncoin.fr/gdpr-report-leboncoin.fr-2026-02-22.html +764 -0
  52. package/docs/reports/www.netflix.com/after-accept.png +0 -0
  53. package/docs/reports/www.netflix.com/after-reject.png +0 -0
  54. package/docs/reports/www.netflix.com/gdpr-report-netflix.com-2026-02-23.html +1050 -0
  55. package/docs/reports/www.radiofrance.fr/after-accept.png +0 -0
  56. package/docs/reports/www.radiofrance.fr/after-reject.png +0 -0
  57. package/docs/reports/www.radiofrance.fr/gdpr-report-radiofrance.fr-2026-02-24.html +1145 -0
  58. package/package.json +1 -1
  59. package/src/analyzers/colour.ts +89 -0
  60. package/src/analyzers/compliance.ts +35 -10
  61. package/src/analyzers/tcf-decoder.ts +130 -0
  62. package/src/analyzers/wording.ts +44 -0
  63. package/src/report/generator.ts +83 -1
  64. package/src/report/html.ts +146 -0
  65. package/src/scanner/consent-modal.ts +3 -1
  66. package/src/scanner/index.ts +5 -0
  67. package/src/scanner/tcf.ts +80 -0
  68. package/src/types.ts +29 -0
  69. package/tests/analyzers/colour.test.ts +187 -0
  70. package/tests/analyzers/compliance.test.ts +102 -0
  71. package/tests/analyzers/tcf-decoder.test.ts +292 -0
  72. package/tests/analyzers/wording.test.ts +38 -0
  73. package/tests/scanner/button-classification.test.ts +32 -0
  74. package/docs/reports/github.com/after-accept.png +0 -0
  75. package/docs/reports/github.com/after-reject.png +0 -0
  76. package/docs/reports/github.com/gdpr-checklist-github.com-2026-02-22.md +0 -44
  77. package/docs/reports/github.com/gdpr-cookies-github.com-2026-02-22.md +0 -29
  78. package/docs/reports/github.com/gdpr-report-github.com-2026-02-22.md +0 -102
  79. package/docs/reports/github.com/gdpr-report-github.com-2026-02-22.pdf +0 -0
  80. package/docs/reports/gitlab.com/after-accept.png +0 -0
  81. package/docs/reports/gitlab.com/after-reject.png +0 -0
  82. package/docs/reports/gitlab.com/gdpr-checklist-gitlab.com-2026-02-22.md +0 -44
  83. package/docs/reports/gitlab.com/gdpr-cookies-gitlab.com-2026-02-22.md +0 -55
  84. package/docs/reports/gitlab.com/gdpr-report-gitlab.com-2026-02-22.md +0 -200
  85. package/docs/reports/gitlab.com/gdpr-report-gitlab.com-2026-02-22.pdf +0 -0
  86. package/docs/reports/gitlab.com/modal-initial.png +0 -0
  87. package/docs/reports/npmjs.com/after-accept.png +0 -0
  88. package/docs/reports/npmjs.com/after-reject.png +0 -0
  89. package/docs/reports/npmjs.com/gdpr-checklist-npmjs.com-2026-02-22.md +0 -44
  90. package/docs/reports/npmjs.com/gdpr-cookies-npmjs.com-2026-02-22.md +0 -25
  91. package/docs/reports/npmjs.com/gdpr-report-npmjs.com-2026-02-22.md +0 -88
  92. package/docs/reports/npmjs.com/gdpr-report-npmjs.com-2026-02-22.pdf +0 -0
  93. package/docs/reports/reddit.com/after-accept.png +0 -0
  94. package/docs/reports/reddit.com/after-reject.png +0 -0
  95. package/docs/reports/reddit.com/gdpr-checklist-reddit.com-2026-02-22.md +0 -44
  96. package/docs/reports/reddit.com/gdpr-cookies-reddit.com-2026-02-22.md +0 -33
  97. package/docs/reports/reddit.com/gdpr-report-reddit.com-2026-02-22.md +0 -148
  98. package/docs/reports/reddit.com/gdpr-report-reddit.com-2026-02-22.pdf +0 -0
  99. package/docs/reports/reddit.com/modal-initial.png +0 -0
  100. package/docs/reports/stackoverflow.com/after-accept.png +0 -0
  101. package/docs/reports/stackoverflow.com/after-reject.png +0 -0
  102. package/docs/reports/stackoverflow.com/gdpr-checklist-stackoverflow.com-2026-02-22.md +0 -44
  103. package/docs/reports/stackoverflow.com/gdpr-cookies-stackoverflow.com-2026-02-22.md +0 -67
  104. package/docs/reports/stackoverflow.com/gdpr-report-stackoverflow.com-2026-02-22.md +0 -206
  105. package/docs/reports/stackoverflow.com/gdpr-report-stackoverflow.com-2026-02-22.pdf +0 -0
  106. package/docs/reports/stackoverflow.com/modal-initial.png +0 -0
  107. package/docs/reports/www.afp.com/after-accept.png +0 -0
  108. package/docs/reports/www.afp.com/after-reject.png +0 -0
  109. package/docs/reports/www.afp.com/gdpr-checklist-afp.com-2026-02-22.md +0 -44
  110. package/docs/reports/www.afp.com/gdpr-cookies-afp.com-2026-02-22.md +0 -42
  111. package/docs/reports/www.afp.com/gdpr-report-afp.com-2026-02-22.md +0 -202
  112. package/docs/reports/www.afp.com/gdpr-report-afp.com-2026-02-22.pdf +0 -0
  113. package/docs/reports/www.afp.com/modal-initial.png +0 -0
@@ -0,0 +1,1667 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>GDPR Report — deezer.com</title>
7
+ <style>
8
+ *,
9
+ *::before,
10
+ *::after {
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ :root {
15
+ --grade: #65a30d;
16
+ --grade-bg: #f7fee7;
17
+ --surface: #ffffff;
18
+ --bg: #f1f5f9;
19
+ --border: #e2e8f0;
20
+ --text: #0f172a;
21
+ --text-muted: #64748b;
22
+ --critical: #dc2626;
23
+ --critical-bg: #fef2f2;
24
+ --critical-border: #fecaca;
25
+ --warning: #d97706;
26
+ --warning-bg: #fffbeb;
27
+ --warning-border: #fde68a;
28
+ --ok: #16a34a;
29
+ --ok-bg: #f0fdf4;
30
+ --ok-border: #bbf7d0;
31
+ --radius: 10px;
32
+ --shadow: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.06);
33
+ --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07), 0 2px 4px rgba(0, 0, 0, 0.06);
34
+ }
35
+
36
+ body {
37
+ margin: 0;
38
+ background: var(--bg);
39
+ color: var(--text);
40
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
41
+ font-size: 14px;
42
+ line-height: 1.6;
43
+ }
44
+
45
+ /* ── Layout ── */
46
+ .page {
47
+ max-width: 1000px;
48
+ margin: 0 auto;
49
+ padding: 24px 16px 64px;
50
+ }
51
+
52
+ /* ── Hero ── */
53
+ .hero {
54
+ background: var(--surface);
55
+ border-radius: var(--radius);
56
+ box-shadow: var(--shadow-md);
57
+ padding: 32px 36px;
58
+ display: flex;
59
+ align-items: center;
60
+ gap: 32px;
61
+ margin-bottom: 20px;
62
+ border-top: 4px solid var(--grade);
63
+ }
64
+ .grade-badge {
65
+ flex-shrink: 0;
66
+ width: 80px;
67
+ height: 80px;
68
+ border-radius: 16px;
69
+ background: var(--grade);
70
+ color: #fff;
71
+ font-size: 42px;
72
+ font-weight: 800;
73
+ display: flex;
74
+ align-items: center;
75
+ justify-content: center;
76
+ letter-spacing: -2px;
77
+ }
78
+ .hero-info {
79
+ flex: 1;
80
+ min-width: 0;
81
+ }
82
+ .hero-info h1 {
83
+ margin: 0 0 4px;
84
+ font-size: 22px;
85
+ font-weight: 700;
86
+ color: var(--text);
87
+ white-space: nowrap;
88
+ overflow: hidden;
89
+ text-overflow: ellipsis;
90
+ }
91
+ .hero-meta {
92
+ font-size: 13px;
93
+ color: var(--text-muted);
94
+ margin: 0;
95
+ }
96
+ .hero-score {
97
+ flex-shrink: 0;
98
+ text-align: right;
99
+ }
100
+ .hero-score .score-num {
101
+ font-size: 40px;
102
+ font-weight: 800;
103
+ color: var(--grade);
104
+ line-height: 1;
105
+ }
106
+ .hero-score .score-den {
107
+ font-size: 18px;
108
+ color: var(--text-muted);
109
+ font-weight: 400;
110
+ }
111
+ .hero-score .score-label {
112
+ font-size: 12px;
113
+ color: var(--text-muted);
114
+ margin-top: 4px;
115
+ }
116
+
117
+ /* ── Score grid ── */
118
+ .score-grid {
119
+ display: grid;
120
+ grid-template-columns: repeat(4, 1fr);
121
+ gap: 12px;
122
+ margin-bottom: 20px;
123
+ }
124
+ @media (max-width: 640px) {
125
+ .score-grid {
126
+ grid-template-columns: repeat(2, 1fr);
127
+ }
128
+ }
129
+ .score-card {
130
+ background: var(--surface);
131
+ border-radius: var(--radius);
132
+ padding: 16px 18px;
133
+ box-shadow: var(--shadow);
134
+ }
135
+ .score-card-label {
136
+ font-size: 11px;
137
+ font-weight: 600;
138
+ text-transform: uppercase;
139
+ letter-spacing: 0.05em;
140
+ color: var(--text-muted);
141
+ margin-bottom: 8px;
142
+ }
143
+ .score-card-value {
144
+ font-size: 22px;
145
+ font-weight: 700;
146
+ color: var(--text);
147
+ margin-bottom: 8px;
148
+ }
149
+ .score-card-value span {
150
+ font-size: 14px;
151
+ font-weight: 400;
152
+ color: var(--text-muted);
153
+ }
154
+ .progress-track {
155
+ height: 6px;
156
+ background: var(--border);
157
+ border-radius: 3px;
158
+ overflow: hidden;
159
+ }
160
+ .progress-fill {
161
+ height: 100%;
162
+ border-radius: 3px;
163
+ background: var(--grade-color, #64748b);
164
+ }
165
+
166
+ /* ── Section ── */
167
+ .section {
168
+ background: var(--surface);
169
+ border-radius: var(--radius);
170
+ box-shadow: var(--shadow);
171
+ margin-bottom: 16px;
172
+ overflow: hidden;
173
+ }
174
+ .section-header {
175
+ padding: 16px 20px;
176
+ border-bottom: 1px solid var(--border);
177
+ display: flex;
178
+ align-items: center;
179
+ gap: 10px;
180
+ }
181
+ .section-header h2 {
182
+ margin: 0;
183
+ font-size: 15px;
184
+ font-weight: 600;
185
+ color: var(--text);
186
+ }
187
+ .section-body {
188
+ padding: 20px;
189
+ }
190
+ .section-body.no-pad {
191
+ padding: 0;
192
+ }
193
+
194
+ /* ── Badges ── */
195
+ .badge {
196
+ display: inline-flex;
197
+ align-items: center;
198
+ gap: 4px;
199
+ padding: 2px 8px;
200
+ border-radius: 99px;
201
+ font-size: 11px;
202
+ font-weight: 600;
203
+ }
204
+ .badge-critical {
205
+ background: var(--critical-bg);
206
+ color: var(--critical);
207
+ border: 1px solid var(--critical-border);
208
+ }
209
+ .badge-warning {
210
+ background: var(--warning-bg);
211
+ color: var(--warning);
212
+ border: 1px solid var(--warning-border);
213
+ }
214
+ .badge-ok {
215
+ background: var(--ok-bg);
216
+ color: var(--ok);
217
+ border: 1px solid var(--ok-border);
218
+ }
219
+ .badge-muted {
220
+ background: var(--bg);
221
+ color: var(--text-muted);
222
+ border: 1px solid var(--border);
223
+ }
224
+ .count-badge {
225
+ background: var(--bg);
226
+ color: var(--text-muted);
227
+ font-size: 12px;
228
+ font-weight: 600;
229
+ padding: 1px 8px;
230
+ border-radius: 99px;
231
+ margin-left: auto;
232
+ }
233
+
234
+ /* ── Issue cards ── */
235
+ .issue-list {
236
+ display: flex;
237
+ flex-direction: column;
238
+ gap: 10px;
239
+ }
240
+ .issue-card {
241
+ border-radius: 8px;
242
+ padding: 14px 16px;
243
+ border: 1px solid;
244
+ }
245
+ .issue-card.critical {
246
+ background: var(--critical-bg);
247
+ border-color: var(--critical-border);
248
+ }
249
+ .issue-card.warning {
250
+ background: var(--warning-bg);
251
+ border-color: var(--warning-border);
252
+ }
253
+ .issue-title {
254
+ font-size: 13px;
255
+ font-weight: 600;
256
+ margin-bottom: 4px;
257
+ }
258
+ .issue-card.critical .issue-title {
259
+ color: var(--critical);
260
+ }
261
+ .issue-card.warning .issue-title {
262
+ color: var(--warning);
263
+ }
264
+ .issue-evidence {
265
+ font-size: 12px;
266
+ color: var(--text-muted);
267
+ margin: 0;
268
+ }
269
+ .no-issues {
270
+ display: flex;
271
+ align-items: center;
272
+ gap: 8px;
273
+ color: var(--ok);
274
+ font-weight: 500;
275
+ font-size: 14px;
276
+ }
277
+
278
+ /* ── Tables ── */
279
+ .data-table {
280
+ width: 100%;
281
+ border-collapse: collapse;
282
+ font-size: 13px;
283
+ }
284
+ .data-table th {
285
+ background: var(--bg);
286
+ padding: 10px 14px;
287
+ text-align: left;
288
+ font-size: 11px;
289
+ font-weight: 600;
290
+ text-transform: uppercase;
291
+ letter-spacing: 0.04em;
292
+ color: var(--text-muted);
293
+ border-bottom: 1px solid var(--border);
294
+ white-space: nowrap;
295
+ }
296
+ .data-table td {
297
+ padding: 10px 14px;
298
+ border-bottom: 1px solid var(--border);
299
+ vertical-align: top;
300
+ }
301
+ .data-table tr:last-child td {
302
+ border-bottom: none;
303
+ }
304
+ .data-table tr:hover td {
305
+ background: #fafafa;
306
+ }
307
+ code {
308
+ font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace;
309
+ font-size: 12px;
310
+ background: var(--bg);
311
+ padding: 1px 6px;
312
+ border-radius: 4px;
313
+ border: 1px solid var(--border);
314
+ }
315
+ .empty-state {
316
+ text-align: center;
317
+ padding: 32px;
318
+ color: var(--text-muted);
319
+ font-size: 13px;
320
+ }
321
+
322
+ /* ── Checklist status ── */
323
+ .status-ok {
324
+ color: var(--ok);
325
+ font-weight: 600;
326
+ }
327
+ .status-ko {
328
+ color: var(--critical);
329
+ font-weight: 600;
330
+ }
331
+ .status-warn {
332
+ color: var(--warning);
333
+ font-weight: 600;
334
+ }
335
+
336
+ /* ── Info grid ── */
337
+ .info-grid {
338
+ display: grid;
339
+ grid-template-columns: 1fr 1fr;
340
+ gap: 12px;
341
+ }
342
+ @media (max-width: 640px) {
343
+ .info-grid {
344
+ grid-template-columns: 1fr;
345
+ }
346
+ }
347
+ .info-item {
348
+ }
349
+ .info-label {
350
+ font-size: 11px;
351
+ font-weight: 600;
352
+ text-transform: uppercase;
353
+ letter-spacing: 0.04em;
354
+ color: var(--text-muted);
355
+ margin-bottom: 2px;
356
+ }
357
+ .info-value {
358
+ font-size: 13px;
359
+ color: var(--text);
360
+ }
361
+
362
+ /* ── Buttons table ── */
363
+ .btn-chip {
364
+ display: inline-block;
365
+ padding: 2px 10px;
366
+ border-radius: 4px;
367
+ font-size: 12px;
368
+ font-weight: 600;
369
+ }
370
+ .btn-chip.accept {
371
+ background: #dcfce7;
372
+ color: #166534;
373
+ }
374
+ .btn-chip.reject {
375
+ background: #fee2e2;
376
+ color: #991b1b;
377
+ }
378
+ .btn-chip.preferences {
379
+ background: #dbeafe;
380
+ color: #1e40af;
381
+ }
382
+ .btn-chip.unknown,
383
+ .btn-chip.close {
384
+ background: var(--bg);
385
+ color: var(--text-muted);
386
+ }
387
+
388
+ /* ── Recommendations ── */
389
+ .rec-list {
390
+ list-style: none;
391
+ margin: 0;
392
+ padding: 0;
393
+ display: flex;
394
+ flex-direction: column;
395
+ gap: 10px;
396
+ }
397
+ .rec-item {
398
+ display: flex;
399
+ gap: 12px;
400
+ padding: 12px 14px;
401
+ background: #f8fafc;
402
+ border-radius: 8px;
403
+ border: 1px solid var(--border);
404
+ font-size: 13px;
405
+ }
406
+ .rec-num {
407
+ flex-shrink: 0;
408
+ width: 24px;
409
+ height: 24px;
410
+ border-radius: 50%;
411
+ background: var(--text);
412
+ color: #fff;
413
+ font-size: 12px;
414
+ font-weight: 700;
415
+ display: flex;
416
+ align-items: center;
417
+ justify-content: center;
418
+ margin-top: 1px;
419
+ }
420
+
421
+ /* ── Footer ── */
422
+ .footer {
423
+ text-align: center;
424
+ margin-top: 40px;
425
+ font-size: 12px;
426
+ color: var(--text-muted);
427
+ }
428
+ .footer a {
429
+ color: var(--text-muted);
430
+ }
431
+
432
+ @media print {
433
+ body {
434
+ background: #fff;
435
+ }
436
+ .section {
437
+ box-shadow: none;
438
+ border: 1px solid var(--border);
439
+ }
440
+ .page {
441
+ padding: 0;
442
+ }
443
+ }
444
+ </style>
445
+ </head>
446
+ <body>
447
+ <div class="page">
448
+ <div class="hero">
449
+ <div class="grade-badge" style="background: #65a30d">B</div>
450
+ <div class="hero-info">
451
+ <h1>deezer.com</h1>
452
+ <p class="hero-meta">Scanned on 22 February 2026 at 20:53 · 13.9s</p>
453
+ </div>
454
+ <div class="hero-score">
455
+ <div>
456
+ <span class="score-num" style="color: #65a30d">80</span
457
+ ><span class="score-den">/100</span>
458
+ </div>
459
+ <div class="score-label">Compliance score</div>
460
+ </div>
461
+ </div>
462
+
463
+ <div class="score-grid">
464
+ <div class="score-card">
465
+ <div class="score-card-label">Consent validity</div>
466
+ <div class="score-card-value">25<span>/25</span></div>
467
+ <div class="progress-track">
468
+ <div class="progress-fill" style="width: 100%; background: #16a34a"></div>
469
+ </div>
470
+ </div>
471
+ <div class="score-card">
472
+ <div class="score-card-label">Easy refusal</div>
473
+ <div class="score-card-value">25<span>/25</span></div>
474
+ <div class="progress-track">
475
+ <div class="progress-fill" style="width: 100%; background: #16a34a"></div>
476
+ </div>
477
+ </div>
478
+ <div class="score-card">
479
+ <div class="score-card-label">Transparency</div>
480
+ <div class="score-card-value">25<span>/25</span></div>
481
+ <div class="progress-track">
482
+ <div class="progress-fill" style="width: 100%; background: #16a34a"></div>
483
+ </div>
484
+ </div>
485
+ <div class="score-card">
486
+ <div class="score-card-label">Cookie behavior</div>
487
+ <div class="score-card-value">5<span>/25</span></div>
488
+ <div class="progress-track">
489
+ <div class="progress-fill" style="width: 20%; background: #dc2626"></div>
490
+ </div>
491
+ </div>
492
+ </div>
493
+
494
+ <div class="section">
495
+ <div class="section-header">
496
+ <h2>Issues</h2>
497
+ <span class="count-badge">3</span>
498
+ <span class="badge badge-critical">3 critical</span>
499
+ </div>
500
+ <div class="section-body">
501
+ <div class="issue-list">
502
+ <div class="issue-card critical">
503
+ <div class="issue-title">
504
+ 1 non-essential cookie(s) deposited before any interaction
505
+ </div>
506
+ <p class="issue-evidence">sid (unknown)</p>
507
+ </div>
508
+ <div class="issue-card critical">
509
+ <div class="issue-title">2 non-essential cookie(s) persist after rejection</div>
510
+ <p class="issue-evidence">sid (unknown), ajs_anonymous_id (analytics)</p>
511
+ </div>
512
+ <div class="issue-card critical">
513
+ <div class="issue-title">8 tracker request(s) fired before any consent</div>
514
+ <p class="issue-evidence">Google Tag Manager, Segment, Google AdSense</p>
515
+ </div>
516
+ </div>
517
+ </div>
518
+ </div>
519
+
520
+ <div class="section">
521
+ <div class="section-header">
522
+ <h2>Consent modal</h2>
523
+ <span class="badge badge-ok">Detected</span>
524
+ </div>
525
+ <div class="section-body">
526
+ <div class="info-grid" style="margin-bottom: 20px">
527
+ <div class="info-item">
528
+ <div class="info-label">Selector</div>
529
+ <div class="info-value"><code>[class*='cookie'][class*='modal']</code></div>
530
+ </div>
531
+ <div class="info-item">
532
+ <div class="info-label">Granular controls</div>
533
+ <div class="info-value"><span class="status-ok">✓ Yes</span></div>
534
+ </div>
535
+ <div class="info-item">
536
+ <div class="info-label">Privacy policy link</div>
537
+ <div class="info-value">
538
+ <a href="https://vdp.deezer.com/p/Welcome" target="_blank" rel="noopener"
539
+ >https://vdp.deezer.com/p/Welcome</a
540
+ >
541
+ </div>
542
+ </div>
543
+ <div class="info-item">
544
+ <div class="info-label">Pre-ticked checkboxes</div>
545
+ <div class="info-value"><span class="status-ok">✓ None</span></div>
546
+ </div>
547
+ </div>
548
+ <div
549
+ style="
550
+ font-size: 12px;
551
+ font-weight: 600;
552
+ text-transform: uppercase;
553
+ letter-spacing: 0.04em;
554
+ color: var(--text-muted);
555
+ margin-bottom: 8px;
556
+ "
557
+ >
558
+ Buttons
559
+ </div>
560
+ <table class="data-table">
561
+ <thead>
562
+ <tr>
563
+ <th>Type</th>
564
+ <th>Label</th>
565
+ <th>Font size</th>
566
+ <th>Contrast</th>
567
+ <th>Clicks</th>
568
+ </tr>
569
+ </thead>
570
+ <tbody>
571
+ <tr>
572
+ <td><span class="btn-chip accept">accept</span></td>
573
+ <td>Accepter</td>
574
+ <td>16px</td>
575
+ <td>4.49:1</td>
576
+ <td>1</td>
577
+ </tr>
578
+ <tr>
579
+ <td><span class="btn-chip reject">reject</span></td>
580
+ <td>Refuser</td>
581
+ <td>16px</td>
582
+ <td>20.42:1</td>
583
+ <td>1</td>
584
+ </tr>
585
+ <tr>
586
+ <td><span class="btn-chip preferences">preferences</span></td>
587
+ <td>Préférences</td>
588
+ <td>16px</td>
589
+ <td>20.42:1</td>
590
+ <td>1</td>
591
+ </tr>
592
+ </tbody>
593
+ </table>
594
+ </div>
595
+ </div>
596
+
597
+ <div class="section">
598
+ <div class="section-header"><h2>Cookies</h2></div>
599
+ <div class="section-body">
600
+ <div style="margin-bottom: 24px">
601
+ <div
602
+ style="
603
+ font-size: 12px;
604
+ font-weight: 600;
605
+ text-transform: uppercase;
606
+ letter-spacing: 0.04em;
607
+ color: var(--text-muted);
608
+ margin-bottom: 8px;
609
+ display: flex;
610
+ align-items: center;
611
+ gap: 8px;
612
+ "
613
+ >
614
+ Before interaction
615
+ <span class="count-badge">4</span>
616
+ <span class="badge badge-critical">1 non-essential</span>
617
+ </div>
618
+ <table class="data-table">
619
+ <thead>
620
+ <tr>
621
+ <th>Name</th>
622
+ <th>Domain</th>
623
+ <th>Category</th>
624
+ <th>Expiry</th>
625
+ <th>Consent</th>
626
+ </tr>
627
+ </thead>
628
+ <tbody>
629
+ <tr>
630
+ <td><code>sid</code></td>
631
+ <td style="color: var(--text-muted)">.deezer.com</td>
632
+ <td><span class="badge badge-muted">unknown</span></td>
633
+ <td style="color: var(--text-muted)">Session</td>
634
+ <td><span class="badge badge-warning">Required</span></td>
635
+ </tr>
636
+ <tr>
637
+ <td><code>dzr_uniq_id</code></td>
638
+ <td style="color: var(--text-muted)">.deezer.com</td>
639
+ <td><span class="badge badge-muted">unknown</span></td>
640
+ <td style="color: var(--text-muted)">6mo</td>
641
+ <td><span class="badge badge-muted">No</span></td>
642
+ </tr>
643
+ <tr>
644
+ <td><code>bm_sz</code></td>
645
+ <td style="color: var(--text-muted)">.deezer.com</td>
646
+ <td><span class="badge badge-muted">unknown</span></td>
647
+ <td style="color: var(--text-muted)">< 1 day</td>
648
+ <td><span class="badge badge-muted">No</span></td>
649
+ </tr>
650
+ <tr>
651
+ <td><code>_abck</code></td>
652
+ <td style="color: var(--text-muted)">.deezer.com</td>
653
+ <td><span class="badge badge-muted">unknown</span></td>
654
+ <td style="color: var(--text-muted)">12mo</td>
655
+ <td><span class="badge badge-muted">No</span></td>
656
+ </tr>
657
+ </tbody>
658
+ </table>
659
+ </div>
660
+ <div style="margin-bottom: 24px">
661
+ <div
662
+ style="
663
+ font-size: 12px;
664
+ font-weight: 600;
665
+ text-transform: uppercase;
666
+ letter-spacing: 0.04em;
667
+ color: var(--text-muted);
668
+ margin-bottom: 8px;
669
+ display: flex;
670
+ align-items: center;
671
+ gap: 8px;
672
+ "
673
+ >
674
+ After reject
675
+ <span class="count-badge">9</span>
676
+
677
+ <span class="badge badge-critical">2 non-essential</span>
678
+ </div>
679
+ <table class="data-table">
680
+ <thead>
681
+ <tr>
682
+ <th>Name</th>
683
+ <th>Domain</th>
684
+ <th>Category</th>
685
+ <th>Expiry</th>
686
+ <th>Consent</th>
687
+ </tr>
688
+ </thead>
689
+ <tbody>
690
+ <tr>
691
+ <td><code>sid</code></td>
692
+ <td style="color: var(--text-muted)">.deezer.com</td>
693
+ <td><span class="badge badge-muted">unknown</span></td>
694
+ <td style="color: var(--text-muted)">Session</td>
695
+ <td><span class="badge badge-warning">Required</span></td>
696
+ </tr>
697
+ <tr>
698
+ <td><code>dzr_uniq_id</code></td>
699
+ <td style="color: var(--text-muted)">.deezer.com</td>
700
+ <td><span class="badge badge-muted">unknown</span></td>
701
+ <td style="color: var(--text-muted)">6mo</td>
702
+ <td><span class="badge badge-muted">No</span></td>
703
+ </tr>
704
+ <tr>
705
+ <td><code>bm_sz</code></td>
706
+ <td style="color: var(--text-muted)">.deezer.com</td>
707
+ <td><span class="badge badge-muted">unknown</span></td>
708
+ <td style="color: var(--text-muted)">< 1 day</td>
709
+ <td><span class="badge badge-muted">No</span></td>
710
+ </tr>
711
+ <tr>
712
+ <td><code>euconsent-v2</code></td>
713
+ <td style="color: var(--text-muted)">.deezer.com</td>
714
+ <td><span class="badge badge-muted">unknown</span></td>
715
+ <td style="color: var(--text-muted)">3mo</td>
716
+ <td><span class="badge badge-muted">No</span></td>
717
+ </tr>
718
+ <tr>
719
+ <td><code>noIabVendors</code></td>
720
+ <td style="color: var(--text-muted)">.deezer.com</td>
721
+ <td><span class="badge badge-muted">unknown</span></td>
722
+ <td style="color: var(--text-muted)">3mo</td>
723
+ <td><span class="badge badge-muted">No</span></td>
724
+ </tr>
725
+ <tr>
726
+ <td><code>consentMarketing</code></td>
727
+ <td style="color: var(--text-muted)">.deezer.com</td>
728
+ <td><span class="badge badge-muted">strictly-necessary</span></td>
729
+ <td style="color: var(--text-muted)">3mo</td>
730
+ <td><span class="badge badge-muted">No</span></td>
731
+ </tr>
732
+ <tr>
733
+ <td><code>consentStatistics</code></td>
734
+ <td style="color: var(--text-muted)">.deezer.com</td>
735
+ <td><span class="badge badge-muted">strictly-necessary</span></td>
736
+ <td style="color: var(--text-muted)">3mo</td>
737
+ <td><span class="badge badge-muted">No</span></td>
738
+ </tr>
739
+ <tr>
740
+ <td><code>ajs_anonymous_id</code></td>
741
+ <td style="color: var(--text-muted)">.deezer.com</td>
742
+ <td><span class="badge badge-muted">analytics</span></td>
743
+ <td style="color: var(--text-muted)">12mo</td>
744
+ <td><span class="badge badge-warning">Required</span></td>
745
+ </tr>
746
+ <tr>
747
+ <td><code>_abck</code></td>
748
+ <td style="color: var(--text-muted)">.deezer.com</td>
749
+ <td><span class="badge badge-muted">unknown</span></td>
750
+ <td style="color: var(--text-muted)">12mo</td>
751
+ <td><span class="badge badge-muted">No</span></td>
752
+ </tr>
753
+ </tbody>
754
+ </table>
755
+ </div>
756
+ <div style="margin-bottom: 24px">
757
+ <div
758
+ style="
759
+ font-size: 12px;
760
+ font-weight: 600;
761
+ text-transform: uppercase;
762
+ letter-spacing: 0.04em;
763
+ color: var(--text-muted);
764
+ margin-bottom: 8px;
765
+ display: flex;
766
+ align-items: center;
767
+ gap: 8px;
768
+ "
769
+ >
770
+ After accept
771
+ <span class="count-badge">40</span>
772
+ </div>
773
+ <table class="data-table">
774
+ <thead>
775
+ <tr>
776
+ <th>Name</th>
777
+ <th>Domain</th>
778
+ <th>Category</th>
779
+ <th>Expiry</th>
780
+ <th>Consent</th>
781
+ </tr>
782
+ </thead>
783
+ <tbody>
784
+ <tr>
785
+ <td><code>X-AB</code></td>
786
+ <td style="color: var(--text-muted)">sc-static.net</td>
787
+ <td><span class="badge badge-muted">unknown</span></td>
788
+ <td style="color: var(--text-muted)">1d</td>
789
+ <td><span class="badge badge-warning">Required</span></td>
790
+ </tr>
791
+ <tr>
792
+ <td><code>sid</code></td>
793
+ <td style="color: var(--text-muted)">.deezer.com</td>
794
+ <td><span class="badge badge-muted">unknown</span></td>
795
+ <td style="color: var(--text-muted)">Session</td>
796
+ <td><span class="badge badge-warning">Required</span></td>
797
+ </tr>
798
+ <tr>
799
+ <td><code>dzr_uniq_id</code></td>
800
+ <td style="color: var(--text-muted)">.deezer.com</td>
801
+ <td><span class="badge badge-muted">unknown</span></td>
802
+ <td style="color: var(--text-muted)">6mo</td>
803
+ <td><span class="badge badge-muted">No</span></td>
804
+ </tr>
805
+ <tr>
806
+ <td><code>bm_sz</code></td>
807
+ <td style="color: var(--text-muted)">.deezer.com</td>
808
+ <td><span class="badge badge-muted">unknown</span></td>
809
+ <td style="color: var(--text-muted)">< 1 day</td>
810
+ <td><span class="badge badge-muted">No</span></td>
811
+ </tr>
812
+ <tr>
813
+ <td><code>euconsent-v2</code></td>
814
+ <td style="color: var(--text-muted)">.deezer.com</td>
815
+ <td><span class="badge badge-muted">unknown</span></td>
816
+ <td style="color: var(--text-muted)">3mo</td>
817
+ <td><span class="badge badge-muted">No</span></td>
818
+ </tr>
819
+ <tr>
820
+ <td><code>noIabVendors</code></td>
821
+ <td style="color: var(--text-muted)">.deezer.com</td>
822
+ <td><span class="badge badge-muted">unknown</span></td>
823
+ <td style="color: var(--text-muted)">3mo</td>
824
+ <td><span class="badge badge-muted">No</span></td>
825
+ </tr>
826
+ <tr>
827
+ <td><code>pageviewCount</code></td>
828
+ <td style="color: var(--text-muted)">.deezer.com</td>
829
+ <td><span class="badge badge-muted">unknown</span></td>
830
+ <td style="color: var(--text-muted)">1d</td>
831
+ <td><span class="badge badge-muted">No</span></td>
832
+ </tr>
833
+ <tr>
834
+ <td><code>consentMarketing</code></td>
835
+ <td style="color: var(--text-muted)">.deezer.com</td>
836
+ <td><span class="badge badge-muted">strictly-necessary</span></td>
837
+ <td style="color: var(--text-muted)">3mo</td>
838
+ <td><span class="badge badge-muted">No</span></td>
839
+ </tr>
840
+ <tr>
841
+ <td><code>consentStatistics</code></td>
842
+ <td style="color: var(--text-muted)">.deezer.com</td>
843
+ <td><span class="badge badge-muted">strictly-necessary</span></td>
844
+ <td style="color: var(--text-muted)">3mo</td>
845
+ <td><span class="badge badge-muted">No</span></td>
846
+ </tr>
847
+ <tr>
848
+ <td><code>ajs_anonymous_id</code></td>
849
+ <td style="color: var(--text-muted)">.deezer.com</td>
850
+ <td><span class="badge badge-muted">analytics</span></td>
851
+ <td style="color: var(--text-muted)">12mo</td>
852
+ <td><span class="badge badge-warning">Required</span></td>
853
+ </tr>
854
+ <tr>
855
+ <td><code>_rdt_uuid</code></td>
856
+ <td style="color: var(--text-muted)">.deezer.com</td>
857
+ <td><span class="badge badge-muted">unknown</span></td>
858
+ <td style="color: var(--text-muted)">3mo</td>
859
+ <td><span class="badge badge-muted">No</span></td>
860
+ </tr>
861
+ <tr>
862
+ <td><code>IR_gbd</code></td>
863
+ <td style="color: var(--text-muted)">.deezer.com</td>
864
+ <td><span class="badge badge-muted">unknown</span></td>
865
+ <td style="color: var(--text-muted)">Session</td>
866
+ <td><span class="badge badge-muted">No</span></td>
867
+ </tr>
868
+ <tr>
869
+ <td><code>IR_28329</code></td>
870
+ <td style="color: var(--text-muted)">.deezer.com</td>
871
+ <td><span class="badge badge-muted">unknown</span></td>
872
+ <td style="color: var(--text-muted)">Session</td>
873
+ <td><span class="badge badge-muted">No</span></td>
874
+ </tr>
875
+ <tr>
876
+ <td><code>_abck</code></td>
877
+ <td style="color: var(--text-muted)">.deezer.com</td>
878
+ <td><span class="badge badge-muted">unknown</span></td>
879
+ <td style="color: var(--text-muted)">12mo</td>
880
+ <td><span class="badge badge-muted">No</span></td>
881
+ </tr>
882
+ <tr>
883
+ <td><code>brwsr</code></td>
884
+ <td style="color: var(--text-muted)">.sjv.io</td>
885
+ <td><span class="badge badge-muted">unknown</span></td>
886
+ <td style="color: var(--text-muted)">12mo</td>
887
+ <td><span class="badge badge-muted">No</span></td>
888
+ </tr>
889
+ <tr>
890
+ <td><code>irld</code></td>
891
+ <td style="color: var(--text-muted)">deezer.sjv.io</td>
892
+ <td><span class="badge badge-muted">unknown</span></td>
893
+ <td style="color: var(--text-muted)">6mo</td>
894
+ <td><span class="badge badge-warning">Required</span></td>
895
+ </tr>
896
+ <tr>
897
+ <td><code>irtps</code></td>
898
+ <td style="color: var(--text-muted)">.sjv.io</td>
899
+ <td><span class="badge badge-muted">unknown</span></td>
900
+ <td style="color: var(--text-muted)">1d</td>
901
+ <td><span class="badge badge-muted">No</span></td>
902
+ </tr>
903
+ <tr>
904
+ <td><code>_ga</code></td>
905
+ <td style="color: var(--text-muted)">.deezer.com</td>
906
+ <td><span class="badge badge-muted">analytics</span></td>
907
+ <td style="color: var(--text-muted)">13mo</td>
908
+ <td><span class="badge badge-warning">Required</span></td>
909
+ </tr>
910
+ <tr>
911
+ <td><code>_ttp</code></td>
912
+ <td style="color: var(--text-muted)">.tiktok.com</td>
913
+ <td><span class="badge badge-muted">advertising</span></td>
914
+ <td style="color: var(--text-muted)">3mo</td>
915
+ <td><span class="badge badge-warning">Required</span></td>
916
+ </tr>
917
+ <tr>
918
+ <td><code>_scid</code></td>
919
+ <td style="color: var(--text-muted)">.deezer.com</td>
920
+ <td><span class="badge badge-muted">unknown</span></td>
921
+ <td style="color: var(--text-muted)">13mo</td>
922
+ <td><span class="badge badge-muted">No</span></td>
923
+ </tr>
924
+ <tr>
925
+ <td><code>_scid_r</code></td>
926
+ <td style="color: var(--text-muted)">.deezer.com</td>
927
+ <td><span class="badge badge-muted">unknown</span></td>
928
+ <td style="color: var(--text-muted)">13mo</td>
929
+ <td><span class="badge badge-muted">No</span></td>
930
+ </tr>
931
+ <tr>
932
+ <td><code>IR_PI</code></td>
933
+ <td style="color: var(--text-muted)">.deezer.com</td>
934
+ <td><span class="badge badge-muted">unknown</span></td>
935
+ <td style="color: var(--text-muted)">13mo</td>
936
+ <td><span class="badge badge-muted">No</span></td>
937
+ </tr>
938
+ <tr>
939
+ <td><code>_cs_c</code></td>
940
+ <td style="color: var(--text-muted)">.deezer.com</td>
941
+ <td><span class="badge badge-muted">unknown</span></td>
942
+ <td style="color: var(--text-muted)">13mo</td>
943
+ <td><span class="badge badge-muted">No</span></td>
944
+ </tr>
945
+ <tr>
946
+ <td><code>_cs_id</code></td>
947
+ <td style="color: var(--text-muted)">.deezer.com</td>
948
+ <td><span class="badge badge-muted">unknown</span></td>
949
+ <td style="color: var(--text-muted)">13mo</td>
950
+ <td><span class="badge badge-muted">No</span></td>
951
+ </tr>
952
+ <tr>
953
+ <td><code>_fbp</code></td>
954
+ <td style="color: var(--text-muted)">.deezer.com</td>
955
+ <td><span class="badge badge-muted">advertising</span></td>
956
+ <td style="color: var(--text-muted)">3mo</td>
957
+ <td><span class="badge badge-warning">Required</span></td>
958
+ </tr>
959
+ <tr>
960
+ <td><code>_cs_s</code></td>
961
+ <td style="color: var(--text-muted)">.deezer.com</td>
962
+ <td><span class="badge badge-muted">unknown</span></td>
963
+ <td style="color: var(--text-muted)">< 1 day</td>
964
+ <td><span class="badge badge-muted">No</span></td>
965
+ </tr>
966
+ <tr>
967
+ <td><code>_uetsid</code></td>
968
+ <td style="color: var(--text-muted)">.deezer.com</td>
969
+ <td><span class="badge badge-muted">unknown</span></td>
970
+ <td style="color: var(--text-muted)">1d</td>
971
+ <td><span class="badge badge-muted">No</span></td>
972
+ </tr>
973
+ <tr>
974
+ <td><code>_uetvid</code></td>
975
+ <td style="color: var(--text-muted)">.deezer.com</td>
976
+ <td><span class="badge badge-muted">unknown</span></td>
977
+ <td style="color: var(--text-muted)">13mo</td>
978
+ <td><span class="badge badge-muted">No</span></td>
979
+ </tr>
980
+ <tr>
981
+ <td><code>brwsr</code></td>
982
+ <td style="color: var(--text-muted)">.ojrq.net</td>
983
+ <td><span class="badge badge-muted">unknown</span></td>
984
+ <td style="color: var(--text-muted)">12mo</td>
985
+ <td><span class="badge badge-muted">No</span></td>
986
+ </tr>
987
+ <tr>
988
+ <td><code>_tt_enable_cookie</code></td>
989
+ <td style="color: var(--text-muted)">.deezer.com</td>
990
+ <td><span class="badge badge-muted">unknown</span></td>
991
+ <td style="color: var(--text-muted)">3mo</td>
992
+ <td><span class="badge badge-muted">No</span></td>
993
+ </tr>
994
+ <tr>
995
+ <td><code>_ttp</code></td>
996
+ <td style="color: var(--text-muted)">.deezer.com</td>
997
+ <td><span class="badge badge-muted">advertising</span></td>
998
+ <td style="color: var(--text-muted)">3mo</td>
999
+ <td><span class="badge badge-warning">Required</span></td>
1000
+ </tr>
1001
+ <tr>
1002
+ <td><code>MUID</code></td>
1003
+ <td style="color: var(--text-muted)">.bing.com</td>
1004
+ <td><span class="badge badge-muted">advertising</span></td>
1005
+ <td style="color: var(--text-muted)">13mo</td>
1006
+ <td><span class="badge badge-warning">Required</span></td>
1007
+ </tr>
1008
+ <tr>
1009
+ <td><code>_gcl_au</code></td>
1010
+ <td style="color: var(--text-muted)">.deezer.com</td>
1011
+ <td><span class="badge badge-muted">unknown</span></td>
1012
+ <td style="color: var(--text-muted)">3mo</td>
1013
+ <td><span class="badge badge-muted">No</span></td>
1014
+ </tr>
1015
+ <tr>
1016
+ <td><code>_ga_QHEXZ4K1SH</code></td>
1017
+ <td style="color: var(--text-muted)">.deezer.com</td>
1018
+ <td><span class="badge badge-muted">analytics</span></td>
1019
+ <td style="color: var(--text-muted)">13mo</td>
1020
+ <td><span class="badge badge-warning">Required</span></td>
1021
+ </tr>
1022
+ <tr>
1023
+ <td><code>_ScCbts</code></td>
1024
+ <td style="color: var(--text-muted)">.deezer.com</td>
1025
+ <td><span class="badge badge-muted">unknown</span></td>
1026
+ <td style="color: var(--text-muted)">7d</td>
1027
+ <td><span class="badge badge-muted">No</span></td>
1028
+ </tr>
1029
+ <tr>
1030
+ <td><code>ttcsid</code></td>
1031
+ <td style="color: var(--text-muted)">.deezer.com</td>
1032
+ <td><span class="badge badge-muted">unknown</span></td>
1033
+ <td style="color: var(--text-muted)">3mo</td>
1034
+ <td><span class="badge badge-muted">No</span></td>
1035
+ </tr>
1036
+ <tr>
1037
+ <td><code>ttcsid_C5A7OKS6J7TSRVQBNON0</code></td>
1038
+ <td style="color: var(--text-muted)">.deezer.com</td>
1039
+ <td><span class="badge badge-muted">unknown</span></td>
1040
+ <td style="color: var(--text-muted)">3mo</td>
1041
+ <td><span class="badge badge-muted">No</span></td>
1042
+ </tr>
1043
+ <tr>
1044
+ <td><code>_clck</code></td>
1045
+ <td style="color: var(--text-muted)">.deezer.com</td>
1046
+ <td><span class="badge badge-muted">unknown</span></td>
1047
+ <td style="color: var(--text-muted)">12mo</td>
1048
+ <td><span class="badge badge-muted">No</span></td>
1049
+ </tr>
1050
+ <tr>
1051
+ <td><code>IDE</code></td>
1052
+ <td style="color: var(--text-muted)">.doubleclick.net</td>
1053
+ <td><span class="badge badge-muted">advertising</span></td>
1054
+ <td style="color: var(--text-muted)">13mo</td>
1055
+ <td><span class="badge badge-warning">Required</span></td>
1056
+ </tr>
1057
+ <tr>
1058
+ <td><code>_clsk</code></td>
1059
+ <td style="color: var(--text-muted)">.deezer.com</td>
1060
+ <td><span class="badge badge-muted">unknown</span></td>
1061
+ <td style="color: var(--text-muted)">1d</td>
1062
+ <td><span class="badge badge-muted">No</span></td>
1063
+ </tr>
1064
+ </tbody>
1065
+ </table>
1066
+ </div>
1067
+ </div>
1068
+ </div>
1069
+
1070
+ <div class="section">
1071
+ <div class="section-header">
1072
+ <h2>Network trackers</h2>
1073
+ <span class="count-badge">54</span>
1074
+ <span class="badge badge-critical">8 before consent</span>
1075
+ </div>
1076
+ <div class="section-body no-pad">
1077
+ <table class="data-table">
1078
+ <thead>
1079
+ <tr>
1080
+ <th>Tracker</th>
1081
+ <th>Category</th>
1082
+ <th>Phase</th>
1083
+ <th>URL</th>
1084
+ </tr>
1085
+ </thead>
1086
+ <tbody>
1087
+ <tr>
1088
+ <td>Google Tag Manager</td>
1089
+ <td><span class="badge badge-muted">analytics</span></td>
1090
+ <td><span class="badge badge-critical">before consent</span></td>
1091
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1092
+ <code>https://www.googletagmanager.com/gtm.js?id=GTM-PPQNZ6</code>
1093
+ </td>
1094
+ </tr>
1095
+ <tr>
1096
+ <td>Segment</td>
1097
+ <td><span class="badge badge-muted">analytics</span></td>
1098
+ <td><span class="badge badge-critical">before consent</span></td>
1099
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1100
+ <code>https://cdn.segment.com/v1/projects/VyJDmr2wHu0SDrieAdHE8tIX2Gi2WgU…</code>
1101
+ </td>
1102
+ </tr>
1103
+ <tr>
1104
+ <td>Google AdSense</td>
1105
+ <td><span class="badge badge-muted">advertising</span></td>
1106
+ <td><span class="badge badge-critical">before consent</span></td>
1107
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1108
+ <code
1109
+ >https://pagead2.googlesyndication.com/ccm/collect?frm=0&amp;en=page_vie…</code
1110
+ >
1111
+ </td>
1112
+ </tr>
1113
+ <tr>
1114
+ <td>Google Tag Manager</td>
1115
+ <td><span class="badge badge-muted">analytics</span></td>
1116
+ <td><span class="badge badge-critical">before consent</span></td>
1117
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1118
+ <code>https://www.googletagmanager.com/static/service_worker/6240/sw_ifra…</code>
1119
+ </td>
1120
+ </tr>
1121
+ <tr>
1122
+ <td>Segment</td>
1123
+ <td><span class="badge badge-muted">analytics</span></td>
1124
+ <td><span class="badge badge-critical">before consent</span></td>
1125
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1126
+ <code>https://cdn.segment.com/next-integrations/actions/braze-cloud-plugi…</code>
1127
+ </td>
1128
+ </tr>
1129
+ <tr>
1130
+ <td>Segment</td>
1131
+ <td><span class="badge badge-muted">analytics</span></td>
1132
+ <td><span class="badge badge-critical">before consent</span></td>
1133
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1134
+ <code>https://cdn.segment.com/next-integrations/actions/3962/1faa179dfb20…</code>
1135
+ </td>
1136
+ </tr>
1137
+ <tr>
1138
+ <td>Segment</td>
1139
+ <td><span class="badge badge-muted">analytics</span></td>
1140
+ <td><span class="badge badge-critical">before consent</span></td>
1141
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1142
+ <code>https://cdn.segment.com/next-integrations/integrations/survicate/1.…</code>
1143
+ </td>
1144
+ </tr>
1145
+ <tr>
1146
+ <td>Segment</td>
1147
+ <td><span class="badge badge-muted">analytics</span></td>
1148
+ <td><span class="badge badge-critical">before consent</span></td>
1149
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1150
+ <code>https://cdn.segment.com/next-integrations/integrations/vendor/commo…</code>
1151
+ </td>
1152
+ </tr>
1153
+ <tr>
1154
+ <td>Google Tag Manager</td>
1155
+ <td><span class="badge badge-muted">analytics</span></td>
1156
+ <td><span class="badge badge-muted">after-accept</span></td>
1157
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1158
+ <code>https://www.googletagmanager.com/gtm.js?id=GTM-PPQNZ6</code>
1159
+ </td>
1160
+ </tr>
1161
+ <tr>
1162
+ <td>Segment</td>
1163
+ <td><span class="badge badge-muted">analytics</span></td>
1164
+ <td><span class="badge badge-muted">after-accept</span></td>
1165
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1166
+ <code>https://cdn.segment.com/v1/projects/VyJDmr2wHu0SDrieAdHE8tIX2Gi2WgU…</code>
1167
+ </td>
1168
+ </tr>
1169
+ <tr>
1170
+ <td>Google AdSense</td>
1171
+ <td><span class="badge badge-muted">advertising</span></td>
1172
+ <td><span class="badge badge-muted">after-accept</span></td>
1173
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1174
+ <code
1175
+ >https://pagead2.googlesyndication.com/ccm/collect?frm=0&amp;en=page_vie…</code
1176
+ >
1177
+ </td>
1178
+ </tr>
1179
+ <tr>
1180
+ <td>Google Tag Manager</td>
1181
+ <td><span class="badge badge-muted">analytics</span></td>
1182
+ <td><span class="badge badge-muted">after-accept</span></td>
1183
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1184
+ <code>https://www.googletagmanager.com/static/service_worker/6240/sw_ifra…</code>
1185
+ </td>
1186
+ </tr>
1187
+ <tr>
1188
+ <td>Segment</td>
1189
+ <td><span class="badge badge-muted">analytics</span></td>
1190
+ <td><span class="badge badge-muted">after-accept</span></td>
1191
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1192
+ <code>https://cdn.segment.com/next-integrations/actions/braze-cloud-plugi…</code>
1193
+ </td>
1194
+ </tr>
1195
+ <tr>
1196
+ <td>Segment</td>
1197
+ <td><span class="badge badge-muted">analytics</span></td>
1198
+ <td><span class="badge badge-muted">after-accept</span></td>
1199
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1200
+ <code>https://cdn.segment.com/next-integrations/actions/3962/1faa179dfb20…</code>
1201
+ </td>
1202
+ </tr>
1203
+ <tr>
1204
+ <td>Segment</td>
1205
+ <td><span class="badge badge-muted">analytics</span></td>
1206
+ <td><span class="badge badge-muted">after-accept</span></td>
1207
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1208
+ <code>https://cdn.segment.com/next-integrations/integrations/survicate/1.…</code>
1209
+ </td>
1210
+ </tr>
1211
+ <tr>
1212
+ <td>Segment</td>
1213
+ <td><span class="badge badge-muted">analytics</span></td>
1214
+ <td><span class="badge badge-muted">after-accept</span></td>
1215
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1216
+ <code>https://cdn.segment.com/next-integrations/integrations/vendor/commo…</code>
1217
+ </td>
1218
+ </tr>
1219
+ <tr>
1220
+ <td>Google Tag Manager</td>
1221
+ <td><span class="badge badge-muted">analytics</span></td>
1222
+ <td><span class="badge badge-muted">after-accept</span></td>
1223
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1224
+ <code
1225
+ >https://www.googletagmanager.com/gtag/js?id=DC-14894270&amp;cx=c&amp;gtm=4e…</code
1226
+ >
1227
+ </td>
1228
+ </tr>
1229
+ <tr>
1230
+ <td>Google Tag Manager</td>
1231
+ <td><span class="badge badge-muted">analytics</span></td>
1232
+ <td><span class="badge badge-muted">after-accept</span></td>
1233
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1234
+ <code
1235
+ >https://www.googletagmanager.com/gtag/js?id=AW-988306579&amp;cx=c&amp;gtm=4…</code
1236
+ >
1237
+ </td>
1238
+ </tr>
1239
+ <tr>
1240
+ <td>TikTok Analytics</td>
1241
+ <td><span class="badge badge-muted">analytics</span></td>
1242
+ <td><span class="badge badge-muted">after-accept</span></td>
1243
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1244
+ <code>https://analytics.tiktok.com/i18n/pixel/events.js?sdkid=C5A7OKS6J7T…</code>
1245
+ </td>
1246
+ </tr>
1247
+ <tr>
1248
+ <td>Bing Ads</td>
1249
+ <td><span class="badge badge-muted">advertising</span></td>
1250
+ <td><span class="badge badge-muted">after-accept</span></td>
1251
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1252
+ <code>https://bat.bing.com/bat.js</code>
1253
+ </td>
1254
+ </tr>
1255
+ <tr>
1256
+ <td>Facebook SDK</td>
1257
+ <td><span class="badge badge-muted">social</span></td>
1258
+ <td><span class="badge badge-muted">after-accept</span></td>
1259
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1260
+ <code>https://connect.facebook.net/en_US/fbevents.js</code>
1261
+ </td>
1262
+ </tr>
1263
+ <tr>
1264
+ <td>Google Tag Manager</td>
1265
+ <td><span class="badge badge-muted">analytics</span></td>
1266
+ <td><span class="badge badge-muted">after-accept</span></td>
1267
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1268
+ <code
1269
+ >https://www.googletagmanager.com/gtag/js?id=G-QHEXZ4K1SH&amp;cx=c&amp;gtm=4…</code
1270
+ >
1271
+ </td>
1272
+ </tr>
1273
+ <tr>
1274
+ <td>Tracking Pixel</td>
1275
+ <td><span class="badge badge-muted">pixel</span></td>
1276
+ <td><span class="badge badge-muted">after-accept</span></td>
1277
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1278
+ <code
1279
+ >https://alb.reddit.com/rp.gif?ts=1771789981100&amp;id=a2_h7t01c9hiroo&amp;e…</code
1280
+ >
1281
+ </td>
1282
+ </tr>
1283
+ <tr>
1284
+ <td>Google AdSense</td>
1285
+ <td><span class="badge badge-muted">advertising</span></td>
1286
+ <td><span class="badge badge-muted">after-accept</span></td>
1287
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1288
+ <code
1289
+ >https://pagead2.googlesyndication.com/ccm/collect?frm=0&amp;en=page_vie…</code
1290
+ >
1291
+ </td>
1292
+ </tr>
1293
+ <tr>
1294
+ <td>Google AdSense</td>
1295
+ <td><span class="badge badge-muted">advertising</span></td>
1296
+ <td><span class="badge badge-muted">after-accept</span></td>
1297
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1298
+ <code>https://ade.googlesyndication.com/ddm/activity/src=14894270;type=in…</code>
1299
+ </td>
1300
+ </tr>
1301
+ <tr>
1302
+ <td>Google AdSense</td>
1303
+ <td><span class="badge badge-muted">advertising</span></td>
1304
+ <td><span class="badge badge-muted">after-accept</span></td>
1305
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1306
+ <code>https://pagead2.googlesyndication.com/pagead/conversion/988306579/?…</code>
1307
+ </td>
1308
+ </tr>
1309
+ <tr>
1310
+ <td>Google AdSense</td>
1311
+ <td><span class="badge badge-muted">advertising</span></td>
1312
+ <td><span class="badge badge-muted">after-accept</span></td>
1313
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1314
+ <code
1315
+ >https://pagead2.googlesyndication.com/ccm/collect?frm=0&amp;en=page_vie…</code
1316
+ >
1317
+ </td>
1318
+ </tr>
1319
+ <tr>
1320
+ <td>Google Analytics</td>
1321
+ <td><span class="badge badge-muted">analytics</span></td>
1322
+ <td><span class="badge badge-muted">after-accept</span></td>
1323
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1324
+ <code
1325
+ >https://region1.google-analytics.com/g/collect?v=2&amp;tid=G-QHEXZ4K1SH…</code
1326
+ >
1327
+ </td>
1328
+ </tr>
1329
+ <tr>
1330
+ <td>Google AdSense</td>
1331
+ <td><span class="badge badge-muted">advertising</span></td>
1332
+ <td><span class="badge badge-muted">after-accept</span></td>
1333
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1334
+ <code>https://ade.googlesyndication.com/ddm/activity/src=14894270;dc_pre=…</code>
1335
+ </td>
1336
+ </tr>
1337
+ <tr>
1338
+ <td>Facebook SDK</td>
1339
+ <td><span class="badge badge-muted">social</span></td>
1340
+ <td><span class="badge badge-muted">after-accept</span></td>
1341
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1342
+ <code>https://connect.facebook.net/signals/config/264792006515013?v=2.9.2…</code>
1343
+ </td>
1344
+ </tr>
1345
+ <tr>
1346
+ <td>Bing Ads</td>
1347
+ <td><span class="badge badge-muted">advertising</span></td>
1348
+ <td><span class="badge badge-muted">after-accept</span></td>
1349
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1350
+ <code>https://bat.bing.com/p/action/5601943.js</code>
1351
+ </td>
1352
+ </tr>
1353
+ <tr>
1354
+ <td>TikTok Analytics</td>
1355
+ <td><span class="badge badge-muted">analytics</span></td>
1356
+ <td><span class="badge badge-muted">after-accept</span></td>
1357
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1358
+ <code>https://analytics.tiktok.com/i18n/pixel/static/main.MWIwNzUxMTllMQ.js</code>
1359
+ </td>
1360
+ </tr>
1361
+ <tr>
1362
+ <td>Microsoft Clarity</td>
1363
+ <td><span class="badge badge-muted">analytics</span></td>
1364
+ <td><span class="badge badge-muted">after-accept</span></td>
1365
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1366
+ <code>https://www.clarity.ms/tag/uet/5601943</code>
1367
+ </td>
1368
+ </tr>
1369
+ <tr>
1370
+ <td>Bing Ads</td>
1371
+ <td><span class="badge badge-muted">advertising</span></td>
1372
+ <td><span class="badge badge-muted">after-accept</span></td>
1373
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1374
+ <code
1375
+ >https://bat.bing.com/actionp/0?ti=5601943&amp;tm=gtm002&amp;Ver=2&amp;mid=b7b66…</code
1376
+ >
1377
+ </td>
1378
+ </tr>
1379
+ <tr>
1380
+ <td>Bing Ads</td>
1381
+ <td><span class="badge badge-muted">advertising</span></td>
1382
+ <td><span class="badge badge-muted">after-accept</span></td>
1383
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1384
+ <code
1385
+ >https://bat.bing.com/action/0?ti=5601943&amp;tm=gtm002&amp;Ver=2&amp;mid=b7b66a…</code
1386
+ >
1387
+ </td>
1388
+ </tr>
1389
+ <tr>
1390
+ <td>TikTok Analytics</td>
1391
+ <td><span class="badge badge-muted">analytics</span></td>
1392
+ <td><span class="badge badge-muted">after-accept</span></td>
1393
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1394
+ <code>https://analytics.tiktok.com/i18n/pixel/static/identify_31760074.js</code>
1395
+ </td>
1396
+ </tr>
1397
+ <tr>
1398
+ <td>TikTok Analytics</td>
1399
+ <td><span class="badge badge-muted">analytics</span></td>
1400
+ <td><span class="badge badge-muted">after-accept</span></td>
1401
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1402
+ <code>https://analytics.tiktok.com/api/v2/pixel</code>
1403
+ </td>
1404
+ </tr>
1405
+ <tr>
1406
+ <td>TikTok Analytics</td>
1407
+ <td><span class="badge badge-muted">analytics</span></td>
1408
+ <td><span class="badge badge-muted">after-accept</span></td>
1409
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1410
+ <code>https://analytics.tiktok.com/api/v2/pixel</code>
1411
+ </td>
1412
+ </tr>
1413
+ <tr>
1414
+ <td>TikTok Analytics</td>
1415
+ <td><span class="badge badge-muted">analytics</span></td>
1416
+ <td><span class="badge badge-muted">after-accept</span></td>
1417
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1418
+ <code>https://analytics.tiktok.com/api/v2/pixel</code>
1419
+ </td>
1420
+ </tr>
1421
+ <tr>
1422
+ <td>Google DoubleClick</td>
1423
+ <td><span class="badge badge-muted">advertising</span></td>
1424
+ <td><span class="badge badge-muted">after-accept</span></td>
1425
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1426
+ <code>https://ad.doubleclick.net/activity;src=14894270;type=invmedia;cat=…</code>
1427
+ </td>
1428
+ </tr>
1429
+ <tr>
1430
+ <td>Google DoubleClick</td>
1431
+ <td><span class="badge badge-muted">advertising</span></td>
1432
+ <td><span class="badge badge-muted">after-accept</span></td>
1433
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1434
+ <code>https://14894270.fls.doubleclick.net/activityi;src=14894270;type=in…</code>
1435
+ </td>
1436
+ </tr>
1437
+ <tr>
1438
+ <td>Google DoubleClick</td>
1439
+ <td><span class="badge badge-muted">advertising</span></td>
1440
+ <td><span class="badge badge-muted">after-accept</span></td>
1441
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1442
+ <code>https://googleads.g.doubleclick.net/pagead/viewthroughconversion/98…</code>
1443
+ </td>
1444
+ </tr>
1445
+ <tr>
1446
+ <td>Google DoubleClick</td>
1447
+ <td><span class="badge badge-muted">advertising</span></td>
1448
+ <td><span class="badge badge-muted">after-accept</span></td>
1449
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1450
+ <code>https://googleads.g.doubleclick.net/pagead/viewthroughconversion/98…</code>
1451
+ </td>
1452
+ </tr>
1453
+ <tr>
1454
+ <td>Google Ad Services</td>
1455
+ <td><span class="badge badge-muted">advertising</span></td>
1456
+ <td><span class="badge badge-muted">after-accept</span></td>
1457
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1458
+ <code>https://www.googleadservices.com/pagead/conversion/988306579/?rando…</code>
1459
+ </td>
1460
+ </tr>
1461
+ <tr>
1462
+ <td>Bing Ads</td>
1463
+ <td><span class="badge badge-muted">advertising</span></td>
1464
+ <td><span class="badge badge-muted">after-accept</span></td>
1465
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1466
+ <code
1467
+ >https://bat.bing.com/actionp/0?ti=5601943&amp;tm=gtm002&amp;Ver=2&amp;mid=b7b66…</code
1468
+ >
1469
+ </td>
1470
+ </tr>
1471
+ <tr>
1472
+ <td>Bing Ads</td>
1473
+ <td><span class="badge badge-muted">advertising</span></td>
1474
+ <td><span class="badge badge-muted">after-accept</span></td>
1475
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1476
+ <code
1477
+ >https://bat.bing.com/actionp/0?ti=5601943&amp;tm=gtm002&amp;Ver=2&amp;mid=b7b66…</code
1478
+ >
1479
+ </td>
1480
+ </tr>
1481
+ <tr>
1482
+ <td>Google Analytics</td>
1483
+ <td><span class="badge badge-muted">analytics</span></td>
1484
+ <td><span class="badge badge-muted">after-accept</span></td>
1485
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1486
+ <code
1487
+ >https://region1.analytics.google.com/g/collect?v=2&amp;tid=G-QHEXZ4K1SH…</code
1488
+ >
1489
+ </td>
1490
+ </tr>
1491
+ <tr>
1492
+ <td>Tracking Pixel</td>
1493
+ <td><span class="badge badge-muted">pixel</span></td>
1494
+ <td><span class="badge badge-muted">after-accept</span></td>
1495
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1496
+ <code
1497
+ >https://www.google.com/ccm/collect?frm=0&amp;en=consent_update&amp;dl=https…</code
1498
+ >
1499
+ </td>
1500
+ </tr>
1501
+ <tr>
1502
+ <td>Microsoft Clarity</td>
1503
+ <td><span class="badge badge-muted">analytics</span></td>
1504
+ <td><span class="badge badge-muted">after-accept</span></td>
1505
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1506
+ <code>https://scripts.clarity.ms/0.8.54/clarity.js</code>
1507
+ </td>
1508
+ </tr>
1509
+ <tr>
1510
+ <td>Google DoubleClick</td>
1511
+ <td><span class="badge badge-muted">advertising</span></td>
1512
+ <td><span class="badge badge-muted">after-accept</span></td>
1513
+ <td style="font-size: 11px; color: var(--text-muted); word-break: break-all">
1514
+ <code>https://14894270.fls.doubleclick.net/activityi;dc_pre=COaV24Pw7ZIDF…</code>
1515
+ </td>
1516
+ </tr>
1517
+ </tbody>
1518
+ </table>
1519
+ <p style="padding: 12px 14px; font-size: 12px; color: var(--text-muted)">… and 4 more.</p>
1520
+ </div>
1521
+ </div>
1522
+
1523
+ <div class="section">
1524
+ <div class="section-header">
1525
+ <h2>Recommendations</h2>
1526
+ <span class="count-badge">2</span>
1527
+ </div>
1528
+ <div class="section-body">
1529
+ <ul class="rec-list">
1530
+ <li class="rec-item">
1531
+ <span class="rec-num">1</span>
1532
+ <span
1533
+ >Do not set any non-essential cookie before consent. Gate the initialisation of
1534
+ third-party scripts on the acceptance callback.</span
1535
+ >
1536
+ </li>
1537
+ <li class="rec-item">
1538
+ <span class="rec-num">2</span>
1539
+ <span
1540
+ >Remove or block non-essential cookies after rejection, and verify consent handling
1541
+ server-side.</span
1542
+ >
1543
+ </li>
1544
+ </ul>
1545
+ </div>
1546
+ </div>
1547
+
1548
+ <div class="section">
1549
+ <div class="section-header">
1550
+ <h2>Compliance checklist</h2>
1551
+ <span class="count-badge">12 rules</span>
1552
+ <span class="badge badge-ok">9 ✓</span>
1553
+ <span class="badge badge-critical">3 ✗</span>
1554
+ </div>
1555
+ <div class="section-body no-pad">
1556
+ <table class="data-table">
1557
+ <thead>
1558
+ <tr>
1559
+ <th>Category</th>
1560
+ <th>Rule</th>
1561
+ <th>Status</th>
1562
+ <th>Detail</th>
1563
+ </tr>
1564
+ </thead>
1565
+ <tbody>
1566
+ <tr>
1567
+ <td
1568
+ rowspan="3"
1569
+ style="font-weight: 600; vertical-align: top; background: var(--bg)"
1570
+ >
1571
+ Consent
1572
+ </td>
1573
+ <td>Consent modal detected</td>
1574
+ <td><span class="status-ok">✓ Compliant</span></td>
1575
+ <td style="color: var(--text-muted); font-size: 12px">
1576
+ Detected ([class*='cookie'][class*='modal'])
1577
+ </td>
1578
+ </tr>
1579
+ <tr>
1580
+ <td>No pre-ticked checkboxes</td>
1581
+ <td><span class="status-ok">✓ Compliant</span></td>
1582
+ <td style="color: var(--text-muted); font-size: 12px">None detected</td>
1583
+ </tr>
1584
+ <tr>
1585
+ <td>Unambiguous accept label</td>
1586
+ <td><span class="status-ok">✓ Compliant</span></td>
1587
+ <td style="color: var(--text-muted); font-size: 12px">Accepter</td>
1588
+ </tr>
1589
+ <tr>
1590
+ <td
1591
+ rowspan="3"
1592
+ style="font-weight: 600; vertical-align: top; background: var(--bg)"
1593
+ >
1594
+ Easy refusal
1595
+ </td>
1596
+ <td>Reject button at first layer</td>
1597
+ <td><span class="status-ok">✓ Compliant</span></td>
1598
+ <td style="color: var(--text-muted); font-size: 12px">Refuser</td>
1599
+ </tr>
1600
+ <tr>
1601
+ <td>Reject ≤ clicks than accept</td>
1602
+ <td><span class="status-ok">✓ Compliant</span></td>
1603
+ <td style="color: var(--text-muted); font-size: 12px">Accept: 1 · Reject: 1</td>
1604
+ </tr>
1605
+ <tr>
1606
+ <td>Button size symmetry</td>
1607
+ <td><span class="status-ok">✓ Compliant</span></td>
1608
+ <td style="color: var(--text-muted); font-size: 12px">Comparable sizes</td>
1609
+ </tr>
1610
+ <tr>
1611
+ <td
1612
+ rowspan="3"
1613
+ style="font-weight: 600; vertical-align: top; background: var(--bg)"
1614
+ >
1615
+ Transparency
1616
+ </td>
1617
+ <td>Granular controls available</td>
1618
+ <td><span class="status-ok">✓ Compliant</span></td>
1619
+ <td style="color: var(--text-muted); font-size: 12px">0 control(s) detected</td>
1620
+ </tr>
1621
+ <tr>
1622
+ <td>Privacy policy in modal</td>
1623
+ <td><span class="status-ok">✓ Compliant</span></td>
1624
+ <td style="color: var(--text-muted); font-size: 12px">
1625
+ https://vdp.deezer.com/p/Welcome
1626
+ </td>
1627
+ </tr>
1628
+ <tr>
1629
+ <td>Privacy policy on page</td>
1630
+ <td><span class="status-ok">✓ Compliant</span></td>
1631
+ <td style="color: var(--text-muted); font-size: 12px">
1632
+ https://vdp.deezer.com/p/Welcome
1633
+ </td>
1634
+ </tr>
1635
+ <tr>
1636
+ <td
1637
+ rowspan="3"
1638
+ style="font-weight: 600; vertical-align: top; background: var(--bg)"
1639
+ >
1640
+ Cookie behavior
1641
+ </td>
1642
+ <td>No non-essential cookie before consent</td>
1643
+ <td><span class="status-ko">✗ Non-compliant</span></td>
1644
+ <td style="color: var(--text-muted); font-size: 12px">1: sid</td>
1645
+ </tr>
1646
+ <tr>
1647
+ <td>Non-essential cookies removed after reject</td>
1648
+ <td><span class="status-ko">✗ Non-compliant</span></td>
1649
+ <td style="color: var(--text-muted); font-size: 12px">2 persisting</td>
1650
+ </tr>
1651
+ <tr>
1652
+ <td>No tracker before consent</td>
1653
+ <td><span class="status-ko">✗ Non-compliant</span></td>
1654
+ <td style="color: var(--text-muted); font-size: 12px">8 tracker(s)</td>
1655
+ </tr>
1656
+ </tbody>
1657
+ </table>
1658
+ </div>
1659
+ </div>
1660
+
1661
+ <div class="footer">
1662
+ Generated by <a href="https://github.com/Slashgear/gdpr-report">gdpr-cookie-scanner</a>
1663
+ on 22 February 2026 at 20:53
1664
+ </div>
1665
+ </div>
1666
+ </body>
1667
+ </html>