TEL: +421 950 659 908   EMAIL: INFO@YOUTHFULLYYOURS.SK
GEARS

GEARS

About the Project

Green Explorers: Adults Reimagining Sustainability (G.E.A.R.S.) is an Erasmus+ funded project focused on empowering adults with practical skills for sustainable living. The project responds to the growing environmental challenges and the urgent need for accessible, high-quality education that helps individuals adopt eco-friendly lifestyles.

The Problem

Many adults across Europe lack access to practical, engaging, and flexible learning opportunities related to sustainability. While awareness of environmental issues is increasing, there is still a gap in everyday knowledge and skills—such as reducing waste, making sustainable consumption choices, or applying eco-friendly practices in daily life. This limits individuals’ ability to contribute to environmental protection and community resilience.

The Solution

G.E.A.R.S. addresses this gap by transforming sustainability education into accessible and engaging learning experiences. The project develops:

  • Interactive online learning modules on topics like the 5R principles (Refuse, Reduce, Reuse, Recycle, Rot) and zero-waste living

  • Hands-on city quests that allow participants to explore real-life sustainable initiatives

  • A creative comic book that shares participants’ journeys and inspires wider audiences

  • An accredited educational programme aligned with the EU GreenComp framework

  • Community-based “sustainability cabinets” providing tools and resources for local engagement

Together, these activities combine digital learning with real-world experiences to support lasting behaviour change and practical application of sustainability principles.

Target Groups

The project primarily targets:

  • Adult learners (aged 21–60) interested in developing sustainable skills for personal and professional use

  • Educators and trainers who want to integrate sustainability into their teaching

  • Local community members eager to explore eco-friendly practices in their environment

  • Stakeholders and institutions supporting education, sustainability, and policy development

Special attention is given to making learning accessible for people from both urban and rural areas, including those with fewer opportunities.

Impact

By combining education, creativity, and community engagement, G.E.A.R.S. aims to:

  • Increase awareness and adoption of sustainable practices

  • Improve access to flexible and high-quality adult education

  • Empower individuals with certified green competences

  • Strengthen cooperation between organisations and communities across Europe

Ultimately, the project supports individuals in making informed, environmentally responsible choices and contributes to building more sustainable communities!

One Day City Quest – Interactive Map of Local Initiatives

This interactive map was created as part of the One Day City Quest and gathers places related to sustainable living, conscious consumption, and local ecological practices. It features points promoting repair, reuse, waste reduction, plant-based eating choices, and supporting local producers and services. The map encourages participants to explore the city through the lens of everyday activities that can support a more responsible and sustainable lifestyle. It is an educational tool that combines locality, practical experience, and the development of green skills in urban spaces.

#kosice-sustainability-map { margin: 0; padding: 0; font-family: Arial, sans-serif; color: #1f2937; } #kosice-sustainability-map * { box-sizing: border-box; } #kosice-sustainability-map .ksm-shell { display: flex; flex-direction: column; background: #f3f4f6; border-radius: 16px; overflow: hidden; } #kosice-sustainability-map .ksm-header { border-bottom: 1px solid #e5e7eb; background: #ffffff; padding: 20px 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.06); } #kosice-sustainability-map .ksm-header-inner { max-width: 1200px; margin: 0 auto; } #kosice-sustainability-map .ksm-eyebrow { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.2em; color: #047857; margin: 0 0 8px 0; } #kosice-sustainability-map .ksm-title { margin: 0; font-size: 30px; line-height: 1.2; font-weight: 700; color: #111827; } #kosice-sustainability-map .ksm-subtitle { margin: 10px 0 0 0; max-width: 760px; font-size: 16px; line-height: 1.6; color: #4b5563; } #kosice-sustainability-map .ksm-map-wrapper { position: relative; width: 100%; min-height: 650px; background: #dbeafe; box-shadow: 0 10px 20px rgba(0,0,0,0.08); } #kosice-sustainability-map .ksm-map { position: absolute; inset: 0; width: 100%; height: 100%; min-height: 650px; z-index: 1; } #kosice-sustainability-map .ksm-filter-control, #kosice-sustainability-map .ksm-funding-overlay { z-index: 1000; } #kosice-sustainability-map .ksm-filter-control { position: absolute; left: 50%; top: 16px; transform: translateX(-50%); width: auto; max-width: 96%; background: #ffffff; border: 1px solid #e5e7eb; border-radius: 12px; padding: 12px; box-shadow: 0 10px 25px rgba(0,0,0,0.12); pointer-events: auto; } #kosice-sustainability-map .ksm-filter-title { margin: 0 0 10px 0; padding-bottom: 8px; border-bottom: 1px solid #e5e7eb; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: #1f2937; } #kosice-sustainability-map .ksm-filters-list { display: flex; flex-wrap: nowrap; align-items: center; gap: 8px; overflow-x: auto; padding-bottom: 2px; } #kosice-sustainability-map .ksm-filter-btn { flex-shrink: 0; white-space: nowrap; border: none; border-radius: 999px; padding: 8px 14px; font-size: 12px; font-weight: 600; cursor: pointer; transition: 0.2s ease; text-align: center; } #kosice-sustainability-map .ksm-filter-btn.inactive { background: #f3f4f6; color: #4b5563; } #kosice-sustainability-map .ksm-filter-btn.inactive:hover { background: #e5e7eb; } #kosice-sustainability-map .ksm-filter-btn.active:hover { opacity: 0.9; } #kosice-sustainability-map .ksm-funding-overlay { position: absolute; bottom: 16px; left: 16px; max-width: 250px; background: #ffffff; border: 1px solid #e5e7eb; border-radius: 12px; padding: 12px; box-shadow: 0 10px 25px rgba(0,0,0,0.12); pointer-events: auto; } #kosice-sustainability-map .ksm-funding-overlay img { width: 100%; height: auto; max-height: 60px; object-fit: contain; display: block; } #kosice-sustainability-map .ksm-list-section { padding: 20px 16px; flex-grow: 1; } #kosice-sustainability-map .ksm-accordion-container { max-width: 1100px; margin: 0 auto; } #kosice-sustainability-map .ksm-category-heading { margin: 26px 0 14px; display: flex; align-items: center; gap: 10px; padding-bottom: 8px; border-bottom: 1px solid #d1d5db; font-size: 24px; font-weight: 700; color: #1f2937; } #kosice-sustainability-map .ksm-color-dot { width: 16px; height: 16px; border-radius: 4px; display: inline-block; flex: 0 0 auto; } #kosice-sustainability-map .ksm-accordion-item { background: #ffffff; border: 1px solid #e5e7eb; border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); margin-bottom: 10px; overflow: hidden; } #kosice-sustainability-map .ksm-accordion-header { display: flex; justify-content: space-between; align-items: center; cursor: pointer; padding: 16px; gap: 16px; } #kosice-sustainability-map .ksm-accordion-header:hover { background: #f9fafb; } #kosice-sustainability-map .ksm-place-title { margin: 0; font-size: 18px; font-weight: 600; color: #1f2937; } #kosice-sustainability-map .ksm-place-subtitle { margin: 6px 0 0 0; font-size: 14px; color: #6b7280; } #kosice-sustainability-map .ksm-chevron { width: 20px; height: 20px; color: #6b7280; transition: transform 0.2s ease; flex: 0 0 auto; } #kosice-sustainability-map .ksm-chevron.rotated { transform: rotate(180deg); } #kosice-sustainability-map .ksm-accordion-content { max-height: 0; overflow: hidden; transition: max-height 0.3s ease-out; } #kosice-sustainability-map .ksm-accordion-content-inner { border-top: 1px solid #e5e7eb; padding: 20px 16px; background: #ffffff; } #kosice-sustainability-map .ksm-content-grid { display: flex; flex-direction: row; gap: 24px; } #kosice-sustainability-map .ksm-content-main { flex: 1; min-width: 0; } #kosice-sustainability-map .ksm-content-side { width: 38%; min-width: 280px; } #kosice-sustainability-map .ksm-side-box { padding-left: 24px; border-left: 1px solid #e5e7eb; } #kosice-sustainability-map .ksm-info-block { margin-bottom: 18px; } #kosice-sustainability-map .ksm-info-label { margin-bottom: 6px; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: #6b7280; } #kosice-sustainability-map .ksm-info-value { font-size: 14px; line-height: 1.7; color: #374151; } #kosice-sustainability-map .ksm-info-value a { color: #2563eb; text-decoration: none; word-break: break-word; } #kosice-sustainability-map .ksm-info-value a:hover { text-decoration: underline; } #kosice-sustainability-map .leaflet-popup-content-wrapper { border-radius: 12px; } #kosice-sustainability-map .leaflet-popup-content { margin: 16px 16px 14px; } #kosice-sustainability-map .ksm-empty { text-align: center; padding: 30px 0; color: #6b7280; } @media (max-width: 767px) { #kosice-sustainability-map .ksm-title { font-size: 24px; } #kosice-sustainability-map .ksm-subtitle { font-size: 15px; } #kosice-sustainability-map .ksm-map-wrapper, #kosice-sustainability-map .ksm-map { min-height: 520px; } #kosice-sustainability-map .ksm-content-grid { flex-direction: column; } #kosice-sustainability-map .ksm-content-side { width: 100%; min-width: 0; } #kosice-sustainability-map .ksm-side-box { padding-left: 0; border-left: none; border-top: 1px solid #e5e7eb; padding-top: 18px; } #kosice-sustainability-map .ksm-funding-overlay { max-width: 180px; } }

Green Explorers

Interactive Map of Sustainable Development in Košice

Click on a marker on the map or expand an item in the list to view details about the location.

Filter Categories

Spolufinancované Európskou úniou
Spolufinancované Európskou úniou

(function () { const root = document.getElementById("kosice-sustainability-map"); if (!root) return; const rawPlacesData = [ { "Category": "Zero waste and eco shops", "Name": "Na Kôpke", "Description": "Na Kôpke is one of the pioneering zero-waste shops in Košice. Customers bring their own containers and buy groceries, toiletries, and household goods by weight, actively reducing single-use plastics in their daily lives. It is an ideal place to discuss packaging-free consumption and the principles of the circular economy in a very practical, everyday context.", "Address": "Park Angelinum 13, 040 01 Košice", "Contact": "+421 950 377 787\nnakopke@gmail.com", "OpeningHours": "Mon–Fri: 10:00–13:00, 14:00–18:00\nSat: 10:00–13:00\nSun: closed", "Website": "nakopke.sk", "Lat": 48.7298683, "Lng": 21.2494567 }, { "Category": "Zero waste and eco shops", "Name": "Košická špajza", "Description": "Košická špajza is a packaging-free shop in the city center, where customers bring their own jars and containers for bulk foods, oils, or cleaning products sold by weight. The shop demonstrates that an alternative way of shopping without unnecessary packaging is fully possible even in a normal urban environment, making it an excellent example for the topic of waste reduction.", "Address": "Poštová 14, 040 01 Košice", "Contact": "—", "OpeningHours": "Mon–Fri: 12:00–16:00\nSat–Sun: closed", "Website": "kosickaspajza.sk", "Lat": 48.7222117, "Lng": 21.2531173 }, { "Category": "Zero waste and eco shops", "Name": "Verdevana", "Description": "Verdevana is an eco-shop focused on natural products with minimal packaging, from cosmetics to household cleaning products. It helps participants of the urban quest understand how daily purchasing decisions affect the amount of waste and carbon footprint, while also showing that sustainable alternatives are easily accessible even on the main street.", "Address": "Ludmanská 5, 040 01 Košice", "Contact": "+421 915 370 681\nludka@verdevana.sk", "OpeningHours": "Mon, Tue, Thu: 13:00–17:00\nWed: 11:00–18:00\nFri–Sun: closed", "Website": "verdevana.sk", "Lat": 48.7137793, "Lng": 21.2640169 }, { "Category": "Zero waste and eco shops", "Name": "Rezke", "Description": "Rezke is a unique clothing swap boutique where items are not bought or sold, but exchanged. Customers bring a piece of clothing they no longer wear and take another, thus closing the loop in the fashion industry. For the urban quest, it is an excellent example of the sharing economy and extending product life cycles as an alternative to fast fashion.", "Address": "Mäsiarska 26, 040 01 Košice\n(also at Stanica Košice)", "Contact": "—", "OpeningHours": "Current schedule can be found on the website", "Website": "rezke.sk", "Lat": 48.7219339, "Lng": 21.2542848 }, { "Category": "Zero waste and eco shops", "Name": "Bylinkáreň & Čajovňa – Bioinštitút plus", "Description": "This herbal shop and tea room offers medicinal herbs, natural products, and advice on plant-based health care. It connects traditional knowledge about nature with a modern approach to sustainable self-care and motivates visitors to look beyond chemically-laden alternatives and rediscover locally grown plants.", "Address": "Hrnčiarska 20, 040 01 Košice", "Contact": "+421 918 475 640\n+421 55 625 52 07\nbylinkar@bylinkar.sk", "OpeningHours": "Mon–Fri: 09:00–17:00\nSat–Sun: closed", "Website": "bylinkar.sk", "Lat": 48.724249, "Lng": 21.2589403 }, { "Category": "Local and organic food", "Name": "Náš Dvor – Potraviny nie otraviny", "Description": "Náš Dvor sells honest Slovak food from small farmers and producers, without unnecessary additives and with an emphasis on short supply chains. The shop shows how local shopping reduces transport emissions and supports rural communities. For the urban quest, it is a model example of responsible consumption in its most practical everyday form.", "Address": "Hlavná 16, 040 01 Košice", "Contact": "+421 918 036 699\nkosice@potravinynieotraviny.sk", "OpeningHours": "Tue–Fri: 11:00–19:00\nSat: 08:00–14:00\nSun–Mon: closed", "Website": "potravinynieotraviny.sk", "Lat": 48.7188037, "Lng": 21.2579289 }, { "Category": "Local and organic food", "Name": "Trhovisko Dominikánske námestie", "Description": "This open market in Dominikánske námestie has existed in some form since the 1830s. Vendors offer fresh fruit, vegetables, honey, and flowers, often grown by their own hands. The 'Golden Seller' designation helps visitors identify verified local producers. The market is an excellent example of short food chains, seasonality, and the value of direct contact between producer and customer.", "Address": "Dominikánske námestie, 040 01 Košice", "Contact": "—", "OpeningHours": "Mon–Sat: mornings (approx. 06:00–12:00)\nSun: closed", "Website": "—", "Lat": 48.720647, "Lng": 21.255098 }, { "Category": "Parks and nature", "Name": "Mestský park Košice", "Description": "Košice City Park in the heart of Košice is one of the oldest urban green spaces in the region. It functions as the green lungs of the city, regulating temperature, absorbing CO₂, and supporting urban biodiversity. It is a natural starting point for a discussion on the role of green infrastructure in combating heat islands and adapting cities to climate change.", "Address": "Mestský park, 040 01 Košice", "Contact": "—", "OpeningHours": "Open continuously (exterior)", "Website": "—", "Lat": 48.7229604, "Lng": 21.2628203 }, { "Category": "Parks and nature", "Name": "Areál Anička", "Description": "Anička is an extensive recreational area of approximately 50 hectares by the Hornád river, full of greenery and supplemented with a mineral spring, mini-golf, mini zoo, workout park, and summer swimming pool. Information boards about local birds and waste sorting are placed throughout the area. The place is ideal for exploring the relationship between the city and nature and how urban green spaces fulfill both ecological and social functions.", "Address": "Pod šiancom 5, 040 01 Košice – Sever", "Contact": "+421 918 523 304", "OpeningHours": "Daily: 09:00–18:00\n(possible seasonal changes)", "Website": "arealanicka.sk", "Lat": 48.7449643, "Lng": 21.2545401 }, { "Category": "Community spaces and culture", "Name": "Tabačka Kulturfabrik", "Description": "Tabačka Kulturfabrik is an independent cultural center located in a renovated former tobacco factory. It organizes exhibitions, concerts, and community events with an emphasis on participation and social inclusion. For the urban quest, it demonstrates how adaptive reuse of existing buildings can reduce the ecological footprint of cultural institutions while revitalizing urban neighborhoods.", "Address": "Gorkého 2, 040 01 Košice", "Contact": "+421 905 545 986\ninfo@tabacka.sk", "OpeningHours": "Mon, Tue, Thu: 09:00–24:00\nWed, Fri: 09:00–01:00\nSat: 15:00–01:00\nSun: closed", "Website": "tabacka.sk", "Lat": 48.72903, "Lng": 21.2559594 }, { "Category": "Community spaces and culture", "Name": "Spoločenský pavilón – Komunitná záhrada", "Description": "The Community Garden at the Spoločenský pavilón is a participatory project where city residents collectively grow vegetables and herbs. The garden strengthens social ties, raises awareness of local food production, and brings a piece of biodiversity back into the urban landscape, thus tangibly connecting sustainability with community building.", "Address": "Medická 6, 040 11 Košice", "Contact": "—", "OpeningHours": "Accessible during daylight hours (exterior)", "Website": "—", "Lat": 48.7196527, "Lng": 21.2400015 }, { "Category": "Community spaces and culture", "Name": "Komunitná kaviareň KVP", "Description": "Komunitná kaviareň KVP in Drocárov Park was a city project that breathed new life into a neglected building in the KVP housing estate, transforming it into a neighborhood hub for coffee, events, and community gatherings. For the urban quest, it shows how the revitalization of public spaces through community investment is an important part of sustainable and pleasant neighborhoods.", "Address": "Drocárov Park 3110/1, 040 23 Košice – KVP", "Contact": "—", "OpeningHours": "Mon: 14:00–20:00\nTue–Fri: 10:00–20:00\nSat–Sun: 15:00–20:00", "Website": "mckvp.sk", "Lat": 48.70976, "Lng": 21.2152521 }, { "Category": "Community spaces and culture", "Name": "Kaviareň a vináreň Na Dlani", "Description": "Na Dlani is a pleasant neighborhood cafe and wine bar on Hlinkova Street that prioritizes Slovak wines and local ingredients. In the context of the urban quest, it serves as a quiet place to reflect on local gastronomy and the relationship between responsible beverage choices and supporting regional producers.", "Address": "Hlinkova 9, 040 01 Košice – Sever", "Contact": "—", "OpeningHours": "Check current opening hours directly at the establishment", "Website": "—", "Lat": 48.7395402, "Lng": 21.2522249 }, { "Category": "Green mobility", "Name": "Cyklokuchyňa Košice", "Description": "Cyklokuchyňa is a community bicycle repair workshop where cyclists can repair their bikes themselves with the help of shared tools and experienced volunteers. It promotes a culture of repair instead of replacement, reduces waste from discarded bicycles, and is a great example of the sharing economy in sustainable urban transport.", "Address": "Čárskeho 7, 040 01 Košice", "Contact": "—", "OpeningHours": "Mon–Fri: 10:00–12:00, 13:00–18:00", "Website": "cke.sk", "Lat": 48.7389989, "Lng": 21.2540164 }, { "Category": "Green mobility", "Name": "ANTIK SmartWay – shared e-scooters and bicycles", "Description": "ANTIK SmartWay is Košice's shared micromobility platform, offering bicycles, e-bikes, and e-scooters via a mobile application. The station-free system allows flexible movement around the city and can replace short car journeys. It specifically shows how technology can reduce transport emissions and how shared mobility services contribute to a cleaner urban environment.", "Address": "Throughout the city (flexible zones in Košice)", "Contact": "+421 650 777 888\nsmartway@antik.sk", "OpeningHours": "24/7 via mobile application", "Website": "antiksmartway.sk", "Lat": 48.7211, "Lng": 21.2579 }, { "Category": "Ecological architecture", "Name": "Bastion Office Center", "Description": "Bastion Office Center on Továrenská Street is only the second building in Košice with LEED Gold certification. It uses groundwater for toilet flushing, cleans incoming air with plasma ionization filters, measures CO₂ in each room for automatic ventilation control, and uses LED lighting set for user comfort. It is a living example of how green building standards can significantly reduce the operational energy consumption of a building.", "Address": "Továrenská 4, 040 01 Košice", "Contact": "—", "OpeningHours": "Exterior freely accessible; interior: only on weekdays", "Website": "bastion-kosice.sk", "Lat": 48.7266457, "Lng": 21.2553168 } ]; const placesData = rawPlacesData.map((place, index) => ({ id: index + 1, category: place.Category, name: place.Name, description: place.Description, address: place.Address, contact: place.Contact, openingHours: place.OpeningHours, website: place.Website, lat: place.Lat, lng: place.Lng })); const CATEGORY_STYLES = { "Zero waste a eko obchody": { color: "#16a34a", bgColor: "#16a34a", iconPath: "M18 4h-3V2h-2v2H9V2H7v2H4c-1.1 0-2 .9-2 2v13c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 15H4V10h14v9zm0-11H4V6h14v2zM9 13H7v4h2v-4zm4 0h-2v4h2v-4zm4 0h-2v4h2v-4z" }, "Lokálne a organické potraviny": { color: "#ea580c", bgColor: "#ea580c", iconPath: "M11 9H9V2H7v7H5V2H3v7c0 2.12 1.66 3.84 3.75 3.97V22h2.5v-9.03C11.34 12.84 13 11.12 13 9V2h-2v7zm5-3v8h2.5v8H21V2c-2.76 0-5 2.24-5 4z" }, "Parky a príroda": { color: "#059669", bgColor: "#059669", iconPath: "M12 2 6 10h4l-3 5h3v7h4v-7h3l-3-5h4z" }, "Komunitné priestory a kultúra": { color: "#7c3aed", bgColor: "#7c3aed", iconPath: "M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5s-3 1.34-3 3 1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5C15 14.17 10.33 13 8 13zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.98 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z" }, "Zelená mobilita": { color: "#2563eb", bgColor: "#2563eb", iconPath: "M5.5 17A2.5 2.5 0 1 0 5.5 22 2.5 2.5 0 1 0 5.5 17zM18.5 17A2.5 2.5 0 1 0 18.5 22 2.5 2.5 0 1 0 18.5 17zM15.82 8l-2.69 3.5H9.5l1.96-3H15.82zM19 6h-3.79c-.63 0-1.22.3-1.59.8L10.2 11.2C9.89 11.68 9.35 12 8.77 12H7V9H5v3c0 1.1.9 2 2 2h1.77c1.24 0 2.4-.62 3.09-1.65L12.45 12h2.93l1.52 3.27C16.33 15.73 16 16.34 16 17c0 1.38 1.12 2.5 2.5 2.5S21 18.38 21 17c0-1.12-.73-2.06-1.74-2.39L17 10h2V6z" }, "Ekologická architektúra": { color: "#475569", bgColor: "#475569", iconPath: "M4 22h16v-2H4v2zm2-4h3V8H6v10zm5 0h3V2h-3v16zm5 0h3v-7h-3v7z" } }; const categories = [...new Set(placesData.map(place => place.category))]; let activeCategories = [...categories]; let markerObjects = {}; let map; let markersLayer; const accordionContainer = root.querySelector("#ksm-accordion-container"); const filtersContainer = root.querySelector("#ksm-filters-list"); function loadLeafletAssets() { return new Promise((resolve, reject) => { if (window.L) { resolve(); return; } const leafletCssId = "ksm-leaflet-css"; const leafletJsId = "ksm-leaflet-js"; if (!document.getElementById(leafletCssId)) { const link = document.createElement("link"); link.id = leafletCssId; link.rel = "stylesheet"; link.href = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"; document.head.appendChild(link); } const existingScript = document.getElementById(leafletJsId); if (existingScript) { existingScript.addEventListener("load", () => resolve()); existingScript.addEventListener("error", () => reject(new Error("Failed to load Leaflet JS."))); return; } const script = document.createElement("script"); script.id = leafletJsId; script.src = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"; script.onload = () => resolve(); script.onerror = () => reject(new Error("Failed to load Leaflet JS.")); document.body.appendChild(script); }); } function getCategoryStyle(category) { return CATEGORY_STYLES[category] || { color: "#16a34a", bgColor: "#16a34a", iconPath: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z" }; } function escapeHtml(value) { return String(value) .replaceAll("&", "&amp;") .replaceAll("<", "&lt;") .replaceAll(">", "&gt;") .replaceAll("\"", "&quot;") .replaceAll("'", "&#39;"); } function formatMultilineText(value) { return escapeHtml(value).replace(/\n/g, "<br>"); } function formatContact(contact) { if (!contact || contact.trim() === "" || contact.trim() === "—") { return "Contact details are not available"; } return contact.split("\n").map(line => { const trimmed = line.trim(); if (trimmed.includes("@") && !trimmed.includes(" ")) { return `<a href="mailto:${escapeHtml(trimmed)}">${escapeHtml(trimmed)}</a>`; } return escapeHtml(trimmed); }).join("<br>"); } function formatWebsite(website) { if (!website || website.trim() === "" || website.trim() === "—") { return "Website is not available"; } const normalized = website.startsWith("http") ? website : `https://${website}`; return `<a href="${normalized}" target="_blank" rel="noopener noreferrer">${escapeHtml(website)}</a>`; } function createSvgIcon(color, iconPath) { return L.divIcon({ className: "ksm-custom-pin", html: ` <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="48" height="48" style="filter: drop-shadow(2px 4px 6px rgba(0,0,0,0.3));"> <path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z" fill="${color}" /> <circle cx="12" cy="9" r="3.5" fill="rgba(255,255,255,0.18)"></circle> <path d="${iconPath}" fill="white" transform="translate(7, 4) scale(0.42)"></path> </svg> `, iconSize: [40, 40], iconAnchor: [20, 40], popupAnchor: [4, -35] }); } function getFilterButtonClass(isActive) { return `ksm-filter-btn ${isActive ? "active" : "inactive"}`; } function renderFilters() { filtersContainer.innerHTML = ""; categories.forEach(category => { const button = document.createElement("button"); const style = getCategoryStyle(category); const isActive = activeCategories.includes(category); button.textContent = category; button.className = getFilterButtonClass(isActive); if (isActive) { button.style.background = style.bgColor; button.style.color = "#ffffff"; } button.addEventListener("click", () => { const active = activeCategories.includes(category); activeCategories = active ? activeCategories.filter(item => item !== category) : [...activeCategories, category]; renderFilters(); renderMarkersAndList(); }); filtersContainer.appendChild(button); }); } function renderMarkersAndList() { markersLayer.clearLayers(); markerObjects = {}; accordionContainer.innerHTML = ""; const visibleMarkers = []; categories.forEach(category => { if (!activeCategories.includes(category)) return; const categoryPlaces = placesData.filter(place => place.category === category); if (!categoryPlaces.length) return; const categoryStyle = getCategoryStyle(category); const sectionHeader = document.createElement("h3"); sectionHeader.className = "ksm-category-heading"; sectionHeader.innerHTML = ` <span class="ksm-color-dot" style="background:${categoryStyle.bgColor}"></span> ${escapeHtml(category)} `; accordionContainer.appendChild(sectionHeader); categoryPlaces.forEach(place => { const style = getCategoryStyle(place.category); const icon = createSvgIcon(style.color, style.iconPath); const addressHtml = formatMultilineText(place.address); const hoursHtml = formatMultilineText(place.openingHours || "Opening hours are not available"); const contactHtml = formatContact(place.contact); const websiteHtml = formatWebsite(place.website); const popupContent = ` <div style="font-family:Arial,sans-serif;min-width:240px;max-width:280px;"> <h3 style="margin:0 0 8px;font-size:18px;line-height:1.3;font-weight:700;color:#111827;">${escapeHtml(place.name)}</h3> <span style="display:inline-block;margin-bottom:12px;border-radius:6px;padding:4px 8px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:0.08em;color:#fff;background:${style.bgColor};"> ${escapeHtml(place.category)} </span> <p style="margin:0 0 12px;font-size:14px;line-height:1.5;color:#374151;">${escapeHtml(place.description)}</p> <div style="margin-top:8px;padding-top:8px;border-top:1px solid #f3f4f6;font-size:12px;color:#4b5563;"> <div style="margin-bottom:8px;"><strong style="color:#1f2937;">Address:</strong><br>${addressHtml}</div> <div style="margin-bottom:8px;"><strong style="color:#1f2937;">Opening hours:</strong><br>${hoursHtml}</div> <div style="margin-bottom:8px;"><strong style="color:#1f2937;">Contact:</strong><br>${contactHtml}</div> <div><strong style="color:#1f2937;">Web:</strong><br>${websiteHtml}</div> </div> </div> `; const marker = L.marker([place.lat, place.lng], { icon }) .addTo(markersLayer) .bindPopup(popupContent); markerObjects[place.id] = marker; visibleMarkers.push(marker); const accordionItem = document.createElement("div"); accordionItem.className = "ksm-accordion-item"; accordionItem.innerHTML = ` <div class="ksm-accordion-header" data-id="${place.id}"> <div> <h4 class="ksm-place-title">${escapeHtml(place.name)}</h4> <p class="ksm-place-subtitle">${escapeHtml(place.address.split("\n")[0])}</p> </div> <svg class="ksm-chevron" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path> </svg> </div> <div class="ksm-accordion-content"> <div class="ksm-accordion-content-inner"> <div class="ksm-content-grid"> <div class="ksm-content-main"> <span class="ksm-badge" style="background:${style.bgColor};">${escapeHtml(place.category)}</span> <p class="ksm-description">${escapeHtml(place.description)}</p> </div> <div class="ksm-content-side"> <div class="ksm-side-box"> <div class="ksm-info-block"> <div class="ksm-info-label">Address</div> <div class="ksm-info-value">${addressHtml}</div> </div> <div class="ksm-info-block"> <div class="ksm-info-label">Opening hours</div> <div class="ksm-info-value">${hoursHtml}</div> </div> <div class="ksm-info-block"> <div class="ksm-info-label">Contact</div> <div class="ksm-info-value">${contactHtml}</div> <div class="ksm-info-block" style="margin-bottom:0;"> <div class="ksm-info-label">Website</div> <div class="ksm-info-value">${websiteHtml}</div> </div> </div> </div> </div> </div> </div> `; accordionContainer.appendChild(accordionItem); }); }); if (!visibleMarkers.length) { accordionContainer.innerHTML = '<p class="ksm-empty">No places match the selected criteria.</p>'; map.setView([48.7209, 21.2578], 13); return; } const bounds = L.featureGroup(visibleMarkers).getBounds(); if (bounds.isValid()) { map.fitBounds(bounds.pad(0.18)); } } function bindAccordionEvents() { accordionContainer.addEventListener("click", function (event) { const header = event.target.closest(".ksm-accordion-header"); if (!header) return; const currentItem = header.parentElement; const content = currentItem.querySelector(".ksm-accordion-content"); const icon = header.querySelector(".ksm-chevron"); const placeId = header.dataset.id; const isOpen = Boolean(content.style.maxHeight); accordionContainer.querySelectorAll(".ksm-accordion-content").forEach(item => { item.style.maxHeight = null; }); accordionContainer.querySelectorAll(".ksm-chevron").forEach(item => { item.classList.remove("rotated"); }); if (!isOpen) { content.style.maxHeight = content.scrollHeight + "px"; icon.classList.add("rotated"); const marker = markerObjects[placeId]; if (marker) { map.flyTo(marker.getLatLng(), 15, { duration: 0.8 }); marker.openPopup(); } } }); } async function initMap() { try { await loadLeafletAssets(); map = L.map("ksm-map-canvas", { scrollWheelZoom: true }).setView([48.7209, 21.2578], 13); L.tileLayer("https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png", { subdomains: "abcd", maxZoom: 19, attribution: '&copy; OpenStreetMap contributors &copy; CARTO' }).addTo(map); markersLayer = L.layerGroup().addTo(map); renderFilters(); renderMarkersAndList(); bindAccordionEvents(); setTimeout(() => { map.invalidateSize(); }, 300); window.addEventListener("resize", function () { map.invalidateSize(); }); } catch (error) { root.innerHTML = '<div style="padding:20px;background:#fff3f3;border:1px solid #f5c2c2;border-radius:12px;color:#991b1b;">Failed to load the map. Check if WordPress or a security plugin is blocking external scripts.</div>'; } } initMap(); })();

2024-2-PL01-KA210-ADU-000279352