@@ -0,0 +1,652 @@
<!DOCTYPE html>
< html >
< head >
< meta charset = "utf-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< script src = "./support.js" > < / script >
< / head >
< body >
< x-dc >
< helmet >
< link href = "assets/fonts.css" rel = "stylesheet" >
< link href = "https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.css" rel = "stylesheet" >
< script src = "https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js" > < / script >
< style >
/* WK-THEME-START */
: root {
--wk-accent : #F0912F ;
--wk-accent-dark : #b96d1f ;
--wk-on-accent : #0d0f12 ;
--wk-deep : #0D2A46 ;
--wk-deep-2 : #10151b ;
--wk-page : #0d0f12 ;
--wk-band-1 : #164a7d ;
--wk-band-2 : #123a63 ;
--wk-band-3 : #1d5c99 ;
--wk-band-4 : #0f3154 ;
--wk-glow : #2FA4F0 ;
--wk-glow-soft : #9FD1F5 ;
--wk-ink : #f5f4f0 ;
--wk-body : #c9d6e2 ;
--wk-body-2 : #e7e9ec ;
--wk-body-soft : #c5c9ce ;
--wk-muted : #8fa4b8 ;
--wk-card : #F1F0EB ;
--wk-card-ink : #0D2A46 ;
--wk-card-body : #45535f ;
--wk-card-tag : #1b72af ;
--wk-tint-soft : rgba ( 18 , 60 , 120 , 0.32 ) ;
--wk-tint-strong : rgba ( 18 , 60 , 120 , 0.38 ) ;
--wk-veil-strong : rgba ( 13 , 42 , 70 , .45 ) ;
--wk-veil-soft : rgba ( 13 , 42 , 70 , .10 ) ;
--wk-hero-hue : 85 deg ;
}
/* WK-THEME-END */
* { margin : 0 ; padding : 0 ; box-sizing : border-box ; }
body { background : var ( - - wk - page ) ; font-family : 'Archivo' , system-ui , sans-serif ; -webkit- font-smoothing : antialiased ; }
a { color : #f0f0ec ; text-decoration : none ; }
a : hover { color : var ( - - accent , #F0912F ) ; }
@ keyframes lw-shimmer { 0 % { background-position : -200 % 0 ; } 100 % { background-position : 200 % 0 ; } }
@ keyframes lw-fadein { from { opacity : 0 ; transform : translateY ( 14 px ) ; } to { opacity : 1 ; transform : translateY ( 0 ) ; } }
[ data-wk-section ] [ hidden ] { display : none !important ; }
. lw-about : has ( > [ data-wk-section = "inhaber-foto" ] [ hidden ] ) { grid-template-columns : 1 fr !important ; }
@ media ( max-width : 1080px ) {
. lw-review { display : none !important ; }
}
@ media ( max-width : 860px ) {
. lw-navlinks { display : none !important ; }
. lw-burger { display : inline-flex !important ; }
. lw-benefits { grid-template-columns : repeat ( 2 , 1 fr ) !important ; row-gap : 26 px !important ; }
}
@ media ( max-width : 520px ) {
. lw-benefits { grid-template-columns : 1 fr !important ; }
}
@ media ( max-width : 980px ) {
. lw-services { grid-template-columns : repeat ( 2 , 1 fr ) !important ; }
}
@ media ( max-width : 620px ) {
. lw-services { grid-template-columns : 1 fr !important ; }
}
@ media ( max-width : 980px ) {
. lw-refs { grid-template-columns : repeat ( 2 , 1 fr ) !important ; grid-auto-rows : 200 px !important ; }
}
@ media ( max-width : 620px ) {
. lw-refs { grid-template-columns : 1 fr !important ; grid-auto-rows : 220 px !important ; }
. lw-ref-wide { grid-column : auto !important ; grid-row : auto !important ; }
}
@ media ( max-width : 860px ) {
. lw-about { grid-template-columns : 1 fr !important ; }
. lw-contact { grid-template-columns : 1 fr !important ; }
. lw-footer-cols { grid-template-columns : repeat ( 2 , 1 fr ) !important ; }
. lw-footer-bottom { flex-direction : column !important ; align-items : flex-start !important ; }
. lw-footer-bottom > div : last-child { text-align : left !important ; }
. lw-footer-bottom > div : last-child > div { justify-content : flex-start !important ; }
}
< / style >
< / helmet >
< div ref = "{{ rootRef }}" style = "width: 100%; --accent: var(--wk-accent); background: var(--wk-page);" >
<!-- HERO -->
< div style = "position: relative; min-height: 100vh; overflow: hidden;" >
<!-- BACKGROUND -->
< div style = "position: absolute; inset: 0; z-index: 0; background: radial-gradient(120% 90% at 78% 12%, #1c2530 0%, #12161b 42%, #0a0c0f 100%);" > < / div >
< div style = "position: absolute; inset: 0; z-index: 1; filter: hue-rotate(var(--wk-hero-hue, 85deg)) saturate(1.15);" >
< img src = "assets/hero-tankklappe.jpg" alt = "" style = "display: block; width: 100%; height: 100%; object-fit: cover;" >
< / div >
<!-- blue tint -->
< div style = "position: absolute; inset: 0; z-index: 2; pointer-events: none; background: var(--wk-tint-soft); mix-blend-mode: multiply;" > < / div >
<!-- legibility overlay (click - through) -->
< div style = "position: absolute; inset: 0; z-index: 2; pointer-events: none; background: linear-gradient(180deg, rgba(9,11,14,0.82) 0%, rgba(9,11,14,0.34) 30%, rgba(9,11,14,0.30) 55%, rgba(9,11,14,0.86) 100%);" > < / div >
< div style = "position: absolute; inset: 0; z-index: 2; pointer-events: none; background: radial-gradient(90% 70% at 22% 42%, rgba(9,11,14,0.55) 0%, rgba(9,11,14,0) 60%);" > < / div >
<!-- thin accent glow top -->
< div style = "position: absolute; top: 0; left: 0; right: 0; height: 3px; z-index: 4; background: linear-gradient(90deg, transparent, var(--accent, #F0912F), transparent); opacity: 0.5;" > < / div >
<!-- NAV -->
< nav ref = "{{ navRef }}" style = "position: fixed; top: 0; left: 0; right: 0; z-index: 40; transition: background .35s ease, backdrop-filter .35s ease, border-color .35s ease, padding .35s ease; padding: 22px clamp(20px, 4vw, 56px); border-bottom: 1px solid transparent;" >
< div style = "max-width: 1320px; margin: 0 auto; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 24px;" >
<!-- left links -->
< div class = "lw-navlinks" style = "display: flex; gap: 34px; align-items: center;" >
< a href = "#services" style = "font-size: 15px; font-weight: 600; letter-spacing: .02em; text-transform: uppercase;" > Services< / a >
< a href = "#referenzen" style = "font-size: 15px; font-weight: 600; letter-spacing: .02em; text-transform: uppercase;" > Referenzen< / a >
< / div >
<!-- logo — PLATZHALTER: assets/logo - placeholder.svg durch Ihr Logo ersetzen -->
< a href = "#top" style = "display: flex; align-items: center; justify-self: center;" >
< img src = "assets/logo-placeholder.svg" alt = "DieLack" style = "height: 26px; width: auto; display: block;" >
< / a >
<!-- right links -->
< div class = "lw-navlinks" style = "display: flex; gap: 34px; align-items: center; justify-content: flex-end;" >
< a href = "#ueber-uns" style = "font-size: 15px; font-weight: 600; letter-spacing: .02em; text-transform: uppercase;" > Über uns< / a >
< a href = "#kontakt" style = "font-size: 15px; font-weight: 600; letter-spacing: .02em; text-transform: uppercase;" > Kontakt< / a >
< / div >
<!-- mobile menu button -->
< button class = "lw-burger" aria-label = "Menü" style = "display: none; grid-column: 3; justify-self: end; background: transparent; border: 1.5px solid rgba(255,255,255,.28); border-radius: 10px; padding: 9px 11px; cursor: pointer; color: #f4f3ef; align-items: center; gap: 8px;" >
< span style = "display: block; width: 18px; height: 2px; background: currentColor; box-shadow: 0 6px 0 currentColor, 0 -6px 0 currentColor;" > < / span >
< / button >
< / div >
< / nav >
<!-- HERO CONTENT -->
< div style = "position: relative; z-index: 10; display: flex; flex-direction: column; min-height: 100vh; padding: clamp(120px, 16vh, 190px) clamp(20px, 4vw, 56px) 0;" >
< div style = "max-width: 1320px; margin: 0 auto; width: 100%; display: flex; flex-direction: column; flex: 1;" >
<!-- spacer -->
< div style = "flex: 1; min-height: 40px;" > < / div >
<!-- headline block -->
< div style = "max-width: 720px; margin: 0 auto; text-align: center; animation: lw-fadein .7s ease both;" >
< h1 style = "font-family: 'Source Serif 4', Georgia, serif; font-weight: 600; line-height: 1.08; letter-spacing: -0.005em; color: var(--wk-ink); font-size: clamp(36px, 4.8vw, 64px); margin-bottom: 22px;" >
< span style = "display: block;" > Rein mit
< span ref = "{{ wordSlotRef }}" style = "display: inline-block; position: relative; overflow: hidden; vertical-align: bottom; text-align: left;" >
< span ref = "{{ wordRef }}" style = "display: inline-block; color: var(--accent, #F0912F); font-style: italic; will-change: transform, opacity;" > Kratzer< / span >
< / span >
< / span >
< span style = "display: block;" > Raus wie neu.< / span >
< / h1 >
< p style = "font-size: clamp(15px, 1.3vw, 18px); line-height: 1.5; color: var(--wk-body-soft); max-width: 560px; margin: 0 auto; font-weight: 500;" data-wk-copy = "hero-subline" >
Wir reparieren alles! Mit Originalteilen und neuester Technik zu fairen Preisen. Als wäre nichts passiert.
< / p >
< / div >
<!-- spacer -->
< div style = "flex: 1; min-height: 40px;" > < / div >
<!-- BENEFIT STRIP -->
< div class = "lw-benefits" style = "display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(18px, 3vw, 48px); padding: 28px 0 46px;" >
< div style = "display: flex; flex-direction: column; justify-content: flex-end; gap: 12px;" >
< p style = "font-size: 15.5px; line-height: 1.4; color: var(--wk-body-2); font-weight: 600;" data-wk-copy = "benefit-1" > Fahrzeug-Reparatur wie in der Vertragswerkstatt — nur günstiger< / p >
< / div >
< div style = "display: flex; flex-direction: column; justify-content: flex-end; gap: 12px;" >
< img src = "assets/benefit01.svg" alt = "" width = "22" height = "27" style = "opacity: .95;" >
< p style = "font-size: 15.5px; line-height: 1.4; color: var(--wk-body-2); font-weight: 600;" data-wk-copy = "benefit-2" > Wir nutzen Premium-Lacke< / p >
< / div >
< div style = "display: flex; flex-direction: column; justify-content: flex-end; gap: 12px;" >
< img src = "assets/benefit02.svg" alt = "" width = "30" height = "24" style = "opacity: .95;" >
< p style = "font-size: 15.5px; line-height: 1.4; color: var(--wk-body-2); font-weight: 600;" data-wk-copy = "benefit-3" > Wir verbauen nur Originalteile< / p >
< / div >
< div style = "display: flex; flex-direction: column; gap: 14px;" >
<!-- Google badge -->
< a href = "{{ googleUrl }}" target = "_blank" rel = "noopener" style = "display: inline-flex; flex-direction: column; gap: 3px; align-self: flex-start; background: #000; border: 1px solid rgba(255,255,255,.12); border-radius: 44px; padding: 11px 20px; transition: transform .3s ease, box-shadow .3s ease;" style-hover = "transform: scale(1.05); box-shadow: 0 6px 20px rgba(0,0,0,.4);" >
< span style = "color: #fff; font-weight: 700; font-size: 15px; letter-spacing: .01em;" > DieLack< / span >
< span style = "display: inline-flex; align-items: center; gap: 7px;" >
< span style = "color: #DBDED9; font-weight: 600; font-size: 15px;" > {{ ratingLabel }}< / span >
< img src = "assets/review.svg" alt = "Bewertung" width = "66" height = "10" >
< span style = "color: #DBDED9; font-weight: 300; font-size: 15px;" > {{ countLabel }}< / span >
< / span >
< / a >
< img src = "assets/benefit03.svg" alt = "" width = "20" height = "30" style = "opacity: .95;" >
< p style = "font-size: 15.5px; line-height: 1.4; color: var(--wk-body-2); font-weight: 600;" data-wk-copy = "benefit-4" > Wir arbeiten mit der gleichen Genauigkeit< / p >
< / div >
< / div >
< / div >
< / div >
< / div >
<!-- LEISTUNGEN SECTION -->
< section id = "services" data-screen-label = "Leistungen" style = "position: relative; overflow: hidden; background: var(--wk-deep); padding: clamp(80px, 12vh, 140px) clamp(20px, 4vw, 56px);" >
< svg viewBox = "0 0 1440 900" preserveAspectRatio = "xMidYMid slice" aria-hidden = "true" style = "position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none;" >
< path d = "M-100,780 C300,620 500,930 900,760 C1180,640 1350,700 1540,560" fill = "none" stroke = "var(--wk-band-1)" stroke-width = "150" stroke-linecap = "round" opacity = "0.75" > < / path >
< path d = "M-120,320 C260,480 620,120 980,300 C1240,430 1380,320 1560,400" fill = "none" stroke = "var(--wk-band-2)" stroke-width = "190" stroke-linecap = "round" opacity = "0.8" > < / path >
< path d = "M-80,90 C380,220 760,-40 1120,120 C1330,215 1450,140 1560,190" fill = "none" stroke = "var(--wk-band-3)" stroke-width = "110" stroke-linecap = "round" opacity = "0.55" > < / path >
< path d = "M-100,560 C340,420 700,660 1080,500 C1300,410 1420,470 1560,410" fill = "none" stroke = "var(--wk-band-4)" stroke-width = "230" stroke-linecap = "round" opacity = "0.9" > < / path >
< / svg >
< div style = "position: absolute; inset: 0; background: linear-gradient(180deg, var(--wk-veil-strong) 0%, var(--wk-veil-soft) 40%, var(--wk-veil-strong) 100%); pointer-events: none;" > < / div >
< div style = "position: relative; max-width: 1320px; margin: 0 auto;" >
< div style = "max-width: 760px; margin-bottom: clamp(40px, 6vh, 64px);" >
< span style = "display: inline-block; font-size: 13px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--wk-glow-soft); margin-bottom: 16px;" > Leistungen< / span >
< h2 style = "font-family: 'Source Serif 4', Georgia, serif; font-weight: 600; line-height: 1.1; color: var(--wk-ink); font-size: clamp(30px, 3.6vw, 52px); margin-bottom: 18px;" data-wk-copy = "services-title" > Alles rund um den Lack – aus einer Hand< / h2 >
< p style = "font-size: clamp(15px, 1.3vw, 18px); line-height: 1.55; color: var(--wk-body); font-weight: 500;" data-wk-copy = "services-intro" > Ob Neuwagen, Alltagsauto oder Klassiker: Wir bringen jede Oberfläche zurück in Bestform. Präzise vorbereitet, sauber lackiert, perfekt finiert.< / p >
< / div >
< div class = "lw-services" style = "display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(18px, 2.4vw, 30px);" >
< div style = "background: var(--wk-card); border-radius: 24px; padding: 34px 30px; display: flex; flex-direction: column; gap: 12px; box-shadow: 2px 4px 14px rgba(0,0,0,.25);" >
< h3 style = "font-family: 'Source Serif 4', Georgia, serif; font-weight: 600; font-size: 23px; color: var(--wk-card-ink);" data-wk-copy = "service-1-title" > Lackierungen aller Art< / h3 >
< p style = "font-size: 15.5px; line-height: 1.55; color: var(--wk-card-body); font-weight: 500; flex: 1;" data-wk-copy = "service-1-text" > Vom Kotflügel bis zur Komplettlackierung – markenunabhängig, farbtongenau und in dauerhafter Qualität.< / p >
< span style = "font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--wk-card-tag);" data-wk-copy = "service-1-tag" > Uni · Metallic · Perleffekt< / span >
< / div >
< div style = "background: var(--wk-card); border-radius: 24px; padding: 34px 30px; display: flex; flex-direction: column; gap: 12px; box-shadow: 2px 4px 14px rgba(0,0,0,.25);" >
< h3 style = "font-family: 'Source Serif 4', Georgia, serif; font-weight: 600; font-size: 23px; color: var(--wk-card-ink);" data-wk-copy = "service-2-title" > Smart Repair< / h3 >
< p style = "font-size: 15.5px; line-height: 1.55; color: var(--wk-card-body); font-weight: 500; flex: 1;" data-wk-copy = "service-2-text" > Kleine Kratzer, Steinschläge und Parkdellen punktgenau beseitigt – schnell, günstig und ohne sichtbaren Übergang.< / p >
< span style = "font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--wk-card-tag);" data-wk-copy = "service-2-tag" > Spot-Repair · Same Day< / span >
< / div >
< div style = "background: var(--wk-card); border-radius: 24px; padding: 34px 30px; display: flex; flex-direction: column; gap: 12px; box-shadow: 2px 4px 14px rgba(0,0,0,.25);" >
< h3 style = "font-family: 'Source Serif 4', Georgia, serif; font-weight: 600; font-size: 23px; color: var(--wk-card-ink);" data-wk-copy = "service-3-title" > Oldtimer & Klassiker< / h3 >
< p style = "font-size: 15.5px; line-height: 1.55; color: var(--wk-card-body); font-weight: 500; flex: 1;" data-wk-copy = "service-3-text" > Restaurierung mit Fingerspitzengefühl: originalgetreue Farbtöne und ein Finish, das dem Wert Ihres Fahrzeugs gerecht wird.< / p >
< span style = "font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--wk-card-tag);" data-wk-copy = "service-3-tag" > Restauration · Karosserie< / span >
< / div >
< div style = "background: var(--wk-card); border-radius: 24px; padding: 34px 30px; display: flex; flex-direction: column; gap: 12px; box-shadow: 2px 4px 14px rgba(0,0,0,.25);" >
< h3 style = "font-family: 'Source Serif 4', Georgia, serif; font-weight: 600; font-size: 23px; color: var(--wk-card-ink);" data-wk-copy = "service-4-title" > Lackaufbereitung & Politur< / h3 >
< p style = "font-size: 15.5px; line-height: 1.55; color: var(--wk-card-body); font-weight: 500; flex: 1;" data-wk-copy = "service-4-text" > Professionelles Polieren, Versiegeln und Aufbereiten für tiefen Glanz und langanhaltenden Schutz Ihres Lacks.< / p >
< span style = "font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--wk-card-tag);" data-wk-copy = "service-4-tag" > Politur · Versiegelung< / span >
< / div >
< div style = "background: var(--wk-card); border-radius: 24px; padding: 34px 30px; display: flex; flex-direction: column; gap: 12px; box-shadow: 2px 4px 14px rgba(0,0,0,.25);" >
< h3 style = "font-family: 'Source Serif 4', Georgia, serif; font-weight: 600; font-size: 23px; color: var(--wk-card-ink);" data-wk-copy = "service-5-title" > Felgen & Motorrad< / h3 >
< p style = "font-size: 15.5px; line-height: 1.55; color: var(--wk-card-body); font-weight: 500; flex: 1;" data-wk-copy = "service-5-text" > Felgenaufbereitung und Motorradlackierung im gleichen hohen Standard – für den perfekten Auftritt bis ins Detail.< / p >
< span style = "font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--wk-card-tag);" data-wk-copy = "service-5-tag" > Felgen · Zweirad< / span >
< / div >
<!-- LEISTUNGS - VIDEO — bewusst beibehalten (assets/leistungen - video.mp4) -->
< div style = "position: relative; border-radius: 24px; overflow: hidden; box-shadow: 2px 4px 14px rgba(0,0,0,.25);" >
< video ref = "{{ videoRef }}" src = "assets/leistungen-video.mp4" autoplay muted loop playsinline style = "position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;" > < / video >
< div style = "position: absolute; inset: 0; background: linear-gradient(180deg, rgba(8,20,34,0) 45%, rgba(8,20,34,.78) 100%); pointer-events: none;" > < / div >
< div style = "position: absolute; left: 30px; right: 30px; bottom: 26px; display: flex; flex-direction: column; gap: 8px;" >
< h3 style = "font-family: 'Source Serif 4', Georgia, serif; font-weight: 600; font-size: 23px; color: var(--wk-ink);" data-wk-copy = "service-6-title" > Design- & Sonderlackierung< / h3 >
< p style = "font-size: 14.5px; line-height: 1.5; color: var(--wk-body); font-weight: 500;" data-wk-copy = "service-6-text" > Individuelle Farbwünsche, Sondereffekte und Akzente – wir setzen Ihre Ideen sauber und hochwertig um.< / p >
< span style = "font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--wk-glow-soft);" data-wk-copy = "service-6-tag" > Custom · Effektlack< / span >
< / div >
< / div >
< / div >
< / div >
< / section >
<!-- REFERENZEN SECTION — Vorher/Nachher - Vergleich entfernt, durch Foto - Galerie ersetzt -->
< section id = "referenzen" data-wk-section = "referenzen" data-screen-label = "Referenzen" style = "position: relative; overflow: hidden; background: var(--wk-deep); padding: clamp(80px, 12vh, 140px) clamp(20px, 4vw, 56px);" >
< img src = "assets/bg-radkasten.jpg" alt = "" style = "position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: hue-rotate(var(--wk-hero-hue, 85deg)) saturate(1.2); pointer-events: none;" >
< div style = "position: absolute; inset: 0; background: var(--wk-tint-strong); mix-blend-mode: multiply; pointer-events: none;" > < / div >
< div style = "position: absolute; inset: 0; background: linear-gradient(180deg, rgba(10,18,30,.8) 0%, rgba(10,18,30,.45) 45%, rgba(10,18,30,.8) 100%); pointer-events: none;" > < / div >
< div style = "position: relative; max-width: 1320px; margin: 0 auto;" >
< div style = "max-width: 760px; margin-bottom: clamp(40px, 6vh, 64px);" >
< span style = "display: inline-block; font-size: 13px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--wk-glow-soft); margin-bottom: 16px;" > Referenzen< / span >
< h2 style = "font-family: 'Source Serif 4', Georgia, serif; font-weight: 600; line-height: 1.1; color: var(--wk-ink); font-size: clamp(30px, 3.6vw, 52px); margin-bottom: 18px;" data-wk-copy = "refs-title" > Echte Arbeiten aus unserer Werkstatt< / h2 >
< p style = "font-size: clamp(15px, 1.3vw, 18px); line-height: 1.55; color: var(--wk-body); font-weight: 500;" data-wk-copy = "refs-intro" > Ein Auszug aus unseren Projekten. Ziehen Sie eigene Fotos (z. B. Vorher/Nachher) einfach per Drag & Drop in die Platzhalter.< / p >
< / div >
<!-- Foto - Galerie — jeder Platzhalter ist per Drag & Drop mit einem eigenen Foto befüllbar -->
< div class = "lw-refs" style = "display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 240px; gap: clamp(14px, 1.8vw, 22px);" >
< div class = "lw-ref-wide" style = "position: relative; grid-column: span 2; grid-row: span 2; border-radius: 24px; overflow: hidden; box-shadow: 2px 6px 24px rgba(0,0,0,.45); background: rgba(255,255,255,.05); border: 1.5px dashed rgba(255,255,255,.3);" >
< x-import component-from-global-scope = "image-slot" from = "./assets/image-slot.js" id = "ref-1" shape = "rect" fit = "cover" placeholder = "Projektfoto 1 hier ablegen" hint-size = "100%,100%" style = "display:block;width:100%;height:100%;" > < / x-import >
< / div >
< div style = "position: relative; border-radius: 24px; overflow: hidden; box-shadow: 2px 6px 24px rgba(0,0,0,.45); background: rgba(255,255,255,.05); border: 1.5px dashed rgba(255,255,255,.3);" >
< x-import component-from-global-scope = "image-slot" from = "./assets/image-slot.js" id = "ref-2" shape = "rect" fit = "cover" placeholder = "Foto 2" hint-size = "100%,100%" style = "display:block;width:100%;height:100%;" > < / x-import >
< / div >
< div style = "position: relative; border-radius: 24px; overflow: hidden; box-shadow: 2px 6px 24px rgba(0,0,0,.45); background: rgba(255,255,255,.05); border: 1.5px dashed rgba(255,255,255,.3);" >
< x-import component-from-global-scope = "image-slot" from = "./assets/image-slot.js" id = "ref-3" shape = "rect" fit = "cover" placeholder = "Foto 3" hint-size = "100%,100%" style = "display:block;width:100%;height:100%;" > < / x-import >
< / div >
< div style = "position: relative; border-radius: 24px; overflow: hidden; box-shadow: 2px 6px 24px rgba(0,0,0,.45); background: rgba(255,255,255,.05); border: 1.5px dashed rgba(255,255,255,.3);" >
< x-import component-from-global-scope = "image-slot" from = "./assets/image-slot.js" id = "ref-4" shape = "rect" fit = "cover" placeholder = "Foto 4" hint-size = "100%,100%" style = "display:block;width:100%;height:100%;" > < / x-import >
< / div >
< div style = "position: relative; border-radius: 24px; overflow: hidden; box-shadow: 2px 6px 24px rgba(0,0,0,.45); background: rgba(255,255,255,.05); border: 1.5px dashed rgba(255,255,255,.3);" >
< x-import component-from-global-scope = "image-slot" from = "./assets/image-slot.js" id = "ref-5" shape = "rect" fit = "cover" placeholder = "Foto 5" hint-size = "100%,100%" style = "display:block;width:100%;height:100%;" > < / x-import >
< / div >
< / div >
< p style = "margin-top: clamp(28px, 4vh, 44px); text-align: center; font-size: 15px; color: var(--wk-body); font-weight: 500;" > Mehr laufende Projekte gibt es auf unserer < a href = "https://www.facebook.com/DieLackBlatt/" target = "_blank" rel = "noopener" style = "color: var(--wk-glow-soft); font-weight: 700;" data-wk-copy = "refs-social-link" > Facebook-Seite< / a > .< / p >
< / div >
< / section >
<!-- ÜBER UNS SECTION -->
< section id = "ueber-uns" data-screen-label = "Über uns" style = "position: relative; overflow: hidden; background: var(--wk-deep); padding: clamp(80px, 12vh, 140px) clamp(20px, 4vw, 56px);" >
< svg viewBox = "0 0 1440 900" preserveAspectRatio = "xMidYMid slice" aria-hidden = "true" style = "position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none;" >
< path d = "M-100,120 C340,260 720,-20 1100,140 C1320,230 1450,160 1560,210" fill = "none" stroke = "var(--wk-band-3)" stroke-width = "120" stroke-linecap = "round" opacity = "0.5" > < / path >
< path d = "M-120,480 C280,340 640,620 1020,460 C1280,350 1400,420 1560,360" fill = "none" stroke = "var(--wk-band-2)" stroke-width = "210" stroke-linecap = "round" opacity = "0.8" > < / path >
< path d = "M-100,800 C320,660 560,940 960,780 C1220,670 1380,730 1560,610" fill = "none" stroke = "var(--wk-band-1)" stroke-width = "150" stroke-linecap = "round" opacity = "0.7" > < / path >
< / svg >
< div style = "position: absolute; inset: 0; background: linear-gradient(180deg, var(--wk-veil-strong) 0%, var(--wk-veil-soft) 40%, var(--wk-veil-strong) 100%); pointer-events: none;" > < / div >
< div style = "position: relative; max-width: 1320px; margin: 0 auto;" >
< div style = "max-width: 900px; margin-bottom: clamp(50px, 8vh, 90px);" >
< span style = "display: inline-block; font-size: 13px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--wk-glow-soft); margin-bottom: 16px;" > Über uns< / span >
< h2 style = "font-family: 'Source Serif 4', Georgia, serif; font-weight: 600; line-height: 1.12; color: var(--wk-ink); font-size: clamp(32px, 4vw, 58px);" data-wk-copy = "about-title" > Wir kombinieren handwerkliches Wissen und viel Erfahrung mit modernster Technik.< / h2 >
< / div >
<!-- Reihe 1: Vorstellung + Profilbild - Platzhalter -->
< div class = "lw-about" style = "display: grid; grid-template-columns: 1.1fr 0.9fr; gap: clamp(28px, 4vw, 64px); align-items: center; margin-bottom: clamp(50px, 8vh, 90px);" >
< div style = "display: flex; flex-direction: column; gap: 16px;" >
< h3 style = "font-family: 'Source Serif 4', Georgia, serif; font-weight: 600; font-size: clamp(24px, 2.2vw, 32px); line-height: 1.2; color: var(--wk-ink);" > Hallo, ich bin< br > Andreas Blatt,< / h3 >
< p style = "font-size: clamp(15px, 1.3vw, 18px); line-height: 1.6; color: var(--wk-body); font-weight: 500;" data-wk-copy = "about-lead" > Lack- und Karosserie-Experte und Inhaber der Fahrzeuglackiererei DieLack – Andreas Blatt Auto-Einbrennlackiererei in Geretsried.< / p >
< p style = "font-size: clamp(15px, 1.3vw, 18px); line-height: 1.6; color: var(--wk-body); font-weight: 500;" data-wk-copy = "about-text" > Mit meinem Werkstatt-Team aus professionellen Fachkräften erfülle ich Ihre individuellen Wünsche zum bestmöglichen Preis — von der Smart-Repair bis zur kompletten Restauration.< / p >
< / div >
< div data-wk-section = "inhaber-foto" style = "justify-self: center; width: min(340px, 100%);" >
< div style = "position: relative; width: 100%; aspect-ratio: 4/5; border-radius: 24px; overflow: hidden; box-shadow: 2px 6px 24px rgba(0,0,0,.4); background: rgba(255,255,255,.05); border: 1.5px dashed rgba(255,255,255,.3);" >
< x-import component-from-global-scope = "image-slot" from = "./assets/image-slot.js" id = "profil-inhaber" shape = "rect" fit = "cover" placeholder = "Profilbild der Inhaberin / des Inhabers hier ablegen" hint-size = "100%,100%" style = "display:block;width:100%;height:100%;" > < / x-import >
< / div >
< / div >
< / div >
<!-- Reihe 2: Kundenstimmen + Philosophie -->
< div class = "lw-about" style = "display: grid; grid-template-columns: 0.9fr 1.1fr; gap: clamp(28px, 4vw, 64px); align-items: center;" >
< div style = "position: relative; border-radius: 24px; padding: 28px; background: rgba(10,20,34,.55); border: 1px solid rgba(255,255,255,.12); backdrop-filter: blur(10px); box-shadow: 2px 6px 24px rgba(0,0,0,.35);" >
< div style = "display: flex; align-items: center; gap: 12px; margin-bottom: 16px;" >
< span style = "display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 42px; border-radius: 50%; background: var(--accent, #2FA4F0); color: var(--wk-on-accent); font-weight: 800; font-size: 17px; flex-shrink: 0;" > {{ reviewInitial }}< / span >
< div style = "display: flex; flex-direction: column; gap: 3px; min-width: 0;" >
< span style = "color: #f4f3ef; font-weight: 700; font-size: 15px;" > {{ reviewAuthor }}< / span >
< span style = "color: #F2BD3F; font-size: 14px; letter-spacing: 2px; line-height: 1;" > ★★★★★< / span >
< / div >
< / div >
< p ref = "{{ reviewTextRef }}" style = "color: var(--wk-body); font-size: 15px; line-height: 1.6; font-weight: 500; transition: opacity .4s ease;" > {{ reviewText }}< / p >
< span style = "display: block; margin-top: 14px; padding-top: 12px; border-top: 1px solid rgba(255,255,255,.1); color: var(--wk-muted); font-size: 12.5px; font-weight: 600;" > {{ reviewMeta }}< / span >
< / div >
< div style = "display: flex; flex-direction: column; gap: 16px;" >
< h3 style = "font-family: 'Source Serif 4', Georgia, serif; font-weight: 600; font-size: clamp(24px, 2.2vw, 32px); line-height: 1.2; color: var(--wk-ink);" data-wk-copy = "philosophy-title" > Meine Philosophie< / h3 >
< p style = "font-size: clamp(15px, 1.3vw, 18px); line-height: 1.6; color: var(--wk-body); font-weight: 500;" data-wk-copy = "philosophy-1" > Für Sie – meine Kunden – soll meisterhafte Arbeit bezahlbar sein. Unser Service sieht aus wie aus der Vertragswerkstatt, hat die gleiche Qualität, ist aber deutlich günstiger.< / p >
< p style = "font-size: clamp(15px, 1.3vw, 18px); line-height: 1.6; color: var(--wk-body); font-weight: 500;" data-wk-copy = "philosophy-2" > Es ist für mich oberstes Gesetz, dass Sie nur 1A-Qualität bekommen, statt billiger „Pinselarbeiten". Mit hastig erledigten, minderwertigen Flickarbeiten kann ich nicht dienen.< / p >
< p style = "font-size: clamp(15px, 1.3vw, 18px); line-height: 1.6; color: var(--wk-body); font-weight: 500;" data-wk-copy = "philosophy-3" > Mein Credo: Glückliche Kunden kommen wieder. Mein Team und ich sind unheimlich stolz auf Ihre Zufriedenheit und begeisterten Bewertungen.< / p >
< / div >
< / div >
< / div >
< / section >
<!-- KONTAKT SECTION -->
< section id = "kontakt" data-screen-label = "Kontakt & Anfahrt" style = "position: relative; overflow: hidden; background: var(--wk-deep-2); padding: clamp(80px, 12vh, 140px) clamp(20px, 4vw, 56px);" >
< img src = "assets/bg-vorderlicht.jpg" alt = "" style = "position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: hue-rotate(var(--wk-hero-hue, 85deg)) saturate(1.2); pointer-events: none;" >
< div style = "position: absolute; inset: 0; background: var(--wk-tint-strong); mix-blend-mode: multiply; pointer-events: none;" > < / div >
< div style = "position: absolute; inset: 0; background: linear-gradient(180deg, rgba(10,18,30,.88) 0%, rgba(10,18,30,.55) 45%, rgba(10,18,30,.88) 100%); pointer-events: none;" > < / div >
< div style = "position: relative; max-width: 1320px; margin: 0 auto;" >
< div style = "max-width: 760px; margin-bottom: clamp(40px, 6vh, 64px);" >
< span style = "display: inline-block; font-size: 13px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--wk-glow-soft); margin-bottom: 16px;" > Kontakt & Anfahrt< / span >
< h2 style = "font-family: 'Source Serif 4', Georgia, serif; font-weight: 600; line-height: 1.1; color: var(--wk-ink); font-size: clamp(30px, 3.6vw, 52px); margin-bottom: 18px;" data-wk-copy = "contact-title" > Sprechen wir über Ihr Fahrzeug< / h2 >
< p style = "font-size: clamp(15px, 1.3vw, 18px); line-height: 1.55; color: var(--wk-body); font-weight: 500;" data-wk-copy = "contact-intro" > Rufen Sie an, schreiben Sie uns oder kommen Sie direkt vorbei – wir beraten Sie gern und unverbindlich.< / p >
< / div >
< div class = "lw-contact" style = "display: grid; grid-template-columns: 0.9fr 1.1fr; gap: clamp(24px, 3vw, 40px); align-items: stretch;" >
<!-- Kontakt - Infos -->
< div style = "display: flex; flex-direction: column; gap: 18px; border-radius: 24px; padding: clamp(26px, 3vw, 40px); background: rgba(10,20,34,.6); border: 1px solid rgba(255,255,255,.12); backdrop-filter: blur(10px); box-shadow: 2px 6px 24px rgba(0,0,0,.35);" >
< div style = "display: flex; flex-direction: column; gap: 4px;" >
< span style = "font-size: 12.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--wk-glow-soft);" > Adresse< / span >
< p style = "font-size: 16px; line-height: 1.5; color: var(--wk-body-2); font-weight: 600;" > Fahrzeuglackiererei DieLack – Andreas Blatt Auto-Einbrennlackiererei< br > Breslauer Weg 13, 82538 Geretsried< / p >
< / div >
< div style = "display: flex; flex-direction: column; gap: 4px;" >
< span style = "font-size: 12.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--wk-glow-soft);" > Telefon< / span >
< p style = "font-size: 16px; line-height: 1.5; color: var(--wk-body-2); font-weight: 600;" > < a href = "tel:+49817132636" style = "color: var(--wk-body-2);" > 08171 32636< / a > < br > < span style = "font-weight: 500; color: var(--wk-body-soft);" > Fax: < / span > < / p >
< / div >
< div style = "display: flex; flex-direction: column; gap: 4px;" >
< span style = "font-size: 12.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--wk-glow-soft);" > E-Mail< / span >
< p style = "font-size: 16px; line-height: 1.5; font-weight: 600;" > < a href = "mailto:anfrage@dielack.de" style = "color: var(--wk-body-2);" > anfrage@dielack.de< / a > < / p >
< / div >
< div style = "display: flex; flex-direction: column; gap: 4px;" >
< span style = "font-size: 12.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--wk-glow-soft);" > Öffnungszeiten< / span >
< p style = "font-size: 16px; line-height: 1.6; color: var(--wk-body-2); font-weight: 600;" > Mo– Fr< br > < span style = "font-weight: 500; color: var(--wk-body-soft);" > nach Vereinbarung< / span > < br > < br > < span style = "font-weight: 500; color: var(--wk-body-soft);" > < / span > < / p >
< / div >
< div style = "display: flex; flex-wrap: wrap; gap: 12px; margin-top: 8px;" >
< a href = "tel:+49817132636" style = "display: inline-flex; align-items: center; gap: 8px; font-size: 14.5px; font-weight: 700; letter-spacing: .02em; text-transform: uppercase; color: var(--wk-on-accent); background: var(--accent, #2FA4F0); padding: 13px 22px; border-radius: 44px; transition: transform .2s ease, box-shadow .2s ease;" style-hover = "transform: translateY(-2px); box-shadow: 0 10px 26px rgba(47,164,240,.4);" > Jetzt anrufen< / a >
< a href = "mailto:anfrage@dielack.de" style = "display: inline-flex; align-items: center; font-size: 14.5px; font-weight: 700; letter-spacing: .02em; text-transform: uppercase; color: #f4f3ef; padding: 13px 22px; border-radius: 44px; border: 1.5px solid rgba(255,255,255,.3); transition: border-color .2s ease, background .2s ease;" style-hover = "border-color: var(--accent, #2FA4F0); background: rgba(255,255,255,.05);" > E-Mail schreiben< / a >
< / div >
< / div >
<!-- Karte -->
< div style = "position: relative; border-radius: 24px; overflow: hidden; box-shadow: 2px 6px 24px rgba(0,0,0,.4); min-height: 420px; background: var(--wk-page);" >
< div ref = "{{ mapRef }}" style = "position: absolute; inset: 0;" > < / div >
< / div >
< / div >
< / div >
< / section >
<!-- FOOTER (sticky reveal) -->
< footer data-screen-label = "Footer" style = "position: relative; height: 70vh; clip-path: polygon(0% 0, 100% 0%, 100% 100%, 0 100%);" >
< div style = "position: relative; height: calc(100vh + 70vh); top: -100vh;" >
< div style = "height: 70vh; position: sticky; top: calc(100vh - 70vh);" >
< div style = "height: 100%; width: 100%; display: flex; flex-direction: column; justify-content: space-between; overflow: hidden; position: relative; background: linear-gradient(135deg, #0a1526 0%, #0D2A46 55%, #0a1526 100%); padding: clamp(32px, 6vh, 64px) clamp(20px, 4vw, 56px);" >
<!-- Glow - Elemente -->
< div style = "position: absolute; top: -120px; right: -120px; width: 380px; height: 380px; border-radius: 50%; background: rgba(47,164,240,.09); filter: blur(70px); pointer-events: none;" > < / div >
< div style = "position: absolute; bottom: -140px; left: -100px; width: 380px; height: 380px; border-radius: 50%; background: rgba(29,92,153,.12); filter: blur(70px); pointer-events: none;" > < / div >
<!-- Link - Spalten -->
< div class = "lw-footer-cols" style = "position: relative; z-index: 1; display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(24px, 4vw, 80px); max-width: 1320px; width: 100%; margin: 0 auto;" >
< div style = "display: flex; flex-direction: column; gap: 9px;" >
< h3 style = "font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--wk-muted); border-bottom: 1px solid rgba(255,255,255,.12); padding-bottom: 7px; margin-bottom: 6px;" > Navigation< / h3 >
< a href = "#top" style = "font-size: 14px; color: var(--wk-body); font-weight: 500;" > Start< / a >
< a href = "#services" style = "font-size: 14px; color: var(--wk-body); font-weight: 500;" > Services< / a >
< a href = "#referenzen" style = "font-size: 14px; color: var(--wk-body); font-weight: 500;" > Referenzen< / a >
< a href = "#ueber-uns" style = "font-size: 14px; color: var(--wk-body); font-weight: 500;" > Über uns< / a >
< a href = "#kontakt" style = "font-size: 14px; color: var(--wk-body); font-weight: 500;" > Kontakt< / a >
< / div >
< div style = "display: flex; flex-direction: column; gap: 9px;" >
< h3 style = "font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--wk-muted); border-bottom: 1px solid rgba(255,255,255,.12); padding-bottom: 7px; margin-bottom: 6px;" > Leistungen< / h3 >
< a href = "#services" style = "font-size: 14px; color: var(--wk-body); font-weight: 500;" data-wk-copy = "footer-leistung-1" > Lackierungen aller Art< / a >
< a href = "#services" style = "font-size: 14px; color: var(--wk-body); font-weight: 500;" data-wk-copy = "footer-leistung-2" > Smart Repair< / a >
< a href = "#services" style = "font-size: 14px; color: var(--wk-body); font-weight: 500;" data-wk-copy = "footer-leistung-3" > Oldtimer & Klassiker< / a >
< a href = "#services" style = "font-size: 14px; color: var(--wk-body); font-weight: 500;" data-wk-copy = "footer-leistung-4" > Felgen & Motorrad< / a >
< / div >
< div style = "display: flex; flex-direction: column; gap: 9px;" >
< h3 style = "font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--wk-muted); border-bottom: 1px solid rgba(255,255,255,.12); padding-bottom: 7px; margin-bottom: 6px;" > Kontakt< / h3 >
< span style = "font-size: 14px; color: var(--wk-body); font-weight: 500;" > Breslauer Weg 13< br > 82538 Geretsried< / span >
< a href = "tel:+49817132636" style = "font-size: 14px; color: var(--wk-body); font-weight: 500;" > 08171 32636< / a >
< a href = "mailto:anfrage@dielack.de" style = "font-size: 14px; color: var(--wk-body); font-weight: 500;" > anfrage@dielack.de< / a >
< / div >
< div style = "display: flex; flex-direction: column; gap: 9px;" >
< h3 style = "font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--wk-muted); border-bottom: 1px solid rgba(255,255,255,.12); padding-bottom: 7px; margin-bottom: 6px;" > Öffnungszeiten< / h3 >
< span style = "font-size: 14px; color: var(--wk-body); font-weight: 500;" > Mo– Fr< br > nach Vereinbarung< / span >
< span style = "font-size: 14px; color: var(--wk-body); font-weight: 500;" > · < / span >
< / div >
< / div >
<!-- Untere Zeile -->
< div class = "lw-footer-bottom" style = "position: relative; z-index: 1; display: flex; justify-content: space-between; align-items: flex-end; gap: 24px; max-width: 1320px; width: 100%; margin: 0 auto;" >
< div style = "min-width: 0;" >
< img src = "assets/logo-placeholder.svg" alt = "DieLack" style = "width: min(46vw, 360px); height: auto; display: block; opacity: .95;" >
< div style = "display: flex; align-items: center; gap: 14px; margin-top: 16px;" >
< span style = "width: 44px; height: 2px; background: linear-gradient(90deg, #2FA4F0, transparent);" > < / span >
< span style = "font-size: 13.5px; color: var(--wk-muted); font-weight: 500;" data-wk-copy = "footer-claim" > Autolackiererei & Karosserie · Geretsried< / span >
< / div >
< / div >
< div style = "text-align: right; flex-shrink: 0;" >
< p style = "font-size: 13px; color: var(--wk-muted); font-weight: 500; margin-bottom: 12px;" > © 2026 Fahrzeuglackiererei DieLack – Andreas Blatt Auto-Einbrennlackiererei · Alle Rechte vorbehalten< / p >
< div style = "display: flex; justify-content: flex-end; align-items: center; gap: 14px;" >
< a href = "https://www.facebook.com/DieLackBlatt/" target = "_blank" rel = "noopener" aria-label = "Facebook" style = "width: 36px; height: 36px; border-radius: 50%; background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.14); display: inline-flex; align-items: center; justify-content: center; color: var(--wk-body); font-weight: 800; font-size: 15px; transition: background .2s ease, transform .2s ease;" style-hover = "background: var(--accent, #2FA4F0); color: var(--wk-on-accent); transform: scale(1.1);" > f< / a >
< a href = "#impressum" style = "font-size: 13px; color: var(--wk-muted); font-weight: 500;" > Impressum< / a >
< a href = "#datenschutz" style = "font-size: 13px; color: var(--wk-muted); font-weight: 500;" > Datenschutz< / a >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< / footer >
< / div >
< / x-dc >
< script type = "text/x-dc" data-dc-script data-props = "{"$preview":{"width":1440,"height":900},"accentColor":{"editor":"color","default":"#2FA4F0","tsType":"string","section":"Design","options":["#2FA4F0","#F0912F","#E23744","#16462C","#C9A227"]},"showReviewCard":{"editor":"boolean","default":true,"tsType":"boolean","section":"Inhalt"},"rotateWords":{"editor":"boolean","default":true,"tsType":"boolean","section":"Inhalt"}}" >
class Component extends DCLogic {
state = {
loading : true ,
reviews : [ ] ,
idx : 0 ,
// 5,0 / 3 — werden nur als Text angezeigt, dürfen daher Platzhalter bleiben
rating : "5,0" ,
count : "3" ,
} ;
// Demo-/Fallback-Bewertungen (angezeigt, wenn /api/reviews nicht erreichbar ist, z. B. in der Vorschau)
// Durch echte Beispiel-Bewertungen ersetzen ODER über das eigene /api/reviews-Backend live laden.
DEMO = {
rating : "5,0" ,
user _ratings _total : "3" ,
reviews : [
{ author _name : "Andreas M." , rating : 5 , text : "Sehr guter Lackierer zu einem guten Preis – nur zu empfehlen." } ,
{ author _name : "Petra S." , rating : 5 , text : "Absolut empfehlenswert, astreine Arbeit und freundlicher Service." } ,
{ author _name : "Jürgen H." , rating : 5 , text : "Ehrliche Beratung, faire Preise und ein top Lackierergebnis." } ,
] ,
} ;
PLACE _ID = "" ;
WORDS = [ "Unfall" , "Delle" , "Beule" , "Kratzer" ] ;
componentDidMount ( ) {
this . applyAccent ( ) ;
this . sizeWordSlot ( ) ;
this . onResize = ( ) => this . sizeWordSlot ( ) ;
window . addEventListener ( "resize" , this . onResize ) ;
if ( document . fonts && document . fonts . ready ) document . fonts . ready . then ( ( ) => this . sizeWordSlot ( ) ) ;
this . loadReviews ( ) ;
if ( this . props . rotateWords !== false ) this . startWordRotator ( ) ;
this . onScroll = ( ) => this . updateNav ( ) ;
window . addEventListener ( "scroll" , this . onScroll , { passive : true } ) ;
this . updateNav ( ) ;
this . initMap ( ) ;
// Immer oben starten (kein Wiederherstellen der Scroll-Position)
if ( "scrollRestoration" in history ) history . scrollRestoration = "manual" ;
if ( ! location . hash ) requestAnimationFrame ( ( ) => window . scrollTo ( 0 , 0 ) ) ;
}
initMap ( ) {
if ( this . _map || ! this . mapEl ) return ;
if ( ! window . maplibregl ) { setTimeout ( ( ) => this . initMap ( ) , 250 ) ; return ; }
// / — Koordinaten des eigenen Standorts eintragen.
// Vorbelegt mit der geografischen Mitte Deutschlands, damit die Karte auch ohne Eintrag funktioniert.
const LNG = 10.4515 , LAT = 51.1657 ;
const map = new maplibregl . Map ( {
container : this . mapEl ,
style : "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json" ,
center : [ LNG , LAT ] ,
zoom : 14.5 ,
attributionControl : { compact : true } ,
cooperativeGestures : true ,
} ) ;
map . addControl ( new maplibregl . NavigationControl ( { showCompass : false } ) , "bottom-right" ) ;
const el = document . createElement ( "div" ) ;
el . style . cssText = "width:20px;height:20px;border-radius:50%;background:var(--wk-glow);border:3px solid #fff;box-shadow:0 0 0 6px rgba(47,164,240,.3),0 4px 12px rgba(0,0,0,.5);cursor:pointer;" ;
const popupHtml =
'<div style="font-family:Archivo,sans-serif;padding:4px 2px;min-width:190px;">' +
'<div style="font-weight:800;font-size:14px;color: var(--wk-card-ink);margin-bottom:3px;">Fahrzeuglackiererei DieLack – Andreas Blatt Auto-Einbrennlackiererei</div>' +
'<div style="font-size:12.5px;color: var(--wk-card-body);line-height:1.45;margin-bottom:8px;">Breslauer Weg 13<br>82538 Geretsried</div>' +
'<a href="https://www.google.com/maps/dir/?api=1&destination=Breslauer Weg 13, 82538 Geretsried" target="_blank" rel="noopener" style="display:inline-block;font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:#fff;background:var(--wk-glow);padding:7px 13px;border-radius:20px;text-decoration:none;">Route planen</a>' +
"</div>" ;
const popup = new maplibregl . Popup ( { offset : 20 , closeButton : false } ) . setHTML ( popupHtml ) ;
new maplibregl . Marker ( { element : el } ) . setLngLat ( [ LNG , LAT ] ) . setPopup ( popup ) . addTo ( map ) ;
popup . setLngLat ( [ LNG , LAT ] ) . addTo ( map ) ;
this . _map = map ;
}
componentDidUpdate ( ) { this . applyAccent ( ) ; }
componentWillUnmount ( ) {
clearInterval ( this . _wordTimer ) ;
clearInterval ( this . _revTimer ) ;
if ( this . _map ) { this . _map . remove ( ) ; this . _map = null ; }
window . removeEventListener ( "scroll" , this . onScroll ) ;
window . removeEventListener ( "resize" , this . onResize ) ;
}
// fix the rotating-word slot to the widest word so "Rein mit" never shifts
sizeWordSlot ( ) {
const slot = this . wordSlot , word = this . word ;
if ( ! slot || ! word ) return ;
const probe = document . createElement ( "span" ) ;
probe . style . cssText = "position:absolute;visibility:hidden;white-space:nowrap;" ;
const cs = getComputedStyle ( word ) ;
probe . style . font = cs . font ;
probe . style . fontStyle = cs . fontStyle ;
probe . style . letterSpacing = cs . letterSpacing ;
document . body . appendChild ( probe ) ;
let max = 0 ;
for ( const w of this . WORDS ) { probe . textContent = w ; max = Math . max ( max , probe . getBoundingClientRect ( ) . width ) ; }
probe . remove ( ) ;
slot . style . width = Math . ceil ( max + 2 ) + "px" ;
}
applyAccent ( ) {
if ( this . root ) this . root . style . setProperty ( "--accent" , this . props . accentColor || "#F0912F" ) ;
}
updateNav ( ) {
if ( ! this . nav ) return ;
const s = window . scrollY > 30 ;
this . nav . style . background = s ? "rgba(11,13,16,0.92)" : "transparent" ;
this . nav . style . backdropFilter = s ? "blur(14px)" : "none" ;
this . nav . style . borderBottomColor = s ? "rgba(255,255,255,0.10)" : "transparent" ;
this . nav . style . paddingTop = s ? "14px" : "22px" ;
this . nav . style . paddingBottom = s ? "14px" : "22px" ;
}
async loadReviews ( ) {
let data = null ;
try {
// In der produktiven Next.js-App trifft das den Server-Route-Handler
// /api/reviews (Place ID + GOOGLE_PLACES_API_KEY bleiben server-seitig).
const res = await fetch ( "/api/reviews" , { cache : "no-store" } ) ;
if ( res . ok ) {
const j = await res . json ( ) ;
if ( j && Array . isArray ( j . reviews ) && j . reviews . length ) data = j ;
}
} catch ( e ) { /* fall through to demo */ }
if ( ! data ) data = this . DEMO ;
const reviews = ( data . reviews || [ ] ) . filter ( r => r && r . text ) . slice ( 0 , 5 ) ;
this . setState ( {
loading : false ,
reviews ,
rating : data . rating || this . DEMO . rating ,
count : data . user _ratings _total || this . DEMO . user _ratings _total ,
} , ( ) => { if ( reviews . length > 1 ) this . startReviewRotator ( ) ; } ) ;
}
startReviewRotator ( ) {
this . _revTimer = setInterval ( ( ) => {
const el = this . reviewText ;
const next = ( this . state . idx + 1 ) % this . state . reviews . length ;
const swap = ( ) => this . setState ( { idx : next } , ( ) => { if ( this . reviewText ) this . reviewText . style . opacity = 1 ; } ) ;
if ( el ) { el . style . opacity = 0 ; setTimeout ( swap , 380 ) ; } else { swap ( ) ; }
} , 5200 ) ;
}
startWordRotator ( ) {
let i = this . WORDS . indexOf ( "Kratzer" ) ;
this . _wordTimer = setInterval ( ( ) => {
const el = this . word ;
if ( ! el ) return ;
i = ( i + 1 ) % this . WORDS . length ;
const next = this . WORDS [ i ] ;
el . animate (
[ { transform : "translateY(0)" , opacity : 1 } , { transform : "translateY(-110%)" , opacity : 0 } ] ,
{ duration : 300 , easing : "cubic-bezier(.6,0,.4,1)" , fill : "forwards" }
) . onfinish = ( ) => {
el . textContent = next ;
el . animate (
[ { transform : "translateY(110%)" , opacity : 0 } , { transform : "translateY(0)" , opacity : 1 } ] ,
{ duration : 340 , easing : "cubic-bezier(.2,.7,.3,1)" , fill : "forwards" }
) ;
} ;
} , 2400 ) ;
}
renderVals ( ) {
const st = this . state ;
const r = st . reviews [ st . idx ] || null ;
const author = r ? r . author _name : "" ;
const initial = author ? author . trim ( ) . charAt ( 0 ) . toUpperCase ( ) : "" ;
const ratingLabel = String ( st . rating ) . replace ( "." , "," ) ;
return {
rootRef : ( el ) => { this . root = el ; } ,
videoRef : ( el ) => { if ( el ) { el . muted = true ; el . volume = 0 ; } } ,
mapRef : ( el ) => { this . mapEl = el ; if ( el ) this . initMap ( ) ; } ,
navRef : ( el ) => { this . nav = el ; } ,
wordRef : ( el ) => { this . word = el ; } ,
wordSlotRef : ( el ) => { this . wordSlot = el ; } ,
reviewTextRef : ( el ) => { this . reviewText = el ; } ,
dot0Ref : ( ) => { } , dot1Ref : ( ) => { } , dot2Ref : ( ) => { } ,
showReviewCard : this . props . showReviewCard !== false ,
loading : st . loading ,
hasReview : ! st . loading && ! ! r ,
reviewAuthor : author ,
reviewInitial : initial ,
reviewText : r ? ( "“" + r . text + "”" ) : "" ,
reviewMeta : "Google Bewertung" ,
ratingLabel : ratingLabel ,
countLabel : "(" + st . count + ")" ,
googleUrl : "https://www.google.com/maps/place/?q=place_id:" + this . PLACE _ID ,
} ;
}
}
< / script >
< / body >
< / html >