Styles/global #1
No files matched your search
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 3.8 KiB |
@@ -34,7 +34,7 @@
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: var(--font-size-small);
|
||||
font-size: var(--font-size-xs);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
letter-spacing: var(--letter-spacing-wide);
|
||||
text-transform: uppercase;
|
||||
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@@ -19,19 +19,12 @@ html.has-menu-open {
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
max-width: 100vw;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: var(--font-body-color);
|
||||
background: var(--color-background);
|
||||
font-family: var(--font-body);
|
||||
font-size: 1rem;
|
||||
font-size: var(--font-size-base);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
line-height: var(--line-height-body);
|
||||
@@ -40,19 +33,10 @@ body {
|
||||
|
||||
main {
|
||||
width: 100%;
|
||||
max-width: 1280px;
|
||||
margin-inline: auto;
|
||||
padding: 0 var(--space-4);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
main {
|
||||
padding: 0 var(--space-4);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
main {
|
||||
padding: 0 var(--space-6);
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="1024" height="1024" viewBox="0 0 1024 1024"><metadata><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"><rdf:Description><dc:creator>RealFaviconGenerator</dc:creator><dc:source>https://realfavicongenerator.net</dc:source></rdf:Description></rdf:RDF></metadata><image width="1024" height="1024" xlink:href="data:image/png;base64,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 truncated
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="1024" height="1024" viewBox="0 0 1024 1024"><metadata><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"><rdf:Description><dc:creator>RealFaviconGenerator</dc:creator><dc:source>https://realfavicongenerator.net</dc:source></rdf:Description></rdf:RDF></metadata><image width="1024" height="1024" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABAAAAAQAEAYAAAAvjffAAAAFFmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIgogICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgeG1wOkNyZWF0ZURhdGU9IjIwMjYtMDQtMjhUMTI6MzE6MzgrMDI6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDI2LTA0LTI4VDEyOjMyOjMyKzAyOjAwIgogICB4bXA6TWV0YWRhdGFEYXRlPSIyMDI2LTA0LTI4VDEyOjMyOjMyKzAyOjAwIgogICBwaG90b3Nob3A6RGF0ZUNyZWF0ZWQ9IjIwMjYtMDQtMjhUMTI6MzE6MzgrMDI6MDAiCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjEwMjQiCiAgIGV4aWY6UGl4ZWxZ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 truncated
|
||||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.7 KiB |
@@ -1,10 +1,10 @@
|
||||
import CookieConsentBanner from "@/components/CookieConsent";
|
||||
import type { Metadata, Viewport } from "next";
|
||||
import { Manrope, Nunito_Sans } from "next/font/google";
|
||||
import "./globals.css";
|
||||
|
||||
import Footer from "@/components/Footer";
|
||||
import Header from "@/components/Header";
|
||||
import CookieConsentLoader from "@/components/CookieConsentLoader";
|
||||
|
||||
const nunitoSans = Nunito_Sans({
|
||||
subsets: ["latin"],
|
||||
@@ -25,14 +25,14 @@ export const viewport: Viewport = {
|
||||
initialScale: 1,
|
||||
};
|
||||
|
||||
const siteName = "ENVU";
|
||||
const title = "ENVU - Code Connect";
|
||||
const siteName = "Basiclean";
|
||||
const title = "Basiclean";
|
||||
const description = "Wir bieten Ihnen maßgeschneiderte Lösungen.";
|
||||
const siteUrl = "https://envu.de";
|
||||
const siteUrl = "https://basiclean.de";
|
||||
|
||||
const ogImage = {
|
||||
url: "/images/envu.png",
|
||||
alt: "Envu Wallpaper",
|
||||
url: "/images/baiclean.png",
|
||||
alt: "Basiclean",
|
||||
width: 1200,
|
||||
height: 628,
|
||||
};
|
||||
@@ -44,7 +44,7 @@ export const metadata: Metadata = {
|
||||
template: `%s | ${siteName}`,
|
||||
},
|
||||
description,
|
||||
keywords: "Envu, Hannover",
|
||||
keywords: "Basiclean, Hannover",
|
||||
authors: [{ name: siteName }],
|
||||
robots: "index, follow",
|
||||
alternates: {
|
||||
@@ -64,7 +64,7 @@ export const metadata: Metadata = {
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
site: "@envu",
|
||||
site: "@basiclean",
|
||||
title,
|
||||
description,
|
||||
images: [{ url: ogImage.url, alt: ogImage.alt }],
|
||||
@@ -94,10 +94,10 @@ export default function RootLayout({
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
||||
/>
|
||||
<CookieConsentLoader />
|
||||
<Header />
|
||||
{children}
|
||||
<Footer />
|
||||
<CookieConsentBanner />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ENVU",
|
||||
"short_name": "ENVU",
|
||||
"name": "Basiclean",
|
||||
"short_name": "Basiclean",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/favicon/web-app-manifest-192x192.png",
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: var(--font-size-small);
|
||||
font-size: var(--font-size-xs);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
letter-spacing: var(--letter-spacing-wide);
|
||||
text-transform: uppercase;
|
||||
|
||||
@@ -1,192 +1,25 @@
|
||||
import { ArrowRightIcon } from "@phosphor-icons/react/dist/ssr";
|
||||
import AboutUsSection from "@/components/AboutUsSection";
|
||||
import BenefitsSection from "@/components/benefitsSection";
|
||||
import ContactCtaSection from "@/components/contact/ContactCtaSection";
|
||||
import { homepageFaq } from "@/components/faq/faqData";
|
||||
import FaqSection from "@/components/faq/FaqSection";
|
||||
import HeroSection from "@/components/HeroSection";
|
||||
import IndustrySolutionsSection from "@/components/IndustrySolutionsSection";
|
||||
import ServiceSection from "@/components/ServiceSection";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main>
|
||||
<h1>Startseite</h1>
|
||||
<h2>Startseite</h2>
|
||||
<h3>Startseite</h3>
|
||||
<h4>Startseite</h4>
|
||||
<p>Startseite</p>
|
||||
<br />
|
||||
<button className="btn btn--filled">Filled</button>
|
||||
<br />
|
||||
<br />
|
||||
<button className="btn btn--outline">Outline</button>
|
||||
<br />
|
||||
<br />
|
||||
<button className="btn btn--ghost">Ghost</button>
|
||||
<br />
|
||||
<br />
|
||||
<button className="btn btn--tertiary">Tertiary</button>
|
||||
<br />
|
||||
<br />
|
||||
<button className="btn btn--filled" disabled>
|
||||
Disabled
|
||||
</button>
|
||||
<br />
|
||||
<br />
|
||||
<button className="btn btn--filled">
|
||||
<ArrowRightIcon className="btn-icon animate" size={18} />
|
||||
Jetzt starten
|
||||
</button>
|
||||
<br />
|
||||
<br />
|
||||
<button className="btn btn--outline">
|
||||
<ArrowRightIcon className="btn-icon animate" size={18} />
|
||||
Outline
|
||||
</button>
|
||||
<br />
|
||||
<br />
|
||||
<button className="btn btn--ghost">
|
||||
<ArrowRightIcon className="btn-icon animate" size={18} />
|
||||
Ghost
|
||||
</button>
|
||||
<br />
|
||||
<br />
|
||||
<button className="btn btn--tertiary">
|
||||
<ArrowRightIcon className="btn-icon animate" size={18} />
|
||||
Tertiary
|
||||
</button>
|
||||
<br />
|
||||
<br />
|
||||
<button className="btn btn--filled" disabled>
|
||||
<ArrowRightIcon className="btn-icon animate" size={18} />
|
||||
Disabled
|
||||
</button>
|
||||
<br />
|
||||
<br />
|
||||
<p>
|
||||
<a href="#">Webdesign</a> und Webentwicklung bilden das Fundament jeder
|
||||
erfolgreichen digitalen Präsenz. Während Webdesign die visuelle
|
||||
Gestaltung, Benutzerführung und das Nutzererlebnis in den Vordergrund
|
||||
stellt, sorgt die Webentwicklung für die technische Umsetzung im
|
||||
Hintergrund. Beide Disziplinen greifen eng ineinander – ein
|
||||
ansprechendes Design entfaltet seine volle Wirkung nur durch sauberen,
|
||||
performanten Code.
|
||||
</p>
|
||||
<p>
|
||||
Moderne Websites müssen auf allen Geräten funktionieren, schnell laden
|
||||
und barrierefrei zugänglich sein. Suchmaschinenoptimierung, Ladezeiten
|
||||
und intuitive Navigation sind dabei keine optionalen Extras, sondern
|
||||
entscheidende Faktoren für den Erfolg. Wer heute im Netz wahrgenommen
|
||||
werden möchte, braucht mehr als nur eine schöne Oberfläche – er braucht
|
||||
eine durchdachte digitale Strategie, die Design und Technik vereint.
|
||||
</p>
|
||||
<br />
|
||||
<h2>Kontakt</h2>
|
||||
<form>
|
||||
{/* Name */}
|
||||
<div className="form-group">
|
||||
<label className="form-label form-label--required" htmlFor="name">
|
||||
Name
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
name="name"
|
||||
placeholder="Max Mustermann"
|
||||
<HeroSection />
|
||||
<ServiceSection />
|
||||
<BenefitsSection />
|
||||
<IndustrySolutionsSection />
|
||||
<FaqSection
|
||||
title="In drei Schritten zu planbarer Sauberkeit"
|
||||
items={homepageFaq}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* E-Mail */}
|
||||
<div className="form-group">
|
||||
<label className="form-label form-label--required" htmlFor="email">
|
||||
E-Mail
|
||||
</label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
placeholder="max@beispiel.de"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Telefon */}
|
||||
<div className="form-group">
|
||||
<label className="form-label" htmlFor="telefon">
|
||||
Telefon
|
||||
</label>
|
||||
<input
|
||||
type="tel"
|
||||
id="telefon"
|
||||
name="telefon"
|
||||
placeholder="+49 511 123456"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Betreff */}
|
||||
<div className="form-group">
|
||||
<label className="form-label" htmlFor="betreff">
|
||||
Betreff
|
||||
</label>
|
||||
<select id="betreff" name="betreff">
|
||||
<option value="">Bitte auswählen</option>
|
||||
<option value="anfrage">Allgemeine Anfrage</option>
|
||||
<option value="angebot">Angebotsanfrage</option>
|
||||
<option value="support">Support</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Nachricht */}
|
||||
<div className="form-group">
|
||||
<label
|
||||
className="form-label form-label--required"
|
||||
htmlFor="nachricht"
|
||||
>
|
||||
Nachricht
|
||||
</label>
|
||||
<textarea
|
||||
id="nachricht"
|
||||
name="nachricht"
|
||||
placeholder="Ihre Nachricht..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Datenschutz Checkbox */}
|
||||
<div className="form-group">
|
||||
<label className="form-check">
|
||||
<input type="checkbox" />
|
||||
<span className="form-check-label">
|
||||
Ich habe die Datenschutzerklärung gelesen und stimme zu.
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* Error-Beispiel zum Testen */}
|
||||
<div className="form-group">
|
||||
<label className="form-label" htmlFor="fehler">
|
||||
Fehler-Beispiel
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="fehler"
|
||||
className="is-error"
|
||||
defaultValue="Falscher Wert"
|
||||
/>
|
||||
<span className="form-error-msg">
|
||||
Bitte gib einen gültigen Wert ein.
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Disabled-Beispiel */}
|
||||
<div className="form-group">
|
||||
<label className="form-label" htmlFor="deaktiviert">
|
||||
Deaktiviert
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="deaktiviert"
|
||||
disabled
|
||||
defaultValue="Nicht bearbeitbar"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Submit */}
|
||||
<button type="submit" className="btn btn--filled">
|
||||
Nachricht senden
|
||||
</button>
|
||||
</form>
|
||||
<AboutUsSection />
|
||||
<ContactCtaSection />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -1,9 +1,6 @@
|
||||
// app/sitemap.ts
|
||||
// Erreichbar unter: https://deinedomain.de/sitemap.xml
|
||||
|
||||
import type { MetadataRoute } from "next";
|
||||
|
||||
const BASE_URL = "https://deinedomain.de"; // ← Domain anpassen
|
||||
const BASE_URL = "https://basiclean.de";
|
||||
|
||||
// ─── Typen ───────────────────────────────────────────────────────────────────
|
||||
// interface BlogPost {
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
"use client";
|
||||
|
||||
export default function TestErrorPage() {
|
||||
throw new Error("Testfehler – Error-Seite prüfen");
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
export type AboutUsMember = {
|
||||
name: string;
|
||||
imageSrc: string;
|
||||
imageAlt: string;
|
||||
};
|
||||
|
||||
export type AboutUsData = {
|
||||
title: string;
|
||||
paragraphs: string[];
|
||||
members: AboutUsMember[];
|
||||
};
|
||||
|
||||
export const aboutUsData: AboutUsData = {
|
||||
title: "Ihre Reinigungsfirma für professionelle Ansprüche",
|
||||
paragraphs: [
|
||||
"Basiclean ist ein junges Reinigungsunternehmen mit Fokus auf gewerbliche Kunden in Hannover und der umliegenden Region.",
|
||||
"Unser Ziel ist es, Unternehmen mit planbarer Sauberkeit, klaren Abläufen und zuverlässiger Zusammenarbeit zu entlasten. Statt starrer Standards bieten wir individuelle Reinigungslösungen, abgestimmt auf Ihr Objekt und Ihre Anforderungen.",
|
||||
"Persönlicher Kontakt, transparente Leistungen und geschulte Reinigungskräfte stehen dabei im Mittelpunkt.",
|
||||
],
|
||||
members: [
|
||||
{
|
||||
name: "Abdulkabi Dastan",
|
||||
imageSrc: "/images/portrait/abdulkabi-dastan.jpg",
|
||||
imageAlt: "Porträt von Abdulkabi Dastan",
|
||||
},
|
||||
{
|
||||
name: "Gökhan Özsayiner",
|
||||
imageSrc: "/images/portrait/goekhan-oezsayiner.jpg",
|
||||
imageAlt: "Porträt von Gökhan Özsayiner",
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,120 @@
|
||||
.section {
|
||||
padding-block: var(--space-16);
|
||||
}
|
||||
|
||||
.inner {
|
||||
width: 100%;
|
||||
max-width: var(--container-width);
|
||||
margin-inline: auto;
|
||||
padding-inline: var(--space-4);
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: var(--space-8);
|
||||
justify-items: center;
|
||||
}
|
||||
|
||||
.heading {
|
||||
max-width: 20ch;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.team {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: var(--space-4);
|
||||
max-width: 420px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-3);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.imageWrap {
|
||||
position: relative;
|
||||
aspect-ratio: 4 / 5;
|
||||
overflow: hidden;
|
||||
border-radius: 20px;
|
||||
background: #e9e9e9;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.image {
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: var(----font-size-xs);
|
||||
color: var(--color-text);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.textBlock {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-5);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.text {
|
||||
max-width: 56ch;
|
||||
color: var(--color-text-muted);
|
||||
font-size: var(----font-size-xs);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.section {
|
||||
padding-block: var(--space-24);
|
||||
}
|
||||
|
||||
.inner {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
column-gap: var(--space-16);
|
||||
row-gap: var(--space-8);
|
||||
align-items: start;
|
||||
justify-items: stretch;
|
||||
}
|
||||
|
||||
.heading {
|
||||
grid-column: 1 / -1;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.team {
|
||||
grid-column: 1;
|
||||
grid-row: 2;
|
||||
}
|
||||
|
||||
.card {
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.textBlock {
|
||||
grid-column: 2;
|
||||
grid-row: 2;
|
||||
align-self: center;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.text {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.section {
|
||||
padding-block: var(--space-32);
|
||||
}
|
||||
|
||||
.inner {
|
||||
padding-inline: var(--space-6);
|
||||
}
|
||||
|
||||
.team {
|
||||
max-width: 460px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import styles from "./AboutUsSection.module.css";
|
||||
import { aboutUsData } from "./AboutUsData";
|
||||
|
||||
export default function AboutUsSection() {
|
||||
const { title, paragraphs, members } = aboutUsData;
|
||||
|
||||
return (
|
||||
<section className={styles.section} aria-labelledby="about-us-heading">
|
||||
<div className={styles.inner}>
|
||||
<h2 id="about-us-heading" className={styles.heading}>
|
||||
{title}
|
||||
</h2>
|
||||
|
||||
<div className={styles.team}>
|
||||
{members.map((member) => (
|
||||
<article key={member.name} className={styles.card}>
|
||||
<div className={styles.imageWrap}>
|
||||
<Image
|
||||
src={member.imageSrc}
|
||||
alt={member.imageAlt}
|
||||
fill
|
||||
className={styles.image}
|
||||
sizes="(max-width: 767px) 42vw, 180px"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<p className={styles.name}>{member.name}</p>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className={styles.textBlock}>
|
||||
{paragraphs.map((paragraph, index) => (
|
||||
<p key={index} className={styles.text}>
|
||||
{paragraph}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -29,5 +29,5 @@
|
||||
}
|
||||
|
||||
:global(#cc-main .cm) {
|
||||
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.08) !important;
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.08) !important;
|
||||
}
|
||||
@@ -1,12 +1,31 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import * as CookieConsent from "vanilla-cookieconsent";
|
||||
import "vanilla-cookieconsent/dist/cookieconsent.css";
|
||||
import "./CookieConsent.module.css";
|
||||
|
||||
export default function CookieConsentBanner() {
|
||||
useEffect(() => {
|
||||
let mounted = true;
|
||||
let idleId: number | undefined;
|
||||
let timeoutId: ReturnType<typeof setTimeout> | undefined;
|
||||
|
||||
const loadConsent = async () => {
|
||||
const [cookieConsentModule] = await Promise.all([
|
||||
import("vanilla-cookieconsent"),
|
||||
import("vanilla-cookieconsent/dist/cookieconsent.css"),
|
||||
]);
|
||||
|
||||
const mod = cookieConsentModule as {
|
||||
run?: (config: unknown) => void;
|
||||
default?: {
|
||||
run?: (config: unknown) => void;
|
||||
};
|
||||
};
|
||||
|
||||
const CookieConsent = mod.run ? mod : mod.default;
|
||||
|
||||
if (!mounted || !CookieConsent?.run) return;
|
||||
|
||||
CookieConsent.run({
|
||||
categories: {
|
||||
necessary: {
|
||||
@@ -23,10 +42,7 @@ export default function CookieConsentBanner() {
|
||||
consentModal: {
|
||||
title: "Ihre Privatsphäre ist uns wichtig",
|
||||
description:
|
||||
"Wir verwenden Cookies, um Ihnen die bestmögliche Nutzung unserer Website zu ermöglichen. " +
|
||||
"Einige Cookies sind technisch notwendig, andere helfen uns, die Website zu verbessern " +
|
||||
"und Ihnen relevante Inhalte anzuzeigen. Sie können Ihre Auswahl jederzeit unter " +
|
||||
"<a href='/datenschutz'>Datenschutz</a> anpassen oder widerrufen.",
|
||||
"Wir setzen notwendige und optionale Cookies ein. Ihre Auswahl können Sie jederzeit unter <a href='/datenschutz'>Datenschutz</a> ändern.",
|
||||
acceptAllBtn: "Alle akzeptieren",
|
||||
acceptNecessaryBtn: "Nur notwendige",
|
||||
showPreferencesBtn: "Einstellungen anpassen",
|
||||
@@ -44,44 +60,30 @@ export default function CookieConsentBanner() {
|
||||
{
|
||||
title: "Ihre Privatsphäre",
|
||||
description:
|
||||
"Wir setzen Cookies ein, um die Funktionalität unserer Website sicherzustellen " +
|
||||
"und unser Angebot kontinuierlich zu verbessern. Sie entscheiden selbst, " +
|
||||
"welche Kategorien Sie zulassen möchten.",
|
||||
"Wir setzen Cookies ein, um die Funktionalität unserer Website sicherzustellen und unser Angebot kontinuierlich zu verbessern. Sie entscheiden selbst, welche Kategorien Sie zulassen möchten.",
|
||||
},
|
||||
{
|
||||
title: "Technisch notwendig",
|
||||
description:
|
||||
"Diese Cookies sind für den reibungslosen Betrieb der Website unbedingt erforderlich " +
|
||||
"und können nicht deaktiviert werden. Sie speichern keine personenbezogenen Daten " +
|
||||
"und werden ausschließlich als Reaktion auf von Ihnen durchgeführte Aktionen gesetzt " +
|
||||
"(z. B. Spracheinstellungen oder Sicherheits-Token).",
|
||||
"Diese Cookies sind für den reibungslosen Betrieb der Website unbedingt erforderlich und können nicht deaktiviert werden.",
|
||||
linkedCategory: "necessary",
|
||||
},
|
||||
{
|
||||
title: "Analyse & Statistik",
|
||||
description:
|
||||
"Diese Cookies helfen uns zu verstehen, wie Besucher mit unserer Website interagieren. " +
|
||||
"Alle Daten werden anonymisiert gesammelt und dienen ausschließlich zur Verbesserung " +
|
||||
"unseres Angebots. Wir nutzen Google Analytics (GA4) – Ihre IP-Adresse wird dabei " +
|
||||
"anonymisiert und nicht gespeichert.",
|
||||
"Diese Cookies helfen uns zu verstehen, wie Besucher mit unserer Website interagieren.",
|
||||
linkedCategory: "analytics",
|
||||
},
|
||||
{
|
||||
title: "Marketing & externe Medien",
|
||||
description:
|
||||
"Diese Cookies ermöglichen die Einbindung externer Inhalte wie YouTube-Videos, " +
|
||||
"Google Maps, Instagram-, Facebook- und X (Twitter)-Inhalte. " +
|
||||
"Ohne Ihre Zustimmung werden diese Inhalte nicht geladen und keine Daten übertragen. " +
|
||||
"Bitte beachten Sie, dass bei Aktivierung personenbezogene Daten " +
|
||||
"an Drittanbieter (ggf. auch in die USA) übertragen werden können.",
|
||||
"Diese Cookies ermöglichen die Einbindung externer Inhalte wie YouTube-Videos, Google Maps, Instagram-, Facebook- und X-Inhalte.",
|
||||
linkedCategory: "marketing",
|
||||
},
|
||||
{
|
||||
title: "Weitere Informationen",
|
||||
description:
|
||||
"Bei Fragen zu unserer Cookie-Richtlinie wenden Sie sich bitte an uns über das " +
|
||||
"<a href='/kontakt'>Kontaktformular</a>. Mehr Details finden Sie in unserer " +
|
||||
"<a href='/datenschutz'>Datenschutzerklärung</a>.",
|
||||
"Bei Fragen wenden Sie sich bitte über das <a href='/kontakt'>Kontaktformular</a> an uns. Mehr Details finden Sie in unserer <a href='/datenschutz'>Datenschutzerklärung</a>.",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -89,6 +91,32 @@ export default function CookieConsentBanner() {
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
if (window.requestIdleCallback) {
|
||||
idleId = window.requestIdleCallback(
|
||||
() => {
|
||||
void loadConsent();
|
||||
},
|
||||
{ timeout: 2000 },
|
||||
);
|
||||
} else {
|
||||
timeoutId = setTimeout(() => {
|
||||
void loadConsent();
|
||||
}, 300);
|
||||
}
|
||||
|
||||
return () => {
|
||||
mounted = false;
|
||||
|
||||
if (idleId && window.cancelIdleCallback) {
|
||||
window.cancelIdleCallback(idleId);
|
||||
}
|
||||
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
"use client";
|
||||
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
const CookieConsentBanner = dynamic(() => import("./CookieConsent"), {
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
export default function CookieConsentLoader() {
|
||||
return <CookieConsentBanner />;
|
||||
}
|
||||
@@ -1,15 +1,9 @@
|
||||
/*
|
||||
FOOTER
|
||||
Datei: components/Footer.module.css
|
||||
*/
|
||||
|
||||
:root {
|
||||
--footer-bg: #171717;
|
||||
--footer-text: #a1a1aa;
|
||||
--footer-bg: #272727;
|
||||
--footer-text: #adadb3;
|
||||
--footer-text-hover: #ffffff;
|
||||
--footer-title: #ffffff;
|
||||
--footer-divider: rgba(255, 255, 255, 0.1);
|
||||
--footer-padding-y: clamp(3rem, 6vw, 5rem);
|
||||
--footer-gap: clamp(2rem, 5vw, 4rem);
|
||||
}
|
||||
|
||||
@@ -17,13 +11,18 @@
|
||||
.footer {
|
||||
background-color: var(--footer-bg);
|
||||
color: var(--footer-text);
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.footer a:focus-visible {
|
||||
outline: 2px solid var(--nav-outline-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.footer__inner {
|
||||
max-width: 1280px;
|
||||
max-width: var(--container-width);
|
||||
margin-inline: auto;
|
||||
padding: var(--footer-padding-y) clamp(1rem, 5vw, 2rem);
|
||||
padding-inline: var(--space-4);
|
||||
padding-block: var(--space-16);
|
||||
}
|
||||
|
||||
/* Top */
|
||||
@@ -33,26 +32,16 @@
|
||||
gap: var(--footer-gap);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.footer__top {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.footer__top {
|
||||
grid-template-columns: 1.5fr 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Brand */
|
||||
.footer__brand {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
|
||||
.footer__logo {
|
||||
display: inline-block;
|
||||
font-size: 1.4rem;
|
||||
font-weight: 700;
|
||||
color: var(--footer-title);
|
||||
margin-bottom: 0.75rem;
|
||||
transition: opacity 0.2s ease;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.footer__logo:hover {
|
||||
@@ -60,8 +49,6 @@
|
||||
}
|
||||
|
||||
.footer__tagline {
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.6;
|
||||
max-width: 32ch;
|
||||
color: var(--footer-text);
|
||||
}
|
||||
@@ -69,34 +56,32 @@
|
||||
/* Navigation */
|
||||
.footer__nav {
|
||||
display: flex;
|
||||
gap: var(--footer-gap);
|
||||
flex-wrap: wrap;
|
||||
gap: var(--footer-gap);
|
||||
}
|
||||
|
||||
.footer__nav ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.footer__nav-group ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.6rem;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.footer__nav-title {
|
||||
display: block;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
margin-bottom: var(--space-4);
|
||||
font-size: var(--font-size-xxs);
|
||||
letter-spacing: var(--letter-spacing-wide);
|
||||
color: var(--footer-title);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.footer__nav-group a {
|
||||
font-size: 0.9rem;
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--footer-text);
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
@@ -152,3 +137,31 @@
|
||||
border-color: rgba(255, 255, 255, 0.3);
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
/* Tablet */
|
||||
@media (min-width: 768px) {
|
||||
.footer__top {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.footer__nav {
|
||||
justify-self: end;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
/* Desktop */
|
||||
@media (min-width: 1024px) {
|
||||
.footer__inner {
|
||||
padding-inline: var(--space-6);
|
||||
}
|
||||
|
||||
.footer__top {
|
||||
grid-template-columns: 1fr auto;
|
||||
}
|
||||
|
||||
.footer__nav {
|
||||
justify-self: end;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
import styles from "./Footer.module.css";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import {
|
||||
InstagramLogoIcon,
|
||||
LinkedinLogoIcon,
|
||||
XLogoIcon,
|
||||
FacebookLogoIcon,
|
||||
} from "@phosphor-icons/react/dist/ssr";
|
||||
import { companyData } from "@/data/companyData";
|
||||
|
||||
const currentYear = new Date().getFullYear();
|
||||
|
||||
@@ -13,22 +15,24 @@ export default function Footer() {
|
||||
return (
|
||||
<footer className={styles.footer}>
|
||||
<div className={styles.footer__inner}>
|
||||
{/* Top: Brand + Navigation */}
|
||||
<div className={styles.footer__top}>
|
||||
{/* Brand */}
|
||||
<div className={styles.footer__brand}>
|
||||
<Link href="/" className={styles.footer__logo}>
|
||||
ENVU {/* ← Logo oder Bildkomponente hier */}
|
||||
<Image
|
||||
src="/logo/logo-basiclean-white.svg"
|
||||
alt={companyData.companyName}
|
||||
width={160}
|
||||
height={48}
|
||||
unoptimized
|
||||
/>
|
||||
</Link>
|
||||
<p className={styles.footer__tagline}>
|
||||
Maßgeschneiderte digitale Lösungen für Ihr Unternehmen.
|
||||
</p>
|
||||
|
||||
<p className={styles.footer__tagline}>{companyData.slogan}</p>
|
||||
</div>
|
||||
|
||||
{/* Navigation Spalten */}
|
||||
<nav className={styles.footer__nav} aria-label="Footer Navigation">
|
||||
<div className={styles.footer__nav_group}>
|
||||
<span className={styles.footer__nav_title}>Unternehmen</span>
|
||||
<div className={styles["footer__nav-group"]}>
|
||||
<span className={styles["footer__nav-title"]}>Unternehmen</span>
|
||||
<ul>
|
||||
<li>
|
||||
<Link href="/ueberuns">Über uns</Link>
|
||||
@@ -36,14 +40,17 @@ export default function Footer() {
|
||||
<li>
|
||||
<Link href="/leistungen">Leistungen</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/branchenloesungen">Branchenlösungen</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/kontakt">Kontakt</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className={styles.footer__nav_group}>
|
||||
<span className={styles.footer__nav_title}>Rechtliches</span>
|
||||
<div className={styles["footer__nav-group"]}>
|
||||
<span className={styles["footer__nav-title"]}>Rechtliches</span>
|
||||
<ul>
|
||||
<li>
|
||||
<Link href="/impressum">Impressum</Link>
|
||||
@@ -56,13 +63,12 @@ export default function Footer() {
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
{/* Divider */}
|
||||
<div className={styles.footer__divider} />
|
||||
|
||||
{/* Bottom: Copyright + Social */}
|
||||
<div className={styles.footer__bottom}>
|
||||
<p className={styles.footer__copy}>
|
||||
© {currentYear} ENVU. Alle Rechte vorbehalten.
|
||||
Copyright © {currentYear} {companyData.companyName}. Alle Rechte
|
||||
vorbehalten.
|
||||
</p>
|
||||
|
||||
<div className={styles.footer__social}>
|
||||
@@ -74,6 +80,7 @@ export default function Footer() {
|
||||
>
|
||||
<InstagramLogoIcon size={20} />
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://linkedin.com"
|
||||
target="_blank"
|
||||
@@ -82,6 +89,7 @@ export default function Footer() {
|
||||
>
|
||||
<LinkedinLogoIcon size={20} />
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://x.com"
|
||||
target="_blank"
|
||||
@@ -90,6 +98,7 @@ export default function Footer() {
|
||||
>
|
||||
<XLogoIcon size={20} />
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://facebook.com"
|
||||
target="_blank"
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
.hero {
|
||||
position: relative;
|
||||
background: var(--color-background-linear);
|
||||
padding-block: var(--space-16);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.inner {
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
max-width: var(--container-width);
|
||||
margin-inline: auto;
|
||||
padding-inline: var(--space-4);
|
||||
}
|
||||
|
||||
.heroDecoration {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-5);
|
||||
}
|
||||
|
||||
.heading {
|
||||
max-width: 15ch;
|
||||
}
|
||||
|
||||
.lead {
|
||||
max-width: 40ch;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: var(--space-4);
|
||||
margin-top: var(--space-2);
|
||||
}
|
||||
|
||||
.actions :global(.btn) {
|
||||
width: fit-content;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
|
||||
.actions :global(.btn--tertiary) {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
color: var(--font-body-color);
|
||||
}
|
||||
|
||||
/* Tablet */
|
||||
@media (min-width: 768px) {
|
||||
.hero {
|
||||
padding-block: var(--space-28);
|
||||
}
|
||||
|
||||
.heroDecoration {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: auto;
|
||||
right: 0;
|
||||
transform: translateY(-50%);
|
||||
width: min(42vw, 420px);
|
||||
height: auto;
|
||||
opacity: 0.06;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.actions {
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: var(--space-6);
|
||||
}
|
||||
.heading {
|
||||
max-width: 24ch;
|
||||
}
|
||||
|
||||
.lead {
|
||||
max-width: 48ch;
|
||||
}
|
||||
}
|
||||
|
||||
/* Desktop */
|
||||
@media (min-width: 1024px) {
|
||||
.hero {
|
||||
padding-block: var(--space-36);
|
||||
}
|
||||
.inner {
|
||||
padding-inline: var(--space-6);
|
||||
}
|
||||
|
||||
.heroDecoration {
|
||||
width: min(44vw, 560px);
|
||||
opacity: 0.08;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { ArrowRightIcon, PhoneIcon } from "@phosphor-icons/react/dist/ssr";
|
||||
import Link from "next/link";
|
||||
import styles from "./HeroSection.module.css";
|
||||
import { companyData } from "@/data/companyData";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function HeroSection() {
|
||||
return (
|
||||
<section className={styles.hero} aria-labelledby="hero-heading">
|
||||
<div className={styles.inner}>
|
||||
<Image
|
||||
src="/logo/logo-mininmal-basiclean-grey.svg"
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
className={styles.heroDecoration}
|
||||
width={620}
|
||||
height={620}
|
||||
unoptimized
|
||||
/>
|
||||
<div className={styles.content}>
|
||||
<h1 id="hero-heading" className={styles.heading}>
|
||||
Gebäudereinigung für ein makelloses Arbeitsumfeld
|
||||
</h1>
|
||||
<p className={`lead ${styles.lead}`}>
|
||||
Mit festen Abläufen und hohen Qualitätsstandards – für ein sauberes,
|
||||
professionelles Arbeitsumfeld.
|
||||
</p>
|
||||
<div className={styles.actions}>
|
||||
<Link href="/kontakt" className="btn btn--filled">
|
||||
<span className="btn-icon animate" aria-hidden="true">
|
||||
<ArrowRightIcon size={18} weight="bold" />
|
||||
</span>
|
||||
Jetzt Angebot anfragen
|
||||
</Link>
|
||||
<Link href="/Leistungen" className="btn btn--outline">
|
||||
Leistungen ansehen
|
||||
</Link>
|
||||
</div>
|
||||
<div className={styles.actions}>
|
||||
<a
|
||||
href={`tel:${companyData.contact.phone.value}`}
|
||||
className="btn btn--tertiary"
|
||||
>
|
||||
<span className="btn-icon" aria-hidden="true">
|
||||
<PhoneIcon size={18} weight="bold" />
|
||||
</span>
|
||||
{companyData.contact.phone.display}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
.section {
|
||||
padding-block: var(--space-16);
|
||||
}
|
||||
|
||||
.inner {
|
||||
max-width: var(--container-width);
|
||||
margin-inline: auto;
|
||||
padding-inline: var(--space-4);
|
||||
}
|
||||
|
||||
.intro {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: var(--space-4);
|
||||
margin-bottom: var(--space-8);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.heading {
|
||||
max-width: 18ch;
|
||||
}
|
||||
|
||||
.lead {
|
||||
max-width: 58ch;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: var(--space-4);
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-4);
|
||||
background-color: #e2ebe5;
|
||||
color: var(--color-accent);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: var(--space-6) var(--space-6);
|
||||
text-decoration: none;
|
||||
min-height: 88px;
|
||||
transition:
|
||||
background-color 0.25s ease,
|
||||
color 0.25s ease,
|
||||
box-shadow 0.25s ease;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.card:hover,
|
||||
.card:focus-visible {
|
||||
background-color: var(--color-accent);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.cardText {
|
||||
font-size: var(--font-size-body);
|
||||
line-height: 1.2;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
max-width: 18ch;
|
||||
}
|
||||
|
||||
.iconWrap {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50px;
|
||||
background-color: var(--color-accent);
|
||||
color: #ffffff;
|
||||
transition:
|
||||
background-color 0.25s ease,
|
||||
color 0.25s ease;
|
||||
}
|
||||
|
||||
.card:hover .iconWrap,
|
||||
.card:focus-visible .iconWrap {
|
||||
background-color: #ffffff;
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.section {
|
||||
padding-block: var(--space-24);
|
||||
}
|
||||
|
||||
.intro {
|
||||
margin-bottom: var(--space-10);
|
||||
}
|
||||
|
||||
.heading {
|
||||
max-width: 18ch;
|
||||
}
|
||||
|
||||
.grid {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.card {
|
||||
min-height: 96px;
|
||||
}
|
||||
|
||||
.card:nth-child(4),
|
||||
.card:nth-child(5) {
|
||||
grid-column: span 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.section {
|
||||
padding-block: var(--space-24);
|
||||
}
|
||||
|
||||
.inner {
|
||||
padding-inline: var(--space-6);
|
||||
}
|
||||
|
||||
.grid {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
max-width: 860px;
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: var(--space-12) var(--space-6);
|
||||
}
|
||||
|
||||
.card:nth-child(4) {
|
||||
grid-column: 1 / 2;
|
||||
justify-self: end;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.card:nth-child(5) {
|
||||
grid-column: 2 / 3;
|
||||
justify-self: start;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: none) {
|
||||
.card:hover,
|
||||
.card:focus-visible {
|
||||
background-color: #e2ebe5;
|
||||
color: var(--color-accent);
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.card:hover .iconWrap,
|
||||
.card:focus-visible .iconWrap {
|
||||
background-color: var(--color-accent);
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
import Link from "next/link";
|
||||
import styles from "./IndustrySolutionsSection.module.css";
|
||||
import {
|
||||
BuildingsIcon,
|
||||
StethoscopeIcon,
|
||||
WarehouseIcon,
|
||||
HouseLineIcon,
|
||||
ArrowRightIcon,
|
||||
} from "@phosphor-icons/react/dist/ssr";
|
||||
|
||||
const industries = [
|
||||
{
|
||||
title: "Büros",
|
||||
href: "/branchen/bueros",
|
||||
icon: BuildingsIcon,
|
||||
},
|
||||
{
|
||||
title: "Arztpraxen",
|
||||
href: "/branchen/arztpraxen",
|
||||
icon: StethoscopeIcon,
|
||||
},
|
||||
{
|
||||
title: "Hallen und Lagerflächen",
|
||||
href: "/branchen/hallen-lagerflaechen",
|
||||
icon: WarehouseIcon,
|
||||
},
|
||||
{
|
||||
title: "Wohn- und Geschäftshäuser",
|
||||
href: "/branchen/wohn-geschaeftshaeuser",
|
||||
icon: HouseLineIcon,
|
||||
},
|
||||
{
|
||||
title: "Zum Kontaktformular",
|
||||
href: "/kontakt",
|
||||
icon: ArrowRightIcon,
|
||||
},
|
||||
];
|
||||
|
||||
export default function IndustrySolutionsSection() {
|
||||
return (
|
||||
<section
|
||||
className={styles.section}
|
||||
aria-labelledby="industry-solutions-heading"
|
||||
>
|
||||
<div className={styles.inner}>
|
||||
<div className={styles.intro}>
|
||||
<h2 id="industry-solutions-heading" className={styles.heading}>
|
||||
Reinigungsleistungen für verschiedene Branchen
|
||||
</h2>
|
||||
<p className={styles.lead}>
|
||||
Als Reinigungsfirma betreuen wir Unternehmen aus unterschiedlichen
|
||||
Branchen. Unsere Leistungen passen wir individuell an Nutzung,
|
||||
Objektgröße und branchenspezifische Anforderungen an.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className={styles.grid}>
|
||||
{industries.map((industry) => {
|
||||
const Icon = industry.icon;
|
||||
|
||||
return (
|
||||
<Link
|
||||
key={industry.title}
|
||||
href={industry.href}
|
||||
className={styles.card}
|
||||
>
|
||||
<span className={styles.cardText}>{industry.title}</span>
|
||||
|
||||
<span className={styles.iconWrap} aria-hidden="true">
|
||||
<Icon size={18} weight="bold" className={styles.icon} />
|
||||
</span>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -5,8 +5,9 @@
|
||||
--nav-padding-lr: var(--space-4);
|
||||
--nav-font-size: 1rem;
|
||||
--nav-font-weight: 600;
|
||||
--nav-font-color: #5f5f5f;
|
||||
--nav-font-color: #141316;
|
||||
--nav-hamburger-icon: var(--nav-font-color);
|
||||
--nav-outline-color: #0060df;
|
||||
}
|
||||
.noTransition {
|
||||
transition: none !important;
|
||||
@@ -25,46 +26,62 @@
|
||||
font-weight: var(--nav-font-weight);
|
||||
background-color: var(--nav-bg);
|
||||
color: var(--nav-font-color);
|
||||
letter-spacing: 0.1px;
|
||||
}
|
||||
|
||||
.nav a:focus-visible,
|
||||
.nav button:focus-visible {
|
||||
outline: 2px solid var(--nav-outline-color);
|
||||
outline-offset: -8px;
|
||||
}
|
||||
.nav-logo {
|
||||
width: auto;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.nav-logo a:focus-visible {
|
||||
outline: 2px solid var(--nav-outline-color);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.nav-logo-image {
|
||||
width: auto;
|
||||
height: 30px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.nav-links button:focus-visible {
|
||||
outline: 2px solid #000000;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
background-color: inherit;
|
||||
position: fixed;
|
||||
inset: var(--nav-h) 0 0 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
transition: max-height 400ms ease;
|
||||
/* Scrollbar ausblenden (Firefox/IE/Edge legacy) */
|
||||
overflow-y: auto;
|
||||
transform: translateY(-12px);
|
||||
transition:
|
||||
opacity 220ms ease,
|
||||
transform 220ms ease,
|
||||
visibility 0s linear 220ms;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
/* Chrome/Safari/Opera */
|
||||
.nav-links::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-links.open {
|
||||
max-height: 100vh;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
pointer-events: auto;
|
||||
overflow-y: auto;
|
||||
transform: translateY(0);
|
||||
transition:
|
||||
opacity 220ms ease,
|
||||
transform 220ms ease,
|
||||
visibility 0s linear 0s;
|
||||
}
|
||||
|
||||
.nav-links li {
|
||||
@@ -90,10 +107,6 @@
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.nav-links li a:focus-visible {
|
||||
outline: 2px solid #393636;
|
||||
}
|
||||
|
||||
.nav-hamburger {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
@@ -109,16 +122,6 @@
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
.nav-hamburger:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.nav-hamburger:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px #000000;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.nav-hamburger span {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
@@ -174,8 +177,7 @@
|
||||
}
|
||||
|
||||
.nav {
|
||||
padding: var(--nav-padding-tb) var(--nav-padding-lr) var(--nav-padding-tb)
|
||||
var(--nav-padding-lr);
|
||||
padding: var(--nav-padding-tb) var(--nav-padding-lr);
|
||||
}
|
||||
|
||||
.nav-logo-image {
|
||||
@@ -186,19 +188,27 @@
|
||||
.nav-links {
|
||||
position: static;
|
||||
inset: auto;
|
||||
overflow: visible;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 0;
|
||||
|
||||
overflow: visible;
|
||||
max-height: none;
|
||||
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
pointer-events: auto;
|
||||
|
||||
transform: none;
|
||||
clip-path: none;
|
||||
|
||||
background-color: transparent;
|
||||
transition: none;
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
.nav-links > li a {
|
||||
padding: 20px 16px;
|
||||
padding: 24px 12px;
|
||||
}
|
||||
|
||||
.nav-links > li:first-child {
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useNavToggleMenu } from "@/hooks/useNavToggleMenu";
|
||||
import { useSupportsHover } from "@/hooks/useSupportsHover";
|
||||
import { useToggleBodyOverflow } from "@/hooks/useToggleBodyOverflow";
|
||||
import styles from "./Navbar.module.css";
|
||||
import { useIsDesktop } from "@/hooks/useIsDesktop";
|
||||
import { NavbarSubMenu } from "./NavbarSubMenu";
|
||||
|
||||
type BasicLink = {
|
||||
@@ -21,10 +22,13 @@ export default function Navbar() {
|
||||
const pathname = usePathname();
|
||||
const navRef = useRef<HTMLElement | null>(null);
|
||||
const supportsHover = useSupportsHover();
|
||||
const isDesktop = useIsDesktop(1024);
|
||||
|
||||
const [instantSwitch, setInstantSwitch] = useState(false);
|
||||
const raf1Ref = useRef<number | null>(null);
|
||||
const raf2Ref = useRef<number | null>(null);
|
||||
const hamburgerRef = useRef<HTMLButtonElement | null>(null);
|
||||
const navLinksRef = useRef<HTMLUListElement | null>(null);
|
||||
|
||||
const {
|
||||
menuOpen,
|
||||
@@ -92,12 +96,72 @@ export default function Navbar() {
|
||||
</li>
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (isDesktop || !menuOpen) return;
|
||||
|
||||
const navEl = navRef.current;
|
||||
if (!navEl) return;
|
||||
|
||||
const getFocusableElements = () =>
|
||||
Array.from(
|
||||
navEl.querySelectorAll<HTMLElement>(
|
||||
'a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])',
|
||||
),
|
||||
).filter((el) => {
|
||||
if (el.hasAttribute("inert")) return false;
|
||||
if (el.closest("[inert]")) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
const firstMenuFocusable = navLinksRef.current?.querySelector<HTMLElement>(
|
||||
'a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])',
|
||||
);
|
||||
|
||||
firstMenuFocusable?.focus();
|
||||
|
||||
const onKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") {
|
||||
e.preventDefault();
|
||||
toggleMenu();
|
||||
requestAnimationFrame(() => {
|
||||
hamburgerRef.current?.focus();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.key !== "Tab") return;
|
||||
|
||||
const currentFocusable = getFocusableElements();
|
||||
const currentFirst = currentFocusable[0];
|
||||
const currentLast = currentFocusable[currentFocusable.length - 1];
|
||||
|
||||
if (!currentFirst || !currentLast) return;
|
||||
|
||||
if (e.shiftKey) {
|
||||
if (document.activeElement === currentFirst) {
|
||||
e.preventDefault();
|
||||
currentLast.focus();
|
||||
}
|
||||
} else {
|
||||
if (document.activeElement === currentLast) {
|
||||
e.preventDefault();
|
||||
currentFirst.focus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("keydown", onKeyDown);
|
||||
return () => {
|
||||
document.removeEventListener("keydown", onKeyDown);
|
||||
};
|
||||
}, [isDesktop, menuOpen, toggleMenu]);
|
||||
|
||||
return (
|
||||
<nav className={styles["nav"]} ref={navRef} aria-label="Hauptnavigation">
|
||||
<div className={styles["nav-logo"]}>
|
||||
<Link href="/" aria-label="Startseite">
|
||||
<Image
|
||||
src="/logo/logo.svg"
|
||||
src="/logo/logo-basiclean.svg"
|
||||
alt="Logo"
|
||||
width={160}
|
||||
height={48}
|
||||
@@ -106,9 +170,23 @@ export default function Navbar() {
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<button
|
||||
ref={hamburgerRef}
|
||||
type="button"
|
||||
className={`${styles["nav-hamburger"]} ${menuOpen ? styles.open : ""}`}
|
||||
onClick={toggleMenu}
|
||||
aria-label={menuOpen ? "Menü schließen" : "Menü öffnen"}
|
||||
aria-expanded={menuOpen}
|
||||
aria-controls="main-navigation"
|
||||
>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</button>
|
||||
<ul
|
||||
ref={navLinksRef}
|
||||
id="main-navigation"
|
||||
inert={!isDesktop && !menuOpen}
|
||||
className={[
|
||||
styles["nav-links"],
|
||||
menuOpen ? styles.open : "",
|
||||
@@ -133,19 +211,6 @@ export default function Navbar() {
|
||||
|
||||
{endLinks.map(renderNavLink)}
|
||||
</ul>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className={`${styles["nav-hamburger"]} ${menuOpen ? styles.open : ""}`}
|
||||
onClick={toggleMenu}
|
||||
aria-label={menuOpen ? "Menü schließen" : "Menü öffnen"}
|
||||
aria-expanded={menuOpen}
|
||||
aria-controls="main-navigation"
|
||||
>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</button>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
--nav-submenu-max-width: var(--container-width);
|
||||
--nav-submenu-bg: var(--color-surface);
|
||||
}
|
||||
|
||||
.nav-submenu {
|
||||
display: grid;
|
||||
list-style: none;
|
||||
@@ -9,14 +10,28 @@
|
||||
max-height: 0;
|
||||
opacity: 1;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
transition: max-height 250ms ease;
|
||||
transform: translateY(-4px);
|
||||
transition:
|
||||
max-height 250ms ease,
|
||||
opacity 180ms ease,
|
||||
transform 180ms ease,
|
||||
visibility 0s linear 300ms;
|
||||
background-color: var(--nav-bg);
|
||||
}
|
||||
|
||||
.nav-submenu.open {
|
||||
max-height: var(--submenu-h);
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
pointer-events: auto;
|
||||
transform: translateY(0);
|
||||
transition:
|
||||
max-height 250ms ease,
|
||||
opacity 180ms ease,
|
||||
transform 180ms ease,
|
||||
visibility 0s linear 0s;
|
||||
}
|
||||
|
||||
.nav-submenu-inner {
|
||||
@@ -29,6 +44,27 @@
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.nav-submenu-list li a {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-submenu-list li a:focus-visible {
|
||||
outline: none;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.nav-submenu-list li a:focus-visible::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
bottom: 8px;
|
||||
left: 8px;
|
||||
border: 2px solid var(--nav-outline-color);
|
||||
pointer-events: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.nav-sub-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -41,6 +77,8 @@
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
height: var(--nav-h);
|
||||
letter-spacing: 0.1px;
|
||||
}
|
||||
|
||||
.nav-item-with-sub {
|
||||
@@ -65,9 +103,31 @@
|
||||
pointer-events: none;
|
||||
box-shadow: 0 4px 6px -6px rgb(0 0 0 / 30%);
|
||||
opacity: 0;
|
||||
transform: translateY(-8px);
|
||||
transition:
|
||||
max-height 300ms,
|
||||
opacity 300ms;
|
||||
max-height 300ms ease,
|
||||
opacity 300ms ease,
|
||||
transform 300ms ease,
|
||||
visibility 0s linear 300ms;
|
||||
background-color: var(--nav-bg);
|
||||
}
|
||||
|
||||
.nav-submenu.open {
|
||||
transition:
|
||||
max-height 300ms ease,
|
||||
opacity 300ms ease,
|
||||
transform 300ms ease,
|
||||
visibility 0s linear 0s;
|
||||
}
|
||||
|
||||
.nav-submenu-list li a:focus-visible {
|
||||
outline: 2px solid var(--nav-outline-color);
|
||||
outline-offset: 2px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.nav-submenu-list li a:focus-visible::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-submenu.open {
|
||||
@@ -87,10 +147,10 @@
|
||||
margin: 0 auto;
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
grid-template-rows: repeat(5, auto);
|
||||
grid-template-rows: repeat(3, auto);
|
||||
grid-auto-columns: minmax(180px, max-content);
|
||||
column-gap: 48px;
|
||||
row-gap: 4px;
|
||||
row-gap: 16px;
|
||||
justify-content: start;
|
||||
align-items: start;
|
||||
padding: 24px 24px 48px 24px;
|
||||
@@ -99,6 +159,6 @@
|
||||
}
|
||||
.nav-sub-toggle {
|
||||
position: relative;
|
||||
padding: 16px 8px;
|
||||
padding: 16px 12px;
|
||||
}
|
||||
}
|
||||
@@ -71,6 +71,7 @@ export const NavbarSubMenu: FC<Props> = ({
|
||||
<ul
|
||||
ref={subMenuRef}
|
||||
id={`submenu-${id}`}
|
||||
inert={!open}
|
||||
className={[
|
||||
styles["nav-submenu"],
|
||||
open ? styles.open : "",
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
.services {
|
||||
padding-block: var(--space-16);
|
||||
}
|
||||
|
||||
.inner {
|
||||
max-width: var(--container-width);
|
||||
margin-inline: auto;
|
||||
padding-inline: var(--space-4);
|
||||
}
|
||||
|
||||
.intro {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-4);
|
||||
margin-bottom: var(--space-8);
|
||||
}
|
||||
|
||||
.heading,
|
||||
.lead {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
justify-content: center;
|
||||
gap: var(--space-8);
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100%;
|
||||
background: var(--color-surface);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.imageWrap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 7;
|
||||
background: var(--color-surface-alt);
|
||||
overflow: hidden;
|
||||
border-bottom: 4px solid var(--color-accent);
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.cardBody {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-5);
|
||||
padding: var(--space-5);
|
||||
}
|
||||
|
||||
.cardContent {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.cardTitle {
|
||||
font-size: var(--font-size-s);
|
||||
background-color: var(--color-accent);
|
||||
width: fit-content;
|
||||
padding: 8px;
|
||||
color: #ffffff;
|
||||
letter-spacing: var(--letter-spacing-normal);
|
||||
border-radius: 4px;
|
||||
font-weight: var(--font-weight-regular);
|
||||
}
|
||||
|
||||
.cardText {
|
||||
max-width: 34ch;
|
||||
color: var(--color-text-muted);
|
||||
font-size: var(--font-size-xs);
|
||||
}
|
||||
|
||||
.cardBody :global(.btn) {
|
||||
width: fit-content;
|
||||
padding: 0;
|
||||
color: var(--font-body-color);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
|
||||
/* Tablet */
|
||||
@media (min-width: 768px) {
|
||||
.services {
|
||||
padding-block: var(--space-24);
|
||||
}
|
||||
|
||||
.intro {
|
||||
margin-bottom: var(--space-10);
|
||||
}
|
||||
.heading {
|
||||
max-width: 22ch;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.lead {
|
||||
max-width: 62ch;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* .card {
|
||||
max-width: 100%;
|
||||
} */
|
||||
|
||||
.grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
/* Desktop */
|
||||
@media (min-width: 1024px) {
|
||||
.services {
|
||||
padding-block: var(--space-24);
|
||||
}
|
||||
|
||||
.inner {
|
||||
padding-inline: var(--space-6);
|
||||
}
|
||||
|
||||
.grid {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
align-items: stretch;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
import { ArrowRightIcon } from "@phosphor-icons/react/dist/ssr";
|
||||
import Link from "next/link";
|
||||
import styles from "./ServiceSection.module.css";
|
||||
import Image from "next/image";
|
||||
|
||||
const services = [
|
||||
{
|
||||
title: "Grundreinigung",
|
||||
description:
|
||||
"Regelmäßige Reinigung von Arbeitsplätzen, Besprechungsräumen und Gemeinschaftsbereichen für einen gepflegten Eindruck im Alltag.",
|
||||
image: "/images/services/grundreinigung.jpg",
|
||||
imageAlt: "Sauberer Büroarbeitsplatz nach der Reinigung",
|
||||
href: "/leistungen/bueroreinigung",
|
||||
},
|
||||
{
|
||||
title: "Glas- und Fensterreinigung",
|
||||
description:
|
||||
"Streifenfreie Reinigung von Fenstern, Glaselementen und Eingangsbereichen für einen professionellen ersten Eindruck.",
|
||||
image: "/images/services/Fensterreinigung.jpg",
|
||||
imageAlt: "Große gereinigte Fensterfront eines Geschäftsgebäudes",
|
||||
href: "/leistungen/glasreinigung",
|
||||
},
|
||||
{
|
||||
title: "Treppenhausreinigung",
|
||||
description:
|
||||
"Saubere Eingangs- und Treppenbereiche als Visitenkarte für Mitarbeitende, Kundschaft und Besucher.",
|
||||
image: "/images/services/treppenhausreinigung.jpg",
|
||||
imageAlt: "Sauberes Treppenhaus in einem Gewerbeobjekt",
|
||||
href: "/leistungen/treppenhausreinigung",
|
||||
},
|
||||
{
|
||||
title: "Unterhaltsreinigung",
|
||||
description:
|
||||
"Individuell abgestimmte Reinigungsintervalle für dauerhaft gepflegte Büro-, Praxis- und Gewerbeflächen.",
|
||||
image: "/images/services/unterhaltsreinigung.jpg",
|
||||
imageAlt: "Reinigungskraft bei der Unterhaltsreinigung in einem Büro",
|
||||
href: "/leistungen/unterhaltsreinigung",
|
||||
},
|
||||
{
|
||||
title: "Hausmeisterdienste",
|
||||
description:
|
||||
"Hausmeisterdienste für Kleinreparaturen bis zur Objektbetreuung – für reibungslose Abläufe.",
|
||||
image: "/images/services/Hausmeisterdienste.jpg",
|
||||
imageAlt: "Hausmeisterdienste für Gartenarbeit",
|
||||
href: "/leistungen/Hausmeisterdienste",
|
||||
},
|
||||
];
|
||||
|
||||
export default function ServiceSection() {
|
||||
return (
|
||||
<section className={styles.services} aria-labelledby="services-heading">
|
||||
<div className={styles.inner}>
|
||||
<div className={styles.intro}>
|
||||
<h2 id="services-heading" className={styles.heading}>
|
||||
Professionelle Reinigung für Büros, Praxen und Geschäftsräume
|
||||
</h2>
|
||||
<p className={`lead ${styles.lead}`}>
|
||||
Individuelle Reinigungskonzepte für Unternehmen – damit Ihre Räume sauber, zuverlässig und professions sorgenfrei bleiben.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className={styles.grid}>
|
||||
{services.map((service) => (
|
||||
<article key={service.title} className={styles.card}>
|
||||
<div className={styles.imageWrap}>
|
||||
<Image
|
||||
src={service.image}
|
||||
alt={service.imageAlt}
|
||||
fill
|
||||
sizes="(min-width: 1024px) 400px, (min-width: 768px) 50vw, 100vw"
|
||||
className={styles.image}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.cardBody}>
|
||||
<div className={styles.cardContent}>
|
||||
<h3 className={styles.cardTitle}>{service.title}</h3>
|
||||
<p className={styles.cardText}>{service.description}</p>
|
||||
</div>
|
||||
|
||||
<Link href={service.href} className="btn btn--tertiary">
|
||||
Mehr
|
||||
<span className="btn-icon animate" aria-hidden="true">
|
||||
<ArrowRightIcon size={16} weight="bold" />
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
.benefits {
|
||||
background: var(--color-background-linear);
|
||||
padding-block: var(--space-16);
|
||||
}
|
||||
|
||||
.inner {
|
||||
max-width: var(--container-width);
|
||||
margin-inline: auto;
|
||||
padding-inline: var(--space-4);
|
||||
}
|
||||
|
||||
/* Mobile: Intro oben, Grid unten */
|
||||
.intro {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-4);
|
||||
margin-bottom: var(--space-8);
|
||||
}
|
||||
|
||||
.heading,
|
||||
.lead {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
gap: var(--space-5);
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
gap: var(--space-4);
|
||||
background: var(--color-surface);
|
||||
border-radius: 12px;
|
||||
padding: var(--space-5);
|
||||
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.iconWrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.cardContent {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.cardTitle {
|
||||
font-size: var(--font-size-base);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--font-heading-color);
|
||||
}
|
||||
|
||||
.cardText {
|
||||
color: var(--color-text-muted);
|
||||
font-size: var(--font-size-xs);
|
||||
max-width: 34ch;
|
||||
}
|
||||
|
||||
/* Tablet */
|
||||
@media (min-width: 768px) {
|
||||
.benefits {
|
||||
padding-block: var(--space-24);
|
||||
}
|
||||
|
||||
.intro {
|
||||
margin-bottom: var(--space-10);
|
||||
}
|
||||
|
||||
.heading {
|
||||
max-width: 16ch;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.lead {
|
||||
max-width: 48ch;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
/* Desktop: Intro links, Grid rechts — nebeneinander */
|
||||
@media (min-width: 1024px) {
|
||||
.benefits {
|
||||
padding-block: var(--space-36);
|
||||
}
|
||||
|
||||
.inner {
|
||||
display: grid;
|
||||
grid-template-columns: 280px 1fr;
|
||||
gap: var(--space-16);
|
||||
align-items: start;
|
||||
padding-inline: var(--space-6);
|
||||
}
|
||||
|
||||
.intro {
|
||||
position: sticky;
|
||||
top: var(--space-8);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.heading {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.lead {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
import {
|
||||
UsersThreeIcon,
|
||||
GraduationCapIcon,
|
||||
ClockIcon,
|
||||
SealCheckIcon,
|
||||
LeafIcon,
|
||||
CurrencyCircleDollarIcon,
|
||||
} from "@phosphor-icons/react/dist/ssr";
|
||||
import styles from "./benefitsSection.module.css";
|
||||
|
||||
const benefits = [
|
||||
{
|
||||
icon: UsersThreeIcon,
|
||||
title: "Feste Ansprechpartner",
|
||||
description:
|
||||
"Keine wechselnden Zuständigkeiten – wir sind immer persönlich für Sie da.",
|
||||
},
|
||||
{
|
||||
icon: GraduationCapIcon,
|
||||
title: "Geschultes Personal",
|
||||
description:
|
||||
"Unsere Teams werden kontinuierlich in modernen Reinigungstechniken geschult.",
|
||||
},
|
||||
{
|
||||
icon: ClockIcon,
|
||||
title: "Flexible Zeiten",
|
||||
description:
|
||||
"Wir reinigen dann, wenn es Ihren Betriebsablauf am wenigsten stört.",
|
||||
},
|
||||
{
|
||||
icon: SealCheckIcon,
|
||||
title: "Höchste Qualität",
|
||||
description:
|
||||
"Strenges Qualitätsmanagement durch regelmäßige Objektkontrollen.",
|
||||
},
|
||||
{
|
||||
icon: LeafIcon,
|
||||
title: "Umweltfreundlich",
|
||||
description:
|
||||
"Einsatz von biologisch abbaubaren Reinigungsmitteln für die Umwelt.",
|
||||
},
|
||||
{
|
||||
icon: CurrencyCircleDollarIcon,
|
||||
title: "Transparente Kosten",
|
||||
description:
|
||||
"Klare Preisgestaltung ohne versteckte Nebenkosten für Ihre Planung.",
|
||||
},
|
||||
];
|
||||
|
||||
export default function BenefitsSection() {
|
||||
return (
|
||||
<section className={styles.benefits} aria-labelledby="benefits-heading">
|
||||
<div className={styles.inner}>
|
||||
<div className={styles.intro}>
|
||||
<h2 id="benefits-heading" className={styles.heading}>
|
||||
Ihre Vorteile mit uns
|
||||
</h2>
|
||||
<p className={`lead ${styles.lead}`}>
|
||||
Wir verstehen die Anforderungen moderner Unternehmen an einen
|
||||
Facility-Partner: Verlässlichkeit, Professionalität und Transparenz.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className={styles.grid}>
|
||||
{benefits.map((benefit) => {
|
||||
const Icon = benefit.icon;
|
||||
return (
|
||||
<article key={benefit.title} className={styles.card}>
|
||||
<span className={styles.iconWrap} aria-hidden="true">
|
||||
<Icon size={24} weight="duotone" />
|
||||
</span>
|
||||
<div className={styles.cardContent}>
|
||||
<h3 className={styles.cardTitle}>{benefit.title}</h3>
|
||||
<p className={styles.cardText}>{benefit.description}</p>
|
||||
</div>
|
||||
</article>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import type { ElementType } from "react";
|
||||
import {
|
||||
PhoneIcon,
|
||||
EnvelopeSimpleIcon,
|
||||
ClockIcon,
|
||||
} from "@phosphor-icons/react/dist/ssr";
|
||||
|
||||
export type CompanyContactKey = "phone" | "email" | "openingHours";
|
||||
|
||||
export type CompanyContactItem = {
|
||||
type: "company";
|
||||
contactKey: CompanyContactKey;
|
||||
icon: ElementType;
|
||||
};
|
||||
|
||||
export type StaticContactItem = {
|
||||
type: "static";
|
||||
icon: ElementType;
|
||||
label: string;
|
||||
href?: string;
|
||||
};
|
||||
|
||||
export type ContactInfo = CompanyContactItem | StaticContactItem;
|
||||
|
||||
export type ContactCtaData = {
|
||||
heading: string;
|
||||
lead: string;
|
||||
buttonLabel: string;
|
||||
buttonHref: string;
|
||||
contacts: ContactInfo[];
|
||||
};
|
||||
|
||||
export const contactCtaData: ContactCtaData = {
|
||||
heading: "Lassen Sie uns über Ihre Anforderungen sprechen",
|
||||
lead: "Wir erstellen ein individuelles Reinigungskonzept für Ihr Unternehmen in Hannover und Umgebung. Unverbindlich, transparent und exakt auf Ihre Anforderung abgestimmt.",
|
||||
buttonLabel: "Angebot anfragen",
|
||||
buttonHref: "/kontakt",
|
||||
contacts: [
|
||||
{
|
||||
type: "company",
|
||||
contactKey: "phone",
|
||||
icon: PhoneIcon,
|
||||
},
|
||||
{
|
||||
type: "company",
|
||||
contactKey: "email",
|
||||
icon: EnvelopeSimpleIcon,
|
||||
},
|
||||
{
|
||||
type: "company",
|
||||
contactKey: "openingHours",
|
||||
icon: ClockIcon,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,108 @@
|
||||
.section {
|
||||
background: #ffffff;
|
||||
padding-bottom: var(--space-16);
|
||||
}
|
||||
|
||||
.inner {
|
||||
max-width: var(--container-width);
|
||||
margin-inline: auto;
|
||||
padding-inline: var(--space-4);
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: var(--color-accent);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: var(--space-8) var(--space-6);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-6);
|
||||
}
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-6);
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.top :global(.btn) {
|
||||
font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
|
||||
.text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.heading {
|
||||
color: #ffffff;
|
||||
max-width: 24ch;
|
||||
}
|
||||
|
||||
.lead {
|
||||
color: rgba(255, 255, 255);
|
||||
font-size: var(--font-size-xs);
|
||||
max-width: 72ch;
|
||||
}
|
||||
|
||||
.divider {
|
||||
border: none;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.2);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.contactRow {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.contactItem {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
color: #ffffff;
|
||||
font-size: var(--font-size-xs);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.section {
|
||||
padding-bottom: var(--space-24);
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: var(--space-10) var(--space-10);
|
||||
}
|
||||
|
||||
.top {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-8);
|
||||
}
|
||||
|
||||
.contactRow {
|
||||
flex-direction: row;
|
||||
gap: var(--space-8);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.inner {
|
||||
padding-inline: var(--space-6);
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: var(--space-12) var(--space-12);
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: none) {
|
||||
.button:hover,
|
||||
.button:focus-visible {
|
||||
background: #ffffff;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
import Link from "next/link";
|
||||
import { ArrowRightIcon } from "@phosphor-icons/react/dist/ssr";
|
||||
import { companyData } from "@/data/companyData";
|
||||
import styles from "./ContactCtaSection.module.css";
|
||||
import { contactCtaData, type ContactInfo } from "./ContactCtaData";
|
||||
|
||||
function resolveCompanyContact(
|
||||
item: Extract<ContactInfo, { type: "company" }>,
|
||||
) {
|
||||
if (item.contactKey === "phone") {
|
||||
return {
|
||||
label: companyData.contact.phone.display,
|
||||
href: `tel:${companyData.contact.phone.value}`,
|
||||
};
|
||||
}
|
||||
|
||||
if (item.contactKey === "email") {
|
||||
const email = `${companyData.contact.email.user}@${companyData.contact.email.domain}`;
|
||||
|
||||
return {
|
||||
label: email,
|
||||
href: `mailto:${email}`,
|
||||
};
|
||||
}
|
||||
|
||||
if (item.contactKey === "openingHours") {
|
||||
return {
|
||||
label: companyData.contact.openingHours.display,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export default function ContactCtaSection() {
|
||||
const { heading, lead, buttonLabel, buttonHref, contacts } = contactCtaData;
|
||||
|
||||
return (
|
||||
<section className={styles.section} aria-labelledby="contact-cta-heading">
|
||||
<div className={styles.inner}>
|
||||
<div className={styles.card}>
|
||||
<div className={styles.top}>
|
||||
<div className={styles.text}>
|
||||
<h2 id="contact-cta-heading" className={styles.heading}>
|
||||
{heading}
|
||||
</h2>
|
||||
<p className={styles.lead}>{lead}</p>
|
||||
</div>
|
||||
|
||||
<Link href={buttonHref} className="btn btn--filled-inverse">
|
||||
<span className="btn-icon animate" aria-hidden="true">
|
||||
<ArrowRightIcon size={16} weight="bold" />
|
||||
</span>
|
||||
{buttonLabel}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<hr className={styles.divider} aria-hidden="true" />
|
||||
|
||||
<div className={styles.contactRow}>
|
||||
{contacts.map((item) => {
|
||||
const icon = (
|
||||
<item.icon size={20} weight="regular" aria-hidden="true" />
|
||||
);
|
||||
|
||||
if (item.type === "company") {
|
||||
const resolved = resolveCompanyContact(item);
|
||||
|
||||
if (!resolved) return null;
|
||||
|
||||
return (
|
||||
<a
|
||||
key={item.contactKey}
|
||||
href={resolved.href}
|
||||
className={styles.contactItem}
|
||||
aria-label={resolved.label}
|
||||
>
|
||||
{icon}
|
||||
{resolved.label}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
if (item.href) {
|
||||
return (
|
||||
<a
|
||||
key={item.label}
|
||||
href={item.href}
|
||||
className={styles.contactItem}
|
||||
aria-label={item.label}
|
||||
>
|
||||
{icon}
|
||||
{item.label}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span key={item.label} className={styles.contactItem}>
|
||||
{icon}
|
||||
{item.label}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
.section {
|
||||
background: var(--color-background-linear);
|
||||
padding-block: var(--space-16);
|
||||
}
|
||||
|
||||
.inner {
|
||||
max-width: var(--container-width);
|
||||
margin-inline: auto;
|
||||
padding-inline: var(--space-4);
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: var(--space-8);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.heading {
|
||||
max-width: 11ch;
|
||||
text-align: left;
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.accordion {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.itemHeading {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.trigger {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-4);
|
||||
width: 100%;
|
||||
min-height: 52px;
|
||||
padding: var(--space-3) var(--space-5);
|
||||
background: var(--color-accent);
|
||||
color: #ffffff;
|
||||
border: 0;
|
||||
border-radius: 9999px;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.trigger:hover,
|
||||
.trigger:focus-visible {
|
||||
background: #1f6152;
|
||||
}
|
||||
|
||||
.triggerText {
|
||||
font-size: var(--font-size-s);
|
||||
font-weight: var(--font-weight-medium);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.iconWrap {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
transition: transform 0.25s ease;
|
||||
}
|
||||
|
||||
.trigger[aria-expanded="true"] .iconWrap {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.panel {
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.4s ease;
|
||||
}
|
||||
|
||||
.panelInner {
|
||||
padding: var(--space-4) var(--space-5) var(--space-2);
|
||||
}
|
||||
|
||||
.answer {
|
||||
max-width: 52ch;
|
||||
color: var(--color-text-muted);
|
||||
font-size: var(----font-size-xs);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.section {
|
||||
padding-block: var(--space-24);
|
||||
}
|
||||
|
||||
.inner {
|
||||
grid-template-columns: 280px 1fr;
|
||||
gap: var(--space-16);
|
||||
}
|
||||
|
||||
.trigger {
|
||||
min-height: 56px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.section {
|
||||
padding-block: var(--space-36);
|
||||
}
|
||||
|
||||
.inner {
|
||||
padding-inline: var(--space-6);
|
||||
}
|
||||
|
||||
.accordion {
|
||||
max-width: 560px;
|
||||
justify-self: end;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: none) {
|
||||
.trigger:hover,
|
||||
.trigger:focus-visible {
|
||||
background: var(--color-accent);
|
||||
box-shadow: 0 4px 14px rgba(38, 115, 97, 0.14);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
"use client";
|
||||
|
||||
import { useId, useRef, useState } from "react";
|
||||
import { CaretDownIcon } from "@phosphor-icons/react/dist/ssr";
|
||||
import styles from "./FaqSection.module.css";
|
||||
|
||||
export type FaqItem = {
|
||||
question: string;
|
||||
answer: string;
|
||||
};
|
||||
|
||||
type FaqSectionProps = {
|
||||
title: string;
|
||||
items: FaqItem[];
|
||||
};
|
||||
|
||||
type AccordionItemProps = {
|
||||
item: FaqItem;
|
||||
isOpen: boolean;
|
||||
buttonId: string;
|
||||
panelId: string;
|
||||
onToggle: () => void;
|
||||
};
|
||||
|
||||
function AccordionItem({
|
||||
item,
|
||||
isOpen,
|
||||
buttonId,
|
||||
panelId,
|
||||
onToggle,
|
||||
}: AccordionItemProps) {
|
||||
const panelRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const handleToggle = () => {
|
||||
const panel = panelRef.current;
|
||||
if (!panel) return;
|
||||
|
||||
if (panel.style.maxHeight) {
|
||||
panel.style.maxHeight = "";
|
||||
} else {
|
||||
panel.style.maxHeight = panel.scrollHeight + "px";
|
||||
}
|
||||
|
||||
onToggle();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.item}>
|
||||
<h3 className={styles.itemHeading}>
|
||||
<button
|
||||
id={buttonId}
|
||||
type="button"
|
||||
className={styles.trigger}
|
||||
aria-expanded={isOpen}
|
||||
aria-controls={panelId}
|
||||
onClick={handleToggle}
|
||||
>
|
||||
<span className={styles.triggerText}>{item.question}</span>
|
||||
|
||||
<span className={styles.iconWrap} aria-hidden="true">
|
||||
<CaretDownIcon size={14} weight="bold" />
|
||||
</span>
|
||||
</button>
|
||||
</h3>
|
||||
|
||||
<div
|
||||
id={panelId}
|
||||
ref={panelRef}
|
||||
role="region"
|
||||
aria-labelledby={buttonId}
|
||||
className={styles.panel}
|
||||
>
|
||||
<div className={styles.panelInner}>
|
||||
<p className={styles.answer}>{item.answer}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function FaqSection({ title, items }: FaqSectionProps) {
|
||||
const baseId = useId();
|
||||
const [openIndex, setOpenIndex] = useState<number | null>(null);
|
||||
|
||||
return (
|
||||
<section className={styles.section} aria-labelledby="faq-heading">
|
||||
<div className={styles.inner}>
|
||||
<div className={styles.content}>
|
||||
<h2 id="faq-heading" className={styles.heading}>
|
||||
{title}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div className={styles.accordion}>
|
||||
{items.map((item, index) => {
|
||||
const isOpen = openIndex === index;
|
||||
|
||||
return (
|
||||
<AccordionItem
|
||||
key={item.question}
|
||||
item={item}
|
||||
isOpen={isOpen}
|
||||
buttonId={`${baseId}-btn-${index}`}
|
||||
panelId={`${baseId}-panel-${index}`}
|
||||
onToggle={() => setOpenIndex(isOpen ? null : index)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
export const homepageFaq = [
|
||||
{
|
||||
question: "Kostenlose Beratung und Angebotserstellung",
|
||||
answer:
|
||||
"Wir besprechen Ihr Objekt, den Reinigungsbedarf und die gewünschten Intervalle. Anschließend erhalten Sie ein transparentes Angebot.",
|
||||
},
|
||||
{
|
||||
question: "Individuelle Reinigungslösungen",
|
||||
answer:
|
||||
"Unsere Leistungen passen wir an Ihre Branche, Objektgröße und Anforderungen an. So entsteht ein Reinigungsplan, der wirklich zu Ihrem Alltag passt.",
|
||||
},
|
||||
{
|
||||
question: "Zeitverfügbare Umsetzung",
|
||||
answer:
|
||||
"Wir planen flexibel und reinigen dann, wenn es Ihren Betrieb am wenigsten stört. Auf Wunsch auch früh morgens, abends oder am Wochenende.",
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,18 @@
|
||||
export const companyData = {
|
||||
name: "Basiclean",
|
||||
companyName: "Basiclean",
|
||||
slogan: "Wo Sauberkeit Standard ist.",
|
||||
contact: {
|
||||
email: {
|
||||
user: "info",
|
||||
domain: "basiclean.de",
|
||||
},
|
||||
phone: {
|
||||
display: "0172 621 0606",
|
||||
value: "+491726210606",
|
||||
},
|
||||
openingHours: {
|
||||
display: "Mo. - Fr. 08:00 - 17:00 Uhr",
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
@@ -0,0 +1,17 @@
|
||||
import { companyData } from "./companyData";
|
||||
|
||||
export function getCompanyEmail() {
|
||||
return `${companyData.contact.email.user}@${companyData.contact.email.domain}`;
|
||||
}
|
||||
|
||||
export function getCompanyEmailHref() {
|
||||
return `mailto:${getCompanyEmail()}`;
|
||||
}
|
||||
|
||||
export function getCompanyPhoneDisplay() {
|
||||
return companyData.contact.phone.display;
|
||||
}
|
||||
|
||||
export function getCompanyPhoneHref() {
|
||||
return `tel:${companyData.contact.phone.value}`;
|
||||
}
|
||||
@@ -13,40 +13,50 @@ export const singleLinks: NavItem[] = [{ label: "Home", to: "/" }];
|
||||
|
||||
export const subMenus: SubMenu[] = [
|
||||
{
|
||||
id: "services",
|
||||
label: "Dienstleistungen",
|
||||
id: "leistungen",
|
||||
label: "Leistungen",
|
||||
items: [
|
||||
{ label: "Überblick", to: "/dienstleistungen" },
|
||||
{ label: "Zweiter Link", to: "/dienstleistungen/zweiter-link" },
|
||||
{ label: "Dritter Link", to: "/dienstleistungen/Dritter Link" },
|
||||
{ label: "Produkt 5", to: "/produkte/produkt-5" },
|
||||
{ label: "Produkt 6", to: "/produkte/produkt-6" },
|
||||
{ label: "Produkt 7", to: "/produkte/produkt-7" }
|
||||
{
|
||||
label: "Unterhaltsreinigung",
|
||||
to: "/dienstleistungen/unterhaltsreinigung",
|
||||
},
|
||||
{
|
||||
label: "Treppenhausreinigung",
|
||||
to: "/dienstleistungen/treppenhausreinigung",
|
||||
},
|
||||
{
|
||||
label: "Fensterreinigung",
|
||||
to: "/dienstleistungen/fensterreinigung",
|
||||
},
|
||||
{
|
||||
label: "Grundreinigung",
|
||||
to: "/dienstleistungen/grundreinigung",
|
||||
},
|
||||
{
|
||||
label: "Hausmeisterdienste",
|
||||
to: "/dienstleistungen/hausmeisterdienste",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "products",
|
||||
label: "Produkte",
|
||||
id: "branchenloesungen",
|
||||
label: "Branchenlösungen",
|
||||
items: [
|
||||
{ label: "Produkt 1", to: "/produkte" },
|
||||
{ label: "Produkt 2", to: "/produkte/produkt-2" },
|
||||
{ label: "Produkt 3", to: "/produkte/produkt-3" },
|
||||
{ label: "Produkt 4", to: "/produkte/produkt-4" },
|
||||
{ label: "Produkt 5", to: "/produkte/produkt-5" },
|
||||
{ label: "Produkt 6", to: "/produkte/produkt-6" },
|
||||
{ label: "Produkt 7", to: "/produkte/produkt-7" },
|
||||
{ label: "Produkt 8", to: "/produkte/produkt-8" },
|
||||
{ label: "Produkt 9", to: "/produkte/produkt-9" },
|
||||
{ label: "Produkt 10", to: "/produkte/produkt-10" },
|
||||
{ label: "Produkt 11", to: "/produkte/produkt-11" },
|
||||
{ label: "Produkt 12", to: "/produkte/produkt-12" },
|
||||
{ label: "Produkt 13", to: "/produkte/produkt-13" },
|
||||
{ label: "Büros", to: "/branchenloesungen/bueros" },
|
||||
{
|
||||
label: "Hallen und Lagerflächen",
|
||||
to: "/branchenloesungen/hallen-und-lagerflaechen",
|
||||
},
|
||||
{
|
||||
label: "Wohn- und Geschäftshäuser",
|
||||
to: "/branchenloesungen/wohn--und-geschaeftshaeuser",
|
||||
},
|
||||
{ label: "Kanzlei", to: "/branchenloesungen/kanzlei" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export const endLinks: NavItem[] = [
|
||||
{ label: "Branche", to: "/branche" },
|
||||
{ label: "Unternehmen", to: "/unternehmen" },
|
||||
{ label: "Kontakt", to: "/kontakt" },
|
||||
{ label: "Blog", to: "/blog" },
|
||||
];
|
||||
@@ -11,14 +11,11 @@ export function useIsDesktop(breakpoint = 1024) {
|
||||
const update = () => setIsDesktop(mql.matches);
|
||||
|
||||
update();
|
||||
|
||||
if (mql.addEventListener) {
|
||||
mql.addEventListener("change", update);
|
||||
return () => mql.removeEventListener("change", update);
|
||||
}
|
||||
|
||||
mql.addListener(update);
|
||||
return () => mql.removeListener(update);
|
||||
return () => {
|
||||
mql.removeEventListener("change", update);
|
||||
};
|
||||
}, [breakpoint]);
|
||||
|
||||
return isDesktop;
|
||||
|
||||
@@ -11,15 +11,19 @@ export function useToggleBodyOverflow(locked: boolean, options: Options = {}) {
|
||||
|
||||
useEffect(() => {
|
||||
const root = document.documentElement;
|
||||
const body = document.body;
|
||||
|
||||
root.classList.toggle(className, locked);
|
||||
|
||||
const prevOverflow = document.body.style.overflow;
|
||||
document.body.style.overflow = locked ? "hidden" : "";
|
||||
if (locked) {
|
||||
root.classList.add(className);
|
||||
body.style.overflow = "hidden";
|
||||
} else {
|
||||
root.classList.remove(className);
|
||||
body.style.overflow = "";
|
||||
}
|
||||
|
||||
return () => {
|
||||
root.classList.remove(className);
|
||||
document.body.style.overflow = prevOverflow;
|
||||
body.style.overflow = "";
|
||||
};
|
||||
}, [locked, className]);
|
||||
}
|
||||
@@ -1,12 +1,15 @@
|
||||
import type { NextConfig } from "next";
|
||||
|
||||
const allowedOrigin = process.env.NEXT_ALLOWED_DEV_ORIGIN;
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
/* config options here */
|
||||
output: "standalone",
|
||||
trailingSlash: false,
|
||||
poweredByHeader: false,
|
||||
allowedDevOrigins: [
|
||||
"192.168.178.59", // deine PC-IP
|
||||
],
|
||||
};
|
||||
|
||||
if (allowedOrigin) {
|
||||
nextConfig.allowedDevOrigins = [allowedOrigin];
|
||||
}
|
||||
|
||||
export default nextConfig;
|
||||
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 119 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 188 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 120 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 748 167" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><g id="Logo-neben-Schriftzug" serif:id="Logo neben Schriftzug"><path d="M105.008,158.958c-22.419,11.972 -50.938,8.512 -69.831,-10.381c-39.541,-39.541 -35.021,-113.988 -35.021,-113.988c0.167,-2.605 2.243,-4.68 4.848,-4.848c0,0 74.447,-4.52 113.988,35.021c21.914,21.914 23.066,56.779 3.454,80.054c-0.362,-0.185 -0.737,-0.379 -1.127,-0.582c-5.154,-2.691 -5.16,-2.68 -5.604,-2.92c-1.436,-0.776 -1.97,-1.044 -2.742,-1.452c17.744,-19.163 17.304,-49.132 -1.323,-67.759c-30.978,-30.978 -85.143,-32.462 -101.303,-32.17c-0.292,16.16 1.193,70.325 32.17,101.303c13.793,13.793 33.808,17.614 51.047,11.462c0.145,0.095 0.291,0.19 0.439,0.286c2.484,1.615 5.959,3.52 6.376,3.731c1.806,0.917 3.237,1.615 4.628,2.243Z" style="fill:#298972;"/><path d="M189.124,165.924c-3.398,0.229 -16.488,1.214 -32.559,0.216c-2.19,-0.136 -9.695,-0.773 -15.864,-1.809c-10.966,-1.842 -17.633,-3.992 -21.329,-5.221c-7.711,-2.565 -18.01,-6.682 -29.769,-15.316c-4.985,-3.66 -9.537,-7.394 -15.842,-13.667c-0.927,-0.922 -5.602,-5.807 -9.04,-10.007c-4.591,-5.61 -8.504,-11.049 -11.653,-15.709c-3.199,-4.735 -7.124,-11.263 -10.135,-16.633c0.21,0.254 5.761,7.164 14.336,16.223c1.045,1.104 6.617,7.092 15.664,14.982c2.689,2.345 8.097,6.853 13.443,10.683c1.802,1.291 7.343,5.31 15.048,9.761c16.464,9.511 27.83,13.425 29.737,14.138c12.597,4.709 25.101,7.248 26.764,7.609c7.797,1.694 17.199,3.279 31.199,4.751Z" style="fill:#298972;"/><path d="M138.583,150.484c14.876,-8.386 26.33,-25.547 26.33,-43.826c0,-43.809 -37.251,-83.159 -48.884,-94.38c-4.908,4.734 -14.376,14.475 -23.683,27.446c-3.19,-1.426 -6.42,-2.72 -9.664,-3.896c14.593,-20.964 29.92,-34.535 29.92,-34.535c1.96,-1.724 4.895,-1.724 6.856,0c0,0 55.838,49.446 55.838,105.365c0,18.717 -10.095,36.63 -23.662,47.495c-3.502,-0.854 -8.107,-2.077 -13.05,-3.668Z" style="fill:#3166b3;"/></g><g><path d="M230.865,75.544c2.065,-3.614 5.089,-6.565 9.073,-8.851c3.983,-2.287 8.519,-3.43 13.609,-3.43c5.458,0 10.363,1.291 14.715,3.872c4.352,2.582 7.782,6.214 10.29,10.898c2.508,4.684 3.762,10.124 3.762,16.32c0,6.122 -1.254,11.58 -3.762,16.375c-2.508,4.794 -5.956,8.519 -10.345,11.175c-4.389,2.655 -9.275,3.983 -14.66,3.983c-5.237,0 -9.829,-1.143 -13.775,-3.43c-3.946,-2.287 -6.915,-5.2 -8.907,-8.741l0,11.175l-10.068,0l0,-81.875l10.068,0l0,32.529Zm41.159,18.809c0,-4.573 -0.922,-8.556 -2.766,-11.949c-1.844,-3.393 -4.333,-5.975 -7.468,-7.745c-3.135,-1.77 -6.583,-2.655 -10.345,-2.655c-3.688,0 -7.099,0.904 -10.234,2.711c-3.135,1.807 -5.643,4.426 -7.524,7.856c-1.881,3.43 -2.821,7.395 -2.821,11.894c0,4.573 0.94,8.575 2.821,12.005c1.881,3.43 4.389,6.048 7.524,7.856c3.135,1.807 6.546,2.711 10.234,2.711c3.762,0 7.21,-0.904 10.345,-2.711c3.135,-1.807 5.624,-4.426 7.468,-7.856c1.844,-3.43 2.766,-7.468 2.766,-12.115Z" style="fill:#fff;fill-rule:nonzero;"/><path d="M291.829,94.353c0,-6.196 1.254,-11.636 3.762,-16.32c2.508,-4.684 5.956,-8.317 10.345,-10.898c4.389,-2.582 9.275,-3.872 14.66,-3.872c5.311,0 9.921,1.143 13.83,3.43c3.909,2.287 6.823,5.163 8.741,8.63l0,-11.064l10.179,0l0,60.631l-10.179,0l0,-11.285c-1.992,3.541 -4.96,6.473 -8.907,8.796c-3.946,2.323 -8.538,3.485 -13.775,3.485c-5.385,0 -10.253,-1.328 -14.605,-3.983c-4.352,-2.655 -7.782,-6.38 -10.29,-11.175c-2.508,-4.794 -3.762,-10.253 -3.762,-16.375Zm51.338,0.111c0,-4.573 -0.922,-8.556 -2.766,-11.949c-1.844,-3.393 -4.333,-5.993 -7.468,-7.8c-3.135,-1.807 -6.583,-2.711 -10.345,-2.711c-3.762,0 -7.192,0.885 -10.29,2.655c-3.098,1.77 -5.569,4.352 -7.413,7.745c-1.844,3.393 -2.766,7.376 -2.766,11.949c0,4.647 0.922,8.685 2.766,12.115c1.844,3.43 4.315,6.048 7.413,7.856c3.098,1.807 6.528,2.711 10.29,2.711c3.762,0 7.21,-0.904 10.345,-2.711c3.135,-1.807 5.624,-4.426 7.468,-7.856c1.844,-3.43 2.766,-7.431 2.766,-12.005Z" style="fill:#fff;fill-rule:nonzero;"/><path d="M391.686,125.886c-4.658,0 -8.836,-0.793 -12.534,-2.379c-3.696,-1.586 -6.617,-3.799 -8.761,-6.638c-2.144,-2.84 -3.216,-6.104 -3.216,-9.792l10.29,0c0.295,3.024 1.715,5.495 4.26,7.413c2.545,1.918 5.882,2.877 10.013,2.877c3.836,0 6.86,-0.848 9.073,-2.545c2.213,-1.696 3.319,-3.836 3.319,-6.417c0,-2.655 -1.18,-4.628 -3.541,-5.919c-2.36,-1.291 -6.012,-2.563 -10.953,-3.817c-4.499,-1.18 -8.169,-2.379 -11.009,-3.596c-2.84,-1.217 -5.274,-3.024 -7.302,-5.421c-2.028,-2.397 -3.043,-5.551 -3.043,-9.46c0,-3.098 0.922,-5.938 2.766,-8.519c1.844,-2.582 4.463,-4.628 7.856,-6.141c3.393,-1.512 7.265,-2.268 11.617,-2.268c6.712,0 12.134,1.696 16.264,5.089c4.131,3.393 6.343,8.04 6.638,13.941l-10.29,0c0,-3.172 -1.167,-5.716 -3.501,-7.634c-2.334,-1.918 -5.464,-2.877 -9.391,-2.877c-3.63,0 -6.52,0.774 -8.67,2.323c-2.148,1.549 -3.222,3.577 -3.222,6.0Line truncated
|
||||
|
After Width: | Height: | Size: 8.8 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 748 167" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><g id="Logo-neben-Schriftzug" serif:id="Logo neben Schriftzug"></g><g><g id="Logo-neben-Schriftzug1" serif:id="Logo neben Schriftzug"><path d="M105.008,158.958c-22.419,11.972 -50.938,8.512 -69.831,-10.381c-39.541,-39.541 -35.021,-113.988 -35.021,-113.988c0.167,-2.605 2.243,-4.68 4.848,-4.848c0,0 74.447,-4.52 113.988,35.021c21.914,21.914 23.066,56.779 3.454,80.054c-0.362,-0.185 -0.737,-0.379 -1.127,-0.582c-5.154,-2.691 -5.16,-2.68 -5.604,-2.92c-1.436,-0.776 -1.97,-1.044 -2.742,-1.452c17.744,-19.163 17.304,-49.132 -1.323,-67.759c-30.978,-30.978 -85.143,-32.462 -101.303,-32.17c-0.292,16.16 1.193,70.325 32.17,101.303c13.793,13.793 33.808,17.614 51.047,11.462c0.145,0.095 0.291,0.19 0.439,0.286c2.484,1.615 5.959,3.52 6.376,3.731c1.806,0.917 3.237,1.615 4.628,2.243Z" style="fill:#298972;"/><path d="M189.124,165.924c-3.398,0.229 -16.488,1.214 -32.559,0.216c-2.19,-0.136 -9.695,-0.773 -15.864,-1.809c-10.966,-1.842 -17.633,-3.992 -21.329,-5.221c-7.711,-2.565 -18.01,-6.682 -29.769,-15.316c-4.985,-3.66 -9.537,-7.394 -15.842,-13.667c-0.927,-0.922 -5.602,-5.807 -9.04,-10.007c-4.591,-5.61 -8.504,-11.049 -11.653,-15.709c-3.199,-4.735 -7.124,-11.263 -10.135,-16.633c0.21,0.254 5.761,7.164 14.336,16.223c1.045,1.104 6.617,7.092 15.664,14.982c2.689,2.345 8.097,6.853 13.443,10.683c1.802,1.291 7.343,5.31 15.048,9.761c16.464,9.511 27.83,13.425 29.737,14.138c12.597,4.709 25.101,7.248 26.764,7.609c7.797,1.694 17.199,3.279 31.199,4.751Z" style="fill:#298972;"/><path d="M138.583,150.484c14.876,-8.386 26.33,-25.547 26.33,-43.826c0,-43.809 -37.251,-83.159 -48.884,-94.38c-4.908,4.734 -14.376,14.475 -23.683,27.446c-3.19,-1.426 -6.42,-2.72 -9.664,-3.896c14.593,-20.964 29.92,-34.535 29.92,-34.535c1.96,-1.724 4.895,-1.724 6.856,0c0,0 55.838,49.446 55.838,105.365c0,18.717 -10.095,36.63 -23.662,47.495c-3.502,-0.854 -8.107,-2.077 -13.05,-3.668Z" style="fill:#3166b3;"/></g><g><path d="M230.865,75.544c2.065,-3.614 5.089,-6.565 9.073,-8.851c3.983,-2.287 8.519,-3.43 13.609,-3.43c5.458,0 10.363,1.291 14.715,3.872c4.352,2.582 7.782,6.214 10.29,10.898c2.508,4.684 3.762,10.124 3.762,16.32c0,6.122 -1.254,11.58 -3.762,16.375c-2.508,4.794 -5.956,8.519 -10.345,11.175c-4.389,2.655 -9.275,3.983 -14.66,3.983c-5.237,0 -9.829,-1.143 -13.775,-3.43c-3.946,-2.287 -6.915,-5.2 -8.907,-8.741l0,11.175l-10.068,0l0,-81.875l10.068,0l0,32.529Zm41.159,18.809c0,-4.573 -0.922,-8.556 -2.766,-11.949c-1.844,-3.393 -4.333,-5.975 -7.468,-7.745c-3.135,-1.77 -6.583,-2.655 -10.345,-2.655c-3.688,0 -7.099,0.904 -10.234,2.711c-3.135,1.807 -5.643,4.426 -7.524,7.856c-1.881,3.43 -2.821,7.395 -2.821,11.894c0,4.573 0.94,8.575 2.821,12.005c1.881,3.43 4.389,6.048 7.524,7.856c3.135,1.807 6.546,2.711 10.234,2.711c3.762,0 7.21,-0.904 10.345,-2.711c3.135,-1.807 5.624,-4.426 7.468,-7.856c1.844,-3.43 2.766,-7.468 2.766,-12.115Z" style="fill:#0c0b0f;fill-rule:nonzero;"/><path d="M291.829,94.353c0,-6.196 1.254,-11.636 3.762,-16.32c2.508,-4.684 5.956,-8.317 10.345,-10.898c4.389,-2.582 9.275,-3.872 14.66,-3.872c5.311,0 9.921,1.143 13.83,3.43c3.909,2.287 6.823,5.163 8.741,8.63l0,-11.064l10.179,0l0,60.631l-10.179,0l0,-11.285c-1.992,3.541 -4.96,6.473 -8.907,8.796c-3.946,2.323 -8.538,3.485 -13.775,3.485c-5.385,0 -10.253,-1.328 -14.605,-3.983c-4.352,-2.655 -7.782,-6.38 -10.29,-11.175c-2.508,-4.794 -3.762,-10.253 -3.762,-16.375Zm51.338,0.111c0,-4.573 -0.922,-8.556 -2.766,-11.949c-1.844,-3.393 -4.333,-5.993 -7.468,-7.8c-3.135,-1.807 -6.583,-2.711 -10.345,-2.711c-3.762,0 -7.192,0.885 -10.29,2.655c-3.098,1.77 -5.569,4.352 -7.413,7.745c-1.844,3.393 -2.766,7.376 -2.766,11.949c0,4.647 0.922,8.685 2.766,12.115c1.844,3.43 4.315,6.048 7.413,7.856c3.098,1.807 6.528,2.711 10.29,2.711c3.762,0 7.21,-0.904 10.345,-2.711c3.135,-1.807 5.624,-4.426 7.468,-7.856c1.844,-3.43 2.766,-7.431 2.766,-12.005Z" style="fill:#0c0b0f;fill-rule:nonzero;"/><path d="M391.686,125.886c-4.658,0 -8.836,-0.793 -12.534,-2.379c-3.696,-1.586 -6.617,-3.799 -8.761,-6.638c-2.144,-2.84 -3.216,-6.104 -3.216,-9.792l10.29,0c0.295,3.024 1.715,5.495 4.26,7.413c2.545,1.918 5.882,2.877 10.013,2.877c3.836,0 6.86,-0.848 9.073,-2.545c2.213,-1.696 3.319,-3.836 3.319,-6.417c0,-2.655 -1.18,-4.628 -3.541,-5.919c-2.36,-1.291 -6.012,-2.563 -10.953,-3.817c-4.499,-1.18 -8.169,-2.379 -11.009,-3.596c-2.84,-1.217 -5.274,-3.024 -7.302,-5.421c-2.028,-2.397 -3.043,-5.551 -3.043,-9.46c0,-3.098 0.922,-5.938 2.766,-8.519c1.844,-2.582 4.463,-4.628 7.856,-6.141c3.393,-1.512 7.265,-2.268 11.617,-2.268c6.712,0 12.134,1.696 16.264,5.089c4.131,3.393 6.343,8.04 6.638,13.941l-10.29,0c0,-3.172 -1.167,-5.716 -3.501,-7.634c-2.334,-1.918 -5.464,-2.877 -9.39Line truncated
|
||||
|
After Width: | Height: | Size: 8.9 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 1024 902" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><g id="Logo-neben-Schriftzug" serif:id="Logo neben Schriftzug"><path d="M568.561,860.67c-121.387,64.822 -275.801,46.086 -378.096,-56.209c-214.09,-214.09 -189.618,-617.181 -189.618,-617.181c0.906,-14.104 12.143,-25.342 26.247,-26.247c0,0 403.091,-24.473 617.181,189.618c118.652,118.652 124.887,307.425 18.703,433.446c-1.961,-1.002 -3.99,-2.05 -6.1,-3.152c-27.908,-14.569 -27.936,-14.511 -30.345,-15.813c-7.774,-4.2 -10.665,-5.654 -14.845,-7.86c96.076,-103.758 93.689,-266.024 -7.161,-366.874c-167.726,-167.726 -461.003,-175.762 -548.498,-174.183c-1.579,87.496 6.457,380.772 174.183,548.498c74.684,74.684 183.049,95.37 276.391,62.059c0.785,0.512 1.577,1.028 2.378,1.549c13.447,8.745 32.265,19.056 34.522,20.202c9.78,4.963 17.525,8.742 25.057,12.147Z" style="fill:#c7c7c7;"/><path d="M1024,898.385c-18.4,1.238 -89.273,6.573 -176.29,1.168c-11.859,-0.737 -52.493,-4.184 -85.893,-9.795c-59.374,-9.973 -95.473,-21.616 -115.483,-28.271c-41.748,-13.885 -97.513,-36.181 -161.183,-82.926c-26.993,-19.818 -51.638,-40.032 -85.778,-73.999c-5.019,-4.994 -30.333,-31.441 -48.944,-54.183c-24.857,-30.375 -46.046,-59.822 -63.093,-85.054c-17.318,-25.635 -38.574,-60.982 -54.873,-90.056c1.135,1.375 31.191,38.787 77.621,87.837c5.659,5.978 35.829,38.399 84.809,81.117c14.558,12.697 43.841,37.104 72.784,57.841c9.756,6.99 39.76,28.753 81.476,52.852c89.145,51.497 150.685,72.69 161.008,76.549c68.205,25.499 135.906,39.242 144.914,41.199c42.216,9.173 93.125,17.751 168.922,25.722Z" style="fill:#c7c7c7;"/><path d="M750.35,814.786c80.544,-45.405 142.563,-138.321 142.563,-237.294c0,-237.2 -201.695,-450.261 -264.681,-511.013c-26.574,25.632 -77.839,78.375 -128.23,148.604c-17.272,-7.72 -34.763,-14.73 -52.327,-21.094c79.015,-113.507 161.998,-186.99 161.998,-186.99c10.613,-9.333 26.506,-9.333 37.119,0c0,0 302.333,267.724 302.333,570.493c0,101.34 -54.657,198.33 -128.117,257.156c-18.963,-4.625 -43.895,-11.244 -70.657,-19.863Z" style="fill:#c7c7c7;"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 1024 902" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><g id="Logo-neben-Schriftzug" serif:id="Logo neben Schriftzug"><path d="M568.561,860.67c-121.387,64.822 -275.801,46.086 -378.096,-56.209c-214.09,-214.09 -189.618,-617.181 -189.618,-617.181c0.906,-14.104 12.143,-25.342 26.247,-26.247c0,0 403.091,-24.473 617.181,189.618c118.652,118.652 124.887,307.425 18.703,433.446c-1.961,-1.002 -3.99,-2.05 -6.1,-3.152c-27.908,-14.569 -27.936,-14.511 -30.345,-15.813c-7.774,-4.2 -10.665,-5.654 -14.845,-7.86c96.076,-103.758 93.689,-266.024 -7.161,-366.874c-167.726,-167.726 -461.003,-175.762 -548.498,-174.183c-1.579,87.496 6.457,380.772 174.183,548.498c74.684,74.684 183.049,95.37 276.391,62.059c0.785,0.512 1.577,1.028 2.378,1.549c13.447,8.745 32.265,19.056 34.522,20.202c9.78,4.963 17.525,8.742 25.057,12.147Z" style="fill:#fff;"/><path d="M1024,898.385c-18.4,1.238 -89.273,6.573 -176.29,1.168c-11.859,-0.737 -52.493,-4.184 -85.893,-9.795c-59.374,-9.973 -95.473,-21.616 -115.483,-28.271c-41.748,-13.885 -97.513,-36.181 -161.183,-82.926c-26.993,-19.818 -51.638,-40.032 -85.778,-73.999c-5.019,-4.994 -30.333,-31.441 -48.944,-54.183c-24.857,-30.375 -46.046,-59.822 -63.093,-85.054c-17.318,-25.635 -38.574,-60.982 -54.873,-90.056c1.135,1.375 31.191,38.787 77.621,87.837c5.659,5.978 35.829,38.399 84.809,81.117c14.558,12.697 43.841,37.104 72.784,57.841c9.756,6.99 39.76,28.753 81.476,52.852c89.145,51.497 150.685,72.69 161.008,76.549c68.205,25.499 135.906,39.242 144.914,41.199c42.216,9.173 93.125,17.751 168.922,25.722Z" style="fill:#fff;"/><path d="M750.35,814.786c80.544,-45.405 142.563,-138.321 142.563,-237.294c0,-237.2 -201.695,-450.261 -264.681,-511.013c-26.574,25.632 -77.839,78.375 -128.23,148.604c-17.272,-7.72 -34.763,-14.73 -52.327,-21.094c79.015,-113.507 161.998,-186.99 161.998,-186.99c10.613,-9.333 26.506,-9.333 37.119,0c0,0 302.333,267.724 302.333,570.493c0,101.34 -54.657,198.33 -128.117,257.156c-18.963,-4.625 -43.895,-11.244 -70.657,-19.863Z" style="fill:#fff;"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 1024 902" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><g id="Logo-neben-Schriftzug" serif:id="Logo neben Schriftzug"><path d="M568.561,860.67c-121.387,64.822 -275.801,46.086 -378.096,-56.209c-214.09,-214.09 -189.618,-617.181 -189.618,-617.181c0.906,-14.104 12.143,-25.342 26.247,-26.247c0,0 403.091,-24.473 617.181,189.618c118.652,118.652 124.887,307.425 18.703,433.446c-1.961,-1.002 -3.99,-2.05 -6.1,-3.152c-27.908,-14.569 -27.936,-14.511 -30.345,-15.813c-7.774,-4.2 -10.665,-5.654 -14.845,-7.86c96.076,-103.758 93.689,-266.024 -7.161,-366.874c-167.726,-167.726 -461.003,-175.762 -548.498,-174.183c-1.579,87.496 6.457,380.772 174.183,548.498c74.684,74.684 183.049,95.37 276.391,62.059c0.785,0.512 1.577,1.028 2.378,1.549c13.447,8.745 32.265,19.056 34.522,20.202c9.78,4.963 17.525,8.742 25.057,12.147Z" style="fill:#298972;"/><path d="M1024,898.385c-18.4,1.238 -89.273,6.573 -176.29,1.168c-11.859,-0.737 -52.493,-4.184 -85.893,-9.795c-59.374,-9.973 -95.473,-21.616 -115.483,-28.271c-41.748,-13.885 -97.513,-36.181 -161.183,-82.926c-26.993,-19.818 -51.638,-40.032 -85.778,-73.999c-5.019,-4.994 -30.333,-31.441 -48.944,-54.183c-24.857,-30.375 -46.046,-59.822 -63.093,-85.054c-17.318,-25.635 -38.574,-60.982 -54.873,-90.056c1.135,1.375 31.191,38.787 77.621,87.837c5.659,5.978 35.829,38.399 84.809,81.117c14.558,12.697 43.841,37.104 72.784,57.841c9.756,6.99 39.76,28.753 81.476,52.852c89.145,51.497 150.685,72.69 161.008,76.549c68.205,25.499 135.906,39.242 144.914,41.199c42.216,9.173 93.125,17.751 168.922,25.722Z" style="fill:#298972;"/><path d="M750.35,814.786c80.544,-45.405 142.563,-138.321 142.563,-237.294c0,-237.2 -201.695,-450.261 -264.681,-511.013c-26.574,25.632 -77.839,78.375 -128.23,148.604c-17.272,-7.72 -34.763,-14.73 -52.327,-21.094c79.015,-113.507 161.998,-186.99 161.998,-186.99c10.613,-9.333 26.506,-9.333 37.119,0c0,0 302.333,267.724 302.333,570.493c0,101.34 -54.657,198.33 -128.117,257.156c-18.963,-4.625 -43.895,-11.244 -70.657,-19.863Z" style="fill:#3166b3;"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="1024" height="1024" viewBox="0 0 1024 1024"><metadata><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"><rdf:Description><dc:creator>RealFaviconGenerator</dc:creator><dc:source>https://realfavicongenerator.net</dc:source></rdf:Description></rdf:RDF></metadata><image width="1024" height="1024" xlink:href="data:image/png;base64,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 truncated
|
||||
|
Before Width: | Height: | Size: 30 KiB |
@@ -1,13 +1,13 @@
|
||||
:root {
|
||||
/* Colors */
|
||||
--btn-bg-primary: #474747;
|
||||
--btn-bg-primary-hover: #3b3b3b;
|
||||
--btn-bg-primary: var(--color-accent);
|
||||
--btn-bg-primary-hover: var(--color-accent);
|
||||
--btn-bg-primary-active: #353030;
|
||||
|
||||
--btn-text-light: #fefcfb;
|
||||
--btn-text-dark: #474747;
|
||||
--btn-text-dark: var(--color-accent);
|
||||
|
||||
--btn-border-primary: #474747;
|
||||
--btn-border-primary: var(--color-accent);
|
||||
--btn-border-ghost: #e9e9e9;
|
||||
--btn-border-ghost-hover: #ececec;
|
||||
--btn-border-ghost-active: #e1e1e1;
|
||||
@@ -25,20 +25,21 @@
|
||||
--btn-focus-offset: 2px;
|
||||
|
||||
/* Layout */
|
||||
--btn-py: 12px;
|
||||
--btn-px: 16px;
|
||||
--btn-py: 8px;
|
||||
--btn-px: 12px;
|
||||
--btn-py-lg: 16px;
|
||||
--btn-px-lg: 24px;
|
||||
--btn-radius: 4px;
|
||||
--btn-px-lg: 20px;
|
||||
--btn-radius: 50px;
|
||||
--btn-gap: 8px;
|
||||
--btn-max-height: 52px;
|
||||
--btn-max-height: 46px;
|
||||
--btn-min-height: 38px;
|
||||
--btn-icon-size: 18px;
|
||||
--btn-tertiary-px: 4px;
|
||||
|
||||
/* Typography */
|
||||
--btn-font-family: inherit;
|
||||
--btn-font-size: 0.889rem;
|
||||
--btn-font-weight: 600;
|
||||
--btn-font-family: var(--font-body);
|
||||
--btn-font-size: var(--font-size-xs);
|
||||
--btn-font-weight: var(--font-weight-medium);
|
||||
--btn-line-height: 1;
|
||||
|
||||
/* Shadow */
|
||||
@@ -72,6 +73,7 @@
|
||||
user-select: none;
|
||||
transition: var(--btn-transition);
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.btn:focus {
|
||||
@@ -121,12 +123,37 @@
|
||||
transition: none;
|
||||
}
|
||||
|
||||
/* Filled Inverse */
|
||||
.btn--filled-inverse {
|
||||
background-color: #ffffff;
|
||||
color: var(--color-accent);
|
||||
border-color: #ffffff;
|
||||
box-shadow: var(--btn-shadow);
|
||||
}
|
||||
|
||||
.btn--filled-inverse .btn-icon {
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
.btn--filled-inverse:hover {
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
border-color: rgba(255, 255, 255, 0.9);
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.btn--filled-inverse:active {
|
||||
background-color: rgba(255, 255, 255, 0.75);
|
||||
border-color: rgba(255, 255, 255, 0.75);
|
||||
transition: none;
|
||||
}
|
||||
|
||||
/* Outline */
|
||||
.btn--outline {
|
||||
background-color: transparent;
|
||||
color: var(--btn-text-dark);
|
||||
border-color: var(--btn-border-primary);
|
||||
box-shadow: var(--btn-shadow-none);
|
||||
min-height: var(--btn-min-height);
|
||||
}
|
||||
|
||||
.btn--outline .btn-icon {
|
||||
@@ -217,6 +244,12 @@
|
||||
border-color: var(--btn-bg-primary);
|
||||
}
|
||||
|
||||
.btn--filled-inverse:hover {
|
||||
background-color: #ffffff;
|
||||
border-color: #ffffff;
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.btn--outline:hover {
|
||||
background-color: transparent;
|
||||
border-color: var(--btn-border-primary);
|
||||
|
||||
@@ -11,17 +11,53 @@
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-7: 32px;
|
||||
--space-7: 28px;
|
||||
--space-8: 32px;
|
||||
--space-9: 36px;
|
||||
--space-10: 40px;
|
||||
--space-11: 44px;
|
||||
--space-12: 48px;
|
||||
--space-13: 52px;
|
||||
--space-14: 56px;
|
||||
--space-15: 60px;
|
||||
--space-16: 64px;
|
||||
--space-17: 68px;
|
||||
--space-18: 72px;
|
||||
--space-19: 76px;
|
||||
--space-20: 80px;
|
||||
--space-21: 84px;
|
||||
--space-22: 88px;
|
||||
--space-23: 92px;
|
||||
--space-24: 96px;
|
||||
--space-25: 100px;
|
||||
--space-26: 104px;
|
||||
--space-27: 108px;
|
||||
--space-28: 112px;
|
||||
--space-29: 116px;
|
||||
--space-30: 120px;
|
||||
--space-31: 124px;
|
||||
--space-32: 128px;
|
||||
--space-33: 132px;
|
||||
--space-34: 136px;
|
||||
--space-35: 140px;
|
||||
--space-36: 144px;
|
||||
|
||||
/* Colors */
|
||||
--color-surface: #ffffff;
|
||||
--color-surface-alt: #f9f9f9;
|
||||
--color-background: #ffffff;
|
||||
--color-background-alt: #f9f9f9;
|
||||
--color-background-linear: linear-gradient(
|
||||
to bottom,
|
||||
#f9f9f9 5%,
|
||||
#ffffff 50%,
|
||||
#f9f9f9 100%
|
||||
);
|
||||
--color-text: #171717;
|
||||
--color-text-muted: #5f5f5f;
|
||||
--color-text-muted: #4a4a4a;
|
||||
--color-text-soft: #7a7a7a;
|
||||
--color-heading: #171717;
|
||||
--color-accent: #267361;
|
||||
|
||||
/* Radius */
|
||||
--radius-none: 0;
|
||||
|
||||
@@ -1,41 +1,21 @@
|
||||
:root {
|
||||
/* Font sizes */
|
||||
--font-size-body: 1rem;
|
||||
--font-size-small: 0.875rem;
|
||||
--font-size-lead: 1.125rem;
|
||||
--font-size-h1: clamp(
|
||||
2.566rem,
|
||||
calc(
|
||||
2.566rem + (3.247rem - 2.566rem) * ((100vw - 768px) / (1024px - 768px))
|
||||
),
|
||||
3.247rem
|
||||
);
|
||||
--font-size-h2: clamp(
|
||||
2.027rem,
|
||||
calc(
|
||||
2.027rem + (2.566rem - 2.027rem) * ((100vw - 768px) / (1024px - 768px))
|
||||
),
|
||||
2.566rem
|
||||
);
|
||||
--font-size-xxs: 0.79rem;
|
||||
--font-size-xs: clamp(0.79rem, 2vw, 0.889rem);
|
||||
--font-size-s: 0.889rem;
|
||||
--font-size-base: clamp(0.889rem, 2.2vw, 1rem);
|
||||
--font-size-m: clamp(1rem, 2.15vw, 1.125rem);
|
||||
|
||||
--font-size-h3: clamp(
|
||||
1.602rem,
|
||||
calc(
|
||||
1.602rem + (2.027rem - 1.602rem) * ((100vw - 768px) / (1024px - 768px))
|
||||
),
|
||||
2.027rem
|
||||
);
|
||||
|
||||
--font-size-h4: clamp(
|
||||
1.266rem,
|
||||
calc(
|
||||
1.266rem + (1.602rem - 1.266rem) * ((100vw - 768px) / (1024px - 768px))
|
||||
),
|
||||
1.602rem
|
||||
);
|
||||
/* Fluid typography (768px to 1024px) */
|
||||
--font-size-h1: clamp(1.802rem, 5.71vw, 3.247rem);
|
||||
--font-size-h2: clamp(1.602rem, 4.51vw, 2.566rem);
|
||||
--font-size-h3: clamp(1.424rem, 3.56vw, 2.027rem);
|
||||
--font-size-h4: clamp(1.266rem, 3.17vw, 1.802rem);
|
||||
--font-size-h5: clamp(1.125rem, 2.82vw, 1.602rem);
|
||||
|
||||
--line-height-body: 1.5;
|
||||
--line-height-heading: 1.2;
|
||||
--line-height-heading: 1.1;
|
||||
--line-height-lead: 1.2;
|
||||
|
||||
--letter-spacing-tight: -0.02em;
|
||||
--letter-spacing-normal: 0;
|
||||
@@ -59,20 +39,20 @@ a {
|
||||
|
||||
p,
|
||||
li {
|
||||
font-size: var(--font-size-body);
|
||||
font-size: var(--font-size-base);
|
||||
line-height: var(--line-height-body);
|
||||
}
|
||||
|
||||
small,
|
||||
.small,
|
||||
.text-small {
|
||||
font-size: var(--font-size-small);
|
||||
font-size: var(--font-size-xs);
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.lead,
|
||||
.text-lead {
|
||||
font-size: var(--font-size-lead);
|
||||
line-height: 1.6;
|
||||
font-size: var(--font-size-m);
|
||||
line-height: var(--line-height-lead);
|
||||
}
|
||||
|
||||
h1,
|
||||
@@ -91,12 +71,19 @@ h6 {
|
||||
h1 {
|
||||
font-size: var(--font-size-h1);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: var(--font-size-h2);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: var(--font-size-h3);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: var(--font-size-h4);
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: var(--font-size-h5);
|
||||
}
|
||||