` z siatką miast
+ - HTML: `
Miasto` rozdzielone separatorem `|`
+ - Layout: CSS grid/flex, 5 kolumn na desktop (jak na Figmie), 2-3 kolumny na tablet, 1 na mobile
+ - Font: Albert Sans, kolor #2F2482
+ - Miasta dynamiczne — jeśli oddział dodany w Softra, automatycznie pojawia się w widgecie
+
+ **2b. Rejestracja widgetu:**
+ - W `carei-reservation.php`: require + register `Carei_Cities_Widget`
+
+ **Avoid:**
+ - NIE hardkoduj listy miast
+ - NIE duplikuj requestów — użyj tego samego cache co mapa
+
+
+ - Widget "Carei Cities" widoczny w panelu Elementor
+ - Siatka miast renderuje się z unikalnymi miastami z API
+ - Responsywność: 5 kolumn desktop → mniej na mobile
+ - Brak duplikatów miast
+
+
AC-2 satisfied: Siatka miast dynamiczna, responsywna, unikalne wartości.
+
+
+
+ Dwa widgety Elementor: mapa Polski z pinami oddziałów + siatka miast. Cachowanie API 60 min.
+
+ 1. Otwórz stronę w Elementorze, dodaj widget "Carei Map" — sprawdź czy piny są na mapie
+ 2. Najedź na pin — tooltip z adresem powinien się pojawić
+ 3. Dodaj widget "Carei Cities" — sprawdź siatkę miast
+ 4. Sprawdź responsywność (mobile preview w Elementorze)
+ 5. Opcjonalnie: podaj kod SVG mapy Polski do zastąpienia placeholdera
+
+ Type "approved" to continue, or describe issues to fix
+
+
+
+
+
+
+## DO NOT CHANGE
+- wp-content/plugins/carei-reservation/includes/class-elementor-widget.php (główny widget rezerwacji)
+- wp-content/plugins/carei-reservation/includes/class-admin-panel.php (admin panel)
+- Istniejące endpointy REST (nie zmieniaj zachowania `/branches`, `/car-classes` itd.)
+- Logika formularza rezerwacji w JS (sekcje modal, booking flow)
+
+## SCOPE LIMITS
+- Mapa to SVG statyczny z dynamicznymi pinami — NIE interaktywna mapa z zoomem
+- Brak geokodowania w runtime — współrzędne miast zmapowane statycznie w PHP
+- Tooltip prosty (adres) — bez linków, bez routingu do formularza
+- Cachowanie tylko na `/branch/list` — inne endpointy bez zmian w tym planie
+
+
+
+
+Before declaring plan complete:
+- [ ] Widget "Carei Map" renderuje mapę z pinami na prawidłowych pozycjach
+- [ ] Tooltip na hover/click pokazuje adres oddziału
+- [ ] Widget "Carei Cities" wyświetla unikalne miasta w siatce
+- [ ] Cache transient `carei_branches_list` aktywny z TTL 60 min
+- [ ] Responsywność obu widgetów (desktop + mobile)
+- [ ] Brak błędów JS w konsoli
+- [ ] Brak broken layouts w istniejących widgetach (rezerwacja, search form)
+
+
+
+- Oba widgety dostępne w Elementorze i renderują dane z API
+- Piny na mapie odpowiadają miastom oddziałów z Softra
+- Tooltips wyświetlają adresy
+- Siatka miast dynamiczna i responsywna
+- Cache 60 min działa — brak nadmiarowych requestów do API
+- Istniejąca funkcjonalność nienaruszona
+
+
+
diff --git a/.paul/phases/08-map-and-cities-widgets/08-01-SUMMARY.md b/.paul/phases/08-map-and-cities-widgets/08-01-SUMMARY.md
new file mode 100644
index 0000000..c9db089
--- /dev/null
+++ b/.paul/phases/08-map-and-cities-widgets/08-01-SUMMARY.md
@@ -0,0 +1,145 @@
+---
+phase: 08-map-and-cities-widgets
+plan: 01
+subsystem: ui
+tags: [elementor, svg, map, api-cache, transient]
+
+requires:
+ - phase: 01-reservation-form-plugin
+ provides: Softra API client, REST proxy, plugin bootstrap
+
+provides:
+ - Carei Map widget (SVG map with dynamic pins + tooltips)
+ - Carei Cities widget (city name grid)
+ - Carei Branches widget (branch grid with addresses)
+ - Branches API caching (60min transient)
+ - REST endpoint /branches-full
+
+affects: []
+
+tech-stack:
+ added: []
+ patterns:
+ - "Branch name cleaning: strip D/L suffixes, NAME_FIXES for truncated names"
+ - "City coordinates: static PHP array mapping normalized names to SVG viewBox coords"
+
+key-files:
+ created:
+ - wp-content/plugins/carei-reservation/includes/class-map-widget.php
+ - wp-content/plugins/carei-reservation/includes/class-cities-widget.php
+ - wp-content/plugins/carei-reservation/includes/class-branches-widget.php
+ modified:
+ - wp-content/plugins/carei-reservation/includes/class-softra-api.php
+ - wp-content/plugins/carei-reservation/includes/class-rest-proxy.php
+ - wp-content/plugins/carei-reservation/carei-reservation.php
+ - wp-content/plugins/carei-reservation/assets/css/carei-reservation.css
+ - wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
+
+key-decisions:
+ - "Branch name D=Dworzec, L=Lotnisko — strip suffixes, deduplicate to base city"
+ - "Tooltip format: Oddział [City] + ul. Street + ZipCode City"
+ - "Branches widget added beyond original plan scope"
+ - "Cities separator via CSS ::after to prevent line-start orphan |"
+
+patterns-established:
+ - "NAME_FIXES const for API name corrections (shared across widgets)"
+ - "get_branches_cached() as single source for all branch data"
+
+duration: ~45min
+started: 2026-04-01T17:30:00Z
+completed: 2026-04-01T18:15:00Z
+---
+
+# Phase 8 Plan 01: Map, Cities & Branches Widgets Summary
+
+**Three Elementor widgets for branch visualization: SVG map with dynamic pins/tooltips, city name list, and full branch grid with addresses. Plus 60-min API cache.**
+
+## Performance
+
+| Metric | Value |
+|--------|-------|
+| Duration | ~45min |
+| Tasks | 3 completed (2 auto + 1 checkpoint) |
+| Files modified | 7 (3 created, 4 modified) |
+
+## Acceptance Criteria Results
+
+| Criterion | Status | Notes |
+|-----------|--------|-------|
+| AC-1: Mapa Polski z dynamicznymi pinami | Pass | Real SVG (Vector.svg), pins from API, tooltip with address |
+| AC-2: Siatka miast oddziałowych | Pass | Unique cities, ::after separators, responsive |
+| AC-3: Cachowanie API 60 min | Pass | `get_branches_cached()` with HOUR_IN_SECONDS transient |
+
+## Accomplishments
+
+- SVG map of Poland (user-provided Vector.svg) with dynamic red pins positioned by city coordinate mapping, tooltips showing "Oddział [City] / ul. Street / ZipCode City"
+- Cities widget with deduplicated, title-cased names from API, CSS ::after separators that never orphan to line start
+- Branches grid widget (5→3→2→1 columns responsive) with full address data from API fields (street, zipCode, city)
+- Unified branch name cleaning: D/L suffix stripping, NAME_FIXES for truncated API names (BYDGOSZC→BYDGOSZCZ, GORZÓW WIE→GORZÓW WIELKOPOLSKI, RZSZÓW→RZESZÓW, SK-KAM→skip)
+- 60-min transient cache on /branch/list, used by all three widgets via single `get_branches_cached()` method
+
+## Files Created/Modified
+
+| File | Change | Purpose |
+|------|--------|---------|
+| `includes/class-map-widget.php` | Created | SVG map widget with pins, tooltips, city coords |
+| `includes/class-cities-widget.php` | Created | City name grid widget |
+| `includes/class-branches-widget.php` | Created | Branch grid with addresses |
+| `includes/class-softra-api.php` | Modified | Added `get_branches_cached()` with 60min transient |
+| `includes/class-rest-proxy.php` | Modified | Added `/branches-full` endpoint |
+| `carei-reservation.php` | Modified | Registered 3 new widgets |
+| `assets/css/carei-reservation.css` | Modified | Styles for map, cities, branches widgets |
+| `assets/js/carei-reservation.js` | Modified | Dynamic pin rendering + tooltip logic |
+
+## Decisions Made
+
+| Decision | Rationale | Impact |
+|----------|-----------|--------|
+| Static city→SVG coordinate mapping in PHP | No runtime geocoding, simple and fast | New cities need manual coord addition |
+| D suffix = Dworzec, display as "Oddział [City]" | User request for consistent naming | All tooltips show "Oddział X" format |
+| CSS ::after for city separators | Prevents `\|` orphaning to line start on wrap | Cleaner than separate `
` elements |
+| Added Branches widget (not in original plan) | User requested during execution | Extra widget, no negative impact |
+
+## Deviations from Plan
+
+### Summary
+
+| Type | Count | Impact |
+|------|-------|--------|
+| Scope additions | 1 | Branches grid widget added |
+| Auto-fixed | 3 | API name cleaning, separator orphans, tooltip content |
+
+**Total impact:** Scope addition was user-requested. Auto-fixes were essential for data quality.
+
+### Auto-fixed Issues
+
+**1. API branch names with D/L suffixes causing 39 duplicates**
+- Found during: checkpoint verification
+- Issue: API returns "GDAŃSK", "GDAŃSK D", "GDAŃSK L" as separate branches
+- Fix: Strip suffixes, NAME_FIXES for truncated names, deduplicate
+- Verification: 17 unique cities displayed
+
+**2. Separator `|` orphaning to new line start**
+- Found during: user review
+- Fix: Replaced `` separator with CSS `::after` pseudo-element
+
+**3. Tooltip showing raw API description instead of formatted address**
+- Found during: user review
+- Fix: Built address from `street`, `zipCode`, `city` API fields
+
+## Next Phase Readiness
+
+**Ready:**
+- All branch visualization widgets operational
+- API cache in place for all branch data consumers
+- Branch name cleaning pattern reusable
+
+**Concerns:**
+- City coordinates are static — new Softra branches in unmapped cities won't show pins
+- Some API zipCodes are null (e.g., Białystok)
+
+**Blockers:** None
+
+---
+*Phase: 08-map-and-cities-widgets, Plan: 01*
+*Completed: 2026-04-01*
diff --git a/.playwright-mcp/console-2026-04-01T17-48-34-799Z.log b/.playwright-mcp/console-2026-04-01T17-48-34-799Z.log
new file mode 100644
index 0000000..480631c
--- /dev/null
+++ b/.playwright-mcp/console-2026-04-01T17-48-34-799Z.log
@@ -0,0 +1,2 @@
+[ 2171ms] [LOG] JQMIGRATE: Migrate is installed, version 3.4.1 @ https://carei.pagedev.pl/wp-includes/js/jquery/jquery-migrate.min.js?ver=3.4.1:1
+[ 2728ms] [ERROR] Failed to load resource: the server responded with a status of 404 () @ https://carei.pagedev.pl/favicon.ico:0
diff --git a/.playwright-mcp/console-2026-04-01T17-50-48-199Z.log b/.playwright-mcp/console-2026-04-01T17-50-48-199Z.log
new file mode 100644
index 0000000..13b1809
--- /dev/null
+++ b/.playwright-mcp/console-2026-04-01T17-50-48-199Z.log
@@ -0,0 +1 @@
+[ 230ms] [LOG] JQMIGRATE: Migrate is installed, version 3.4.1 @ https://carei.pagedev.pl/wp-includes/js/jquery/jquery-migrate.min.js?ver=3.4.1:1
diff --git a/.playwright-mcp/page-2026-04-01T17-48-37-691Z.yml b/.playwright-mcp/page-2026-04-01T17-48-37-691Z.yml
new file mode 100644
index 0000000..f306325
--- /dev/null
+++ b/.playwright-mcp/page-2026-04-01T17-48-37-691Z.yml
@@ -0,0 +1,618 @@
+- generic [active] [ref=e1]:
+ - link "Przejdź do treści" [ref=e2] [cursor=pointer]:
+ - /url: "#content"
+ - banner [ref=e3]:
+ - generic [ref=e5]:
+ - link [ref=e7] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - navigation "Menu" [ref=e9]:
+ - list [ref=e10]:
+ - listitem [ref=e11]:
+ - link "Wynajem długoterminowy" [ref=e12] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl/wynajem-dlugoterminowy/
+ - listitem [ref=e13]:
+ - link "Wynajem krótkoterminowy" [ref=e14] [cursor=pointer]:
+ - /url: "#"
+ - listitem [ref=e15]:
+ - link "Kontakt" [ref=e16] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl/kontakt/
+ - generic [ref=e18]:
+ - list [ref=e20]:
+ - listitem [ref=e21]:
+ - link "+48 572 663 614" [ref=e22] [cursor=pointer]:
+ - /url: tel:+48572663614
+ - img [ref=e24]
+ - generic [ref=e30]: +48 572 663 614
+ - generic [ref=e32]:
+ - button "Złóż zapytanie o rezerwację" [ref=e33] [cursor=pointer]:
+ - img [ref=e34]
+ - text: Złóż zapytanie o rezerwację
+ - option "Wybierz segment pojazdu" [disabled] [selected]
+ - option "Miejsce odbioru" [disabled] [selected]
+ - generic [ref=e39]:
+ - generic [ref=e41]:
+ - generic [ref=e42]:
+ - heading "Wypożyczalnia samochodów osobowych" [level=4] [ref=e44]
+ - heading "Wybierz segment i zacznij podróż." [level=2] [ref=e46]
+ - paragraph [ref=e48]:
+ - text: Otrzymaj auto w ciągu
+ - strong [ref=e49]: 1h
+ - text: od przyjęcia przez nas zlecenia.
+ - generic [ref=e53]:
+ - heading "Wypełnij formularz rezerwacji." [level=2] [ref=e54]
+ - generic [ref=e55]:
+ - generic [ref=e57]:
+ - combobox [ref=e58] [cursor=pointer]:
+ - option "Wybierz segment" [disabled] [selected]
+ - img
+ - generic [ref=e59]:
+ - generic [ref=e61]:
+ - img
+ - generic: Od kiedy?
+ - textbox "Od kiedy?" [ref=e62]
+ - generic [ref=e64]:
+ - img
+ - generic: Do kiedy?
+ - textbox "Do kiedy?" [ref=e65]
+ - generic [ref=e67]:
+ - img
+ - combobox [ref=e68] [cursor=pointer]:
+ - option "Miejsce odbioru" [disabled] [selected]
+ - img
+ - generic [ref=e70] [cursor=pointer]:
+ - checkbox "Zwrot w tej samej lokalizacji" [checked]
+ - img [ref=e72]
+ - generic [ref=e74]: Zwrot w tej samej lokalizacji
+ - button "Złóż zapytanie o rezerwację" [ref=e75] [cursor=pointer]:
+ - img [ref=e76]
+ - text: Złóż zapytanie o rezerwację
+ - generic [ref=e79]:
+ - generic [ref=e81]:
+ - img [ref=e84]
+ - generic [ref=e91]:
+ - heading "Szybka i dokładna obsługa zamówień" [level=3] [ref=e92]
+ - paragraph [ref=e93]: Gwarantujemy pełną gotowość auta na Twój przyjazd.
+ - generic [ref=e99]:
+ - img [ref=e102]
+ - generic [ref=e108]:
+ - heading "Bez opłat przygotowawczych" [level=3] [ref=e109]
+ - paragraph [ref=e110]: Stawiamy na jasne zasady, nie doliczamy ukrytych kosztów.
+ - generic [ref=e116]:
+ - img [ref=e119]
+ - generic [ref=e123]:
+ - heading "Atrakcyjne promocje weekendowe" [level=3] [ref=e124]
+ - paragraph [ref=e125]: Oszczędzaj na wynajmie planując weekendowy wyjazd.
+ - generic [ref=e127]:
+ - heading "Jak wypożyczyć auto krótkoterminowo?" [level=2] [ref=e132]
+ - paragraph [ref=e137]: Najszybciej i najprościej zrobić to z Carei – w ciągu 1h od przyjęcia przez nas zlecenia otrzymasz już samochód.
+ - generic [ref=e142]:
+ - generic [ref=e145]:
+ - generic [ref=e146]:
+ - generic: "1."
+ - generic [ref=e147]:
+ - heading "Złóż zapytanie o rezerwację" [level=3] [ref=e148]
+ - paragraph [ref=e149]: W formularzu zaznacz jaka oferta Cię interesuje i podaj nam dane do kontaktu.
+ - generic [ref=e152]:
+ - generic [ref=e153]:
+ - generic: "2."
+ - generic [ref=e154]:
+ - heading "Skontaktuje się z Tobą obsługa klienta" [level=3] [ref=e155]
+ - paragraph [ref=e156]: Nasza infolinia działa 24h na dobę i przedstawi Ci konkretną propozycję
+ - generic [ref=e159]:
+ - generic [ref=e160]:
+ - generic: "3."
+ - generic [ref=e161]:
+ - heading "Odbierz kluczyki" [level=3] [ref=e162]
+ - paragraph [ref=e163]: Gwarantujemy minimum formalności przy odbiorze auta.
+ - link "Złóż zapytanie o rezerwację" [ref=e170] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e171]:
+ - img [ref=e173]
+ - generic [ref=e175]: Złóż zapytanie o rezerwację
+ - generic [ref=e183]:
+ - heading "Chcesz wynająć auto na dłużej niż miesiąc?" [level=2] [ref=e185]
+ - paragraph [ref=e187]: Przygotujemy dla Ciebie atrakcyjne warunki wynajmu długoterminowego.
+ - link "Oferta najmu długoterminowego" [ref=e189] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e191]: Oferta najmu długoterminowego
+ - generic [ref=e196]:
+ - img [ref=e201]
+ - generic [ref=e219]:
+ - heading "17 oddziałów w całej Polsce" [level=3] [ref=e221]:
+ - text: 17 oddziałów
+ - text: w całej Polsce
+ - heading "Podróżuj z Carei!" [level=2] [ref=e223]
+ - generic [ref=e224]:
+ - paragraph [ref=e225]: Od 2006 roku zajmujemy się szeroko rozumianym wynajmem samochodów osobowych na terenie Polski.
+ - paragraph [ref=e226]:
+ - text: W naszej ofercie znajdują się
+ - strong [ref=e227]: samochody standardowe oraz klasy premium
+ - text: .
+ - generic [ref=e230]:
+ - generic [ref=e231]: BIAŁYSTOK
+ - generic [ref=e232]: "|"
+ - generic [ref=e233]: BYDGOSZC D
+ - generic [ref=e234]: "|"
+ - generic [ref=e235]: BYDGOSZC L
+ - generic [ref=e236]: "|"
+ - generic [ref=e237]: BYDGOSZCZ
+ - generic [ref=e238]: "|"
+ - generic [ref=e239]: GDAŃSK
+ - generic [ref=e240]: "|"
+ - generic [ref=e241]: GDAŃSK D
+ - generic [ref=e242]: "|"
+ - generic [ref=e243]: GDAŃSK L
+ - generic [ref=e244]: "|"
+ - generic [ref=e245]: GORZÓW WIE
+ - generic [ref=e246]: "|"
+ - generic [ref=e247]: KATOWICE
+ - generic [ref=e248]: "|"
+ - generic [ref=e249]: KATOWICE D
+ - generic [ref=e250]: "|"
+ - generic [ref=e251]: KATOWICE L
+ - generic [ref=e252]: "|"
+ - generic [ref=e253]: KIELCE
+ - generic [ref=e254]: "|"
+ - generic [ref=e255]: KRAKÓW
+ - generic [ref=e256]: "|"
+ - generic [ref=e257]: KRAKÓW D
+ - generic [ref=e258]: "|"
+ - generic [ref=e259]: KRAKÓW L
+ - generic [ref=e260]: "|"
+ - generic [ref=e261]: LUBLIN
+ - generic [ref=e262]: "|"
+ - generic [ref=e263]: LUBLIN D
+ - generic [ref=e264]: "|"
+ - generic [ref=e265]: LUBLIN L
+ - generic [ref=e266]: "|"
+ - generic [ref=e267]: OLSZTYN
+ - generic [ref=e268]: "|"
+ - generic [ref=e269]: POZNAŃ
+ - generic [ref=e270]: "|"
+ - generic [ref=e271]: POZNAŃ D
+ - generic [ref=e272]: "|"
+ - generic [ref=e273]: POZNAŃ L
+ - generic [ref=e274]: "|"
+ - generic [ref=e275]: RADOM
+ - generic [ref=e276]: "|"
+ - generic [ref=e277]: RADOM D
+ - generic [ref=e278]: "|"
+ - generic [ref=e279]: RADOM L
+ - generic [ref=e280]: "|"
+ - generic [ref=e281]: RUMIA D
+ - generic [ref=e282]: "|"
+ - generic [ref=e283]: RZESZÓW
+ - generic [ref=e284]: "|"
+ - generic [ref=e285]: RZESZÓW L
+ - generic [ref=e286]: "|"
+ - generic [ref=e287]: RZSZÓW D
+ - generic [ref=e288]: "|"
+ - generic [ref=e289]: SK-KAM
+ - generic [ref=e290]: "|"
+ - generic [ref=e291]: SOPOT D
+ - generic [ref=e292]: "|"
+ - generic [ref=e293]: SZCZECIN
+ - generic [ref=e294]: "|"
+ - generic [ref=e295]: WARSZAWA
+ - generic [ref=e296]: "|"
+ - generic [ref=e297]: WARSZAWA D
+ - generic [ref=e298]: "|"
+ - generic [ref=e299]: WARSZAWA L
+ - generic [ref=e300]: "|"
+ - generic [ref=e301]: WROCŁAW
+ - generic [ref=e302]: "|"
+ - generic [ref=e303]: WROCŁAW D
+ - generic [ref=e304]: "|"
+ - generic [ref=e305]: WROCŁAW L
+ - generic [ref=e306]: "|"
+ - generic [ref=e307]: ŁÓDŹ
+ - generic [ref=e314]:
+ - heading "Wypożycz auto na swój wyjazd." [level=2] [ref=e316]
+ - paragraph [ref=e318]:
+ - text: Szybka obsługa zamówienia
+ - text: i minimum formalności.
+ - generic [ref=e319]:
+ - region "Carousel" [ref=e320]:
+ - generic [ref=e321]:
+ - group [ref=e322]:
+ - generic [ref=e326]:
+ - heading [level=3] [ref=e328]: Segment B
+ - paragraph [ref=e330]: "Przykładowy model: Toyota Yaris"
+ - paragraph [ref=e332]: Od 79 zł brutto / doba
+ - link [ref=e334] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e335]:
+ - img [ref=e337]
+ - generic [ref=e339]: Złóż zapytanie o rezerwację
+ - group [ref=e340]:
+ - generic [ref=e344]:
+ - heading [level=3] [ref=e346]: Segment LUX
+ - paragraph [ref=e348]: "Przykładowy model: Toyota Yaris"
+ - paragraph [ref=e350]: Od 79 zł brutto / doba
+ - link [ref=e352] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e353]:
+ - img [ref=e355]
+ - generic [ref=e357]: Złóż zapytanie o rezerwację
+ - group [ref=e358]:
+ - generic [ref=e362]:
+ - heading [level=3] [ref=e364]: Segment C/C+
+ - paragraph [ref=e366]: "Przykładowy model: Toyota Yaris"
+ - paragraph [ref=e368]: Od 79 zł brutto / doba
+ - link [ref=e370] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e371]:
+ - img [ref=e373]
+ - generic [ref=e375]: Złóż zapytanie o rezerwację
+ - group "1 / 3" [ref=e376]:
+ - generic [ref=e380]:
+ - heading "Segment B" [level=3] [ref=e382]
+ - paragraph [ref=e384]:
+ - text: "Przykładowy model:"
+ - text: Toyota Yaris
+ - paragraph [ref=e386]: Od 79 zł brutto / doba
+ - link "Złóż zapytanie o rezerwację" [ref=e388] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e389]:
+ - img [ref=e391]
+ - generic [ref=e393]: Złóż zapytanie o rezerwację
+ - group "2 / 3" [ref=e394]:
+ - generic [ref=e398]:
+ - heading "Segment LUX" [level=3] [ref=e400]
+ - paragraph [ref=e402]:
+ - text: "Przykładowy model:"
+ - text: Toyota Yaris
+ - paragraph [ref=e404]: Od 79 zł brutto / doba
+ - link "Złóż zapytanie o rezerwację" [ref=e406] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e407]:
+ - img [ref=e409]
+ - generic [ref=e411]: Złóż zapytanie o rezerwację
+ - group "3 / 3" [ref=e412]:
+ - generic [ref=e416]:
+ - heading "Segment C/C+" [level=3] [ref=e418]
+ - paragraph [ref=e420]:
+ - text: "Przykładowy model:"
+ - text: Toyota Yaris
+ - paragraph [ref=e422]: Od 79 zł brutto / doba
+ - link "Złóż zapytanie o rezerwację" [ref=e424] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e425]:
+ - img [ref=e427]
+ - generic [ref=e429]: Złóż zapytanie o rezerwację
+ - group [ref=e430]:
+ - generic [ref=e434]:
+ - heading [level=3] [ref=e436]: Segment B
+ - paragraph [ref=e438]: "Przykładowy model: Toyota Yaris"
+ - paragraph [ref=e440]: Od 79 zł brutto / doba
+ - link [ref=e442] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e443]:
+ - img [ref=e445]
+ - generic [ref=e447]: Złóż zapytanie o rezerwację
+ - group [ref=e448]:
+ - generic [ref=e452]:
+ - heading [level=3] [ref=e454]: Segment LUX
+ - paragraph [ref=e456]: "Przykładowy model: Toyota Yaris"
+ - paragraph [ref=e458]: Od 79 zł brutto / doba
+ - link [ref=e460] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e461]:
+ - img [ref=e463]
+ - generic [ref=e465]: Złóż zapytanie o rezerwację
+ - group [ref=e466]:
+ - generic [ref=e470]:
+ - heading [level=3] [ref=e472]: Segment C/C+
+ - paragraph [ref=e474]: "Przykładowy model: Toyota Yaris"
+ - paragraph [ref=e476]: Od 79 zł brutto / doba
+ - link [ref=e478] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e479]:
+ - img [ref=e481]
+ - generic [ref=e483]: Złóż zapytanie o rezerwację
+ - button "Poprzedni slajd" [ref=e484] [cursor=pointer]:
+ - img [ref=e485]
+ - button "Następny slajd" [ref=e487] [cursor=pointer]:
+ - img [ref=e488]
+ - heading "Opinie o Carei." [level=2] [ref=e500]
+ - region "Carousel" [ref=e502]:
+ - generic [ref=e503]:
+ - group [ref=e504]:
+ - generic [ref=e506]:
+ - generic [ref=e507]:
+ - img [ref=e510]:
+ - generic [ref=e511]:
+ - img [ref=e513]
+ - img [ref=e516]
+ - generic [ref=e518]:
+ - img [ref=e520]
+ - img [ref=e523]
+ - generic [ref=e525]:
+ - img [ref=e527]
+ - img [ref=e530]
+ - generic [ref=e532]:
+ - img [ref=e534]
+ - img [ref=e537]
+ - generic [ref=e539]:
+ - img [ref=e541]
+ - img [ref=e544]
+ - link [ref=e547] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e549]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e550]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e551]: Aneta W.
+ - group [ref=e552]:
+ - generic [ref=e554]:
+ - generic [ref=e555]:
+ - img [ref=e558]:
+ - generic [ref=e559]:
+ - img [ref=e561]
+ - img [ref=e564]
+ - generic [ref=e566]:
+ - img [ref=e568]
+ - img [ref=e571]
+ - generic [ref=e573]:
+ - img [ref=e575]
+ - img [ref=e578]
+ - generic [ref=e580]:
+ - img [ref=e582]
+ - img [ref=e585]
+ - generic [ref=e587]:
+ - img [ref=e589]
+ - img [ref=e592]
+ - link [ref=e595] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e597]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e598]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e599]: Aneta W.
+ - group [ref=e600]:
+ - generic [ref=e602]:
+ - generic [ref=e603]:
+ - img [ref=e606]:
+ - generic [ref=e607]:
+ - img [ref=e609]
+ - img [ref=e612]
+ - generic [ref=e614]:
+ - img [ref=e616]
+ - img [ref=e619]
+ - generic [ref=e621]:
+ - img [ref=e623]
+ - img [ref=e626]
+ - generic [ref=e628]:
+ - img [ref=e630]
+ - img [ref=e633]
+ - generic [ref=e635]:
+ - img [ref=e637]
+ - img [ref=e640]
+ - link [ref=e643] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e645]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e646]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e647]: Aneta W.
+ - group "1 / 4" [ref=e648]:
+ - generic [ref=e650]:
+ - generic [ref=e651]:
+ - img "Ocena 5 z 5" [ref=e654]:
+ - generic [ref=e655]:
+ - img [ref=e657]
+ - img [ref=e660]
+ - generic [ref=e662]:
+ - img [ref=e664]
+ - img [ref=e667]
+ - generic [ref=e669]:
+ - img [ref=e671]
+ - img [ref=e674]
+ - generic [ref=e676]:
+ - img [ref=e678]
+ - img [ref=e681]
+ - generic [ref=e683]:
+ - img [ref=e685]
+ - img [ref=e688]
+ - link [ref=e691] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e693]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e694]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e695]: Aneta W.
+ - group "2 / 4" [ref=e696]:
+ - generic [ref=e698]:
+ - generic [ref=e699]:
+ - img "Ocena 5 z 5" [ref=e702]:
+ - generic [ref=e703]:
+ - img [ref=e705]
+ - img [ref=e708]
+ - generic [ref=e710]:
+ - img [ref=e712]
+ - img [ref=e715]
+ - generic [ref=e717]:
+ - img [ref=e719]
+ - img [ref=e722]
+ - generic [ref=e724]:
+ - img [ref=e726]
+ - img [ref=e729]
+ - generic [ref=e731]:
+ - img [ref=e733]
+ - img [ref=e736]
+ - link [ref=e739] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e741]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e742]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e743]: Aneta W.
+ - group "3 / 4" [ref=e744]:
+ - generic [ref=e746]:
+ - generic [ref=e747]:
+ - img "Ocena 5 z 5" [ref=e750]:
+ - generic [ref=e751]:
+ - img [ref=e753]
+ - img [ref=e756]
+ - generic [ref=e758]:
+ - img [ref=e760]
+ - img [ref=e763]
+ - generic [ref=e765]:
+ - img [ref=e767]
+ - img [ref=e770]
+ - generic [ref=e772]:
+ - img [ref=e774]
+ - img [ref=e777]
+ - generic [ref=e779]:
+ - img [ref=e781]
+ - img [ref=e784]
+ - link [ref=e787] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e789]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e790]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e791]: Aneta W.
+ - group [ref=e792]:
+ - generic [ref=e794]:
+ - generic [ref=e795]:
+ - img [ref=e798]:
+ - generic [ref=e799]:
+ - img [ref=e801]
+ - img [ref=e804]
+ - generic [ref=e806]:
+ - img [ref=e808]
+ - img [ref=e811]
+ - generic [ref=e813]:
+ - img [ref=e815]
+ - img [ref=e818]
+ - generic [ref=e820]:
+ - img [ref=e822]
+ - img [ref=e825]
+ - generic [ref=e827]:
+ - img [ref=e829]
+ - img [ref=e832]
+ - link [ref=e835] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e837]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e838]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e839]: Aneta W.
+ - group [ref=e840]:
+ - generic [ref=e842]:
+ - generic [ref=e843]:
+ - img [ref=e846]:
+ - generic [ref=e847]:
+ - img [ref=e849]
+ - img [ref=e852]
+ - generic [ref=e854]:
+ - img [ref=e856]
+ - img [ref=e859]
+ - generic [ref=e861]:
+ - img [ref=e863]
+ - img [ref=e866]
+ - generic [ref=e868]:
+ - img [ref=e870]
+ - img [ref=e873]
+ - generic [ref=e875]:
+ - img [ref=e877]
+ - img [ref=e880]
+ - link [ref=e883] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e885]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e886]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e887]: Aneta W.
+ - group [ref=e888]:
+ - generic [ref=e890]:
+ - generic [ref=e891]:
+ - img [ref=e894]:
+ - generic [ref=e895]:
+ - img [ref=e897]
+ - img [ref=e900]
+ - generic [ref=e902]:
+ - img [ref=e904]
+ - img [ref=e907]
+ - generic [ref=e909]:
+ - img [ref=e911]
+ - img [ref=e914]
+ - generic [ref=e916]:
+ - img [ref=e918]
+ - img [ref=e921]
+ - generic [ref=e923]:
+ - img [ref=e925]
+ - img [ref=e928]
+ - link [ref=e931] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e933]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e934]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e935]: Aneta W.
+ - group [ref=e936]:
+ - generic [ref=e938]:
+ - generic [ref=e939]:
+ - img [ref=e942]:
+ - generic [ref=e943]:
+ - img [ref=e945]
+ - img [ref=e948]
+ - generic [ref=e950]:
+ - img [ref=e952]
+ - img [ref=e955]
+ - generic [ref=e957]:
+ - img [ref=e959]
+ - img [ref=e962]
+ - generic [ref=e964]:
+ - img [ref=e966]
+ - img [ref=e969]
+ - generic [ref=e971]:
+ - img [ref=e973]
+ - img [ref=e976]
+ - link [ref=e979] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e981]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e982]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e983]: Aneta W.
+ - contentinfo [ref=e984]:
+ - generic [ref=e987]:
+ - heading "Szukasz więcej informacji?" [level=4] [ref=e989]
+ - heading "Skontaktuj się z naszą obsługą." [level=3] [ref=e994]:
+ - text: Skontaktuj się
+ - text: z naszą obsługą.
+ - generic [ref=e998]:
+ - generic [ref=e1000]:
+ - link "Assistance" [ref=e1002] [cursor=pointer]:
+ - /url: tel:+48572663614
+ - img [ref=e1003]
+ - generic [ref=e1007]:
+ - heading "Assistance" [level=3] [ref=e1008]:
+ - link "Assistance" [ref=e1009] [cursor=pointer]:
+ - /url: tel:+48572663614
+ - paragraph [ref=e1010]: +48 572 663 614
+ - generic [ref=e1012]:
+ - link "Biuro" [ref=e1014] [cursor=pointer]:
+ - /url: mailto:bok@carei.pl
+ - img [ref=e1015]
+ - generic [ref=e1021]:
+ - heading "Biuro" [level=3] [ref=e1022]:
+ - link "Biuro" [ref=e1023] [cursor=pointer]:
+ - /url: mailto:bok@carei.pl
+ - paragraph [ref=e1024]: bok@carei.pl
+ - generic [ref=e1035]:
+ - heading "Carei - Wypożyczalnia aut osobowych" [level=3] [ref=e1037]
+ - generic [ref=e1038]:
+ - paragraph [ref=e1040]:
+ - text: CAREI Sp. z o.o. Sp. k.
+ - text: ul. Solipska 1/U4,
+ - text: 02-482 Warszawa
+ - paragraph [ref=e1042]:
+ - text: "NIP: 527 249 90 39"
+ - text: "REGON: 140473129 KRS: 0000668452"
+ - generic [ref=e1050]:
+ - paragraph [ref=e1052]: Copyright © 2026 Carei
+ - paragraph [ref=e1054]: "Designed by: Kreatywny Brand"
+ - generic [ref=e1055]: laptop
\ No newline at end of file
diff --git a/.playwright-mcp/page-2026-04-01T17-50-49-058Z.yml b/.playwright-mcp/page-2026-04-01T17-50-49-058Z.yml
new file mode 100644
index 0000000..7944ea6
--- /dev/null
+++ b/.playwright-mcp/page-2026-04-01T17-50-49-058Z.yml
@@ -0,0 +1,587 @@
+- generic [active] [ref=e1]:
+ - link "Przejdź do treści" [ref=e2] [cursor=pointer]:
+ - /url: "#content"
+ - banner [ref=e3]:
+ - generic [ref=e5]:
+ - link [ref=e7] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - navigation "Menu" [ref=e9]:
+ - list [ref=e10]:
+ - listitem [ref=e11]:
+ - link "Wynajem długoterminowy" [ref=e12] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl/wynajem-dlugoterminowy/
+ - listitem [ref=e13]:
+ - link "Wynajem krótkoterminowy" [ref=e14] [cursor=pointer]:
+ - /url: "#"
+ - listitem [ref=e15]:
+ - link "Kontakt" [ref=e16] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl/kontakt/
+ - generic [ref=e18]:
+ - list [ref=e20]:
+ - listitem [ref=e21]:
+ - link "+48 572 663 614" [ref=e22] [cursor=pointer]:
+ - /url: tel:+48572663614
+ - img [ref=e24]
+ - generic [ref=e30]: +48 572 663 614
+ - generic [ref=e32]:
+ - button "Złóż zapytanie o rezerwację" [ref=e33] [cursor=pointer]:
+ - img [ref=e34]
+ - text: Złóż zapytanie o rezerwację
+ - option "Wybierz segment pojazdu" [disabled] [selected]
+ - option "Miejsce odbioru" [disabled] [selected]
+ - generic [ref=e39]:
+ - generic [ref=e41]:
+ - generic [ref=e42]:
+ - heading "Wypożyczalnia samochodów osobowych" [level=4] [ref=e44]
+ - heading "Wybierz segment i zacznij podróż." [level=2] [ref=e46]
+ - paragraph [ref=e48]:
+ - text: Otrzymaj auto w ciągu
+ - strong [ref=e49]: 1h
+ - text: od przyjęcia przez nas zlecenia.
+ - generic [ref=e53]:
+ - heading "Wypełnij formularz rezerwacji." [level=2] [ref=e54]
+ - generic [ref=e55]:
+ - generic [ref=e57]:
+ - combobox [ref=e58] [cursor=pointer]:
+ - option "Wybierz segment" [disabled] [selected]
+ - option "Segment B"
+ - option "Segment C"
+ - option "Segment C+"
+ - option "Segment D"
+ - option "Segment E"
+ - option "Segment LCV"
+ - option "Segment LUX"
+ - option "Segment P"
+ - option "Segment SUV"
+ - option "Segment SUV+"
+ - option "Segment VAN"
+ - img
+ - generic [ref=e59]:
+ - generic [ref=e61]:
+ - img
+ - generic: Od kiedy?
+ - textbox "Od kiedy?" [ref=e62]
+ - generic [ref=e64]:
+ - img
+ - generic: Do kiedy?
+ - textbox "Do kiedy?" [ref=e65]
+ - generic [ref=e67]:
+ - img
+ - combobox [disabled] [ref=e68] [cursor=pointer]:
+ - option "Najpierw wybierz segment" [disabled] [selected]
+ - img
+ - generic [ref=e70] [cursor=pointer]:
+ - checkbox "Zwrot w tej samej lokalizacji" [checked]
+ - img [ref=e72]
+ - generic [ref=e74]: Zwrot w tej samej lokalizacji
+ - button "Złóż zapytanie o rezerwację" [ref=e75] [cursor=pointer]:
+ - img [ref=e76]
+ - text: Złóż zapytanie o rezerwację
+ - generic [ref=e79]:
+ - generic [ref=e81]:
+ - img [ref=e84]
+ - generic [ref=e91]:
+ - heading "Szybka i dokładna obsługa zamówień" [level=3] [ref=e92]
+ - paragraph [ref=e93]: Gwarantujemy pełną gotowość auta na Twój przyjazd.
+ - generic [ref=e99]:
+ - img [ref=e102]
+ - generic [ref=e108]:
+ - heading "Bez opłat przygotowawczych" [level=3] [ref=e109]
+ - paragraph [ref=e110]: Stawiamy na jasne zasady, nie doliczamy ukrytych kosztów.
+ - generic [ref=e116]:
+ - img [ref=e119]
+ - generic [ref=e123]:
+ - heading "Atrakcyjne promocje weekendowe" [level=3] [ref=e124]
+ - paragraph [ref=e125]: Oszczędzaj na wynajmie planując weekendowy wyjazd.
+ - generic [ref=e127]:
+ - heading "Jak wypożyczyć auto krótkoterminowo?" [level=2] [ref=e132]
+ - paragraph [ref=e137]: Najszybciej i najprościej zrobić to z Carei – w ciągu 1h od przyjęcia przez nas zlecenia otrzymasz już samochód.
+ - generic [ref=e142]:
+ - generic [ref=e145]:
+ - generic [ref=e146]:
+ - generic: "1."
+ - generic [ref=e147]:
+ - heading "Złóż zapytanie o rezerwację" [level=3] [ref=e148]
+ - paragraph [ref=e149]: W formularzu zaznacz jaka oferta Cię interesuje i podaj nam dane do kontaktu.
+ - generic [ref=e152]:
+ - generic [ref=e153]:
+ - generic: "2."
+ - generic [ref=e154]:
+ - heading "Skontaktuje się z Tobą obsługa klienta" [level=3] [ref=e155]
+ - paragraph [ref=e156]: Nasza infolinia działa 24h na dobę i przedstawi Ci konkretną propozycję
+ - generic [ref=e159]:
+ - generic [ref=e160]:
+ - generic: "3."
+ - generic [ref=e161]:
+ - heading "Odbierz kluczyki" [level=3] [ref=e162]
+ - paragraph [ref=e163]: Gwarantujemy minimum formalności przy odbiorze auta.
+ - link "Złóż zapytanie o rezerwację" [ref=e170] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e171]:
+ - img [ref=e173]
+ - generic [ref=e175]: Złóż zapytanie o rezerwację
+ - generic [ref=e183]:
+ - heading "Chcesz wynająć auto na dłużej niż miesiąc?" [level=2] [ref=e185]
+ - paragraph [ref=e187]: Przygotujemy dla Ciebie atrakcyjne warunki wynajmu długoterminowego.
+ - link "Oferta najmu długoterminowego" [ref=e189] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e191]: Oferta najmu długoterminowego
+ - generic [ref=e196]:
+ - img [ref=e201]
+ - generic [ref=e222]:
+ - heading "17 oddziałów w całej Polsce" [level=3] [ref=e224]:
+ - text: 17 oddziałów
+ - text: w całej Polsce
+ - heading "Podróżuj z Carei!" [level=2] [ref=e226]
+ - generic [ref=e227]:
+ - paragraph [ref=e228]: Od 2006 roku zajmujemy się szeroko rozumianym wynajmem samochodów osobowych na terenie Polski.
+ - paragraph [ref=e229]:
+ - text: W naszej ofercie znajdują się
+ - strong [ref=e230]: samochody standardowe oraz klasy premium
+ - text: .
+ - generic [ref=e233]:
+ - generic [ref=e234]: Białystok
+ - generic [ref=e235]: "|"
+ - generic [ref=e236]: Bydgoszcz
+ - generic [ref=e237]: "|"
+ - generic [ref=e238]: Gdańsk
+ - generic [ref=e239]: "|"
+ - generic [ref=e240]: Gorzów Wielkopolski
+ - generic [ref=e241]: "|"
+ - generic [ref=e242]: Katowice
+ - generic [ref=e243]: "|"
+ - generic [ref=e244]: Kielce
+ - generic [ref=e245]: "|"
+ - generic [ref=e246]: Kraków
+ - generic [ref=e247]: "|"
+ - generic [ref=e248]: Lublin
+ - generic [ref=e249]: "|"
+ - generic [ref=e250]: Olsztyn
+ - generic [ref=e251]: "|"
+ - generic [ref=e252]: Poznań
+ - generic [ref=e253]: "|"
+ - generic [ref=e254]: Radom
+ - generic [ref=e255]: "|"
+ - generic [ref=e256]: Rumia
+ - generic [ref=e257]: "|"
+ - generic [ref=e258]: Rzeszów
+ - generic [ref=e259]: "|"
+ - generic [ref=e260]: Sopot
+ - generic [ref=e261]: "|"
+ - generic [ref=e262]: Szczecin
+ - generic [ref=e263]: "|"
+ - generic [ref=e264]: Warszawa
+ - generic [ref=e265]: "|"
+ - generic [ref=e266]: Wrocław
+ - generic [ref=e267]: "|"
+ - generic [ref=e268]: Łódź
+ - generic [ref=e275]:
+ - heading "Wypożycz auto na swój wyjazd." [level=2] [ref=e277]
+ - paragraph [ref=e279]:
+ - text: Szybka obsługa zamówienia
+ - text: i minimum formalności.
+ - generic [ref=e280]:
+ - region "Carousel" [ref=e281]:
+ - generic [ref=e282]:
+ - group [ref=e283]:
+ - generic [ref=e287]:
+ - heading [level=3] [ref=e289]: Segment B
+ - paragraph [ref=e291]: "Przykładowy model: Toyota Yaris"
+ - paragraph [ref=e293]: Od 79 zł brutto / doba
+ - link [ref=e295] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e296]:
+ - img [ref=e298]
+ - generic [ref=e300]: Złóż zapytanie o rezerwację
+ - group [ref=e301]:
+ - generic [ref=e305]:
+ - heading [level=3] [ref=e307]: Segment LUX
+ - paragraph [ref=e309]: "Przykładowy model: Toyota Yaris"
+ - paragraph [ref=e311]: Od 79 zł brutto / doba
+ - link [ref=e313] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e314]:
+ - img [ref=e316]
+ - generic [ref=e318]: Złóż zapytanie o rezerwację
+ - group [ref=e319]:
+ - generic [ref=e323]:
+ - heading [level=3] [ref=e325]: Segment C/C+
+ - paragraph [ref=e327]: "Przykładowy model: Toyota Yaris"
+ - paragraph [ref=e329]: Od 79 zł brutto / doba
+ - link [ref=e331] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e332]:
+ - img [ref=e334]
+ - generic [ref=e336]: Złóż zapytanie o rezerwację
+ - group "1 / 3" [ref=e337]:
+ - generic [ref=e341]:
+ - heading "Segment B" [level=3] [ref=e343]
+ - paragraph [ref=e345]:
+ - text: "Przykładowy model:"
+ - text: Toyota Yaris
+ - paragraph [ref=e347]: Od 79 zł brutto / doba
+ - link "Złóż zapytanie o rezerwację" [ref=e349] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e350]:
+ - img [ref=e352]
+ - generic [ref=e354]: Złóż zapytanie o rezerwację
+ - group "2 / 3" [ref=e355]:
+ - generic [ref=e359]:
+ - heading "Segment LUX" [level=3] [ref=e361]
+ - paragraph [ref=e363]:
+ - text: "Przykładowy model:"
+ - text: Toyota Yaris
+ - paragraph [ref=e365]: Od 79 zł brutto / doba
+ - link "Złóż zapytanie o rezerwację" [ref=e367] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e368]:
+ - img [ref=e370]
+ - generic [ref=e372]: Złóż zapytanie o rezerwację
+ - group "3 / 3" [ref=e373]:
+ - generic [ref=e377]:
+ - heading "Segment C/C+" [level=3] [ref=e379]
+ - paragraph [ref=e381]:
+ - text: "Przykładowy model:"
+ - text: Toyota Yaris
+ - paragraph [ref=e383]: Od 79 zł brutto / doba
+ - link "Złóż zapytanie o rezerwację" [ref=e385] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e386]:
+ - img [ref=e388]
+ - generic [ref=e390]: Złóż zapytanie o rezerwację
+ - group [ref=e391]:
+ - generic [ref=e395]:
+ - heading [level=3] [ref=e397]: Segment B
+ - paragraph [ref=e399]: "Przykładowy model: Toyota Yaris"
+ - paragraph [ref=e401]: Od 79 zł brutto / doba
+ - link [ref=e403] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e404]:
+ - img [ref=e406]
+ - generic [ref=e408]: Złóż zapytanie o rezerwację
+ - group [ref=e409]:
+ - generic [ref=e413]:
+ - heading [level=3] [ref=e415]: Segment LUX
+ - paragraph [ref=e417]: "Przykładowy model: Toyota Yaris"
+ - paragraph [ref=e419]: Od 79 zł brutto / doba
+ - link [ref=e421] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e422]:
+ - img [ref=e424]
+ - generic [ref=e426]: Złóż zapytanie o rezerwację
+ - group [ref=e427]:
+ - generic [ref=e431]:
+ - heading [level=3] [ref=e433]: Segment C/C+
+ - paragraph [ref=e435]: "Przykładowy model: Toyota Yaris"
+ - paragraph [ref=e437]: Od 79 zł brutto / doba
+ - link [ref=e439] [cursor=pointer]:
+ - /url: "#"
+ - generic [ref=e440]:
+ - img [ref=e442]
+ - generic [ref=e444]: Złóż zapytanie o rezerwację
+ - button "Poprzedni slajd" [ref=e445] [cursor=pointer]:
+ - img [ref=e446]
+ - button "Następny slajd" [ref=e448] [cursor=pointer]:
+ - img [ref=e449]
+ - heading "Opinie o Carei." [level=2] [ref=e461]
+ - region "Carousel" [ref=e463]:
+ - generic [ref=e464]:
+ - group [ref=e465]:
+ - generic [ref=e467]:
+ - generic [ref=e468]:
+ - img [ref=e471]:
+ - generic [ref=e472]:
+ - img [ref=e474]
+ - img [ref=e477]
+ - generic [ref=e479]:
+ - img [ref=e481]
+ - img [ref=e484]
+ - generic [ref=e486]:
+ - img [ref=e488]
+ - img [ref=e491]
+ - generic [ref=e493]:
+ - img [ref=e495]
+ - img [ref=e498]
+ - generic [ref=e500]:
+ - img [ref=e502]
+ - img [ref=e505]
+ - link [ref=e508] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e510]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e511]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e512]: Aneta W.
+ - group [ref=e513]:
+ - generic [ref=e515]:
+ - generic [ref=e516]:
+ - img [ref=e519]:
+ - generic [ref=e520]:
+ - img [ref=e522]
+ - img [ref=e525]
+ - generic [ref=e527]:
+ - img [ref=e529]
+ - img [ref=e532]
+ - generic [ref=e534]:
+ - img [ref=e536]
+ - img [ref=e539]
+ - generic [ref=e541]:
+ - img [ref=e543]
+ - img [ref=e546]
+ - generic [ref=e548]:
+ - img [ref=e550]
+ - img [ref=e553]
+ - link [ref=e556] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e558]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e559]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e560]: Aneta W.
+ - group [ref=e561]:
+ - generic [ref=e563]:
+ - generic [ref=e564]:
+ - img [ref=e567]:
+ - generic [ref=e568]:
+ - img [ref=e570]
+ - img [ref=e573]
+ - generic [ref=e575]:
+ - img [ref=e577]
+ - img [ref=e580]
+ - generic [ref=e582]:
+ - img [ref=e584]
+ - img [ref=e587]
+ - generic [ref=e589]:
+ - img [ref=e591]
+ - img [ref=e594]
+ - generic [ref=e596]:
+ - img [ref=e598]
+ - img [ref=e601]
+ - link [ref=e604] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e606]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e607]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e608]: Aneta W.
+ - group "1 / 4" [ref=e609]:
+ - generic [ref=e611]:
+ - generic [ref=e612]:
+ - img "Ocena 5 z 5" [ref=e615]:
+ - generic [ref=e616]:
+ - img [ref=e618]
+ - img [ref=e621]
+ - generic [ref=e623]:
+ - img [ref=e625]
+ - img [ref=e628]
+ - generic [ref=e630]:
+ - img [ref=e632]
+ - img [ref=e635]
+ - generic [ref=e637]:
+ - img [ref=e639]
+ - img [ref=e642]
+ - generic [ref=e644]:
+ - img [ref=e646]
+ - img [ref=e649]
+ - link [ref=e652] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e654]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e655]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e656]: Aneta W.
+ - group "2 / 4" [ref=e657]:
+ - generic [ref=e659]:
+ - generic [ref=e660]:
+ - img "Ocena 5 z 5" [ref=e663]:
+ - generic [ref=e664]:
+ - img [ref=e666]
+ - img [ref=e669]
+ - generic [ref=e671]:
+ - img [ref=e673]
+ - img [ref=e676]
+ - generic [ref=e678]:
+ - img [ref=e680]
+ - img [ref=e683]
+ - generic [ref=e685]:
+ - img [ref=e687]
+ - img [ref=e690]
+ - generic [ref=e692]:
+ - img [ref=e694]
+ - img [ref=e697]
+ - link [ref=e700] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e702]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e703]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e704]: Aneta W.
+ - group "3 / 4" [ref=e705]:
+ - generic [ref=e707]:
+ - generic [ref=e708]:
+ - img "Ocena 5 z 5" [ref=e711]:
+ - generic [ref=e712]:
+ - img [ref=e714]
+ - img [ref=e717]
+ - generic [ref=e719]:
+ - img [ref=e721]
+ - img [ref=e724]
+ - generic [ref=e726]:
+ - img [ref=e728]
+ - img [ref=e731]
+ - generic [ref=e733]:
+ - img [ref=e735]
+ - img [ref=e738]
+ - generic [ref=e740]:
+ - img [ref=e742]
+ - img [ref=e745]
+ - link [ref=e748] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e750]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e751]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e752]: Aneta W.
+ - group [ref=e753]:
+ - generic [ref=e755]:
+ - generic [ref=e756]:
+ - img [ref=e759]:
+ - generic [ref=e760]:
+ - img [ref=e762]
+ - img [ref=e765]
+ - generic [ref=e767]:
+ - img [ref=e769]
+ - img [ref=e772]
+ - generic [ref=e774]:
+ - img [ref=e776]
+ - img [ref=e779]
+ - generic [ref=e781]:
+ - img [ref=e783]
+ - img [ref=e786]
+ - generic [ref=e788]:
+ - img [ref=e790]
+ - img [ref=e793]
+ - link [ref=e796] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e798]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e799]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e800]: Aneta W.
+ - group [ref=e801]:
+ - generic [ref=e803]:
+ - generic [ref=e804]:
+ - img [ref=e807]:
+ - generic [ref=e808]:
+ - img [ref=e810]
+ - img [ref=e813]
+ - generic [ref=e815]:
+ - img [ref=e817]
+ - img [ref=e820]
+ - generic [ref=e822]:
+ - img [ref=e824]
+ - img [ref=e827]
+ - generic [ref=e829]:
+ - img [ref=e831]
+ - img [ref=e834]
+ - generic [ref=e836]:
+ - img [ref=e838]
+ - img [ref=e841]
+ - link [ref=e844] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e846]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e847]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e848]: Aneta W.
+ - group [ref=e849]:
+ - generic [ref=e851]:
+ - generic [ref=e852]:
+ - img [ref=e855]:
+ - generic [ref=e856]:
+ - img [ref=e858]
+ - img [ref=e861]
+ - generic [ref=e863]:
+ - img [ref=e865]
+ - img [ref=e868]
+ - generic [ref=e870]:
+ - img [ref=e872]
+ - img [ref=e875]
+ - generic [ref=e877]:
+ - img [ref=e879]
+ - img [ref=e882]
+ - generic [ref=e884]:
+ - img [ref=e886]
+ - img [ref=e889]
+ - link [ref=e892] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e894]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e895]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e896]: Aneta W.
+ - group [ref=e897]:
+ - generic [ref=e899]:
+ - generic [ref=e900]:
+ - img [ref=e903]:
+ - generic [ref=e904]:
+ - img [ref=e906]
+ - img [ref=e909]
+ - generic [ref=e911]:
+ - img [ref=e913]
+ - img [ref=e916]
+ - generic [ref=e918]:
+ - img [ref=e920]
+ - img [ref=e923]
+ - generic [ref=e925]:
+ - img [ref=e927]
+ - img [ref=e930]
+ - generic [ref=e932]:
+ - img [ref=e934]
+ - img [ref=e937]
+ - link [ref=e940] [cursor=pointer]:
+ - /url: https://carei.pagedev.pl
+ - paragraph [ref=e942]:
+ - text: Lorem ipsum dolor sit amet consectetur. Id ut sit sed diam id lorem donec.
+ - strong [ref=e943]: Id eget felis enim
+ - text: ullamcorper dui adipiscing sed. Pharetra at egestas sed dignissim. Viverra ultrices id lacus eu ultricies commodo. Morbi ipsum purus est dolor. Luctus etiam mi nunc augue.
+ - generic [ref=e944]: Aneta W.
+ - contentinfo [ref=e945]:
+ - generic [ref=e948]:
+ - heading "Szukasz więcej informacji?" [level=4] [ref=e950]
+ - heading "Skontaktuj się z naszą obsługą." [level=3] [ref=e955]:
+ - text: Skontaktuj się
+ - text: z naszą obsługą.
+ - generic [ref=e959]:
+ - generic [ref=e961]:
+ - link "Assistance" [ref=e963] [cursor=pointer]:
+ - /url: tel:+48572663614
+ - img [ref=e964]
+ - generic [ref=e968]:
+ - heading "Assistance" [level=3] [ref=e969]:
+ - link "Assistance" [ref=e970] [cursor=pointer]:
+ - /url: tel:+48572663614
+ - paragraph [ref=e971]: +48 572 663 614
+ - generic [ref=e973]:
+ - link "Biuro" [ref=e975] [cursor=pointer]:
+ - /url: mailto:bok@carei.pl
+ - img [ref=e976]
+ - generic [ref=e982]:
+ - heading "Biuro" [level=3] [ref=e983]:
+ - link "Biuro" [ref=e984] [cursor=pointer]:
+ - /url: mailto:bok@carei.pl
+ - paragraph [ref=e985]: bok@carei.pl
+ - generic [ref=e996]:
+ - heading "Carei - Wypożyczalnia aut osobowych" [level=3] [ref=e998]
+ - generic [ref=e999]:
+ - paragraph [ref=e1001]:
+ - text: CAREI Sp. z o.o. Sp. k.
+ - text: ul. Solipska 1/U4,
+ - text: 02-482 Warszawa
+ - paragraph [ref=e1003]:
+ - text: "NIP: 527 249 90 39"
+ - text: "REGON: 140473129 KRS: 0000668452"
+ - generic [ref=e1011]:
+ - paragraph [ref=e1013]: Copyright © 2026 Carei
+ - paragraph [ref=e1015]: "Designed by: Kreatywny Brand"
+ - generic [ref=e1016]: laptop
\ No newline at end of file
diff --git a/.vscode/ftp-kr.sync.cache.json b/.vscode/ftp-kr.sync.cache.json
index 4d40e45..a538f0f 100644
--- a/.vscode/ftp-kr.sync.cache.json
+++ b/.vscode/ftp-kr.sync.cache.json
@@ -31,37 +31,12 @@
"lmtime": 0,
"modified": false
},
- ".playwright-mcp": {},
"readme.html": {
"type": "-",
"size": 7425,
"lmtime": 0,
"modified": false
},
- ".serena": {
- ".gitignore": {
- "type": "-",
- "size": 28,
- "lmtime": 1774382289791,
- "modified": false
- },
- "memories": {},
- "project.local.yml": {
- "type": "-",
- "size": 407,
- "lmtime": 1774382289788,
- "modified": false
- },
- "project.yml": {
- "type": "-",
- "size": 9594,
- "lmtime": 1774382289785,
- "modified": false
- },
- "cache": {
- "php": {}
- }
- },
"softra-test.php": {
"type": "-",
"size": 6081,
diff --git a/carei-cities-current.png b/carei-cities-current.png
new file mode 100644
index 0000000..d6f0d1f
Binary files /dev/null and b/carei-cities-current.png differ
diff --git a/carei-cities-section.png b/carei-cities-section.png
new file mode 100644
index 0000000..6fc9dee
Binary files /dev/null and b/carei-cities-section.png differ
diff --git a/carei-full-page.png b/carei-full-page.png
new file mode 100644
index 0000000..dcbb39f
Binary files /dev/null and b/carei-full-page.png differ
diff --git a/wp-admin/.DS_Store b/wp-admin/.DS_Store
deleted file mode 100644
index 676ccd7..0000000
Binary files a/wp-admin/.DS_Store and /dev/null differ
diff --git a/wp-content/.DS_Store b/wp-content/.DS_Store
deleted file mode 100644
index 611bffa..0000000
Binary files a/wp-content/.DS_Store and /dev/null differ
diff --git a/wp-content/languages/.DS_Store b/wp-content/languages/.DS_Store
deleted file mode 100644
index 8f047d7..0000000
Binary files a/wp-content/languages/.DS_Store and /dev/null differ
diff --git a/wp-content/plugins/.DS_Store b/wp-content/plugins/.DS_Store
deleted file mode 100644
index b9b4f1c..0000000
Binary files a/wp-content/plugins/.DS_Store and /dev/null differ
diff --git a/wp-content/plugins/carei-reservation/assets/css/carei-reservation.css b/wp-content/plugins/carei-reservation/assets/css/carei-reservation.css
index 1f047f7..a04ecab 100644
--- a/wp-content/plugins/carei-reservation/assets/css/carei-reservation.css
+++ b/wp-content/plugins/carei-reservation/assets/css/carei-reservation.css
@@ -1403,3 +1403,164 @@ button.carei-reservation-trigger:hover {
flex-direction: column;
}
}
+
+/* ═══════════════════════════════════════════
+ Carei Map Widget
+ ═══════════════════════════════════════════ */
+
+.carei-map {
+ position: relative;
+ max-width: 520px;
+ width: 100%;
+}
+
+.carei-map__svg {
+ width: 100%;
+ height: auto;
+ display: block;
+}
+
+.carei-map__pin {
+ cursor: pointer;
+ transition: r 0.2s ease, fill 0.2s ease;
+}
+
+.carei-map__pin:hover,
+.carei-map__pin--active {
+ r: 8;
+}
+
+.carei-map__tooltip {
+ position: absolute;
+ pointer-events: none;
+ z-index: 10;
+ transform: translate(-50%, -100%);
+ padding-bottom: 12px;
+}
+
+.carei-map__tooltip-content {
+ background: var(--carei-blue);
+ color: var(--carei-white);
+ font-family: var(--carei-font);
+ font-size: 13px;
+ line-height: 1.4;
+ padding: 10px 14px;
+ border-radius: var(--carei-radius);
+ white-space: pre-line;
+ min-width: 160px;
+ max-width: 260px;
+ text-align: center;
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
+}
+
+.carei-map__tooltip-content::after {
+ content: '';
+ position: absolute;
+ bottom: 4px;
+ left: 50%;
+ transform: translateX(-50%);
+ border: 6px solid transparent;
+ border-top-color: var(--carei-blue);
+}
+
+/* ═══════════════════════════════════════════
+ Carei Cities Widget
+ ═══════════════════════════════════════════ */
+
+.carei-cities {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: flex-start;
+ align-items: center;
+ gap: 6px 0;
+ font-family: var(--carei-font);
+ font-size: 15px;
+ font-weight: 500;
+ color: var(--carei-blue);
+ line-height: 2;
+}
+
+.carei-cities__item {
+ white-space: nowrap;
+}
+
+.carei-cities__item::after {
+ content: '|';
+ padding: 0 14px;
+ opacity: 0.35;
+ font-weight: 300;
+ display: inline-block;
+}
+
+.carei-cities__item:last-child::after {
+ display: none;
+}
+
+@media (max-width: 767px) {
+ .carei-cities {
+ font-size: 13px;
+ gap: 4px 0;
+ }
+ .carei-cities__item::after {
+ padding: 0 8px;
+ }
+}
+
+/* ═══════════════════════════════════════════
+ Carei Branches Widget
+ ═══════════════════════════════════════════ */
+
+.carei-branches {
+ display: grid;
+ grid-template-columns: repeat(5, 1fr);
+ font-family: var(--carei-font);
+ color: var(--carei-white);
+}
+
+.carei-branches__item {
+ padding: 24px 16px;
+ text-align: center;
+ border-top: 1px solid rgba(255, 255, 255, 0.15);
+}
+
+.carei-branches__name {
+ font-size: 16px;
+ font-weight: 700;
+ margin-bottom: 6px;
+}
+
+.carei-branches__street,
+.carei-branches__zip-city {
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 1.5;
+ opacity: 0.85;
+}
+
+@media (max-width: 1024px) {
+ .carei-branches {
+ grid-template-columns: repeat(3, 1fr);
+ }
+}
+
+@media (max-width: 767px) {
+ .carei-branches {
+ grid-template-columns: repeat(2, 1fr);
+ }
+ .carei-branches__item {
+ padding: 18px 12px;
+ }
+ .carei-branches__name {
+ font-size: 14px;
+ }
+ .carei-branches__street,
+ .carei-branches__zip-city {
+ font-size: 13px;
+ }
+}
+
+@media (max-width: 480px) {
+ .carei-branches {
+ grid-template-columns: 1fr;
+ }
+}
diff --git a/wp-content/plugins/carei-reservation/assets/js/carei-reservation.js b/wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
index b05487a..578c046 100644
--- a/wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
+++ b/wp-content/plugins/carei-reservation/assets/js/carei-reservation.js
@@ -1265,6 +1265,110 @@
initClearErrors();
initAbroad();
initSubmit();
+ initMap();
+ }
+
+ /* ═══════════════════════════════════════════
+ Carei Map — dynamic pins & tooltips
+ ═══════════════════════════════════════════ */
+
+ function initMap() {
+ var mapEl = document.querySelector('.carei-map');
+ if (!mapEl) return;
+
+ var pins;
+ try {
+ pins = JSON.parse(mapEl.getAttribute('data-pins') || '[]');
+ } catch (e) {
+ return;
+ }
+ if (!pins.length) return;
+
+ var svg = mapEl.querySelector('.carei-map__svg');
+ var pinsGroup = svg.querySelector('.carei-map__pins');
+ var tooltip = mapEl.querySelector('.carei-map__tooltip');
+ var tooltipContent = mapEl.querySelector('.carei-map__tooltip-content');
+ if (!svg || !pinsGroup || !tooltip || !tooltipContent) return;
+
+ var activePin = null;
+ var SVG_NS = 'http://www.w3.org/2000/svg';
+
+ pins.forEach(function (pin) {
+ var circle = document.createElementNS(SVG_NS, 'circle');
+ circle.setAttribute('cx', pin.x);
+ circle.setAttribute('cy', pin.y);
+ circle.setAttribute('r', '6');
+ circle.setAttribute('fill', '#FF0000');
+ circle.setAttribute('class', 'carei-map__pin');
+ circle.setAttribute('data-city', pin.city);
+ circle.setAttribute('data-address', pin.address || '');
+
+ circle.addEventListener('mouseenter', function () {
+ showTooltip(pin, circle);
+ });
+ circle.addEventListener('mouseleave', function () {
+ if (activePin !== circle) {
+ hideTooltip();
+ }
+ });
+ circle.addEventListener('click', function (e) {
+ e.stopPropagation();
+ if (activePin === circle) {
+ activePin = null;
+ circle.classList.remove('carei-map__pin--active');
+ hideTooltip();
+ } else {
+ if (activePin) activePin.classList.remove('carei-map__pin--active');
+ activePin = circle;
+ circle.classList.add('carei-map__pin--active');
+ showTooltip(pin, circle);
+ }
+ });
+
+ pinsGroup.appendChild(circle);
+ });
+
+ // Click outside closes tooltip
+ document.addEventListener('click', function () {
+ if (activePin) {
+ activePin.classList.remove('carei-map__pin--active');
+ activePin = null;
+ hideTooltip();
+ }
+ });
+
+ function showTooltip(pin, circle) {
+ // Build tooltip text: address lines + bold city
+ var addr = pin.address || '';
+ var lines = addr ? addr.replace(/\\n/g, '\n') : pin.city;
+ tooltipContent.textContent = '';
+
+ // If address has postal code, format nicely
+ if (addr) {
+ tooltipContent.innerHTML = addr.replace(/\n/g, '
');
+ } else {
+ tooltipContent.textContent = pin.city;
+ }
+
+ // Position tooltip relative to map container
+ var svgRect = svg.getBoundingClientRect();
+ var mapRect = mapEl.getBoundingClientRect();
+ var svgWidth = svg.viewBox.baseVal.width || 600;
+ var svgHeight = svg.viewBox.baseVal.height || 570;
+ var scaleX = svgRect.width / svgWidth;
+ var scaleY = svgRect.height / svgHeight;
+
+ var left = (svgRect.left - mapRect.left) + pin.x * scaleX;
+ var top = (svgRect.top - mapRect.top) + pin.y * scaleY;
+
+ tooltip.style.display = 'block';
+ tooltip.style.left = left + 'px';
+ tooltip.style.top = top + 'px';
+ }
+
+ function hideTooltip() {
+ tooltip.style.display = 'none';
+ }
}
if (document.readyState === 'loading') {
diff --git a/wp-content/plugins/carei-reservation/carei-reservation.php b/wp-content/plugins/carei-reservation/carei-reservation.php
index ab037db..d967d07 100644
--- a/wp-content/plugins/carei-reservation/carei-reservation.php
+++ b/wp-content/plugins/carei-reservation/carei-reservation.php
@@ -88,6 +88,15 @@ add_action( 'elementor/widgets/register', function ( $widgets_manager ) {
require_once CAREI_RESERVATION_PATH . 'includes/class-search-widget.php';
$widgets_manager->register( new Carei_Search_Widget() );
+
+ require_once CAREI_RESERVATION_PATH . 'includes/class-map-widget.php';
+ $widgets_manager->register( new Carei_Map_Widget() );
+
+ require_once CAREI_RESERVATION_PATH . 'includes/class-cities-widget.php';
+ $widgets_manager->register( new Carei_Cities_Widget() );
+
+ require_once CAREI_RESERVATION_PATH . 'includes/class-branches-widget.php';
+ $widgets_manager->register( new Carei_Branches_Widget() );
} );
/**
diff --git a/wp-content/plugins/carei-reservation/includes/class-branches-widget.php b/wp-content/plugins/carei-reservation/includes/class-branches-widget.php
new file mode 100644
index 0000000..d8afdc6
--- /dev/null
+++ b/wp-content/plugins/carei-reservation/includes/class-branches-widget.php
@@ -0,0 +1,133 @@
+ 'BYDGOSZCZ',
+ 'GORZÓW WIE' => 'GORZÓW WIELKOPOLSKI',
+ 'RZSZÓW' => 'RZESZÓW',
+ 'SK-KAM' => '',
+ );
+
+ public function get_name() {
+ return 'carei-branches';
+ }
+
+ public function get_title() {
+ return 'Carei Branches';
+ }
+
+ public function get_icon() {
+ return 'eicon-posts-grid';
+ }
+
+ public function get_categories() {
+ return array( 'general' );
+ }
+
+ public function get_style_depends() {
+ return array( 'carei-reservation-css' );
+ }
+
+ protected function register_controls() {}
+
+ /**
+ * Clean branch name and return base city.
+ */
+ private static function clean_name( $raw ) {
+ $name = trim( $raw );
+ $name = preg_replace( '/\s+[DL]$/u', '', $name );
+ if ( isset( self::NAME_FIXES[ $name ] ) ) {
+ $name = self::NAME_FIXES[ $name ];
+ }
+ if ( empty( $name ) || preg_match( '/^[A-Z]{2,4}-[A-Z]{2,4}$/u', $name ) ) {
+ return '';
+ }
+ return $name;
+ }
+
+ /**
+ * Get unique branches with addresses.
+ */
+ private function get_branches_data() {
+ $api = Carei_Softra_API::get_instance();
+ if ( null === $api ) {
+ return array();
+ }
+
+ $branches = $api->get_branches_cached();
+ if ( is_wp_error( $branches ) || ! is_array( $branches ) ) {
+ return array();
+ }
+
+ $result = array();
+ $seen = array();
+
+ foreach ( $branches as $b ) {
+ $raw_name = isset( $b['name'] ) ? $b['name'] : '';
+ $city = self::clean_name( $raw_name );
+ if ( empty( $city ) ) {
+ continue;
+ }
+
+ $norm = mb_strtolower( $city, 'UTF-8' );
+ if ( isset( $seen[ $norm ] ) ) {
+ continue;
+ }
+ $seen[ $norm ] = true;
+
+ $display_city = mb_convert_case( $city, MB_CASE_TITLE, 'UTF-8' );
+ $street = isset( $b['street'] ) ? trim( $b['street'] ) : '';
+ $zip = isset( $b['zipCode'] ) ? trim( (string) $b['zipCode'] ) : '';
+ $api_city = isset( $b['city'] ) ? trim( $b['city'] ) : '';
+ $api_city_tc = mb_convert_case( $api_city, MB_CASE_TITLE, 'UTF-8' );
+
+ // Format street
+ if ( $street ) {
+ $street_lower = mb_strtolower( $street, 'UTF-8' );
+ $has_prefix = preg_match( '/^(ul\.|al\.|pl\.|os\.)/u', $street_lower );
+ $street = $has_prefix ? $street : 'ul. ' . $street;
+ }
+
+ $result[] = array(
+ 'name' => 'Oddział ' . $display_city,
+ 'street' => $street,
+ 'zipCity' => trim( $zip . ' ' . $api_city_tc ),
+ );
+ }
+
+ usort( $result, function ( $a, $b ) {
+ return strcmp( $a['name'], $b['name'] );
+ } );
+
+ return $result;
+ }
+
+ protected function render() {
+ $branches = $this->get_branches_data();
+ if ( empty( $branches ) ) {
+ return;
+ }
+ ?>
+
+ 'BYDGOSZCZ',
+ 'GORZÓW WIE' => 'GORZÓW WIELKOPOLSKI',
+ 'RZSZÓW' => 'RZESZÓW',
+ 'SK-KAM' => '',
+ );
+
+ /**
+ * Clean branch name: handle D(Dworzec)/L suffixes, fix truncated names, title-case.
+ * API returns names like "GDAŃSK D", "GDAŃSK L", "BYDGOSZC D", "SK-KAM", "GORZÓW WIE".
+ * D-suffix branches without a base variant → "Oddział [City]".
+ */
+ private static function clean_city_name( $raw ) {
+ $name = trim( $raw );
+ // Detect D (Dworzec) suffix before stripping
+ $is_dworzec = (bool) preg_match( '/\s+D$/u', $name );
+ // Strip trailing single-letter suffixes (D=Dworzec, L=Lotnisko/inne)
+ $name = preg_replace( '/\s+[DL]$/u', '', $name );
+ // Fix known truncated/misspelled names
+ if ( isset( self::NAME_FIXES[ $name ] ) ) {
+ $name = self::NAME_FIXES[ $name ];
+ }
+ // Skip empty or non-city codes
+ if ( empty( $name ) || preg_match( '/^[A-Z]{2,4}-[A-Z]{2,4}$/u', $name ) ) {
+ return '';
+ }
+ // Title-case: "GDAŃSK" → "Gdańsk"
+ $name = mb_convert_case( $name, MB_CASE_TITLE, 'UTF-8' );
+ return $name;
+ }
+
+ /**
+ * Extract unique city names from branches.
+ */
+ private function get_city_names() {
+ $api = Carei_Softra_API::get_instance();
+ if ( null === $api ) {
+ return array();
+ }
+
+ $branches = $api->get_branches_cached();
+ if ( is_wp_error( $branches ) || ! is_array( $branches ) ) {
+ return array();
+ }
+
+ $cities = array();
+ $seen = array();
+
+ foreach ( $branches as $b ) {
+ $name = isset( $b['name'] ) ? $b['name'] : '';
+ $city = self::clean_city_name( $name );
+ if ( empty( $city ) ) {
+ continue;
+ }
+
+ $norm = mb_strtolower( $city, 'UTF-8' );
+ if ( isset( $seen[ $norm ] ) ) {
+ continue;
+ }
+ $seen[ $norm ] = true;
+ $cities[] = $city;
+ }
+
+ sort( $cities );
+ return $cities;
+ }
+
+ protected function render() {
+ $cities = $this->get_city_names();
+ if ( empty( $cities ) ) {
+ return;
+ }
+ ?>
+
+ $city ) : ?>
+
+
+
+ array( 304, 169 ),
+ 'krakow' => array( 257, 310 ),
+ 'wroclaw' => array( 129, 242 ),
+ 'gdansk' => array( 200, 32 ),
+ 'poznan' => array( 124, 158 ),
+ 'katowice' => array( 217, 298 ),
+ 'lodz' => array( 237, 201 ),
+ 'lublin' => array( 373, 233 ),
+ 'bialystok' => array( 399, 111 ),
+ 'szczecin' => array( 40, 92 ),
+ 'rzeszow' => array( 348, 311 ),
+ 'bydgoszcz' => array( 171, 112 ),
+ 'olsztyn' => array( 281, 69 ),
+ 'kielce' => array( 288, 258 ),
+ 'opole' => array( 168, 271 ),
+ 'zielona gora' => array( 61, 188 ),
+ 'radom' => array( 311, 224 ),
+ 'torun' => array( 198, 119 ),
+ 'czestochowa' => array( 221, 262 ),
+ 'gliwice' => array( 201, 296 ),
+ 'sosnowiec' => array( 221, 296 ),
+ 'gdynia' => array( 195, 21 ),
+ 'plock' => array( 247, 149 ),
+ 'tarnow' => array( 304, 313 ),
+ 'legnica' => array( 90, 236 ),
+ 'grudziadz' => array( 205, 88 ),
+ 'slupsk' => array( 129, 25 ),
+ 'koszalin' => array( 91, 42 ),
+ 'elblag' => array( 233, 44 ),
+ 'siedlce' => array( 361, 173 ),
+ 'nowy sacz' => array( 291, 339 ),
+ 'piotrkow trybunalski' => array( 247, 224 ),
+ 'zamosc' => array( 403, 268 ),
+ 'przemysl' => array( 382, 329 ),
+ 'wloclawek' => array( 219, 142 ),
+ 'skierniewice' => array( 267, 188 ),
+ 'gorzow wie' => array( 87, 210 ),
+ 'gorzow wielkopolski' => array( 87, 210 ),
+ 'rumia' => array( 192, 28 ),
+ 'sopot' => array( 197, 27 ),
+ 'bydgoszc' => array( 171, 112 ),
+ 'rzszow' => array( 348, 311 ),
+ );
+
+ public function get_name() {
+ return 'carei-map';
+ }
+
+ public function get_title() {
+ return 'Carei Map';
+ }
+
+ public function get_icon() {
+ return 'eicon-google-maps';
+ }
+
+ public function get_categories() {
+ return array( 'general' );
+ }
+
+ public function get_style_depends() {
+ return array( 'carei-reservation-css' );
+ }
+
+ public function get_script_depends() {
+ return array( 'carei-reservation-js' );
+ }
+
+ protected function register_controls() {}
+
+ /**
+ * Normalize city name: lowercase, strip Polish diacritics.
+ */
+ private static function normalize_city( $name ) {
+ $map = array(
+ 'ą' => 'a', 'ć' => 'c', 'ę' => 'e', 'ł' => 'l', 'ń' => 'n',
+ 'ó' => 'o', 'ś' => 's', 'ź' => 'z', 'ż' => 'z',
+ 'Ą' => 'a', 'Ć' => 'c', 'Ę' => 'e', 'Ł' => 'l', 'Ń' => 'n',
+ 'Ó' => 'o', 'Ś' => 's', 'Ź' => 'z', 'Ż' => 'z',
+ );
+ $name = mb_strtolower( trim( $name ), 'UTF-8' );
+ return strtr( $name, $map );
+ }
+
+ /**
+ * Truncated / misspelled names from Softra API → correct full city names.
+ */
+ const NAME_FIXES = array(
+ 'BYDGOSZC' => 'BYDGOSZCZ',
+ 'GORZÓW WIE' => 'GORZÓW WIELKOPOLSKI',
+ 'RZSZÓW' => 'RZESZÓW',
+ 'SK-KAM' => '',
+ );
+
+ /**
+ * Clean branch name: handle D(Dworzec)/L suffixes, fix truncated names, skip codes.
+ * Returns array: [ 'name' => cleaned name, 'dworzec' => bool ]
+ */
+ private static function clean_branch_name( $raw ) {
+ $name = trim( $raw );
+ $is_dworzec = (bool) preg_match( '/\s+D$/u', $name );
+ $name = preg_replace( '/\s+[DL]$/u', '', $name );
+ if ( isset( self::NAME_FIXES[ $name ] ) ) {
+ $name = self::NAME_FIXES[ $name ];
+ }
+ if ( empty( $name ) || preg_match( '/^[A-Z]{2,4}-[A-Z]{2,4}$/u', $name ) ) {
+ return array( 'name' => '', 'dworzec' => false );
+ }
+ return array( 'name' => $name, 'dworzec' => $is_dworzec );
+ }
+
+ /**
+ * Build branch data with coordinates for JS.
+ */
+ private function get_branch_pins() {
+ $api = Carei_Softra_API::get_instance();
+ if ( null === $api ) {
+ return array();
+ }
+
+ $branches = $api->get_branches_cached();
+ if ( is_wp_error( $branches ) || ! is_array( $branches ) ) {
+ return array();
+ }
+
+ $pins = array();
+ $seen_cities = array();
+
+ foreach ( $branches as $b ) {
+ $raw_name = isset( $b['name'] ) ? $b['name'] : '';
+ $cleaned = self::clean_branch_name( $raw_name );
+ $city = $cleaned['name'];
+ if ( empty( $city ) ) {
+ continue;
+ }
+
+ $norm = self::normalize_city( $city );
+ if ( isset( $seen_cities[ $norm ] ) ) {
+ continue;
+ }
+ $seen_cities[ $norm ] = true;
+
+ $coords = isset( self::CITY_COORDS[ $norm ] ) ? self::CITY_COORDS[ $norm ] : null;
+ if ( ! $coords ) {
+ continue;
+ }
+
+ $display_city = mb_convert_case( $city, MB_CASE_TITLE, 'UTF-8' );
+
+ // Build address from API fields: "ul. Street\nZipCode City"
+ $street = isset( $b['street'] ) ? trim( $b['street'] ) : '';
+ $zip = isset( $b['zipCode'] ) ? trim( (string) $b['zipCode'] ) : '';
+ $api_city = isset( $b['city'] ) ? trim( $b['city'] ) : '';
+ $api_city_title = mb_convert_case( $api_city, MB_CASE_TITLE, 'UTF-8' );
+
+ $address_lines = array( 'Oddział ' . $display_city );
+ if ( $street ) {
+ $street_lower = mb_strtolower( $street, 'UTF-8' );
+ $has_prefix = preg_match( '/^(ul\.|al\.|pl\.|os\.)/u', $street_lower );
+ $address_lines[] = $has_prefix ? $street : 'ul. ' . $street;
+ }
+ $zip_city = trim( $zip . ' ' . $api_city_title );
+ if ( $zip_city ) {
+ $address_lines[] = $zip_city;
+ }
+
+ $pins[] = array(
+ 'city' => $display_city,
+ 'x' => $coords[0],
+ 'y' => $coords[1],
+ 'address' => implode( "\n", $address_lines ),
+ );
+ }
+
+ return $pins;
+ }
+
+ protected function render() {
+ $pins = $this->get_branch_pins();
+ $pins_json = wp_json_encode( $pins );
+ ?>
+
+ 'GET',
+ 'callback' => array( $this, 'get_branches_full' ),
+ 'permission_callback' => '__return_true',
+ ) );
+
// GET /agreements
register_rest_route( self::NAMESPACE, '/agreements', array(
'methods' => 'GET',
@@ -276,6 +283,14 @@ class Carei_REST_Proxy {
) );
}
+ public function get_branches_full( WP_REST_Request $request ) {
+ $api = $this->api();
+ if ( is_wp_error( $api ) ) {
+ return $api;
+ }
+ return $this->respond( $api->get_branches_cached() );
+ }
+
public function get_agreements( WP_REST_Request $request ) {
$api = $this->api();
if ( is_wp_error( $api ) ) {
diff --git a/wp-content/plugins/carei-reservation/includes/class-softra-api.php b/wp-content/plugins/carei-reservation/includes/class-softra-api.php
index 74277fa..f236d2e 100644
--- a/wp-content/plugins/carei-reservation/includes/class-softra-api.php
+++ b/wp-content/plugins/carei-reservation/includes/class-softra-api.php
@@ -153,6 +153,26 @@ class Carei_Softra_API {
return $this->request( 'GET', '/branch/list' );
}
+ /**
+ * Get branches with 60-min transient cache.
+ */
+ public function get_branches_cached() {
+ $cache_key = 'carei_branches_list';
+ $cached = get_transient( $cache_key );
+ if ( false !== $cached ) {
+ return $cached;
+ }
+
+ $branches = $this->get_branches();
+ if ( is_wp_error( $branches ) || ! is_array( $branches ) ) {
+ return is_wp_error( $branches ) ? $branches : array();
+ }
+
+ set_transient( $cache_key, $branches, HOUR_IN_SECONDS );
+
+ return $branches;
+ }
+
public function get_all_car_classes() {
return $this->request( 'GET', '/car/class/listAll' );
}
@@ -170,7 +190,7 @@ class Carei_Softra_API {
return $cached;
}
- $branches = $this->get_branches();
+ $branches = $this->get_branches_cached();
if ( is_wp_error( $branches ) || ! is_array( $branches ) ) {
return is_wp_error( $branches ) ? $branches : array();
}
diff --git a/wp-content/themes/.DS_Store b/wp-content/themes/.DS_Store
deleted file mode 100644
index ed6a7d8..0000000
Binary files a/wp-content/themes/.DS_Store and /dev/null differ
diff --git a/wp-includes/.DS_Store b/wp-includes/.DS_Store
deleted file mode 100644
index 3b26fc3..0000000
Binary files a/wp-includes/.DS_Store and /dev/null differ
diff --git a/wp-includes/Requests/.DS_Store b/wp-includes/Requests/.DS_Store
deleted file mode 100644
index daaed11..0000000
Binary files a/wp-includes/Requests/.DS_Store and /dev/null differ
diff --git a/wp-includes/SimplePie/.DS_Store b/wp-includes/SimplePie/.DS_Store
deleted file mode 100644
index 293c5f7..0000000
Binary files a/wp-includes/SimplePie/.DS_Store and /dev/null differ
diff --git a/wp-includes/blocks/.DS_Store b/wp-includes/blocks/.DS_Store
deleted file mode 100644
index dca73f4..0000000
Binary files a/wp-includes/blocks/.DS_Store and /dev/null differ
diff --git a/wp-includes/images/.DS_Store b/wp-includes/images/.DS_Store
deleted file mode 100644
index e80bca2..0000000
Binary files a/wp-includes/images/.DS_Store and /dev/null differ
diff --git a/wp-includes/js/.DS_Store b/wp-includes/js/.DS_Store
deleted file mode 100644
index f36b7cc..0000000
Binary files a/wp-includes/js/.DS_Store and /dev/null differ
diff --git a/wp-includes/rest-api/.DS_Store b/wp-includes/rest-api/.DS_Store
deleted file mode 100644
index df2d9d6..0000000
Binary files a/wp-includes/rest-api/.DS_Store and /dev/null differ
diff --git a/wp-includes/sodium_compat/.DS_Store b/wp-includes/sodium_compat/.DS_Store
deleted file mode 100644
index f166db1..0000000
Binary files a/wp-includes/sodium_compat/.DS_Store and /dev/null differ