diff --git a/.claude/launch.json b/.claude/launch.json index fc054dd..632ec13 100644 --- a/.claude/launch.json +++ b/.claude/launch.json @@ -58,6 +58,16 @@ "$env:APP_ENV='dev'; $env:DATABASE_URL='sqlite:///C:/Django Project/KantSites/var/kantit.db'; $env:MEDIA_DIRECTORY='C:/Django Project/KantSites/var/kantit-media'; $env:SITE_ORIGIN='http://127.0.0.1:8130'; & C:/php84/php.exe -d upload_max_filesize=8M -d post_max_size=10M -d memory_limit=256M -S 127.0.0.1:8130 -t public bin/dev-router.php" ], "port": 8130 + }, + { + "name": "maler-drews", + "runtimeExecutable": "powershell", + "runtimeArgs": [ + "-NoProfile", + "-Command", + "$env:APP_ENV='dev'; $env:DATABASE_URL='sqlite:///C:/Django Project/KantSites/var/maler-drews.db'; $env:MEDIA_DIRECTORY='C:/Django Project/KantSites/var/maler-drews-media'; $env:SITE_ORIGIN='http://127.0.0.1:8093'; & C:/php84/php.exe -d upload_max_filesize=8M -d post_max_size=10M -d memory_limit=256M -S 127.0.0.1:8093 -t public bin/dev-router.php" + ], + "port": 8093 } ] } diff --git a/README.md b/README.md index ccea91d..21d0ab9 100644 --- a/README.md +++ b/README.md @@ -329,6 +329,10 @@ In der App-Vorschau erledigt das die Startkonfiguration `elektro-bernhard` in `. Der Bestand wird nicht von Hand gepflegt, sondern aufgebaut: `scripts/seed-elektro-bernhard.php ` legt Gestaltung, Medien, Formular, Kopf- und Fußbereich, elf Seiten, vier Menüs, Einstellungen, Weiterleitungen und ein Administratorkonto an. Das Skript weigert sich, wenn die Datenbank schon Seiten enthält oder `DATABASE_URL` nicht auf diese Installation zeigt. `sh scripts/reset-elektro-bernhard.sh ` wirft die Installation weg, migriert neu und baut sie wieder auf; das Passwort des Kontos steht am Ende der Ausgabe. Vorlage ist das statische Paket `Elektro-Bernhard-Website`; die drei Stellen, an denen der Nachbau bewusst abweicht, stehen in `docs/STATUS.md`. +### Vierte lokale Referenzwebsite: Ihr Malerservice Drews + +Der Nachbau von maler-drews.com (Malermeister Axel Drews, Gernsbach) liegt in `var/maler-drews.db` mit Medien in `var/maler-drews-media`; die Startkonfiguration `maler-drews` in `.claude/launch.json` nutzt Port 8093. `scripts/seed-maler-drews.php ` baut Gestaltung, Kopf- und Fußbereich, acht Seiten, 31 Beiträge in zwei Kategorien, Menüs, Formular, Einstellungen und Weiterleitungen auf; der Wortlaut der Beiträge, des Impressums und der Datenschutzerklärung steht in `scripts/seed-maler-drews-inhalte.php`. `sh scripts/reset-maler-drews.sh [Bilderordner]` (Standard `var/maler-drews-assets`, Zuordnung in `manifest.json`) wirft die Installation weg und baut sie neu auf; die Schriften Lato 400/700 und Cormorant Garamond 700 holt es nur, wenn die Cormorant-Dateien in `public/assets/fonts` fehlen, weil `cms:fonts:fetch` die geteilte `fonts.css` sonst nur für dieses Design neu schreibt (Kant-IT und Elektro Bernhard brauchen Lato 900). Für den Abruf liegt `var/cacert.pem` (curl.se) bereit, weil das PHP 8.4 auf diesem Rechner keine Stammzertifikate kennt. Die bewussten Abweichungen vom Original stehen im Kopf des Skripts. + Zusätzliche Prüfung mit den lokalen Kant-IT-Inhalten: `node scripts/admin-quality-check.mjs` (PHP über `PHP_BINARY` wählbar). Das Skript benötigt `var/kantit.db` und `var/kantit-media`, erstellt eine eigene Datenbankkopie und ein zufälliges Testkonto darin; es ändert die Pilotdatenbank nicht. Screenshots und Bericht landen in `reports/admin-quality/`. Die Livesuche prüft `npm run test:search` mit derselben isolierten Pilotkopie: Eingabe ohne Enter, langsame Antworten, Fehler/Wiederholen, Filter, Browserhistorie, Mediathek, Tastaturfokus, mobile Ansicht und axe. Ergebnisse stehen in `reports/live-search/`. Die allgemeine Verwaltungsprüfung ohne erneuten öffentlichen Bewegungstest startet `npm run test:admin -- --admin-only`. diff --git a/docs/QUALITY.md b/docs/QUALITY.md index 6fc46da..8de02fd 100644 --- a/docs/QUALITY.md +++ b/docs/QUALITY.md @@ -1,5 +1,15 @@ # Qualitätsbericht – erster ausführbarer Prototyp +## Ergänzung: Ihr Malerservice Drews gemessen, 15.09.2026 (1.16.0 + zwei unveröffentlichte Korrekturen) + +Lighthouse **13.4.1** (`scripts/audit.mjs`, je drei Läufe Mobil und Desktop, Mediane) gegen den lokalen Produktionsmodus der vierten Referenzwebsite „Ihr Malerservice Drews“ (`var/maler-drews.db`, Port 8092), sechs Adressen: `/`, `/aktuelles`, `/unsere-projekte`, `/kunstmalerei`, `/kontakt`, `/friedrichsbad-baden-baden`. Ergebnis: **Barrierefreiheit, Best Practices, SEO und agentisches Browsing überall 100**, Leistung 98–100 – Startseite 99 mobil und 98 Desktop, Kunstmalerei 99/99, Projekte und Beitrag 99 mobil, alle übrigen 100. Der Rest zur 100 ist überall das Foto hinter dem Seitenkopf als CSS-Hintergrund (LCP mobil 1,6–2,1 s, Desktop 0,6–1,0 s; CLS ≤ 0,01, TBT ≤ 7 ms). Berichte unter `reports/lighthouse-maler-drews/`. + +Drei Messrunden führten dorthin. Die erste zeigte Barrierefreiheit 91–93: das Gold `#c6a36b` der Vorlage erreicht auf Weiß 2,4:1 (Kleinzeilen, Datum, Links, weiße Buttonschrift auf Gold), die Beitragslisten sprangen von H1 auf H3, der Copyright-Link hob sich nur durch Farbe ab, und der Nach-oben-Knopf lag außerhalb jeder Landmarke (axe „region“, auf jeder Seite). Behoben durch `@gold-text` (`#8a6a2f`, 5,0:1) für Text auf hellem Grund, dunkle Buttonschrift (6:1), eine unsichtbare H2 vor den Listen, Unterstreichung, und im CMS ein `nav` um den Knopf. Die zweite Runde ließ noch den aktiven Menüpunkt (Gold auf Weiß) und graue Formularbeschriftungen (`#999`, 2,8:1) übrig. Für die Leistung: nur das erste Hintergrundbild einer Seite wird vorgeladen – der Slider der Startseite liegt eine Ebene tiefer, deshalb trägt der äußere Abschnitt dasselbe Foto; jede im Design genannte Schriftstärke wird vorgeladen, deshalb Lato nur 400/700 (ohne das 300 der Vorlage, 23 KB weniger vor dem größten Bild); Kacheln und Galeriebilder bekamen feste Breiten, weil ohne sie eine 270 px breite Kachel die 2400er Datei lud (108 KB Ersparnis auf der Startseite laut `image-delivery`). + +axe (WCAG 2.0/2.1 A+AA und Best-Practice-Regeln, Playwright, 1440 und 390 px, nach dem Durchscrollen und zwei Sekunden Wartezeit) auf neun Seiten einschließlich Impressum und Datenschutz: **null Verstöße** (`var/drews-axe.mjs`); die erste Runde hatte 58. + +Maschinenlesbar: `llms.txt` (8 Seiten, 31 Beiträge mit Beschreibung), `robots.txt`, `sitemap.xml` (41 Adressen), `feed.xml`, `LocalBusiness` mit Adresse, Telefon, Öffnungszeiten Mo–Do/Fr, Einsatzgebiet und Instagram als `sameAs`. Nicht gemessen: Felddaten (LCP/INP/CLS am 75. Perzentil), Screenreader, Firefox/Safari, ein echtes Touchgerät, das tatsächliche Hosting. + ## Ergänzung: Elektro Bernhard gemessen, 14.09.2026 (1.12.1) Lighthouse **13** (`scripts/audit.mjs`, je drei Läufe Mobil und Desktop, Mediane) gegen den lokalen Produktionsmodus der Referenzwebsite Elektro Bernhard (`var/elektro-bernhard.db`, Port 8090), vier Adressen: `/`, `/leistungen`, `/leistungen/notdienst`, `/kontakt`. Ergebnis nach den Korrekturen: **Barrierefreiheit, Best Practices, SEO und agentisches Browsing überall 100**, Leistung überall 100 bis auf die mobile Startseite mit **99** (LCP 2,1 s durch das Hero-Foto als Hintergrund unter Mobildrosselung; CLS 0, TBT 30 ms). Berichte unter `reports/lighthouse-elektro-bernhard-2/`; der erste Lauf davor (`reports/lighthouse-elektro-bernhard/`) zeigte Barrierefreiheit 95–97. diff --git a/docs/STATUS.md b/docs/STATUS.md index a370e0b..049b1cf 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -1,5 +1,21 @@ # Projektstatus +## Ihr Malerservice Drews nachgebaut, 15.09.2026 + +**Anlass:** Umut wollte maler-drews.com (Flatsome-Auftritt, Malermeister Axel Drews, Gernsbach) nach dem bekannten Prinzip in eigener Installation nachbauen – exakt im Viewer, mit Lighthouse, axe und maschinenlesbaren Ausgaben auf 100. + +**Vorlage ausgelesen, nicht geschätzt.** Alle 9 Seiten und 31 Beiträge der laufenden Website als HTML geholt, Struktur, eigenes CSS (`malerdrews-*`, `drews-*`), Abschnittsfarben und Inline-Werte extrahiert, Screenshots in 1440 und 390 px als Vergleich. Befund: Lato + Cormorant Garamond 700, Gold `#c6a36b`, Creme `#f7f5f2`, dunkle Bänder `#232323`/`#111`/`#0a0a0a`, Kopf 90 px weiß mit Versalmenü, Startbild als Slider mit drei Folien und goldener Welle, Kartenraster aus Bild und Verlauf, Zickzackliste der Projekte, Zeitleiste der Mitteilungen. `/about-us` und `/innenaustattung` sind auf der Vorlage Lorem-ipsum-Reste, `/little-greene` ein 404. + +**Nachbau (`scripts/seed-maler-drews.php`, `scripts/seed-maler-drews-inhalte.php`, `scripts/reset-maler-drews.sh`).** Eigene Installation `var/maler-drews.db`, `var/maler-drews-media`, Bildquellen `var/maler-drews-assets` (139 Bilder, auf 2400 px verkleinert, Zuordnung in `manifest.json`), Startkonfiguration `maler-drews` auf Port 8093. Acht Seiten (Start, Aktuelles, Unsere Projekte, Kunstmalerei, Kontakt, Impressum, Datenschutz, 404), 31 Beiträge mit Bildkopf, Text, Galerie mit Bildbetrachter, Nachbarn und Aufruf, Kategorien „Aktuelles“ (5) und „Projekte“ (26); die Listen sind Beitragslisten-Bausteine (Karten auf der Startseite, Liste als Zeitleiste, Wechselseitig als Zickzack). Kopf mit Marke und Versalmenü, Fuß in vier Spalten mit Instagram, Öffnungszeiten und Rechtszeile. Formular serverseitig, Google-Karte und elf Videos als eingebettete Inhalte hinter der Einwilligungsleiste. Impressum und Datenschutz wörtlich übernommen (die Datenschutzerklärung nennt Google Analytics und reCAPTCHA, die der Nachbau nicht nutzt – vor dem Livegang zu bereinigen). Weiterleitungen für die drei toten Vorlagenadressen und die eine über 80 Zeichen lange Beitragsadresse. Bewusste Abweichungen stehen im Kopf des Skripts. + +**Für 100 geändert, nicht für die Optik:** Gold auf Weiß erreicht 2,4:1 – Kleinzeilen, Datum, Links und aktive Menüpunkte auf hellem Grund tragen `@gold-text` (`#8a6a2f`, 5,0:1), Buttons dunkle statt weiße Schrift auf Gold (6:1), der Einwilligungsknopf ebenso; vor den Beitragslisten steht eine nur für Vorlesesoftware sichtbare H2; der Copyright-Link ist unterstrichen. Das Startbild wird über den äußeren Abschnitt vorgeladen (nur das erste Hintergrundbild einer Seite bekommt ein `preload`). + +**Zwei Lücken im CMS behoben (`site.css`, `page.html.twig`, unveröffentlicht, gehört in 1.16.1):** Abschnitte mit Breite „breit“ oder „voll“ blieben so schmal wie alle anderen, weil `.kant .shell{max-width:var(--k-container)}` des Designs die Breitenregeln schlug – jetzt mit `.kant` davor. Der Nach-oben-Knopf stand außerhalb jeder Landmarke (axe „region“) und steckt jetzt in einem `nav`. Beim Bauen gelernt: eigenes CSS erlaubt kein `@media`, keine Anführungszeichen, keine Klammern in Selektoren (`:not()`, `nth-child()`), keine Kommaselektoren, und eine leere `&{…}`-Regel geht verloren – Eigenschaften des Elements ohne `&{}` schreiben. + +**Geprüft:** Lighthouse 13.4.1 (`scripts/audit.mjs`, je drei Läufe Mobil und Desktop, Mediane) gegen den lokalen Produktionsmodus (`APP_ENV=prod`, Port 8092) auf sechs Adressen (`/`, `/aktuelles`, `/unsere-projekte`, `/kunstmalerei`, `/kontakt`, `/friedrichsbad-baden-baden`): **Barrierefreiheit, Best Practices, SEO und agentisches Browsing überall 100**, Leistung 98–100 (Startseite 99 mobil / 98 Desktop, Kunstmalerei 99/99, Projekte und Beitrag 99 mobil, sonst 100; LCP ist jeweils das Foto hinter dem Seitenkopf, mobil 1,6–2,1 s, Desktop 0,6–1,0 s; CLS ≤ 0,01, TBT ≤ 7 ms). Berichte in `reports/lighthouse-maler-drews/`. Drei Messrunden davor zeigten Barrierefreiheit 91–93 (Gold-Kontrast, Überschriftenfolge, Link nur durch Farbe), dann 96–100 (aktiver Menüpunkt, Formularbeschriftungen), jetzt 100. axe (WCAG 2.0/2.1 A+AA und Best Practice, Playwright, 1440 und 390 px, nach dem Durchscrollen) auf neun Seiten einschließlich Impressum und Datenschutz: **null Verstöße** (`var/drews-axe.mjs`); vorher 58, davon 36 Kontrast, 18 „region“ am Nach-oben-Knopf, 2 Überschriftenfolge, 2 Link im Text. Maschinenlesbar: `llms.txt` mit allen Seiten und Beiträgen, `sitemap.xml` mit 41 Adressen, `robots.txt`, `feed.xml`, `LocalBusiness` mit Adresse, Öffnungszeiten, Einsatzgebiet und Instagram als `sameAs`. Alle 41 Adressen der Vorlage antworten mit 200 oder 301. Screenshots des Nachbaus in 1440 und 390 px gegen die der Vorlage verglichen (Startseite, Aktuelles, Projekte, Kunstmalerei, Kontakt, Beitrag, Impressum). PHP-Tests 512 grün (PHP 8.4), `npm test` 33 grün, Twig-Lint, php-cs-fixer auf den neuen Skripten. + +**Nicht geprüft:** der Editor auf den Drews-Dokumenten im Browser (kein Anmelden mit Passwort in dieser Sitzung), Firefox/Safari, ein echtes Touchgerät, das Hosting. Die Videos liegen weiter auf maler-drews.com und brauchen für den Livegang einen eigenen Speicherort. + ## 1.16.0 veröffentlicht (15.09.2026) Tag `v1.16.0` (Commit `32ee288`), Release: https://git.kant-it.de/kantarci/KantSites/releases/tag/v1.16.0 – Spaltenbreiten einer Zeile durch Ziehen im Editor. diff --git a/public/assets/fonts/LIZENZ.md b/public/assets/fonts/LIZENZ.md index c197641..6dffa1a 100644 --- a/public/assets/fonts/LIZENZ.md +++ b/public/assets/fonts/LIZENZ.md @@ -19,6 +19,10 @@ Dziedzic, Reserved Font Name „Lato". Die Lizenz erlaubt ausdrücklich, die Dat von einem eigenen Server auszuliefern; verboten ist der Verkauf der Schrift für sich genommen und die Verwendung des reservierten Namens für eine geänderte Fassung. +**Cormorant Garamond** (Überschriften der Referenzwebsite „Ihr Malerservice Drews") steht ebenfalls +unter der SIL Open Font License 1.1, Text in `cormorant-garamond-OFL.txt`. Copyright 2015 The +Cormorant Project Authors (github.com/CatharsisFonts/Cormorant), Reserved Font Name „Cormorant". + Wer hier andere Schriften ablegt, prüft deren Lizenz selbst: nicht jede Schrift, die Google Fonts ausliefert, steht unter der OFL – einige stehen unter der Apache-Lizenz 2.0, und eine gekaufte Schrift eines Schriftenhauses darf meist gar nicht weitergegeben werden. Die Lizenzdatei gehört in diff --git a/public/assets/fonts/cormorant-garamond-700-latin-ext.woff2 b/public/assets/fonts/cormorant-garamond-700-latin-ext.woff2 new file mode 100644 index 0000000..4ac03f9 Binary files /dev/null and b/public/assets/fonts/cormorant-garamond-700-latin-ext.woff2 differ diff --git a/public/assets/fonts/cormorant-garamond-700-latin.woff2 b/public/assets/fonts/cormorant-garamond-700-latin.woff2 new file mode 100644 index 0000000..a0fd9f6 Binary files /dev/null and b/public/assets/fonts/cormorant-garamond-700-latin.woff2 differ diff --git a/public/assets/fonts/cormorant-garamond-OFL.txt b/public/assets/fonts/cormorant-garamond-OFL.txt new file mode 100644 index 0000000..507d70f --- /dev/null +++ b/public/assets/fonts/cormorant-garamond-OFL.txt @@ -0,0 +1,93 @@ +Copyright 2015 the Cormorant Project Authors (github.com/CatharsisFonts/Cormorant) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/public/assets/fonts/fonts.css b/public/assets/fonts/fonts.css index e9d607a..bacc0d6 100644 --- a/public/assets/fonts/fonts.css +++ b/public/assets/fonts/fonts.css @@ -10,3 +10,7 @@ @font-face{font-family:'Lato';font-style:normal;font-weight:900;font-display:swap;src:url(/assets/fonts/lato-900-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF} /* latin */ @font-face{font-family:'Lato';font-style:normal;font-weight:900;font-display:swap;src:url(/assets/fonts/lato-900-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD} +/* latin-ext */ +@font-face{font-family:'Cormorant Garamond';font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/cormorant-garamond-700-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF} +/* latin */ +@font-face{font-family:'Cormorant Garamond';font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/cormorant-garamond-700-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD} diff --git a/public/assets/site.css b/public/assets/site.css index 24ba7c7..4000b45 100644 --- a/public/assets/site.css +++ b/public/assets/site.css @@ -376,9 +376,11 @@ body.consent-open{padding-bottom:320px} /* Section widths. "wide" only widens the content, "full" removes the container entirely: that is what a picture or a colour field from edge to edge needs. A full width section drops its own padding as well, otherwise "edge to edge" would still have 32 pixels of air on each side. */ -.width-wide>.section-inner{width:min(1600px,calc(100% - 64px))} -.width-full>.section-inner{width:100%;max-width:none;margin-inline:0} -@media (max-width:650px){.width-wide>.section-inner{width:calc(100% - 36px)}} +/* Mit ".kant" davor, weil das Design ".kant .shell{max-width:var(--k-container)}" schreibt: ohne + den Zusatz gewann diese Regel und ein breiter oder voller Abschnitt blieb so schmal wie alle. */ +.kant .width-wide>.section-inner{width:min(1600px,calc(100% - 64px));max-width:none} +.kant .width-full>.section-inner{width:100%;max-width:none;margin-inline:0} +@media (max-width:650px){.kant .width-wide>.section-inner{width:calc(100% - 36px)}} /* A section that is a flex container centres its content box; the inner container must then be allowed to grow, or a full height section would show a strip in the middle. */ diff --git a/scripts/reset-maler-drews.sh b/scripts/reset-maler-drews.sh new file mode 100644 index 0000000..e82b81b --- /dev/null +++ b/scripts/reset-maler-drews.sh @@ -0,0 +1,23 @@ +#!/bin/sh +# Wirft die Maler-Drews-Installation weg und baut sie neu auf. Nur fuer den Aufbau gedacht. +set -e +root="C:/Django Project/KantSites" +php="${PHP_BINARY:-C:/php84/php.exe}" +export DATABASE_URL="sqlite:///$root/var/maler-drews.db" +export MEDIA_DIRECTORY="$root/var/maler-drews-media" +rm -f "$root/var/maler-drews.db" +rm -rf "$root/var/maler-drews-media" +"$php" vendor/bin/doctrine-migrations migrate --no-interaction -q +assets="${1:-$root/var/maler-drews-assets}" +"$php" -d memory_limit=512M scripts/seed-maler-drews.php "$assets" +# Lato und Cormorant Garamond vom eigenen Server. Der Abruf schreibt fonts.css nur fuer dieses +# Design neu; die Datei teilen sich hier aber alle Installationen (Kant-IT und Elektro Bernhard +# brauchen Lato 900). Deshalb nur holen, wenn die Cormorant-Dateien fehlen. Das PHP 8.4 hier kennt +# keine Stammzertifikate; mit var/cacert.pem (https://curl.se/ca/cacert.pem) klappt der Abruf. +if [ -f "$root/public/assets/fonts/cormorant-garamond-700-latin.woff2" ]; then + echo "Schriften liegen bereits unter public/assets/fonts." +elif [ -f "$root/var/cacert.pem" ]; then + "$php" -d curl.cainfo="$root/var/cacert.pem" -d openssl.cafile="$root/var/cacert.pem" bin/console cms:fonts:fetch +else + "$php" bin/console cms:fonts:fetch +fi diff --git a/scripts/seed-maler-drews-inhalte.php b/scripts/seed-maler-drews-inhalte.php new file mode 100644 index 0000000..ed0aea1 --- /dev/null +++ b/scripts/seed-maler-drews-inhalte.php @@ -0,0 +1,328 @@ + '

Axel Drews
Ihr Malerservice Drews
Am Bachgarten 1
76593 Gernsbach

Telefon: +49 7224 40821
Telefax: +49 7224 990503
E-Mail: info@maler-drews.com

Umsatzsteuer-ID:
Umsatzsteuer-Identifikationsnummer nach §27a Umsatzsteuergesetz: DE205838338

Hinweis gemäß Online-Streitbeilegungs-Verordnung

Nach geltendem Recht sind wir verpflichtet, Verbraucher auf die Existenz der Europäischen Online-Streitbeilegungs-Plattform hinzuweisen, die für die Beilegung von Streitigkeiten genutzt werden kann, ohne dass ein Gericht eingeschaltet werden muss. Für die Einrichtung der Plattform ist die Europäische Kommission zuständig. Die Europäische Online-Streitbeilegungs-Plattform ist hier zu finden: http://ec.europa.eu/odr. Unsere E-Mail lautet: info@maler-drews.com

Wir weisen aber darauf hin, dass wir nicht bereit sind, uns am Streitbeilegungsverfahren im Rahmen der Europäischen Online-Streitbeilegungs-Plattform zu beteiligen. Nutzen Sie zur Kontaktaufnahme bitte unsere obige E-Mail und Telefonnummer.

Disclaimer – rechtliche Hinweise

§ 1 Warnhinweis zu Inhalten

Die kostenlosen und frei zugänglichen Inhalte dieser Webseite wurden mit größtmöglicher Sorgfalt erstellt. Der Anbieter dieser Webseite übernimmt jedoch keine Gewähr für die Richtigkeit und Aktualität der bereitgestellten kostenlosen und frei zugänglichen journalistischen Ratgeber und Nachrichten. Namentlich gekennzeichnete Beiträge geben die Meinung des jeweiligen Autors und nicht immer die Meinung des Anbieters wieder. Allein durch den Aufruf der kostenlosen und frei zugänglichen Inhalte kommt keinerlei Vertragsverhältnis zwischen dem Nutzer und dem Anbieter zustande, insoweit fehlt es am Rechtsbindungswillen des Anbieters.

§ 2 Externe Links

Diese Website enthält Verknüpfungen zu Websites Dritter („externe Links“). Diese Websites unterliegen der Haftung der jeweiligen Betreiber. Der Anbieter hat bei der erstmaligen Verknüpfung der externen Links die fremden Inhalte daraufhin überprüft, ob etwaige Rechtsverstöße bestehen. Zu dem Zeitpunkt waren keine Rechtsverstöße ersichtlich. Der Anbieter hat keinerlei Einfluss auf die aktuelle und zukünftige Gestaltung und auf die Inhalte der verknüpften Seiten. Das Setzen von externen Links bedeutet nicht, dass sich der Anbieter die hinter dem Verweis oder Link liegenden Inhalte zu Eigen macht. Eine ständige Kontrolle der externen Links ist für den Anbieter ohne konkrete Hinweise auf Rechtsverstöße nicht zumutbar. Bei Kenntnis von Rechtsverstößen werden jedoch derartige externe Links unverzüglich gelöscht.

§ 3 Urheber- und Leistungsschutzrechte

Die auf dieser Website veröffentlichten Inhalte unterliegen dem deutschen Urheber- und Leistungsschutzrecht. Jede vom deutschen Urheber- und Leistungsschutzrecht nicht zugelassene Verwertung bedarf der vorherigen schriftlichen Zustimmung des Anbieters oder jeweiligen Rechteinhabers. Dies gilt insbesondere für Vervielfältigung, Bearbeitung, Übersetzung, Einspeicherung, Verarbeitung bzw. Wiedergabe von Inhalten in Datenbanken oder anderen elektronischen Medien und Systemen. Inhalte und Rechte Dritter sind dabei als solche gekennzeichnet. Die unerlaubte Vervielfältigung oder Weitergabe einzelner Inhalte oder kompletter Seiten ist nicht gestattet und strafbar. Lediglich die Herstellung von Kopien und Downloads für den persönlichen, privaten und nicht kommerziellen Gebrauch ist erlaubt. Die Darstellung dieser Website in fremden Frames ist nur mit schriftlicher Erlaubnis zulässig.

§ 4 Besondere Nutzungsbedingungen

Soweit besondere Bedingungen für einzelne Nutzungen dieser Website von den vorgenannten Paragraphen abweichen, wird an entsprechender Stelle ausdrücklich darauf hingewiesen. In diesem Falle gelten im jeweiligen Einzelfall die besonderen Nutzungsbedingungen.

', + 'datenschutz' => [ + '

Wir informieren Sie nachfolgend gemäß den gesetzlichen Vorgaben des Datenschutzrechts (insb. gemäß BDSG n.F. und der europäischen Datenschutz-Grundverordnung ‚DS-GVO‘) über die Art, den Umfang und Zweck der Verarbeitung personenbezogener Daten durch unser Unternehmen. Diese Datenschutzerklärung gilt auch für unsere Websites und Sozial-Media-Profile. Bezüglich der Definition von Begriffen wie etwa „personenbezogene Daten“ oder „Verarbeitung“ verweisen wir auf Art. 4 DS-GVO.

Name und Kontaktdaten des / der Verantwortlichen
Unser/e Verantwortliche/r (nachfolgend „Verantwortlicher“) i.S.d. Art. 4 Zif. 7 DS-GVO ist:

Ihr Malerservice Drews
Am Bachgarten 1
76593 Gernsbach
Geschäftsführer: Axel Drews
Tel: +49 7224 40821
Fax: +49 7224 990503
E-Mail-Adresse: info@maler-drews.com

Datenarten, Zwecke der Verarbeitung und Kategorien betroffener Personen

Nachfolgend informieren wir Sie über Art, Umfang und Zweck der Erhebung, Verarbeitung und Nutzung personenbezogener Daten.

1. Arten der Daten, die wir verarbeiten
Nutzungsdaten (Zugriffszeiten, besuchte Websites etc.), Kontaktdaten (Telefonnummer, E-Mail, Fax etc.), Kommunikationsdaten (IP-Adresse etc.),

2. Zwecke der Verarbeitung nach Art. 13 Abs. 1 c) DS-GVO
Website technisch und wirtschaftlich optimieren, Leichten Zugang zur Website ermöglichen, Erfüllung gesetzlicher Aufbewahrungspflichten, Optimierung und statistische Auswertung unserer Dienste, Vermeidung von SPAM und Missbrauch, Kontaktanfragen abwickeln,

3. Kategorien der betroffenen Personen nach Art. 13 Abs. 1 e) DS-GVO
Besucher/Nutzer der Website, Kunden, Bewerber,

Die betroffenen Personen werden zusammenfassend als „Nutzer“ bezeichnet.


Rechtsgrundlagen der Verarbeitung personenbezogener Daten

Nachfolgend Informieren wir Sie über die Rechtsgrundlagen der Verarbeitung personenbezogener Daten:

  1. Wenn wir Ihre Einwilligung für die Verarbeitung personenbezogenen Daten eingeholt haben, ist Art. 6 Abs. 1 S. 1 lit. a) DS-GVO Rechtsgrundlage.
  2. Ist die Verarbeitung zur Erfüllung eines Vertrags oder zur Durchführung vorvertraglicher Maßnahmen erforderlich, die auf Ihre Anfrage hin erfolgen, so ist Art. 6 Abs. 1 S. 1 lit. b) DS-GVO Rechtsgrundlage.
  3. Ist die Verarbeitung zur Erfüllung einer rechtlichen Verpflichtung erforderlich, der wir unterliegen (z.B. gesetzliche Aufbewahrungspflichten), so ist Art. 6 Abs. 1 S. 1 lit. c) DS-GVO Rechtsgrundlage.
  4. Ist die Verarbeitung erforderlich, um lebenswichtige Interessen der betroffenen Person oder einer anderen natürlichen Person zu schützen, so ist Art. 6 Abs. 1 S. 1 lit. d) DS-GVO Rechtsgrundlage.
  5. Ist die Verarbeitung zur Wahrung unserer oder der berechtigten Interessen eines Dritten erforderlich und überwiegen diesbezüglich Ihre Interessen oder Grundrechte und Grundfreiheiten nicht, so ist Art. 6 Abs. 1 S. 1 lit. f) DS-GVO Rechtsgrundlage.

Weitergabe personenbezogener Daten an Dritte und Auftragsverarbeiter

Ohne Ihre Einwilligung geben wir grundsätzlich keine Daten an Dritte weiter. Sollte dies doch der Fall sein, dann erfolgt die Weitergabe auf der Grundlage der zuvor genannten Rechtsgrundlagen z.B. bei der Weitergabe von Daten an Online-Paymentanbieter zur Vertragserfüllung oder aufgrund gerichtlicher Anordnung oder wegen einer gesetzlichen Verpflichtung zur Herausgabe der Daten zum Zwecke der Strafverfolgung, zur Gefahrenabwehr oder zur Durchsetzung der Rechte am geistigen Eigentum.
Wir setzen zudem Auftragsverarbeiter (externe Dienstleister z.B. zum Webhosting unserer Websites und Datenbanken) zur Verarbeitung Ihrer Daten ein. Wenn im Rahmen einer Vereinbarung zur Auftragsverarbeitung an die Auftragsverarbeiter Daten weitergegeben werden, erfolgt dies immer nach Art. 28 DS-GVO. Wir wählen dabei unsere Auftragsverarbeiter sorgfältig aus, kontrollieren diese regelmäßig und haben uns ein Weisungsrecht hinsichtlich der Daten einräumen lassen. Zudem müssen die Auftragsverarbeiter geeignete technische und organisatorische Maßnahmen getroffen haben und die Datenschutzvorschriften gem. BDSG n.F. und DS-GVO einhalten


Datenübermittlung in Drittstaaten

Durch die Verabschiedung der europäischen Datenschutz-Grundverordnung (DS-GVO) wurde eine einheitliche Grundlage für den Datenschutz in Europa geschaffen. Ihre Daten werden daher vorwiegend durch Unternehmen verarbeitet, für die DS-GVO Anwendung findet. Sollte doch die Verarbeitung durch Dienste Dritter außerhalb der Europäischen Union oder des Europäischen Wirtschaftsraums stattfinden, so müssen diese die besonderen Voraussetzungen der Art. 44 ff. DS-GVO erfüllen. Das bedeutet, die Verarbeitung erfolgt aufgrund besonderer Garantien, wie etwa die von der EU-Kommission offiziell anerkannte Feststellung eines der EU entsprechenden Datenschutzniveaus oder der Beachtung offiziell anerkannter spezieller vertraglicher Verpflichtungen, der so genannten „Standardvertragsklauseln“.
Soweit wir aufgrund der Unwirksamkeit des sog. „Privacy Shields“, nach Art. 49 Abs. 1 S. 1 lit. a) DSGVO die ausdrückliche Einwilligung in die Datenübermittlung in die USA von Ihnen einholen, weisen wird diesbezüglich auf das Risiko eines geheimen Zugriffs durch US-Behörden und die Nutzung der Daten zu Überwachungszwecken, ggf. ohne Rechtsbehelfsmöglichkeiten für EU-Bürger, hin.


Löschung von Daten und Speicherdauer

Sofern nicht in dieser Datenschutzerklärung ausdrücklich angegeben, werden Ihre personenbezogen Daten gelöscht oder gesperrt, sobald die zur Verarbeitung erteilte Einwilligung von Ihnen widerrufen wird oder der Zweck für die Speicherung entfällt bzw. die Daten für den Zweck nicht mehr erforderlich sind, es sei denn deren weitere Aufbewahrung ist zu Beweiszwecken erforderlich oder dem stehen gesetzliche Aufbewahrungspflichten entgegenstehen. Darunter fallen etwa handelsrechtliche Aufbewahrungspflichten von Geschäftsbriefen nach § 257 Abs. 1 HGB (6 Jahre) sowie steuerrechtliche Aufbewahrungspflichten nach § 147 Abs. 1 AO von Belegen (10 Jahre). Wenn die vorgeschriebene Aufbewahrungsfrist abläuft, erfolgt eine Sperrung oder Löschung Ihrer Daten, es sei denn die Speicherung ist weiterhin für einen Vertragsabschluss oder zur Vertragserfüllung erforderlich.


Bestehen einer automatisierten Entscheidungsfindung

Wir setzen keine automatische Entscheidungsfindung oder ein Profiling ein.


Bereitstellung unserer Website und Erstellung von Logfiles
  1. Wenn Sie unsere Webseite lediglich informatorisch nutzen (also keine Registrierung und auch keine anderweitige Übermittlung von Informationen), erheben wir nur die personenbezogenen Daten, die Ihr Browser an unseren Server übermittelt. Wenn Sie unsere Website betrachten möchten, erheben wir die folgenden Daten:
    • IP-Adresse;
    • Internet-Service-Provider des Nutzers;
    • Datum und Uhrzeit des Abrufs;
    • Browsertyp;
    • Sprache und Browser-Version;
    • Inhalt des Abrufs;
    • Zeitzone;
    • Zugriffsstatus/HTTP-Statuscode;
    • Datenmenge;
    • Websites, von denen die Anforderung kommt;
    • Betriebssystem.
    Eine Speicherung dieser Daten zusammen mit anderen personenbezogenen Daten von Ihnen findet nicht statt.

  2. Diese Daten dienen dem Zweck der nutzerfreundlichen, funktionsfähigen und sicheren Auslieferung unserer Website an Sie mit Funktionen und Inhalten sowie deren Optimierung und statistischen Auswertung.

  3. Rechtsgrundlage hierfür ist unser in den obigen Zwecken auch liegendes berechtigtes Interesse an der Datenverarbeitung nach Art. 6 Abs. 1 S.1 lit. f) DS-GVO.

  4. Wir speichern aus Sicherheitsgründen diese Daten in Server-Logfiles für die Speicherdauer von Tagen. Nach Ablauf dieser Frist werden diese automatisch gelöscht, es sei denn wir benötigen deren Aufbewahrung zu Beweiszwecken bei Angriffen auf die Serverinfrastruktur oder anderen Rechtsverletzungen.

Cookies
  1. Wir verwenden sog. Cookies bei Ihrem Besuch unserer Website. Cookies sind kleine Textdateien, die Ihr Internet-Browser auf Ihrem Rechner ablegt und speichert. Wenn Sie unsere Website erneut aufrufen, geben diese Cookies Informationen ab, um Sie automatisch wiederzuerkennen. Zu den Cookies zählen auch die sog. „Nutzer-IDs“, wo Angaben der Nutzer mittels pseudonymisierter Profile gespeichert werden. Wir informieren Sie dazu beim Aufruf unserer Website mittels eines Hinweises auf unsere Datenschutzerklärung über die Verwendung von Cookies zu den zuvor genannten Zwecken und wie Sie dieser widersprechen bzw. deren Speicherung verhindern können („Opt-out“).

    Es werden folgende Cookie-Arten unterschieden:

    • Notwendige, essentielle Cookies: Essentielle Cookies sind Cookies, die zum Betrieb der Webseite unbedingt erforderlich sind, um bestimmte Funktionen der Webseite wie Logins, Warenkorb oder Nutzereingaben z.B. bzgl. Sprache der Webseite zu speichern.

    • Session-Cookies: Session-Cookies werden zum Wiedererkennen mehrfacher Nutzung eines Angebots durch denselben Nutzer (z.B. wenn Sie sich eingeloggt haben zur Feststellung Ihres Login-Status) benötigt. Wenn Sie unsere Seite erneut aufrufen, geben diese Cookies Informationen ab, um Sie automatisch wiederzuerkennen. Die so erlangten Informationen dienen dazu, unsere Angebote zu optimieren und Ihnen einen leichteren Zugang auf unsere Seite zu ermöglichen. Wenn Sie den Browser schließen oder Sie sich ausloggen, werden die Session-Cookies gelöscht.

    • Persistente Cookies: Diese Cookies bleiben auch nach dem Schließen des Browsers gespeichert. Sie dienen zur Speicherung des Logins, der Reichweitenmessung und zu Marketingzwecken. Diese werden automatisiert nach einer vorgegebenen Dauer gelöscht, die sich je nach Cookie unterscheiden kann. In den Sicherheitseinstellungen Ihres Browsers können Sie die Cookies jederzeit löschen.

    • Cookies von Drittanbietern (Third-Party-Cookies insb. von Werbetreibenden): Entsprechend Ihren Wünschen können Sie können Ihre Browser-Einstellung konfigurieren und z. B. Die Annahme von Third-Party-Cookies oder allen Cookies ablehnen. Wir weisen Sie jedoch an dieser Stelle darauf hin, dass Sie dann eventuell nicht alle Funktionen dieser Website nutzen können. Lesen Sie Näheres zu diesen Cookies bei den jeweiligen Datenschutzerklärungen zu den Drittanbietern.

  2. Datenkategorien: Nutzerdaten, Cookie, Nutzer-ID (inb. die besuchten Seiten, Geräteinformationen, Zugriffszeiten und IP-Adressen).

  3. Zwecke der Verarbeitung: Die so erlangten Informationen dienen dem Zweck, unsere Webangebote technisch und wirtschaftlich zu optimieren und Ihnen einen leichteren und sicheren Zugang auf unsere Website zu ermöglichen.

  4. Rechtsgrundlagen: Wenn wir Ihre personenbezogenen Daten mit Hilfe von Cookies aufgrund Ihrer Einwilligung verarbeiten („Opt-in“), dann ist Art. 6 Abs. 1 S. 1 lit. a) DSGVO die Rechtsgrundlage. Ansonsten haben wir ein berechtigtes Interesse an der effektiven Funktionalität, Verbesserung und wirtschaftlichen Betrieb der Website, so dass in dem Falle Art. 6 Abs. 1 S. 1 lit. f) DS-GVO Rechtsgrundlage ist. Rechtsgrundlage ist zudem Art. 6 Abs. 1 S. 1 lit. b) DS-GVO, wenn die Cookies zur Vertragsanbahnung z.B. bei Bestellungen gesetzt werden.

  5. Speicherdauer/ Löschung: Die Daten werden gelöscht, sobald sie für die Erreichung des Zweckes ihrer Erhebung nicht mehr erforderlich sind. Im Falle der Erfassung der Daten zur Bereitstellung der Website ist dies der Fall, wenn die jeweilige Session beendet ist.

    Cookies werden ansonsten auf Ihrem Computer gespeichert und von diesem an unsere Seite übermittelt. Daher haben Sie als Nutzer auch die volle Kontrolle über die Verwendung von Cookies. Durch eine Änderung der Einstellungen in Ihrem Internetbrowser können Sie die Übertragung von Cookies deaktivieren oder einschränken. Bereits gespeicherte Cookies können jederzeit gelöscht werden. Dies kann auch automatisiert erfolgen. Werden Cookies für unsere Website deaktiviert, können möglicherweise nicht mehr alle Funktionen der Website vollumfänglich genutzt werden.

    Hier finden Sie Informationen zur Löschung von Cookies nach Browsern:

    Chrome: https://support.google.com/chrome/answer/95647

    Safari: https://support.apple.com/de-at/guide/safari/sfri11471/mac

    Firefox: https://support.mozilla.org/de/kb/cookies-und-website-daten-in-firefox-loschen

    Internet Explorer: https://support.microsoft.com/de-at/help/17442/windows-internet-explorer-delete-manage-cookies

    Microsoft Edge: https://support.microsoft.com/de-at/help/4027947/windows-delete-cookies

  6. Widerspruch und „Opt-Out“: Das Speichern von Cookies auf Ihrer Festplatte können Sie unabhängig von einer Einwilligung oder gesetzlichen Erlaubnis allgemein verhindern, indem Sie in Ihren Browser-Einstellungen „keine Cookies akzeptieren“ wählen. Dies kann aber eine Funktionseinschränkung unserer Angebote zur Folge haben. Sie können dem Einsatz von Cookies von Drittanbietern zu Werbezwecken über ein sog. „Opt-out“ über diese amerikanische Website (https://optout.aboutads.info) oder diese europäische Website (http://www.youronlinechoices.com/de/praferenzmanagement/) widersprechen.


', + 'Kontaktaufnahme per Kontaktformular / E-Mail / Fax / Post
  1. Bei der Kontaktaufnahme mit uns per Kontaktformular, Fax, Post oder E-Mail werden Ihre Angaben zum Zwecke der Abwicklung der Kontaktanfrage verarbeitet.

  2. Rechtsgrundlage für die Verarbeitung der Daten ist bei Vorliegen einer Einwilligung von Ihnen Art. 6 Abs. 1 S. 1 lit. a) DS-GVO. Rechtsgrundlage für die Verarbeitung der Daten, die im Zuge einer Kontaktanfrage oder E-Mail, eines Briefes oder Faxes übermittelt werden, ist Art. 6 Abs. 1 S. 1 lit. f) DS-GVO. Der Verantwortliche hat ein berechtigtes Interesse an der Verarbeitung und Speicherung der Daten, um Anfragen der Nutzer beantworten zu können, zur Beweissicherung aus Haftungsgründen und um ggf. seiner gesetzlichen Aufbewahrungspflichten bei Geschäftsbriefen nachkommen zu können. Zielt der Kontakt auf den Abschluss eines Vertrages ab, so ist zusätzliche Rechtsgrundlage für die Verarbeitung Art. 6 Abs. 1 S. 1 lit. b) DS-GVO.

  3. Wir können Ihre Angaben und Kontaktanfrage in unserem Customer-Relationship-Management System („CRM System“) oder einem vergleichbaren System speichern.

  4. Die Daten werden gelöscht, sobald sie für die Erreichung des Zweckes ihrer Erhebung nicht mehr erforderlich sind. Für die personenbezogenen Daten aus der Eingabemaske des Kontaktformulars und diejenigen, die per E-Mail übersandt wurden, ist dies dann der Fall, wenn die jeweilige Konversation mit Ihnen beendet ist. Beendet ist die Konversation dann, wenn sich aus den Umständen entnehmen lässt, dass der betroffene Sachverhalt abschließend geklärt ist. Anfragen von Nutzern, die über einen Account bzw. Vertrag mit uns verfügen, speichern wir bis zum Ablauf von zwei Jahren nach Vertragsbeendigung. Im Fall von gesetzlichen Archivierungspflichten erfolgt die Löschung nach deren Ablauf: Ende handelsrechtlicher (6 Jahre) und steuerrechtlicher (10 Jahre) Aufbewahrungspflicht.

  5. Sie haben jederzeit die Möglichkeit, die Einwilligung nach Art. 6 Abs. 1 S. 1 lit. a) DS-GVO zur Verarbeitung der personenbezogenen Daten zu widerrufen. Nehmen Sie per E-Mail Kontakt mit uns auf, so können Sie der Speicherung der personenbezogenen Daten jederzeit widersprechen.


Kontaktaufnahme per Telefon
  1. Bei der Kontaktaufnahme mit uns per Telefon wird Ihre Telefonnummer zur Bearbeitung der Kontaktanfrage und deren Abwicklung verarbeitet und temporär im RAM / Cache des Telefongerätes / Displays gespeichert bzw. angezeigt. Die Speicherung erfolgt aus Haftungs- und Sicherheitsgründen, um den Beweis des Anrufs führen zu können sowie aus wirtschaftlichen Gründen, um einen Rückruf zu ermöglichen. Im Falle von unberechtigten Werbeanrufen, sperren wir die Rufnummern.

  2. Rechtsgrundlage für die Verarbeitung der Telefonnummer ist Art. 6 Abs. 1 S. 1 lit. f) DS-GVO. Zielt der Kontakt auf den Abschluss eines Vertrages ab, so ist zusätzliche Rechtsgrundlage für die Verarbeitung Art. 6 Abs. 1 lit. b) DS-GVO.

  3. Der Gerätecache speichert die Anrufe Tage und überschreibt bzw. löscht sukzessiv alte Daten, bei Entsorgung des Gerätes werden alle Daten gelöscht und der Speicher ggf. zerstört. Gesperrte Telefonnummer werden jährlich auf die Notwendigkeit der Sperrung geprüft.

  4. Sie können die Anzeige der Telefonnummer verhindern, indem Sie mit unterdrückter Telefonnummer anrufen.


Google Analytics
  1. Wir haben das Webseitenanalyse-Tool „Google Analytics“ (Dienstanbieter: Google Ireland Limited, Registernr.: 368047, Gordon House, Barrow Street, Dublin 4, Irland) auf unserer Website integriert.

  2. Datenkategorien und Beschreibung der Datenverarbeitung: User-ID, IP-Adresse (anonymisiert). Beim Besuch unserer Website setzt Google einen Cookie auf Ihren Computer, um die Benutzung unserer Website durch Sie analysieren zu können. Wir haben die IP-Anonymisierung „anonymizeIP“ aktiviert, wodurch die IP-Adressen nur gekürzt weiterverarbeitet werden. Auf dieser Webseite wird Ihre IP-Adresse von Google daher innerhalb von Mitgliedstaaten der Europäischen Union oder in anderen Vertragsstaaten des Abkommens über den Europäischen Wirtschaftsraum zuvor gekürzt. Nur in Ausnahmefällen wird die volle IP-Adresse an einen Server von Google in den USA übertragen und dort gekürzt. Im Auftrag des Betreibers dieser Webseite wird Google diese Informationen benutzen, um Ihre Nutzung der Webseite auszuwerten, um Reports über die Webseitenaktivitäten zusammenzustellen und um weitere, mit der Websitenutzung und der Internetnutzung verbundene, Dienstleistungen gegenüber dem Verantwortlichen zu erbringen. Wir haben darüber hinaus die geräteübergreifende Analyse von Website-Besuchern aktiviert, die über eine sog. User-ID durchgeführt wird. Die im Rahmen von Google Analytics von Ihrem Browser übermittelte IP-Adresse wird nicht mit anderen Daten von Google zusammengeführt. Weitere Informationen zu Datennutzung bei Google Analytics finden Sie hier: https://www.google.com/analytics/terms/de.html (Nutzung sbedingungen von Analytics), https://support.google.com/analytics/answer/6004245?hl=de&nb sp;(Hinweise zum Datenschutz bei Analytics) und Googles Datenschutzerklärung https://policies.google.com/privacy.

  3. Zweck der Verarbeitung: Die Nutzung von Google Analytics dient dem Zweck der Analyse, Optimierung und Verbesserung unserer Website.

  4. Rechtsgrundlagen: Haben Sie für Verarbeitung Ihrer personenbezogenen Daten mittels „Google Analytics“ vom Drittanbieter Ihre Einwilligung erteilt („Opt-in“), dann ist Art. 6 Abs. 1 S. 1 lit. a) DS-GVO die Rechtsgrundlage. Rechtsgrundlage ist zudem unser in den obigen Zwecken liegendes berechtigtes Interesse (der Analyse, Optimierung und Verbesserung unserer Website) an der Datenverarbeitung nach Art. 6 Abs. 1 S.1 lit. f) DS-GVO. Bei Services, die im Zusammenhang mit einem Vertrag erbracht werden, erfolgt das Tracking und die Analyse des Nutzerhaltens nach Art. 6 Abs. 1 S. 1 lit. b) DS-GVO, um mit den dadurch gewonnen Informationen, optimierte Services zur Erfüllung des Vertragszwecks anbieten zu können.

  5. Speicherdauer: Die von uns gesendeten und mit Cookies, Nutzerkennungen (z. B. User-ID) oder Werbe-IDs verknüpften Daten werden nach Monaten automatisch gelöscht. Die Löschung von Daten, deren Aufbewahrungsdauer erreicht ist, erfolgt automatisch einmal im Monat.

  6. Datenübermittlung/Empfängerkategorie: Google, Irland und USA. Wir haben zudem mit Google eine Vereinbarung zur Auftragsverarbeitung nach Art. 28 DS-GVO geschlossen.

  7. Widerspruchs- und Beseitigungsmöglichkeiten („Opt-Out“):
    •Das Speichern von Cookies auf Ihrer Festplatte können Sie allgemein verhindern, indem Sie in Ihren Browser-Einstellungen „keine Cookies akzeptieren“ wählen. Dies kann aber eine Funktionseinschränkung unserer Angebote zur Folge haben. Sie können darüber hinaus die Erfassung der, durch das Cookie erzeugten und auf Ihre Nutzung der Website bezogenen, Daten an Google sowie die Verarbeitung dieser Daten durch Google verhindern, indem sie das unter dem folgenden Link verfügbare Browser-Plugin herunterladen und installieren: http://tools.google.com/dlpage/gaoptout?hl=de

    •Als Alternative zum obigen Browser-Plugin können Sie die Erfassung durch Google Analytics unterbinden, indem Sie [__hier bitte__den Analytics Opt-Out Link Ihrer Webseite einfügen] klicken. Durch den Klick wird ein „Opt-out“-Cookie gesetzt, das die Erfassung Ihrer Daten beim Besuch dieser Webseite zukünftig verhindert. Dieses Cookie gilt nur für unsere Webseite und Ihren aktuellen Browser und hat nur solange Bestand bis Sie Ihre Cookies löschen. In dem Falle müssten Sie das Cookie erneut setzen.

    •Die geräteübergreifende Nutzeranalyse können Sie in Ihrem Google-Account unter „Meine Daten > persönliche Daten“ deaktivieren.


Google ReCAPTCHA
  1. Wir haben auf unserer Webseite die Anti-Spam-Funktion „reCAPTCHA“ von „Google“ (Anbieter: Google Ireland Limited, Registernr.: 368047, Gordon House, Barrow Street, Dublin 4, Irland) integriert.

  2. Datenkategorie und Beschreibung der Datenverarbeitung: Nutzungsdaten (z.B. aufgerufene Webseite, IP). Durch den Einsatz von „reCAPTCHA“ in unseren Formularen können wir feststellen, ob die Eingabe durch eine Maschine (Robot) oder einen Menschen erfolgte. Bei der Nutzung des Dienstes können Ihre IP-Adresse und ggf. weitere dafür benötigte Daten an Google-Server in den USA übertragen werden.

  3. Zweck der Verarbeitung: Vermeidung von Spam und Missbrauch sowie unser wirtschaftliches Interesse an der Optimierung unserer Website.

  4. Rechtsgrundlagen: Haben Sie für Verarbeitung Ihrer personenbezogenen Daten mittels „reCaptcha“ vom Drittanbieter Ihre Einwilligung erteilt („Opt-in“), dann ist Art. 6 Abs. 1 S. 1 lit. a) DS-GVO die Rechtsgrundlage. Rechtsgrundlage ist zudem unser in den obigen Zwecken liegendes berechtigtes Interesse an der Datenverarbeitung nach Art. 6 Abs. 1 S.1 lit. f) DS-GVO.

  5. Datenübermittlung/Empfängerkategorie: Drittanbieter in den USA.

  6. Speicherdauer: bis zur Löschung der Cookies durch Sie als Nutzer.

  7. Weitere Informationen finden Sie zu Google ReCAPTCHA unter https://www.google.com/recaptcha/ sowie in der Datenschutzerklärung von Google unter: https://policies.google.com/privacy.


', + 'Google Maps
  1. Wir haben auf unserer Website Karten von „Google Maps“ (Anbieter: Google Ireland Limited, Registernr.: 368047, Gordon House, Barrow Street, Dublin 4, Irland) integriert.

  2. Datenkategorie und Beschreibung der Datenverarbeitung: Nutzungsdaten (z.B. IP, Standort, aufgerufene Seite). Mit Google Maps können wir den Standort von Adressen und eine Anfahrtsbeschreibung direkt auf unserer Website in interaktiven Karten anzeigen und Ihnen die Nutzung dieses Tools ermöglichen. Bei dem Abruf unserer Website, wo Google Maps integriert ist, wird eine Verbindung zu den Servern von Google in den USA aufgebaut. Hierbei können Ihre IP und Standort an Google übertragen werden. Zudem erhält Google die Information, dass Sie die entsprechende Seite aufgerufen haben. Dies erfolgt auch ohne Nutzerkonto bei Google. Sollten Sie in Ihren Google-Account eingeloggt sein, kann Google die obigen Daten Ihrem Account zuordnen. Wenn Sie dies nicht wünschen, müssen Sie sich bei Ihrem Google-Account ausloggen. Google erstellt aus solchen Daten Nutzerprofile und nutzt diese Daten zum Zwecke der Werbung, Marktforschung oder Optimierung seiner Websites.

  3. Zweck der Verarbeitung: Bereitstellung einer nutzerfreundlichen, wirtschaftlichen und optimierten Webseite.

  4. Rechtsgrundlagen: Haben Sie für Verarbeitung Ihrer personenbezogenen Daten mittels „Google Maps“ vom Drittanbieter Ihre Einwilligung erteilt („Opt-in“), dann ist Art. 6 Abs. 1 S. 1 lit. a) DS-GVO die Rechtsgrundlage. Rechtsgrundlage ist zudem unser in den obigen Zwecken liegendes berechtigtes Interesse an der Datenverarbeitung nach Art. 6 Abs. 1 S.1 lit. f) DS-GVO.

  5. Datenübermittlung/Empfängerkategorie: Drittanbieter in den USA.

  6. Speicherdauer: Cookies bis zu 6 Monate oder bis zur Löschung durch Sie. Ansonsten sobald sie nicht mehr für die Verarbeitungszwecke benötigt werden.

  7. Widerspruchs- und Beseitigungsmöglichkeit: Sie haben gegenüber Google ein Widerspruchsrecht gegen die Bildung von Nutzerprofilen. Bitte richten Sie sich deswegen direkt an Google über die unten genannte Datenschutzerklärung. Ein Opt-Out-Widerspruch hinsichtlich der Werbe-Cookies können Sie hier in Ihrem Google-Account vornehmen:
    https://adssettings.google.com/authenticated.

  8. In den Nutzungsbedingungen von Google Maps unter https://www.google.com/intl/de_de/help/terms_maps.html und in der Datenschutzerklärung für Werbung von Google unter https://policies.google.com/technologies/ads finden Sie weitere Informationen zur Verwendung von Google Cookies und deren Werbetechnologien, Speicherdauer, Anonymisierung, Standortdaten, Funktionsweise und Ihre Rechte. Allgemeine Datenschutzerklärung von Google: https://policies.google.com/privacy.


Datenschutz bei Bewerbungen und im Bewerberverfahren
  1. Bewerbungen, die auf elektronischem Wege oder per Post an den Verantwortlichen gesendet werden, werden zum Zwecke der Abwicklung des Bewerberverfahrens elektronisch oder manuell verarbeitet.

  2. Wir weisen ausdrücklich darauf hin, dass Bewerbungsunterlagen mit „besonderen Kategorien personenbezogener Daten“ nach Art. 9 DS-GVO (z.B. ein Foto, welches Rückschlüsse auf Ihre ethnische Herkunft, Religion oder Ihren Familienstand gibt), mit Ausnahme einer eventuellen Schwerbehinderung, welche Sie aus freier Entscheidung offenlegen möchten, unerwünscht sind. Sie sollen Ihre Bewerbung ohne diese Daten einreichen. Dies hat keine Auswirkungen auf Ihre Bewerberchancen.

  3. Rechtsgrundlagen für die Verarbeitung sind Art. 6 Abs. 1 S.1 lit. b) DS-GVO sowie § 26 BDSG n.F.

  4. Wird nach Abschluss des Bewerberverfahrens, ein Arbeitsverhältnis mit dem Bewerber / der Bewerberin eingegangen, werden die Bewerberdaten unter Beachtung einschlägiger Datenschutzvorschriften gespeichert. Wird Ihnen nach Abschluss des Bewerberverfahrens keine Stelle angeboten, so wird Ihr eingereichtes Bewerbungsschreiben samt Unterlagen 6 Monate nach Versand der Absage gelöscht, um etwaigen Ansprüchen und Nachweispflichten nach AGG genügen zu können.


Rechte der betroffenen Person
  1. Widerspruch oder Widerruf gegen die Verarbeitung Ihrer Daten

    Soweit die Verarbeitung auf Ihrer Einwilligung gemäß Art. 6 Abs. 1 S. 1 lit. a), Art. 7 DS-GVO beruht, haben Sie das Recht, die Einwilligung jederzeit zu widerrufen. Die Rechtmäßigkeit der aufgrund der Einwilligung bis zum Widerruf erfolgten Verarbeitung wird dadurch nicht berührt.

    Soweit wir die Verarbeitung Ihrer personenbezogenen Daten auf die Interessenabwägung gemäß Art. 6 Abs. 1 S. 1 lit. f) DS-GVO stützen, können Sie Widerspruch gegen die Verarbeitung einlegen. Dies ist der Fall, wenn die Verarbeitung insbesondere nicht zur Erfüllung eines Vertrags mit Ihnen erforderlich ist, was von uns jeweils bei der nachfolgenden Beschreibung der Funktionen dargestellt wird. Bei Ausübung eines solchen Widerspruchs bitten wir um Darlegung der Gründe, weshalb wir Ihre personenbezogenen Daten nicht wie von uns durchgeführt verarbeiten sollten. Im Falle Ihres begründeten Widerspruchs prüfen wir die Sachlage und werden entweder die Datenverarbeitung einstellen bzw. anpassen oder Ihnen unsere zwingenden schutzwürdigen Gründe aufzeigen, aufgrund derer wir die Verarbeitung fortführen.

    Sie können der Verarbeitung Ihrer personenbezogenen Daten für Zwecke der Werbung und Datenanalyse jederzeit widersprechen. Das Widerspruchsrecht können Sie kostenfrei ausüben. Über Ihren Werbewiderspruch können Sie uns unter folgenden Kontaktdaten informieren:

    Ihr Malerservice Drews
    Am Bachgarten 1
    76593 Gernsbach
    Geschäftsführer Axel Drews
    Fax: +49 7224 990503
    E-Mail-Adresse: +49 7224 40821

  2. Recht auf Auskunft
    Sie haben das Recht, von uns eine Bestätigung darüber zu verlangen, ob Sie betreffende personenbezogene Daten verarbeitet werden. Sofern dies der Fall ist, haben Sie ein Recht auf Auskunft über Ihre bei uns gespeicherten persönlichen Daten nach Art. 15 DS-GVO. Dies beinhaltet insbesondere die Auskunft über die Verarbeitungszwecke, die Kategorie der personenbezogenen Daten, die Kategorien von Empfängern, gegenüber denen Ihre Daten offengelegt wurden oder werden, die geplante Speicherdauer, die Herkunft ihrer Daten, sofern diese nicht direkt bei Ihnen erhoben wurden.

  3. Recht auf Berichtigung
    Sie haben ein Recht auf Berichtigung unrichtiger oder auf Vervollständigung richtiger Daten nach Art. 16 DS-GVO.

  4. Recht auf Löschung
    Sie haben ein Recht auf Löschung Ihrer bei uns gespeicherten Daten nach Art. 17 DS-GVO, es sei denn gesetzliche oder vertraglichen Aufbewahrungsfristen oder andere gesetzliche Pflichten bzw. Rechte zur weiteren Speicherung stehen dieser entgegen.

  5. Recht auf Einschränkung
    Sie haben das Recht, eine Einschränkung bei der Verarbeitung Ihrer personenbezogenen Daten zu verlangen, wenn eine der Voraussetzungen in Art. 18 Abs. 1 lit. a) bis d) DS-GVO erfüllt ist:
    • Wenn Sie die Richtigkeit der Sie betreffenden personenbezogenen für eine Dauer bestreiten, die es dem Verantwortlichen ermöglicht, die Richtigkeit der personenbezogenen Daten zu überprüfen;

    • die Verarbeitung unrechtmäßig ist und Sie die Löschung der personenbezogenen Daten ablehnen und stattdessen die Einschränkung der Nutzung der personenbezogenen Daten verlangen;

    • der Verantwortliche die personenbezogenen Daten für die Zwecke der Verarbeitung nicht länger benötigt, Sie diese jedoch zur Geltendmachung, Ausübung oder Verteidigung von Rechtsansprüchen benötigen, oder

    • wenn Sie Widerspruch gegen die Verarbeitung gemäß Art. 21 Abs. 1 DS-GVO eingelegt haben und noch nicht feststeht, ob die berechtigten Gründe des Verantwortlichen gegenüber Ihren Gründen überwiegen.

  6. Recht auf Datenübertragbarkeit
    Sie haben ein Recht auf Datenübertragbarkeit nach Art. 20 DS-GVO, was bedeutet, dass Sie die bei uns über Sie gespeicherten personenbezogenen Daten in einem strukturierten, gängigen und maschinenlesbaren Format erhalten können oder die Übermittlung an einen anderen Verantwortlichen verlangen können.

  7. Recht auf Beschwerde
    Sie haben ein Recht auf Beschwerde bei einer Aufsichtsbehörde. In der Regel können Sie sich hierfür an die Aufsichtsbehörde insbesondere in dem Mitgliedstaat ihres Aufenthaltsorts, ihres Arbeitsplatzes oder des Orts des mutmaßlichen Verstoßes wenden.


Datensicherheit

Um alle personenbezogen Daten, die an uns übermittelt werden, zu schützen und um sicherzustellen, dass die Datenschutzvorschriften von uns, aber auch unseren externen Dienstleistern eingehalten werden, haben wir geeignete technische und organisatorische Sicherheitsmaßnahmen getroffen. Deshalb werden unter anderem alle Daten zwischen Ihrem Browser und unserem Server über eine sichere SSL-Verbindung verschlüsselt übertragen.



Stand: 06.08.2020

', + ], + 'beitraege' => [ + [ + 'slug' => '60-jahre-ihr-malerservice-drews-ein-jubilaeum-mit-tradition-und-zukunft', + 'kind' => 'news', + 'title' => '60 Jahre Ihr Malerservice Drews – Ein Jubiläum mit Tradition und Zukunft', + 'date' => '2025-10-17 09:36', + 'excerpt' => 'In diesem Jahr feiern wir ein ganz besonderes Ereignis: 60 Jahre Ihr Malerservice Drews!Seit unserer …', + 'description' => 'In diesem Jahr feiern wir ein ganz besonderes Ereignis: 60 Jahre Ihr Malerservice Drews!Seit unserer …', + 'content' => '

In diesem Jahr feiern wir ein ganz besonderes Ereignis: 60 Jahre Ihr Malerservice Drews!
Seit unserer Gründung im Jahr 1965 steht unser Familienbetrieb für Qualität, Zuverlässigkeit und Kreativität rund um alle Maler- und Lackierarbeiten. Was einst im Loffenauer Milchhäusle begann, hat sich über sechs Jahrzehnte zu einem modernen Handwerksunternehmen mit einem starken Team und zufriedenen Kundinnen und Kunden in der gesamten Region entwickelt.

Wir freuen uns sehr, dass unser Jubiläum auch in der regionalen Presse aufgegriffen wurde. Der Artikel gibt spannende Einblicke in unsere Geschichte, unsere Philosophie und die Leidenschaft, mit der wir täglich an die Arbeit gehen.

Ein herzliches Dankeschön gilt all unseren Kundinnen, Kunden, Geschäftspartnern und unserem großartigen Team – ohne Sie wäre dieser Erfolg nicht möglich gewesen.
Mit Stolz blicken wir auf 60 erfolgreiche Jahre zurück und mit Tatkraft und Freude in die Zukunft!

', + 'images' => ['bnn.jpg'], + ], + [ + 'slug' => 'aussenfassade-2', + 'kind' => 'projekt', + 'title' => 'Außenfassade', + 'date' => '2020-10-19 14:44', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['img-0008-scaled.jpg', 'img-4658.jpg', 'img-0007-scaled.jpg'], + ], + [ + 'slug' => 'aussenfassade-3', + 'kind' => 'projekt', + 'title' => 'Außenfassade', + 'date' => '2021-12-14 12:12', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['photo-2021-12-14-13-02-09.jpg'], + ], + [ + 'slug' => 'aussenfassade-44', + 'kind' => 'projekt', + 'title' => 'Außenfassade 44', + 'date' => '2020-08-03 12:29', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['photo-2020-08-03-11-31-21-2-1.jpg', 'photo-2020-08-03-11-31-21-2.jpg', 'photo-2020-08-03-11-31-21-3.jpg'], + ], + [ + 'slug' => 'aussenfassade-fachwerkhaus', + 'kind' => 'projekt', + 'title' => 'Aussenfassade Fachwerkhaus', + 'date' => '2020-08-03 12:33', + 'excerpt' => '', + 'description' => '', + 'content' => '', + 'images' => ['photo-2020-08-03-11-31-21.jpg'], + ], + [ + 'slug' => 'aussenfassade-sanierung', + 'kind' => 'projekt', + 'title' => 'Außenfassade Sanierung', + 'date' => '2021-04-08 06:28', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['gse-buetthof-bilder.jpg', 'img-0103-scaled.jpg', 'img-0104-scaled.jpg', 'img-0118-scaled.jpg'], + ], + [ + 'slug' => 'aussenfassade', + 'kind' => 'projekt', + 'title' => 'Außenfassade', + 'date' => '2020-09-14 06:18', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['photo-2020-09-12-09-50-01-1.jpg'], + ], + [ + 'slug' => 'bad', + 'kind' => 'projekt', + 'title' => 'Bad', + 'date' => '2020-10-19 14:42', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['a934b725-d7dc-4d23-a967-a8ceab1a7268.jpg'], + ], + [ + 'slug' => 'betriebsferien-vom-11-08-bis-22-08', + 'kind' => 'news', + 'title' => 'Betriebsferien vom 11.08. bis 22.08.', + 'date' => '2025-07-23 05:25', + 'excerpt' => 'Liebe Kundinnen und Kunden,bitte beachten Sie, dass wir vom 11. August bis einschließlich 22. August …', + 'description' => 'Liebe Kundinnen und Kunden,bitte beachten Sie, dass wir vom 11. August bis einschließlich 22. August …', + 'content' => '

    Liebe Kundinnen und Kunden,
    bitte beachten Sie, dass wir vom 11. August bis einschließlich 22. August Betriebsferien machen. In dieser Zeit ist unser Betrieb geschlossen. Ab dem 25. August sind wir wieder wie gewohnt für Sie da.

    Vielen Dank für Ihr Verständnis und eine schöne Sommerzeit!
    Ihr Malerservice Drews

    Danke!

    ', + 'images' => ['betriebsferien.jpg', 'betriebsferien-1.jpg'], + ], + [ + 'slug' => 'decke-zierleisten', + 'kind' => 'projekt', + 'title' => 'Rekonstruktion Decken Zierleiste', + 'date' => '2021-02-24 06:52', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['photo-2021-02-24-06-47-34-3.jpg', 'photo-2021-02-24-06-47-34.jpg', 'photo-2021-02-24-06-47-34-1.jpg', 'photo-2021-02-24-06-47-34-2.jpg', 'photo-2021-02-24-06-48-19.jpg', 'photo-2021-02-24-06-48-191.jpg'], + ], + [ + 'slug' => 'dekoration', + 'kind' => 'projekt', + 'title' => 'Dekoration', + 'date' => '2020-08-03 12:20', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['photo-2020-08-03-11-29-15.jpg', 'photo-2020-08-03-11-31-21-1.jpg'], + ], + [ + 'slug' => 'exklusiv-in-mittelbaden-wir-sind-offizieller-little-greene-partner', + 'kind' => 'news', + 'title' => 'Exklusiv in Mittelbaden: Wir sind offizieller Little Greene Partner', + 'date' => '2025-04-11 17:44', + 'excerpt' => 'Wir freuen uns sehr, Ihnen mitteilen zu können, dass unser Malerbetrieb ab sofort exklusiver Partner …', + 'description' => 'Wir freuen uns sehr, Ihnen mitteilen zu können, dass unser Malerbetrieb ab sofort exklusiver Partner …', + 'content' => '

    Wir freuen uns sehr, Ihnen mitteilen zu können, dass unser Malerbetrieb ab sofort exklusiver Partner im Raum Mittelbaden für den traditionsreichen Farben- und Tapetenhersteller Little Greene ist.
    Little Greene steht seit jeher für hochwertige sowie umweltfreundliche Farben mit beeindruckender Farbtiefe, historische Farbkollektionen mit britischem Flair und handverlesene Tapetendesigns mit Stil und Charakter.

    Als exklusiver Partner in der Region Mittelbaden bieten wir Ihnen nicht nur Zugang zu den Produkten von Little Greene, sondern auch eine umfassende Beratung und professionelle Verarbeitung direkt vom Fachbetrieb. Ob Neubau, Altbausanierung oder Innenraumgestaltung – wir setzen Ihre Wünsche mit hochwertigen Materialien und einem Sinn für Ästhetik um.
    Auf unserem Instagram-Account erhalten Sie regelmäßig neue Inspiration für Ihre Raumgestaltung mit Farben und Tapeten von Little Greene.

    ', + 'images' => ['photo-2025-04-11-14-47-35.jpg'], + ], + [ + 'slug' => 'fensterladen-verzierung', + 'kind' => 'projekt', + 'title' => 'Fensterladen Verzierung', + 'date' => '2021-12-01 14:02', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['img-5893-scaled.jpg', 'img-5869.jpg', 'img-0136-scaled.jpg'], + ], + [ + 'slug' => 'freilegen-einer-backsteinwand', + 'kind' => 'projekt', + 'title' => 'Freilegen einer Backsteinwand', + 'date' => '2023-02-16 07:37', + 'excerpt' => '', + 'description' => '', + 'content' => '', + 'images' => ['1676472540643-scaled.jpg', '1676472540620-scaled.jpg', '1676472540632-scaled.jpg'], + ], + [ + 'slug' => 'friedrichsbad-baden-baden', + 'kind' => 'projekt', + 'title' => 'Glanzvoll renoviert: Malerarbeiten im historischen Friedrichsbad, Baden‑Baden', + 'date' => '2025-07-30 09:48', + 'excerpt' => 'Im ehrwürdigen Friedrichsbad in Baden‑Baden, dem prachtvollen römisch-irischen Thermalbad im neorenaissance Stil, …', + 'description' => 'Im ehrwürdigen Friedrichsbad in Baden‑Baden, dem prachtvollen römisch-irischen Thermalbad im neorenaissance Stil, …', + 'content' => '

    Im ehrwürdigen Friedrichsbad in Baden‑Baden, dem prachtvollen römisch-irischen Thermalbad im neorenaissance Stil, wurden die Wände und Decken behutsam restauriert und neu gestaltet. Mit fein abgestimmten Farbtönen und hochwertigen Techniken hat Malermeister Drews die prachtvollen Majolika-Kacheln, die eleganten Stuckelemente und die beeindruckende Kuppelarchitektur gekonnt in Szene gesetzt – ohne den historischen Charakter zu verfälschen.

    Das Ergebnis: ein stimmiger Mix aus eleganter Modernisierung und historischer Ästhetik, der das Bad nicht nur technisch aufwertet, sondern auch den Besuchern eine visuelle Reise durch vergangene Epochen ermöglicht. Gerade in Bereichen wie Eingangsbereich, Kuppelsaal und Umkleiden wurde mit viel Feingefühl gearbeitet, um die subtile Balance zwischen Restaurierung und zeitgemäßem Farbkonzept zu wahren.

    Ob renovierte Wandflächen, frische Texturen oder veredelte Holz- und Metallbereiche – das Team hat dem Friedrichsbad ein innenarchitektonisches Gesicht verliehen, das Geschichte atmet und gleichzeitig einladend wirkt.

    ', + 'images' => ['kopie-von-2024-06-24-2.jpg', 'kopie-von-2024-06-24-4.jpg', 'kopie-von-2024-06-24-3.jpg', 'kopie-von-2024-06-24-5.jpg'], + ], + [ + 'slug' => 'frohe-weihnachten-und-einen-guten-start-ins-neue-jahr', + 'kind' => 'news', + 'title' => 'Frohe Weihnachten und einen guten Start ins neue Jahr!', + 'date' => '2025-11-23 19:33', + 'excerpt' => 'Wir bedanken uns herzlich für Ihr Vertrauen und die angenehme Zusammenarbeit im vergangenen Jahr. Der …', + 'description' => 'Wir bedanken uns herzlich für Ihr Vertrauen und die angenehme Zusammenarbeit im vergangenen Jahr. Der …', + 'content' => '

    Wir bedanken uns herzlich für Ihr Vertrauen und die angenehme Zusammenarbeit im vergangenen Jahr.

    Der gesamte Malerbetrieb wünscht Ihnen und Ihren Liebsten besinnliche Feiertage, erholsame Stunden und einen farbenfrohen Start in das Jahr 2026.

    **Betriebsferien**

    Unser Betrieb bleibt vom **22.12.2025 bis einschließlich 06.01.2026** geschlossen.

    Ab dem **07.01.2026** sind wir wie gewohnt wieder für Sie erreichbar und freuen uns darauf, Ihre Projekte mit frischen Ideen und handwerklicher Qualität umzusetzen.

    Wir wünschen Ihnen eine wundervolle Weihnachtszeit! 🎄

    ', + 'images' => ['image0.jpeg', 'image0-1.jpeg'], + ], + [ + 'slug' => 'fugenloses-bad-und-boden', + 'kind' => 'projekt', + 'title' => 'Fugenloses Bad und Boden', + 'date' => '2020-08-04 08:32', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['photo-2020-08-03-16-36-12.jpg', 'photo-2020-08-03-16-36-12-2.jpg', 'photo-2020-08-03-16-36-12-1.jpg'], + ], + [ + 'slug' => 'fugenloses-bad', + 'kind' => 'projekt', + 'title' => 'Fugenloses Bad', + 'date' => '2020-12-01 22:14', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['44d46f3a-255b-441d-8d80-e4810a150368-e1606860739106-1.jpg', 'img-20201130-155129-resized-20201130-035353784.jpg', 'img-20201130-155118-resized-20201130-035352490.jpg', 'img-20201130-155109-resized-20201130-035353150.jpg', '44d46f3a-255b-441d-8d80-e4810a150368-e1606860739106.jpg'], + ], + [ + 'slug' => 'grund-und-hauptschule', + 'kind' => 'projekt', + 'title' => 'Grund- und Hauptschule', + 'date' => '2020-08-06 08:46', + 'excerpt' => '', + 'description' => '', + 'content' => '', + 'images' => ['binarydata-big-256998.jpg'], + ], + [ + 'slug' => 'kirche', + 'kind' => 'projekt', + 'title' => 'Kirche', + 'date' => '2020-07-20 12:56', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['malerservice-drews-112-von-116.jpg'], + ], + [ + 'slug' => 'modernisierung-neugestaltung', + 'kind' => 'projekt', + 'title' => 'Modernisierung & Neugestaltung', + 'date' => '2021-11-29 13:55', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['img-5922-scaled.jpg', 'img-5921-scaled.jpg', 'img-5923-scaled.jpg', 'img-5924-scaled.jpg'], + ], + [ + 'slug' => 'sanierung-fachwerkhaus', + 'kind' => 'projekt', + 'title' => 'Sanierung Fachwerkhaus', + 'date' => '2020-09-08 04:54', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['photo-2020-09-07-10-06-38-5-1.jpg', 'photo-2020-09-07-10-06-49.jpg'], + ], + [ + 'slug' => 'sanierung-wohnzimmer-mit-kaminofen', + 'kind' => 'projekt', + 'title' => 'Sanierung Wohnzimmer mit Kaminofen', + 'date' => '2020-11-20 13:06', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['photo-2020-11-19-18-30-50.jpg', 'photo-2020-11-19-18-30-46-1.jpg', 'photo-2020-11-19-18-30-46.jpg', 'photo-2020-11-19-18-30-47.jpg', 'photo-2020-11-19-18-30-48-1.jpg', 'photo-2020-11-19-18-30-48.jpg', 'photo-2020-11-19-18-30-49-1.jpg', 'photo-2020-11-19-18-30-49.jpg', 'photo-2020-11-19-18-30-50-1.jpg', 'photo-2020-11-19-18-30-51-1.jpg', 'photo-2020-11-19-18-30-51.jpg', 'photo-2020-11-19-18-30-52.jpg'], + ], + [ + 'slug' => 'schulkindbetreuung-hilpertsau', + 'kind' => 'projekt', + 'title' => 'Unterwasserzauber – Malerarbeiten in der Schulkindbetreuung Hilpertsau', + 'date' => '2025-07-30 09:38', + 'excerpt' => 'Im ehemaligen Feuerwehrhaus in Hilpertsau wurde das Treppenhaus der Schulkindbetreuung mit liebevoll …', + 'description' => 'Im ehemaligen Feuerwehrhaus in Hilpertsau wurde das Treppenhaus der Schulkindbetreuung mit liebevoll …', + 'content' => '

    Im ehemaligen Feuerwehrhaus in Hilpertsau wurde das Treppenhaus der Schulkindbetreuung mit liebevoll gestalteten Wandmalereien in eine fantasievolle Unterwasserwelt verwandelt. Seepferdchen, bunte Fische und wellenförmige Elemente erwecken die Wände und Decken zum Leben und laden Kinder zum Staunen und Entdecken ein.

    Die kreative Gestaltung stammt vom renommierten Malermeisterbetrieb Drews aus Gernsbach – sie schafft nicht nur optische Freude, sondern fördert auch die kindliche Vorstellungskraft und Spielmotivationen

    ', + 'images' => ['kopie-von-2024-04-19-4.jpg', 'kopie-von-2024-04-19-3.jpg', 'kopie-von-2024-04-19-5.jpg', 'kopie-von-2024-04-19-6.jpg', 'kopie-von-img-1398.jpg'], + ], + [ + 'slug' => 'sommerfest-2024', + 'kind' => 'news', + 'title' => 'Sommerfest 2024', + 'date' => '2024-09-28 15:37', + 'excerpt' => 'Am vergangenen Freitag durften wir bei strahlendem Spätsommerwetter unser Sommerfest auf dem Firmengelände feiern.Zu Beginn …', + 'description' => 'Am vergangenen Freitag durften wir bei strahlendem Spätsommerwetter unser Sommerfest auf dem Firmengelände feiern.Zu Beginn …', + 'content' => '

    Am vergangenen Freitag durften wir bei strahlendem Spätsommerwetter unser Sommerfest auf dem Firmengelände feiern.
    Zu Beginn des Festes richtete unser Geschäftsführer Axel Drews einige Worte an die Anwesenden. In seiner Rede bedankte er sich bei allen für ihren unermüdlichen Einsatz und die stetige Bereitschaft, das Unternehmen mit vollem Engagement zu unterstützen. Danach folgte der Höhepunkt des Tages: Die Ehrung langjähriger Mitarbeiter.

    Drei unserer geschätzten Kollegen wurden für ihre beeindruckende Betriebszugehörigkeit geehrt und mit einer Urkunde sowie einem liebevoll zusammengestellten Präsentkorb bedacht. Eine besonders bemerkenswerte Auszeichnung erhielt Dennis Bähring, der bereits seit unglaublichen 30 Jahren Teil unseres Unternehmens ist. Dennis begann seine Laufbahn bei uns mit seiner Ausbildung und ist seitdem ein fester Bestandteil unseres Teams. In seiner langen Zeit bei uns hat er zahlreiche Projekte und Veränderungen miterlebt. Sein Engagement, seine Loyalität und sein Fachwissen sind für uns von unschätzbarem Wert.

    Andreas Vetter und Jan Kassner wurden ebenfalls für ihre langjährige Treue zum Unternehmen gewürdigt. Beide blicken auf stolze 20 Jahre Betriebszugehörigkeit zurück. In dieser Zeit haben sie durch ihre tägliche Arbeit maßgeblich zum Erfolg des Betriebs beigetragen. Sie haben sich stets als verlässliche und engagierte Mitarbeiter erwiesen, und es war uns eine Ehre, ihnen für ihre Loyalität und ihren Einsatz zu danken.

    Das Sommerfest bot den idealen Rahmen, um diese besonderen Jubiläen zu feiern und den Teamgeist noch weiter zu stärken. Bei leckerem Essen, erfrischenden Getränken und geselligen Gesprächen genossen alle Anwesenden den restlichen Abend. Es war ein gelungenes Fest, das nicht nur als Dankeschön für die Mitarbeit der vergangenen Monate diente, sondern auch als Erinnerung daran, wie wichtig das gemeinsame Miteinander in unserem Unternehmen ist.

    Noch einmal herzlichen Glückwunsch an unsere Jubilare und ein großes Dankeschön an alle Mitarbeiterinnen und Mitarbeiter für euer tägliches Engagement und eure wertvolle Arbeit! Wir freuen uns darauf, gemeinsam weiterhin erfolgreich in die Zukunft zu gehen.

    ', + 'images' => ['photo-2024-09-27-15-22-38-1.jpg', 'photo-2024-09-27-15-22-38.jpg'], + ], + [ + 'slug' => 'treppenhaus-sanierung', + 'kind' => 'projekt', + 'title' => 'Treppenhaus Sanierung', + 'date' => '2022-02-24 13:27', + 'excerpt' => '', + 'description' => '', + 'content' => '', + 'images' => ['image-50379521-scaled.jpg', 'image-50438401-scaled.jpg', 'image-50424065-scaled.jpg', 'image-50386433-scaled.jpg', 'image-50382337-scaled.jpg', 'treppenhaus-axel-2-scaled.jpg', 'treppenhaus-axel-3-scaled.jpg', 'treppenhaus-axel-4-scaled.jpg', 'treppenhaus-axel-1-scaled.jpg', 'treppenhaus-axel-5-scaled.jpg', 'treppenhaus-axel-scaled.jpg'], + ], + [ + 'slug' => 'verkleidung-einer-fassade-aus-nf-brettern', + 'kind' => 'projekt', + 'title' => 'Verkleidung einer Fassade aus N+F Brettern', + 'date' => '2023-12-19 06:23', + 'excerpt' => '', + 'description' => '', + 'content' => '', + 'images' => ['img-0594-scaled.jpg', 'screenshot-2023-12-18-084035.jpg', 'pfarramt-fassade.png', 'img-0597-scaled.jpg', 'img-0595-scaled.jpg', 'img-0596-scaled.jpg'], + ], + [ + 'slug' => 'von-abgenutzt-zu-atemberaubend-die-verwandlung-einer-tuer-durch-restauration-und-malerei', + 'kind' => 'projekt', + 'title' => 'Von Abgenutzt zu Atemberaubend: Die Verwandlung einer Tür durch Restauration und Malerei!', + 'date' => '2023-08-17 09:26', + 'excerpt' => '', + 'description' => '', + 'content' => '

    ', + 'images' => ['1692193874729-scaled.jpg', '1692193874743-scaled.jpg', 'img-9452-scaled.jpg', '1692193874974-scaled.jpg', '1692193874955-scaled.jpg'], + ], + [ + 'slug' => 'wand-beton-optik', + 'kind' => 'projekt', + 'title' => 'Wand Beton Optik', + 'date' => '2022-03-09 07:42', + 'excerpt' => '', + 'description' => '', + 'content' => '', + 'images' => ['4e4c6616-c9bb-4660-a3f5-d3617f2f9ddb-1.jpg', '41bad44a-d3b5-4859-a6ae-447dd5de5fc6.jpg', '64c6dc8d-8425-441c-8838-fe9dda248c4e.jpg', 'img-1047-scaled.jpg', 'img-1045-scaled.jpg', 'img-1046-scaled.jpg'], + ], + [ + 'slug' => 'wappen-sanierung', + 'kind' => 'projekt', + 'title' => 'Wappen Sanierung', + 'date' => '2020-10-01 11:11', + 'excerpt' => '', + 'description' => '', + 'content' => '
  • ', + 'images' => ['photo-2020-09-29-09-15-34-1.jpg'], + ], + [ + 'slug' => 'wohnzimmer-gestaltung', + 'kind' => 'projekt', + 'title' => 'Wohnzimmer Gestaltung', + 'date' => '2022-02-28 15:18', + 'excerpt' => '', + 'description' => '', + 'content' => '', + 'images' => ['wohnzimmergestaltung-2.jpg'], + ], + ], +]; diff --git a/scripts/seed-maler-drews.php b/scripts/seed-maler-drews.php new file mode 100644 index 0000000..9bdc1f6 --- /dev/null +++ b/scripts/seed-maler-drews.php @@ -0,0 +1,1122 @@ +fetchOne('SELECT id FROM page LIMIT 1')) { + fwrite(STDERR, "Diese Datenbank enthält bereits Seiten. Abbruch, damit nichts überschrieben wird.\n"); + exit(1); +} + +$inhalte = require __DIR__.'/seed-maler-drews-inhalte.php'; + +$media = new MediaLibrary($db, $mediaDirectory); +$settings = new SiteSettings($db, $media); +$validator = new DocumentValidator(); +$pages = new PageRepository($db, $validator, $settings); +$posts = new PostRepository($db, $media, $settings); +$partials = new PartialRepository($db, $validator); +$menus = new MenuRepository($db, $settings); +$forms = new FormRepository($db); +$theme = new Theme($db); +$redirects = new RedirectRepository($db); + +$mail = 'info@maler-drews.com'; +$telefon = '+49 7224 40821'; +$telHref = 'tel:+49722440821'; +$fax = '+49 7224 990503'; +$SCHEMA = 23; +$GOLD = '#c6a36b'; + +// --------------------------------------------------------------------------------------------- +// Bausteine +// --------------------------------------------------------------------------------------------- + +$ecken = static fn (string $r): array => ['topLeft' => $r, 'topRight' => $r, 'bottomRight' => $r, 'bottomLeft' => $r]; +$seiten = static fn (string $w): array => ['top' => $w, 'right' => $w, 'bottom' => $w, 'left' => $w]; +$nurOben = static fn (string $w): array => ['top' => $w, 'right' => '0px', 'bottom' => '0px', 'left' => '0px']; +$nurLinks = static fn (string $w): array => ['top' => '0px', 'right' => '0px', 'bottom' => '0px', 'left' => $w]; + +$section = static function (string $id, array $children, array $style = [], ?string $anchor = null, array $layout = []): array { + $block = ['id' => $id, 'type' => 'section', 'children' => $children, 'style' => $style]; + if (null !== $anchor) { + $block['anchor'] = $anchor; + } + if ([] !== $layout) { + $block['layout'] = $layout; + } + + return $block; +}; + +$row = static function (string $id, array $children, array $design = [], array $style = []): array { + $block = ['id' => $id, 'type' => 'row', 'children' => $children]; + if ([] !== $design) { + $block['layout'] = ['design' => $design]; + } + if ([] !== $style) { + $block['style'] = $style; + } + + return $block; +}; + +$column = static function (string $id, array $children, array $style = [], string $sichtbarkeit = 'all', string $css = ''): array { + $block = ['id' => $id, 'type' => 'column', 'children' => $children]; + if ([] !== $style) { + $block['style'] = $style; + } + if ('all' !== $sichtbarkeit) { + $block['layout'] = ['visibility' => $sichtbarkeit]; + } + if ('' !== $css) { + $block['css'] = $css; + } + + return $block; +}; + +$heading = static function (string $id, string $text, int $level, array $style = [], string $css = ''): array { + $block = ['id' => $id, 'type' => 'heading', 'props' => ['text' => $text, 'level' => $level]]; + if ([] !== $style) { + $block['style'] = $style; + } + if ('' !== $css) { + $block['css'] = $css; + } + + return $block; +}; + +$text = static function (string $id, string $inhalt, array $style = [], string $css = ''): array { + $block = ['id' => $id, 'type' => 'text', 'props' => ['text' => $inhalt]]; + if ([] !== $style) { + $block['style'] = $style; + } + if ('' !== $css) { + $block['css'] = $css; + } + + return $block; +}; + +/** Eine reine Fläche: Linien, die Welle unter dem Startbild. */ +$flaeche = static function (string $id, array $style, string $css = ''): array { + $block = ['id' => $id, 'type' => 'spacer', 'props' => ['size' => 'small'], 'style' => $style]; + if ('' !== $css) { + $block['css'] = $css; + } + + return $block; +}; + +/** + * Ein Button in einer der vier Farbfassungen der Vorlage: gold, dunkel (#333), weißer Rahmen, + * dunkler Rahmen. Der Pfeil des Bausteins bleibt nur dort, wo die Vorlage einen zeigt. + */ +$button = static function (string $id, string $text, string $href, string $fassung = 'gold', bool $pfeil = false, array $style = [], string $groesse = 'large'): array { + $farben = match ($fassung) { + 'dunkel' => '--kb-bg:#333333;--kb-fg:#ffffff;--kb-border:transparent;--kb-hover-bg:#1c1c1c;--kb-hover-fg:#ffffff', + 'weiss-rahmen' => '--kb-bg:transparent;--kb-fg:#ffffff;--kb-border:#ffffff;--kb-hover-bg:#ffffff;--kb-hover-fg:#222222', + 'dunkel-rahmen' => '--kb-bg:transparent;--kb-fg:#222222;--kb-border:#222222;--kb-hover-bg:#222222;--kb-hover-fg:#ffffff', + 'gold-rahmen' => '--kb-bg:transparent;--kb-fg:#c6a36b;--kb-border:#c6a36b;--kb-hover-bg:#c6a36b;--kb-hover-fg:#ffffff', + 'gold-pille' => '--kb-bg:#c6a36b;--kb-fg:#2a2a2a;--kb-border:transparent;--kb-hover-bg:#b4966e;--kb-hover-fg:#2a2a2a;--kb-radius:999px', + default => '--kb-bg:#c6a36b;--kb-fg:#222222;--kb-border:transparent;--kb-hover-bg:#ae8c4e;--kb-hover-fg:#222222', + }; + $css = ''.$farben.";transition:transform .4s cubic-bezier(.25,.46,.45,.94),box-shadow .4s,background-color .3s,color .3s;\n&:hover{transform:translateY(-2px);box-shadow:0 8px 25px rgba(198,163,107,.35)}"; + if (!$pfeil) { + $css .= "\n& span{display:none}"; + } else { + $css .= "\n& span{margin-left:6px}"; + } + $block = ['id' => $id, 'type' => 'button', 'props' => ['text' => $text, 'href' => $href], 'css' => $css]; + if ([] !== $style) { + $block['style'] = $style; + } + if ('large' !== $groesse) { + $block['layout'] = ['button' => ['desktop' => ['size' => $groesse]]]; + } + + return $block; +}; + +$bild = static function (string $id, array $eintrag, string $alt, array $style = [], ?string $href = null, string $css = '', bool $vergroessern = false): array { + $gross = end($eintrag['variants']); + $props = [ + 'src' => $gross['src'], 'alt' => $alt, 'decorative' => '' === $alt, 'width' => $gross['width'], 'height' => $gross['height'], + 'mediaId' => $eintrag['id'], + 'sources' => array_map(static fn (array $v): array => ['src' => $v['src'], 'width' => $v['width']], $eintrag['variants']), + ]; + if (null !== $href) { + $props['href'] = $href; + $props['click'] = 'link'; + } elseif ($vergroessern) { + $props['click'] = 'vergroessern'; + } + $block = ['id' => $id, 'type' => 'image', 'props' => $props]; + if ([] !== $style) { + $block['style'] = $style; + } + if ('' !== $css) { + $block['css'] = $css; + } + + return $block; +}; + +$symbol = static function (string $id, string $name, int $groesse, array $style = []): array { + return ['id' => $id, 'type' => 'icon', 'props' => ['icon' => $name, 'size' => $groesse, 'decorative' => true, 'label' => ''], 'style' => $style]; +}; + +/** Einblendung beim Hereinscrollen, wie Flatsome sie jedem Element anbietet. */ +$fx = static function (array $block, string $entrance = 'rise', string $delay = 'none', ?string $hover = null, ?string $shadow = null): array { + $effects = ['entrance' => $entrance, 'delay' => $delay]; + if (null !== $hover) { + $effects['hover'] = $hover; + } + if (null !== $shadow) { + $effects['shadow'] = $shadow; + } + $block['layout'] = [...($block['layout'] ?? []), 'effects' => $effects]; + + return $block; +}; + +/** Die Kleinzeile über jeder Überschrift: Gold, Versalien, weit gesperrt. */ +$kleinzeile = static function (string $id, string $inhalt, string $farbe = '#8a6a2f', string $ausrichtung = 'left', string $abstand = '18px', string $sperrung = '5px'): array { + return ['id' => $id, 'type' => 'text', 'props' => ['text' => $inhalt], + 'style' => ['desktop' => ['color' => $farbe, 'fontSize' => '11.5px', 'fontWeight' => '600', 'letterSpacing' => $sperrung, 'textTransform' => 'uppercase', 'lineHeight' => 1.5, 'textAlign' => $ausrichtung, 'margin' => ['bottom' => $abstand]]]]; +}; + +// Wiederkehrende Gestaltungswerte der Vorlage. +$h2Stil = ['desktop' => ['fontSize' => '42px', 'lineHeight' => 1.15, 'fontWeight' => '700', 'letterSpacing' => '0px', 'margin' => ['bottom' => '18px']], 'tablet' => ['fontSize' => '36px'], 'mobile' => ['fontSize' => '32px']]; +$h2Mitte = ['desktop' => [...$h2Stil['desktop'], 'textAlign' => 'center'], 'tablet' => $h2Stil['tablet'], 'mobile' => $h2Stil['mobile']]; +$h2Hell = ['desktop' => [...$h2Stil['desktop'], 'color' => '#ffffff'], 'tablet' => $h2Stil['tablet'], 'mobile' => $h2Stil['mobile']]; +$h2HellMitte = ['desktop' => [...$h2Mitte['desktop'], 'color' => '#ffffff'], 'tablet' => $h2Stil['tablet'], 'mobile' => $h2Stil['mobile']]; +$fliess = ['desktop' => ['color' => '#414141', 'fontSize' => '15px', 'lineHeight' => 1.85, 'margin' => ['bottom' => '20px']]]; +$introMitte = ['desktop' => ['color' => '#555555', 'fontSize' => '15.5px', 'lineHeight' => 1.8, 'textAlign' => 'center', 'maxWidth' => '720px', 'margin' => ['top' => '0px', 'right' => 'auto', 'bottom' => '0px', 'left' => 'auto']]]; +$introHellMitte = ['desktop' => ['color' => '#ffffff99', 'fontSize' => '16px', 'fontWeight' => '400', 'lineHeight' => 1.8, 'textAlign' => 'center', 'maxWidth' => '640px', 'margin' => ['top' => '0px', 'right' => 'auto', 'bottom' => '0px', 'left' => 'auto']]]; +$fussTitel = ['desktop' => ['color' => '#c6a36b', 'fontSize' => '11px', 'fontWeight' => '600', 'letterSpacing' => '4px', 'textTransform' => 'uppercase', 'margin' => ['bottom' => '18px']]]; +$fussText = ['desktop' => ['color' => '#fffffffc', 'fontSize' => '14.5px', 'fontWeight' => '400', 'lineHeight' => 1.85, 'margin' => ['bottom' => '14px']]]; +$bildSchatten = "& img{transition:transform .6s cubic-bezier(.25,.46,.45,.94)}\n&:hover img{transform:scale(1.04)}"; + +/** Die dunkle Karte der Beitragslisten auf der Startseite: Bild, Verlauf, Titel unten. */ +$kartenCss = '& .post-list{display:grid;gap:25px} +& .post-card{position:relative;height:clamp(340px,30vw,420px);border:0;border-radius:4px;background:#2a2a2a;overflow:hidden} +& .post-image{position:absolute;inset:0;margin:0} +& .post-image img{width:100%;height:100%;aspect-ratio:auto;object-fit:cover;opacity:.8;transition:transform .5s ease,opacity .5s ease} +& .post-card:hover .post-image img{opacity:1;transform:scale(1.05)} +& .post-view{display:none} +& .post-body{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;padding:25px;background:linear-gradient(180deg,transparent 30%,rgba(42,42,42,.95) 100%);pointer-events:none} +& .post-card h3{font-size:18px;line-height:1.3;color:#fff;font-weight:700;letter-spacing:0} +& .post-card h3 a{color:#fff;pointer-events:auto;text-decoration:none} +& .post-card h3 a:hover{color:#c6a36b}'; + +// --------------------------------------------------------------------------------------------- +// Website, Gestaltung, Medien, Formular +// --------------------------------------------------------------------------------------------- + +$db->insert('website', ['id' => 'default', 'name' => 'Ihr Malerservice Drews', 'default_locale' => 'de', 'theme' => '{}']); + +$theme->save( + [ + ['key' => 'gold', 'name' => 'Gold', 'value' => '#c6a36b'], + ['key' => 'gold-dunkel', 'name' => 'Gold dunkel', 'value' => '#ae8c4e'], + // Gold als Schrift auf Weiß erreicht nur 2,4:1; diese Abstufung schafft 5,0:1 und bleibt warm. + ['key' => 'gold-text', 'name' => 'Gold, Schrift auf hell', 'value' => '#8a6a2f'], + ['key' => 'tinte', 'name' => 'Tinte', 'value' => '#222222'], + ['key' => 'dunkel', 'name' => 'Dunkles Band', 'value' => '#232323'], + ['key' => 'nacht', 'name' => 'Fußbereich', 'value' => '#111111'], + ['key' => 'schwarz', 'name' => 'Schlusszeile', 'value' => '#0a0a0a'], + ['key' => 'creme', 'name' => 'Creme', 'value' => '#f7f5f2'], + ['key' => 'beige', 'name' => 'Beige', 'value' => '#e3cbaa'], + ['key' => 'papier', 'name' => 'Papier', 'value' => '#ffffff'], + ['key' => 'gedaempft', 'name' => 'Gedämpft', 'value' => '#555555'], + ['key' => 'linie', 'name' => 'Trennlinie', 'value' => '#e6e1d8'], + ], + [ + // Lato 400/700 trägt den Text, Cormorant Garamond 700 jede Überschrift - beide vom eigenen + // Server. Jeder genannte Schnitt wird vorgeladen; das leichte Lato 300 der Vorlage fehlt + // deshalb bewusst (23 KB weniger vor dem größten Bild), und 900 braucht diese Website nicht. + ['key' => 'body', 'name' => 'Fließtext', 'family' => 'Lato', 'source' => 'google', 'weights' => [400, 700], 'fallback' => 'sans-serif'], + ['key' => 'heading', 'name' => 'Überschriften', 'family' => 'Cormorant Garamond', 'source' => 'google', 'weights' => [700], 'fallback' => 'serif'], + ], + ['fontFamily' => 'body', 'headingFontFamily' => 'heading', 'fontSize' => '15px', 'lineHeight' => 1.7, 'color' => '@tinte', 'backgroundColor' => '@papier', 'linkColor' => '@gold-text', 'containerWidth' => '1170px', 'headingScale' => 1.25, 'linkUnderline' => false], + ['shape' => 'square', 'appearance' => 'solid', 'size' => 'large', 'fontFamily' => 'inherit', 'fontSize' => 13, 'fontWeight' => 700, 'letterSpacing' => 2, 'textTransform' => 'uppercase', 'backgroundColor' => '@gold', 'color' => '@tinte', 'hoverBackgroundColor' => '@gold-dunkel', 'hoverColor' => '@tinte'], +); + +$manifest = json_decode((string) file_get_contents(rtrim($assets, '/\\').'/manifest.json'), true, 512, JSON_THROW_ON_ERROR); +$medien = []; +$hochladen = static function (string $datei, string $alt, string $titel = '') use ($assets, $media, &$medien): array { + if (isset($medien[$datei])) { + return $medien[$datei]; + } + $pfad = rtrim($assets, '/\\').'/'.$datei; + if (!is_file($pfad)) { + fwrite(STDERR, "Bild fehlt: $pfad\n"); + exit(1); + } + $eintrag = $media->upload(new UploadedFile($pfad, $datei, null, null, true)); + $media->update($eintrag['id'], ['title' => '' !== $titel ? $titel : pathinfo($datei, PATHINFO_FILENAME), 'alt' => $alt, 'archived' => false, 'version' => $eintrag['version']]); + $medien[$datei] = $media->find($eintrag['id']); + + return $medien[$datei]; +}; + +$seitenbilder = []; +foreach ([ + 'logo' => 'Ihr Malerservice Drews', + 'favicon' => 'Ihr Malerservice Drews – Markenzeichen', + 'hero-1' => 'Malermeister Axel Drews prüft eine Wandfläche', + 'hero-2' => 'Malermeister Axel Drews bei der Arbeit', + 'hero-3' => 'Malermeister Axel Drews beim Planen mit Farbmuster', + 'ueber-1' => 'Malermeister Axel Drews prüft eine frisch gestrichene Wand', + 'ueber-2' => 'Axel Drews mit Farbmustern in der Werkstatt', + 'ueber-3' => 'Malerarbeiten des Teams von Malerservice Drews', + 'ueber-4' => 'Das Team von Malerservice Drews bei der Arbeit', + 'kunst-bg' => 'Dekorative Wandgestaltung in Steinoptik', + 'kunst-1' => 'Wandgestaltung in Steinoptik in einem Rohbau', + 'kunst-2' => 'Grün gestrichener Raum mit Tageslicht', + 'kunst-3' => 'Farbige Wandgestaltung eines Wohnraums', + 'lg-1' => 'Little Greene – Tapete Upper Brook Street', + 'lg-2' => 'Little Greene – Farbton Mischief', + 'lg-3' => 'Little Greene – Farbton Puck', + 'lg-4' => 'Little Greene – Farbkombinationen', + 'marke-littlegreene' => 'Little Greene', + 'marke-brillux' => 'Brillux', + 'marke-gori' => 'Gori', + 'marke-keim' => 'Keim', + 'marke-sikkens' => 'Sikkens', + 'marke-henkel' => 'Henkel', + 'partner-eisen' => 'Eisen-Raumausstattung', + 'partner-lichtkraus' => 'Licht Kraus Sasbach', + 'partner-kant' => 'Kant-IT Solutions', + 'kontakt-foto' => 'Axel Drews telefoniert vor dem Firmenwagen', + 'projekte-bg' => 'Restaurierte Wandmalerei im Friedrichsbad Baden-Baden', + 'aktuelles-cta-bg' => 'Rücken eines Mitarbeiters mit dem Schriftzug Ihr Malerservice Drews', + 'kunst-portrait' => 'Treppenhaus mit Unterwasser-Wandmalerei', +] as $schluessel => $alt) { + $seitenbilder[$schluessel] = $hochladen($manifest['pages'][$schluessel], $alt, $schluessel); + echo "Bild übernommen: {$manifest['pages'][$schluessel]}\n"; +} +$galerie = []; +foreach ($manifest['galerie'] as $i => $datei) { + $galerie[] = $hochladen($datei, 'Kunstmalerei von Malerservice Drews – Werk '.($i + 1), 'kunstmalerei-'.($i + 1)); +} +echo 'Galeriebilder übernommen: '.count($galerie)."\n"; + +$forms->save('kontakt', 'Kontaktanfrage', [ + ['name' => 'name', 'type' => 'text', 'label' => 'Ihr Name', 'required' => true], + ['name' => 'email', 'type' => 'email', 'label' => 'Ihre E-Mail-Adresse', 'required' => true], + ['name' => 'betreff', 'type' => 'text', 'label' => 'Betreff', 'required' => false], + ['name' => 'nachricht', 'type' => 'textarea', 'label' => 'Ihre Nachricht', 'required' => false], + ['name' => 'datenschutz', 'type' => 'consent', 'label' => 'Ich stimme den Datenschutzrichtlinien zu; meine Daten werden zur Kontaktaufnahme gespeichert.'], +], ['recipient' => $mail, 'subject' => 'Neue Anfrage über maler-drews.com', 'success' => 'Vielen Dank für Ihre Nachricht. Wir melden uns innerhalb von 24 Stunden bei Ihnen.', 'replyToField' => 'email', 'buttonLabel' => 'Senden', 'fieldBorderColor' => '#dddddd', 'fieldBackgroundColor' => '#ffffff', 'buttonColor' => '@gold', 'buttonInk' => '@tinte'], 0); +echo "Formular angelegt: kontakt\n"; + +// --------------------------------------------------------------------------------------------- +// Kopfbereich: weiß, 90 px hoch, Marke links, Menü in Versalien rechts +// --------------------------------------------------------------------------------------------- + +$kopf = [ + 'schemaVersion' => $SCHEMA, 'title' => 'Kopfbereich', 'description' => 'Erscheint auf jeder Seite über dem Inhalt.', + 'blocks' => [ + $section('kopf', [ + $row('kopf-zeile', [ + $column('kopf-marke', [ + $bild('kopf-logo', $seitenbilder['logo'], 'Ihr Malerservice Drews – zur Startseite', ['desktop' => ['maxWidth' => '200px', 'margin' => $seiten('0px')], 'mobile' => ['maxWidth' => '150px']], '/'), + ], ['desktop' => ['flexShrink' => 0]]), + $column('kopf-navigation', [ + ['id' => 'kopf-menue', 'type' => 'menu', 'props' => ['slot' => 'header', 'layout' => 'horizontal', 'collapse' => 'tablet', 'burgerLabel' => 'icon'], + 'style' => ['desktop' => ['fontSize' => '13px', 'fontWeight' => '700', 'letterSpacing' => '0.8px', 'textTransform' => 'uppercase', 'color' => '@tinte', 'justifyContent' => 'flex-end', 'burgerColor' => '@tinte', 'burgerBorderColor' => '#ffffff00']], + 'css' => "& .menu-list{gap:4px 40px;justify-content:flex-end}\n& .menu-list a{padding:8px 0;transition:color .25s}\n& .menu-list a:hover{color:#8a6a2f;text-decoration:none}\n& .menu-list [aria-current=page]{color:#8a6a2f}"], + ], ['desktop' => ['display' => 'flex', 'justifyContent' => 'flex-end', 'alignItems' => 'center']]), + ], [], ['desktop' => ['display' => 'flex', 'alignItems' => 'center', 'justifyContent' => 'space-between', 'gap' => '30px', 'minHeight' => '90px', 'margin' => ['top' => '0px']], 'mobile' => ['minHeight' => '70px']]), + ], ['desktop' => ['backgroundColor' => '@papier', 'padding' => ['top' => '0px', 'bottom' => '0px']]]), + ], +]; + +// --------------------------------------------------------------------------------------------- +// Fußbereich: vier Spalten auf #111, Schlusszeile auf #0a0a0a +// --------------------------------------------------------------------------------------------- + +$zeitenZeile = static function (string $id, string $tag, string $zeit, bool $erste = false, bool $kursiv = false) use ($row, $column, $text, $nurOben): array { + return $row($id, [ + $column($id.'-tag', [$text($id.'-tag-text', $tag, ['desktop' => ['fontSize' => '14px', 'color' => '#fffffffc', 'margin' => ['bottom' => '0px']]])]), + $column($id.'-zeit', [$text($id.'-zeit-text', $zeit, ['desktop' => ['fontSize' => '14px', 'fontWeight' => $kursiv ? '300' : '400', 'fontStyle' => $kursiv ? 'italic' : 'normal', 'color' => '#fffffffc', 'textAlign' => 'right', 'margin' => ['bottom' => '0px']]])]), + ], [], ['desktop' => ['display' => 'flex', 'justifyContent' => 'space-between', 'gap' => '20px', 'margin' => ['top' => '0px'], 'padding' => ['top' => $erste ? '0px' : '9px', 'bottom' => '9px']] + + ($erste ? [] : ['borderWidth' => $nurOben('1px'), 'borderStyle' => 'solid', 'borderColor' => '#ffffff0f'])]); +}; + +$fuss = [ + 'schemaVersion' => $SCHEMA, 'title' => 'Fußbereich', 'description' => 'Erscheint auf jeder Seite unter dem Inhalt.', + 'blocks' => [ + $section('fuss', [ + $row('fuss-zeile', [ + $column('fuss-ueber', [ + $text('fuss-ueber-text', 'Seit über 60 Jahren steht der Name Drews für erstklassiges Malerhandwerk im Raum Gernsbach und Mittelbaden – mit Leidenschaft, Präzision und einem Auge für das Besondere.', ['desktop' => ['color' => '#fffffffc', 'fontSize' => '14px', 'lineHeight' => 1.85, 'margin' => ['bottom' => '20px']]]), + ['id' => 'fuss-sozial', 'type' => 'social', 'props' => ['size' => 16, 'shape' => 'circle', 'layout' => 'horizontal', 'labels' => false, 'networks' => [], 'newTab' => true], + 'style' => ['desktop' => ['color' => '#ffffff', 'hover' => ['color' => '@gold']]], + 'css' => "& a{border:1px solid rgba(255,255,255,.35);background:transparent;transition:border-color .3s,color .3s}\n& a:hover{border-color:#c6a36b}"], + ]), + $column('fuss-navigation', [ + $text('fuss-navigation-titel', 'Navigation', $fussTitel), + ['id' => 'fuss-menue', 'type' => 'menu', 'props' => ['slot' => 'footer', 'layout' => 'vertical'], + 'style' => ['desktop' => ['fontSize' => '14.5px', 'fontWeight' => '400', 'color' => '#fffffffc']], + 'css' => "& .menu-list{gap:12px}\n& .menu-list a{padding:0;transition:color .3s}\n& .menu-list a:hover{color:#c6a36b;text-decoration:none}\n& .menu-list [aria-current=page]{font-weight:300}"], + ]), + $column('fuss-kontakt', [ + $text('fuss-kontakt-titel', 'Kontakt', $fussTitel), + $text('fuss-kontakt-adresse', 'Am Bachgarten 1
    76593 Gernsbach', $fussText), + $text('fuss-kontakt-daten', 'Tel  '.$telefon.'
    Fax  '.$fax.'
    Mail  '.$mail.'', ['desktop' => [...$fussText['desktop'], 'margin' => ['bottom' => '0px']]], "& strong{font-weight:400;margin-right:6px}\n& a{color:#fff;text-decoration:none}\n& a:hover{color:#c6a36b}"), + ]), + $column('fuss-zeiten', [ + $text('fuss-zeiten-titel', 'Öffnungszeiten', $fussTitel), + $zeitenZeile('fuss-zeit-1', 'Mo – Do', '07:00 – 16:30', true), + $zeitenZeile('fuss-zeit-2', 'Freitag', '07:00 – 13:00'), + $zeitenZeile('fuss-zeit-3', 'Sa & So', 'nach Vereinbarung', false, true), + $button('fuss-anfrage', 'Projekt anfragen', '/kontakt', 'gold-rahmen', false, ['desktop' => ['margin' => ['top' => '14px']]], 'small'), + ]), + ], ['desktop' => ['columns' => 'four', 'gap' => 'large'], 'tablet' => ['columns' => 'two'], 'mobile' => ['columns' => 'one']], ['desktop' => ['margin' => ['top' => '0px']]]), + ], ['desktop' => ['backgroundColor' => '@nacht', 'color' => '#ffffff', 'padding' => ['top' => '60px', 'bottom' => '50px']], 'mobile' => ['padding' => ['top' => '44px', 'bottom' => '36px']]]), + $section('fuss-schluss', [ + $row('fuss-schluss-zeile', [ + $column('fuss-schluss-links', [ + $text('fuss-copyright', '© 2026 Ihr Malerservice Drews · Webdesign by Kant-IT Solutions', ['desktop' => ['color' => '#ffffff', 'fontSize' => '12.5px', 'fontWeight' => '400', 'letterSpacing' => '0.5px', 'margin' => ['bottom' => '0px']]], "& a{color:#c6a36b;text-decoration:underline;text-underline-offset:3px}\n& a:hover{text-decoration-thickness:2px}"), + ]), + $column('fuss-schluss-rechts', [ + ['id' => 'fuss-rechtliches', 'type' => 'legal', 'props' => ['label' => 'Rechtliches'], + 'style' => ['desktop' => ['color' => '#ffffff', 'fontSize' => '12.5px', 'fontWeight' => '400', 'justifyContent' => 'flex-end', 'gap' => '20px'], 'mobile' => ['justifyContent' => 'flex-start']], + 'css' => "& span{display:none}\n& a{transition:color .3s}\n& a:hover{color:#c6a36b}"], + ]), + ], ['desktop' => ['columns' => 'two', 'gap' => 'medium'], 'mobile' => ['columns' => 'one']], ['desktop' => ['alignItems' => 'center', 'margin' => ['top' => '0px']], 'mobile' => ['gap' => '10px']]), + ], ['desktop' => ['backgroundColor' => '@schwarz', 'color' => '#ffffff', 'padding' => ['top' => '22px', 'bottom' => '22px']]]), + ], +]; + +$partials->create('header', 'default', 'Kopfbereich', $kopf); +$partials->create('footer', 'default', 'Fußbereich', $fuss); +echo "Kopf- und Fußbereich angelegt\n"; + +// --------------------------------------------------------------------------------------------- +// Wiederkehrende Abschnitte +// --------------------------------------------------------------------------------------------- + +/** Der dunkle Seitenkopf der Unterseiten: Foto mit Überlagerung, Kleinzeile, Titel, Vorspann. */ +$seitenkopf = static function (string $praefix, array $foto, string $label, string $h1, string $intro, string $minHeight = '50vh', string $overlay = '#050505', float $deckung = 0.68, array $zusatz = [], string $position = 'center') use ($section, $column, $kleinzeile, $heading, $text, $fx, $introHellMitte): array { + $kinder = [ + $fx($kleinzeile($praefix.'-label', $label, '#c6a36b', 'center', '18px', '6px'), 'fade'), + $fx($heading($praefix.'-h1', $h1, 1, ['desktop' => ['fontSize' => '58px', 'lineHeight' => 1.08, 'letterSpacing' => '-1px', 'fontWeight' => '700', 'color' => '#ffffff', 'textAlign' => 'center', 'margin' => ['bottom' => '20px']], 'tablet' => ['fontSize' => '46px'], 'mobile' => ['fontSize' => '38px']]), 'rise', 'short'), + ]; + if ('' !== $intro) { + $kinder[] = $fx($text($praefix.'-intro', $intro, $introHellMitte), 'rise', 'medium'); + } + foreach ($zusatz as $block) { + $kinder[] = $fx($block, 'rise', 'long'); + } + + return $section($praefix.'-kopf', [$column($praefix.'-kopf-inhalt', $kinder, ['desktop' => ['maxWidth' => '900px', 'margin' => ['left' => 'auto', 'right' => 'auto']]])], [ + 'desktop' => ['backgroundImage' => $foto['id'], 'backgroundSize' => 'cover', 'backgroundPosition' => $position, 'overlayColor' => $overlay, 'overlayOpacity' => $deckung, + 'color' => '#ffffff', 'minHeight' => $minHeight, 'display' => 'flex', 'alignItems' => 'center', 'padding' => ['top' => '80px', 'bottom' => '80px']], + 'mobile' => ['padding' => ['top' => '60px', 'bottom' => '60px']], + ]); +}; + +/** Ein zentrierter Abschnittskopf: Kleinzeile, Überschrift, Vorspann. */ +$abschnittskopf = static function (string $praefix, string $label, string $titel, string $intro, bool $hell = false) use ($kleinzeile, $heading, $text, $fx, $h2Mitte, $h2HellMitte, $introMitte, $introHellMitte): array { + return [ + $fx($kleinzeile($praefix.'-label', $label, $hell ? '#c6a36b' : '#8a6a2f', 'center', '18px', '6px'), 'fade'), + $fx($heading($praefix.'-titel', $titel, 2, $hell ? $h2HellMitte : $h2Mitte), 'rise'), + $fx($text($praefix.'-intro', $intro, $hell ? $introHellMitte : $introMitte), 'rise', 'short'), + ]; +}; + +/** Der dunkle Handlungsaufruf am Ende von Startseite und Aktuelles. */ +$aufruf = static function (string $praefix, string $label, string $titel, string $intro, string $knopf, ?array $foto = null) use ($section, $column, $abschnittskopf, $text, $button, $fx, $telHref, $telefon, $mail): array { + $style = ['desktop' => ['backgroundColor' => '@dunkel', 'color' => '#ffffff', 'padding' => ['top' => '130px', 'bottom' => '130px']], 'mobile' => ['padding' => ['top' => '80px', 'bottom' => '80px']]]; + if (null !== $foto) { + $style['desktop'] = [...$style['desktop'], 'backgroundImage' => $foto['id'], 'backgroundSize' => 'cover', 'backgroundPosition' => 'center', 'overlayColor' => '#050505', 'overlayOpacity' => 0.6, 'padding' => ['top' => '110px', 'bottom' => '110px']]; + } + + return $section($praefix, [ + $column($praefix.'-inhalt', [ + ...$abschnittskopf($praefix, $label, $titel, $intro, true), + $fx($text($praefix.'-kontaktzeile', 'Tel. '.$telefon.' · '.$mail.'', ['desktop' => ['color' => '#ffffff99', 'fontSize' => '14px', 'letterSpacing' => '2px', 'textAlign' => 'center', 'margin' => ['top' => '24px', 'bottom' => '35px']]], "& a{color:inherit;text-decoration:none}\n& a:hover{color:#c6a36b}"), 'fade', 'medium'), + $fx($button($praefix.'-knopf', $knopf, '/kontakt', 'gold', true, ['desktop' => ['margin' => ['top' => '0px', 'left' => 'auto', 'right' => 'auto']]]), 'rise', 'long'), + ], ['desktop' => ['display' => 'flex', 'flexDirection' => 'column', 'alignItems' => 'center', 'maxWidth' => '860px', 'margin' => ['left' => 'auto', 'right' => 'auto']]]), + ], $style); +}; + +// --------------------------------------------------------------------------------------------- +// Startseite +// --------------------------------------------------------------------------------------------- + +/** Eine Folie des Startbilds: Foto, dunkle Überlagerung, zentrierter Text, Welle unten. */ +$folie = static function (int $n, array $foto, bool $erste) use ($section, $column, $row, $text, $heading, $button, $flaeche, $fx): array { + $titelStil = ['desktop' => ['fontFamily' => 'heading', 'fontSize' => '72px', 'fontWeight' => '700', 'lineHeight' => 1.08, 'letterSpacing' => '-1.5px', 'color' => '#ffffff', 'textAlign' => 'center', 'margin' => ['bottom' => '0px'], 'textShadowY' => '2px', 'textShadowBlur' => '40px', 'textShadowColor' => '#0000004d'], 'tablet' => ['fontSize' => '54px'], 'mobile' => ['fontSize' => '40px', 'letterSpacing' => '-0.5px']]; + $titelText = 'Oberflächen,
    die Eindruck hinterlassen.'; + $emCss = '& em{font-style:normal;color:#c6a36b}'; + $titel = $erste + ? $heading('folie-'.$n.'-titel', $titelText, 1, $titelStil, $emCss) + : $text('folie-'.$n.'-titel', $titelText, $titelStil, $emCss); + $kinder = [ + $text('folie-'.$n.'-label', 'Malermeister Axel Drews · Gernsbach', ['desktop' => ['color' => '#ffffffcc', 'fontSize' => '13px', 'fontWeight' => '500', 'letterSpacing' => '6px', 'textTransform' => 'uppercase', 'textAlign' => 'center', 'margin' => ['bottom' => '22px']], 'mobile' => ['fontSize' => '12px', 'letterSpacing' => '4px']]), + $titel, + $text('folie-'.$n.'-intro', 'Saubere Ausführung, präzise Details und hochwertige Materialien –
    Malerhandwerk für Menschen mit Anspruch.', ['desktop' => ['color' => '#ffffff', 'fontSize' => '15px', 'fontWeight' => '400', 'lineHeight' => 1.8, 'textAlign' => 'center', 'maxWidth' => '680px', 'margin' => ['top' => '18px', 'right' => 'auto', 'bottom' => '26px', 'left' => 'auto']]]), + $row('folie-'.$n.'-aktionen', [ + $column('folie-'.$n.'-aktion-1', [$button('folie-'.$n.'-anfrage', 'Projekt anfragen', '/kontakt', 'dunkel', false, ['desktop' => ['margin' => ['top' => '0px']]])]), + $column('folie-'.$n.'-aktion-2', [$button('folie-'.$n.'-referenzen', 'Referenzen ansehen', '/unsere-projekte', 'weiss-rahmen', false, ['desktop' => ['margin' => ['top' => '0px']]])]), + ], [], ['desktop' => ['display' => 'flex', 'flexWrap' => 'wrap', 'justifyContent' => 'center', 'gap' => '15px', 'margin' => ['top' => '0px']]]), + ]; + if ($erste) { + $kinder = [ + $fx($kinder[0], 'fade'), $fx($kinder[1], 'rise', 'short'), $fx($kinder[2], 'rise', 'medium'), $fx($kinder[3], 'rise', 'long'), + ]; + } + + return $section('folie-'.$n, [ + $column('folie-'.$n.'-text', $kinder, ['desktop' => ['maxWidth' => '60%', 'margin' => ['left' => 'auto', 'right' => 'auto'], 'position' => 'relative', 'zIndex' => 2], 'tablet' => ['maxWidth' => '90%'], 'mobile' => ['maxWidth' => '100%']]), + // Der Pfeil nach unten, wie in der Vorlage am unteren Rand der Folie. + $text('folie-'.$n.'-pfeil', '⌄', ['desktop' => ['position' => 'absolute', 'left' => '0px', 'right' => '0px', 'bottom' => '58px', 'textAlign' => 'center', 'fontSize' => '29px', 'lineHeight' => 1, 'color' => '#ffffff66', 'zIndex' => 2, 'margin' => ['bottom' => '0px']]], "& a{color:inherit;text-decoration:none;display:inline-block}\n& a:hover{color:#fff}"), + // Die Welle am unteren Rand: zwei runde Flächen in Gold, die hintere halb durchsichtig. + $flaeche('folie-'.$n.'-welle-hinten', ['desktop' => ['position' => 'absolute', 'left' => '-25%', 'right' => '-10%', 'bottom' => '-80px', 'height' => '190px', 'backgroundColor' => '#b4966e', 'opacity' => 0.35, 'zIndex' => 1, 'borderRadius' => ['topLeft' => '55%', 'topRight' => '45%', 'bottomRight' => '0px', 'bottomLeft' => '0px']]], 'border-top-left-radius:55% 100%;border-top-right-radius:45% 100%;'), + $flaeche('folie-'.$n.'-welle-vorn', ['desktop' => ['position' => 'absolute', 'left' => '-10%', 'right' => '-30%', 'bottom' => '-95px', 'height' => '175px', 'backgroundColor' => '#b4966e', 'zIndex' => 1, 'borderRadius' => ['topLeft' => '45%', 'topRight' => '55%', 'bottomRight' => '0px', 'bottomLeft' => '0px']]], 'border-top-left-radius:45% 100%;border-top-right-radius:55% 100%;'), + ], [ + 'desktop' => ['backgroundImage' => $foto['id'], 'backgroundSize' => 'cover', 'backgroundPosition' => 'center', 'overlayColor' => '#050505', 'overlayOpacity' => 0.62, + 'color' => '#ffffff', 'minHeight' => '88dvh', 'display' => 'flex', 'alignItems' => 'center', 'position' => 'relative', 'overflow' => 'hidden', 'padding' => ['top' => '90px', 'bottom' => '150px']], + 'mobile' => ['minHeight' => '92dvh', 'padding' => ['top' => '70px', 'bottom' => '130px']], + ]); +}; + +$leistungen = [ + ['innenausbau', '■', 'Innenausbau & Raumgestaltung', 'Wände, Decken, Böden – wir gestalten Räume mit Gespür für Farbe, Material und Proportion.'], + ['fassade', '◆', 'Fassadenarbeiten', 'Außenanstriche, Putzarbeiten und Fassadengestaltung – langlebig und witterungsbeständig.'], + ['restaurierung', '✦', 'Restaurierung & Denkmalpflege', 'Historische Substanz bewahren und behutsam aufarbeiten – mit handwerklicher Expertise.'], +]; + +/** Ein Bild mit Rundung, Schatten und Zoom beim Zeigen - das Bildraster der Vorlage. */ +$rasterbild = static function (string $id, array $foto, string $alt, string $hoehe = '260px', string $mobil = '220px', string $breite = '300px') use ($bild, $ecken, $seiten, $fx, $bildSchatten): array { + // Die feste Breite ist die Spaltenbreite am Schreibtisch; aus ihr entsteht das sizes-Attribut, + // sonst lud eine 270 px breite Kachel die 2400er Datei. + return $fx($bild($id, $foto, $alt, ['desktop' => ['maxWidth' => $breite, 'imageHeight' => $hoehe, 'objectFit' => 'cover', 'objectPosition' => 'center', 'imageRadius' => $ecken('4px'), 'borderRadius' => $ecken('4px'), 'overflow' => 'hidden', 'margin' => $seiten('0px')], 'mobile' => ['imageHeight' => $mobil]], null, $bildSchatten), 'fade', 'short', null, 'strong'); +}; + +$startseite = [ + 'schemaVersion' => $SCHEMA, + 'title' => 'Ihr Malerservice Drews', + 'description' => 'Ihr Malermeister aus Gernsbach und Umgebung. Innen- und Außengestaltung, Fassaden, Anstriche, Restaurierung und Kunstmalerei – Malerservice Drews, seit über 60 Jahren.', + 'blocks' => [ + // 1 – Das Startbild: drei Folien, dieselbe Botschaft auf drei Fotos. + $section('hero', [ + ['id' => 'hero-slider', 'type' => 'slider', 'props' => ['desktopVisible' => 1, 'tabletVisible' => 1, 'mobileVisible' => 1, 'snap' => true, 'dots' => true, 'autoplay' => 7], + 'children' => [ + $folie(1, $seitenbilder['hero-1'], true), + $folie(2, $seitenbilder['hero-2'], false), + $folie(3, $seitenbilder['hero-3'], false), + ], + 'css' => "gap:0;padding-bottom:0;--slider-dot:rgba(255,255,255,.6);--slider-dot-active:#c6a36b;--slider-bg:rgba(255,255,255,.9);--slider-ink:#222;\n& .slider-slide>.block-section{margin:0}"], + ], [ + // Dasselbe Foto wie die erste Folie: nur das Hintergrundbild des ersten Abschnitts wird + // vorgeladen, und die Folie liegt eine Ebene tiefer. So ist das größte Bild der Seite + // im HTML angekündigt, statt erst aus dem Stylesheet entdeckt zu werden. + 'desktop' => ['backgroundImage' => $seitenbilder['hero-1']['id'], 'backgroundSize' => 'cover', 'backgroundPosition' => 'center', 'padding' => ['top' => '0px', 'bottom' => '0px']], + ], 'start', ['width' => 'full']), + + // 2 – Über uns: Text links, vier Fotos rechts. + $section('geschichte', [ + $row('ueber-uns-zeile', [ + $column('ueber-uns-text', [ + $fx($kleinzeile('ueber-uns-label', 'Über Uns · Unsere Geschichte'), 'fade'), + $fx($heading('ueber-uns-titel', 'Seit über einem
    halben Jahrhundert…', 2, $h2Stil), 'rise'), + $fx($text('ueber-uns-1', 'Die Firmengeschichte begann vor 60 Jahren mit einem kleinen Lager von gerade mal 1,5 Quadratmetern am 2. Juni in Calw. Im Herbst 1965 bezog Hans-Jürgen Drews dann seine erste Werkstatt in Loffenau.', $fliess), 'rise', 'short'), + $fx($text('ueber-uns-zitat', 'Heute, ein halbes Jahrhundert später, ist Axel Drews Chef von 16 Mitarbeitern.', ['desktop' => ['color' => '#222222', 'fontSize' => '15.5px', 'fontStyle' => 'italic', 'lineHeight' => 1.8, 'borderWidth' => $nurLinks('3px'), 'borderStyle' => 'solid', 'borderColor' => '@gold', 'padding' => ['left' => '20px', 'top' => '4px', 'bottom' => '4px'], 'margin' => ['top' => '4px', 'bottom' => '24px']]]), 'rise', 'short'), + $fx($text('ueber-uns-2', 'Im Jahr 2000 hat der Malermeister die Firma von seinem Vater übernommen. Aus dem kleinen Anfang im Milchhäusel in Loffenau ist schnell ein erfolgreiches Malergeschäft geworden. Bereits zwei Jahre nach Firmengründung zog Hans-Jürgen Drews 1967 in die alte Post von Loffenau in der Oberen Dorfstraße um, ehe der Bau eines Wohn- und Geschäftshauses im Kändelweg 27 folgte.', $fliess), 'rise', 'medium'), + $fx($text('ueber-uns-3', '1977 eröffnete Drews eine zweite Werkstatt in der Gernsbacher Amtsstraße, 1979 übernahm er das Malergeschäft Oskar Fieg. Ein wichtiges Jahr in der Firmengeschichte ist 1983: Damals kaufte Hans-Jürgen Drews eine Halle vom Möbelhaus Vogel und baute sie um. Das Anwesen am Bachgarten 1 in Gernsbach mit Werkstatt, Lager und Garage sowie Aufenthaltsräume ist nach wie vor Firmensitz. 2001 wurde das Betriebsgebäude abgerissen und neu aufgebaut.', $fliess), 'rise', 'medium'), + $fx($text('ueber-uns-4', 'In seinen 35 Jahren der Selbstständigkeit hat Diplom-Maler Hans-Jürgen Drews zwölf Lehrlinge ausgebildet, die teilweise heute noch im Betrieb arbeiten.', ['desktop' => [...$fliess['desktop'], 'margin' => ['bottom' => '0px']]]), 'rise', 'long'), + ], ['desktop' => ['padding' => ['right' => '55px']], 'tablet' => ['padding' => ['right' => '0px']], 'mobile' => ['padding' => ['right' => '0px']]]), + $column('ueber-uns-bilder', [ + $row('ueber-uns-raster', [ + $rasterbild('ueber-uns-bild-1', $seitenbilder['ueber-1'], 'Malermeister Axel Drews prüft eine frisch gestrichene Wand'), + $rasterbild('ueber-uns-bild-2', $seitenbilder['ueber-2'], 'Axel Drews mit Farbmustern in der Werkstatt'), + $rasterbild('ueber-uns-bild-3', $seitenbilder['ueber-3'], 'Malerarbeiten des Teams von Malerservice Drews'), + $rasterbild('ueber-uns-bild-4', $seitenbilder['ueber-4'], 'Das Team von Malerservice Drews bei der Arbeit'), + ], ['desktop' => ['columns' => 'two'], 'mobile' => ['columns' => 'two']], ['desktop' => ['gap' => '16px', 'margin' => ['top' => '0px']], 'mobile' => ['gap' => '10px']]), + ], ['desktop' => ['alignSelf' => 'center']]), + ], ['desktop' => ['columns' => 'two', 'gap' => 'medium'], 'mobile' => ['columns' => 'one']], ['desktop' => ['alignItems' => 'center', 'margin' => ['top' => '0px']], 'mobile' => ['gap' => '40px']]), + ], ['desktop' => ['padding' => ['top' => '120px', 'bottom' => '120px']], 'mobile' => ['padding' => ['top' => '70px', 'bottom' => '70px']]], 'ueber-uns'), + + // 3 – Leistungen: drei weiße Karten auf Creme. + $section('leistungen-abschnitt', [ + ...$abschnittskopf('leistungen', 'Was wir tun', 'Unsere Leistungen', 'Vom kleinen Detail bis zur kompletten Fassade – alles aus einer Hand, mit der Sorgfalt, die nur echtes Handwerk bieten kann.'), + $row('leistungen-raster', array_map( + static fn (array $l, int $i): array => $fx($column('leistung-'.$l[0], [ + $text('leistung-'.$l[0].'-symbol', $l[1], ['desktop' => ['color' => '#a07f45', 'fontSize' => '24px', 'lineHeight' => 1, 'textAlign' => 'center', 'margin' => ['bottom' => '22px']]]), + $heading('leistung-'.$l[0].'-titel', $l[2], 3, ['desktop' => ['fontSize' => '22px', 'fontWeight' => '700', 'lineHeight' => 1.3, 'textAlign' => 'center', 'margin' => ['bottom' => '12px']]]), + $text('leistung-'.$l[0].'-text', $l[3], ['desktop' => ['color' => '#666666', 'fontSize' => '14.5px', 'lineHeight' => 1.75, 'textAlign' => 'center', 'margin' => ['bottom' => '0px']]]), + ], ['desktop' => ['backgroundColor' => '@papier', 'padding' => ['top' => '40px', 'right' => '30px', 'bottom' => '40px', 'left' => '30px'], 'borderRadius' => $ecken('4px'), 'borderWidth' => $seiten('1px'), 'borderStyle' => 'solid', 'borderColor' => '#0000000a', 'shadowY' => '2px', 'shadowBlur' => '15px', 'shadowColor' => '#0000000a', 'transition' => 400, 'hover' => ['translateY' => '-6px', 'shadowColor' => '#00000014', 'borderColor' => '#c6a36b33']]]), 'rise', ['none', 'short', 'medium'][$i]), + $leistungen, array_keys($leistungen), + ), ['desktop' => ['columns' => 'three', 'gap' => 'medium'], 'tablet' => ['columns' => 'three'], 'mobile' => ['columns' => 'one']], ['desktop' => ['margin' => ['top' => '50px']], 'mobile' => ['margin' => ['top' => '36px']]]), + ], ['desktop' => ['backgroundColor' => '@creme', 'padding' => ['top' => '110px', 'bottom' => '110px']], 'mobile' => ['padding' => ['top' => '70px', 'bottom' => '70px']]], 'leistungen'), + + // 4 – Aktuelles: vier dunkle Karten auf dunklem Band. + $section('aktuelles-abschnitt', [ + ...$abschnittskopf('aktuelles', 'News & Projekte', 'Aktuelles aus dem Betrieb', 'Bei Malerservice Drews tut sich immer was! Hier finden Sie Einblicke in aktuelle Projekte, kreative Farbkonzepte und besondere Herausforderungen.', true), + $fx(['id' => 'aktuelles-liste', 'type' => 'postlist', 'props' => ['count' => 4, 'category' => 'aktuelles', 'layout' => 'karten', 'paginate' => false, 'showMeta' => false, 'showExcerpt' => false, 'showTerms' => false], + 'style' => ['desktop' => ['maxWidth' => '1400px', 'margin' => ['top' => '40px', 'left' => 'auto', 'right' => 'auto']], 'mobile' => ['margin' => ['top' => '30px']]], + 'css' => $kartenCss."\n& .post-list{grid-template-columns:repeat(auto-fit,minmax(min(100%,270px),1fr))}"], 'rise', 'short'), + $fx($button('aktuelles-alle', 'Alle Mitteilungen', '/aktuelles', 'gold', false, ['desktop' => ['margin' => ['top' => '40px', 'left' => 'auto', 'right' => 'auto']]], 'normal'), 'fade', 'medium'), + ], ['desktop' => ['backgroundColor' => '@dunkel', 'color' => '#ffffff', 'padding' => ['top' => '110px', 'bottom' => '110px'], 'display' => 'flex', 'flexDirection' => 'column'], 'mobile' => ['padding' => ['top' => '70px', 'bottom' => '70px']]], 'aktuelles', ['width' => 'wide']), + + // 5 – Referenzen: drei Projektkarten. + $section('referenzen-abschnitt', [ + ...$abschnittskopf('referenzen', 'Ausgewählte Arbeiten', 'Referenzen, die für sich sprechen', 'Ein Eindruck sagt mehr als hundert Worte. Hier sehen Sie einige unserer Projekte aus Innenausbau, Fassadenarbeiten und Restaurierung.'), + $fx(['id' => 'referenzen-liste', 'type' => 'postlist', 'props' => ['count' => 3, 'category' => 'projekte', 'layout' => 'karten', 'paginate' => false, 'showMeta' => false, 'showExcerpt' => false, 'showTerms' => false], + 'style' => ['desktop' => ['maxWidth' => '900px', 'margin' => ['top' => '40px', 'left' => 'auto', 'right' => 'auto']], 'mobile' => ['margin' => ['top' => '30px']]], + 'css' => $kartenCss."\n& .post-list{grid-template-columns:repeat(auto-fit,minmax(min(100%,260px),1fr))}"], 'rise', 'short'), + $fx($button('referenzen-alle', 'Alle Projekte ansehen', '/unsere-projekte', 'dunkel-rahmen', true, ['desktop' => ['margin' => ['top' => '40px', 'left' => 'auto', 'right' => 'auto']]], 'normal'), 'fade', 'medium'), + ], ['desktop' => ['backgroundColor' => '@papier', 'padding' => ['top' => '120px', 'bottom' => '120px'], 'display' => 'flex', 'flexDirection' => 'column'], 'mobile' => ['padding' => ['top' => '70px', 'bottom' => '70px']]], 'referenzen'), + + // 6 – Kunstmalerei: Foto als Hintergrund, Text links, drei Bilder rechts. + $section('kunstmalerei', [ + $row('kunstmalerei-zeile', [ + $column('kunstmalerei-text', [ + $fx($kleinzeile('kunstmalerei-label', 'Kunst & Gestaltung', '#c6a36b'), 'fade'), + $fx($heading('kunstmalerei-titel', 'Kunstmalerei bei Ihrem
    Malerservice Drews', 2, $h2Hell), 'rise'), + $fx($text('kunstmalerei-intro', 'Die Malerei ist neben der Grafik eine Kunst der Fläche – wir verbinden traditionelles Können mit kreativer Gestaltung und schaffen Unikate, die Räume verwandeln.', ['desktop' => ['color' => '#ffffffd9', 'fontSize' => '15.5px', 'fontWeight' => '400', 'lineHeight' => 1.8, 'margin' => ['bottom' => '30px']]]), 'rise', 'short'), + $fx($button('kunstmalerei-knopf', 'Galerie ansehen', '/kunstmalerei', 'dunkel', true, ['desktop' => ['margin' => ['top' => '0px']]], 'normal'), 'rise', 'medium'), + ], ['desktop' => ['alignSelf' => 'center', 'flexGrow' => 7, 'flexBasis' => '0px', 'minWidth' => '0px', 'padding' => ['right' => '55px']], 'tablet' => ['padding' => ['right' => '0px']], 'mobile' => ['padding' => ['right' => '0px'], 'flexBasis' => 'auto']]), + $column('kunstmalerei-bilder', [ + $rasterbild('kunstmalerei-bild-1', $seitenbilder['kunst-1'], 'Wandgestaltung in Steinoptik in einem Rohbau', '330px', '240px', '520px'), + $row('kunstmalerei-raster', [ + $rasterbild('kunstmalerei-bild-2', $seitenbilder['kunst-2'], 'Grün gestrichener Raum mit Tageslicht', '150px', '120px'), + $rasterbild('kunstmalerei-bild-3', $seitenbilder['kunst-3'], 'Farbige Wandgestaltung eines Wohnraums', '150px', '120px'), + ], ['desktop' => ['columns' => 'two'], 'mobile' => ['columns' => 'two']], ['desktop' => ['gap' => '16px', 'margin' => ['top' => '16px']], 'mobile' => ['gap' => '10px', 'margin' => ['top' => '10px']]]), + ], ['desktop' => ['flexGrow' => 5, 'flexBasis' => '0px', 'minWidth' => '0px'], 'mobile' => ['flexBasis' => 'auto', 'width' => '100%']]), + ], [], ['desktop' => ['display' => 'flex', 'alignItems' => 'center', 'gap' => '40px', 'margin' => ['top' => '0px']], 'mobile' => ['flexDirection' => 'column', 'gap' => '40px']]), + ], [ + 'desktop' => ['backgroundImage' => $seitenbilder['kunst-bg']['id'], 'backgroundSize' => 'cover', 'backgroundPosition' => 'center', 'overlayColor' => '#050505', 'overlayOpacity' => 0.55, 'color' => '#ffffff', 'padding' => ['top' => '140px', 'bottom' => '140px']], + 'mobile' => ['padding' => ['top' => '80px', 'bottom' => '80px']], + ], 'kunst'), + + // 7 – Little Greene: Text links, vier Produktbilder rechts. + $section('little-greene-abschnitt', [ + $row('little-greene-zeile', [ + $column('little-greene-text', [ + $fx($kleinzeile('little-greene-label', 'Exklusiv in Mittelbaden'), 'fade'), + $fx($heading('little-greene-titel', 'Little Greene', 2, $h2Stil), 'rise'), + $fx($text('little-greene-1', 'Wir sind offizieller Partner von Little Greene – für hochwertige, umweltfreundliche Farben und außergewöhnliche Farbtiefe.', $fliess), 'rise', 'short'), + $fx($text('little-greene-2', 'Als Fachbetrieb beraten wir Sie nicht nur zur Farbwahl, sondern sorgen auch für die perfekte Verarbeitung – von der Vorbereitung bis zum Finish.', ['desktop' => [...$fliess['desktop'], 'margin' => ['bottom' => '30px']]]), 'rise', 'medium'), + $fx($button('little-greene-knopf', 'Mehr über Little Greene', '/exklusiv-in-mittelbaden-wir-sind-offizieller-little-greene-partner', 'dunkel-rahmen', true, ['desktop' => ['margin' => ['top' => '0px']]], 'normal'), 'rise', 'long'), + ], ['desktop' => ['alignSelf' => 'center', 'padding' => ['right' => '55px']], 'tablet' => ['padding' => ['right' => '0px']], 'mobile' => ['padding' => ['right' => '0px']]]), + $column('little-greene-bilder', [ + $row('little-greene-raster', [ + $rasterbild('little-greene-bild-1', $seitenbilder['lg-1'], 'Little Greene – Tapete Upper Brook Street'), + $rasterbild('little-greene-bild-2', $seitenbilder['lg-2'], 'Little Greene – Farbton Mischief'), + $rasterbild('little-greene-bild-3', $seitenbilder['lg-3'], 'Little Greene – Farbton Puck'), + $rasterbild('little-greene-bild-4', $seitenbilder['lg-4'], 'Little Greene – Farbkombinationen'), + ], ['desktop' => ['columns' => 'two'], 'mobile' => ['columns' => 'two']], ['desktop' => ['gap' => '16px', 'margin' => ['top' => '0px']], 'mobile' => ['gap' => '10px']]), + ]), + ], ['desktop' => ['columns' => 'two', 'gap' => 'medium'], 'mobile' => ['columns' => 'one']], ['desktop' => ['alignItems' => 'center', 'margin' => ['top' => '0px']], 'mobile' => ['gap' => '40px']]), + ], ['desktop' => ['padding' => ['top' => '120px', 'bottom' => '120px']], 'mobile' => ['padding' => ['top' => '70px', 'bottom' => '70px']]], 'little-greene'), + + // 8 – Das Zitat: dunkles Band, goldene Linien links und rechts. + $section('zitat', [ + $fx($column('zitat-inhalt', [ + $text('zitat-text', '„Qualität ist kein Zufall – sie ist das Ergebnis von Anspruch, Erfahrung und Leidenschaft.“', ['desktop' => ['color' => '#ffffff', 'fontSize' => '24px', 'fontStyle' => 'italic', 'fontWeight' => '400', 'lineHeight' => 1.6, 'textAlign' => 'center', 'margin' => ['bottom' => '22px']], 'mobile' => ['fontSize' => '19px']]), + $kleinzeile('zitat-autor', 'Axel Drews · Malermeister', '#c6a36b', 'center', '0px', '4px'), + ], ['desktop' => ['maxWidth' => '780px', 'margin' => ['left' => 'auto', 'right' => 'auto'], 'padding' => ['top' => '24px', 'right' => '40px', 'bottom' => '24px', 'left' => '40px'], 'borderWidth' => ['top' => '0px', 'right' => '1px', 'bottom' => '0px', 'left' => '1px'], 'borderStyle' => 'solid', 'borderColor' => '@gold'], 'mobile' => ['padding' => ['top' => '10px', 'right' => '18px', 'bottom' => '10px', 'left' => '18px']]]), 'fade'), + ], ['desktop' => ['backgroundColor' => '@dunkel', 'color' => '#ffffff', 'padding' => ['top' => '100px', 'bottom' => '100px']], 'mobile' => ['padding' => ['top' => '60px', 'bottom' => '60px']]]), + + // 9 – Marken: sechs Logos in Graustufen, farbig beim Zeigen. + $section('marken-abschnitt', [ + ...$abschnittskopf('marken', 'Marken & Partner', 'Qualität beginnt beim Produkt', 'Wir arbeiten ausschließlich mit hochwertigen Marken – für langlebige Ergebnisse, satte Farbtiefe und perfekte Oberflächen.'), + $fx(['id' => 'marken-logos', 'type' => 'logos', 'children' => array_map( + static fn (string $schluessel, string $name): array => $bild('marke-'.$schluessel, $seitenbilder['marke-'.$schluessel], $name, ['desktop' => ['maxWidth' => '150px', 'grayscale' => 1, 'opacity' => 0.6, 'transition' => 400, 'margin' => $seiten('0px'), 'hover' => ['grayscale' => 0, 'opacity' => 1]], 'mobile' => ['maxWidth' => '110px']]), + ['littlegreene', 'brillux', 'gori', 'keim', 'sikkens', 'henkel'], ['Little Greene', 'Brillux', 'Gori', 'Keim', 'Sikkens', 'Henkel'], + ), 'style' => ['desktop' => ['margin' => ['top' => '50px']], 'mobile' => ['margin' => ['top' => '36px']]], + 'css' => "grid-template-columns:repeat(auto-fit,minmax(min(100%,140px),1fr));gap:40px 30px;\n& img{max-height:70px}"], 'fade', 'short'), + ], ['desktop' => ['backgroundColor' => '@creme', 'padding' => ['top' => '100px', 'bottom' => '100px']], 'mobile' => ['padding' => ['top' => '60px', 'bottom' => '60px']]], 'marken'), + + // 10 – Das beige Band mit drei Partnern. + $section('partner', [ + ['id' => 'partner-logos', 'type' => 'logos', 'children' => [ + $bild('partner-eisen', $seitenbilder['partner-eisen'], 'Eisen-Raumausstattung', ['desktop' => ['maxWidth' => '190px', 'margin' => $seiten('0px')], 'mobile' => ['maxWidth' => '130px']]), + $bild('partner-lichtkraus', $seitenbilder['partner-lichtkraus'], 'Licht Kraus Sasbach', ['desktop' => ['maxWidth' => '120px', 'margin' => $seiten('0px')], 'mobile' => ['maxWidth' => '90px']]), + $bild('partner-kant', $seitenbilder['partner-kant'], 'Kant-IT Solutions', ['desktop' => ['maxWidth' => '210px', 'margin' => $seiten('0px')], 'mobile' => ['maxWidth' => '140px']], 'https://kant-it.de'), + ], 'css' => "grid-template-columns:repeat(auto-fit,minmax(150px,max-content));justify-content:center;gap:40px clamp(40px,10vw,150px);\n& img{max-height:80px}"], + ], ['desktop' => ['backgroundColor' => '@beige', 'padding' => ['top' => '30px', 'bottom' => '30px']]]), + + // 11 – Handlungsaufruf + $aufruf('aufruf', 'Unverbindlich anfragen', 'Bereit für ein Ergebnis,
    das man sieht?', 'Wir beraten Sie persönlich und erstellen Ihnen ein Angebot, das zu Ihrem Objekt passt – transparent, sauber und professionell.', 'Jetzt Kontakt aufnehmen'), + ], +]; + +// --------------------------------------------------------------------------------------------- +// Seiten anlegen und veröffentlichen +// --------------------------------------------------------------------------------------------- + +$erstellt = []; +$anlegen = static function (string $slug, array $dokument, string $seoTitel = '', string $teilbild = '') use ($pages, $db, &$erstellt): string { + $id = $pages->createPage($slug, null, 'page', $dokument); + if ('' !== $seoTitel) { + $db->executeStatement('UPDATE page SET seo_title = ? WHERE id = ?', [$seoTitel, $id]); + } + if ('' !== $teilbild) { + $db->executeStatement('UPDATE page SET og_media_id = ? WHERE id = ?', [$teilbild, $id]); + } + $seite = $db->fetchAssociative('SELECT draft_revision_id, version FROM page WHERE id = ?', [$id]); + $pages->publish($id, $seite['draft_revision_id'], (int) $seite['version']); + $erstellt[$slug] = $id; + echo 'Seite angelegt: /'.$db->fetchOne('SELECT path FROM page WHERE id = ?', [$id])."\n"; + + return $id; +}; + +$anlegen('home', $startseite, 'Ihr Malerservice Drews | Malermeister Axel Drews', $seitenbilder['hero-1']['id']); + +// Aktuelles: Seitenkopf, Zeitleiste, Handlungsaufruf mit Foto. +$anlegen('aktuelles', [ + 'schemaVersion' => $SCHEMA, 'title' => 'Aktuelles', + 'description' => 'Aktuelles aus dem Betrieb: Einblicke in Projekte, Neuigkeiten und Veranstaltungen von Ihr Malerservice Drews in Gernsbach.', + 'blocks' => [ + $seitenkopf('aktuelles-seite', $seitenbilder['hero-1'], 'News & Projekte', 'Aktuelles aus dem Betrieb', 'Einblicke in unsere Projekte, Neuigkeiten und Veranstaltungen – erfahren Sie, woran wir gerade arbeiten.', '45vh', '#050505', 0.65, [], 'center'), + $section('aktuelles-liste-abschnitt', [ + $heading('aktuelles-liste-titel', 'Alle Mitteilungen im Überblick', 2, ['desktop' => ['position' => 'absolute', 'width' => '1px', 'height' => '1px', 'overflow' => 'hidden', 'margin' => ['bottom' => '0px']]], 'clip-path:inset(50%);white-space:nowrap'), + ['id' => 'aktuelles-zeitleiste', 'type' => 'postlist', 'props' => ['count' => 10, 'category' => 'aktuelles', 'layout' => 'liste', 'paginate' => true, 'showMeta' => true, 'showExcerpt' => true, 'showTerms' => false], + 'style' => ['desktop' => ['maxWidth' => '1000px', 'margin' => ['left' => 'auto', 'right' => 'auto']]], + 'css' => '& .post-list{gap:50px;padding-left:clamp(20px,5vw,60px);border-left:3px solid transparent;border-image:linear-gradient(180deg,#c6a36b 0%,rgba(198,163,107,.3) 100%) 1} +& .post-card{position:relative;border:0;border-radius:16px;background:#fff;box-shadow:0 10px 40px rgba(198,163,107,.15);transition:transform .4s ease,box-shadow .4s ease;flex-wrap:wrap} +& .post-card:hover{transform:translateY(-4px);box-shadow:0 20px 60px rgba(198,163,107,.25)} +& .post-image{flex:1 1 220px;max-width:none} +& .post-image img{min-height:190px;height:100%} +& .post-body{flex:3 1 300px;padding:28px 32px;gap:10px} +& .post-card h3{font-size:22px;font-weight:700;line-height:1.3} +& .post-meta{order:-1;font-size:12px;letter-spacing:2px;text-transform:uppercase;color:#8a6a2f;font-weight:600} +& .post-excerpt{margin:0;color:#555;font-size:15px;line-height:1.7} +& .post-pager{margin-top:50px}', ], + ], ['desktop' => ['backgroundColor' => '@creme', 'padding' => ['top' => '100px', 'bottom' => '100px']], 'mobile' => ['padding' => ['top' => '60px', 'bottom' => '60px']]]), + $aufruf('aktuelles-aufruf', 'Ihr nächstes Projekt?', 'Lassen Sie uns über Ihre Ideen sprechen', 'Ob Renovierung, Farbkonzept oder besondere Herausforderung – wir freuen uns auf Ihre Anfrage.', 'Jetzt Kontakt aufnehmen', $seitenbilder['aktuelles-cta-bg']), + ], +], 'Aktuelles | Ihr Malerservice Drews', $seitenbilder['hero-1']['id']); + +// Unsere Projekte: Seitenkopf, Zickzackliste, dunkler Schluss. +$anlegen('unsere-projekte', [ + 'schemaVersion' => $SCHEMA, 'title' => 'Unsere Projekte', + 'description' => 'Einblicke in ausgewählte Arbeiten von Ihr Malerservice Drews aus dem Bereich Innenausstattung und Außenfassade – Referenzen aus Gernsbach, Baden-Baden und Mittelbaden.', + 'blocks' => [ + $section('projekte-kopf', [ + $column('projekte-kopf-inhalt', [ + $fx($kleinzeile('projekte-label', 'Unsere Arbeit', '#ffffffb3', 'center', '20px', '5px'), 'fade'), + $fx($heading('projekte-h1', 'Unsere Projekte', 1, ['desktop' => ['fontSize' => '60px', 'lineHeight' => 1.1, 'fontWeight' => '700', 'color' => '#ffffff', 'textAlign' => 'center', 'margin' => ['bottom' => '0px']], 'tablet' => ['fontSize' => '48px'], 'mobile' => ['fontSize' => '38px']]), 'rise', 'short'), + $flaeche('projekte-linie', ['desktop' => ['width' => '50px', 'height' => '1px', 'backgroundColor' => '#b09066', 'margin' => ['top' => '28px', 'bottom' => '28px', 'left' => 'auto', 'right' => 'auto']]]), + $fx($text('projekte-intro', 'Einblicke in ausgewählte Arbeiten aus dem Bereich Innenaustattung und Außenfassade.', ['desktop' => ['color' => '#ffffff80', 'fontSize' => '14.5px', 'fontWeight' => '400', 'lineHeight' => 1.8, 'textAlign' => 'center', 'maxWidth' => '500px', 'margin' => ['left' => 'auto', 'right' => 'auto', 'bottom' => '0px']]]), 'rise', 'medium'), + ], ['desktop' => ['maxWidth' => '900px', 'margin' => ['left' => 'auto', 'right' => 'auto']]]), + ], [ + 'desktop' => ['backgroundImage' => $seitenbilder['projekte-bg']['id'], 'backgroundSize' => 'cover', 'backgroundPosition' => 'center', 'overlayColor' => '#0a0806', 'overlayOpacity' => 0.65, 'color' => '#ffffff', 'padding' => ['top' => '160px', 'bottom' => '160px']], + 'mobile' => ['padding' => ['top' => '100px', 'bottom' => '100px']], + ]), + $section('projekte-liste-abschnitt', [ + $heading('projekte-liste-titel', 'Alle Projekte im Überblick', 2, ['desktop' => ['position' => 'absolute', 'width' => '1px', 'height' => '1px', 'overflow' => 'hidden', 'margin' => ['bottom' => '0px']]], 'clip-path:inset(50%);white-space:nowrap'), + ['id' => 'projekte-liste', 'type' => 'postlist', 'props' => ['count' => 8, 'category' => 'projekte', 'layout' => 'wechsel', 'paginate' => true, 'showMeta' => false, 'showExcerpt' => false, 'showTerms' => false], + 'style' => ['desktop' => ['maxWidth' => '1360px', 'margin' => ['left' => 'auto', 'right' => 'auto']]], + 'css' => '& .post-card{gap:20px 60px;padding:40px 0} +& .post-card + .post-card{border-top:0} +& .post-image{border-radius:16px;box-shadow:0 10px 40px rgba(198,163,107,.15);transition:transform .4s ease,box-shadow .4s ease} +& .post-image:hover{transform:translateY(-8px);box-shadow:0 20px 60px rgba(198,163,107,.25)} +& .post-image img{aspect-ratio:16/11;border-radius:16px;transition:transform .6s ease} +& .post-view{display:none} +& .post-body::before{display:none} +& .post-body{gap:15px;max-width:450px} +& .post-card h3{font-size:clamp(24px,2.3vw,32px);font-weight:700;line-height:1.3;color:#2a2a2a} +& .post-excerpt{color:#333;font-size:15.5px;line-height:1.7} +& .post-more{font-size:15px;font-weight:600;background:#c6a36b;color:#2a2a2a;border-radius:50px;padding:14px 28px;margin-top:10px;transition:transform .3s ease,box-shadow .3s ease,background-color .3s} +& .post-more:hover{background:#b4966e;transform:translateY(-2px);box-shadow:0 8px 25px rgba(198,163,107,.35)} +& .post-pager{margin-top:60px;gap:10px 22px} +& .post-pager a{background:#fff;color:#333;border-radius:50px;padding:14px 24px;text-decoration:none;font-weight:500;transition:background-color .3s,color .3s} +& .post-pager a:hover{background:#c6a36b;color:#fff}', ], + ], ['desktop' => ['backgroundColor' => '#f8f6f3', 'padding' => ['top' => '100px', 'bottom' => '100px']], 'mobile' => ['padding' => ['top' => '50px', 'bottom' => '50px']]], null, ['width' => 'wide']), + $section('projekte-schluss', [ + $column('projekte-schluss-inhalt', [ + $fx($kleinzeile('projekte-schluss-label', 'Ihr Projekt ist das nächste', '#c8a882', 'center', '18px', '4px'), 'fade'), + $fx($heading('projekte-schluss-titel', 'Lassen Sie uns gemeinsam
    Farbe bekennen.', 2, $h2HellMitte), 'rise'), + $flaeche('projekte-schluss-linie', ['desktop' => ['width' => '50px', 'height' => '1px', 'backgroundColor' => '#b09066', 'margin' => ['top' => '10px', 'bottom' => '25px', 'left' => 'auto', 'right' => 'auto']]]), + $fx($text('projekte-schluss-text', 'Unverbindliche Beratung — wir freuen uns auf Ihre Anfrage.', ['desktop' => ['color' => '#ffffff99', 'fontSize' => '14px', 'fontWeight' => '400', 'textAlign' => 'center', 'margin' => ['bottom' => '40px']]]), 'rise', 'short'), + $fx($button('projekte-schluss-knopf', 'Kontakt aufnehmen', '/kontakt', 'weiss-rahmen', false, ['desktop' => ['margin' => ['top' => '0px', 'left' => 'auto', 'right' => 'auto'], 'letterSpacing' => '3px', 'fontSize' => '11px', 'borderColor' => '#ffffff4d']], 'normal'), 'rise', 'medium'), + ], ['desktop' => ['display' => 'flex', 'flexDirection' => 'column', 'alignItems' => 'center', 'maxWidth' => '800px', 'margin' => ['left' => 'auto', 'right' => 'auto']]]), + ], ['desktop' => ['backgroundColor' => '#1c1a17', 'color' => '#ffffff', 'padding' => ['top' => '100px', 'bottom' => '100px']], 'mobile' => ['padding' => ['top' => '60px', 'bottom' => '60px']]]), + ], +], 'Unsere Projekte | Ihr Malerservice Drews', $seitenbilder['projekte-bg']['id']); + +// Kunstmalerei: Kopf, Handschrift, Galerie, Videos, Arbeitsweise, Schluss. +$kunstSchritte = [ + ['beratung', 'Beratung & Konzept', 'Wir besprechen Ihre Wünsche und erstellen eine individuelle Idee passend zum Raum.'], + ['detail', 'Detailarbeit', 'Feine Strukturen, Farbverläufe und Präzision sorgen für Tiefe und Wirkung.'], + ['material', 'Hochwertige Materialien', 'Wir verwenden nur professionelle Farben und langlebige Schutzbeschichtungen.'], + ['umsetzung', 'Perfekte Umsetzung', 'Sauber, zuverlässig und exakt nach Plan – bis alles perfekt aussieht.'], +]; +$kunstKarte = static fn (array $s, string $verzug): array => $fx($column('kunst-schritt-'.$s[0], [ + $heading('kunst-schritt-'.$s[0].'-titel', $s[1], 3, ['desktop' => ['fontSize' => '20px', 'fontWeight' => '700', 'margin' => ['bottom' => '10px']]]), + $text('kunst-schritt-'.$s[0].'-text', $s[2], ['desktop' => ['color' => '#000000a6', 'fontSize' => '15px', 'lineHeight' => 1.7, 'margin' => ['bottom' => '0px']]]), +], ['desktop' => ['backgroundColor' => '#f7f7f7', 'padding' => $seiten('28px'), 'borderRadius' => $ecken('16px'), 'shadowY' => '8px', 'shadowBlur' => '22px', 'shadowColor' => '#0000000d', 'height' => '100%']]), 'rise', $verzug); + +$videos = [ + '2022/12/VIDEO-2022-12-27-19-46-50-2022-12-28-08_33_09.mp4', '2022/12/VIDEO-2022-12-27-20-15-29-2022-12-28-08_33_10.mp4', '2022/04/VIDEO-2022-04-27-09-10-39.mp4', + '2022/04/VIDEO-2022-04-27-09-10-39-video-converter.com_.mp4', '2022/04/VIDEO-2022-04-27-10-32-16-2022-04-27-08_57_30.mp4', '2022/04/VIDEO-2022-04-27-10-29-57-2022-04-27-08_57_29.mp4', + '2022/04/Video_start.mp4', '2022/04/Video_start-online-video-cutter.com-1.mp4', '2022/08/VIDEO-2022-08-29-16-09-21.mp4', + '2022/11/VIDEO-2022-11-07-06-45-45.mp4', '2022/12/VIDEO-2022-12-27-19-49-05-2022-12-28-08_33_09.mp4', +]; + +$anlegen('kunstmalerei', [ + 'schemaVersion' => $SCHEMA, 'title' => 'Kunstmalerei', + 'description' => 'Kunstmalerei bei Ihrem Malerservice Drews: klassische Motive, moderne Kompositionen und individuelle Kunstwerke, die Räume lebendig machen – mit Galerie und Videos.', + 'blocks' => [ + $seitenkopf('kunst-seite', $seitenbilder['hero-1'], 'Kunstmalerei', 'Kunst, die Räume lebendig macht', 'Ob klassische Motive, moderne Kompositionen oder individuelle Kunstwerke – wir erschaffen Malerei mit Charakter. Jedes Werk entsteht mit Liebe zum Detail und dem Anspruch, Emotionen sichtbar zu machen.', '40vh', '#000000', 0.55, [ + $button('kunst-seite-knopf', 'Jetzt Projekt anfragen', '/kontakt', 'dunkel', false, ['desktop' => ['margin' => ['top' => '14px', 'left' => 'auto', 'right' => 'auto'], 'borderRadius' => $ecken('99px')]], 'normal'), + ]), + $section('kunst-handschrift', [ + $row('kunst-handschrift-zeile', [ + $column('kunst-handschrift-text', [ + $fx($kleinzeile('kunst-handschrift-label', 'Unsere Handschrift'), 'fade'), + $fx($heading('kunst-handschrift-titel', 'Kunstmalerei mit Stil & Persönlichkeit', 2, $h2Stil), 'rise'), + $fx($text('kunst-handschrift-1', 'Kunstmalerei ist mehr als Farbe auf Leinwand – sie ist Ausdruck, Stimmung und Atmosphäre. Wir schaffen einzigartige Werke, die nicht nur schön aussehen, sondern Räume aufwerten und Emotionen transportieren.', ['desktop' => ['color' => '#000000b8', 'fontSize' => '16px', 'fontWeight' => '400', 'lineHeight' => 1.8, 'margin' => ['bottom' => '20px']]]), 'rise', 'short'), + $fx($text('kunst-handschrift-2', 'Von detailreichen Naturmotiven bis hin zu modernen abstrakten Elementen: Unsere Arbeiten entstehen individuell, passend zu Ihrem Raum, Ihrer Idee und Ihrem Stil.', ['desktop' => ['color' => '#000000b8', 'fontSize' => '16px', 'fontWeight' => '400', 'lineHeight' => 1.8, 'margin' => ['bottom' => '0px']]]), 'rise', 'medium'), + ], ['desktop' => ['alignSelf' => 'center']]), + $column('kunst-handschrift-bild', [ + $fx($bild('kunst-handschrift-foto', $seitenbilder['kunst-1'], 'Wandgestaltung in Steinoptik in einem Rohbau', ['desktop' => ['maxWidth' => '560px', 'imageRadius' => $ecken('4px'), 'margin' => $seiten('0px')]], null, $bildSchatten), 'right', 'short', null, 'strong'), + ]), + ], ['desktop' => ['columns' => 'two', 'gap' => 'large'], 'mobile' => ['columns' => 'one']], ['desktop' => ['alignItems' => 'center', 'margin' => ['top' => '0px']]]), + ], ['desktop' => ['padding' => ['top' => '90px', 'bottom' => '90px']], 'mobile' => ['padding' => ['top' => '60px', 'bottom' => '60px']]]), + $section('kunst-galerie-abschnitt', [ + ...$abschnittskopf('kunst-galerie', 'Galerie', 'Einblicke in unsere Kunstwerke', 'Hier sehen Sie eine Auswahl an Projekten. Jedes Werk ist individuell gefertigt – mit dem Ziel, Räume einzigartig wirken zu lassen.'), + $fx(['id' => 'kunst-galerie', 'type' => 'gallery', 'props' => ['lightbox' => true], 'children' => array_map( + static fn (array $foto, int $i): array => $bild('kunst-werk-'.($i + 1), $foto, 'Kunstmalerei von Malerservice Drews – Werk '.($i + 1), ['desktop' => ['maxWidth' => '360px', 'imageHeight' => '100%', 'objectFit' => 'cover', 'imageRadius' => $ecken('4px'), 'margin' => $seiten('0px')]], null, "& img{aspect-ratio:1/1;transition:transform .5s ease}\n&:hover img{transform:scale(1.04)}", true), + $galerie, array_keys($galerie), + ), 'style' => ['desktop' => ['gridColumns' => 4, 'gap' => '15px', 'margin' => ['top' => '60px']], 'tablet' => ['gridColumns' => 3], 'mobile' => ['gridColumns' => 2, 'gap' => '10px', 'margin' => ['top' => '36px']]]], 'fade', 'short'), + ], ['desktop' => ['backgroundColor' => '#f7f7f7', 'padding' => ['top' => '90px', 'bottom' => '60px']], 'mobile' => ['padding' => ['top' => '60px', 'bottom' => '40px']]], 'galerie', ['width' => 'wide']), + $section('kunst-videos-abschnitt', [ + $heading('kunst-videos-titel', 'Videogalerie', 2, ['desktop' => [...$h2Mitte['desktop'], 'margin' => ['bottom' => '40px']], 'tablet' => $h2Stil['tablet'], 'mobile' => $h2Stil['mobile']]), + $row('kunst-videos', array_map( + static fn (string $datei, int $i): array => ['id' => 'kunst-video-'.($i + 1), 'type' => 'embed', 'props' => ['group' => 'external', 'title' => 'Video '.($i + 1).' aus der Werkstatt von Malerservice Drews', 'provider' => 'maler-drews.com', 'hint' => 'Das Video wird von maler-drews.com geladen.', 'url' => 'https://www.maler-drews.com/wp-content/uploads/'.$datei, 'height' => 240]], + $videos, array_keys($videos), + ), ['desktop' => ['columns' => 'three', 'gap' => 'medium'], 'tablet' => ['columns' => 'two'], 'mobile' => ['columns' => 'one']], ['desktop' => ['margin' => ['top' => '0px']]]), + ], ['desktop' => ['backgroundColor' => '#f7f7f7', 'padding' => ['top' => '30px', 'bottom' => '90px']], 'mobile' => ['padding' => ['top' => '20px', 'bottom' => '60px']]], null, ['width' => 'wide']), + $section('kunst-arbeitsweise', [ + $row('kunst-arbeitsweise-zeile', [ + $column('kunst-arbeitsweise-text', [ + $fx($kleinzeile('kunst-arbeitsweise-label', 'So arbeiten wir'), 'fade'), + $fx($heading('kunst-arbeitsweise-titel', 'Von der Idee bis zum fertigen Kunstwerk', 2, $h2Stil), 'rise'), + $fx($text('kunst-arbeitsweise-intro', 'Wir beraten Sie persönlich, entwickeln ein Konzept und setzen Ihr Wunschmotiv mit hochwertigen Materialien um. Ob für Privatkunden, Unternehmen oder öffentliche Einrichtungen – wir liefern Kunst, die Eindruck hinterlässt.', ['desktop' => ['color' => '#000000b8', 'fontSize' => '16px', 'fontWeight' => '400', 'lineHeight' => 1.8, 'margin' => ['bottom' => '0px']]]), 'rise', 'short'), + ], ['desktop' => ['alignSelf' => 'center']]), + $column('kunst-arbeitsweise-karten', [ + $kunstKarte($kunstSchritte[0], 'none'), + $kunstKarte($kunstSchritte[1], 'short'), + ], ['desktop' => ['display' => 'flex', 'flexDirection' => 'column', 'gap' => '20px']]), + ], ['desktop' => ['columns' => 'two', 'gap' => 'large'], 'mobile' => ['columns' => 'one']], ['desktop' => ['alignItems' => 'center', 'margin' => ['top' => '0px']]]), + $row('kunst-arbeitsweise-raster', [$kunstKarte($kunstSchritte[2], 'none'), $kunstKarte($kunstSchritte[3], 'short')], ['desktop' => ['columns' => 'two', 'gap' => 'medium'], 'mobile' => ['columns' => 'one']], ['desktop' => ['margin' => ['top' => '20px']]]), + ], ['desktop' => ['padding' => ['top' => '90px', 'bottom' => '90px']], 'mobile' => ['padding' => ['top' => '60px', 'bottom' => '60px']]]), + $section('kunst-schluss', [ + $row('kunst-schluss-zeile', [ + $column('kunst-schluss-text', [ + $fx($kleinzeile('kunst-schluss-label', 'Interesse?', '#c6a36b'), 'fade'), + $fx($heading('kunst-schluss-titel', 'Lassen Sie uns gemeinsam etwas Einzigartiges erschaffen', 2, ['desktop' => [...$h2Hell['desktop'], 'fontSize' => '46px'], 'tablet' => $h2Stil['tablet'], 'mobile' => $h2Stil['mobile']]), 'rise'), + $fx($text('kunst-schluss-intro', 'Ob Wandgestaltung, Leinwandkunst oder dekorative Malerei – wir freuen uns auf Ihre Anfrage. Gemeinsam entwickeln wir ein Werk, das perfekt zu Ihnen passt.', ['desktop' => ['color' => '#ffffffc7', 'fontSize' => '16px', 'fontWeight' => '400', 'lineHeight' => 1.8, 'margin' => ['bottom' => '0px']]]), 'rise', 'short'), + ], ['desktop' => ['flexGrow' => 7, 'flexBasis' => '0px', 'minWidth' => '0px'], 'mobile' => ['flexBasis' => 'auto']]), + $column('kunst-schluss-aktion', [ + $fx($button('kunst-schluss-knopf', 'Kontakt aufnehmen', '/kontakt', 'gold', false, ['desktop' => ['margin' => ['top' => '0px', 'left' => 'auto', 'right' => 'auto'], 'borderRadius' => $ecken('99px')]]), 'rise', 'medium'), + $fx($text('kunst-schluss-hinweis', 'Antwort innerhalb von 24 Stunden', ['desktop' => ['color' => '#ffffffa6', 'fontSize' => '14px', 'textAlign' => 'center', 'margin' => ['top' => '14px', 'bottom' => '0px']]]), 'fade', 'long'), + ], ['desktop' => ['display' => 'flex', 'flexDirection' => 'column', 'alignItems' => 'center', 'justifyContent' => 'center', 'flexGrow' => 5, 'flexBasis' => '0px'], 'mobile' => ['flexBasis' => 'auto', 'width' => '100%']]), + ], [], ['desktop' => ['display' => 'flex', 'alignItems' => 'center', 'gap' => '60px', 'margin' => ['top' => '0px']], 'mobile' => ['flexDirection' => 'column', 'gap' => '36px']]), + ], ['desktop' => ['backgroundColor' => '#0f0f0f', 'color' => '#ffffff', 'padding' => ['top' => '90px', 'bottom' => '90px']], 'mobile' => ['padding' => ['top' => '60px', 'bottom' => '60px']]]), + ], +], 'Kunstmalerei | Ihr Malerservice Drews', $seitenbilder['kunst-1']['id']); + +// Kontakt: Kopf, dunkler Streifen, Formular und Standort, Karte. +$kontaktKachel = static fn (string $id, string $icon, string $label, string $inhalt, string $zusatz = '', bool $letzte = false): array => $column($id, array_values(array_filter([ + $symbol($id.'-symbol', $icon, 32, ['desktop' => ['color' => '@gold', 'margin' => ['bottom' => '14px', 'left' => 'auto', 'right' => 'auto']]]), + $text($id.'-label', $label, ['desktop' => ['color' => '#ffffffa6', 'fontSize' => '11px', 'letterSpacing' => '4px', 'textTransform' => 'uppercase', 'fontWeight' => '600', 'textAlign' => 'center', 'margin' => ['bottom' => '10px']]]), + $text($id.'-text', $inhalt, ['desktop' => ['color' => '#ffffffd9', 'fontSize' => '16.5px', 'fontWeight' => '400', 'lineHeight' => 1.7, 'textAlign' => 'center', 'margin' => ['bottom' => '0px']]], "& a{color:inherit;text-decoration:none}\n& a:hover{color:#c6a36b}"), + '' === $zusatz ? null : $text($id.'-zusatz', $zusatz, ['desktop' => ['color' => '#ffffff99', 'fontSize' => '13.5px', 'textAlign' => 'center', 'margin' => ['top' => '5px', 'bottom' => '0px']]]), +])), ['desktop' => ['display' => 'flex', 'flexDirection' => 'column', 'alignItems' => 'center', 'padding' => $seiten('20px')] + ($letzte ? [] : ['borderWidth' => ['top' => '0px', 'right' => '1px', 'bottom' => '0px', 'left' => '0px'], 'borderStyle' => 'solid', 'borderColor' => '#ffffff14']), 'mobile' => $letzte ? [] : ['borderWidth' => ['top' => '0px', 'right' => '0px', 'bottom' => '1px', 'left' => '0px']]]); + +$zeitenKarte = static fn (string $id, string $tag, string $zeit, bool $erste = false, bool $kursiv = false): array => $row($id, [ + $column($id.'-tag', [$text($id.'-tag-text', $tag, ['desktop' => ['fontSize' => '14.5px', 'color' => '#555555', 'margin' => ['bottom' => '0px']]])]), + $column($id.'-zeit', [$text($id.'-zeit-text', $kursiv ? ''.$zeit.'' : ''.$zeit.'', ['desktop' => ['fontSize' => '14.5px', 'color' => '#555555', 'textAlign' => 'right', 'margin' => ['bottom' => '0px']]])]), +], [], ['desktop' => ['display' => 'flex', 'justifyContent' => 'space-between', 'gap' => '20px', 'margin' => ['top' => '0px'], 'padding' => ['top' => $erste ? '0px' : '6px', 'bottom' => '6px']] + + ($erste ? [] : ['borderWidth' => $nurOben('1px'), 'borderStyle' => 'solid', 'borderColor' => '#f0ece6'])]); + +$anlegen('kontakt', [ + 'schemaVersion' => $SCHEMA, 'title' => 'Kontakt', + 'description' => 'Kontakt zu Ihr Malerservice Drews in Gernsbach: Telefon '.$telefon.', Am Bachgarten 1, 76593 Gernsbach. Persönliche Beratung, faire Angebote – wir melden uns innerhalb von 24 Stunden.', + 'blocks' => [ + $seitenkopf('kontakt-seite', $seitenbilder['hero-1'], 'Malermeister Axel Drews · Gernsbach', 'Sprechen wir über Ihr Projekt', 'Persönliche Beratung, faire Angebote und ein offenes Ohr für Ihre Wünsche – wir sind für Sie da.', '50vh', '#050505', 0.68, [], 'center'), + $section('kontakt-streifen', [ + $row('kontakt-streifen-zeile', [ + $kontaktKachel('kontakt-kachel-telefon', 'phone', 'Telefon', ''.$telefon.'', 'Fax: '.$fax), + $kontaktKachel('kontakt-kachel-adresse', 'pin', 'Anschrift', 'Am Bachgarten 1
    76593 Gernsbach'), + $kontaktKachel('kontakt-kachel-mail', 'mail', 'E-Mail', ''.$mail.'', '', true), + ], ['desktop' => ['columns' => 'three', 'gap' => 'medium'], 'tablet' => ['columns' => 'three'], 'mobile' => ['columns' => 'one']], ['desktop' => ['margin' => ['top' => '0px']]], + ), + ], ['desktop' => ['backgroundColor' => '#0e0e0e', 'color' => '#ffffff', 'padding' => ['top' => '55px', 'bottom' => '55px']], 'mobile' => ['padding' => ['top' => '40px', 'bottom' => '40px']]]), + $section('kontakt-formular-abschnitt', [ + $row('kontakt-formular-zeile', [ + $column('kontakt-formular-spalte', [ + $fx($kleinzeile('kontakt-formular-label', 'Kontaktformular'), 'fade'), + $fx($heading('kontakt-formular-titel', 'Schreiben Sie uns', 2, ['desktop' => [...$h2Stil['desktop'], 'margin' => ['bottom' => '8px']], 'tablet' => $h2Stil['tablet'], 'mobile' => $h2Stil['mobile']]), 'rise'), + $fx($text('kontakt-formular-intro', 'Beschreiben Sie Ihr Vorhaben in wenigen Worten – wir melden uns innerhalb von 24 Stunden bei Ihnen. Unverbindlich und kostenfrei.', ['desktop' => ['color' => '#666666', 'fontSize' => '15px', 'lineHeight' => 1.8, 'margin' => ['bottom' => '40px']]]), 'rise', 'short'), + $fx($column('kontakt-formular-karte', [ + ['id' => 'kontakt-formular', 'type' => 'form', 'props' => ['form' => 'kontakt'], + 'css' => '& .form-field{margin-bottom:18px} +& .form-field label{font-size:12.5px;letter-spacing:1.5px;text-transform:uppercase;font-weight:600;color:#6b6b6b;margin-bottom:0} +& .form-field input{width:100%;padding:14px 0;border:0;border-bottom:1px solid #ddd;border-radius:0;background:transparent;font-size:15px;color:#222;box-shadow:none;transition:border-color .35s} +& .form-field textarea{width:100%;padding:14px 0;border:0;border-bottom:1px solid #ddd;border-radius:0;background:transparent;font-size:15px;color:#222;box-shadow:none;transition:border-color .35s} +& .form-field input:focus{outline:none;border-bottom-color:#c6a36b;box-shadow:none} +& .form-field textarea:focus{outline:none;border-bottom-color:#c6a36b;box-shadow:none} +& .form-field textarea{min-height:120px;resize:vertical} +& .form-field input[type=checkbox]{width:16px;height:16px;accent-color:#c6a36b;margin-top:4px;padding:0} +& .form-consent label{font-size:13px;text-transform:none;letter-spacing:0;font-weight:400;color:#6b6b6b;line-height:1.55} +& .field-consent label{font-size:13px;text-transform:none;letter-spacing:0;font-weight:400;color:#6b6b6b;line-height:1.55} +& .cms-button{border-radius:0;padding:16px 48px;font-size:12.5px;letter-spacing:3px;margin-top:28px} +& .cms-button span{display:none}', ], + ], ['desktop' => ['backgroundColor' => '@papier', 'padding' => ['top' => '40px', 'right' => '38px', 'bottom' => '35px', 'left' => '38px'], 'borderWidth' => $nurOben('3px'), 'borderStyle' => 'solid', 'borderColor' => '@gold', 'shadowY' => '4px', 'shadowBlur' => '25px', 'shadowColor' => '#0000000f'], 'mobile' => ['padding' => ['top' => '28px', 'right' => '22px', 'bottom' => '25px', 'left' => '22px']]]), 'rise', 'medium'), + ], ['desktop' => ['flexGrow' => 7, 'flexBasis' => '0px', 'minWidth' => '0px', 'padding' => ['right' => '60px']], 'tablet' => ['padding' => ['right' => '30px']], 'mobile' => ['padding' => ['right' => '0px'], 'flexBasis' => 'auto', 'width' => '100%']]), + $column('kontakt-standort', [ + $fx($kleinzeile('kontakt-standort-label', 'Standort'), 'fade'), + $fx($heading('kontakt-standort-titel', 'Gernsbach im Murgtal', 2, ['desktop' => [...$h2Stil['desktop'], 'margin' => ['bottom' => '25px']], 'tablet' => $h2Stil['tablet'], 'mobile' => $h2Stil['mobile']]), 'rise'), + $fx($column('kontakt-anruf', [ + $text('kontakt-anruf-label', 'Lieber direkt anrufen?', ['desktop' => ['color' => '@gold', 'fontSize' => '11px', 'letterSpacing' => '4px', 'textTransform' => 'uppercase', 'fontWeight' => '600', 'margin' => ['bottom' => '12px']]]), + $text('kontakt-anruf-text', 'Für dringende Anfragen erreichen Sie uns telefonisch:', ['desktop' => ['color' => '#ffffff99', 'fontSize' => '14.5px', 'lineHeight' => 1.7, 'margin' => ['bottom' => '12px']]]), + $text('kontakt-anruf-nummer', ''.$telefon.'', ['desktop' => ['color' => '#ffffff', 'fontSize' => '21px', 'fontWeight' => '700', 'letterSpacing' => '0.5px', 'margin' => ['bottom' => '0px']]], "& a{color:#fff;text-decoration:none}\n& a:hover{color:#c6a36b}"), + ], ['desktop' => ['backgroundColor' => '#0e0e0e', 'color' => '#ffffff', 'padding' => ['top' => '30px', 'right' => '30px', 'bottom' => '30px', 'left' => '30px']]]), 'rise', 'short'), + $fx($bild('kontakt-foto', $seitenbilder['kontakt-foto'], 'Axel Drews telefoniert vor dem Firmenwagen', ['desktop' => ['imageHeight' => '320px', 'objectFit' => 'cover', 'objectPosition' => 'center', 'margin' => $seiten('0px')], 'mobile' => ['imageHeight' => '240px']]), 'fade', 'medium'), + $fx($column('kontakt-zeiten-karte', [ + $text('kontakt-zeiten-label', 'Öffnungszeiten', ['desktop' => ['color' => '@gold-text', 'fontSize' => '11px', 'letterSpacing' => '4px', 'textTransform' => 'uppercase', 'fontWeight' => '600', 'margin' => ['bottom' => '14px']]]), + $zeitenKarte('kontakt-zeit-1', 'Mo – Do', '07:00 – 16:30', true), + $zeitenKarte('kontakt-zeit-2', 'Freitag', '07:00 – 13:00'), + $zeitenKarte('kontakt-zeit-3', 'Sa & So', 'nach Vereinbarung', false, true), + ], ['desktop' => ['backgroundColor' => '@papier', 'padding' => ['top' => '25px', 'right' => '28px', 'bottom' => '25px', 'left' => '28px'], 'borderWidth' => $nurLinks('3px'), 'borderStyle' => 'solid', 'borderColor' => '@gold', 'shadowY' => '2px', 'shadowBlur' => '12px', 'shadowColor' => '#0000000a', 'margin' => ['top' => '30px']]]), 'rise', 'long'), + ], ['desktop' => ['flexGrow' => 5, 'flexBasis' => '0px', 'minWidth' => '0px'], 'mobile' => ['flexBasis' => 'auto', 'width' => '100%']]), + ], [], ['desktop' => ['display' => 'flex', 'alignItems' => 'flex-start', 'gap' => '0px', 'margin' => ['top' => '0px']], 'mobile' => ['flexDirection' => 'column', 'gap' => '50px']]), + ], ['desktop' => ['backgroundColor' => '@creme', 'padding' => ['top' => '110px', 'bottom' => '110px']], 'mobile' => ['padding' => ['top' => '70px', 'bottom' => '70px']]], 'kontakt'), + $section('kontakt-karte-abschnitt', [ + ['id' => 'kontakt-karte', 'type' => 'embed', 'props' => ['group' => 'external', 'title' => 'Google-Karte: Ihr Malerservice Drews, Am Bachgarten 1, Gernsbach', 'provider' => 'Google Maps', 'hint' => 'Die Karte wird von Google geladen. Dabei erfährt Google Ihre IP-Adresse.', 'url' => 'https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d4465.340405747277!2d8.329596477683358!3d48.7648255713197!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x4797184150f38e7b%3A0x77b609b6d2aa14ae!2sIhr%20Malerservice%20Drews!5e1!3m2!1sde!2sde!4v1770799998354!5m2!1sde!2sde', 'height' => 500], + 'css' => "& iframe{border-radius:0;filter:grayscale(85%) contrast(1.05) brightness(1.02);transition:filter .5s ease}\n&:hover iframe{filter:grayscale(15%) contrast(1.05)}\n&.embed-blocked{border-radius:0;padding:60px 24px}"], + ], ['desktop' => ['padding' => ['top' => '0px', 'bottom' => '0px']]], null, ['width' => 'full']), + ], +], 'Kontakt | Ihr Malerservice Drews Gernsbach', $seitenbilder['kontakt-foto']['id']); + +/** Eine Rechtsseite: heller Kopf mit Titel, darunter der übernommene Text in Absätzen. */ +$rechtsseite = static function (string $praefix, string $titel, array $abschnitte) use ($section, $column, $heading, $text, $fx): array { + $bloecke = []; + foreach ($abschnitte as $i => $inhalt) { + $bloecke[] = $text($praefix.'-text-'.($i + 1), $inhalt, ['desktop' => ['color' => '#414141', 'fontSize' => '15px', 'lineHeight' => 1.85, 'margin' => ['bottom' => '0px']]], "& p{margin:0 0 18px}\n& strong{color:#222}\n& ol{margin:0 0 18px;padding-left:24px}\n& ul{margin:0 0 18px;padding-left:24px}\n& li{margin-bottom:8px}\n& a{color:#8a6a2f;text-decoration:none;border-bottom:1px solid rgba(138,106,47,.45);overflow-wrap:anywhere}\n& a:hover{border-bottom-color:#8a6a2f}"); + } + + return [ + $section($praefix.'-kopf', [ + $fx($heading($praefix.'-h1', $titel, 1, ['desktop' => ['fontSize' => '54px', 'fontWeight' => '700', 'lineHeight' => 1.1, 'textAlign' => 'center', 'margin' => ['bottom' => '0px']], 'mobile' => ['fontSize' => '38px']]), 'rise'), + ], ['desktop' => ['backgroundColor' => '@creme', 'padding' => ['top' => '70px', 'bottom' => '70px']], 'mobile' => ['padding' => ['top' => '50px', 'bottom' => '50px']]]), + $section($praefix.'-inhalt', [$column($praefix.'-spalte', $bloecke, ['desktop' => ['maxWidth' => '860px', 'margin' => ['left' => 'auto', 'right' => 'auto']]])], ['desktop' => ['padding' => ['top' => '70px', 'bottom' => '100px']], 'mobile' => ['padding' => ['top' => '50px', 'bottom' => '70px']]]), + ]; +}; + +$anlegen('impressum', [ + 'schemaVersion' => $SCHEMA, 'title' => 'Impressum', + 'description' => 'Impressum von Ihr Malerservice Drews, Axel Drews, Am Bachgarten 1, 76593 Gernsbach – Anbieterkennzeichnung, Umsatzsteuer-ID und rechtliche Hinweise.', + 'blocks' => $rechtsseite('impressum', 'Impressum', [$inhalte['impressum']]), +], 'Impressum | Ihr Malerservice Drews'); + +$anlegen('datenschutz', [ + 'schemaVersion' => $SCHEMA, 'title' => 'Datenschutz', + 'description' => 'Datenschutzerklärung von Ihr Malerservice Drews: Art, Umfang und Zweck der Verarbeitung personenbezogener Daten auf dieser Website und Ihre Rechte.', + 'blocks' => $rechtsseite('datenschutz', 'Datenschutz', $inhalte['datenschutz']), +], 'Datenschutz | Ihr Malerservice Drews'); + +$fehlerId = $anlegen('404', [ + 'schemaVersion' => $SCHEMA, 'title' => 'Seite nicht gefunden', + 'description' => 'Die gesuchte Seite gibt es nicht oder sie wurde verschoben.', + 'blocks' => [ + $seitenkopf('fehler', $seitenbilder['hero-1'], 'Fehler 404', 'Hoppla! Diese Seite wurde nicht gefunden.', 'Es sieht so aus, als ob an dieser Stelle nichts gefunden wurde. Über die Startseite finden Sie zurück.', '60vh', '#050505', 0.68, [ + $button('fehler-knopf', 'Zur Startseite', '/', 'gold', false, ['desktop' => ['margin' => ['top' => '14px', 'left' => 'auto', 'right' => 'auto']]]), + ]), + ], +]); +$db->executeStatement('UPDATE page SET robots = ? WHERE id = ?', ['noindex', $fehlerId]); + +// --------------------------------------------------------------------------------------------- +// Beiträge: 5 Mitteilungen und 26 Projekte, jeweils mit Bildkopf, Text, Galerie, Nachbarn, Aufruf +// --------------------------------------------------------------------------------------------- + +$beitragAnlegen = static function (array $b, int $nummer) use ($pages, $posts, $db, $redirects, $hochladen, $section, $column, $heading, $text, $bild, $button, $fx, $ecken, $seiten, $SCHEMA, $h2Mitte, &$erstellt): void { + // Block-IDs müssen mit einem Buchstaben beginnen und kurz bleiben - die Adresse eines Beitrags tut beides nicht immer. + $p = 'beitrag-'.$nummer; + // Beiträge ohne Text bekommen einen Satz für Suche und Vorschau; leere Absätze zählen nicht als Text. + $inhalt = '' === trim(strip_tags($b['content'])) ? '' : $b['content']; + $beschreibung = '' !== $b['description'] ? $b['description'] : sprintf('„%s“ – ein Projekt von Ihr Malerservice Drews, Malermeister Axel Drews in Gernsbach.', $b['title']); + $bilder = []; + foreach ($b['images'] as $i => $datei) { + $bilder[] = $hochladen($datei, $b['title'].(0 === $i ? '' : ' – Bild '.($i + 1)), $b['slug'].(0 === $i ? '' : '-'.($i + 1))); + } + $kopfbild = $bilder[0]; + $bloecke = [ + $section($p.'-kopf', [ + $column($p.'-kopf-inhalt', [ + $fx($heading($p.'-h1', $b['title'], 1, ['desktop' => ['fontSize' => '46px', 'fontWeight' => '700', 'lineHeight' => 1.15, 'color' => '#ffffff', 'margin' => ['bottom' => '0px'], 'textShadowY' => '2px', 'textShadowBlur' => '20px', 'textShadowColor' => '#00000066'], 'tablet' => ['fontSize' => '36px'], 'mobile' => ['fontSize' => '30px']]), 'rise'), + ], ['desktop' => ['maxWidth' => '1100px']]), + ], [ + 'desktop' => ['backgroundImage' => $kopfbild['id'], 'backgroundSize' => 'cover', 'backgroundPosition' => 'center', 'gradientFrom' => '#0a0a0a33', 'gradientTo' => '#0a0a0ad9', 'gradientAngle' => 180, 'color' => '#ffffff', 'minHeight' => '62vh', 'display' => 'flex', 'alignItems' => 'flex-end', 'padding' => ['top' => '120px', 'bottom' => '50px']], + 'mobile' => ['minHeight' => '48vh', 'padding' => ['top' => '90px', 'bottom' => '36px']], + ]), + ]; + if ('' !== $inhalt) { + $bloecke[] = $section($p.'-text', [ + $column($p.'-text-spalte', [ + $text($p.'-inhalt', $inhalt, ['desktop' => ['color' => '#333333', 'fontSize' => '17px', 'lineHeight' => 1.85]], "& p{margin:0 0 20px}\n& p:last-child{margin-bottom:0}\n& strong{color:#2a2a2a}\n& a{color:#8a6a2f;text-decoration:underline}"), + ], ['desktop' => ['maxWidth' => '900px', 'margin' => ['left' => 'auto', 'right' => 'auto']]]), + ], ['desktop' => ['padding' => ['top' => '80px', 'bottom' => '80px']], 'mobile' => ['padding' => ['top' => '50px', 'bottom' => '50px']]]); + } + $bloecke[] = $section($p.'-galerie-abschnitt', [ + $heading($p.'-galerie-titel', 'news' === $b['kind'] ? 'Bilder' : 'Projektbilder', 2, ['desktop' => [...$h2Mitte['desktop'], 'fontSize' => '30px', 'margin' => ['bottom' => '50px']], 'mobile' => ['fontSize' => '26px', 'margin' => ['bottom' => '30px']]]), + ['id' => $p.'-galerie', 'type' => 'gallery', 'props' => ['lightbox' => true], 'children' => array_map( + static fn (array $foto, int $i): array => $bild($p.'-bild-'.($i + 1), $foto, $b['title'].(0 === $i ? '' : ' – Bild '.($i + 1)), ['desktop' => ['maxWidth' => 0 === $i ? '920px' : '450px', 'imageHeight' => '100%', 'objectFit' => 'cover', 'imageRadius' => $ecken('12px'), 'margin' => $seiten('0px')]], null, "& img{aspect-ratio:1/1;transition:transform .5s ease}\n&:hover img{transform:scale(1.05)}", true), + $bilder, array_keys($bilder), + ), 'style' => ['desktop' => ['gridColumns' => 3, 'gap' => '20px', 'maxWidth' => '1400px', 'margin' => ['left' => 'auto', 'right' => 'auto']], 'mobile' => ['gridColumns' => 2, 'gap' => '10px']], + 'css' => '& > :first-child{grid-column:span 2;grid-row:span 2}'], + ], ['desktop' => ['backgroundColor' => '#f8f9fa', 'padding' => ['top' => '80px', 'bottom' => '80px']], 'mobile' => ['padding' => ['top' => '50px', 'bottom' => '50px']]], null, ['width' => 'wide']); + $bloecke[] = $section($p.'-nachbarn', [ + ['id' => $p.'-navigation', 'type' => 'postnav', 'props' => ['previousLabel' => '← Vorheriges Projekt', 'nextLabel' => 'Nächstes Projekt →'], 'css' => "& .post-nav-link{border-radius:12px;box-shadow:0 4px 20px rgba(0,0,0,.05);border:0}\n& .post-nav-label{color:#8a6a2f}"], + ], ['desktop' => ['padding' => ['top' => '40px', 'bottom' => '40px']], 'mobile' => ['padding' => ['top' => '30px', 'bottom' => '30px']]], null, ['width' => 'wide']); + $bloecke[] = $section($p.'-aufruf', [ + $column($p.'-aufruf-inhalt', [ + $heading($p.'-aufruf-titel', 'Haben Sie ein ähnliches Projekt?', 2, ['desktop' => [...$h2Mitte['desktop'], 'color' => '#ffffff', 'fontSize' => '36px', 'margin' => ['bottom' => '16px']], 'mobile' => ['fontSize' => '28px']]), + $text($p.'-aufruf-text', 'Wir freuen uns darauf, mehr über Ihre Wünsche zu erfahren und Ihr Projekt professionell umzusetzen.', ['desktop' => ['color' => '#ffffffb3', 'fontSize' => '16px', 'lineHeight' => 1.8, 'textAlign' => 'center', 'maxWidth' => '600px', 'margin' => ['left' => 'auto', 'right' => 'auto', 'bottom' => '32px']]]), + $button($p.'-aufruf-knopf', 'Jetzt Kontakt aufnehmen', '/kontakt', 'gold-pille', false, ['desktop' => ['margin' => ['top' => '0px', 'left' => 'auto', 'right' => 'auto']]], 'normal'), + ], ['desktop' => ['display' => 'flex', 'flexDirection' => 'column', 'alignItems' => 'center']]), + ], ['desktop' => ['backgroundColor' => '#2a2a2a', 'color' => '#ffffff', 'padding' => ['top' => '90px', 'bottom' => '90px']], 'mobile' => ['padding' => ['top' => '60px', 'bottom' => '60px']]]); + + // Adressen sind auf 80 Zeichen begrenzt; die eine längere der Vorlage wird gekürzt und umgeleitet. + $slug = strlen($b['slug']) > 80 ? substr($b['slug'], 0, strrpos(substr($b['slug'], 0, 80), '-')) : $b['slug']; + $id = $pages->createPage($slug, null, 'post', [ + 'schemaVersion' => $SCHEMA, 'title' => $b['title'], 'description' => $beschreibung, + 'blocks' => $bloecke, + ]); + $seite = $db->fetchAssociative('SELECT version FROM page WHERE id = ?', [$id]); + $posts->saveMetadata($id, [ + 'excerpt' => $b['excerpt'], 'author' => '', 'publishedAt' => $b['date'], 'featuredMediaId' => $kopfbild['id'], 'ogMediaId' => $kopfbild['id'], + 'seoTitle' => $b['title'].' | Ihr Malerservice Drews', 'robots' => 'index', + ], ['news' === $b['kind'] ? 'Aktuelles' : 'Projekte'], [], (int) $seite['version']); + $seite = $db->fetchAssociative('SELECT draft_revision_id, version FROM page WHERE id = ?', [$id]); + $pages->publish($id, $seite['draft_revision_id'], (int) $seite['version']); + $erstellt[$b['slug']] = $id; + if ($slug !== $b['slug']) { + $redirects->save('/'.$b['slug'], '/'.$slug, 301); + } + echo 'Beitrag angelegt: /'.$slug.' ('.count($bilder)." Bilder)\n"; +}; + +foreach ($inhalte['beitraege'] as $i => $beitrag) { + $beitragAnlegen($beitrag, $i + 1); +} + +// --------------------------------------------------------------------------------------------- +// Menüs, Einstellungen, Weiterleitungen, Konto +// --------------------------------------------------------------------------------------------- + +$seite = static fn (string $label, string $slug, string $anchor = ''): array => ['label' => $label, 'type' => 'page', 'pageId' => $erstellt[$slug], 'anchor' => $anchor, 'children' => []]; + +$hauptmenue = [ + $seite('Home', 'home'), + $seite('Über Uns', 'home', 'ueber-uns'), + $seite('Aktuelles', 'aktuelles'), + $seite('Unsere Projekte', 'unsere-projekte'), + $seite('Kunstmalerei', 'kunstmalerei'), + $seite('Kontakt', 'kontakt'), +]; +$menus->save('header', 'Hauptnavigation', $hauptmenue, 0); +$menus->save('footer', 'Fußzeile', $hauptmenue, 0); +$menus->save('legal', 'Rechtliches', [$seite('Impressum', 'impressum'), $seite('Datenschutz', 'datenschutz')], 0); +echo "Menüs angelegt\n"; + +$settings->assignNotFoundPage($fehlerId, ''); +$settings->save([ + 'legalName' => 'Ihr Malerservice Drews', + 'description' => 'Malermeister Axel Drews in Gernsbach: Innenausbau und Raumgestaltung, Fassadenarbeiten, Restaurierung und Denkmalpflege sowie Kunstmalerei. Seit über 60 Jahren erstklassiges Malerhandwerk in Gernsbach und Mittelbaden, offizieller Little-Greene-Partner.', + 'phone' => $telefon, 'email' => $mail, + 'street' => 'Am Bachgarten 1', 'postalCode' => '76593', 'city' => 'Gernsbach', 'country' => 'DE', + 'social' => ['instagram' => 'https://www.instagram.com/malerservicedrews/'], + 'hours' => [...array_fill_keys(['Monday', 'Tuesday', 'Wednesday', 'Thursday'], ['opens' => '07:00', 'closes' => '16:30']), 'Friday' => ['opens' => '07:00', 'closes' => '13:00']], + 'areaServed' => implode("\n", ['Gernsbach', 'Loffenau', 'Gaggenau', 'Baden-Baden', 'Rastatt', 'Kuppenheim', 'Bühl', 'Murgtal', 'Mittelbaden']), + 'localBusiness' => true, 'llmsTxt' => true, + 'faviconMediaId' => $seitenbilder['favicon']['id'], + 'stickyHeader' => true, 'headerOverlay' => false, + 'motion' => 'always', + 'homePath' => 'home', 'privacyPath' => 'datenschutz', 'imprintPath' => 'impressum', + // Karte und Videos laden erst nach Einwilligung; deshalb die Frage als Leiste im Zuschnitt der Website. + 'consentBanner' => true, 'consentGroups' => ['external'], 'consentLayout' => 'leiste', 'consentShape' => 'eckig', + 'consentTitle' => 'Externe Inhalte', 'consentText' => 'Die Google-Karte auf der Kontaktseite und die Videos der Kunstmalerei werden von anderen Anbietern geladen. Sie entscheiden, ob das geschehen darf.', + 'consentColor' => '#111111', 'consentInk' => '#ffffff', 'consentAccent' => '@gold', 'consentAccentInk' => '#111111', + 'scrollTop' => true, 'scrollTopShape' => 'eckig', 'scrollTopColor' => '@gold', 'scrollTopInk' => '@tinte', + 'postMetaHeader' => false, +]); +echo "Einstellungen gespeichert\n"; + +foreach (['/about-us' => '/home', '/innenaustattung' => '/unsere-projekte', '/little-greene' => '/exklusiv-in-mittelbaden-wir-sind-offizieller-little-greene-partner', '/blocks/footer' => '/home'] as $von => $nach) { + $redirects->save($von, $nach, 301); +} +echo "Weiterleitungen angelegt\n"; + +$passwort = bin2hex(random_bytes(12)); +$db->insert('cms_user', ['id' => bin2hex(random_bytes(16)), 'username' => 'umut', 'password_hash' => password_hash($passwort, PASSWORD_BCRYPT), 'roles' => '["ROLE_ADMIN"]']); + +echo "\nFertig.\nVerwaltung: Benutzer „umut“, Passwort: $passwort\n"; diff --git a/templates/page.html.twig b/templates/page.html.twig index 7e3dd51..d3a6198 100644 --- a/templates/page.html.twig +++ b/templates/page.html.twig @@ -104,8 +104,10 @@ Ankerpositionierung auf ihre Oberkante, und ein Anker muss im Dokument davor stehen. #} {% set oben = siteSettings.load() %} {% if oben.scrollTop|default(false) and not editing|default(false) %} - {# Ein Anker, kein Skript. Er springt an den Anfang - das kann ein Browser allein. #} - + {# Ein Anker, kein Skript. Er springt an den Anfang - das kann ein Browser allein. Der nav-Rahmen + gibt ihm eine Landmarke: ein Verweis außerhalb jeder Landmarke ist für Vorlesesoftware + Inhalt ohne Ort, und axe meldet ihn als Verstoß gegen „region“. #} + {% endif %}