diff --git a/.paul/PROJECT.md b/.paul/PROJECT.md
index 6bd2ca7..2d8dcc9 100644
--- a/.paul/PROJECT.md
+++ b/.paul/PROJECT.md
@@ -13,7 +13,7 @@ Uzytkownicy moga szybko i bezpiecznie kupic bilety online oraz otrzymac natychmi
- [x] Poprawne rejestrowanie zamowien i danych transakcyjnych
- [x] Data layer purchase po finalizacji zakupu (wdrozone w Phase 1)
- [x] Event purchase capturuje 100% zamowien — fires przy skladaniu, nie przy powrocie z P24 (Phase 2)
-- [ ] Zgodnosc z RODO — baner zgody na cookies z Google Consent Mode v2 (Phase 3)
+- [x] Zgodnosc z RODO — baner zgody na cookies z Google Consent Mode v2 (Phase 3)
### Should Have
- [x] Spojny tracking analityczny dla zdarzen ecommerce
@@ -34,13 +34,15 @@ Uzytkownicy moga szybko i bezpiecznie kupic bilety online oraz otrzymac natychmi
| Event purchase na order-confirm (post-payment) | Phase 1 | Eliminuje falszywe konwersje |
| ZMIANA: Event purchase na przelewy24 (pre-payment, post-order) | Phase 2 | Capturuje 100% zamowien, beacon transport |
| Payload ecommerce budowany w backendzie | Phase 1 | Bezpieczenstwo, brak XSS |
+| cookieNoticePro.init() zamiast $.fn.cookieNoticePro() | Phase 3 | Zgodnie z dokumentacja biblioteki |
+| Consent Mode v2 default-denied przed GTM snippetem | Phase 3 | Wymog Google od marca 2024 |
## Success Criteria
- Event purchase trafia do data layer po zlozeniu zamowienia (osiagniete — Phase 2)
- Payload zawiera wszystkie dostepne dane transakcyjne i produktowe
- Integracja nie wplywa negatywnie na istniejacy checkout
-- Baner cookies zgodny z RODO + Google Consent Mode v2 (cel Phase 3)
+- Baner cookies zgodny z RODO + Google Consent Mode v2 (osiagniete — Phase 3)
---
*Created: 2026-04-19 20:20*
-*Last updated: 2026-04-26 after Phase 2*
+*Last updated: 2026-04-26 after Phase 3 (v0.2 complete)*
diff --git a/.paul/ROADMAP.md b/.paul/ROADMAP.md
index 8189ca9..0ca8535 100644
--- a/.paul/ROADMAP.md
+++ b/.paul/ROADMAP.md
@@ -5,8 +5,8 @@ W najblizszej iteracji skupiamy sie na uzupelnieniu warstwy analitycznej po zaku
## Current Milestone
**v0.2 Analytics & Privacy** (v0.2.0)
-Status: In progress
-Phases: 1 of 2 complete
+Status: Complete (2026-04-26)
+Phases: 3 of 3 complete
## Previous Milestones
@@ -20,7 +20,7 @@ Phases: 1 of 1 complete
|-------|------|-------|--------|-----------|
| 1 | Purchase Data Layer | 1 | Complete | 2026-04-19 |
| 2 | Purchase Event Pre-Payment | 1 | Complete | 2026-04-26 |
-| 3 | Cookie Consent Banner | 1 | Not started | — |
+| 3 | Cookie Consent Banner | 1 | Complete | 2026-04-26 |
## Phase Details
diff --git a/.paul/STATE.md b/.paul/STATE.md
index 61702a5..fd0a206 100644
--- a/.paul/STATE.md
+++ b/.paul/STATE.md
@@ -2,29 +2,29 @@
## Project Reference
-See: .paul/PROJECT.md (updated 2026-04-19)
+See: .paul/PROJECT.md (updated 2026-04-26)
**Core value:** Uzytkownicy moga szybko i bezpiecznie kupic bilety online oraz otrzymac natychmiastowe potwierdzenie zakupu.
-**Current focus:** v0.2 Analytics & Privacy — Phase 2 (Purchase Event Pre-Payment) planning
+**Current focus:** v0.2 Analytics & Privacy — COMPLETE
## Current Position
-Milestone: v0.2 Analytics & Privacy
-Phase: 2 of 3 (Purchase Event Pre-Payment) — Planning
-Plan: 02-01 executed
-Status: APPLY complete, ready for UNIFY
-Last activity: 2026-04-26 — Executed 02-01-PLAN.md (2 tasks, 3 files modified)
+Milestone: v0.2 Analytics & Privacy — COMPLETE
+Phase: 3 of 3 (Cookie Consent Banner) — Complete
+Plan: 03-01 complete
+Status: Milestone complete — ready for next milestone
+Last activity: 2026-04-26 — Phase 3 complete, v0.2 shipped
Progress:
-- Milestone: [░░░░░░░░░░] 0%
-- Phase 2: [░░░░░░░░░░] 0%
+- Milestone: [##########] 100%
+- Phase 3: [##########] 100%
## Loop Position
Current loop state:
```
-PLAN --> APPLY --> UNIFY
- ✓ ✓ ○ [APPLY complete, awaiting UNIFY]
+PLAN ──▶ APPLY ──▶ UNIFY
+ ✓ ✓ ✓ [Loop complete — milestone complete]
```
## Accumulated Context
@@ -34,34 +34,39 @@ Date: 2026-04-26
Documents: `.paul/codebase/` (8 files — stack, architecture, structure, conventions, testing, integrations, concerns, db_schema)
### GTM Status
-- GTM-TW9WCD9J już wdrożony w templates/site/layout-logged.php (i layout-unlogged.php)
+- GTM-TW9WCD9J już wdrożony w templates/site/layout-logged.php
- layout-unlogged.php NIE jest renderowany — view/class.Site.php zawsze używa layout-logged.php
### Decisions
-- 2026-04-19: Event `purchase` emitowany na `order-confirm`, nie na `przelewy24` (eliminuje falszywe konwersje).
+- 2026-04-19: Event purchase emitowany na order-confirm, nie na przelewy24 (eliminuje falszywe konwersje).
- 2026-04-19: Payload ecommerce budowany w backendzie i serializowany bezpiecznie do widoku.
-- 2026-04-26: ZMIANA DECYZJI — event purchase przenoszony na `przelewy24` (post-order, pre-payment) aby capturować użytkowników którzy nie wracają po płatności.
+- 2026-04-26: ZMIANA — event purchase przeniesiony na przelewy24 (post-order, pre-payment). Capturuje 100% zamowien.
+- 2026-04-26: cookieNoticePro.init() zamiast $.fn.cookieNoticePro() — zgodnie z dokumentacja biblioteki.
+- 2026-04-26: Consent Mode v2 default-denied inicjalizowany przed GTM snippetem (wymog Google od marca 2024).
-### Cookie Consent Bug
-- cookienoticepro.script.js ~linia 351: gdy analytics NIE zaakceptowane, kod wywołuje gtag('consent','update',{'analytics_storage':'granted'}) zamiast 'denied'
+### Cookie Consent (Phase 3 — COMPLETE)
+- Biblioteka: libraries/CookieNoticePro/ (skopiowana z pomysloweprezenty.pl)
+- Bug naprawiony: linia ~351 — blok else teraz wysyla analytics_storage: 'denied'
+- Dodatkowe poprawki: CSS initial hide dla acceptBtnSettingsLabel, Bootstrap 5 compat reset
+- Consent Mode v2 init PRZED snippetem GTM w layout-logged.php
### Deferred Issues
-- Phase 3: Cookie Consent Banner (zaplanowane po Phase 2)
+None.
### Blockers/Concerns
-None yet.
+None.
### Git State
-Last commit: 9de0429
+Last commit: 86e712b
Branch: main
Feature branches merged: none
## Session Continuity
Last session: 2026-04-26
-Stopped at: Plan 02-01 created
-Next action: Review and approve plan, then run /paul:apply .paul/phases/02-purchase-event-prepayment/02-01-PLAN.md
-Resume file: .paul/phases/02-purchase-event-prepayment/02-01-PLAN.md
+Stopped at: v0.2 milestone complete
+Next action: /paul:milestone — zdefiniuj v0.3 lub /paul:complete-milestone
+Resume file: .paul/ROADMAP.md
---
*STATE.md - Updated after every significant action*
diff --git a/.paul/changelog/2026-04-26.md b/.paul/changelog/2026-04-26.md
index bd8ac1a..43fd932 100644
--- a/.paul/changelog/2026-04-26.md
+++ b/.paul/changelog/2026-04-26.md
@@ -12,3 +12,18 @@
- `autoload/controls/class.Tickets.php`
- `templates/tickets/przelewy24.php`
- `templates/tickets/order-confirm.php`
+
+---
+
+- [Phase 3, Plan 01] Wdrożono baner zgody na cookies (CookieNoticePro) z Google Consent Mode v2
+- Skopiowano bibliotekę CookieNoticePro do libraries/CookieNoticePro/
+- Naprawiono błąd biblioteki: analytics_storage wysyłało 'granted' zamiast 'denied' przy odmowie
+- Dodano inicjalizację Consent Mode v2 (default: denied) przed snippetem GTM w layout-logged.php
+- Naprawiono inicjalizację pluginu: cookieNoticePro.init()
+- Naprawiono duplikat tekstu w przycisku (CSS display:none dla acceptBtnSettingsLabel)
+- Zmieniono link regulaminu na https://bilety.brzezovka.pl/tickets/regulamin/
+- Milestone v0.2 Analytics & Privacy — COMPLETE
+
+- `libraries/CookieNoticePro/cookienoticepro.script.js`
+- `libraries/CookieNoticePro/cookienoticepro.style.css`
+- `templates/site/layout-logged.php`
diff --git a/.paul/phases/03-cookie-consent/03-01-PLAN.md b/.paul/phases/03-cookie-consent/03-01-PLAN.md
new file mode 100644
index 0000000..dd8012d
--- /dev/null
+++ b/.paul/phases/03-cookie-consent/03-01-PLAN.md
@@ -0,0 +1,227 @@
+---
+phase: 03-cookie-consent
+plan: 01
+type: execute
+wave: 1
+depends_on: []
+files_modified:
+ - libraries/CookieNoticePro/cookienoticepro.script.js
+ - libraries/CookieNoticePro/cookienoticepro.style.css
+ - templates/site/layout-logged.php
+autonomous: false
+delegation: off
+---
+
+
+## Goal
+Wdrożyć baner zgody na cookies (CookieNoticePro) z Google Consent Mode v2, naprawić błąd `analytics_storage: 'granted'` w bibliotece oraz dodać domyślną inicjalizację consent mode przed snippetem GTM.
+
+## Purpose
+Wymaganie RODO — serwis musi uzyskać zgodę użytkownika przed uruchomieniem trackerów analitycznych i marketingowych. Google Consent Mode v2 zapewnia zgodność z wymaganiami Google (od marca 2024) i zachowanie modelowanych danych konwersji nawet przy braku zgody.
+
+## Output
+- `libraries/CookieNoticePro/cookienoticepro.script.js` — zkopiony z pomysloweprezenty.pl i naprawiony (linia ~351: `'granted'` → `'denied'`)
+- `libraries/CookieNoticePro/cookienoticepro.style.css` — zkopiony z pomysloweprezenty.pl
+- `templates/site/layout-logged.php` — consent mode v2 default init przed GTM, załadowane CSS/JS banera, wywołanie `$.cookieNoticePro()`
+
+
+
+## Project Context
+@.paul/PROJECT.md
+@.paul/ROADMAP.md
+@.paul/STATE.md
+
+## Source Files
+@templates/site/layout-logged.php
+
+## Biblioteka źródłowa (pomysloweprezenty.pl)
+Pliki do skopiowania:
+- `c:\visual studio code\projekty\pomysloweprezenty.pl\libraries\CookieNoticePro\cookienoticepro.script.js`
+- `c:\visual studio code\projekty\pomysloweprezenty.pl\libraries\CookieNoticePro\cookienoticepro.style.css`
+
+
+
+
+## AC-1: Consent Mode v2 default init przed GTM
+```gherkin
+Given layout-logged.php jest renderowany w przeglądarce
+When strona się ładuje
+Then w , PRZED snippetem GTM, znajduje się blok gtag('consent','default',{...}) ustawiający wszystkie storage na 'denied'
+```
+
+## AC-2: Baner cookies wyświetla się przy pierwszej wizycie
+```gherkin
+Given użytkownik odwiedza serwis po raz pierwszy (brak cookie COOKIE_CONSENT)
+When strona się załaduje
+Then pojawia się baner CookieNoticePro z przyciskami akceptacji/odrzucenia/dostosowania
+```
+
+## AC-3: Naprawa błędu analytics_storage denied
+```gherkin
+Given użytkownik odwiedza serwis i wybiera "Odrzuć" lub wyłącza analytics w ustawieniach
+When biblioteka wywołuje googleConsentModeHandler()
+Then gtag('consent','update') wysyła {'analytics_storage': 'denied'} (nie 'granted')
+```
+
+## AC-4: Akceptacja cookies uruchamia gtag update z 'granted'
+```gherkin
+Given użytkownik wybrał akceptację wszystkich cookies
+When biblioteka wywołuje googleConsentModeHandler()
+Then gtag('consent','update') wysyła {'analytics_storage': 'granted'} i {'ad_storage': 'granted', ...}
+```
+
+## AC-5: Pliki biblioteki obecne w projekcie
+```gherkin
+Given wdrożenie jest kompletne
+When sprawdzamy strukturę projektu
+Then istnieją pliki libraries/CookieNoticePro/cookienoticepro.script.js i cookienoticepro.style.css
+```
+
+
+
+
+
+
+ Task 1: Skopiuj pliki CookieNoticePro i napraw błąd analytics_storage
+ libraries/CookieNoticePro/cookienoticepro.script.js, libraries/CookieNoticePro/cookienoticepro.style.css
+
+ 1. Skopiuj oba pliki z `c:\visual studio code\projekty\pomysloweprezenty.pl\libraries\CookieNoticePro\` do `libraries/CookieNoticePro\` w tym projekcie.
+
+ 2. W `cookienoticepro.script.js`, napraw błąd w funkcji `googleConsentModeHandler` (~linia 351):
+ - Znajdź blok `else` po `if(preferences.indexOf("analytics") > -1)` — ten blok obsługuje sytuację gdy analytics NIE jest zaakceptowane
+ - W tym bloku `else`, zmień:
+ ```js
+ gtag('consent', 'update', {
+ 'analytics_storage': 'granted'
+ });
+ ```
+ na:
+ ```js
+ gtag('consent', 'update', {
+ 'analytics_storage': 'denied'
+ });
+ ```
+ - Blok `if` (analytics zaakceptowane, ~linia 341-343) musi pozostać z `'granted'` — nie ruszaj go.
+
+ Unikaj: modyfikowania innych fragmentów pliku; zmiany konfiguracji `config {}` (kolory, tekst) — to ustawi się w layout.
+
+
+ Grep w skopiowanym pliku:
+ - Potwierdź że istnieje dokładnie JEDNO wywołanie `'analytics_storage': 'denied'` w bloku else
+ - Potwierdź że `'analytics_storage': 'granted'` nadal istnieje w bloku if (analytics accepted)
+ Komenda: grep -n "analytics_storage" libraries/CookieNoticePro/cookienoticepro.script.js
+
+ AC-3, AC-4, AC-5 satisfied: plik skopiowany, błąd naprawiony, 'denied' w else, 'granted' w if
+
+
+
+ Task 2: Dodaj Consent Mode v2 default init i integruj baner w layout-logged.php
+ templates/site/layout-logged.php
+
+ W `templates/site/layout-logged.php`:
+
+ 1. **Consent Mode v2 default — PRZED snippetem GTM** (wstaw przed komentarzem ``):
+ ```html
+
+
+
+ ```
+
+ 2. **CSS banera** — dodaj do sekcji `` po istniejących linkach CSS (przed zamknięciem ``):
+ ```html
+
+ ```
+
+ 3. **JS banera + inicjalizacja** — dodaj przed zamknięciem ``, po istniejącym bloku `
+
+ ```
+
+ Kolejność w `` po zmianie (od góry):
+ 1. Meta tagi
+ 2. Linki CSS (istniejące + nowy CSS banera)
+ 3. jQuery i inne JS
+ 4. **Consent Mode v2 default** ← NOWE (musi być przed GTM)
+ 5. **GTM snippet** ← istniejący (bez zmian)
+
+ Unikaj: modyfikowania snippetu GTM; zmiany kolejności istniejących skryptów; dodawania atrybutu `async` lub `defer` do skryptu banera.
+
+
+ Sprawdź w pliku layout-logged.php:
+ - Blok consent default pojawia się PRZED ``
+ - `cookienoticepro.style.css` jest linkowany w ``
+ - `cookienoticepro.script.js` i wywołanie `$.cookieNoticePro()` są przed ``
+ Komenda: grep -n "Consent Mode\|cookienoticepro\|GTM-TW9WCD9J" templates/site/layout-logged.php
+
+ AC-1, AC-2 satisfied: consent default init przed GTM, CSS i JS banera załadowane
+
+
+
+ Baner CookieNoticePro z Consent Mode v2 zintegrowany w layout-logged.php. Pliki biblioteki w libraries/CookieNoticePro/. Błąd analytics_storage naprawiony.
+
+ 1. Wyślij pliki na serwer przez FTP (Ctrl+Shift+P → "FTP-kr: Upload")
+ 2. Otwórz https://bilety.brzezovka.pl w trybie incognito (brak cookies)
+ 3. Sprawdź czy pojawia się baner zgody na cookies
+ 4. Otwórz DevTools → Console — sprawdź czy NIE ma błędów JS
+ 5. Otwórz DevTools → Network → filtruj "gtm" — sprawdź czy GTM się ładuje
+ 6. W Console wpisz: `document.cookie` — nie powinno być COOKIE_CONSENT (przed akceptacją)
+ 7. Kliknij "Odrzuć wszystkie" → w DevTools → Application → Cookies sprawdź czy GOOGLE_CONSENT_MODE_ANALYTICS_STORAGE ma wartość false/brak
+ 8. Odśwież stronę — baner NIE powinien się pojawić ponownie (cookie zapamiętane)
+ 9. Kliknij ikonę ciasteczka (minimize) → wybierz "Akceptuj wszystkie" → sprawdź że gtag update wysyła 'granted' (DevTools → Console → wpisz: `dataLayer` i poszukaj consent update)
+
+ Wpisz "approved" jeśli baner działa poprawnie, lub opisz problemy do naprawienia
+
+
+
+
+
+
+## DO NOT CHANGE
+- `templates/tickets/przelewy24.php` — purchase event (Phase 2, nie ruszać)
+- `templates/tickets/order-confirm.php` — po czyszczeniu Phase 2
+- Snippet GTM w layout-logged.php — tylko kolejność, nie treść
+- `config.php` — konfiguracja poza zakresem
+
+## SCOPE LIMITS
+- Nie konfiguruj cookienoticepro dla innych layoutów (layout-unlogged.php nie jest używany)
+- Nie zmieniaj kolorów/tekstu/języka banera — domyślna konfiguracja z biblioteki jest wystarczająca na start
+- Nie dodawaj nowych zależności JS poza biblioteką CookieNoticePro
+- Nie wdrażaj server-side consent storage — tylko frontend cookies
+
+
+
+
+Przed ogłoszeniem planu za kompletny:
+- [ ] `grep -n "analytics_storage" libraries/CookieNoticePro/cookienoticepro.script.js` → pokazuje 'denied' w else i 'granted' w if
+- [ ] `grep -n "consent.*default\|cookienoticepro\|GTM-TW9WCD9J" templates/site/layout-logged.php` → consent default PRZED GTM
+- [ ] Baner pojawia się na stronie przy pierwszej wizycie (weryfikacja manualna — checkpoint)
+- [ ] Brak błędów JS w konsoli
+- [ ] Odrzucenie cookies → analytics_storage pozostaje denied (nie grantowane)
+
+
+
+- Pliki CookieNoticePro obecne w libraries/CookieNoticePro/
+- Błąd analytics_storage naprawiony (denied zamiast granted w bloku else)
+- Consent Mode v2 default init znajduje się przed GTM snippetem w layout-logged.php
+- Baner wyświetla się przy pierwszej wizycie i zapamiętuje wybór
+- Serwis spełnia wymaganie RODO z PROJECT.md (Must Have: Zgodność z RODO)
+
+
+
diff --git a/.paul/phases/03-cookie-consent/03-01-SUMMARY.md b/.paul/phases/03-cookie-consent/03-01-SUMMARY.md
new file mode 100644
index 0000000..6b9bc65
--- /dev/null
+++ b/.paul/phases/03-cookie-consent/03-01-SUMMARY.md
@@ -0,0 +1,134 @@
+---
+phase: 03-cookie-consent
+plan: 01
+subsystem: ui
+tags: [cookies, gdpr, consent-mode-v2, gtm, cookienoticepro]
+
+requires:
+ - phase: 02-purchase-event-prepayment
+ provides: GTM już wdrożony w layout-logged.php
+
+provides:
+ - Baner zgody na cookies (CookieNoticePro) zintegrowany z serwisem
+ - Google Consent Mode v2 z domyślnymi denied przed GTM
+ - Naprawiony błąd analytics_storage w bibliotece CookieNoticePro
+affects: []
+
+tech-stack:
+ added: [CookieNoticePro jQuery plugin]
+ patterns: [Consent Mode v2 default-denied init before GTM snippet]
+
+key-files:
+ created:
+ - libraries/CookieNoticePro/cookienoticepro.script.js
+ - libraries/CookieNoticePro/cookienoticepro.style.css
+ modified:
+ - templates/site/layout-logged.php
+
+key-decisions:
+ - "Inicjalizacja: cookieNoticePro.init() zamiast $.fn.cookieNoticePro() — zgodnie z dokumentacją biblioteki"
+ - "acceptBtnSettingsLabel ukryty przez CSS (display:none) — JS nie ustawiał stanu początkowego"
+
+patterns-established:
+ - "Consent Mode v2 default init zawsze przed snippetem GTM w
"
+
+duration: ~45min
+started: 2026-04-26T00:00:00Z
+completed: 2026-04-26T00:00:00Z
+---
+
+# Phase 3 Plan 01: Cookie Consent Banner Summary
+
+**CookieNoticePro z Google Consent Mode v2 wdrożony — serwis spełnia wymogi RODO, analytics_storage poprawnie ustawiane na denied przy odmowie zgody.**
+
+## Performance
+
+| Metric | Value |
+|--------|-------|
+| Duration | ~45 min |
+| Tasks | 2 auto + 1 checkpoint |
+| Files modified | 3 |
+
+## Acceptance Criteria Results
+
+| Criterion | Status | Notes |
+|-----------|--------|-------|
+| AC-1: Consent Mode v2 default przed GTM | Pass | Blok w `` przed `` |
+| AC-2: Baner przy pierwszej wizycie | Pass | Zweryfikowane manualnie |
+| AC-3: Naprawa analytics_storage denied | Pass | Linia ~351: `'granted'` → `'denied'` w bloku else |
+| AC-4: Akceptacja → granted | Pass | Blok if (analytics accepted) bez zmian |
+| AC-5: Pliki biblioteki obecne | Pass | `libraries/CookieNoticePro/` skonfigurowany |
+
+## Accomplishments
+
+- Skopiowano i zintegrowano bibliotekę CookieNoticePro z istniejącym projektem
+- Naprawiono błąd biblioteki: `analytics_storage: 'granted'` → `'denied'` w bloku odrzucenia analytics
+- Consent Mode v2 inicjalizowany z defaultami `denied` przed snippetem GTM — wymaganie Google od marca 2024
+- Baner wyświetla się przy pierwszej wizycie, zapamiętuje wybór przez 365 dni
+
+## Files Created/Modified
+
+| File | Change | Purpose |
+|------|--------|---------|
+| `libraries/CookieNoticePro/cookienoticepro.script.js` | Created | Biblioteka banera — zkopiona + naprawiony błąd analytics_storage + link regulaminu |
+| `libraries/CookieNoticePro/cookienoticepro.style.css` | Created | Style banera — zkopione + Bootstrap 5 compat reset + initial state fix |
+| `templates/site/layout-logged.php` | Modified | Consent Mode v2 default przed GTM, CSS/JS banera, inicjalizacja `cookieNoticePro.init()` |
+
+## Decisions Made
+
+| Decision | Rationale | Impact |
+|----------|-----------|--------|
+| `cookieNoticePro.init()` zamiast `$.fn.cookieNoticePro()` | Demo `index.html` z biblioteki pokazuje właściwy sposób inicjalizacji | Poprawne uruchomienie banera |
+| CSS `display:none` na `.acceptBtnSettingsLabel` | JS przełącza etykiety tylko na click — nie ustawia stanu początkowego | Brak duplikatu tekstu w przycisku "Akceptuj/Zatwierdź" |
+| Bootstrap 5 compat reset w CSS | Bootstrap nadpisuje `line-height`, `font-size` przycisków | Poprawny wygląd przycisków banera |
+
+## Deviations from Plan
+
+### Summary
+
+| Type | Count | Impact |
+|------|-------|--------|
+| Auto-fixed | 3 | Niezbędne poprawki, brak scope creep |
+| Scope additions | 1 | Drobna zmiana na prośbę użytkownika |
+
+**Total impact:** Drobne poprawki wynikające z integracji z Bootstrap 5 i specyfiki biblioteki
+
+### Auto-fixed Issues
+
+**1. Inicjalizacja pluginu**
+- **Found during:** Checkpoint (błąd konsoli)
+- **Issue:** `$.cookieNoticePro is not a function` — plugin rejestruje się jako `$.fn`, nie `$`
+- **Fix:** `$.cookieNoticePro()` → `$.fn.cookieNoticePro()` → `cookieNoticePro.init()`
+- **Files:** `templates/site/layout-logged.php`
+
+**2. Duplikat tekstu w przycisku akceptacji**
+- **Found during:** Checkpoint (feedback użytkownika)
+- **Issue:** `.acceptBtnSettingsLabel` ("Zatwierdź") widoczny razem z `.acceptBtnLabel` ("Akceptuj") — brak initial hide w JS
+- **Fix:** Dodano `display: none` w CSS dla `.acceptBtnSettingsLabel`
+- **Files:** `libraries/CookieNoticePro/cookienoticepro.style.css`
+
+**3. Bootstrap 5 button override**
+- **Found during:** Checkpoint (button layout)
+- **Issue:** Bootstrap nadpisuje `line-height` i `font-size` przycisków banera
+- **Fix:** CSS reset z `!important`-safe specificity dla `.btn-wrap button`
+- **Files:** `libraries/CookieNoticePro/cookienoticepro.style.css`
+
+### Scope Additions
+
+- Link regulaminu zmieniony na `https://bilety.brzezovka.pl/tickets/regulamin/` (prośba użytkownika podczas weryfikacji)
+
+## Next Phase Readiness
+
+**Ready:**
+- v0.2 Analytics & Privacy — wszystkie 3 fazy kompletne
+- Tracking ecommerce (Phase 1+2) + RODO (Phase 3) wdrożone
+
+**Concerns:**
+- Brak — integracja stabilna
+
+**Blockers:**
+- None
+
+---
+*Phase: 03-cookie-consent, Plan: 01*
+*Completed: 2026-04-26*
diff --git a/libraries/CookieNoticePro/cookienoticepro.script.js b/libraries/CookieNoticePro/cookienoticepro.script.js
new file mode 100644
index 0000000..e742686
--- /dev/null
+++ b/libraries/CookieNoticePro/cookienoticepro.script.js
@@ -0,0 +1,438 @@
+/*
+ * Copyright (c) 2024 Flerosoft (https://flerosoft.com)
+ * Software Name: Cookie Notice Pro - jQuery Plugin
+ * Product Page : https://cookienoticepro.flerosoft.com
+ * Documentation: https://cookienoticepro.flerosoft.com/docs
+ * Description: Cookie Notice Pro, a lightweight jQuery plugin, helps you to comply with GDPR.
+Make your own cookie information popup in minutes.
+ * Changelog: https://cookienoticepro.flerosoft.com/docs/getting-started#item-1-4
+*/
+
+(function ($) {
+
+ 'use strict'
+
+ const settingsIcon =
+ '';
+
+ const cookieIcon =
+ '';
+
+ const closeIcon = '';
+
+ /*
+ *--------------------------------------------------------------------------
+ * CONFIG OR SETTINGS - Customize the popup banner START
+ *--------------------------------------------------------------------------
+ */
+ const config = {
+ themeSettings: {
+ primaryColor: "#b7174d", // Primary Color of Popup Banner
+ darkColor: "#3b3e4a", // Dark Theme Color
+ lightColor: "#ffffff", // Light Theme Color
+ themeMode: "light", // Theme Mode (light|dark)
+ },
+ enableGoogleConsentMode: true, // Add support for Google consent mode v2 (https://cookiebannergenerator.com/implementing-google-consent-mode-v2-with-cookie-notice-pro-a-step-by-step-guide/)
+ enableMinimize: true, // Enable minimized floating cookie icon to adjust preferences
+ showCookieIcon: true, // Hide or show the cookie icon
+ showSettingsBtn: true, // Hide or show the preference settings(true|false)
+ showCloseIcon: false, // Hide or show the popup close icon(true|false)
+ showDeclineBtn: true, // Hide or show the cookie decline button(true|false)
+ fullWidth: false, // Full width popup works only when "displayPosition" is set to top/bottom
+ allCheckboxesChecked: true, // The setting checkboxes should be checked by default initially or not(true|false)
+
+ displayPosition: "bottom", // Where popup should appear(top|right|bottom|left)
+ settingsBtnLabel: "Dostosuj", // Text of settings button
+
+ delay: 1, // After how much time should popup appear(2000 is equal to 2 seconds)
+ expires: 365, // Expiry date of cookie(365 is equal to 365 days)
+
+ title: "Cenimy prywatność użytkowników", // Title of popup bannner
+ description: "Używamy plików cookie, aby poprawić jakość przeglądania, wyświetlać reklamy lub treści dostosowane do indywidualnych potrzeb użytkowników oraz analizować ruch na stronie. Kliknięcie przycisku „Akceptuj wszystkie” oznacza zgodę na wykorzystywanie przez nas plików cookie.", // Message
+ acceptBtnLabel: "Akceptuj", // Accept cookie button text
+ declineInfoBtnLabel: "Dostosuj", // Decline cookie button text
+ acceptBtnSettingsLabel: "Zatwierdź",
+ moreInfoBtnLink: "https://bilety.brzezovka.pl/tickets/regulamin/", // Learn more link(default: privacy policy page)
+ moreInfoBtnLabel: "Regulamin", // More info link text
+ cookieTypesTitle: "Wybierz pliki cookies do akceptacji", // Title of cookie preference options
+ necessaryCookieTypeLabel: "Wymagane", // Label text of Necessary cookie item
+ floatingIconTooltip: "Dostosuj", // Tooltip of floating cookie icon (Minimized)
+ necessaryCookieTypeDesc: "Te ciasteczka są niezbędne do działania strony internetowej i nie mogą zostać wyłączone w naszych systemach.", // Hover text of necessary cookies
+ onConsentAccept: ()=> { // It will inject scripts in head if cookie preferences menu(showSettingsBtn) is enabled
+ console.log("Consent accepted!")
+ },
+ onConsentReject: ()=> { // This code will run on cookie reject/decline
+ console.log("Consent Rejected!");
+ },
+ cookieTypes: [
+ // Cookie types, value and description (Cookie Preferences Selection)
+ {
+ type: "Funkcjonalne",
+ value: "preferences", // WARNING: DO NOT EDIT THIS VALUE
+ description: "Niezbędne pliki cookie mają kluczowe znaczenie dla podstawowych funkcji witryny i witryna nie będzie działać w zamierzony sposób bez nich.Te pliki cookie nie przechowują żadnych danych umożliwiających identyfikację osoby.",
+ },
+ {
+ type: "Reklama",
+ value: "marketing", // WARNING: DO NOT EDIT THIS VALUE
+ description: "Reklamowe pliki cookie służą do dostarczania użytkownikom spersonalizowanych reklam w oparciu o strony, które odwiedzili wcześniej, oraz do analizowania skuteczności kampanii reklamowej.",
+ },
+ {
+ type: "Analityka",
+ value: "analytics", // WARNING: DO NOT EDIT THIS VALUE
+ description: "Analityczne pliki cookie służą do zrozumienia, w jaki sposób użytkownicy wchodzą w interakcję z witryną. Te pliki cookie pomagają dostarczać informacje o metrykach liczby odwiedzających, współczynniku odrzuceń, źródle ruchu itp.",
+ },
+ ],
+ };
+ /*
+ *--------------------------------------------------------------------------
+ * CONFIG OR SETTINGS - Customize the popup banner END
+ *--------------------------------------------------------------------------
+ */
+
+ const COOKIE_CONSENT = "cnp_consent"; // WARNING: DO NOT EDIT THIS VALUE
+ const COOKIE_CONSENT_PREFS = "cnp_prefs"; // WARNING: DO NOT EDIT THIS VALUE
+ const GOOGLE_CONSENT_MODE_AD_PREFS = "cnp_gconsent_ad_prefs" // WARNING: DO NOT EDIT THIS VALUE
+ const GOOGLE_CONSENT_MODE_ANALYTICS_STORAGE = "cnp_gconsent_analytics_storage" // WARNING: DO NOT EDIT THIS VALUE
+
+ $.fn.cookieNoticePro = (event) => {
+ changeRootVariables();
+ let cookieConsentExists = cookieExists(COOKIE_CONSENT);
+ let cookiePrefsValue = accessCookie(COOKIE_CONSENT_PREFS);
+
+ if ( !cookieConsentExists) {
+ // add layer to the body below cookies to prevent click
+ $('body').append('');
+ }
+
+ // If consent is not accepted
+ if (!cookieConsentExists || event == "open") {
+ $("#cookieNoticePro").remove();
+ $("#cookieMinimizeIcon").remove();
+
+ let cookieTypes='