1<!DOCTYPE html> 2 3<html lang="de-CH" data-website-id="1" data-main-object="website.page(54,)" data-add2cart-redirect="1"> 4 <head> 5 <meta charset="utf-8"/> 6 <meta http-equiv="X-UA-Compatible" content="IE=edge"/> 7 <meta name="viewport" content="width=device-width, initial-scale=1"/> 8 <meta name="generator" content="Odoo"/> 9 10 <meta property="og:type" content="website"/> 11 <meta property="og:title" content="LARS_Seite_Stores | LARS Brillen"/> 12 <meta property="og:site_name" content="LARS Brillen"/> 13 <meta property="og:url" content="https://larsbrillen.ch/stores"/> 14 <meta property="og:image" content="https://larsbrillen.ch/web/image/website/1/logo?unique=c9e8819"/> 15 16 <meta name="twitter:card" content="summary_large_image"/> 17 <meta name="twitter:title" content="LARS_Seite_Stores | LARS Brillen"/> 18 <meta name="twitter:image" content="https://larsbrillen.ch/web/image/website/1/logo/300x300?unique=c9e8819"/> 19 20 <link rel="canonical" href="https://larsbrillen.ch/stores"/> 21 22 <link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin=""/> 23 <title>LARS_Seite_Stores | LARS Brillen</title> 24 <link type="image/x-icon" rel="shortcut icon" href="/web/image/website/1/favicon?unique=c9e8819"/> 25 <link rel="preload" href="/web/static/src/libs/fontawesome/fonts/fontawesome-webfont.woff2?v=4.7.0" as="font" crossorigin=""/> 26 <link type="text/css" rel="stylesheet" href="/web/assets/1/aaca33b/web.assets_frontend.min.css"/> 27
27<script id="web.layout.odooscript" type="text/javascript"> 28 var odoo = { 29 csrf_token: "9bede61db4bc15fef63f2e8ec6fc4b91e18301ddo1823041764", 30 debug: "", 31 }; 32 </script>
32 33
33<script type="text/javascript"> 34 odoo.__session_info__ = {"is_admin": false, "is_system": false, "is_public": true, "is_website_user": true, "user_id": false, "is_frontend": true, "profile_session": null, "profile_collectors": null, "profile_params": null, "show_effect": true, "currencies": {"4": {"symbol": "CHF", "position": "before", "digits": [69, 2]}, "125": {"symbol": "\u20ac", "position": "after", "digits": [69, 2]}, "1": {"symbol": "$", "position": "before", "digits": [69, 2]}}, "bundle_params": {"lang": "de_CH", "website_id": 1}, "websocket_worker_version": "17.0-3", "translationURL": "/website/translations", "cache_hashes": {"translations": "b4c0cac81eb97632e6ddc82b2f6c11d9361a2d82"}, "geoip_country_code": "US", "geoip_phone_code": 1, "lang_url_code": "de_CH"}; 35 if (!/(^|;\s)tz=/.test(document.cookie)) { 36 const userTZ = Intl.DateTimeFormat().resolvedOptions().timeZone; 37 document.cookie = `tz=${userTZ}; path=/`; 38 } 39 </script>
39 40
40<script type="text/javascript" defer="defer" src="/web/assets/1/20f9201/web.assets_frontend_minimal.min.js" onerror="__odooAssetError=1"></script>
40 41
41<script type="text/javascript" defer="defer" data-src="/web/assets/1/836fa32/web.assets_frontend_lazy.min.js" onerror="__odooAssetError=1"></script>
41 42 43 <style> 44 .s_carousel_wrapper .carousel-control-prev-icon, 45 .s_carousel_wrapper .carousel-control-next-icon { 46 width: 20px !important; 47 height: 20px !important; 48 background-repeat: no-repeat !important; 49 background-position: center !important; 50 background-size: contain !important; 51 } 52 53 .s_carousel_wrapper .carousel-control-prev-icon { 54 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='15 18 9 12 15 6'/%3E%3C/svg%3E") !important; 55 } 56 57 .s_carousel_wrapper .carousel-control-next-icon { 58 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='9 18 15 12 9 6'/%3E%3C/svg%3E") !important; 59 } 60 61 .s_carousel_wrapper .carousel-control-prev, 62 .s_carousel_wrapper .carousel-control-next { 63 opacity: 1 !important; 64 } 65 66 .s_carousel_wrapper .carousel-indicators { 67 bottom: 24px; 68 } 69 70 .s_carousel_wrapper .carousel-indicators li { 71 width: 8px !important; 72 height: 8px !important; 73 border-radius: 50% !important; 74 background-color: rgba(255, 255, 255, 0.5) !important; 75 border: none !important; 76 margin: 0 5px !important; 77 opacity: 1 !important; 78 text-indent: -9999px; 79 } 80 81 .s_carousel_wrapper .carousel-indicators li.active { 82 background-color: #ffffff !important; 83 } 84 </style> 85 <style> 86 /* Preis auf Produktseite */ 87 span.oe_price, 88 .product_price { 89 display: none !important; 90 } 91 92 /* Warenkorb Button und Menge */ 93 .o_wsale_product_btn, 94 #add_to_cart_wrap, 95 .o_wsale_product_quantity, 96 .css_quantity, 97 input[name="add_qty"] { 98 display: none !important; 99 } 100 101 /* Optiker finden Button */ 102 .lars_optiker_btn, 103 .lars_public_cta { 104 display: block !important; 105 } 106 </style> 107 <style> 108 .s_faq_collapse, 109 .s_faq_collapse.s_faq_collapse_light { 110 background: #fff !important; 111 } 112 .s_faq_collapse .accordion { 113 border: none !important; 114 border-radius: 0 !important; 115 background: #fff !important; 116 box-shadow: none !important; 117 overflow: visible !important; 118 } 119 .s_faq_collapse .card { 120 border: 0 !important; 121 border-radius: 0 !important; 122 background: transparent !important; 123 margin: 0 !important; 124 } 125 .s_faq_collapse a.card-header, 126 .s_faq_collapse a.card-header:hover, 127 .s_faq_collapse a.card-header:focus, 128 .s_faq_collapse a.card-header:active, 129 .s_faq_collapse a.card-header:visited { 130 background: transparent !important; 131 border: none !important; 132 border-bottom: 1px solid rgba(0,0,0,0.10) !important; 133 padding: 18px 0 !important; 134 font-weight: 700 !important; 135 font-size: 16px !important; 136 letter-spacing: 0 !important; 137 text-decoration: none !important; 138 text-transform: uppercase !important; 139 display: flex !important; 140 align-items: center !important; 141 justify-content: space-between !important; 142 color: #111 !important; 143 border-radius: 0 !important; 144 box-shadow: none !important; 145 } 146 .s_faq_collapse a.card-header span { 147 font-size: 16px !important; 148 font-weight: 700 !important; 149 text-transform: uppercase !important; 150 text-decoration: none !important; 151 color: #111 !important; 152 } 153 .s_faq_collapse .card-header.s_faq_collapse_right_icon::before, 154 .s_faq_collapse .card-header::before, 155 .s_faq_collapse .card-header.collapsed::before { 156 content: '' !important; 157 display: inline-block !important; 158 width: 16px !important; 159 height: 16px !important; 160 position: static !important; 161 order: 2 !important; 162 margin-left: 12px !important; 163 margin-right: 0 !important; 164 background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpolyline points='9 6 15 12 9 18' fill='none' stroke='%23111111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") !important; 165 background-repeat: no-repeat !important; 166 background-position: center !important; 167 background-size: contain !important; 168 background-color: transparent !important; 169 border: none !important; 170 border-radius: 0 !important; 171 transition: transform 0.25s ease !important; 172 flex-shrink: 0 !important; 173 transform: none !important; 174 color: transparent !important; 175 font-size: 0 !important; 176 } 177 .s_faq_collapse .card-header:not(.collapsed)::before, 178 .s_faq_collapse .card-header[aria-expanded="true"]::before { 179 transform: rotate(90deg) !important; 180 } 181 .s_faq_collapse .card-header::after { 182 content: none !important; 183 display: none !important; 184 background-image: none !important; 185 } 186 .s_faq_collapse .card-body { 187 padding: 18px 0 22px 0 !important; 188 background: transparent !important; 189 } 190 .s_faq_collapse .card-body p, 191 .s_faq_collapse .card-body .card-text, 192 .s_faq_collapse .card-body .lead { 193 font-weight: 400 !important; 194 font-size: 16px !important; 195 line-height: 1.5 !important; 196 color: #111 !important; 197 margin-bottom: 12px !important; 198 text-transform: none !important; 199 } 200 .s_faq_collapse .card-body p:last-child, 201 .s_faq_collapse .card-body .card-text:last-child { 202 margin-bottom: 0 !important; 203 } 204 </style> 205 <style> 206 /* Search Input */ 207 .oe_search_box, 208 input.search-query { 209 color: #111 !important; 210 background-color: #fff !important; 211 border: 1px solid rgba(0,0,0,0.20) !important; 212 border-radius: 0 !important; 213 } 214 .oe_search_box::placeholder, 215 input.search-query::placeholder { 216 color: rgba(0,0,0,0.5) !important; 217 } 218 .oe_search_box:focus, 219 input.search-query:focus { 220 color: #111 !important; 221 background-color: #fff !important; 222 border-color: #111 !important; 223 outline: none !important; 224 box-shadow: none !important; 225 } 226 227 /* Dropdown Container */ 228 .o_dropdown_menu { 229 background: #fff !important; 230 border: 1px solid rgba(0,0,0,0.20) !important; 231 border-radius: 0 !important; 232 box-shadow: 0 4px 12px rgba(0,0,0,0.08) !important; 233 } 234 235 /* Dropdown Items */ 236 .o_dropdown_menu .dropdown-item, 237 .o_dropdown_menu .o_search_result_item, 238 .o_dropdown_menu .o_search_result_item_detail, 239 .o_dropdown_menu .h6, 240 .o_dropdown_menu p, 241 .o_dropdown_menu .fa { 242 color: #111 !important; 243 } 244 .o_dropdown_menu .dropdown-item { 245 background-color: #fff !important; 246 } 247 .o_dropdown_menu .dropdown-item:hover, 248 .o_dropdown_menu .dropdown-item:focus, 249 .o_dropdown_menu .dropdown-item:active { 250 background-color: #f5f5f5 !important; 251 color: #111 !important; 252 } 253 .o_dropdown_menu .dropdown-item:hover .h6, 254 .o_dropdown_menu .dropdown-item:hover p, 255 .o_dropdown_menu .dropdown-item:focus .h6, 256 .o_dropdown_menu .dropdown-item:focus p { 257 color: #111 !important; 258 } 259 260 /* Search Highlight Match */ 261 .o_dropdown_menu mark, 262 .o_dropdown_menu .dropdown-item mark, 263 .o_dropdown_menu strong, 264 .o_dropdown_menu b { 265 background-color: #ffec99 !important; 266 color: #111 !important; 267 padding: 0 1px !important; 268 font-weight: 700 !important; 269 } 270 271 /* "Alle Ergebnisse" Button */ 272 .o_dropdown_menu .text-primary, 273 .o_dropdown_menu button.text-primary { 274 color: #111 !important; 275 background-color: #fff !important; 276 border-top: 1px solid rgba(0,0,0,0.10) !important; 277 font-weight: 700 !important; 278 text-transform: uppercase !important; 279 } 280 .o_dropdown_menu .text-primary:hover, 281 .o_dropdown_menu button.text-primary:hover { 282 background-color: #111 !important; 283 color: #fff !important; 284 } 285 </style> 286 <style> 287/* Nur Abstand NACH OBEN vergröÃern â für alle Header-Zustände */ 288#wrapwrap > header[class*="o_header"] .o_header_main, 289#wrapwrap > header[class*="o_header"] .navbar { 290 padding-top: 32px !important; /* Wert anpassbar: 28â40 */ 291 padding-bottom: 0 !important; /* damit unten unverändert bleibt */ 292} 293 294/* Sticky-Header (beim Scrollen) auch oben gepolstert halten */ 295.o_header_affixed .o_header_main, 296.o_header_is_scrolled .o_header_main, 297.o_header_affixed .navbar, 298.o_header_is_scrolled .navbar { 299 padding-top: 22px !important; 300 padding-bottom: 0 !important; 301} 302
303/* Logo etwas kleiner halten */ 304#wrapwrap > header[class*="o_header"] .navbar-brand img { 305 max-height: 44px !important; /* ggf. 40â48 anpassen */ 306 height: auto; 307} 308</style> 309
310<script src="https://app.privacybee.io/cookie-banner.js" website-id="clj8mpgld202820ymq7ryugmv"></script>
vendor: 1 bytes, line 310
310
311<script> 312 document.addEventListener('DOMContentLoaded', function () { 313 let titleDone = false; 314 let descDone = false; 315 316 function applyPrivacyBeeTexts() { 317 const title = document.getElementById('privacybee-banner-title'); 318 const desc = document.getElementById('privacybee-banner-description'); 319 320 if (title && !titleDone) { 321 title.textContent = "Deine Privatsphäre ist uns wichtig"; 322 titleDone = true; 323 } 324 325 if (desc && !descDone) { 326 desc.innerHTML = "Wir nutzen auf unserer Webseite Cookies, um deinen Besuch für dich zu optimieren, natürlich nur mit deiner Zustimmung. Mehr dazu findest du in unserer <a href=\"https://larsbrillen.ch/datenschutzerklarung\">Datenschutzerklärung</a>."; 327 descDone = true; 328 } 329 330 return titleDone && descDone; 331 } 332 333 const observer = new MutationObserver(() => { 334 if (applyPrivacyBeeTexts()) { 335 observer.disconnect(); 336 } 337 }); 338 339 observer.observe(document.body, { childList: true, subtree: true }); 340 341 let attempts = 0; 342 const interval = setInterval(() => { 343 attempts++; 344 if (applyPrivacyBeeTexts() || attempts > 20) { 345 clearInterval(interval); 346 observer.disconnect(); 347 } 348 }, 300); 349 }); 350</script>
350 351 352<style> 353 /* Alles auf Inter */ 354 .pbcb_header_text, 355 .pbcb_content_text, 356 .pbcb_category_label, 357 .pbcb_buttons_text { 358 font-family: Inter, sans-serif !important; 359 } 360 361 /* Rahmen um die Toggles entfernen */ 362 .pbcb_categories_fieldset { 363 border: none !important; 364 padding: 0 !important; 365 } 366 367 /* Header: Logo oben, Titel darunter, alles linksbündig */ 368 .pbcb_header { 369 display: flex !important; 370 flex-direction: column !important; 371 align-items: flex-start !important; 372 gap: 8px !important; 373 padding: 20px 24px 10px 24px !important; 374 } 375 376 .pbcb_mascot { 377 order: -1 !important; 378 width: 90px !important; 379 height: auto !important; 380 margin: 0 !important; 381 align-self: flex-start !important; 382 } 383 384 .pbcb_mascot_img { 385 max-width: 100% !important; 386 height: auto !important; 387 } 388 389 .pbcb_title_container { 390 padding-left: 0 !important; 391 margin: 0 !important; 392 } 393 394 .pbcb_header_text { 395 margin: 0 !important; 396 } 397</style> 398 <style> 399#o_wsale_offcanvas_attribute_14_header, 400#o_wsale_offcanvas #o_wsale_offcanvas_attribute_14.accordion-collapse { 401 display: none !important; 402} 403 </style> 404 <style> 405 406 /* Kollektions-Bilder im Masonry-Grid: immer ganz sichtbar, Höhe folgt dem Bild */ 407#LINEARS-COLLECTION .o_grid_item_image { 408 height: auto !important; 409 align-self: start !important; 410} 411#LINEARS-COLLECTION .o_grid_item_image img.o_we_custom_image { 412 width: 100% !important; 413 height: auto !important; 414 object-fit: contain !important; 415 max-height: none !important; 416} 417.lars-essential-badge{ 418 position:absolute !important; 419 top:-10px !important; 420 right:-10px !important; 421 width:25px !important; 422 height:25px !important; 423 display:flex !important; 424 align-items:center !important; 425 justify-content:center !important; 426 border-radius:999px !important; 427 background:#000 !important; 428 color:#fff !important; 429 padding:0 !important; 430 margin:0 !important; 431 line-height:1 !important; 432 font-size:16px !important; 433 font-weight:400 !important; 434 z-index:10 !important; 435 pointer-events:none !important; 436} 437 438.o_navbar_mobile a.btn-outline-secondary { 439 color: #212529 !important; 440} 441 442/* Beratungsmodus Button auf allen Breakpoints sichtbar */ 443#lars_beratung_toggle_wrap { 444 display: flex !important; 445 align-items: center; 446 margin-left: 16px; 447} 448 449@media (max-width: 991px) { 450 .o_wsale_products_searchbar_form { 451 display: block !important; 452 } 453} 454 455/* Swatches eckig */ 456.js_add_cart_variants .css_attribute_color{ 457 border-radius:0 ; 458} 459.js_add_cart_variants label.css_attribute_color{ 460 width:60px !important; 461 height:45px !important; 462 min-width:60px !important; 463 padding:0 !important; 464 box-sizing:border-box !important; 465} 466.js_add_cart_variants label.css_attribute_color::before, 467.js_add_cart_variants label.css_attribute_color span{ 468 border-radius:0 ; 469} 470 471/* Ausgewählte Karte: nur Rand, kein Hintergrund */ 472.card.bg-primary.border-primary { 473 background-color: transparent !important; 474 border: 2px solid var(--color-primary) !important; 475 box-shadow: 0 0 0 2px var(--color-primary); 476} 477 478/* Rahmenlogik sauber */ 479.js_add_cart_variants label.css_attribute_color{ 480 border:none !important; 481 box-shadow:none !important; 482 outline:none !important; 483} 484.js_add_cart_variants label.css_attribute_color.active{ 485 outline:5px solid #000000 !important; 486 outline-offset:0px !important; 487} 488 489/* Abstand nur in Swatch-Liste */ 490.js_add_cart_variants ul.list-inline > li{ 491 margin-right:10px !important; 492 margin-bottom:10px !important; 493} 494.js_add_cart_variants ul.list-inline > li:last-child{ 495 margin-right:0 !important; 496} 497 498/* Tooltip muss ein hoverbares Element haben */ 499.js_add_cart_variants .o_wsale_product_attribute li{ 500 pointer-events: auto !important; 501} 502.js_add_cart_variants label.css_attribute_color{ 503 pointer-events: auto !important; 504} 505 506/* === Nicht verfügbare Varianten ausgrauen statt ausblenden === */ 507.js_add_cart_variants label.css_not_available, 508.js_add_cart_variants label.o_wsale_not_available { 509 opacity: 0.3 !important; 510 cursor: not-allowed !important; 511 display: flex !important; 512} 513.js_add_cart_variants label:has(input:disabled) { 514 opacity: 0.3 !important;
515 cursor: not-allowed !important; 516} 517/* Verbotssymbol (crossed circle) auf nicht verfügbaren Swatches entfernen */ 518.js_add_cart_variants label.css_not_available::after, 519.js_add_cart_variants label.o_wsale_not_available::after, 520.js_add_cart_variants label:has(input:disabled)::after, 521.js_add_cart_variants label.css_not_available svg, 522.js_add_cart_variants label.o_wsale_not_available svg, 523.js_add_cart_variants label:has(input:disabled) svg { 524 display: none !important; 525 content: none !important; 526} 527 528/* ========================= 529 RADIO (Grössen) 530 ========================= */ 531.js_add_cart_variants .o_wsale_product_attribute li.js_attribute_value, 532.js_add_cart_variants .o_wsale_product_attribute li.js_attribute_value > label.col-form-label, 533.js_add_cart_variants .o_wsale_product_attribute li.js_attribute_value .form-check{ 534 background:transparent !important; 535 border:none !important; 536 box-shadow:none !important; 537 padding:0 !important; 538 margin:0 !important; 539} 540.js_add_cart_variants .o_wsale_product_attribute li.js_attribute_value input.form-check-input{ 541 display:none !important; 542} 543.js_add_cart_variants .o_wsale_product_attribute li.js_attribute_value .radio_input_value{ 544 width:60px !important; 545 height:45px !important; 546 min-width:60px !important; 547 display:flex !important; 548 align-items:center !important; 549 justify-content:center !important; 550 background:#fff !important; 551 color:#111 !important; 552 border:1px solid #000 !important; 553 outline:none !important; 554 border-radius:0 !important; 555 box-shadow:none !important; 556 box-sizing:border-box !important; 557} 558 559.js_add_cart_variants .o_wsale_product_attribute li.js_attribute_value:not(:first-child:last-child) input:checked + .radio_input_value{ 560 border:1px solid #000 !important; 561} 562 563.js_add_cart_variants .o_wsale_product_attribute li.list-inline-item.js_attribute_value{ 564 margin:0 6.5px 10px 0 !important; 565 padding:0 !important; 566 vertical-align:top !important; 567} 568.js_add_cart_variants .o_wsale_product_attribute li.list-inline-item.js_attribute_value:last-child{ 569 margin-right:0 !important; 570} 571 572/* ========================= 573 PILLS (Grössen) 574 ========================= */ 575/* Standard: fix 60x45 */ 576.js_add_cart_variants .o_variant_pills { 577 background: #fff !important; 578 border: 1px solid #000 !important; 579 border-radius: 0 !important; 580 padding: 0 !important; 581 box-shadow: none !important; 582 margin: 0 10px 10px 0 !important; 583 outline: 2px solid transparent !important; 584 outline-offset: 4px !important; 585} 586.js_add_cart_variants .o_variant_pills.active { 587 outline: 2px solid #000 !important; 588 outline-offset: 4px !important; 589} 590.js_add_cart_variants .o_variant_pills_input_value { 591 width: 60px !important; 592 height: 45px !important; 593 display: flex !important; 594 align-items: center !important; 595 justify-content: center !important; 596 color: #111 !important; 597 background: transparent !important; 598 border: none !important; 599} 600 601.js_add_cart_variants ul[data-attribute_id="3"] .o_variant_pills { 602 width: auto !important; 603} 604.js_add_cart_variants ul[data-attribute_id="3"] .o_variant_pills .o_variant_pills_input_value { 605 width: auto !important; 606 min-width: 60px !important; 607 padding: 0 14px !important; 608} 609 610.js_add_cart_variants ul[data-attribute_id="14"] .o_variant_pills { 611 width: auto !important; 612} 613.js_add_cart_variants ul[data-attribute_id="14"] .o_variant_pills .o_variant_pills_input_value { 614 width: auto !important; 615 min-width: 60px !important; 616 padding: 0 14px !important; 617} 618 619/* ========================================================= 620 NASENSTEG (Single-Select) 621 ========================================================= */ 622.js_add_cart_variants .lars_single_block, 623.js_add_cart_variants .lars_single_block--pill{ 624 outline: none !important; 625 display:flex !important; 626 align-items:center !important; 627 justify-content:center !important; 628 width:130.5px !important; 629 min-width:130.5px !important; 630 height:45px !important; 631 padding:0 12px !important; 632 background:#fff !important; 633 color:#111 !important; 634 border-radius:0 !important; 635 font-weight:400 !important; 636 font-size:16px !important; 637 line-height:1 !important; 638 box-sizing:border-box !important; 639 white-space:nowrap !important; 640 overflow:hidden !important; 641 text-overflow:ellipsis !important; 642 border: 1px solid #000 !important; 643 box-shadow:none !important; 644} 645 646/* Aktiver Nasensteg */ 647.js_add_cart_variants li.js_attribute_value.active .lars_single_block, 648.js_add_cart_variants li.js_attribute_value.active .lars_single_block--pill, 649.js_add_cart_variants input:checked ~ .lars_single_block, 650.js_add_cart_variants input:checked ~ .lars_single_block--pill { 651 outline: 1px solid #000 !important; 652 outline-offset: 2px !important; 653} 654 655.js_add_cart_variants li.js_attribute_value:only-of-type.o_variant_pills { 656 outline: 2px solid #000 !important; 657 outline-offset: 4px !important; 658} 659 660#product_details .js_add_cart_variants{ 661 min-height: 260px; 662} 663#product_details .o_wsale_product_images, 664#product_details .o_wsale_product_images .carousel, 665#product_details .o_wsale_product_images .carousel-item{ 666 min-height: 420px; 667} 668 669@media (min-width: 992px) { 670 .navbar-brand.logo { 671 padding-left: 0 !important; 672 } 673} 674 675.js_add_cart_variants .attribute_name { 676 font-size: 16px !important; 677} 678 679 680 681/* ========================================================= 682 OFFCANVAS / SIDEBAR / FILTER FARB-SWATCHES 683 ========================================================= */ 684
685/* Container: overflow sichtbar + padding-left für Outline-Platz */ 686#o_wsale_offcanvas .o_wsale_offcanvas_color_attribute, 687.o_wsale_offcanvas .o_wsale_offcanvas_color_attribute, 688#wsale_products_attributes_collapse .o_wsale_offcanvas_color_attribute, 689form.js_attributes .o_wsale_offcanvas_color_attribute, 690.js_attributes .o_wsale_offcanvas_color_attribute, 691#o_wsale_offcanvas .css_attribute_color_container, 692form.js_attributes .css_attribute_color_container, 693.js_attributes .css_attribute_color_container { 694 display: flex !important; 695 flex-wrap: wrap !important; 696 gap: 10px !important; 697 padding: 10px 10px 10px 10px !important; 698 overflow: visible !important; 699} 700 701/* Alle Eltern-Container: overflow visible erzwingen */ 702#o_wsale_offcanvas, 703#o_wsale_offcanvas .offcanvas-body, 704#o_wsale_offcanvas .accordion, 705#o_wsale_offcanvas .accordion-item, 706#o_wsale_offcanvas .accordion-body, 707#o_wsale_offcanvas .accordion-collapse, 708#wsale_products_attributes_collapse, 709#wsale_products_attributes_collapse .accordion, 710#wsale_products_attributes_collapse .accordion-item, 711#wsale_products_attributes_collapse .accordion-body, 712#wsale_products_attributes_collapse .accordion-collapse, 713form.js_attributes, 714form.js_attributes .accordion, 715form.js_attributes .accordion-item, 716form.js_attributes .accordion-body, 717form.js_attributes .accordion-collapse, 718aside, 719aside .accordion, 720aside .accordion-item, 721aside .accordion-body, 722aside .accordion-collapse { 723 overflow: hidden !important; 724 overflow-y: auto !important; 725} 726 727/* Swatch-Grösse Form */ 728#o_wsale_offcanvas label.css_attribute_color, 729.o_wsale_offcanvas label.css_attribute_color, 730#wsale_products_attributes_collapse label.css_attribute_color, 731.accordion label.css_attribute_color, 732aside label.css_attribute_color, 733form.js_attributes label.css_attribute_color, 734.js_attributes label.css_attribute_color { 735 width: 60px !important; 736 height: 45px !important; 737 min-width: 60px !important; 738 padding: 0 !important; 739 border-radius: 0 !important; 740 border: none !important; 741 box-shadow: none !important; 742 outline: none !important; 743 margin: 6px 4px 4px 2px !important; 744 position: relative !important; 745 overflow: visible !important; 746 box-sizing: border-box !important; 747 cursor: pointer !important; 748} 749 750/* Innerer Farbbereich eckig füllend */ 751#o_wsale_offcanvas label.css_attribute_color span, 752.o_wsale_offcanvas label.css_attribute_color span, 753#wsale_products_attributes_collapse label.css_attribute_color span, 754.accordion label.css_attribute_color span, 755aside label.css_attribute_color span, 756form.js_attributes label.css_attribute_color span, 757.js_attributes label.css_attribute_color span, 758#o_wsale_offcanvas label.css_attribute_color::before, 759.o_wsale_offcanvas label.css_attribute_color::before, 760#wsale_products_attributes_collapse label.css_attribute_color::before, 761.accordion label.css_attribute_color::before, 762aside label.css_attribute_color::before, 763form.js_attributes label.css_attribute_color::before, 764.js_attributes label.css_attribute_color::before { 765 border-radius: 0 !important; 766 width: 100% !important; 767 height: 100% !important; 768 top: 0 !important; 769 left: 0 !important; 770 position: absolute !important; 771 background-size: cover !important; 772 background-position: center !important; 773} 774 775/* ACTIVE â dünne Linie */ 776#o_wsale_offcanvas label.css_attribute_color.active, 777.o_wsale_offcanvas label.css_attribute_color.active, 778#wsale_products_attributes_collapse label.css_attribute_color.active, 779.accordion label.css_attribute_color.active, 780aside label.css_attribute_color.active, 781form.js_attributes label.css_attribute_color.active, 782.js_attributes label.css_attribute_color.active { 783 outline: 2px solid #000 !important; 784 outline-offset: 2px !important; 785 border: none !important; 786 box-shadow: none !important; 787 z-index: 1 !important; 788} 789 790/* Checkmark-Overlay entfernen */ 791#o_wsale_offcanvas label.css_attribute_color.active::after, 792.o_wsale_offcanvas label.css_attribute_color.active::after, 793#wsale_products_attributes_collapse label.css_attribute_color.active::after, 794.accordion label.css_attribute_color.active::after, 795aside label.css_attribute_color.active::after, 796form.js_attributes label.css_attribute_color.active::after, 797.js_attributes label.css_attribute_color.active::after {
798 content: none !important; 799} 800 801/* Nicht verfügbare ausblenden */ 802#o_wsale_offcanvas label.css_attribute_color.css_not_available, 803form.js_attributes label.css_attribute_color.css_not_available, 804.js_attributes label.css_attribute_color.css_not_available, 805#o_wsale_offcanvas label.css_attribute_color:has(input:disabled), 806form.js_attributes label.css_attribute_color:has(input:disabled), 807.js_attributes label.css_attribute_color:has(input:disabled) { 808 display: none !important; 809} 810 811@media (max-width: 991px) { 812 .lars-product-nav { 813 display: none !important; 814 } 815} 816 817.o_search_result_item > .flex-shrink-0.ms-auto { 818 display: none !important; 819} 820 821/* Breadcrumb Styling */ 822.lars-bc-bar .breadcrumb-item, 823.lars-bc-bar .breadcrumb-item a, 824.lars-bc-bar .breadcrumb-item.active, 825ol.breadcrumb.small .breadcrumb-item, 826ol.breadcrumb.small .breadcrumb-item a, 827ol.breadcrumb.small .breadcrumb-item.active { 828 color: #111 !important; 829 font-size: 16px !important; 830} 831.lars-bc-bar .breadcrumb-item + .breadcrumb-item::before, 832ol.breadcrumb.small .breadcrumb-item + .breadcrumb-item::before { 833 content: "âº" !important; 834 color: #111 !important; 835} 836 837/* Navbar Menu Links */ 838.navbar-nav .nav-link, 839.navbar-nav .nav-link:hover, 840.navbar-nav .dropdown-toggle { 841 color: #111 !important; 842 border: none !important; 843 border-left: none !important; 844 border-right: none !important; 845} 846.navbar-nav .nav-item + .nav-item { 847 border-left: none !important; 848} 849 850.navbar-nav .nav-item:first-child::before, 851.navbar-nav .nav-item:last-child::after, 852.navbar-nav > li:first-child, 853.navbar-nav > li:last-child { 854 border: none !important; 855} 856 857/* Mobile Hamburger #111 */ 858.navbar-toggler-icon { 859 background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23111111' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") !important; 860} 861 862.lars_optiker_btn.btn { 863 margin-left: 0 !important; 864 margin-right: 0 !important; 865 padding-left: 0 !important; 866 padding-right: 0 !important; 867} 868 869/* ========================================================= 870 WARENKORB BUTTON 871 ========================================================= */ 872#add_to_cart, 873.o_wsale_product_btn #add_to_cart { 874 background: #fff !important; 875 color: #111 !important; 876 border: 1px solid #111 !important; 877 border-radius: 0 !important; 878 box-shadow: none !important; 879 height: 47px !important; 880 min-height: 47px !important; 881 max-height: 47px !important; 882 padding-top: 0 !important; 883 padding-bottom: 0 !important; 884 box-sizing: border-box !important; 885 display: flex !important; 886 align-items: center !important; 887 justify-content: center !important; 888} 889 890#product_attributes_simple { 891 display: none !important; 892} 893 894/* ========================================================= 895 NICHT VERFÃGBARE KOMBINATIONEN 896 ========================================================= */ 897.js_add_cart_variants .o_wsale_product_attribute li.js_attribute_value.css_not_available .radio_input_value, 898.js_add_cart_variants .o_wsale_product_attribute li.js_attribute_value.css_not_available .o_variant_pills_input_value { 899 opacity: 0.3 !important; 900 cursor: not-allowed !important; 901} 902.js_add_cart_variants label.css_attribute_color.css_not_available { 903 opacity: 0.3 !important; 904 cursor: not-allowed !important; 905 display: flex !important; 906} 907.js_add_cart_variants .o_variant_pills.css_not_available { 908 opacity: 0.3 !important; 909 cursor: not-allowed !important; 910} 911 912/* ========================================================= 913 MENGENAUSWAHL 914 ========================================================= */ 915.css_quantity.input-group { 916 border: 1px solid #111 !important; 917 border-radius: 0 !important; 918 overflow: hidden !important; 919 width: 130.5px !important; 920 min-width: 130.5px !important; 921 max-width: 130.5px !important; 922 flex: 0 0 130.5px !important; 923} 924.css_quantity .btn-link { 925 background: #fff !important; 926 color: #111 !important; 927 border: none !important; 928 padding: 0 !important; 929 font-size: 14px !important; 930 box-shadow: none !important; 931 height: 45px !important; 932 flex: 1 !important; 933 display: flex !important; 934 align-items: center !important; 935 justify-content: center !important; 936 text-decoration: none !important; 937} 938.css_quantity .btn-link:hover { 939 background: #f5f5f5 !important; 940} 941.css_quantity input.quantity { 942 background: #fff !important; 943 border: none !important; 944 border-left: 1px solid #111 !important; 945 border-right: 1px solid #111 !important; 946 border-radius: 0 !important; 947 box-shadow: none !important; 948 color: #111 !important; 949 font-size: 14px !important; 950 height: 45px !important; 951 width: 45px !important; 952 min-width: 45px !important; 953 max-width: 45px !important; 954 padding: 0 !important; 955} 956 957#o_wsale_offcanvas label.css_attribute_color span, 958.accordion label.css_attribute_color span { 959 border-radius: 0 !important; 960 width: 100% !important; 961 height: 100% !important; 962 top: 0 !important; 963 left: 0 !important; 964 position: absolute !important; 965 background-size: cover !important; 966 background-position: center !important; 967} 968 969body > span.lars-color-tooltip { 970 background: #fff !important; 971 color: #111 !important; 972 font-size: 11px !important; 973 font-weight: 400 !important; 974 white-space: nowrap !important; 975 padding: 3px 7px !important; 976 border: 1px solid #111 !important; 977 border-radius: 0 !important; 978 box-shadow: none !important; 979 width: auto !important; 980 height: auto !important; 981 position: fixed !important; 982 top: auto !important; 983 left: auto !important; 984} 985 986/* ========================================================= 987 PRODUKTKARTEN SWATCHES 988 ========================================================= */ 989.lars-card-swatches { 990 display: flex; 991 flex-wrap: wrap; 992 gap: 6px; 993 padding: 8px 0 0 0; 994} 995.lars-card-swatch { 996 width: 42px; 997 height: 28px; 998 cursor: pointer; 999 border: 1px solid rgba(0,0,0,0.15); 1000 box-sizing: border-box; 1001 flex-shrink: 0; 1002} 1003.lars-card-swatch.active { 1004 outline: 1px solid #000; 1005 outline-offset: 1.5px; 1006} 1007.lars-card-swatch--split { 1008 width: 42px; 1009 height: 28px; 1010 cursor: pointer; 1011 border: none; 1012 box-sizing: border-box; 1013 flex-shrink: 0; 1014 display: flex; 1015 overflow: hidden; 1016 position: relative; 1017} 1018.lars-card-swatch-divider { 1019 position: absolute; 1020 top: 0; 1021 left: 0; 1022 width: 100%; 1023 height: 100%; 1024 pointer-events: none; 1025 z-index: 1; 1026 background: linear-gradient( 1027 to bottom right, 1028 transparent calc(50% - 0.5px), 1029 rgba(255,255,255,0.9) calc(50% - 0.5px), 1030 rgba(255,255,255,0.9) calc(50% + 0.5px), 1031 transparent calc(50% + 0.5px) 1032 ); 1033} 1034.lars-card-swatch--split.active { 1035 outline: 1px solid #000; 1036 outline-offset: 1.5px; 1037} 1038.lars-card-swatch-left { 1039 position: absolute; 1040 inset: 0; 1041 background-size: cover; 1042 background-position: center; 1043 clip-path: polygon(0 0, 100% 0, 0 100%); 1044} 1045.lars-card-swatch-right { 1046 position: absolute; 1047 inset: 0; 1048 background-size: cover; 1049 background-position: center; 1050 clip-path: polygon(100% 0, 100% 100%, 0 100%); 1051} 1052/* ========================================================= 1053 SHOP SUCHLEISTE + FILMSTRIP 1054 ========================================================= */ 1055.o_wsale_products_searchbar_form input[type="search"] { 1056 background: #fff !important; 1057 border: 1px solid #111 !important;
1058 border-right: none !important; 1059 border-radius: 0 !important; 1060 box-shadow: none !important; 1061 color: #111 !important; 1062} 1063.o_wsale_products_searchbar_form input[type="search"]::placeholder { 1064 color: rgba(0,0,0,0.4) !important; 1065} 1066.o_wsale_products_searchbar_form .oe_search_button { 1067 background: #fff !important; 1068 border: 1px solid #111 !important; 1069 border-left: none !important; 1070 border-radius: 0 !important; 1071 box-shadow: none !important; 1072 color: #111 !important; 1073} 1074button[data-bs-target="#o_wsale_offcanvas"] { 1075 background: #fff !important; 1076 border: 1px solid #111 !important; 1077 border-radius: 0 !important; 1078 box-shadow: none !important; 1079 color: #111 !important; 1080} 1081.o_wsale_filmstip_container .btn { 1082 background: #fff !important; 1083 border: 1px solid #111 !important; 1084 border-radius: 0 !important; 1085 box-shadow: none !important; 1086 color: #111 !important; 1087 font-family: 'Inter', sans-serif !important; 1088 font-size: 16px !important; 1089 font-weight: 500 !important; 1090 letter-spacing: 0.08em !important; 1091 text-transform: uppercase !important; 1092 padding: 10px 24px !important; 1093} 1094.o_wsale_filmstip_container ul { 1095 padding: 4px !important; 1096 overflow: visible !important; 1097} 1098.o_wsale_filmstip_container li:has(input:checked) .btn { 1099 font-weight: 700 !important; 1100 background: #fff !important; 1101 color: #111 !important; 1102 border: 1px solid #111 !important; 1103 outline: 2px solid #111 !important; 1104 outline-offset: 2px !important; 1105} 1106 1107/* Hover: schwarz mit weisser Schrift â alle Shop-Buttons */ 1108.o_wsale_filmstip .btn:hover, 1109button[data-bs-target="#o_wsale_offcanvas"]:hover, 1110.o_wsale_products_searchbar_form .oe_search_button:hover, 1111.products_categories .nav-link:hover, 1112.products_categories a:hover, 1113#add_to_cart:hover, 1114.o_wsale_product_btn #add_to_cart:hover { 1115 background-color: #000 !important; 1116 color: #fff !important; 1117 border-color: #000 !important; 1118 transition: background-color 0.15s ease, color 0.15s ease; 1119} 1120 1121 1122/* ========================================================= 1123 PRODUKTGRID 1124 ========================================================= */ 1125.o_wsale_products_grid_table_wrapper table { 1126 border-spacing: 4px !important; 1127 border-collapse: separate !important; 1128} 1129.o_wsale_products_grid_table_wrapper { 1130 padding: 0 16px !important; 1131} 1132.oe_product .thumbnail, 1133.oe_product .o_wsale_product_grid_wrapper, 1134.oe_product { 1135 background: #fff !important; 1136 border: none !important; 1137 box-shadow: none !important; 1138 border-radius: 0 !important; 1139 margin: 0 !important; 1140} 1141.o_wsale_product_grid_wrapper { 1142 padding: 16px !important; 1143} 1144.o_wsale_product_information { 1145 padding: 0 8px !important; 1146} 1147.oe_product .oe_product_image { 1148 max-height: 280px !important; 1149 min-height: 280px !important; 1150} 1151.oe_product .oe_product_image_img_wrapper { 1152 max-height: 280px !important; 1153} 1154.oe_product .oe_product_image img { 1155 max-height: 280px !important; 1156 object-fit: contain !important; 1157} 1158 1159.oe_product:hover { 1160 outline: 2.5px solid #111 !important; 1161} 1162.o_wsale_products_grid_table_wrapper { 1163 overflow: visible !important; 1164 padding: 0 2px !important; 1165} 1166 1167/* ========================================================= 1168 PRODUKTKARTEN TITEL + PREIS 1169 ========================================================= */ 1170.oe_product .o_wsale_products_item_title { 1171 display: flex !important; 1172 justify-content: space-between !important; 1173 align-items: baseline !important; 1174 gap: 8px !important; 1175 padding-top: 16px !important; 1176 margin-bottom: 8px !important; 1177 1178} 1179.oe_product .o_wsale_products_item_title a.text-primary { 1180 font-family: 'Inter', sans-serif !important; 1181 font-size: 20px !important; 1182 font-weight: 800 !important; 1183 color: #111 !important; 1184 text-decoration: none !important; 1185 flex: 1 !important; 1186} 1187.oe_product .product_price { 1188 font-family: 'Inter', sans-serif !important; 1189 font-size: 15px !important; 1190 font-weight: 400 !important; 1191 color: #111 !important; 1192 text-align: right !important; 1193 white-space: nowrap !important; 1194} 1195.oe_product .product_price .h6 { 1196 font-family: 'Inter', sans-serif !important; 1197 font-size: 15px !important; 1198 font-weight: 400 !important; 1199 color: #111 !important; 1200} 1201 1202.lars-card-swatch--split { 1203 width: 40px !important;
1204 height: 26px !important; 1205} 1206 1207/* Mehr Abstand zwischen Swatches und Titel */ 1208.lars-card-swatches { 1209 padding: 11px 0 25px 0 !important; 1210} 1211 1212/* Preis in Titelzeile, nicht darunter */ 1213.oe_product .o_wsale_product_sub { 1214 display: none !important; 1215} 1216.oe_product .o_wsale_products_item_title .product_price { 1217 display: block !important; 1218} 1219 1220/* Produktgrid Abstände */ 1221.o_wsale_products_grid_table_wrapper table { 1222 border-spacing: 12px !important; 1223 border-collapse: separate !important; 1224 margin: 0 -12px !important; 1225 width: calc(100% + 24px) !important; 1226} 1227.o_wsale_products_grid_table_wrapper { 1228 padding: 0 !important; 1229 overflow: hidden !important; 1230} 1231/* Produktkarte Padding innen */ 1232.o_wsale_product_grid_wrapper { 1233 padding: 16px 20px 16px 20px !important; 1234 } 1235 1236 /* Titel Zeile kompakter */ 1237.oe_product .o_wsale_products_item_title { 1238 margin-top: 0 !important; 1239 margin-bottom: 0 !important; 1240} 1241 1242/* Mehr Abstand unten in der Karte */ 1243.o_wsale_product_information { 1244 padding: 0 4px 8px 4px !important; 1245} 1246.oe_product { 1247 outline: 1px solid #111 !important; 1248} 1249 1250@media (max-width: 767px) { 1251 .oe_product { 1252 outline: none !important; 1253 } 1254 .o_wsale_product_grid_wrapper { 1255 border: 1px solid #111 !important; 1256 } 1257} 1258 1259.o_wsale_products_grid_table_wrapper { 1260 padding: 0 1px !important; 1261} 1262 1263.o_wsale_image_viewer_void { 1264 background-color: #ffffff; 1265} 1266 1267.o_wsale_image_viewer_carousel { 1268 display: none !important; 1269} 1270 1271.fa.fa-times { 1272 font-family: 'Inter', sans-serif; 1273 font-weight: 800; 1274 font-size: 30px; 1275 color: #000; 1276 position: absolute; 1277 top: 50px; 1278 right: 50px; 1279} 1280.fa.fa-times::before { 1281 content: 'Ã'; 1282} 1283.fa.fa-times:hover { 1284 opacity: 0.8; 1285} 1286 1287.product_detail_img { 1288 object-fit: cover !important; 1289 object-position: center center !important; 1290 max-height: 500px !important; 1291 width: 100% !important; 1292} 1293 1294/* Hellgrauer Hintergrund hinter Produktbildern auf der Detailseite */ 1295#product_details .o_wsale_product_images, 1296#product_details .o_wsale_product_images .carousel, 1297#product_details .o_wsale_product_images .carousel-item, 1298.product_detail_img { 1299 background-color: #f5f5f5 !important; 1300} 1301 1302 1303/* ========================================================= 1304 RIBBON / BAND 1305 ========================================================= */ 1306.o_ribbon_left, 1307.o_ribbon_right { 1308 position: absolute !important; 1309 top: 0 !important; 1310 left: 0 !important; 1311 right: auto !important; 1312 transform: none !important; 1313 clip-path: none !important; 1314 border-radius: 0 !important; 1315 background: #111 !important; 1316 color: #fff !important; 1317 border: 1.5px solid #111 !important; 1318 border-top: none !important; 1319 border-left: none !important; 1320 font-family: 'Inter', sans-serif !important; 1321 font-size: 16px !important; 1322 font-weight: 500 !important; 1323 letter-spacing: 0.08em !important; 1324 text-transform: uppercase !important; 1325 padding: 5px 10px !important; 1326 line-height: 1.4 !important; 1327 white-space: nowrap !important; 1328 box-shadow: none !important; 1329 width: auto !important; 1330 height: auto !important; 1331 z-index: 5 !important; 1332 margin: 0 !important; 1333 padding: 12px 10px 10px 12px !important; 1334} 1335 1336.o_wsale_product_grid_wrapper { 1337 position: relative !important; 1338 overflow: hidden !important; 1339} 1340 1341.oe_product { 1342 position: relative !important; 1343 overflow: hidden !important; 1344} 1345 1346@media (max-width: 991px) { 1347 .o_wsale_products_grid_table_wrapper { 1348 padding: 0 12px !important; 1349 overflow: visible !important; 1350 } 1351 1352 .o_wsale_products_grid_table_wrapper table { 1353 display: flex !important; 1354 flex-wrap: wrap !important; 1355 width: 100% !important; 1356 margin: 0 !important; 1357 gap: 8px !important; 1358 } 1359 .o_wsale_products_grid_table_wrapper table tbody { 1360 display: flex !important; 1361 flex-wrap: wrap !important; 1362 width: 100% !important; 1363 gap: 8px !important; 1364 } 1365 .o_wsale_products_grid_table_wrapper table tbody tr { 1366 display: contents !important; 1367 } 1368 1369 .o_wsale_products_grid_table_wrapper table tbody tr td.oe_product { 1370 width: calc(50% - 4px) !important; 1371 flex: 0 0 calc(50% - 4px) !important; 1372 overflow: visible !important; 1373 outline: none !important; 1374 padding: 0 !important; 1375 margin: 0 !important; 1376 } 1377 1378 .o_wsale_products_grid_table_wrapper .oe_product .o_wsale_product_grid_wrapper { 1379 border: 1px solid #111 !important; 1380 overflow: hidden !important; 1381 height: 100% !important; 1382 } 1383 1384 .oe_product .oe_product_image { 1385 display: block !important; 1386 min-height: unset !important; 1387 max-height: unset !important; 1388 height: auto !important; 1389 overflow: visible !important; 1390 padding: 0 !important; 1391 } 1392 .oe_product .oe_product_image img { 1393 display: block !important; 1394 margin: 0 auto !important; 1395 max-height: 120px !important; 1396 max-width: 100% !important; 1397 width: auto !important; 1398 object-fit: contain !important; 1399 } 1400 1401 /* Titel + Preis untereinander, kompakt */ 1402 .oe_product .o_wsale_products_item_title { 1403 flex-direction: column !important;
1404 align-items: flex-start !important; 1405 gap: 1px !important; 1406 padding-top: 6px !important; 1407 margin-bottom: 0 !important; 1408 } 1409 .oe_product .o_wsale_products_item_title a.text-primary { 1410 font-size: 14px !important; 1411 font-weight: 700 !important; 1412 line-height: 1.2 !important; 1413 } 1414 .oe_product .product_price, 1415 .oe_product .product_price .h6 { 1416 font-size: 12px !important; 1417 text-align: left !important; 1418 white-space: nowrap !important; 1419 font-weight: 400 !important; 1420 line-height: 1.3 !important; 1421 } 1422 1423 /* Swatches kompakter */ 1424 .lars-card-swatches { 1425 gap: 3px !important; 1426 padding: 5px 0 6px 0 !important; 1427 } 1428 .lars-card-swatch, 1429 .lars-card-swatch--split { 1430 width: 28px !important; 1431 height: 18px !important; 1432 } 1433 1434 /* Inneres Padding kleiner */ 1435 .o_wsale_product_grid_wrapper { 1436 padding: 8px 8px 8px 8px !important; 1437 } 1438 1439 .o_wsale_product_information { 1440 padding: 0 2px 4px 2px !important; 1441 } 1442} 1443 1444 1445.o_wsale_product_page .o_ribbon_left, 1446.o_wsale_product_page .o_ribbon_right { 1447 display: none !important; 1448} 1449 1450 1451/* ========================================================= 1452 USER ACCOUNT DROPDOWN (.js_usermenu) 1453 ========================================================= */ 1454 1455/* Container */ 1456header .dropdown-menu.js_usermenu { 1457 border-radius: 0 !important; 1458 border: 1px solid #111 !important; 1459 padding: 0 !important; 1460 margin-top: 0 !important; 1461 background-color: #fff !important; 1462 box-shadow: none !important; 1463 font-family: 'Inter', sans-serif !important; 1464 min-width: 180px !important; 1465} 1466 1467/* Items: weià mit schwarzer Trennlinie */ 1468header .dropdown-menu.js_usermenu .dropdown-item { 1469 border-radius: 0 !important; 1470 padding: 12px 20px !important; 1471 color: #111 !important; 1472 font-family: 'Inter', sans-serif !important; 1473 font-size: 16px !important; 1474 font-weight: 400 !important; 1475 border-bottom: 1px solid #111 !important; 1476 background-color: #fff !important; 1477 transition: background-color 0.15s ease, color 0.15s ease !important; 1478} 1479 1480/* Letztes Item ohne Trennlinie */ 1481header .dropdown-menu.js_usermenu .dropdown-item:last-child { 1482 border-bottom: none !important; 1483} 1484 1485/* Hover: schwarz mit weiÃer Schrift */ 1486header .dropdown-menu.js_usermenu .dropdown-item:hover, 1487header .dropdown-menu.js_usermenu .dropdown-item:focus, 1488header .dropdown-menu.js_usermenu .dropdown-item:active, 1489header .dropdown-menu.js_usermenu .dropdown-item.active { 1490 background-color: #111 !important; 1491 color: #fff !important; 1492} 1493 1494/* Icons in den Items ausblenden */ 1495header .dropdown-menu.js_usermenu .dropdown-item i, 1496header .dropdown-menu.js_usermenu .dropdown-item .fa { 1497 display: none !important; 1498} 1499 1500/* Caret beim User Icon entfernen */ 1501header li.dropdown .dropdown-toggle:has(.js_usermenu)::after, 1502header .o_no_autohide_item .dropdown-toggle::after { 1503 display: none !important; 1504} 1505 1506/* Divider ausblenden (zwischen Mein Konto und Abmelden) */ 1507header .dropdown-menu.js_usermenu .dropdown-divider, 1508header .dropdown-menu.js_usermenu hr, 1509header .dropdown-menu.js_usermenu #o_logout_divider { 1510 display: none !important; 1511} 1512 1513/* ========================================================= 1514 HEADER LINIEN 1515 Navbar: keine Linie 1516 Mega Menu: schwarze Linie unten (nur wenn offen) 1517 ========================================================= */ 1518 1519/* Alle Borders und Shadows im Header Bereich komplett weg */ 1520body, 1521#wrapwrap, 1522#wrapwrap > header, 1523#wrapwrap > header .navbar, 1524header.o_header_standard, 1525header.o_header_affixed, 1526.o_header_standard .navbar, 1527.o_header_affixed .navbar, 1528nav.navbar { 1529 border-top: none !important; 1530 border-bottom: none !important; 1531 box-shadow: none !important; 1532} 1533 1534/* Mega Menu: nur unten schwarze Linie, sonst nichts */ 1535#top_menu .dropdown-menu.o_mega_menu, 1536header .dropdown-menu.o_mega_menu { 1537 border: none !important; 1538 border-top: none !important; 1539 border-bottom: 1px solid #111 !important; 1540 border-radius: 0 !important; 1541 box-shadow: none !important; 1542 margin-top: 0 !important; 1543} 1544 1545.lars-hover-wrapper { 1546 position: relative; 1547 display: block; 1548 overflow: hidden; 1549 width: 100%; 1550 height: 100%; 1551} 1552 1553.lars-hover-wrapper .lars-img-default, 1554.lars-hover-wrapper .lars-img-hover { 1555 display: block; 1556 width: 100%; 1557 height: 100%; 1558 object-fit: cover; 1559 transition: opacity 0.4s ease-in-out; 1560} 1561 1562.lars-hover-wrapper .lars-img-hover { 1563 position: absolute; 1564 top: 0; 1565 left: 0; 1566 opacity: 0; 1567} 1568 1569.lars-hover-wrapper:hover .lars-img-default { 1570 opacity: 0; 1571} 1572 1573.lars-hover-wrapper:hover .lars-img-hover { 1574 opacity: 1; 1575} 1576 1577@media (hover: none) { 1578 .lars-hover-wrapper:hover .lars-img-default { 1579 opacity: 1; 1580 } 1581 .lars-hover-wrapper:hover .lars-img-hover { 1582 opacity: 0; 1583 } 1584} 1585/* ========================================================= 1586 LARS CART STYLING 1587 ========================================================= */ 1588
1589/* Cart Zeile: Spalten oben starten, nicht strecken */ 1590.o_cart_product { 1591 align-items: flex-start !important; 1592} 1593 1594/* Rechte Spalte (Buttons + Preis) auf eigene Höhe */ 1595.o_cart_product > div:last-child { 1596 align-self: flex-start !important; 1597 height: auto !important; 1598} 1599 1600/* Leere Verfügbarkeitsmeldungen ausblenden */ 1601.o_cart_product .availability_messages:empty { 1602 display: none !important; 1603} 1604 1605/* ========================================================= 1606 QUANTITY BLOCK IM CART 1607 ========================================================= */ 1608 1609/* Container: 45px hoch, nicht überdehnen */ 1610.o_cart_product [name="website_sale_cart_line_quantity"].css_quantity { 1611 height: 45px !important; 1612 max-height: 45px !important; 1613 align-items: center !important; 1614 overflow: hidden !important; 1615} 1616 1617/* Buttons: feste GröÃe, NICHT mit flex:1 strecken */ 1618.o_cart_product [name="website_sale_cart_line_quantity"] .btn-link { 1619 flex: 0 0 auto !important; 1620 height: 45px !important; 1621 max-height: 45px !important; 1622 width: 42px !important; 1623} 1624 1625/* Input zwischen den Buttons */ 1626.o_cart_product [name="website_sale_cart_line_quantity"] input.quantity { 1627 height: 45px !important; 1628 max-height: 45px !important; 1629} 1630 1631/* ========================================================= 1632 AVAIL ANZEIGE IM CART 1633 ========================================================= */ 1634 1635.lars-avail-cart { 1636 margin-top: 4px !important; 1637 margin-bottom: 0 !important; 1638 min-height: 0 !important; 1639 gap: 6px !important; 1640 display: flex !important; 1641 align-items: center !important; 1642} 1643 1644.o_cart_product .lars-avail-cart .lars-avail-dot { 1645 display: inline-block !important; 1646 width: 10px !important; 1647 height: 10px !important; 1648 border-radius: 50% !important; 1649 flex-shrink: 0 !important; 1650} 1651 1652.o_cart_product .lars-avail-cart .lars-avail-dot.lager { background: #22a861 !important; } 1653.o_cart_product .lars-avail-cart .lars-avail-dot.verfuegbar { background: #f5c400 !important; } 1654.o_cart_product .lars-avail-cart .lars-avail-dot.produktion { background: #f07800 !important; } 1655.o_cart_product .lars-avail-cart .lars-avail-dot.auslauf { background: transparent !important; border: 2px solid #111 !important; } 1656.o_cart_product .lars-avail-cart .lars-avail-dot.naechster_zyklus { background: transparent !important; border: 2px solid #f07800 !important; } 1657 1658.o_cart_product .lars-avail-cart .lars-avail-text { 1659 font-size: 11px !important; 1660 color: rgba(0,0,0,0.6) !important; 1661} 1662 1663/* Mega Menu Links: dezenter Hover */ 1664header .dropdown-menu.o_mega_menu a:hover, 1665header .dropdown-menu.o_mega_menu a:focus { 1666 color: #666 !important; 1667 text-decoration: none !important; 1668 transition: color 0.15s ease !important; 1669 background-color: transparent !important; 1670} 1671 1672.sh-breadcrumb-wrap .breadcrumb, 1673.sh-breadcrumb-wrap .breadcrumb a { 1674 text-transform: uppercase; 1675} 1676 1677</style> 1678
1679<script type="text/javascript"> 1680(function() { 1681 var cardIndex = 0; 1682 function initSwatches() { 1683 document.querySelectorAll('.lars-card-swatches').forEach(function(container) { 1684 var card = container.closest('.oe_product'); 1685 if (!card) return; 1686 var img = card.querySelector('img'); 1687 if (!img) return; 1688 var swatches = container.querySelectorAll('.lars-card-swatch, .lars-card-swatch--split'); 1689 if (!swatches.length) return; 1690 1691 // Startfarbe abhängig von der Kartenposition, damit nicht alle Karten dieselbe Farbe zeigen 1692 var startIndex = cardIndex % swatches.length; 1693 cardIndex++; 1694 1695 swatches.forEach(function(s) { s.classList.remove('active'); }); 1696 swatches[startIndex].classList.add('active'); 1697 1698 var startVariantId = swatches[startIndex].dataset.variantId; 1699 if (startVariantId) { 1700 img.src = '/web/image/product.product/' + startVariantId + '/image_512'; 1701 } 1702 1703 swatches.forEach(function(swatch) { 1704 swatch.addEventListener('click', function(e) { 1705 e.preventDefault(); 1706 e.stopPropagation(); 1707 var variantId = swatch.dataset.variantId; 1708 if (!variantId) return; 1709 swatches.forEach(function(s) { s.classList.remove('active'); }); 1710 swatch.classList.add('active'); 1711 var newSrc = '/web/image/product.product/' + variantId + '/image_512'; 1712 img.style.opacity = '0.5'; 1713 var tempImg = new Image(); 1714 tempImg.onload = function() { img.src = newSrc; img.style.opacity = '1'; }; 1715 tempImg.onerror = function() { img.style.opacity = '1'; }; 1716 tempImg.src = newSrc; 1717 }); 1718 }); 1719 }); 1720 } 1721 if (document.readyState === 'loading') { 1722 document.addEventListener('DOMContentLoaded', initSwatches); 1723 } else { 1724 initSwatches(); 1725 } 1726})(); 1727 1728(function() { 1729 function movePrices() { 1730 document.querySelectorAll('.oe_product').forEach(function(card) { 1731 var title = card.querySelector('.o_wsale_products_item_title'); 1732 var price = card.querySelector('.product_price'); 1733 if (title && price && !title.contains(price)) { 1734 title.appendChild(price); 1735 } 1736 }); 1737 } 1738 if (document.readyState === 'loading') { 1739 document.addEventListener('DOMContentLoaded', movePrices); 1740 } else { 1741 movePrices(); 1742 } 1743})(); 1744 1745(function() { 1746 function applyProductImages() { 1747 document.querySelectorAll('.product_detail_img').forEach(function(img) { 1748 img.style.setProperty('object-fit', 'cover', 'important'); 1749 img.style.setProperty('object-position', 'center center', 'important'); 1750 img.style.setProperty('max-height', '500px', 'important'); 1751 img.style.setProperty('width', '100%', 'important'); 1752 }); 1753 } 1754 1755 // Sofort, nach DOM, und nach 1s nochmal (für lazy-loaded Bilder) 1756 if (document.readyState === 'loading') { 1757 document.addEventListener('DOMContentLoaded', function() { 1758 applyProductImages(); 1759 setTimeout(applyProductImages, 500); 1760 setTimeout(applyProductImages, 1500); 1761 }); 1762 } else { 1763 applyProductImages(); 1764 setTimeout(applyProductImages, 500); 1765 setTimeout(applyProductImages, 1500); 1766 } 1767 1768 if (document.body) { 1769 var observer = new MutationObserver(applyProductImages); 1770 observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['src', 'alt'] }); 1771 } 1772})(); 1773 1774 1775(function() { 1776 function addTitleToViewer() { 1777 setTimeout(function() { 1778 var viewer = document.querySelector('.o_wsale_image_viewer_image'); 1779 if (!viewer) return; 1780 if (document.getElementById('lars-viewer-title')) return; 1781 1782 var productTitle = document.querySelector('h1[itemprop="name"]'); 1783 if (!productTitle) return; 1784 1785 var titleEl = document.createElement('div'); 1786 titleEl.id = 'lars-viewer-title'; 1787 titleEl.textContent = productTitle.textContent.trim(); 1788 titleEl.style.cssText = [ 1789 'position:absolute', 1790 'left:50px', 1791 'top:50px', 1792 'font-family:Inter,sans-serif', 1793 'font-size:18px', 1794 'font-weight:800', 1795 'color:#111', 1796 'z-index:100', 1797 'pointer-events:none' 1798 ].join(';'); 1799 1800 viewer.appendChild(titleEl); 1801 }, 300); 1802 } 1803 1804 document.addEventListener('click', function(e) { 1805 var img = e.target.closest('.product_detail_img, .lars-star-images img'); 1806 if (img) { 1807 document.getElementById('lars-viewer-title') && document.getElementById('lars-viewer-title').remove(); 1808 addTitleToViewer(); 1809 } 1810 }); 1811})(); 1812 1813(function() { 1814 function moveRibbons() { 1815 document.querySelectorAll('.o_ribbon').forEach(function(ribbon) { 1816 var card = ribbon.closest('.oe_product'); 1817 if (!card) return; 1818 if (card.querySelector(':scope > .o_ribbon')) return; 1819 card.appendChild(ribbon); 1820 }); 1821 } 1822 if (document.readyState === 'loading') { 1823 document.addEventListener('DOMContentLoaded', moveRibbons); 1824 } else { 1825 moveRibbons(); 1826 } 1827})(); 1828</script>
1828 1829
1830<script type="text/javascript"> 1831(function () { 1832 var COLOR_ATTRIBUTE_IDS_CARD = [2, 28, 4, 6]; 1833 var cardColorIndex = 0; 1834 1835 function getSelectedColorValues() { 1836 var params = new URLSearchParams(window.location.search); 1837 var attribs = params.getAll('attrib'); 1838 var result = []; 1839 attribs.forEach(function(val) { 1840 var parts = val.split('-'); 1841 var attrId = parseInt(parts[0], 10); 1842 var valId = parseInt(parts[1], 10); 1843 if (COLOR_ATTRIBUTE_IDS_CARD.indexOf(attrId) !== -1 && !isNaN(valId)) { 1844 result.push(valId); 1845 } 1846 }); 1847 return result; 1848 } 1849 1850 // RPC-frei: nutzt window.LARS_EMBEDDED.variant_colors (Variante-ID -> Liste 1851 // von Farbwert-IDs), das serverseitig eingebettet wird und daher auch fuer 1852 // nicht eingeloggte Besucher zuverlaessig verfuegbar ist. 1853 function syncCardSwatchesToFilter() { 1854 var selectedValueIds = getSelectedColorValues(); 1855 if (!selectedValueIds.length) return; 1856 1857 var variantColors = (window.LARS_EMBEDDED && window.LARS_EMBEDDED.variant_colors) || {}; 1858 1859 document.querySelectorAll('.lars-card-swatches').forEach(function(container) { 1860 var card = container.closest('.oe_product'); 1861 if (!card) return; 1862 var img = card.querySelector('img'); 1863 if (!img) return; 1864 1865 var matchingSwatches = []; 1866 container.querySelectorAll('.lars-card-swatch[data-variant-id]').forEach(function(sw) { 1867 var vid = sw.getAttribute('data-variant-id'); 1868 var valueIds = variantColors[vid] || []; 1869 var isMatch = selectedValueIds.some(function(sel) { return valueIds.indexOf(sel) !== -1; }); 1870 if (isMatch) matchingSwatches.push(sw); 1871 }); 1872 if (!matchingSwatches.length) return; 1873 1874 var idx = cardColorIndex % matchingSwatches.length; 1875 cardColorIndex++; 1876 var chosen = matchingSwatches[idx]; 1877 1878 container.querySelectorAll('.lars-card-swatch, .lars-card-swatch--split').forEach(function(s) { 1879 s.classList.remove('active'); 1880 }); 1881 chosen.classList.add('active'); 1882 img.src = '/web/image/product.product/' + chosen.getAttribute('data-variant-id') + '/image_512'; 1883 }); 1884 } 1885 1886 if (document.readyState === 'loading') { 1887 document.addEventListener('DOMContentLoaded', function() { setTimeout(syncCardSwatchesToFilter, 300); }); 1888 } else { 1889 setTimeout(syncCardSwatchesToFilter, 300); 1890 } 1891})(); 1892</script>
1892 1893 </head> 1894 <body> 1895 1896 1897 1898 <div id="wrapwrap" class=" "> 1899 <header id="top" data-anchor="true" data-name="Header" data-extra-items-toggle-aria-label="Schaltfläche für zusätzliche Elemente" class=" o_header_disappears" style=" "> 1900 1901 <nav data-name="Navbar" aria-label="Main" class="navbar navbar-expand-lg navbar-light o_colored_level o_cc d-none d-lg-block py-0 shadow-sm "> 1902 1903 1904 <div id="o_main_nav" class="o_main_nav container align-items-stretch"> 1905 1906 <a data-name="Navbar Logo" href="/" class="navbar-brand logo d-flex align-items-center me-4 p-2"> 1907 1908 <span role="img" aria-label="Logo of LARS Brillen" title="LARS Brillen"><img src="/web/image/website/1/logo/LARS%20Brillen?unique=c9e8819" class="img img-fluid" width="95" height="40" alt="LARS Brillen" loading="lazy"/></span> 1909 </a> 1910 1911 1912 <ul id="top_menu" role="menu" class="nav navbar-nav top_menu o_menu_loading d-flex align-items-center ms-auto o_border_contrast"> 1913 1914 1915 <li role="presentation" class="nav-item h-100 border-start o_border_contrast dropdown position-static"> 1916 <a data-bs-toggle="dropdown" href="#" role="menuitem" class="nav-link d-flex align-items-center h-100 dropdown-toggle o_mega_menu_toggle " data-bs-display="static"> 1917 <span>OPTICAL</span> 1918 </a> 1919 <div data-name="Mega Menu" class="dropdown-menu o_mega_menu o_no_parent_editor"> 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069<section class="s_mega_menu_menu_image_menu py-4 o_colored_level o_cc o_cc1 pt16" style="background-image: none;"> 2070 <div class="container"> 2071 <div class="row o_grid_mode" data-row-count="5"> 2072 2073 2074 2075 <div class="o_grid_item o_colored_level g-height-1 order-lg-0 g-col-lg-3 col-lg-3 d-lg-block d-none o_snippet_mobile_invisible" style="z-index: 9; grid-area: 1 / 1 / 2 / 4; --grid-item-padding-x: 0px; --grid-item-padding-y: 0px; order: 1;" data-invisible="1"><h4 style="text-align: left;"><strong><a class="btn btn-custom" href="/shop/category/optical-6" style="border-width: 0px; border-style: solid;" data-bs-original-title="" title=""><span class="h3-fs">KORREKTURBRILLEN</span></a></strong></h4></div><div class="o_grid_item o_grid_item_image o_colored_level g-col-lg-3 g-height-4 col-lg-3 order-lg-0 d-lg-block d-none o_snippet_mobile_invisible" style="z-index: 6; grid-area: 2 / 1 / 6 / 4; --grid-item-padding-y: 0px; order: 2;" data-invisible="1"><a href="/shop/category/linears-1" data-bs-original-title="" title=""><img src="/web/image/19024-87127ed0/Kollektion-LINEARS-liegend.jpg?access_token=befcd4d4-98b0-4369-bb99-b9f99af9674a" alt="" class="img img-fluid mx-auto o_we_custom_image" data-mimetype="image/jpeg" data-original-id="19012" data-original-src="/web/image/19012-de701cfb/Kollektion-LINEARS-liegend.jpg" data-mimetype-before-conversion="image/jpeg" data-resize-width="1760" loading="lazy"></a></div><div class="o_grid_item o_grid_item_image o_colored_level g-height-4 g-col-lg-3 col-lg-3 order-lg-0 d-lg-block d-none o_snippet_mobile_invisible" style="z-index: 7; grid-area: 2 / 4 / 6 / 7; order: 4; --grid-item-padding-y: 0px;" data-invisible="1"><a href="/shop/category/lacet-2" data-bs-original-title="" title=""><img src="/web/image/19025-e062d8f6/Kollektion-LACET-liegend.jpg?access_token=64dc5103-184b-4b71-949c-7ba216ab886b" alt="" class="img img-fluid mx-auto o_we_custom_image" data-mimetype="image/jpeg" data-original-id="19013" data-original-src="/web/image/19013-f4905cad/Kollektion-LACET-liegend.jpg" data-mimetype-before-conversion="image/jpeg" data-resize-width="1760" loading="lazy"></a></div><div class="o_grid_item o_colored_level g-height-1 g-col-lg-3 order-lg-0 col-lg-3 d-lg-block d-none o_snippet_mobile_invisible" style="z-index: 10; grid-area: 5 / 4 / 6 / 7; --grid-item-padding-y: 20px; --grid-item-padding-x: 20px; background-color: rgba(255, 255, 255, 0); order: 5;" data-invisible="1"><p style="text-align: left;"><a title="" data-bs-original-title="" href="/shop/category/lacet-2"><span class="base-fs"><span class="lead"><span class="base-fs">LACET</span></span></span></a><span class="base-fs"><span class="lead"><span class="base-fs">â</span></span></span></p></div><div class="o_grid_item o_colored_level g-col-lg-3 order-lg-0 g-height-5 col-lg-3" style="z-index: 12; grid-area: 1 / 10 / 6 / 13; order: 0;"><li style="text-align: left;" class="text-uppercase h5 fw-bold mt-0"><span style="font-size: 1.125rem;"><strong>ENTDECKE</strong></span></li> 2076 <nav class="nav flex-column"> 2077 <a style="text-align: left;" title="" data-bs-original-title="" data-name="Menu Item" class="nav-link px-0" href="/shop/category/linears-1#top"><span style="font-size: 1rem;">LINEARS</span></a> 2078 <a style="text-align: left;" title="" data-bs-original-title="" data-name="Menu Item" class="nav-link px-0" href="/shop/category/lacet-2"><span style="font-size: 1rem;">LACET</span></a><a style="text-align: left;" title="" data-bs-original-title="" data-name="Menu Item" class="nav-link px-0" href="/shop?attrib=3-14&attrib=3-75&attrib=3-15&attrib=3-91&attrib=3-16&attrib=3-92&attrib=3-17&attrib=3-18&attrib=3-19&attrib=3-20&attrib=3-21&attrib=3-22&attrib=3-23&attrib=3-25&attrib=3-26&attrib=3-27&attrib=3-28&attrib=3-29&attrib=3-30&attrib=3-31&attrib=3-32&attrib=3-34&attrib=3-35&attrib=3-36&attrib=3-37&attrib=3-38&attrib=3-39&attrib=3-40&attrib=3-41&attrib=3-43&attrib=3-44&attrib=3-54&attrib=3-93&attrib=3-94&attrib=3-95&attrib=3-96&attrib=3-98&
2078attrib=3-165&attrib=3-172&attrib=3-173&attrib=3-193&attrib=3-205&attrib=3-207&tags=93"><span style="font-size: 1rem;">ESSENTIALS</span></a><span style="font-size: 1.125rem;"><br></span> 2079 </nav></div><div class="o_grid_item o_colored_level g-col-lg-3 g-height-1 col-lg-3 order-lg-0 d-lg-block d-none o_snippet_mobile_invisible" style="z-index: 13; grid-area: 5 / 1 / 6 / 4; --grid-item-padding-y: 20px; --grid-item-padding-x: 20px; order: 3;" data-invisible="1"><li style="text-align: left;"><a href="/shop/category/linears-1#top" data-bs-original-title="" title=""><span class="base-fs"><span class="lead"><span class="base-fs">LINEARS</span></span></span></a><span class="base-fs"><span class="lead"><span class="base-fs">â</span></span></span></li></div></div> 2080 </div> 2081 </section></div> 2082 2083 </li> 2084 <li role="presentation" class="nav-item h-100 border-start o_border_contrast dropdown position-static"> 2085 <a data-bs-toggle="dropdown" href="#" role="menuitem" class="nav-link d-flex align-items-center h-100 dropdown-toggle o_mega_menu_toggle " data-bs-display="static"> 2086 <span>SPORTS</span> 2087 </a> 2088 <div data-name="Mega Menu" class="dropdown-menu o_mega_menu o_no_parent_editor"> 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129<section class="s_mega_menu_menu_image_menu py-4 o_colored_level o_cc o_cc1 pt16 pb24" style="background-image: none;"> 2130 <div class="container"> 2131 <div class="row o_grid_mode" data-row-count="5"> 2132 2133 2134 2135 <div class="py-2 text-center o_colored_level o_grid_item col-lg-3 g-col-lg-3 g-height-5" style="z-index: 3; grid-area: 1 / 10 / 6 / 13;"> 2136 <p style="text-align: left;"><span class="h5-fs"><strong>Â ENTDECKE</strong></span></p><nav class="nav flex-column"> 2137 <a href="/shop/category/sports-ileve-active-lifestyle-8" class="nav-link" data-name="Menu Item" data-bs-original-title="" title="" style="text-align: left;">ILEVE ACTIVE LIFESTYLE</a> 2138 2139 </nav> 2140 </div><div class="py-2 text-center o_colored_level o_grid_item o_grid_item_image g-col-lg-3 col-lg-3 g-height-4 d-lg-block d-none o_snippet_mobile_invisible" style="z-index: 2; --grid-item-padding-y: 0px; grid-area: 2 / 1 / 6 / 4;" data-invisible="1"><a href="/shop/category/sports-ileve-active-lifestyle-8" data-bs-original-title="" title=""><img src="/web/image/21441-d0f2e737/Kollektion-SPORT-liegend.webp?access_token=aadecccb-ee04-4fee-978b-a91ad413c774" alt="" class="img-fluid img o_we_custom_image" data-mimetype="image/webp" data-original-id="19014" data-original-src="/web/image/19014-ba5e705a/Kollektion-SPORT-liegend.jpg" data-mimetype-before-conversion="image/jpeg" data-resize-width="1230" loading="lazy"></a></div><div class="o_grid_item o_colored_level g-height-1 g-col-lg-2 col-lg-2 d-lg-block d-none o_snippet_mobile_invisible" style="grid-area: 1 / 1 / 2 / 3; z-index: 4; --grid-item-padding-y: 0px; --grid-item-padding-x: 0px;" data-invisible="1"><h4><a class="o_translate_inline btn btn-custom" href="/shop/category/sports-7" style="border-width: 1px; border-style: solid;" data-bs-original-title="" title=""><span class="h3-fs">SPORTBRILLEN</span></a></h4></div><div class="o_grid_item g-col-lg-4 o_colored_level g-height-1 col-lg-4 d-lg-block d-none o_snippet_mobile_invisible" style="z-index: 5; grid-area: 5 / 1 / 6 / 5; --grid-item-padding-y: 20px; --grid-item-padding-x: 20px;" data-invisible="1"><p><a class="o_translate_inline" href="/shop/category/sports-ileve-active-lifestyle-8" data-bs-original-title="" title="">ILEVE ACTIVE LIFESTYLE</a></p></div></div> 2141 </div> 2142 </section></div> 2143 2144 </li> 2145 <li role="presentation" class="nav-item h-100 border-start o_border_contrast dropdown position-static"> 2146 <a data-bs-toggle="dropdown" href="#" role="menuitem" class="nav-link d-flex align-items-center h-100 dropdown-toggle o_mega_menu_toggle " data-bs-display="static">
2147 <span>EXPLORE</span> 2148 </a> 2149 <div data-name="Mega Menu" class="dropdown-menu o_mega_menu o_no_parent_editor"> 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294<section class="s_mega_menu_odoo_menu o_colored_level o_cc o_cc1 pt16 pb24" style="background-image: none;"> 2295 <div class="container"> 2296 <div class="row o_grid_mode" data-row-count="5"> 2297 2298 2299 2300 2301 <div class="o_grid_item o_grid_item_image o_colored_level g-col-lg-3 g-height-4 col-lg-3 o_animate_in_dropdown order-lg-0" style="z-index: 2; grid-area: 2 / 1 / 6 / 4; --grid-item-padding-y: 0px; order: 2;"><a href="/shop/category/optical-6" data-bs-original-title="" title=""><img src="/web/image/20864-370fb615/Kollektion-LINEARS-liegend.webp" alt="" class="img img-fluid mx-auto o_we_custom_image" style="width: 100% !important;" data-mimetype="image/webp" data-original-id="19020" data-original-src="/web/image/19020-de701cfb/Kollektion-LINEARS-liegend.jpg" data-mimetype-before-conversion="image/jpeg" data-resize-width="908" loading="lazy"></a></div><div class="o_colored_level o_grid_item g-col-lg-3 order-lg-0 g-height-1 col-lg-3 o_animate_in_dropdown" style="z-index: 3; grid-area: 5 / 1 / 6 / 4; --grid-item-padding-y: 20px; --grid-item-padding-x: 20px; order: 3;"> 2302 <p class="text-uppercase fw-bold mt-0"><span class="lead"><span class="base-fs"><a href="/shop/category/optical-6" data-bs-original-title="" title="">OPTICAL</a></span></span></p> 2303 </div><div class="o_grid_item o_grid_item_image o_colored_level g-col-lg-3 g-height-4 col-lg-3 order-lg-0" style="z-index: 6; --grid-item-padding-y: 0px; grid-area: 2 / 4 / 6 / 7; order: 4;"><a data-bs-original-title="" title="" href="/shop/category/sports-7"><img src="/web/image/20863-6c9e6916/Kollektion-SPORT-liegend.webp?access_token=0c928a2f-ffb4-4bb1-b829-093de31e85d0" alt="" class="img img-fluid mx-auto o_we_custom_image" data-mimetype="image/webp" data-original-id="20862" data-original-src="/web/image/20862-ba5e705a/Kollektion-SPORT-liegend.jpg" data-mimetype-before-conversion="image/jpeg" data-resize-width="908" loading="lazy"></a></div><div class="o_grid_item o_colored_level g-height-1 g-col-lg-3 col-lg-3 order-lg-0" style="z-index: 7; --grid-item-padding-y: 20px; --grid-item-padding-x: 20px; grid-area: 5 / 4 / 6 / 7; order: 5;"><p><span class="base-fs"><span class="lead"><span class="base-fs"><a title="" data-bs-original-title="" href="/shop/category/sports-7">SPORTS</a></span></span></span></p></div><div class="o_grid_item g-col-lg-4 o_colored_level g-height-1 col-lg-4 order-lg-0" style="grid-area: 1 / 1 / 2 / 5; z-index: 8; --grid-item-padding-y: 0px; --grid-item-padding-x: 0px; order: 1;"><p><a class="o_translate_inline btn btn-custom" href="/shop" style="border-style: solid; border-width: 0px;" data-bs-original-title="" title=""><span class="h3-fs">KOLLEKTIONEN</span></a></p></div><div class="o_colored_level o_grid_item g-col-lg-3 o_animate_in_dropdown order-lg-0 g-height-5 col-lg-3" style="z-index: 4; grid-area: 1 / 10 / 6 / 13; order: 0;"> 2304 <p class="text-uppercase fw-bold mt-0" style="text-align: left;"><span style="font-size: 1.125rem;">Ãber uns</span></p><nav class="nav flex-column"><a href="/design" class="nav-link px-0" data-name="Menu Item" data-bs-original-title="" title="" style="text-align: left;"><span style="font-size: 1rem;">DESIGN PRINZIPIEN</span></a><a href="/tragekomfort" class="nav-link px-0" data-name="Menu Item" data-bs-original-title="" title="" style="text-align: left;"><span style="font-size: 1rem;">TRAGEKOMFORT</span></a> 2305 <a href="/material" class="nav-link px-0" data-name="Menu Item" data-bs-original-title="" title="" style="text-align: left;"><span style="font-size: 1rem;">MATERIAL</span></a><a href="/made-in-switzerland" class="nav-link px-0" data-name="Menu Item" data-bs-original-title="" title="" style="text-align: left;"><span style="font-size: 1rem;">MADE IN SWITZERLAND</span></a><a href="/lars-who" class="nav-link px-0" data-name="Menu Item" data-bs-original-title="" title="" style="text-align: left;"><span style="font-size: 1rem;">LARS WHO?<br><br></span></a> 2306 2307 </nav> 2308 </div></div> 2309 </div> 2310 2311 </section></div> 2312 2313 </li> 2314 <li role="presentation" class="nav-item h-100 border-start o_border_contrast"> 2315 <a role="menuitem" href="/stores" class="nav-link d-flex align-items-center h-100 active">
2316 <span>STORE FINDER</span> 2317 </a> 2318 </li> 2319 2320 </ul> 2321 2322 <ul class="o_header_stretch_elts navbar-nav flex-shrink-0"> 2323 2324 2325 2326 2327 2328 <li class="border-start o_border_contrast divider d-none"></li> 2329 <li class="o_wsale_my_cart border-start o_border_contrast"> 2330 <a href="/shop/cart" aria-label="E-Commerce-Warenkorb" class="o_navlink_background_hover btn position-relative d-flex align-items-center h-100 rounded-0 p-2 text-reset"> 2331 <div class=""> 2332 <i class="fa fa-shopping-cart fa-stack"></i> 2333 <sup class="my_cart_quantity badge text-bg-primary rounded d-none" data-order-id="">0</sup> 2334 </div> 2335 </a> 2336 </li> 2337 2338 2339 <li data-name="Language Selector" class="o_header_language_selector "> 2340 2341 <div class="js_language_selector h-100 border-start o_border_contrast dropdown d-print-none"> 2342 <button type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="true" class="btn border-0 dropdown-toggle o_navlink_background_hover h-100 rounded-0 text-reset"> 2343 <span class="align-middle small"> Deutsch (CH)</span> 2344 </button> 2345 <div role="menu" class="dropdown-menu dropdown-menu-end"> 2346 <a class="dropdown-item js_change_lang " role="menuitem" href="/fr_CH/stores" data-url_code="fr_CH" title=" Français (CH)"> 2347 <span class="small"> Français (CH)</span> 2348 </a> 2349 <a class="dropdown-item js_change_lang active" role="menuitem" href="/stores" data-url_code="de_CH" title=" Deutsch (CH)"> 2350 <span class="small"> Deutsch (CH)</span> 2351 </a> 2352 </div> 2353 </div> 2354 2355 </li> 2356 2357 <li class="border-start o_border_contrast o_no_autohide_item"> 2358 <a href="/web/login" class="o_navlink_background_hover btn d-flex align-items-center h-100 rounded-0 fw-bold text-reset">Anmelden</a> 2359 </li> 2360 2361 2362 2363 2364 </ul> 2365 </div> 2366 2367 </nav> 2368 <nav data-name="Navbar" aria-label="Mobile" class="navbar navbar-light o_colored_level o_cc o_header_mobile d-block d-lg-none shadow-sm px-0 "> 2369 2370 2371 <div class="o_main_nav container flex-wrap justify-content-between"> 2372 2373 <a data-name="Navbar Logo" href="/" class="navbar-brand logo "> 2374 2375 <span role="img" aria-label="Logo of LARS Brillen" title="LARS Brillen"><img src="/web/image/website/1/logo/LARS%20Brillen?unique=c9e8819" class="img img-fluid" width="95" height="40" alt="LARS Brillen" loading="lazy"/></span> 2376 </a> 2377 2378 <ul class="o_header_mobile_buttons_wrap navbar-nav flex-row align-items-center gap-2 mb-0"> 2379 2380 <li class=" divider d-none"></li> 2381 <li class="o_wsale_my_cart "> 2382 <a href="/shop/cart" aria-label="E-Commerce-Warenkorb" class="o_navlink_background_hover btn position-relative rounded-circle border-0 p-1 text-reset"> 2383 <div class=""> 2384 <i class="fa fa-shopping-cart fa-stack"></i> 2385 <sup class="my_cart_quantity badge text-bg-primary position-absolute top-0 end-0 mt-n1 me-n1 rounded-pill d-none" data-order-id="">0</sup> 2386 </div> 2387 </a> 2388 </li> 2389 2390 <li class="o_not_editable"> 2391 <button class="nav-link btn me-auto p-2 o_not_editable" type="button" data-bs-toggle="offcanvas" data-bs-target="#top_menu_collapse_mobile" aria-controls="top_menu_collapse_mobile" aria-expanded="false" aria-label="Navigation an/aus"> 2392 <span class="navbar-toggler-icon"></span> 2393 </button> 2394 </li> 2395 </ul> 2396 <div id="top_menu_collapse_mobile" class="offcanvas offcanvas-end o_navbar_mobile"> 2397 <div class="offcanvas-header justify-content-end o_not_editable"> 2398 <button type="button" class="nav-link btn-close" data-bs-dismiss="offcanvas" aria-label="SchlieÃen"></button> 2399 </div> 2400 <div class="offcanvas-body d-flex flex-column justify-content-between h-100 w-100"> 2401 <ul class="navbar-nav"> 2402 2403 2404 2405 <ul role="menu" class="nav navbar-nav top_menu text-end"> 2406 2407 2408 2409 <li role="presentation" class="nav-item dropdown position-static"> 2410 <a data-bs-toggle="dropdown" href="#" role="menuitem" class="nav-link dropdown-toggle o_mega_menu_toggle " data-bs-display="static">
2411 <span>OPTICAL</span> 2412 </a> 2413 2414 </li> 2415 <li role="presentation" class="nav-item dropdown position-static"> 2416 <a data-bs-toggle="dropdown" href="#" role="menuitem" class="nav-link dropdown-toggle o_mega_menu_toggle " data-bs-display="static"> 2417 <span>SPORTS</span> 2418 </a> 2419 2420 </li> 2421 <li role="presentation" class="nav-item dropdown position-static"> 2422 <a data-bs-toggle="dropdown" href="#" role="menuitem" class="nav-link dropdown-toggle o_mega_menu_toggle " data-bs-display="static"> 2423 <span>EXPLORE</span> 2424 </a> 2425 2426 </li> 2427 <li role="presentation" class="nav-item"> 2428 <a role="menuitem" href="/stores" class="nav-link active"> 2429 <span>STORE FINDER</span> 2430 </a> 2431 </li> 2432 2433 </ul> 2434 2435 2436 </ul> 2437 <ul class="navbar-nav gap-2 mt-3 w-100"> 2438 2439 <li class=" o_no_autohide_item"> 2440 <a href="/web/login" class="btn btn-outline-secondary w-100">Anmelden</a> 2441 </li> 2442 2443 2444 2445 2446 <li data-name="Language Selector" class="o_header_language_selector "> 2447 2448 <div class="js_language_selector dropup dropdown d-print-none"> 2449 <button type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="true" class="btn border-0 dropdown-toggle btn-outline-secondary d-flex align-items-center w-100 px-2"> 2450 <span class="align-middle me-auto small"> Deutsch (CH)</span> 2451 </button> 2452 <div role="menu" class="dropdown-menu w-100"> 2453 <a class="dropdown-item js_change_lang " role="menuitem" href="/fr_CH/stores" data-url_code="fr_CH" title=" Français (CH)"> 2454 <span class="me-auto small"> Français (CH)</span> 2455 </a> 2456 <a class="dropdown-item js_change_lang active" role="menuitem" href="/stores" data-url_code="de_CH" title=" Deutsch (CH)"> 2457 <span class="me-auto small"> Deutsch (CH)</span> 2458 </a> 2459 </div> 2460 </div> 2461 2462 </li> 2463 2464 </ul> 2465 </div> 2466 </div> 2467 </div> 2468 2469 </nav> 2470 2471 </header> 2472 <main> 2473 2474 <div id="wrap" class="oe_structure oe_empty"><section class="s_title pb40 o_colored_level pt72" data-vcss="001" data-snippet="s_title" data-name="Titel" style="background-image: none;"> 2475 <div class="s_allow_columns container"> 2476 <h2 style="text-align: left;">LARS ERLEBEN - UNSERE PARTNER</h2> 2477 </div> 2478 </section><section class="s_text_block pb40 o_colored_level pt0" data-snippet="s_text_block" data-name="Text" style="background-image: none;"> 2479 <div class="s_allow_columns container"> 2480 <p class="lead">Unsere Korrektur- und Sportbrillen gibtâs bei ausgewählten Fachoptikern. Schau vorbei und erlebe das unbeschwerte Tragegefühl in deiner Nähe.</p> 2481 </div> 2482 </section><section class="s_embed_code pb64 o_colored_level text-center pt0" data-snippet="s_embed_code" data-name="Code einbetten" style="background-image: none;"><template class="s_embed_code_saved"> 2483<link href="https://unpkg.com/[email protected]/dist/maplibre-gl.css" rel="stylesheet"/>
2484<script src="https://unpkg.com/[email protected]/dist/maplibre-gl.js"></script>
vendor: 1 bytes, line 2484
2484
2485<script src="https://cdn.jsdelivr.net/npm/[email protected]/papaparse.min.js"></script>
2485 2486<style> 2487@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap'); 2488 2489.partner-layout { 2490 display: flex; 2491 flex-direction: row; 2492 width: 100vw; 2493 margin-left: calc(50% - 50vw); 2494 margin-right: calc(50% - 50vw); 2495 height: min(75vh, 900px); 2496 min-height: 520px; 2497 font-family: 'Inter', system-ui, -apple-system, sans-serif; 2498 border-top: 1px solid #111; 2499} 2500.fullwidth-map { 2501 flex: 1 1 50%; 2502 min-width: 0; 2503 height: 100%; 2504} 2505.partner-list-wrap { 2506 flex: 0 0 340px; 2507 width: 340px; 2508 height: 100%; 2509 background: #fff; 2510 border-left: 1px solid #111; 2511 display: flex; 2512 flex-direction: column; 2513 overflow: hidden; 2514} 2515.partner-list-top { 2516 flex-shrink: 0; 2517 background: #fff; 2518 border-bottom: 1px solid #111; 2519} 2520.partner-list-title { 2521 padding: 16px 16px 12px; 2522 font-size: 13px; 2523 font-weight: 700; 2524 color: #111; 2525 letter-spacing: 0.1em; 2526 font-family: 'Inter', system-ui, -apple-system, sans-serif; 2527} 2528.partner-list-rule { 2529 height: 1px; 2530 background: #111; 2531 margin: 0 16px; 2532} 2533.partner-list-header { 2534 padding: 14px 16px 8px; 2535 font-size: 11px; 2536 font-weight: 700; 2537 color: #111; 2538 letter-spacing: 0.08em; 2539 text-transform: uppercase; 2540 font-family: 'Inter', system-ui, -apple-system, sans-serif; 2541} 2542.partner-alpha-nav { 2543 display: flex; 2544 flex-wrap: wrap; 2545 gap: 2px; 2546 padding: 0 12px 10px; 2547} 2548.partner-alpha-btn { 2549 width: 24px; 2550 height: 24px; 2551 display: flex; 2552 align-items: center; 2553 justify-content: center; 2554 font-size: 11px; 2555 font-weight: 700; 2556 color: #fff; 2557 background: #111; 2558 border: 1px solid #fff; 2559 border-radius: 0; 2560 cursor: pointer; 2561 font-family: 'Inter', system-ui, -apple-system, sans-serif; 2562 transition: background 0.12s, color 0.12s; 2563} 2564.partner-alpha-btn:hover { background: #fff; color: #111; } 2565.partner-alpha-btn.active { background: #fff; color: #111; } 2566.partner-list-scroll { 2567 flex: 1; 2568 overflow-y: auto; 2569} 2570.partner-list { 2571 list-style: none; 2572 margin: 0; 2573 padding: 0; 2574} 2575.partner-letter-header { 2576 padding: 8px 16px 4px; 2577 font-size: 11px; 2578 font-weight: 700; 2579 color: #111; 2580 letter-spacing: 0.1em; 2581 text-transform: uppercase; 2582 background: #f5f5f5; 2583 border-bottom: 1px solid #111; 2584 border-top: 1px solid #111; 2585 font-family: 'Inter', system-ui, -apple-system, sans-serif; 2586} 2587.partner-search-wrap { 2588 padding: 8px 12px; 2589 border-bottom: 1px solid #111; 2590} 2591.partner-search-input { 2592 width: 100%; 2593 box-sizing: border-box; 2594 border: 1px solid #111; 2595 border-radius: 0; 2596 padding: 7px 10px; 2597 font-size: 12px; 2598 font-family: 'Inter', system-ui, -apple-system, sans-serif; 2599 color: #111; 2600 outline: none; 2601 background: #fff; 2602} 2603.partner-search-input:focus { 2604 background: #f5f5f5; 2605} 2606.partner-city-header { 2607 padding: 7px 16px 5px; 2608 font-size: 11px; 2609 font-weight: 700; 2610 color: #111; 2611 background: #f5f5f5; 2612 border-bottom: 1px solid #e0e0e0; 2613 border-top: 1px solid #e0e0e0; 2614 letter-spacing: 0.04em; 2615 font-family: 'Inter', system-ui, -apple-system, sans-serif; 2616} 2617.partner-list-item { 2618 padding: 8px 16px 8px 24px; 2619 border-bottom: 1px solid #e8e8e8; 2620 cursor: pointer; 2621 transition: background 0.12s; 2622 text-align: left; 2623} 2624.partner-list-item:hover { background: #f5f5f5; } 2625.partner-list-item.active { background: #f5f5f5; border-left: 2px solid #111; padding-left: 22px; } 2626.partner-list-name { 2627 font-weight: 600; 2628 font-size: 13px; 2629 color: #111; 2630 margin-bottom: 2px; 2631 white-space: nowrap; 2632 overflow: hidden; 2633 text-overflow: ellipsis; 2634 font-family: 'Inter', system-ui, -apple-system, sans-serif; 2635} 2636.partner-list-tags { 2637 font-size: 11px; 2638 font-weight: 700; 2639 color: #111; 2640 letter-spacing: 0.04em; 2641 line-height: 1.4; 2642 margin-bottom: 2px; 2643 font-family: 'Inter', system-ui, -apple-system, sans-serif; 2644} 2645.partner-list-website { 2646 font-size: 11px; 2647 color: #888; 2648 font-family: 'Inter', system-ui, -apple-system, sans-serif; 2649} 2650.partner-plz-wrap { 2651 padding: 8px 12px; 2652 border-bottom: 1px solid #111; 2653} 2654.partner-plz-row { 2655 display: flex; 2656 gap: 4px; 2657 margin-bottom: 6px; 2658} 2659.partner-plz-row .partner-search-input { 2660 flex: 1; 2661 margin: 0; 2662} 2663.partner-plz-btn, 2664.partner-loc-btn { 2665 width: 34px; 2666 height: 34px; 2667 flex-shrink: 0; 2668 background: #fff; 2669 border: 1px solid #111; 2670 border-radius: 0; 2671 font-size: 16px; 2672 cursor: pointer; 2673 display: flex; 2674 align-items: center; 2675 justify-content: center; 2676 font-family: 'Inter', system-ui, -apple-system, sans-serif; 2677 color: #111; 2678 transition: background 0.12s; 2679} 2680.partner-plz-btn:hover, 2681.partner-loc-btn:hover { 2682 background: #111; 2683 color: #fff; 2684} 2685#partner-plz-results { 2686 margin-top: 4px; 2687 border: 1px solid #111; 2688 background: #fff; 2689 max-height: 200px; 2690 overflow-y: auto; 2691} 2692.partner-plz-result-item { 2693 padding: 7px 12px; 2694 font-size: 12px; 2695 font-family: 'Inter', system-ui, -apple-system, sans-serif; 2696 color: #111; 2697 cursor: pointer; 2698 border-bottom: 1px solid #e8e8e8; 2699 text-align: left; 2700} 2701.partner-plz-result-item:last-child { border-bottom: none; } 2702.partner-plz-result-item:hover { background: #f5f5f5; } 2703.partner-radius-row { 2704 display: flex; 2705 align-items: center; 2706 gap: 8px; 2707} 2708.partner-radius-label { 2709 font-size: 11px; 2710 font-weight: 700; 2711 color: rgba(0,0,0,0.75); 2712 letter-spacing: 0.06em; 2713 font-family: 'Inter', system-ui, -apple-system, sans-serif; 2714} 2715.partner-radius-select { 2716 flex: 1; 2717 border: 1px solid #111; 2718 border-radius: 0; 2719 padding: 4px 8px; 2720 font-size: 12px; 2721 font-family: 'Inter', system-ui, -apple-system, sans-serif; 2722 color: #111; 2723 background: #fff; 2724 outline: none; 2725} 2726body { overflow-x: hidden; } 2727.marker-with-letter { 2728 background: transparent !important; 2729 border: none !important; 2730 width: 34px; 2731 height: 34px; 2732} 2733.marker-with-letter .marker-glyph { 2734 width: 34px; 2735 height: 34px; 2736 display: block; 2737 pointer-events: none; 2738} 2739.maplibregl-popup-content { 2740 text-align: left !important; 2741 padding: 0 !important; 2742 border-radius: 0 !important; 2743 overflow: hidden !important; 2744 box-shadow: none !important; 2745 border: 1px solid #111 !important; 2746 font-family: 'Inter', system-ui, -apple-system, sans-serif !important; 2747} 2748.maplibregl-popup-tip { display: none !important; } 2749.maplibregl-popup-close-button { 2750 font-size: 18px !important; 2751 color: #888 !important; 2752 padding: 6px 10px !important; 2753 top: 4px !important; 2754 right: 4px !important; 2755 z-index: 10; 2756 line-height: 1; 2757 border: none !important; 2758 outline: none !important; 2759 box-shadow: none !important; 2760 background: none !important; 2761 font-family: 'Inter', system-ui, -apple-system, sans-serif !important; 2762} 2763.maplibregl-popup-close-button:hover { color: #111 !important; background: none !important; } 2764.maplibregl-popup-close-button:focus { outline: none !important; box-shadow: none !important; border: none !important; } 2765.maplibregl-ctrl button, .maplibregl-ctrl-attrib { 2766 font-family: 'Inter', system-ui, -apple-system, sans-serif !important; 2767} 2768@media (max-width: 768px) { 2769 .partner-layout { 2770 flex-direction: column; 2771 height: auto; 2772 min-height: unset; 2773 } 2774 .fullwidth-map { 2775 height: min(55vh, 500px); 2776 min-height: 300px; 2777 flex: none; 2778 width: 100%; 2779 } 2780 .partner-list-wrap { 2781 flex: none; 2782 width: 100%; 2783 height: 480px; 2784 border-left: none; 2785 border-top: 1px solid #111; 2786 } 2787} 2788</style> 2789<div class="partner-layout"> 2790 <div id="partner-map" class="fullwidth-map"></div> 2791 <div class="partner-list-wrap"> 2792 <div class="partner-list-top"> 2793 <div class="partner-list-title">FINDE DEINEN OPTIKER</div> 2794 <div class="partner-list-rule"></div> 2795 <div class="partner-plz-wrap"> 2796 <div class="partner-plz-row"> 2797 <input class="partner-search-input" id="partner-plz" type="text" placeholder="PLZ eingeben..." maxlength="10"/> 2798 <button class="partner-plz-btn" id="partner-plz-btn">âµ</button> 2799 <button class="partner-loc-btn" id="partner-loc-btn" title="Me
2799inen Standort verwenden">â</button> 2800 </div> 2801 <div id="partner-plz-results" style="display:none;"></div> 2802 <div class="partner-radius-row"> 2803 <span class="partner-radius-label">Umkreis</span> 2804 <select class="partner-radius-select" id="partner-radius"> 2805 <option value="10">10 km</option> 2806 <option value="25" selected="selected">25 km</option> 2807 <option value="50">50 km</option> 2808 <option value="100">100 km</option> 2809 <option value="">Alle</option> 2810 </select> 2811 </div> 2812 </div> 2813 <div class="partner-list-header">Ortschaften</div> 2814 <div class="partner-alpha-nav" id="partner-alpha-nav"></div> 2815 <div class="partner-search-wrap"> 2816 <input class="partner-search-input" id="partner-search" type="text" placeholder="Ort oder Optiker suchen..."/> 2817 </div> 2818 </div> 2819 <div class="partner-list-scroll" id="partner-list-scroll"> 2820 <ul class="partner-list" id="partner-list"></ul> 2821 </div> 2822 </div> 2823</div>
2824<script> 2825document.addEventListener("DOMContentLoaded", async function() { 2826 2827 // === SPRACHUMSCHALTUNG (nur fuer die Kartentexte) =================== 2828 var LANG = document.documentElement.lang.startsWith('fr') ? 'fr' : 'de'; 2829 2830 var T = LANG === 'fr' ? { 2831 findTitle: "TROUVEZ VOTRE OPTICIEN", 2832 plzPlaceholder: "Saisir le NPA...", 2833 locBtnTitle: "Utiliser ma position", 2834 radiusLabel: "Rayon", 2835 radiusAll: "Tous", 2836 ortschaften: "Localités", 2837 searchPlaceholder: "Rechercher une localité ou un opticien...", 2838 telefon: "Téléphone", 2839 website: "Site web", 2840 termin: "Rendez-vous", 2841 terminBuchen: "Réserver un rendez-vous", 2842 kollektionen: "Collections", 2843 plzNichtGefunden: "NPA introuvable", 2844 standortFehler: "Impossible de déterminer la position. Veuillez saisir le NPA." 2845 } : { 2846 findTitle: "FINDE DEINEN OPTIKER", 2847 plzPlaceholder: "PLZ eingeben...", 2848 locBtnTitle: "Meinen Standort verwenden", 2849 radiusLabel: "Umkreis", 2850 radiusAll: "Alle", 2851 ortschaften: "Ortschaften", 2852 searchPlaceholder: "Ort oder Optiker suchen...", 2853 telefon: "Telefon", 2854 website: "Website", 2855 termin: "Termin", 2856 terminBuchen: "Termin buchen", 2857 kollektionen: "Kollektionen", 2858 plzNichtGefunden: "PLZ nicht gefunden", 2859 standortFehler: "Standort konnte nicht ermittelt werden. Bitte PLZ eingeben." 2860 }; 2861 2862 document.querySelector(".partner-list-title").textContent = T.findTitle; 2863 document.querySelector(".partner-radius-label").textContent = T.radiusLabel; 2864 document.querySelector(".partner-list-header").textContent = T.ortschaften; 2865 document.getElementById("partner-plz").placeholder = T.plzPlaceholder; 2866 document.getElementById("partner-search").placeholder = T.searchPlaceholder; 2867 document.getElementById("partner-loc-btn").title = T.locBtnTitle; 2868 document.querySelector("#partner-radius option[value='']").textContent = T.radiusAll; 2869 // ====================================================================== 2870 2871 // === KOLLEKTIONEN ===================================================== 2872 // Liste aller gültigen Kollektionen, die im CSV Export als Stichwort 2873 // vorkommen können. Um eine neue Kollektion aufzunehmen, einfach einen 2874 // weiteren Text in dieses Array einfügen. Gross und Kleinschreibung 2875 // spielt keine Rolle, im Popup erscheint der Text genau so wie hier 2876 // eingetragen. 2877 var VALID_COLLECTION_TAGS = ["LARS OPTICAL", "LARS SPORTS"]; 2878 // ======================================================================= 2879 2880 var CSV_URL = "/document/download/3/09856935-b647-4f19-a1ea-78667fc03e75/46?ts=" + Date.now(); 2881
2882 var MAPTILER_KEY = "6kT2zPOU8mZHhmFY86dZ"; 2883 var MAPTILER_MAP_ID = "019be65a-0108-7f33-b1b7-4cbcd40e2b18"; 2884 var STYLE_URL = "https://api.maptiler.com/maps/" + MAPTILER_MAP_ID + "/style.json?key=" + MAPTILER_KEY; 2885 2886 var FALLBACK_STYLE = { 2887 version: 8, 2888 sources: { 2889 carto_base: { type: "raster", tileSize: 256, 2890 attribution: "\u00a9 OpenStreetMap contributors \u00a9 CARTO", 2891 tiles: ["https://a.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png","https://b.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png","https://c.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png","https://d.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png"]}, 2892 carto_labels: { type: "raster", tileSize: 256, 2893 attribution: "\u00a9 OpenStreetMap contributors \u00a9 CARTO", 2894 tiles: ["https://a.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}{r}.png","https://b.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}{r}.png","https://c.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}{r}.png","https://d.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}{r}.png"]} 2895 }, 2896 layers: [{ id: "base", type: "raster", source: "carto_base" },{ id: "labels", type: "raster", source: "carto_labels" }] 2897 }; 2898 2899 var resolvedStyle = FALLBACK_STYLE; 2900 try { 2901 var res = await fetch(STYLE_URL, { cache: "no-store" }); 2902 if (!res.ok) throw new Error("HTTP " + res.status); 2903 resolvedStyle = await res.json(); 2904 } catch(e) { console.warn("MapTiler fallback", e); } 2905 2906 var map = new maplibregl.Map({ 2907 container: "partner-map", 2908 style: resolvedStyle, 2909 center: [8.3, 46.8], 2910 zoom: 7, 2911 attributionControl: true 2912 }); 2913 map.addControl(new maplibregl.NavigationControl({ showCompass: false }), "top-left"); 2914 await new Promise(function(resolve){ map.once("load", resolve); }); 2915 2916 var geolocated = false; 2917 2918 if (navigator.geolocation) { 2919 navigator.geolocation.getCurrentPosition(function(pos) { 2920 geolocated = true; 2921 map.flyTo({ 2922 center: [pos.coords.longitude, pos.coords.latitude], 2923 zoom: 11, 2924 duration: 1200 2925 }); 2926 }, function(err) { 2927 console.log("Standort nicht verfügbar", err); 2928 }, { 2929 maximumAge: 0, 2930 timeout: 5000,
2931 enableHighAccuracy: false 2932 }); 2933 } 2934 2935 var csvText = await fetch(CSV_URL, { cache: "no-store" }).then(function(resp){ return resp.text(); }); 2936 var parsed = Papa.parse(csvText, { header: true, skipEmptyLines: true }); 2937 var rows = parsed.data; 2938 2939 // Odoo exportiert Mehrfachfelder (Stichwörter) mit einer eigenen Zeile pro 2940 // Wert: Firmenname/Koordinaten stehen nur in der ersten Zeile, danach folgen 2941 // Zeilen mit leerem Namen und je einem weiteren Stichwort. Hier werden diese 2942 // Folgezeilen der vorherigen Firma zugeordnet, statt sie zu verwerfen. 2943 var mergedRows = []; 2944 var currentRow = null; 2945 rows.forEach(function(r) { 2946 var name = (r["Name des Unternehmens"] || "").toString().trim(); 2947 if (name) { 2948 currentRow = r; 2949 currentRow.__extraTags = []; 2950 mergedRows.push(currentRow); 2951 } else if (currentRow) { 2952 var tagVal = (r["Stichwörter"] || r["Tags"] || r["Keywords"] || "").toString().trim(); 2953 if (tagVal) currentRow.__extraTags.push(tagVal); 2954 } 2955 }); 2956 rows = mergedRows; 2957 2958 function cleanStr(v) { return (v != null ? v : "").toString().replace(/^'/, "").trim(); } 2959 function normalizePhone(v) { 2960 var s = cleanStr(v); 2961 if (!s) return { display: "", href: "" }; 2962 return { display: s, href: s.replace(/\s+/g, "").replace(/[^0-9+]/g, "") }; 2963 } 2964 function normalizeWebsite(v) { 2965 var s = cleanStr(v); 2966 if (!s) return ""; 2967 if (!/^https?:\/\//i.test(s)) s = "https://" + s; 2968 return s; 2969 } 2970 function prettyLabel(url) { 2971 var s = normalizeWebsite(url); 2972 if (!s) return ""; 2973 try { return new URL(s).hostname.replace(/^www\./i, ""); } 2974 catch(e) { return s.replace(/^https?:\/\//i,"").replace(/^www\./i,""); } 2975 } 2976 function getAddrLines(val, name) { 2977 var s = cleanStr(val); 2978 if (!s) return []; 2979 var lines = s.split(/\r?\n/).map(function(l){ return l.trim(); }).filter(Boolean); 2980 if (lines.length && lines[0].toLowerCase() === name.toLowerCase()) lines.shift(); 2981 return lines; 2982 } 2983 function pick(row, keys) { 2984 var found = ""; 2985 keys.forEach(function(k){ if (k in row && !found) found = row[k]; }); 2986 return found; 2987 } 2988 2989 function getCollectionTags(val) { 2990 var raw = cleanStr(val); 2991 if (!raw) return []; 2992 var parts = raw.split(",").map(function(p){ return p.trim().toUpperCase(); }); 2993 var seen = {}; 2994 var result = []; 2995 parts.forEach(function(p) { 2996 if (VALID_COLLECTION_TAGS.indexOf(p) !== -1 && !seen[p]) { 2997 seen[p] = true; 2998 result.push(p); 2999 } 3000 }); 3001 return result; 3002 } 3003 3004 function makeMarkerEl() { 3005 var el = document.createElement("div"); 3006 el.className = "marker-with-letter"; 3007 var NS = "http://www.w3.org/2000/svg"; 3008 var svg = document.createElementNS(NS, "svg"); 3009 svg.setAttribute("class","marker-glyph"); 3010 svg.setAttribute("viewBox","0 0 28 28"); 3011 svg.setAttribute("aria-hidden","true"); 3012 svg.setAttribute("shape-rendering","geometricPrecision"); 3013 var outerRing = document.createElementNS(NS, "circle"); 3014 outerRing.setAttribute("cx", "14"); 3015 outerRing.setAttribute("cy", "14"); 3016 outerRing.setAttribute("r", "14.5"); 3017 outerRing.setAttribute("fill", "#ffffff"); 3018 var circle = document.createElementNS(NS, "circle"); 3019 circle.setAttribute("cx", "14"); 3020 circle.setAttribute("cy", "14"); 3021 circle.setAttribute("r", "12"); 3022 circle.setAttribute("fill", "#000000"); 3023 var path = document.createElementNS(NS,"path"); 3024 path.setAttribute("d","M7 26 L13 6 L15 6 L21 26"); 3025 path.setAttribute("fill","none"); 3026 path.setAttribute("stroke","#ffffff"); 3027 path.setAttribute("stroke-width","2.4"); 3028 path.setAttribute("stroke-linejoin","round"); 3029 path.setAttribute("stroke-linecap","round"); 3030 svg.appendChild(outerRing); 3031 svg.appendChild(circle); 3032 svg.appendChild(path); 3033 el.appendChild(svg); 3034 return el; 3035} 3036 3037 function makePopupEl(name, phone, website, websiteLabel, termin, addrLines, collectionTags) { 3038 var wrap = document.createElement("div"); 3039 wrap.style.cssText = "min-width:240px;max-width:320px;font-family:'Inter',system-ui,-apple-system,sans-serif;overflow:hidden;text-align:left;"; 3040 var body = document.createElement("div"); 3041 body.style.cssText = "padding:14px 36px 16px 16px;background:#fff;"; 3042 wrap.appendChild(body); 3043 var nameEl = document.createElement("div"); 3044 nameEl.style.cssText = "font-weight:700;font-size:15px;color:#111;margin-bottom:12px;letter-spacing:-0.01em;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 3045 nameEl.textContent = name; 3046 body.appendChild(nameEl); 3047 if (phone.display) { 3048 var row = document.createElement("div"); 3049 row.style.cssText = "display:flex;align-items:center;gap:8px;margin-bottom:8px;"; 3050 var lbl = document.createElement("span"); 3051 lbl.style.cssText = "font-size:13px;color:rgba(0,0,0,0.75);font-weight:400;min-width:60px;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 3052 lbl.textContent = T.telefon; 3053 var a = document.createElement("a"); 3054 a.href = "tel:" + phone.href; 3055 a.style.cssText = "font-size:13px;color:#111;text-decoration:none;font-weight:600;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 3056 a.textContent = phone.display; 3057 row.appendChild(lbl); row.appendChild(a); body.appendChild(row); 3058 } 3059 if (website) { 3060 var row2 = document.createElement("div"); 3061 row2.style.cssText = "display:flex;align-items:center;gap:8px;margin-bottom:8px;"; 3062 var lbl2 = document.createElement("span"); 3063 lbl2.style.cssText = "font-size:13px;color:rgba(0,0,0,0.75);font-weight:400;min-width:60px;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 3064 lbl2.textContent = T.website; 3065 var a2 = document.createElement("a"); 3066 a2.href = website; a2.target = "_blank"; a2.rel = "noopener"; 3067 a2.style.cssText = "font-size:13px;color:#111;text-decoration:none;font-weight:600;word-break:break-word;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 3068 a2.textContent = websiteLabel || website; 3069 row2.appendChild(lbl2);
3069 row2.appendChild(a2); body.appendChild(row2); 3070 } 3071 if (termin) { 3072 var row3 = document.createElement("div"); 3073 row3.style.cssText = "display:flex;align-items:center;gap:8px;margin-bottom:8px;"; 3074 var lbl3 = document.createElement("span"); 3075 lbl3.style.cssText = "font-size:13px;color:rgba(0,0,0,0.75);font-weight:400;min-width:60px;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 3076 lbl3.textContent = T.termin; 3077 var a3 = document.createElement("a"); 3078 a3.href = termin; a3.target = "_blank"; a3.rel = "noopener"; 3079 a3.style.cssText = "font-size:13px;color:#111;text-decoration:none;font-weight:600;word-break:break-word;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 3080 a3.textContent = T.terminBuchen; 3081 row3.appendChild(lbl3); row3.appendChild(a3); body.appendChild(row3); 3082 } 3083 if (addrLines.length) { 3084 var hr = document.createElement("div"); 3085 hr.style.cssText = "height:1px;background:#f0f0f0;margin:10px 0;"; 3086 body.appendChild(hr); 3087 var addr = document.createElement("div"); 3088 addr.style.cssText = "font-size:12px;color:rgba(0,0,0,0.75);font-weight:400;line-height:1.6;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 3089 addrLines.forEach(function(line, idx) { 3090 if (idx > 0) addr.appendChild(document.createElement("br")); 3091 addr.appendChild(document.createTextNode(line)); 3092 }); 3093 body.appendChild(addr); 3094 } 3095 if (collectionTags && collectionTags.length) { 3096 var hr2 = document.createElement("div"); 3097 hr2.style.cssText = "height:1px;background:#f0f0f0;margin:10px 0;"; 3098 body.appendChild(hr2); 3099 var collLabel = document.createElement("div"); 3100 collLabel.style.cssText = "font-size:12px;color:rgba(0,0,0,0.75);font-weight:400;margin-bottom:2px;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 3101 collLabel.textContent = T.kollektionen + ":"; 3102 body.appendChild(collLabel); 3103 var collVal = document.createElement("div"); 3104 collVal.style.cssText = "font-size:12px;color:#111;font-weight:600;line-height:1.6;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 3105 collectionTags.forEach(function(tag, idx) { 3106 if (idx > 0) collVal.appendChild(document.createElement("br")); 3107 collVal.appendChild(document.createTextNode(tag)); 3108 }); 3109 body.appendChild(collVal); 3110 } 3111 return wrap; 3112 } 3113 3114 var bounds = []; 3115 3116 rows.sort(function(a, b) { 3117 var ca = cleanStr(pick(a, ["Stadt","City"])).toLowerCase(); 3118 var cb = cleanStr(pick(b, ["Stadt","City"])).toLowerCase(); 3119 var cmp = ca.localeCompare(cb, LANG); 3120 if (cmp !== 0) return cmp; 3121 var na = cleanStr(pick(a, ["Name des Unternehmens"])).toLowerCase(); 3122 var nb = cleanStr(pick(b, ["Name des Unternehmens"])).toLowerCase(); 3123 return na.localeCompare(nb, LANG); 3124 }); 3125 3126 var listEl = document.getElementById("partner-list"); 3127 var scrollEl = document.getElementById("partner-list-scroll"); 3128 var alphaNav = document.getElementById("partner-alpha-nav"); 3129 var currentLetter = ""; 3130 var currentCity = ""; 3131 var letterElements = {}; 3132 3133 rows.forEach(function(r) { 3134 var lat = parseFloat(pick(r, ["Geo-Breitengrad"])); 3135 var lon = parseFloat(pick(r, ["Geo-Längengrad"])); 3136 if (isNaN(lat) || isNaN(lon)) return; 3137 3138 var name = (pick(r, ["Name des Unternehmens"]) || "Partner").toString(); 3139 var city = cleanStr(pick(r, ["Stadt","City"])) || "\u2013"; 3140 var phone = normalizePhone(pick(r, ["Telefon","Phone","telephone"])); 3141 var websiteVal = pick(r, ["Website-Link","Website","website"]); 3142 var website = normalizeWebsite(websiteVal); 3143 var websiteLabel = prettyLabel(websiteVal); 3144 var termin = normalizeWebsite(pick(r, ["Termin","Termin-URL","x_studio_terminurl"])); 3145 var addrLines = getAddrLines(pick(r, ["Vollständige Adresse","Adresse","Address"]), name); 3146 var ownTags = pick(r, ["Stichwörter", "Tags", "Keywords"]); 3147 var allTagsRaw = [ownTags].concat(r.__extraTags || []).filter(Boolean).join(", "); 3148 var collectionTags = getCollectionTags(allTagsRaw); 3149 3150 bounds.push([lat, lon]); 3151 3152 var el = makeMarkerEl(); 3153 var popupEl = makePopupEl(name, phone, website, websiteLabel, termin, addrLines, collectionTags); 3154 var popup = new maplibregl.Popup({ offset: 25, maxWidth: "320px", closeButton: true }) 3155 .setDOMContent(popupEl); 3156 var marker = new maplibregl.Marker({ element: el, anchor: "top" }) 3157 .setLngLat([lon, lat]) 3158 .setPopup(popup) 3159 .addTo(map); 3160 3161 var letter = city.charAt(0).toUpperCase(); 3162 if (letter !== currentLetter) { 3163 currentLetter = letter; 3164 currentCity = ""; 3165 var letterEl = document.createElement("li"); 3166 letterEl.className = "partner-letter-header"; 3167 letterEl.setAttribute("data-letter", letter); 3168 letterEl.textContent = letter; 3169 listEl.appendChild(letterEl); 3170 letterElements[letter] = letterEl; 3171 } 3172 3173 if (city !== currentCity) { 3174 currentCity = city; 3175 var cityEl = document.createElement("li"); 3176 cityEl.className = "partner-city-header"; 3177 cityEl.textContent = city; 3178 listEl.appendChild(cityEl); 3179 } 3180 3181 var li = document.createElement("li"); 3182 li.className = "partner-list-item"; 3183 li.dataset.lat = lat; 3184 li.dataset.lon = lon; 3185 3186 var nameDiv = document.createElement("div"); 3187 nameDiv.className = "partner-list-name"; 3188 nameDiv.textContent = name; 3189 li.appendChild(nameDiv); 3190 3191 if (websiteLabel) { 3192 var webDiv = document.createElement("div"); 3193 webDiv.className = "partner-list-website"; 3194 webDiv.textContent = websiteLabel; 3195 li.appendChild(webDiv); 3196 } 3197 3198 li.addEventListener("click", function() { 3199 listEl.querySelectorAll(".partner-list-item").forEach(function(item){ item.classList.remove("active"); }); 3200 li.classList.add("active");
3201 map.flyTo({ center: [lon, lat], zoom: 15, duration: 800 }); 3202 setTimeout(function(){ marker.togglePopup(); }, 850); 3203 }); 3204 3205 popup.on("close", function() { 3206 li.classList.remove("active"); 3207 }); 3208 3209 listEl.appendChild(li); 3210 }); 3211 3212 // Suchfeld-Logik 3213 var searchInput = document.getElementById("partner-search"); 3214 if (searchInput) { 3215 searchInput.addEventListener("input", function() { 3216 var q = searchInput.value.toLowerCase().trim(); 3217 var items = listEl.querySelectorAll(".partner-list-item"); 3218 var cityHeaders = listEl.querySelectorAll(".partner-city-header"); 3219 var letterHeaders = listEl.querySelectorAll(".partner-letter-header"); 3220 if (!q) { 3221 items.forEach(function(el) { el.style.display = ""; }); 3222 cityHeaders.forEach(function(el) { el.style.display = ""; }); 3223 letterHeaders.forEach(function(el) { el.style.display = ""; }); 3224 return; 3225 } 3226 letterHeaders.forEach(function(el) { el.style.display = "none"; }); 3227 cityHeaders.forEach(function(cityEl) { 3228 var cityName = cityEl.textContent.toLowerCase(); 3229 var cityMatch = cityName.indexOf(q) !== -1; 3230 var siblings = []; 3231 var next = cityEl.nextElementSibling; 3232 while (next && next.classList.contains("partner-list-item")) { 3233 siblings.push(next); 3234 next = next.nextElementSibling; 3235 } 3236 var anyVisible = cityMatch; 3237 siblings.forEach(function(item) { 3238 var name = item.querySelector(".partner-list-name"); 3239 var web = item.querySelector(".partner-list-website"); 3240 var nameMatch = name && name.textContent.toLowerCase().indexOf(q) !== -1; 3241 var webMatch = web && web.textContent.toLowerCase().indexOf(q) !== -1; 3242 var show = cityMatch || nameMatch || webMatch; 3243 item.style.display = show ? "" : "none"; 3244 if (show) anyVisible = true; 3245 }); 3246 cityEl.style.display = anyVisible ? "" : "none"; 3247 }); 3248 }); 3249 } 3250 3251 // PLZ + Umkreis Logik 3252 function haversineKm(lat1, lon1, lat2, lon2) { 3253 var R = 6371; 3254 var dLat = (lat2 - lat1) * Math.PI / 180; 3255 var dLon = (lon2 - lon1) * Math.PI / 180; 3256 var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 3257 Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * 3258 Math.sin(dLon/2) * Math.sin(dLon/2); 3259 return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 3260 } 3261 3262 function filterByRadius(centerLat, centerLon, radiusKm) { 3263 var items = listEl.querySelectorAll(".partner-list-item"); 3264 var cityHeaders = listEl.querySelectorAll(".partner-city-header"); 3265 var letterHeaders = listEl.querySelectorAll(".partner-letter-header"); 3266 if (!radiusKm) { 3267 items.forEach(function(el) { el.style.display = ""; }); 3268 cityHeaders.forEach(function(el) { el.style.display = ""; }); 3269 letterHeaders.forEach(function(el) { el.style.display = ""; }); 3270 return; 3271 } 3272 letterHeaders.forEach(function(el) { el.style.display = "none"; }); 3273 cityHeaders.forEach(function(cityEl) { 3274 var anyVisible = false; 3275 var siblings = []; 3276 var next = cityEl.nextElementSibling; 3277 while (next && next.classList.contains("partner-list-item")) { 3278 siblings.push(next); 3279 next = next.nextElementSibling; 3280 } 3281 siblings.forEach(function(item) { 3282 var lat = parseFloat(item.dataset.lat); 3283 var lon = parseFloat(item.dataset.lon); 3284 var dist = haversineKm(centerLat, centerLon, lat, lon); 3285 var show = dist <= radiusKm; 3286 item.style.display = show ? "" : "none"; 3287 if (show) anyVisible = true; 3288 }); 3289 cityEl.style.display = anyVisible ? "" : "none"; 3290 }); 3291 } 3292 3293 function applyRadiusFromCenter(centerLat, centerLon) { 3294 var radiusKm = parseInt(document.getElementById("partner-radius").value) || 0; 3295 filterByRadius(centerLat, centerLon, radiusKm); 3296 map.flyTo({ center: [centerLon, centerLat], zoom: radiusKm <= 25 ? 11 : 9, duration: 1000 }); 3297 } 3298 3299document.getElementById("partner-plz-btn").addEventListener("click", function() { 3300 var plz = document.getElementById("partner-plz").value.trim(); 3301 if (!plz) return; 3302 var resultsEl = document.getElementById("partner-plz-results"); 3303 resultsEl.innerHTML = ""; 3304 resultsEl.style.display = "none"; 3305 3306 var EU = "ad,al,at,ba,be,bg,by,cy,cz,de,dk,ee,es,fi,fr,gb,gr,hr,hu,ie,is,it,li,lt,lu,lv,mc,md,me,mk,mt,nl,no,pl,pt,ro,rs,ru,se,si,sk,sm,ua,xk"; 3307 var results = []; 3308 3309 function showResults() { 3310 if (!results.length) { alert(T.plzNichtGefunden); return; } 3311 if (results.length === 1) { 3312 applyRadiusFromCenter(results[0].lat, results[0].lon); 3313 return; 3314 }
3315 results.forEach(function(item) { 3316 var div = document.createElement("div"); 3317 div.className = "partner-plz-result-item"; 3318 div.textContent = item.label; 3319 div.addEventListener("click", function() { 3320 resultsEl.style.display = "none"; 3321 applyRadiusFromCenter(item.lat, item.lon); 3322 }); 3323 resultsEl.appendChild(div); 3324 }); 3325 resultsEl.style.display = "block"; 3326 } 3327 3328 var chFetch = fetch("https://api3.geo.admin.ch/rest/services/api/SearchServer?searchText=" + encodeURIComponent(plz) + "&type=locations&origins=zipcode&limit=5") 3329 .then(function(r) { return r.json(); }) 3330 .then(function(data) { 3331 if (data.results) { 3332 data.results.forEach(function(item) { 3333 results.push({ 3334 lat: item.attrs.lat, 3335 lon: item.attrs.lon, 3336 label: item.attrs.label.replace(/<[^>]+>/g, "") + " (CH)" 3337 }); 3338 }); 3339 } 3340 }).catch(function() {}); 3341 3342 var euFetch = fetch("https://nominatim.openstreetmap.org/search?format=json&limit=5&countrycodes=" + EU + "&postalcode=" + encodeURIComponent(plz)) 3343 .then(function(r) { return r.json(); }) 3344 .then(function(data) { 3345 data.forEach(function(item) { 3346 results.push({ 3347 lat: parseFloat(item.lat), 3348 lon: parseFloat(item.lon), 3349 label: item.display_name 3350 }); 3351 }); 3352 }).catch(function() {}); 3353 3354 Promise.all([chFetch, euFetch]).then(showResults); 3355}); 3356 document.getElementById("partner-plz").addEventListener("keydown", function(e) { 3357 if (e.key === "Enter") document.getElementById("partner-plz-btn").click(); 3358 }); 3359 3360document.getElementById("partner-loc-btn").addEventListener("click", function() { 3361 if (!navigator.geolocation) return; 3362 navigator.geolocation.getCurrentPosition(function(pos) { 3363 geolocated = true; 3364 applyRadiusFromCenter(pos.coords.latitude, pos.coords.longitude); 3365 }, function(err) { 3366 console.log("Standort nicht verfügbar", err); 3367 alert(T.standortFehler); 3368 }, { 3369 maximumAge: 60000, 3370 timeout: 30000,
3371 enableHighAccuracy: false 3372 }); 3373}); 3374 3375 document.getElementById("partner-radius").addEventListener("change", function() { 3376 var plz = document.getElementById("partner-plz").value.trim(); 3377 if (plz) document.getElementById("partner-plz-btn").click(); 3378 }); 3379 3380 Object.keys(letterElements).sort().forEach(function(letter) { 3381 var btn = document.createElement("button"); 3382 btn.className = "partner-alpha-btn"; 3383 btn.textContent = letter; 3384 btn.addEventListener("click", function() { 3385 alphaNav.querySelectorAll(".partner-alpha-btn").forEach(function(b){ b.classList.remove("active"); }); 3386 btn.classList.add("active"); 3387 var target = letterElements[letter]; 3388 if (target) { 3389 var topBar = document.getElementById("partner-list-top") || document.querySelector(".partner-list-top"); 3390 var offset = topBar ? topBar.offsetHeight : 0; 3391 scrollEl.scrollTo({ top: target.offsetTop - offset, behavior: "smooth" }); 3392 } 3393 }); 3394 alphaNav.appendChild(btn); 3395 }); 3396 3397 if (bounds.length) { 3398 var lats = bounds.map(function(b){ return b[0]; }); 3399 var lons2 = bounds.map(function(b){ return b[1]; }); 3400 setTimeout(function() { 3401 if (!geolocated) { 3402 map.fitBounds( 3403 [[Math.min.apply(null,lons2), Math.min.apply(null,lats)], [Math.max.apply(null,lons2), Math.max.apply(null,lats)]], 3404 { padding: 30 } 3405 ); 3406 } 3407 }, 6000); 3408 } 3409}); 3410</script>
3410 3411</template><div class="s_embed_code_embedded container o_not_editable"><link href="https://unpkg.com/[email protected]/dist/maplibre-gl.css" rel="stylesheet"/>
3412<script src="https://unpkg.com/[email protected]/dist/maplibre-gl.js"></script>
vendor: 1 bytes, line 3412
3412
3413<script src="https://cdn.jsdelivr.net/npm/[email protected]/papaparse.min.js"></script>
3413 3414<style> 3415@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap'); 3416 3417.partner-layout { 3418 display: flex; 3419 flex-direction: row; 3420 width: 100vw; 3421 margin-left: calc(50% - 50vw); 3422 margin-right: calc(50% - 50vw); 3423 height: min(75vh, 900px); 3424 min-height: 520px; 3425 font-family: 'Inter', system-ui, -apple-system, sans-serif; 3426 border-top: 1px solid #111; 3427} 3428.fullwidth-map { 3429 flex: 1 1 50%; 3430 min-width: 0; 3431 height: 100%; 3432} 3433.partner-list-wrap { 3434 flex: 0 0 340px; 3435 width: 340px; 3436 height: 100%; 3437 background: #fff; 3438 border-left: 1px solid #111; 3439 display: flex; 3440 flex-direction: column; 3441 overflow: hidden; 3442} 3443.partner-list-top { 3444 flex-shrink: 0; 3445 background: #fff; 3446 border-bottom: 1px solid #111; 3447} 3448.partner-list-title { 3449 padding: 16px 16px 12px; 3450 font-size: 13px; 3451 font-weight: 700; 3452 color: #111; 3453 letter-spacing: 0.1em; 3454 font-family: 'Inter', system-ui, -apple-system, sans-serif; 3455} 3456.partner-list-rule { 3457 height: 1px; 3458 background: #111; 3459 margin: 0 16px; 3460} 3461.partner-list-header { 3462 padding: 14px 16px 8px; 3463 font-size: 11px; 3464 font-weight: 700; 3465 color: #111; 3466 letter-spacing: 0.08em; 3467 text-transform: uppercase; 3468 font-family: 'Inter', system-ui, -apple-system, sans-serif; 3469} 3470.partner-alpha-nav { 3471 display: flex; 3472 flex-wrap: wrap; 3473 gap: 2px; 3474 padding: 0 12px 10px; 3475} 3476.partner-alpha-btn { 3477 width: 24px; 3478 height: 24px; 3479 display: flex; 3480 align-items: center; 3481 justify-content: center; 3482 font-size: 11px; 3483 font-weight: 700; 3484 color: #fff; 3485 background: #111; 3486 border: 1px solid #fff; 3487 border-radius: 0; 3488 cursor: pointer; 3489 font-family: 'Inter', system-ui, -apple-system, sans-serif; 3490 transition: background 0.12s, color 0.12s; 3491} 3492.partner-alpha-btn:hover { background: #fff; color: #111; } 3493.partner-alpha-btn.active { background: #fff; color: #111; } 3494.partner-list-scroll { 3495 flex: 1; 3496 overflow-y: auto; 3497} 3498.partner-list { 3499 list-style: none; 3500 margin: 0; 3501 padding: 0; 3502} 3503.partner-letter-header { 3504 padding: 8px 16px 4px; 3505 font-size: 11px; 3506 font-weight: 700; 3507 color: #111; 3508 letter-spacing: 0.1em; 3509 text-transform: uppercase; 3510 background: #f5f5f5; 3511 border-bottom: 1px solid #111; 3512 border-top: 1px solid #111; 3513 font-family: 'Inter', system-ui, -apple-system, sans-serif; 3514} 3515.partner-search-wrap { 3516 padding: 8px 12px; 3517 border-bottom: 1px solid #111; 3518} 3519.partner-search-input { 3520 width: 100%; 3521 box-sizing: border-box; 3522 border: 1px solid #111; 3523 border-radius: 0; 3524 padding: 7px 10px; 3525 font-size: 12px; 3526 font-family: 'Inter', system-ui, -apple-system, sans-serif; 3527 color: #111; 3528 outline: none; 3529 background: #fff; 3530} 3531.partner-search-input:focus { 3532 background: #f5f5f5; 3533} 3534.partner-city-header { 3535 padding: 7px 16px 5px; 3536 font-size: 11px; 3537 font-weight: 700; 3538 color: #111; 3539 background: #f5f5f5; 3540 border-bottom: 1px solid #e0e0e0; 3541 border-top: 1px solid #e0e0e0; 3542 letter-spacing: 0.04em; 3543 font-family: 'Inter', system-ui, -apple-system, sans-serif; 3544} 3545.partner-list-item { 3546 padding: 8px 16px 8px 24px; 3547 border-bottom: 1px solid #e8e8e8; 3548 cursor: pointer; 3549 transition: background 0.12s; 3550 text-align: left; 3551} 3552.partner-list-item:hover { background: #f5f5f5; } 3553.partner-list-item.active { background: #f5f5f5; border-left: 2px solid #111; padding-left: 22px; } 3554.partner-list-name { 3555 font-weight: 600; 3556 font-size: 13px; 3557 color: #111; 3558 margin-bottom: 2px; 3559 white-space: nowrap; 3560 overflow: hidden; 3561 text-overflow: ellipsis; 3562 font-family: 'Inter', system-ui, -apple-system, sans-serif; 3563} 3564.partner-list-tags { 3565 font-size: 11px; 3566 font-weight: 700; 3567 color: #111; 3568 letter-spacing: 0.04em; 3569 line-height: 1.4; 3570 margin-bottom: 2px; 3571 font-family: 'Inter', system-ui, -apple-system, sans-serif; 3572} 3573.partner-list-website { 3574 font-size: 11px; 3575 color: #888; 3576 font-family: 'Inter', system-ui, -apple-system, sans-serif; 3577} 3578.partner-plz-wrap { 3579 padding: 8px 12px; 3580 border-bottom: 1px solid #111; 3581} 3582.partner-plz-row { 3583 display: flex; 3584 gap: 4px; 3585 margin-bottom: 6px; 3586} 3587.partner-plz-row .partner-search-input { 3588 flex: 1; 3589 margin: 0; 3590} 3591.partner-plz-btn, 3592.partner-loc-btn { 3593 width: 34px; 3594 height: 34px; 3595 flex-shrink: 0; 3596 background: #fff; 3597 border: 1px solid #111; 3598 border-radius: 0; 3599 font-size: 16px; 3600 cursor: pointer; 3601 display: flex; 3602 align-items: center; 3603 justify-content: center; 3604 font-family: 'Inter', system-ui, -apple-system, sans-serif; 3605 color: #111; 3606 transition: background 0.12s; 3607} 3608.partner-plz-btn:hover, 3609.partner-loc-btn:hover { 3610 background: #111; 3611 color: #fff; 3612} 3613#partner-plz-results { 3614 margin-top: 4px; 3615 border: 1px solid #111; 3616 background: #fff; 3617 max-height: 200px; 3618 overflow-y: auto; 3619} 3620.partner-plz-result-item { 3621 padding: 7px 12px; 3622 font-size: 12px; 3623 font-family: 'Inter', system-ui, -apple-system, sans-serif; 3624 color: #111; 3625 cursor: pointer; 3626 border-bottom: 1px solid #e8e8e8; 3627 text-align: left; 3628} 3629.partner-plz-result-item:last-child { border-bottom: none; } 3630.partner-plz-result-item:hover { background: #f5f5f5; } 3631.partner-radius-row { 3632 display: flex; 3633 align-items: center; 3634 gap: 8px; 3635} 3636.partner-radius-label { 3637 font-size: 11px; 3638 font-weight: 700; 3639 color: rgba(0,0,0,0.75); 3640 letter-spacing: 0.06em; 3641 font-family: 'Inter', system-ui, -apple-system, sans-serif; 3642} 3643.partner-radius-select { 3644 flex: 1; 3645 border: 1px solid #111; 3646 border-radius: 0; 3647 padding: 4px 8px; 3648 font-size: 12px; 3649 font-family: 'Inter', system-ui, -apple-system, sans-serif; 3650 color: #111; 3651 background: #fff; 3652 outline: none; 3653} 3654body { overflow-x: hidden; } 3655.marker-with-letter { 3656 background: transparent !important; 3657 border: none !important; 3658 width: 34px; 3659 height: 34px; 3660} 3661.marker-with-letter .marker-glyph { 3662 width: 34px; 3663 height: 34px; 3664 display: block; 3665 pointer-events: none; 3666} 3667.maplibregl-popup-content { 3668 text-align: left !important; 3669 padding: 0 !important; 3670 border-radius: 0 !important; 3671 overflow: hidden !important; 3672 box-shadow: none !important; 3673 border: 1px solid #111 !important; 3674 font-family: 'Inter', system-ui, -apple-system, sans-serif !important; 3675} 3676.maplibregl-popup-tip { display: none !important; } 3677.maplibregl-popup-close-button { 3678 font-size: 18px !important; 3679 color: #888 !important; 3680 padding: 6px 10px !important; 3681 top: 4px !important; 3682 right: 4px !important; 3683 z-index: 10; 3684 line-height: 1; 3685 border: none !important; 3686 outline: none !important; 3687 box-shadow: none !important; 3688 background: none !important; 3689 font-family: 'Inter', system-ui, -apple-system, sans-serif !important; 3690} 3691.maplibregl-popup-close-button:hover { color: #111 !important; background: none !important; } 3692.maplibregl-popup-close-button:focus { outline: none !important; box-shadow: none !important; border: none !important; } 3693.maplibregl-ctrl button, .maplibregl-ctrl-attrib { 3694 font-family: 'Inter', system-ui, -apple-system, sans-serif !important; 3695} 3696@media (max-width: 768px) { 3697 .partner-layout { 3698 flex-direction: column; 3699 height: auto; 3700 min-height: unset; 3701 } 3702 .fullwidth-map { 3703 height: min(55vh, 500px); 3704 min-height: 300px; 3705 flex: none; 3706 width: 100%; 3707 } 3708 .partner-list-wrap { 3709 flex: none; 3710 width: 100%; 3711 height: 480px; 3712 border-left: none; 3713 border-top: 1px solid #111; 3714 } 3715} 3716</style> 3717<div class="partner-layout"> 3718 <div id="partner-map" class="fullwidth-map"></div> 3719 <div class="partner-list-wrap"> 3720 <div class="partner-list-top"> 3721 <div class="partner-list-title">FINDE DEINEN OPTIKER</div> 3722 <div class="partner-list-rule"></div> 3723 <div class="partner-plz-wrap"> 3724 <div class="partner-plz-row"> 3725 <input class="partner-search-input" id="partner-plz" type="text" placeholder="PLZ eingeben..." maxlength="10"/> 3726 <button class="partner-plz-btn" id="partner-plz-btn">âµ</button> 3727 <button class="partner-loc-btn" id="partner-loc-btn" title="Me
3727inen Standort verwenden">â</button> 3728 </div> 3729 <div id="partner-plz-results" style="display:none;"></div> 3730 <div class="partner-radius-row"> 3731 <span class="partner-radius-label">Umkreis</span> 3732 <select class="partner-radius-select" id="partner-radius"> 3733 <option value="10">10 km</option> 3734 <option value="25" selected="selected">25 km</option> 3735 <option value="50">50 km</option> 3736 <option value="100">100 km</option> 3737 <option value="">Alle</option> 3738 </select> 3739 </div> 3740 </div> 3741 <div class="partner-list-header">Ortschaften</div> 3742 <div class="partner-alpha-nav" id="partner-alpha-nav"></div> 3743 <div class="partner-search-wrap"> 3744 <input class="partner-search-input" id="partner-search" type="text" placeholder="Ort oder Optiker suchen..."/> 3745 </div> 3746 </div> 3747 <div class="partner-list-scroll" id="partner-list-scroll"> 3748 <ul class="partner-list" id="partner-list"></ul> 3749 </div> 3750 </div> 3751</div>
3752<script> 3753document.addEventListener("DOMContentLoaded", async function() { 3754 3755 // === SPRACHUMSCHALTUNG (nur fuer die Kartentexte) =================== 3756 var LANG = document.documentElement.lang.startsWith('fr') ? 'fr' : 'de'; 3757 3758 var T = LANG === 'fr' ? { 3759 findTitle: "TROUVEZ VOTRE OPTICIEN", 3760 plzPlaceholder: "Saisir le NPA...", 3761 locBtnTitle: "Utiliser ma position", 3762 radiusLabel: "Rayon", 3763 radiusAll: "Tous", 3764 ortschaften: "Localités", 3765 searchPlaceholder: "Rechercher une localité ou un opticien...", 3766 telefon: "Téléphone", 3767 website: "Site web", 3768 termin: "Rendez-vous", 3769 terminBuchen: "Réserver un rendez-vous", 3770 kollektionen: "Collections", 3771 plzNichtGefunden: "NPA introuvable", 3772 standortFehler: "Impossible de déterminer la position. Veuillez saisir le NPA." 3773 } : { 3774 findTitle: "FINDE DEINEN OPTIKER", 3775 plzPlaceholder: "PLZ eingeben...", 3776 locBtnTitle: "Meinen Standort verwenden", 3777 radiusLabel: "Umkreis", 3778 radiusAll: "Alle", 3779 ortschaften: "Ortschaften", 3780 searchPlaceholder: "Ort oder Optiker suchen...", 3781 telefon: "Telefon", 3782 website: "Website", 3783 termin: "Termin", 3784 terminBuchen: "Termin buchen", 3785 kollektionen: "Kollektionen", 3786 plzNichtGefunden: "PLZ nicht gefunden", 3787 standortFehler: "Standort konnte nicht ermittelt werden. Bitte PLZ eingeben." 3788 }; 3789 3790 document.querySelector(".partner-list-title").textContent = T.findTitle; 3791 document.querySelector(".partner-radius-label").textContent = T.radiusLabel; 3792 document.querySelector(".partner-list-header").textContent = T.ortschaften; 3793 document.getElementById("partner-plz").placeholder = T.plzPlaceholder; 3794 document.getElementById("partner-search").placeholder = T.searchPlaceholder; 3795 document.getElementById("partner-loc-btn").title = T.locBtnTitle; 3796 document.querySelector("#partner-radius option[value='']").textContent = T.radiusAll; 3797 // ====================================================================== 3798 3799 // === KOLLEKTIONEN ===================================================== 3800 // Liste aller gültigen Kollektionen, die im CSV Export als Stichwort 3801 // vorkommen können. Um eine neue Kollektion aufzunehmen, einfach einen 3802 // weiteren Text in dieses Array einfügen. Gross und Kleinschreibung 3803 // spielt keine Rolle, im Popup erscheint der Text genau so wie hier 3804 // eingetragen. 3805 var VALID_COLLECTION_TAGS = ["LARS OPTICAL", "LARS SPORTS"]; 3806 // ======================================================================= 3807 3808 var CSV_URL = "/document/download/3/09856935-b647-4f19-a1ea-78667fc03e75/46?ts=" + Date.now(); 3809
3810 var MAPTILER_KEY = "6kT2zPOU8mZHhmFY86dZ"; 3811 var MAPTILER_MAP_ID = "019be65a-0108-7f33-b1b7-4cbcd40e2b18"; 3812 var STYLE_URL = "https://api.maptiler.com/maps/" + MAPTILER_MAP_ID + "/style.json?key=" + MAPTILER_KEY; 3813 3814 var FALLBACK_STYLE = { 3815 version: 8, 3816 sources: { 3817 carto_base: { type: "raster", tileSize: 256, 3818 attribution: "\u00a9 OpenStreetMap contributors \u00a9 CARTO", 3819 tiles: ["https://a.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png","https://b.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png","https://c.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png","https://d.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png"]}, 3820 carto_labels: { type: "raster", tileSize: 256, 3821 attribution: "\u00a9 OpenStreetMap contributors \u00a9 CARTO", 3822 tiles: ["https://a.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}{r}.png","https://b.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}{r}.png","https://c.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}{r}.png","https://d.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}{r}.png"]} 3823 }, 3824 layers: [{ id: "base", type: "raster", source: "carto_base" },{ id: "labels", type: "raster", source: "carto_labels" }] 3825 }; 3826 3827 var resolvedStyle = FALLBACK_STYLE; 3828 try { 3829 var res = await fetch(STYLE_URL, { cache: "no-store" }); 3830 if (!res.ok) throw new Error("HTTP " + res.status); 3831 resolvedStyle = await res.json(); 3832 } catch(e) { console.warn("MapTiler fallback", e); } 3833 3834 var map = new maplibregl.Map({ 3835 container: "partner-map", 3836 style: resolvedStyle, 3837 center: [8.3, 46.8], 3838 zoom: 7, 3839 attributionControl: true 3840 }); 3841 map.addControl(new maplibregl.NavigationControl({ showCompass: false }), "top-left"); 3842 await new Promise(function(resolve){ map.once("load", resolve); }); 3843 3844 var geolocated = false; 3845 3846 if (navigator.geolocation) { 3847 navigator.geolocation.getCurrentPosition(function(pos) { 3848 geolocated = true; 3849 map.flyTo({ 3850 center: [pos.coords.longitude, pos.coords.latitude], 3851 zoom: 11, 3852 duration: 1200 3853 }); 3854 }, function(err) { 3855 console.log("Standort nicht verfügbar", err); 3856 }, { 3857 maximumAge: 0, 3858 timeout: 5000,
3859 enableHighAccuracy: false 3860 }); 3861 } 3862 3863 var csvText = await fetch(CSV_URL, { cache: "no-store" }).then(function(resp){ return resp.text(); }); 3864 var parsed = Papa.parse(csvText, { header: true, skipEmptyLines: true }); 3865 var rows = parsed.data; 3866 3867 // Odoo exportiert Mehrfachfelder (Stichwörter) mit einer eigenen Zeile pro 3868 // Wert: Firmenname/Koordinaten stehen nur in der ersten Zeile, danach folgen 3869 // Zeilen mit leerem Namen und je einem weiteren Stichwort. Hier werden diese 3870 // Folgezeilen der vorherigen Firma zugeordnet, statt sie zu verwerfen. 3871 var mergedRows = []; 3872 var currentRow = null; 3873 rows.forEach(function(r) { 3874 var name = (r["Name des Unternehmens"] || "").toString().trim(); 3875 if (name) { 3876 currentRow = r; 3877 currentRow.__extraTags = []; 3878 mergedRows.push(currentRow); 3879 } else if (currentRow) { 3880 var tagVal = (r["Stichwörter"] || r["Tags"] || r["Keywords"] || "").toString().trim(); 3881 if (tagVal) currentRow.__extraTags.push(tagVal); 3882 } 3883 }); 3884 rows = mergedRows; 3885 3886 function cleanStr(v) { return (v != null ? v : "").toString().replace(/^'/, "").trim(); } 3887 function normalizePhone(v) { 3888 var s = cleanStr(v); 3889 if (!s) return { display: "", href: "" }; 3890 return { display: s, href: s.replace(/\s+/g, "").replace(/[^0-9+]/g, "") }; 3891 } 3892 function normalizeWebsite(v) { 3893 var s = cleanStr(v); 3894 if (!s) return ""; 3895 if (!/^https?:\/\//i.test(s)) s = "https://" + s; 3896 return s; 3897 } 3898 function prettyLabel(url) { 3899 var s = normalizeWebsite(url); 3900 if (!s) return ""; 3901 try { return new URL(s).hostname.replace(/^www\./i, ""); } 3902 catch(e) { return s.replace(/^https?:\/\//i,"").replace(/^www\./i,""); } 3903 } 3904 function getAddrLines(val, name) { 3905 var s = cleanStr(val); 3906 if (!s) return []; 3907 var lines = s.split(/\r?\n/).map(function(l){ return l.trim(); }).filter(Boolean); 3908 if (lines.length && lines[0].toLowerCase() === name.toLowerCase()) lines.shift(); 3909 return lines; 3910 } 3911 function pick(row, keys) { 3912 var found = ""; 3913 keys.forEach(function(k){ if (k in row && !found) found = row[k]; }); 3914 return found; 3915 } 3916 3917 function getCollectionTags(val) { 3918 var raw = cleanStr(val); 3919 if (!raw) return []; 3920 var parts = raw.split(",").map(function(p){ return p.trim().toUpperCase(); }); 3921 var seen = {}; 3922 var result = []; 3923 parts.forEach(function(p) { 3924 if (VALID_COLLECTION_TAGS.indexOf(p) !== -1 && !seen[p]) { 3925 seen[p] = true; 3926 result.push(p); 3927 } 3928 }); 3929 return result; 3930 } 3931 3932 function makeMarkerEl() { 3933 var el = document.createElement("div"); 3934 el.className = "marker-with-letter"; 3935 var NS = "http://www.w3.org/2000/svg"; 3936 var svg = document.createElementNS(NS, "svg"); 3937 svg.setAttribute("class","marker-glyph"); 3938 svg.setAttribute("viewBox","0 0 28 28"); 3939 svg.setAttribute("aria-hidden","true"); 3940 svg.setAttribute("shape-rendering","geometricPrecision"); 3941 var outerRing = document.createElementNS(NS, "circle"); 3942 outerRing.setAttribute("cx", "14"); 3943 outerRing.setAttribute("cy", "14"); 3944 outerRing.setAttribute("r", "14.5"); 3945 outerRing.setAttribute("fill", "#ffffff"); 3946 var circle = document.createElementNS(NS, "circle"); 3947 circle.setAttribute("cx", "14"); 3948 circle.setAttribute("cy", "14"); 3949 circle.setAttribute("r", "12"); 3950 circle.setAttribute("fill", "#000000"); 3951 var path = document.createElementNS(NS,"path"); 3952 path.setAttribute("d","M7 26 L13 6 L15 6 L21 26"); 3953 path.setAttribute("fill","none"); 3954 path.setAttribute("stroke","#ffffff"); 3955 path.setAttribute("stroke-width","2.4"); 3956 path.setAttribute("stroke-linejoin","round"); 3957 path.setAttribute("stroke-linecap","round"); 3958 svg.appendChild(outerRing); 3959 svg.appendChild(circle); 3960 svg.appendChild(path); 3961 el.appendChild(svg); 3962 return el; 3963} 3964 3965 function makePopupEl(name, phone, website, websiteLabel, termin, addrLines, collectionTags) { 3966 var wrap = document.createElement("div"); 3967 wrap.style.cssText = "min-width:240px;max-width:320px;font-family:'Inter',system-ui,-apple-system,sans-serif;overflow:hidden;text-align:left;"; 3968 var body = document.createElement("div"); 3969 body.style.cssText = "padding:14px 36px 16px 16px;background:#fff;"; 3970 wrap.appendChild(body); 3971 var nameEl = document.createElement("div"); 3972 nameEl.style.cssText = "font-weight:700;font-size:15px;color:#111;margin-bottom:12px;letter-spacing:-0.01em;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 3973 nameEl.textContent = name; 3974 body.appendChild(nameEl); 3975 if (phone.display) { 3976 var row = document.createElement("div"); 3977 row.style.cssText = "display:flex;align-items:center;gap:8px;margin-bottom:8px;"; 3978 var lbl = document.createElement("span"); 3979 lbl.style.cssText = "font-size:13px;color:rgba(0,0,0,0.75);font-weight:400;min-width:60px;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 3980 lbl.textContent = T.telefon; 3981 var a = document.createElement("a"); 3982 a.href = "tel:" + phone.href; 3983 a.style.cssText = "font-size:13px;color:#111;text-decoration:none;font-weight:600;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 3984 a.textContent = phone.display; 3985 row.appendChild(lbl); row.appendChild(a); body.appendChild(row); 3986 } 3987 if (website) { 3988 var row2 = document.createElement("div"); 3989 row2.style.cssText = "display:flex;align-items:center;gap:8px;margin-bottom:8px;"; 3990 var lbl2 = document.createElement("span"); 3991 lbl2.style.cssText = "font-size:13px;color:rgba(0,0,0,0.75);font-weight:400;min-width:60px;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 3992 lbl2.textContent = T.website; 3993 var a2 = document.createElement("a"); 3994 a2.href = website; a2.target = "_blank"; a2.rel = "noopener"; 3995 a2.style.cssText = "font-size:13px;color:#111;text-decoration:none;font-weight:600;word-break:break-word;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 3996 a2.textContent = websiteLabel || website; 3997 row2.appendChild(lbl2);
3997 row2.appendChild(a2); body.appendChild(row2); 3998 } 3999 if (termin) { 4000 var row3 = document.createElement("div"); 4001 row3.style.cssText = "display:flex;align-items:center;gap:8px;margin-bottom:8px;"; 4002 var lbl3 = document.createElement("span"); 4003 lbl3.style.cssText = "font-size:13px;color:rgba(0,0,0,0.75);font-weight:400;min-width:60px;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 4004 lbl3.textContent = T.termin; 4005 var a3 = document.createElement("a"); 4006 a3.href = termin; a3.target = "_blank"; a3.rel = "noopener"; 4007 a3.style.cssText = "font-size:13px;color:#111;text-decoration:none;font-weight:600;word-break:break-word;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 4008 a3.textContent = T.terminBuchen; 4009 row3.appendChild(lbl3); row3.appendChild(a3); body.appendChild(row3); 4010 } 4011 if (addrLines.length) { 4012 var hr = document.createElement("div"); 4013 hr.style.cssText = "height:1px;background:#f0f0f0;margin:10px 0;"; 4014 body.appendChild(hr); 4015 var addr = document.createElement("div"); 4016 addr.style.cssText = "font-size:12px;color:rgba(0,0,0,0.75);font-weight:400;line-height:1.6;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 4017 addrLines.forEach(function(line, idx) { 4018 if (idx > 0) addr.appendChild(document.createElement("br")); 4019 addr.appendChild(document.createTextNode(line)); 4020 }); 4021 body.appendChild(addr); 4022 } 4023 if (collectionTags && collectionTags.length) { 4024 var hr2 = document.createElement("div"); 4025 hr2.style.cssText = "height:1px;background:#f0f0f0;margin:10px 0;"; 4026 body.appendChild(hr2); 4027 var collLabel = document.createElement("div"); 4028 collLabel.style.cssText = "font-size:12px;color:rgba(0,0,0,0.75);font-weight:400;margin-bottom:2px;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 4029 collLabel.textContent = T.kollektionen + ":"; 4030 body.appendChild(collLabel); 4031 var collVal = document.createElement("div"); 4032 collVal.style.cssText = "font-size:12px;color:#111;font-weight:600;line-height:1.6;font-family:'Inter',system-ui,-apple-system,sans-serif;"; 4033 collectionTags.forEach(function(tag, idx) { 4034 if (idx > 0) collVal.appendChild(document.createElement("br")); 4035 collVal.appendChild(document.createTextNode(tag)); 4036 }); 4037 body.appendChild(collVal); 4038 } 4039 return wrap; 4040 } 4041 4042 var bounds = []; 4043 4044 rows.sort(function(a, b) { 4045 var ca = cleanStr(pick(a, ["Stadt","City"])).toLowerCase(); 4046 var cb = cleanStr(pick(b, ["Stadt","City"])).toLowerCase(); 4047 var cmp = ca.localeCompare(cb, LANG); 4048 if (cmp !== 0) return cmp; 4049 var na = cleanStr(pick(a, ["Name des Unternehmens"])).toLowerCase(); 4050 var nb = cleanStr(pick(b, ["Name des Unternehmens"])).toLowerCase(); 4051 return na.localeCompare(nb, LANG); 4052 }); 4053 4054 var listEl = document.getElementById("partner-list"); 4055 var scrollEl = document.getElementById("partner-list-scroll"); 4056 var alphaNav = document.getElementById("partner-alpha-nav"); 4057 var currentLetter = ""; 4058 var currentCity = ""; 4059 var letterElements = {}; 4060 4061 rows.forEach(function(r) { 4062 var lat = parseFloat(pick(r, ["Geo-Breitengrad"])); 4063 var lon = parseFloat(pick(r, ["Geo-Längengrad"])); 4064 if (isNaN(lat) || isNaN(lon)) return; 4065 4066 var name = (pick(r, ["Name des Unternehmens"]) || "Partner").toString(); 4067 var city = cleanStr(pick(r, ["Stadt","City"])) || "\u2013"; 4068 var phone = normalizePhone(pick(r, ["Telefon","Phone","telephone"])); 4069 var websiteVal = pick(r, ["Website-Link","Website","website"]); 4070 var website = normalizeWebsite(websiteVal); 4071 var websiteLabel = prettyLabel(websiteVal); 4072 var termin = normalizeWebsite(pick(r, ["Termin","Termin-URL","x_studio_terminurl"])); 4073 var addrLines = getAddrLines(pick(r, ["Vollständige Adresse","Adresse","Address"]), name); 4074 var ownTags = pick(r, ["Stichwörter", "Tags", "Keywords"]); 4075 var allTagsRaw = [ownTags].concat(r.__extraTags || []).filter(Boolean).join(", "); 4076 var collectionTags = getCollectionTags(allTagsRaw); 4077 4078 bounds.push([lat, lon]); 4079 4080 var el = makeMarkerEl(); 4081 var popupEl = makePopupEl(name, phone, website, websiteLabel, termin, addrLines, collectionTags); 4082 var popup = new maplibregl.Popup({ offset: 25, maxWidth: "320px", closeButton: true }) 4083 .setDOMContent(popupEl); 4084 var marker = new maplibregl.Marker({ element: el, anchor: "top" }) 4085 .setLngLat([lon, lat]) 4086 .setPopup(popup) 4087 .addTo(map); 4088 4089 var letter = city.charAt(0).toUpperCase(); 4090 if (letter !== currentLetter) { 4091 currentLetter = letter; 4092 currentCity = ""; 4093 var letterEl = document.createElement("li"); 4094 letterEl.className = "partner-letter-header"; 4095 letterEl.setAttribute("data-letter", letter); 4096 letterEl.textContent = letter; 4097 listEl.appendChild(letterEl); 4098 letterElements[letter] = letterEl; 4099 } 4100 4101 if (city !== currentCity) { 4102 currentCity = city; 4103 var cityEl = document.createElement("li"); 4104 cityEl.className = "partner-city-header"; 4105 cityEl.textContent = city; 4106 listEl.appendChild(cityEl); 4107 } 4108 4109 var li = document.createElement("li"); 4110 li.className = "partner-list-item"; 4111 li.dataset.lat = lat; 4112 li.dataset.lon = lon; 4113 4114 var nameDiv = document.createElement("div"); 4115 nameDiv.className = "partner-list-name"; 4116 nameDiv.textContent = name; 4117 li.appendChild(nameDiv); 4118 4119 if (websiteLabel) { 4120 var webDiv = document.createElement("div"); 4121 webDiv.className = "partner-list-website"; 4122 webDiv.textContent = websiteLabel; 4123 li.appendChild(webDiv); 4124 } 4125 4126 li.addEventListener("click", function() { 4127 listEl.querySelectorAll(".partner-list-item").forEach(function(item){ item.classList.remove("active"); }); 4128 li.classList.add("active");
4129 map.flyTo({ center: [lon, lat], zoom: 15, duration: 800 }); 4130 setTimeout(function(){ marker.togglePopup(); }, 850); 4131 }); 4132 4133 popup.on("close", function() { 4134 li.classList.remove("active"); 4135 }); 4136 4137 listEl.appendChild(li); 4138 }); 4139 4140 // Suchfeld-Logik 4141 var searchInput = document.getElementById("partner-search"); 4142 if (searchInput) { 4143 searchInput.addEventListener("input", function() { 4144 var q = searchInput.value.toLowerCase().trim(); 4145 var items = listEl.querySelectorAll(".partner-list-item"); 4146 var cityHeaders = listEl.querySelectorAll(".partner-city-header"); 4147 var letterHeaders = listEl.querySelectorAll(".partner-letter-header"); 4148 if (!q) { 4149 items.forEach(function(el) { el.style.display = ""; }); 4150 cityHeaders.forEach(function(el) { el.style.display = ""; }); 4151 letterHeaders.forEach(function(el) { el.style.display = ""; }); 4152 return; 4153 } 4154 letterHeaders.forEach(function(el) { el.style.display = "none"; }); 4155 cityHeaders.forEach(function(cityEl) { 4156 var cityName = cityEl.textContent.toLowerCase(); 4157 var cityMatch = cityName.indexOf(q) !== -1; 4158 var siblings = []; 4159 var next = cityEl.nextElementSibling; 4160 while (next && next.classList.contains("partner-list-item")) { 4161 siblings.push(next); 4162 next = next.nextElementSibling; 4163 } 4164 var anyVisible = cityMatch; 4165 siblings.forEach(function(item) { 4166 var name = item.querySelector(".partner-list-name"); 4167 var web = item.querySelector(".partner-list-website"); 4168 var nameMatch = name && name.textContent.toLowerCase().indexOf(q) !== -1; 4169 var webMatch = web && web.textContent.toLowerCase().indexOf(q) !== -1; 4170 var show = cityMatch || nameMatch || webMatch; 4171 item.style.display = show ? "" : "none"; 4172 if (show) anyVisible = true; 4173 }); 4174 cityEl.style.display = anyVisible ? "" : "none"; 4175 }); 4176 }); 4177 } 4178 4179 // PLZ + Umkreis Logik 4180 function haversineKm(lat1, lon1, lat2, lon2) { 4181 var R = 6371; 4182 var dLat = (lat2 - lat1) * Math.PI / 180; 4183 var dLon = (lon2 - lon1) * Math.PI / 180; 4184 var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 4185 Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * 4186 Math.sin(dLon/2) * Math.sin(dLon/2); 4187 return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 4188 } 4189 4190 function filterByRadius(centerLat, centerLon, radiusKm) { 4191 var items = listEl.querySelectorAll(".partner-list-item"); 4192 var cityHeaders = listEl.querySelectorAll(".partner-city-header"); 4193 var letterHeaders = listEl.querySelectorAll(".partner-letter-header"); 4194 if (!radiusKm) { 4195 items.forEach(function(el) { el.style.display = ""; }); 4196 cityHeaders.forEach(function(el) { el.style.display = ""; }); 4197 letterHeaders.forEach(function(el) { el.style.display = ""; }); 4198 return; 4199 } 4200 letterHeaders.forEach(function(el) { el.style.display = "none"; }); 4201 cityHeaders.forEach(function(cityEl) { 4202 var anyVisible = false; 4203 var siblings = []; 4204 var next = cityEl.nextElementSibling; 4205 while (next && next.classList.contains("partner-list-item")) { 4206 siblings.push(next); 4207 next = next.nextElementSibling; 4208 } 4209 siblings.forEach(function(item) { 4210 var lat = parseFloat(item.dataset.lat); 4211 var lon = parseFloat(item.dataset.lon); 4212 var dist = haversineKm(centerLat, centerLon, lat, lon); 4213 var show = dist <= radiusKm; 4214 item.style.display = show ? "" : "none"; 4215 if (show) anyVisible = true; 4216 }); 4217 cityEl.style.display = anyVisible ? "" : "none"; 4218 }); 4219 } 4220 4221 function applyRadiusFromCenter(centerLat, centerLon) { 4222 var radiusKm = parseInt(document.getElementById("partner-radius").value) || 0; 4223 filterByRadius(centerLat, centerLon, radiusKm); 4224 map.flyTo({ center: [centerLon, centerLat], zoom: radiusKm <= 25 ? 11 : 9, duration: 1000 }); 4225 } 4226 4227document.getElementById("partner-plz-btn").addEventListener("click", function() { 4228 var plz = document.getElementById("partner-plz").value.trim(); 4229 if (!plz) return; 4230 var resultsEl = document.getElementById("partner-plz-results"); 4231 resultsEl.innerHTML = ""; 4232 resultsEl.style.display = "none"; 4233 4234 var EU = "ad,al,at,ba,be,bg,by,cy,cz,de,dk,ee,es,fi,fr,gb,gr,hr,hu,ie,is,it,li,lt,lu,lv,mc,md,me,mk,mt,nl,no,pl,pt,ro,rs,ru,se,si,sk,sm,ua,xk"; 4235 var results = []; 4236 4237 function showResults() { 4238 if (!results.length) { alert(T.plzNichtGefunden); return; } 4239 if (results.length === 1) { 4240 applyRadiusFromCenter(results[0].lat, results[0].lon); 4241 return; 4242 }
4243 results.forEach(function(item) { 4244 var div = document.createElement("div"); 4245 div.className = "partner-plz-result-item"; 4246 div.textContent = item.label; 4247 div.addEventListener("click", function() { 4248 resultsEl.style.display = "none"; 4249 applyRadiusFromCenter(item.lat, item.lon); 4250 }); 4251 resultsEl.appendChild(div); 4252 }); 4253 resultsEl.style.display = "block"; 4254 } 4255 4256 var chFetch = fetch("https://api3.geo.admin.ch/rest/services/api/SearchServer?searchText=" + encodeURIComponent(plz) + "&type=locations&origins=zipcode&limit=5") 4257 .then(function(r) { return r.json(); }) 4258 .then(function(data) { 4259 if (data.results) { 4260 data.results.forEach(function(item) { 4261 results.push({ 4262 lat: item.attrs.lat, 4263 lon: item.attrs.lon, 4264 label: item.attrs.label.replace(/<[^>]+>/g, "") + " (CH)" 4265 }); 4266 }); 4267 } 4268 }).catch(function() {}); 4269 4270 var euFetch = fetch("https://nominatim.openstreetmap.org/search?format=json&limit=5&countrycodes=" + EU + "&postalcode=" + encodeURIComponent(plz)) 4271 .then(function(r) { return r.json(); }) 4272 .then(function(data) { 4273 data.forEach(function(item) { 4274 results.push({ 4275 lat: parseFloat(item.lat), 4276 lon: parseFloat(item.lon), 4277 label: item.display_name 4278 }); 4279 }); 4280 }).catch(function() {}); 4281 4282 Promise.all([chFetch, euFetch]).then(showResults); 4283}); 4284 document.getElementById("partner-plz").addEventListener("keydown", function(e) { 4285 if (e.key === "Enter") document.getElementById("partner-plz-btn").click(); 4286 }); 4287 4288document.getElementById("partner-loc-btn").addEventListener("click", function() { 4289 if (!navigator.geolocation) return; 4290 navigator.geolocation.getCurrentPosition(function(pos) { 4291 geolocated = true; 4292 applyRadiusFromCenter(pos.coords.latitude, pos.coords.longitude); 4293 }, function(err) { 4294 console.log("Standort nicht verfügbar", err); 4295 alert(T.standortFehler); 4296 }, { 4297 maximumAge: 60000, 4298 timeout: 30000,
4299 enableHighAccuracy: false 4300 }); 4301}); 4302 4303 document.getElementById("partner-radius").addEventListener("change", function() { 4304 var plz = document.getElementById("partner-plz").value.trim(); 4305 if (plz) document.getElementById("partner-plz-btn").click(); 4306 }); 4307 4308 Object.keys(letterElements).sort().forEach(function(letter) { 4309 var btn = document.createElement("button"); 4310 btn.className = "partner-alpha-btn"; 4311 btn.textContent = letter; 4312 btn.addEventListener("click", function() { 4313 alphaNav.querySelectorAll(".partner-alpha-btn").forEach(function(b){ b.classList.remove("active"); }); 4314 btn.classList.add("active"); 4315 var target = letterElements[letter]; 4316 if (target) { 4317 var topBar = document.getElementById("partner-list-top") || document.querySelector(".partner-list-top"); 4318 var offset = topBar ? topBar.offsetHeight : 0; 4319 scrollEl.scrollTo({ top: target.offsetTop - offset, behavior: "smooth" }); 4320 } 4321 }); 4322 alphaNav.appendChild(btn); 4323 }); 4324 4325 if (bounds.length) { 4326 var lats = bounds.map(function(b){ return b[0]; }); 4327 var lons2 = bounds.map(function(b){ return b[1]; }); 4328 setTimeout(function() { 4329 if (!geolocated) { 4330 map.fitBounds( 4331 [[Math.min.apply(null,lons2), Math.min.apply(null,lats)], [Math.max.apply(null,lons2), Math.max.apply(null,lats)]], 4332 { padding: 30 } 4333 ); 4334 } 4335 }, 6000); 4336 } 4337}); 4338</script>
4338 4339</div> 4340</section> 4341</div> 4342 4343 <div id="o_shared_blocks" class="oe_unremovable"></div> 4344 </main> 4345 <footer id="bottom" data-anchor="true" data-name="Footer" class="o_footer o_colored_level o_cc "> 4346 <div id="footer" class="oe_structure oe_structure_solo"> 4347 <section class="s_text_block pt40 pb32" data-snippet="s_text_block" data-name="Text" style="background-image: none;"> 4348 <div class="container"> 4349 <div class="row o_grid_mode" data-row-count="4"> 4350 4351 4352 <div class="o_colored_level o_grid_item g-height-4 g-col-lg-2 col-lg-2 order-lg-0" style="grid-area: 1 / 5 / 5 / 7; z-index: 3; order: 2;"> 4353 <h5><span style="font-size: 0.75rem;">LEGAL</span></h5><ul class="list-unstyled"> 4354 <li class="py-1"><span class="o_small-fs"></span><span style="font-size: 0.75rem;"><a title="" data-bs-original-title="" href="/datenschutzerklarung">Datenschutzerklärung</a></span><span class="o_small-fs"></span></li> 4355 <li class="py-1"><span class="o_small-fs"></span><span style="font-size: 0.75rem;"><a title="" data-bs-original-title="" href="/impressum">Impressum</a></span><span class="o_small-fs"></span></li> 4356 <li class="py-1"><span class="o_small-fs"></span><span style="font-size: 0.75rem;"><a title="" data-bs-original-title="" href="/konformitatserklarung">Konformitätserklärung</a></span><span class="o_small-fs"></span><br/></li></ul></div> 4357 4358 4359 <div class="o_colored_level o_grid_item g-col-lg-3 order-lg-0 g-height-4 col-lg-3" style="z-index: 5; grid-area: 1 / 10 / 5 / 13; order: 4;"> 4360 <h5><span style="font-size: 0.75rem;"><strong>LARS Brillen</strong></span></h5><h5><span style="font-size: 0.75rem;">Eine Marke der ILEVE OPTICS AG.<br/>Bernapark 28. 3066 Stettlen. <br/>Schweiz.</span></h5><p class="text-muted"><span style="font-size: 0.75rem;"><a title="" data-bs-original-title="" href="mailto:[email protected]">[email protected]</a></span><span class="o_small-fs"></span><span class="o_force_ltr"><span style="font-size: 0.75rem;"><br/><a title="" data-bs-original-title="" href="tel:+41797674440">+41 79 767 44 40</a><span class="o_force_ltr"><span style="font-size: 0.75rem;"></span></span></span></span></p></div><div class="o_colored_level o_grid_item g-col-lg-2 g-height-4 col-lg-2 order-lg-0" style="z-index: 1; grid-area: 1 / 1 / 5 / 3; order: 0;"> 4361 <h5><span style="font-size: 0.75rem;">KUNDENSERVICE</span></h5> 4362 <ul class="list-unstyled"> 4363 <li class="list-item py-1"><span class="o_small-fs"></span><span style="font-size: 0.75rem;"><a href="/care-guide" data-bs-original-title="" title="">Care Guide</a></span><span class="o_small-fs"></span><br/></li> 4364 <li class="list-item py-1"><span class="o_small-fs"></span><span style="font-size: 0.75rem;"><a href="/stores" data-bs-original-title="" title="">Store Finder</a></span></li> 4365 <li class="list-item py-1"><span class="o_small-fs"></span><span style="font-size: 0.75rem;"><a href="/web/login" data-bs-original-title="" title="">B2B LOGIN</a></span><span class="o_small-fs"></span></li> 4366 4367 </ul> 4368 </div><div class="o_colored_level o_grid_item g-col-lg-2 g-height-4 col-lg-2 order-lg-0" style="z-index: 1; grid-area: 1 / 3 / 5 / 5; order: 1;"> 4369 <h5><span style="font-size: 0.75rem;">UNTERNEHMEN</span><br/></h5> 4370 <ul class="list-unstyled"> 4371 <li class="list-item py-1"><span style="font-size: 0.75rem;"><a title="" data-bs-original-title="" href="/lars-who">LARS who?</a></span></li><li class="list-item py-1"><span style="font-size: 0.75rem;"><a href="/made-in-switzerland" data-bs-original-title="" title="">Made in Switzerland</a></span></li> 4372 <li class="list-item py-1"><span class="o_small-fs"></span><span style="font-size: 0.75rem;"><a href="/karriere">Karriere</a></span><span class="o_small-fs"></span></li></ul></div><div class="o_colored_level o_grid_item g-col-lg-2 g-height-4 col-lg-2 order-lg-0" style="z-index: 4; grid-area: 1 / 7 / 5 / 9; order: 3;"> 4373 4374 <p class="o_small"><span style="font-size: 0.75rem;">SOCIAL MEDIA</span></p><p class="o_small"><span style="font-size: 0.75rem;"><a title="" data-bs-original-title="" href="https://www.instagram.com/larsbrillen/" target="_blank">Instagram</a></span><span class="o_small-fs"></span></p><p class="o_small"><span style="font-size: 0.75rem;"><a title="" data-bs-original-title="" href="https://www.facebook.com/larsbrillen/?locale=de_DE">Facebook</a></span><span class="o_small-fs"></span></p><p class="o_small"><span style="font-size: 0.75rem;"><a title="" data-bs-original-title="" href="https://ch.linkedin.com/company/ileve-optics" target="_blank">Linkedin</a></span></p></div></div> 4375 </div> 4376 </section> 4377 </div> 4378 </footer> 4379 </div>
vendor: 103 bytes, lines 4379-4380
4379 4380 <script id="tracking_code" async="async" src="https://www.googletagmanager.com/gtag/js?id=
4380G-M9TRM5ZXWN
vendor: 24 bytes, lines 4380-4381
4380"></script> 4381
4381<script id="tracking_code_config"> 4382 window.dataLayer = window.dataLayer || []; 4383 function gtag(){dataLayer.push(arguments);} 4384 gtag('consent', 'default', { 4385 'ad_storage': 'denied', 4386 'ad_user_data': 'denied', 4387 'ad_personalization': 'denied', 4388 'analytics_storage': 'denied', 4389 }); 4390 gtag('js', new Date()); 4391 gtag('config', 'G-M9TRM5ZXWN'); 4392 function allConsentsGranted() { 4393 gtag('consent', 'update', { 4394 'ad_storage': 'granted', 4395 'ad_user_data': 'granted', 4396 'ad_personalization': 'granted', 4397 'analytics_storage': 'granted', 4398 }); 4399 } 4400 allConsentsGranted(); 4401 </script>
4401 4402 4403 </body> 4404</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.