Startseite in zwei Entwürfen: A Editorial (/entwurf-a) und B Bögen (/entwurf-b), Übersicht /entwuerfe; Newsreader und Syne selbst gehostet

This commit is contained in:
till committed 2026-10-10 07:40:30 +02:00
1 parent 126313c4b0
commit c3ddf03962
10 files changed
+821

No files matched your search

+2
View File
@@ -4,3 +4,5 @@ und werden selbst gehostet (keine Verbindung zu Google).
- Libre Caslon Condensed (Pablo Impallari, Rodrigo Fuenzalida), latin, variabel 400–700 - Libre Caslon Condensed (Pablo Impallari, Rodrigo Fuenzalida), latin, variabel 400–700
- Pinyon Script (Nicole Fally), latin - Pinyon Script (Nicole Fally), latin
- Albert Sans (Andreas Rasmussen), latin, variabel 400–700 - Albert Sans (Andreas Rasmussen), latin, variabel 400–700
- Newsreader (Production Type), latin, variabel
- Syne (Bonjour Monde), latin, variabel
Binary file not shown.
Binary file not shown.
Binary file not shown.
+57
View File
@@ -0,0 +1,57 @@
/** Gemeinsame Inhalte der Startseiten-Varianten (Entwurf A und B). */
import { priceGroups, fromPrice } from './site';
import salonInnen1 from '../assets/img/salon-innen-1.jpg';
import salonInnen4 from '../assets/img/salon-innen-4.jpg';
import salonEmpfang from '../assets/img/salon-empfang.jpg';
import salonWarte from '../assets/img/salon-wartebereich.jpg';
import teamFoto from '../assets/img/team-gruppenfoto.jpg';
import vero from '../assets/img/team/veronika.jpg';
import marco from '../assets/img/team/marco.jpg';
import gl from '../assets/img/great-lengths.jpg';
import brautA from '../assets/img/arbeiten/braut-wellen-bluetenspangen.jpg';
import brautB from '../assets/img/arbeiten/braut-hochsteck-haarschmuck.jpg';
import brautC from '../assets/img/arbeiten/braut-chignon-blueten.jpg';
import balA from '../assets/img/arbeiten/balayage-beige-wellen.jpg';
import balB from '../assets/img/arbeiten/balayage-honigblond.jpg';
import glN from '../assets/img/arbeiten/gl-laenge-nachher-2.jpg';
import glV from '../assets/img/arbeiten/gl-laenge-vorher-2.jpg';
import fV from '../assets/img/arbeiten/gl-fuelle-vorher-2.jpg';
import fN from '../assets/img/arbeiten/gl-fuelle-nachher-2.jpg';
import cV from '../assets/img/arbeiten/farbe-vorher-blond.jpg';
import cN from '../assets/img/arbeiten/farbe-nachher-blond.jpg';
import damen from '../assets/img/arbeiten/schnitt-lob-wellen.jpg';
import herren from '../assets/img/arbeiten/barber-bart.jpg';
const g = Object.fromEntries(priceGroups.map((x) => [x.id, x]));
const first = (id: string) => fromPrice(g[id].items.find((i) => i.from || i.tiers) ?? g[id].items[0]);
export const img = { salonInnen1, salonInnen4, salonEmpfang, salonWarte, teamFoto, vero, marco, gl, brautA, brautB, brautC, balA, balB, glN, glV, fV, fN, cV, cN, damen, herren };
/** Drei Schwerpunkte */
export const focus = [
{ title: 'Braut', sub: 'Frisur und Make-up', text: 'Vom Probestyling bis zum Morgen der Hochzeit. Im Salon oder bei Ihnen vor Ort.', price: `Brautfrisur ${fromPrice(g.braut.items[1])}`, href: '/brautservice', img: brautB, alt: 'Hochsteckfrisur mit Haarschmuck' },
{ title: 'Balayage & Farbe', sub: 'weich und schonend', text: 'Balayage, Strähnen und Farbwechsel mit Paul Mitchell und Redken. Preise nach Haarlänge.', price: `Balayage ${fromPrice(g.farbe.items[1])}`, href: '/balayage-farbe', img: balA, alt: 'Balayage in Beige mit Wellen' },
{ title: 'Great Lengths', sub: 'Länge und Fülle', text: 'Haarverlängerung und Haarverdichtung als Master of Great Lengths. Die Beratung ist kostenlos.', price: `Verdichtung ${fromPrice(g.verlaengerung.items[1])}`, href: '/haarverlaengerung', img: glN, alt: 'Langes, dunkles Haar nach einer Verlängerung' },
];
/** Alltag (Preisliste kurz) */
export const daily = [
{ title: 'Damen', price: first('damen'), detail: 'Schneiden, Föhnen, Hochstecken, Dauerwelle', href: '/leistungen-preise#damen' },
{ title: 'Herren & Barber', price: first('herren'), detail: 'Haarschnitt, Bart, Nassrasur mit heißem Tuch', href: '/barber' },
{ title: 'Kinder', price: first('kinder'), detail: 'Haarschnitt bis 12 Jahre', href: '/leistungen-preise#kinder' },
{ title: 'Augenbrauen & Wimpern', price: first('augen'), detail: 'Zupfen und Färben', href: '/leistungen-preise#augen' },
];
/** Vorher / Nachher */
export const cases = [
{ title: 'Mehr Länge', where: 'Great Lengths', v: glV, n: glN, altV: 'Vorher: schulterlanges, dunkles Haar', altN: 'Nachher: langes, dunkles Haar', note: 'Schulterlang zu lang, Great Lengths Echthaar, ab 650 €' },
{ title: 'Mehr Fülle', where: 'Great Lengths', v: fV, n: fN, altV: 'Vorher: feines, glattes Haar', altN: 'Nachher: volle Wellen', note: 'Gleiche Länge, deutlich mehr Volumen, ab 350 €' },
{ title: 'Neues Blond', where: 'Balayage & Farbe', v: cV, n: cN, altV: 'Vorher: mittelbraunes Haar', altN: 'Nachher: helles, kühles Blond', note: 'Aufhellung und Glossing, lang ab 160 €' },
];
export const steps = [
{ t: 'Anfrage schicken', d: 'Sagen Sie uns, was Sie vorhaben, gern mit einem Foto von hinten bei Tageslicht. Das dauert zwei Minuten.' },
{ t: 'Rückruf in zwei Werktagen', d: 'Wir klären Fragen und den Preisrahmen. Bei Farbe und Great Lengths folgt eine kurze Beratung im Salon.' },
{ t: 'Termin mit Zeit', d: 'Wir planen so viel Zeit ein, wie Ihr Haar braucht. Wer kurzfristig kann, kommt über die Warteliste oft schneller dran.' },
];
+42
View File
@@ -0,0 +1,42 @@
---
/**
* Schlanker Rahmen für die Startseiten-Entwürfe A und B.
* Eigene Kopf- und Fußzeile je Entwurf, gemeinsame Grundlagen (Reset, .sr, .fig) aus global.css.
*/
import '../styles/global.css';
import '../styles/variants.css';
import Icon from '../components/Icon.astro';
import { salon, SITE_URL } from '../data/site';
interface Props { title: string; description: string; variant: 'a' | 'b'; fonts: string[] }
const { title, description, variant, fonts } = Astro.props;
const path = Astro.url.pathname.replace(/\/$/, '');
---
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{title}</title>
<meta name="description" content={description} />
<meta name="robots" content="noindex, nofollow" />
<link rel="canonical" href={`${SITE_URL}/`} />
<meta name="theme-color" content="#ffffff" />
<meta name="format-detection" content="telephone=no" />
{fonts.map((f) => <link rel="preload" href={`/fonts/${f}`} as="font" type="font/woff2" crossorigin />)}
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
</head>
<body class={`v-${variant}`}>
<a class="skip" href="#inhalt">Zum Inhalt springen</a>
<p class="vnote">Entwurf {variant.toUpperCase()} · <a href="/entwuerfe">alle Entwürfe vergleichen</a></p>
<slot />
<nav class="mbar" aria-label="Schnellkontakt">
<a href={salon.phoneHref}><Icon name="phone" />Anrufen</a>
<a href="/anfrage">Anfragen</a>
</nav>
<script>
import { initSite } from '../scripts/site';
initSite();
</script>
</body>
</html>
+28
View File
@@ -0,0 +1,28 @@
---
import Base from '../layouts/Base.astro';
import Pic from '../components/Pic.astro';
import { img } from '../data/home';
const items = [
{ href: '/entwurf-a', n: 'A', t: 'Editorial', d: 'Große Serifenschrift „TEAM VK“, klare Blöcke in Blau und Navy, eckige Knöpfe. Wirkt wie ein Magazin.', pic: img.brautA },
{ href: '/entwurf-b', n: 'B', t: 'Bögen', d: 'Schreibschrift im Kopf, Bögen wie der Durchgang im Salon, runde Knöpfe. Wirkt weich und persönlich.', pic: img.salonInnen1 },
{ href: '/', n: 'C', t: 'Raster', d: 'Die aktuelle Fassung mit feinen Rasterlinien und schmaler Serifenschrift. Alle Unterseiten sind derzeit in diesem Stil.', pic: img.salonInnen4 },
];
---
<Base title="Entwürfe der Startseite" description="Drei Entwürfe der neuen Startseite vom Friseur-Team VK im Vergleich.">
<section class="pad ent">
<p class="cap">Zur Auswahl</p>
<h1 class="h2 mt-3">Drei Entwürfe für die Startseite</h1>
<p class="lead mt-4">Gleicher Inhalt, gleiche Fotos, drei Gestaltungen. Nach der Entscheidung bekommen alle Unterseiten denselben Stil.</p>
<div class="ent__grid">
{items.map((x) => (
<a class="ent__item" href={x.href}>
<div class="fig"><Pic src={x.pic} alt="" sizes="(min-width: 56rem) 30vw, 100vw" widths={[400, 700]} pos="top" /></div>
<span class="cap">Entwurf {x.n}</span>
<h2>{x.t}</h2>
<p class="small muted">{x.d}</p>
<span class="go">Ansehen</span>
</a>
))}
</div>
</section>
</Base>
+194
View File
@@ -0,0 +1,194 @@
---
import Variant from '../layouts/Variant.astro';
import Pic from '../components/Pic.astro';
import { Image } from 'astro:assets';
import logo from '../assets/logo/logo.png';
import { salon, waits, reviews, hours, fmtHours } from '../data/site';
import { img, focus, daily, cases, steps } from '../data/home';
---
<Variant
title="Entwurf A · Friseur-Team VK in Tostedt"
description="Entwurf A (Editorial) der neuen Startseite vom Friseur-Team VK in Tostedt."
variant="a"
fonts={['newsreader-var.woff2', 'albert-sans-var.woff2']}
>
<header class="a-hd">
<div class="wrap a-hd__in">
<a class="a-hd__logo" href="/entwurf-a" aria-label="Friseur-Team VK, Start"><Image src={logo} height={44} densities={[1, 2]} format="webp" alt="Friseur-Team VK" loading="eager" /></a>
<nav class="a-hd__nav" aria-label="Hauptmenü">
<a href="/brautservice">Braut</a>
<a href="/balayage-farbe">Farbe</a>
<a href="/haarverlaengerung">Great Lengths</a>
<a href="/leistungen-preise">Preise</a>
<a href="/team">Team</a>
<a href="/kontakt">Kontakt</a>
</nav>
<div class="a-hd__right">
<a class="a-hd__phone" href={salon.phoneHref}>{salon.phoneDisplay}</a>
<a class="btn" href="/anfrage">Termin anfragen</a>
</div>
</div>
</header>
<main id="inhalt" tabindex="-1">
<div class="a-wait" aria-label="Wartezeiten für neue Kundinnen">
<div class="wrap a-wait__in">
<span class="lbl">Neue Kundinnen, Stand {waits.asOf}</span>
{waits.items.map((w) => <span><b>{w.label}:</b> {w.value}</span>)}
</div>
</div>
<!-- Hero -->
<section class="wrap a-hero" aria-labelledby="a-h1">
<p class="lbl a-hero__kicker">Friseur · Meisterbetrieb · Tostedt</p>
<h1 id="a-h1"><span class="sr">Friseur-Team VK, Tostedt</span><span aria-hidden="true">TEAM VK</span></h1>
<div class="a-hero__grid">
<figure class="fig a-hero__small" data-clip><Pic src={img.balB} alt="Honigblonde Balayage aus dem Salon" sizes="16rem" widths={[300, 500]} /></figure>
<figure class="fig a-hero__main" data-clip><Pic src={img.brautA} alt="Brautfrisur mit Wellen und Blütenspangen" sizes="(min-width: 56rem) 34vw, 100vw" eager pos="top" /></figure>
<div class="a-hero__text" data-rv>
<p class="a-hero__claim">Schön von außen, <em>glücklich von innen.</em></p>
<p>Brautstyling, Balayage und Haarverlängerung mit Great Lengths. Und der Schnitt zwischendurch, in der Kastanienallee 1.</p>
<div class="row"><a class="btn" href="/anfrage">Termin anfragen</a><a class="more" href="/neue-kundinnen">Neu bei uns?</a></div>
<div class="a-hero__proof">
<span><b>{salon.google.rating} Sterne</b> aus {salon.google.count} Google-Bewertungen</span>
<span><b>Master of Great Lengths</b> und Paul Mitchell Flagship-Salon</span>
</div>
</div>
</div>
</section>
<!-- Über uns -->
<section class="a-about" aria-labelledby="a-about-h">
<div class="a-about__box" data-rv>
<h2 id="a-about-h">Seit {salon.sinceYear} ein Meisterbetrieb, heute ein Team aus acht Menschen.</h2>
<p>Friseurmeisterin Veronika Sprangel hat den Salon im {salon.since} eröffnet. Heute arbeiten Friseurinnen und Friseure, ein Barber und ein Auszubildender im Team. Wir arbeiten mit Paul Mitchell, Redken und Great Lengths.</p>
<a class="more" href="/team">Das Team kennenlernen</a>
</div>
<figure class="fig a-about__pic" data-clip><Pic src={img.teamFoto} alt="Das Team vom Friseur-Team VK" sizes="(min-width: 56rem) 50vw, 100vw" /></figure>
</section>
<!-- Leistungen -->
<section class="a-serv" id="leistungen" aria-labelledby="a-serv-h">
<div class="a-serv__band">
<div class="fig"><Pic src={img.salonInnen4} alt="" sizes="100vw" /></div>
<h2 id="a-serv-h">LEISTUNGEN</h2>
</div>
<div class="wrap">
<div class="a-cards">
{focus.map((s) => (
<a class="card" href={s.href} data-rv>
<div class="fig"><Pic src={s.img} alt={s.alt} sizes="(min-width: 48rem) 30vw, 100vw" widths={[400, 600, 800]} pos="top" /></div>
<h3>{s.title}<em>{s.sub}</em></h3>
<p>{s.text}</p>
<div class="card__foot"><span class="card__price">{s.price}*</span><span class="more">Mehr dazu</span></div>
</a>
))}
</div>
</div>
</section>
<!-- Ergebnisse -->
<section class="a-sec a-sec--white" aria-labelledby="a-cases-h">
<div class="wrap">
<div class="a-head"><span class="lbl">Vorher, nachher</span><h2 id="a-cases-h">ERGEBNISSE</h2><p>Echte Kundinnen aus dem Salon. Damit Sie vorab sehen, was bei Haaren wie Ihren möglich ist.</p></div>
<div class="a-cases">
{cases.map((c) => (
<article class="a-case" data-rv>
<div class="a-case__pics">
<figure class="fig"><Pic src={c.v} alt={c.altV} sizes="(min-width: 56rem) 15vw, 50vw" widths={[300, 450, 675]} /><span class="tag2">Vorher</span></figure>
<figure class="fig"><Pic src={c.n} alt={c.altN} sizes="(min-width: 56rem) 15vw, 50vw" widths={[300, 450, 675]} /><span class="tag2">Nachher</span></figure>
</div>
<span class="lbl">{c.where}</span>
<h3>{c.title}</h3>
<p>{c.note}</p>
</article>
))}
</div>
</div>
</section>
<!-- Team -->
<section class="a-sec" id="team" aria-labelledby="a-team-h">
<div class="wrap a-team">
<div class="a-team__pic"><figure class="fig" data-clip><Pic src={img.vero} alt="Veronika Sprangel, Friseurmeisterin und Inhaberin" sizes="(min-width: 56rem) 40vw, 100vw" widths={[400, 600, 800]} /></figure></div>
<div class="a-team__txt">
<span class="lbl" data-rv>Lernen Sie uns kennen</span>
<h2 id="a-team-h" data-rv>TEAM</h2>
<p data-rv>Erst das Gespräch, dann die Farbe. Veronika Sprangel berät bei Braut, Farbe und Great Lengths selbst und sorgt dafür, dass jede neue Kundin bei der Stylistin landet, die zu ihrem Wunsch passt.</p>
<div class="a-stats" data-rv>
<div><b>{salon.sinceYear}</b><span>als Meisterbetrieb eröffnet</span></div>
<div><b>{salon.teamSize}</b><span>Menschen im Team</span></div>
<div><b>{salon.google.rating}</b><span>{salon.google.count} Google-Bewertungen</span></div>
</div>
<div class="row" data-rv><a class="btn btn--line" href="/team">Zum Team</a></div>
</div>
</div>
</section>
<!-- Bewertungen -->
<section class="a-sec a-sec--white" aria-labelledby="a-rev-h">
<div class="wrap">
<div class="a-head"><span class="lbl">{salon.google.rating} von 5 Sternen bei Google</span><h2 id="a-rev-h">STIMMEN</h2></div>
<div class="a-revs">
{reviews.map((r) => (
<figure class="a-rev" data-rv>
<blockquote><q>{r.q}</q></blockquote>
<figcaption><span class="stars" aria-label="5 von 5 Sternen">★★★★★</span> Google-Bewertung · {r.topic}</figcaption>
</figure>
))}
</div>
<p class="a-note">Ausgewählte Bewertungen aus unserem <a class="link" href={salon.google.url} rel="noopener">Google-Profil</a> ({salon.google.count} Bewertungen, Stand {salon.google.asOf}). Wir haben nicht geprüft, ob die Verfasserinnen bei uns Kundin waren.</p>
</div>
</section>
<!-- Neu bei uns -->
<section class="a-sec" aria-labelledby="a-new-h">
<div class="wrap">
<div class="a-head"><span class="lbl">Wir sind oft ausgebucht</span><h2 id="a-new-h">NEU BEI UNS?</h2><p>Damit Ihr Termin trotzdem gut wird, beginnen große Termine bei uns mit einem Gespräch.</p></div>
<div class="a-steps">
{steps.map((s) => <div class="a-step" data-rv><h3>{s.t}</h3><p>{s.d}</p></div>)}
</div>
<div class="a-center"><a class="btn" href="/anfrage">Anfrage stellen</a><a class="btn btn--line" href={salon.phoneHref}>Schnitt? Einfach anrufen</a></div>
</div>
</section>
<!-- Preise -->
<section class="a-sec a-sec--white" id="preise" aria-labelledby="a-pr-h">
<div class="wrap">
<div class="a-head"><span class="lbl">Für jeden Tag</span><h2 id="a-pr-h">PREISE</h2></div>
<div class="a-prices">
{daily.map((p) => (
<a class="a-price" href={p.href} data-rv>
<span class="a-price__row"><span class="a-price__t">{p.title}</span><span class="a-price__dots" aria-hidden="true"></span><span class="a-price__p">{p.price}*</span></span>
<span class="a-price__d">{p.detail}</span>
</a>
))}
</div>
<div class="a-center"><a class="more" href="/leistungen-preise">Alle Preise ansehen</a></div>
<p class="a-note">* Richtwerte. Den genauen Preis besprechen wir in der Beratung.</p>
</div>
</section>
</main>
<!-- Kontakt -->
<footer class="a-ct" id="kontakt">
<div class="wrap a-ct__in">
<div class="gap-5" data-rv>
<h2>Erzählen Sie uns, was Sie <em>vorhaben.</em></h2>
<div class="row"><a class="btn btn--white" href="/anfrage">Anfrage stellen</a><a class="btn btn--ghost-w" href={salon.phoneHref}>{salon.phoneDisplay}</a></div>
</div>
<div class="a-ct__hours" data-rv>
<p class="lbl mt-2">Öffnungszeiten</p>
{hours.filter((h) => h.day !== 'Sonntag').map((h) => <div class={h.open ? undefined : 'is-closed'}><span>{h.day}</span><span>{fmtHours(h)}</span></div>)}
</div>
<div class="a-ct__addr" data-rv>
<p class="lbl mt-2">Adresse</p>
<span>{salon.legalName}<br />{salon.street}<br />{salon.zip} {salon.city}</span>
<a href={`mailto:${salon.email}`}>{salon.email}</a>
<a href={salon.whatsappHref} rel="noopener">WhatsApp</a>
<a href={salon.routeUrl} rel="noopener">Route planen</a>
</div>
</div>
<div class="a-ct__base"><div class="wrap"><span>© 2026 {salon.name} · <a href={salon.instagram} rel="noopener">Instagram</a></span><span><a href="/impressum">Impressum</a> · <a href="/datenschutz">Datenschutz</a></span></div></div>
</footer>
</Variant>
+163
View File
@@ -0,0 +1,163 @@
---
import Variant from '../layouts/Variant.astro';
import Pic from '../components/Pic.astro';
import { Image } from 'astro:assets';
import logo from '../assets/logo/logo.png';
import { salon, waits, reviews, hours, fmtHours } from '../data/site';
import { img, focus, daily, cases, steps } from '../data/home';
---
<Variant
title="Entwurf B · Friseur-Team VK in Tostedt"
description="Entwurf B (Bögen) der neuen Startseite vom Friseur-Team VK in Tostedt."
variant="b"
fonts={['pinyon-script.woff2', 'syne-var.woff2', 'albert-sans-var.woff2']}
>
<p class="b-top">Neu: Ihre Stempelkarte gibt es jetzt auch im Handy. <a href="/kundenkarte">Mehr erfahren</a></p>
<header class="b-hd">
<div class="wrap b-hd__in">
<details class="b-menu">
<summary aria-label="Menü öffnen"><span class="burger" aria-hidden="true"><span></span><span></span><span></span></span><span>Menü</span></summary>
<nav class="b-menu__panel" aria-label="Hauptmenü">
<a href="/brautservice">Braut</a>
<a href="/balayage-farbe">Balayage & Farbe</a>
<a href="/haarverlaengerung">Great Lengths</a>
<a href="/barber">Barber</a>
<a href="/leistungen-preise">Preise</a>
<a href="/team">Team</a>
<a href="/neue-kundinnen">Neu bei uns</a>
<a href="/kontakt">Kontakt</a>
</nav>
</details>
<a class="b-hd__logo" href="/entwurf-b" aria-label="Friseur-Team VK, Start"><Image src={logo} height={44} densities={[1, 2]} format="webp" alt="Friseur-Team VK" loading="eager" /></a>
<div class="b-hd__right">
<a class="b-hd__phone" href={salon.phoneHref}>{salon.phoneDisplay}</a>
<a class="pill" href="/anfrage">Termin</a>
</div>
</div>
</header>
<main id="inhalt" tabindex="-1">
<!-- Hero -->
<section class="b-hero" aria-labelledby="b-h1">
<h1 id="b-h1" class="script"><span class="sr">Schön und glücklich. Friseur-Team VK in Tostedt.</span><span aria-hidden="true">Schön &amp; glücklich</span></h1>
<p class="b-hero__sub">Ihr Meisterbetrieb in Tostedt für Braut, Balayage und Great Lengths. Und für den Schnitt zwischendurch.</p>
<div class="b-hero__ctas"><a class="pill pill--fill" href="/anfrage">Termin anfragen</a><a class="pill" href="/neue-kundinnen">Neu bei uns?</a></div>
<div class="b-wait" aria-label="Wartezeiten für neue Kundinnen">
{waits.items.map((w) => <span class="b-chip"><b>{w.label}</b> {w.value}</span>)}
</div>
<figure class="fig b-arc" data-clip><Pic src={img.salonInnen1} alt="Der helle Salon in der Kastanienallee mit blauen Wandpaneelen" sizes="100vw" eager /></figure>
</section>
<!-- Leistungen -->
<section class="b-sec" id="leistungen" aria-labelledby="b-serv-h">
<div class="b-head"><span class="script" aria-hidden="true">Leistungen</span><h2 id="b-serv-h">Wir kümmern uns um Ihr Haar</h2></div>
<div class="wrap">
<div class="b-arches">
{focus.map((s) => (
<a class="arch-card" href={s.href} data-rv>
<div class="fig"><Pic src={s.img} alt={s.alt} sizes="(min-width: 48rem) 30vw, 100vw" widths={[400, 600, 800]} pos="top" /></div>
<h3>{s.title}</h3>
<p>{s.text}</p>
<span class="arch-card__price">{s.price}*</span>
</a>
))}
</div>
<div class="b-center"><a class="pill" href="/leistungen-preise">Alle Leistungen und Preise</a></div>
</div>
</section>
<!-- Team -->
<section class="wrap b-team" id="team" aria-labelledby="b-team-h">
<div class="b-team__box" data-rv>
<h2 id="b-team-h">Ihre Haarexpertinnen</h2>
<p>Friseurmeisterin Veronika Sprangel hat den Salon im {salon.since} eröffnet. Heute sind wir zu acht: Friseurinnen und Friseure, ein Barber, ein Auszubildender und Dennis Sprangel in der Organisation.</p>
<p>Für Farbe und Pflege nutzen wir Paul Mitchell und Redken, für Haarverlängerungen Great Lengths. Wir tragen die Auszeichnung Master of Great Lengths.</p>
<div class="b-stats">
<div><b>{salon.sinceYear}</b><span>gegründet</span></div>
<div><b>{salon.google.rating}</b><span>{salon.google.count} Google-Bewertungen</span></div>
</div>
<div class="row mt-4"><a class="pill" href="/team">Zum Team</a></div>
</div>
<figure class="fig b-team__pic" data-clip><Pic src={img.teamFoto} alt="Das Team vom Friseur-Team VK" sizes="(min-width: 56rem) 50vw, 100vw" /></figure>
</section>
<!-- Ergebnisse -->
<section class="b-sec" aria-labelledby="b-cases-h">
<div class="b-head"><span class="script" aria-hidden="true">Vorher, nachher</span><h2 id="b-cases-h">Echte Ergebnisse aus dem Salon</h2><p>Damit Sie vorab sehen, was bei Haaren wie Ihren möglich ist.</p></div>
<div class="wrap">
<div class="b-cases">
{cases.map((c) => (
<article class="b-case" data-rv>
<div class="b-case__pics">
<figure class="fig"><Pic src={c.v} alt={c.altV} sizes="(min-width: 56rem) 15vw, 50vw" widths={[300, 450, 675]} /><span class="b-tag">Vorher</span></figure>
<figure class="fig"><Pic src={c.n} alt={c.altN} sizes="(min-width: 56rem) 15vw, 50vw" widths={[300, 450, 675]} /><span class="b-tag">Nachher</span></figure>
</div>
<h3>{c.title}</h3>
<p>{c.note}</p>
</article>
))}
</div>
</div>
</section>
<!-- Bewertungen -->
<section class="b-sec" aria-labelledby="b-rev-h">
<div class="b-head"><span class="script" aria-hidden="true">Stimmen</span><h2 id="b-rev-h">{salon.google.rating} Sterne bei Google</h2></div>
<div class="wrap">
<div class="b-revs">
{reviews.map((r) => (
<figure class="b-rev" data-rv>
<blockquote><q>{r.q}</q></blockquote>
<figcaption><span class="stars" aria-label="5 von 5 Sternen">★★★★★</span> Google-Bewertung · {r.topic}</figcaption>
</figure>
))}
</div>
<p class="b-note">Ausgewählte Bewertungen aus unserem <a class="link" href={salon.google.url} rel="noopener">Google-Profil</a> ({salon.google.count} Bewertungen, Stand {salon.google.asOf}). Wir haben nicht geprüft, ob die Verfasserinnen bei uns Kundin waren.</p>
</div>
</section>
<!-- Neu bei uns -->
<section class="b-sec" aria-labelledby="b-new-h">
<div class="b-head"><span class="script" aria-hidden="true">Neu bei uns?</span><h2 id="b-new-h">So kommen Sie zu Ihrem Termin</h2><p>Wir sind oft ausgebucht. Damit Ihr Termin trotzdem gut wird, beginnen große Termine mit einem Gespräch.</p></div>
<div class="wrap">
<div class="b-steps">
{steps.map((s, i) => <div class="b-step" data-rv><span class="script" aria-hidden="true">{i + 1}</span><h3>{s.t}</h3><p>{s.d}</p></div>)}
</div>
<div class="b-center"><a class="pill pill--fill" href="/anfrage">Anfrage stellen</a><a class="pill" href={salon.phoneHref}>Schnitt? Einfach anrufen</a></div>
</div>
</section>
<!-- Preise -->
<section class="b-sec" id="preise" aria-labelledby="b-pr-h">
<div class="b-head"><span class="script" aria-hidden="true">Preise</span><h2 id="b-pr-h">Für jeden Tag</h2></div>
<div class="wrap">
<div class="b-prices">
{daily.map((p) => (
<a class="b-price" href={p.href} data-rv>
<span class="b-price__t">{p.title}</span><span class="b-price__p">{p.price}*</span>
<span class="b-price__d">{p.detail}</span>
</a>
))}
<p class="b-note">* Richtwerte. Den genauen Preis besprechen wir in der Beratung. <a class="link" href="/leistungen-preise">Alle Preise</a></p>
</div>
</div>
</section>
</main>
<!-- Kontakt -->
<footer class="b-ct" id="kontakt">
<div class="b-ct__in">
<span class="script" aria-hidden="true">Bis bald</span>
<h2 class="sr">Kontakt</h2>
<p>{salon.street}, {salon.zip} {salon.city}. Für Braut, Balayage und Great Lengths starten wir mit einer kurzen Anfrage und rufen zurück.</p>
<div class="row"><a class="pill pill--white" href="/anfrage">Anfrage stellen</a><a class="pill pill--ghost-w" href={salon.phoneHref}>{salon.phoneDisplay}</a><a class="pill pill--ghost-w" href={salon.whatsappHref} rel="noopener">WhatsApp</a></div>
<div class="b-ct__hours">
{hours.filter((h) => h.day !== 'Sonntag').map((h) => <div><b>{h.day}</b><span>{fmtHours(h)}</span></div>)}
</div>
<div class="b-ct__base">
<span>© 2026 {salon.legalName}</span>
<div><a href={salon.instagram} rel="noopener">Instagram</a><a href={`mailto:${salon.email}`}>{salon.email}</a><a href="/impressum">Impressum</a><a href="/datenschutz">Datenschutz</a></div>
</div>
</div>
</footer>
</Variant>
+335
View File
@@ -0,0 +1,335 @@
/* ==========================================================================
Startseiten-Entwürfe A (Editorial) und B (Bögen)
Alles ist auf body.v-a bzw. body.v-b begrenzt, damit es die übrigen Seiten nicht berührt.
Lesbarkeit zuerst: Fließtext 17–18 px in dunkler Tinte, Kontrast ≥ 7:1,
Großbuchstaben nur für kurze Labels, Schreibschrift nur als große Zierde.
========================================================================== */
@font-face { font-family: 'Newsreader'; font-style: normal; font-weight: 400 600; font-display: swap; src: url('/fonts/newsreader-var.woff2') format('woff2'); }
@font-face { font-family: 'Newsreader'; font-style: italic; font-weight: 400 500; font-display: swap; src: url('/fonts/newsreader-italic-var.woff2') format('woff2'); }
@font-face { font-family: 'Syne'; font-style: normal; font-weight: 500 700; font-display: swap; src: url('/fonts/syne-var.woff2') format('woff2'); }
body.v-a, body.v-b { padding: 0 0 calc(var(--bar-h) + env(safe-area-inset-bottom)); font-size: 1.0625rem; line-height: 1.65; }
@media (min-width: 56rem) { body.v-a, body.v-b { padding: 0; } }
.vnote { margin: 0; padding: 0.45rem 1rem; text-align: center; font-size: 0.8125rem; background: oklch(23% 0.05 258); color: oklch(92% 0.01 245); }
.vnote a { color: #fff; border-bottom: 1px solid currentColor; }
.v-a .wrap, .v-b .wrap { max-width: 82.5rem; margin-inline: auto; padding-inline: clamp(1.25rem, 0.6rem + 3vw, 3rem); }
.v-a .fig img, .v-b .fig img { transition: transform 1.2s var(--ease); }
.v-a a.fig:hover img, .v-b a.fig:hover img, .v-a .card:hover .fig img, .v-b .arch-card:hover .fig img { transform: scale(1.035); }
/* ======================= A · EDITORIAL ======================= */
.v-a {
--a-bg: oklch(97.4% 0.008 245);
--a-ink: oklch(24% 0.05 258); /* Fließtext, 13:1 */
--a-ink-2: oklch(40% 0.04 258); /* leise, 8:1 */
--a-blue: oklch(44% 0.13 252); /* Überschriften, Akzent, 7:1 auf hell */
--a-navy: oklch(25% 0.08 258);
--a-line: oklch(24% 0.05 258 / 0.16);
--a-mist: oklch(92% 0.03 245);
--a-serif: 'Newsreader', 'Iowan Old Style', Georgia, serif;
background: var(--a-bg); color: var(--a-ink);
}
.v-a h1, .v-a h2, .v-a h3 { font-family: var(--a-serif); font-weight: 400; letter-spacing: -0.01em; text-wrap: balance; color: var(--a-blue); }
.v-a .lbl { font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--a-blue); }
.v-a .muted { color: var(--a-ink-2); }
.v-a .btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; min-height: 3rem; padding: 0.8rem 1.5rem; background: var(--a-blue); color: #fff; font-size: 0.875rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; border: 1px solid var(--a-blue); transition: background-color var(--t-med), color var(--t-med), border-color var(--t-med); }
.v-a .btn:hover { background: var(--a-navy); border-color: var(--a-navy); color: #fff; }
.v-a .btn--line { background: transparent; color: var(--a-blue); }
.v-a .btn--line:hover { background: var(--a-blue); color: #fff; }
.v-a .btn--white { background: #fff; color: var(--a-navy); border-color: #fff; }
.v-a .btn--white:hover { background: var(--a-blue); border-color: var(--a-blue); color: #fff; }
.v-a .btn--ghost-w { background: transparent; color: #fff; border-color: oklch(100% 0 0 / 0.6); }
.v-a .btn--ghost-w:hover { background: #fff; color: var(--a-navy); }
.v-a .more { font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--a-blue); border-bottom: 1px solid currentColor; padding-bottom: 2px; }
/* Kopf */
.a-hd { position: sticky; top: 0; z-index: 40; background: oklch(97.4% 0.008 245 / 0.94); backdrop-filter: blur(10px); border-bottom: 1px solid var(--a-line); }
.a-hd__in { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; padding-block: 0.9rem; }
.a-hd__logo img { height: 2.75rem; width: auto; }
.a-hd__nav { display: none; gap: 1.75rem; font-size: 0.875rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; }
.a-hd__nav a:hover { color: var(--a-blue); }
.a-hd__right { display: flex; align-items: center; gap: 1.25rem; }
.a-hd__phone { display: none; font-weight: 600; font-size: 0.9375rem; }
.a-hd .btn { min-height: 2.75rem; padding: 0.6rem 1.1rem; font-size: 0.8125rem; }
@media (min-width: 64rem) { .a-hd__nav, .a-hd__phone { display: flex; } }
/* Wartezeiten */
.a-wait { border-bottom: 1px solid var(--a-line); font-size: 0.9375rem; }
.a-wait__in { display: flex; flex-wrap: wrap; gap: 0.35rem 2rem; padding-block: 0.7rem; align-items: baseline; }
.a-wait b { font-weight: 600; }
.a-wait .lbl { font-size: 0.75rem; }
/* Hero */
.a-hero { padding-block: clamp(2.5rem, 1.5rem + 4vw, 5rem) clamp(4rem, 3rem + 5vw, 7.5rem); }
.a-hero__kicker { text-align: center; font-size: 0.9375rem; letter-spacing: 0.24em; }
.a-hero h1 { margin-top: 0.4rem; text-align: center; font-size: clamp(4.5rem, 1rem + 15vw, 14rem); line-height: 0.86; letter-spacing: -0.025em; overflow: hidden; }
.a-hero h1 span { display: block; }
@media (prefers-reduced-motion: no-preference) { .a-hero h1 span { animation: rise 1.2s var(--ease) both 0.15s; } }
.a-hero__grid { display: grid; gap: 2rem; margin-top: clamp(1.5rem, 1rem + 2vw, 2.5rem); align-items: center; }
.a-hero__small { display: none; }
.a-hero__main { aspect-ratio: 4 / 5; box-shadow: 0 30px 60px -30px oklch(25% 0.08 258 / 0.45); }
.a-hero__text { display: grid; gap: 1.25rem; max-width: 26rem; }
.a-hero__claim { font-family: var(--a-serif); font-size: clamp(1.625rem, 1.3rem + 1vw, 2.125rem); line-height: 1.2; color: var(--a-blue); }
.a-hero__proof { display: grid; gap: 0.35rem; font-size: 0.9375rem; color: var(--a-ink-2); border-top: 1px solid var(--a-line); padding-top: 1rem; }
.a-hero__proof b { color: var(--a-ink); font-weight: 600; }
@media (min-width: 56rem) {
.a-hero__grid { grid-template-columns: 1fr 1.15fr 1fr; gap: clamp(2rem, 4vw, 3.5rem); margin-top: clamp(-4.5rem, -5vw, -2rem); }
.a-hero__small { display: block; justify-self: end; width: min(100%, 16rem); aspect-ratio: 1; margin-top: 3rem; }
}
/* Über uns */
.a-about { display: grid; align-items: center; }
.a-about__box { background: var(--a-blue); color: #fff; padding: clamp(3rem, 2rem + 5vw, 6.5rem) clamp(1.5rem, 1rem + 5vw, 6rem); display: grid; gap: 1.4rem; position: relative; z-index: 1; }
.a-about__box h2 { color: #fff; font-size: clamp(2rem, 1.5rem + 1.8vw, 3rem); line-height: 1.12; }
.a-about__box p { max-width: 32rem; font-size: 1.0625rem; line-height: 1.7; color: oklch(97% 0.01 245); }
.a-about__box .more { color: #fff; justify-self: start; }
.a-about__pic { min-height: 24rem; height: 100%; }
@media (min-width: 56rem) { .a-about { grid-template-columns: 1fr 1fr; } .a-about__box { margin-block: 3rem; } .a-about__pic { min-height: 34rem; } }
/* Leistungen */
.a-serv { margin-top: clamp(4rem, 3rem + 5vw, 7rem); }
.a-serv__band { position: relative; height: clamp(17rem, 10rem + 22vw, 28rem); overflow: hidden; background: var(--a-navy); }
.a-serv__band .fig { position: absolute; inset: 0; background: none; }
.a-serv__band .fig img { filter: grayscale(1) contrast(1.05); opacity: 0.5; }
.a-serv__band::after { content: ''; position: absolute; inset: 0; background: oklch(25% 0.08 258 / 0.4); }
.a-serv__band h2 { position: relative; z-index: 1; text-align: center; padding-top: clamp(3rem, 2rem + 4vw, 6rem); color: #fff; font-size: clamp(3.5rem, 1rem + 9vw, 9rem); line-height: 1; letter-spacing: 0.01em; }
.a-cards { position: relative; z-index: 2; display: grid; gap: 2.5rem; margin-top: clamp(-9rem, -10vw, -5rem); max-width: 72rem; margin-inline: auto; }
.card { display: grid; gap: 1rem; align-content: start; color: inherit; }
.card .fig { aspect-ratio: 4 / 5; }
.card h3 { font-size: 1.875rem; line-height: 1.1; padding-bottom: 0.6rem; border-bottom: 1px solid var(--a-blue); }
.card h3 em { display: block; font-size: 1.125rem; color: var(--a-ink-2); margin-top: 0.2rem; }
.card p { font-size: 1rem; line-height: 1.65; }
.card__foot { display: flex; justify-content: space-between; align-items: baseline; gap: 0.75rem; flex-wrap: wrap; }
.card__price { font-weight: 600; }
.card:hover { color: inherit; }
.card:hover h3 { color: var(--a-navy); }
@media (min-width: 48rem) { .a-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(1.5rem, 3vw, 2.5rem); } }
/* Abschnitts-Überschrift */
.a-head { text-align: center; display: grid; gap: 0.75rem; justify-items: center; margin-bottom: clamp(2.5rem, 2rem + 2vw, 4rem); }
.a-head h2 { font-size: clamp(2.75rem, 1.8rem + 3.6vw, 5rem); line-height: 1; letter-spacing: 0.005em; }
.a-head p { max-width: 36rem; color: var(--a-ink-2); }
.a-sec { padding-block: clamp(4.5rem, 3rem + 6vw, 8rem); }
.a-sec--white { background: #fff; }
/* Ergebnisse */
.a-cases { display: grid; gap: 3rem; }
.a-case { display: grid; gap: 1rem; }
.a-case__pics { display: grid; grid-template-columns: 1fr 1fr; gap: 0.4rem; }
.a-case__pics .fig { aspect-ratio: 3 / 4; }
.a-case h3 { font-size: 1.75rem; }
.a-case p { font-size: 0.9375rem; color: var(--a-ink-2); }
.tag2 { position: absolute; left: 0.5rem; top: 0.5rem; background: #fff; color: var(--a-ink); font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; padding: 0.3rem 0.5rem; }
@media (min-width: 56rem) { .a-cases { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2rem; } }
/* Bewertungen */
.a-revs { display: grid; gap: 2rem; }
.a-rev { display: grid; gap: 1rem; padding-top: 1.5rem; border-top: 1px solid var(--a-blue); }
.a-rev q { font-family: var(--a-serif); font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem); line-height: 1.25; color: var(--a-ink); quotes: '„' '“'; }
.a-rev figcaption { font-size: 0.875rem; color: var(--a-ink-2); }
.a-rev .stars { color: var(--a-blue); }
.a-note { font-size: 0.875rem; color: var(--a-ink-2); max-width: 46rem; margin: 2rem auto 0; text-align: center; }
@media (min-width: 56rem) { .a-revs { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 3rem; } }
/* Team */
.a-team { display: grid; gap: clamp(2.5rem, 2rem + 4vw, 5.5rem); align-items: center; }
.a-team__pic { position: relative; padding: 0 0 2.5rem 2.5rem; }
.a-team__pic::before { content: ''; position: absolute; left: 0; bottom: 0; width: 60%; height: 60%; background: var(--a-mist); }
.a-team__pic .fig { aspect-ratio: 4 / 5; }
.a-team__txt { display: grid; gap: 1.25rem; }
.a-team__txt h2 { font-size: clamp(4.5rem, 2rem + 8vw, 9.5rem); line-height: 0.85; }
.a-team__txt > p { max-width: 32rem; font-size: 1.125rem; }
.a-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; border-top: 1px solid var(--a-line); padding-top: 1.4rem; max-width: 32rem; }
.a-stats div { display: grid; gap: 0.2rem; }
.a-stats b { font-family: var(--a-serif); font-weight: 400; font-size: clamp(2.25rem, 1.8rem + 1.4vw, 3rem); line-height: 1; color: var(--a-blue); }
.a-stats span { font-size: 0.875rem; color: var(--a-ink-2); line-height: 1.35; }
@media (min-width: 56rem) { .a-team { grid-template-columns: 1fr 1fr; } }
/* Schritte */
.a-steps { display: grid; gap: 2rem; counter-reset: s; }
.a-step { display: grid; gap: 0.6rem; padding-top: 1.25rem; border-top: 1px solid var(--a-line); }
.a-step::before { counter-increment: s; content: counter(s, decimal-leading-zero); font-family: var(--a-serif); font-size: 2.5rem; line-height: 1; color: var(--a-blue); }
.a-step h3 { font-size: 1.5rem; color: var(--a-ink); }
.a-step p { color: var(--a-ink-2); }
@media (min-width: 56rem) { .a-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 3rem; } }
.a-center { display: flex; justify-content: center; gap: 0.75rem; flex-wrap: wrap; margin-top: 2.5rem; }
/* Preise */
.a-prices { display: grid; gap: 0 4rem; max-width: 68rem; margin-inline: auto; }
.a-price { display: grid; gap: 0.3rem; padding-block: 1.4rem; border-bottom: 1px solid var(--a-line); color: inherit; }
.a-price__row { display: flex; align-items: baseline; gap: 0.9rem; }
.a-price__t { font-family: var(--a-serif); font-size: 1.625rem; line-height: 1.2; }
.a-price__dots { flex: 1; border-bottom: 1px dotted oklch(24% 0.05 258 / 0.4); transform: translateY(-0.3rem); }
.a-price__p { font-weight: 600; color: var(--a-blue); white-space: nowrap; }
.a-price__d { font-size: 0.9375rem; color: var(--a-ink-2); }
a.a-price:hover .a-price__t { color: var(--a-blue); }
@media (min-width: 56rem) { .a-prices { grid-template-columns: 1fr 1fr; } }
/* Kontakt */
.a-ct { background: var(--a-navy); color: #fff; }
.a-ct__in { display: grid; gap: clamp(2.5rem, 2rem + 3vw, 4.5rem); padding-block: clamp(4.5rem, 3rem + 5vw, 7.5rem); }
.a-ct h2 { color: #fff; font-size: clamp(2.5rem, 1.8rem + 2.6vw, 3.75rem); line-height: 1.05; }
.a-ct .lbl { color: oklch(86% 0.06 240); }
.a-ct__hours div { display: flex; justify-content: space-between; padding-block: 0.6rem; border-bottom: 1px solid oklch(100% 0 0 / 0.15); font-size: 1rem; }
.a-ct__hours .is-closed { color: oklch(80% 0.02 245); }
.a-ct__addr { display: grid; gap: 0.6rem; font-size: 1rem; line-height: 1.6; }
.a-ct__addr a { border-bottom: 1px solid oklch(100% 0 0 / 0.5); justify-self: start; width: max-content; }
.a-ct__addr a:hover, .a-ct a:hover { color: oklch(88% 0.05 240); }
.a-ct__base { border-top: 1px solid oklch(100% 0 0 / 0.15); }
.a-ct__base .wrap { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; padding-block: 1.3rem; font-size: 0.875rem; color: oklch(86% 0.02 245); }
@media (min-width: 56rem) { .a-ct__in { grid-template-columns: 1.2fr 1fr 1fr; } }
/* ======================= B · BÖGEN ======================= */
.v-b {
--b-bg: oklch(98.8% 0.004 245);
--b-ink: oklch(25% 0.06 258); /* Fließtext, 12:1 */
--b-ink-2: oklch(42% 0.05 258);
--b-blue: oklch(45% 0.15 255); /* Akzent, Überschriften */
--b-deep: oklch(28% 0.1 258);
--b-wash: oklch(95.5% 0.025 245);
--b-line: oklch(25% 0.06 258 / 0.15);
--b-sans: 'Syne', 'Avenir Next', 'Helvetica Neue', sans-serif;
background: var(--b-bg); color: var(--b-ink);
}
.v-b h1, .v-b h2, .v-b h3 { font-family: var(--b-sans); font-weight: 700; letter-spacing: -0.012em; text-wrap: balance; color: var(--b-blue); }
.v-b .script { font-family: var(--f-script); font-weight: 400; letter-spacing: 0; color: var(--b-blue); }
.v-b .muted { color: var(--b-ink-2); }
.v-b .pill { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; min-height: 3rem; padding: 0.7rem 1.6rem; border: 1.5px solid var(--b-blue); border-radius: 999px; color: var(--b-blue); font-weight: 600; font-size: 1rem; transition: background-color var(--t-med), color var(--t-med), border-color var(--t-med); }
.v-b .pill:hover { background: var(--b-blue); color: #fff; }
.v-b .pill--fill { background: var(--b-blue); color: #fff; }
.v-b .pill--fill:hover { background: var(--b-deep); border-color: var(--b-deep); }
.v-b .pill--white { background: #fff; border-color: #fff; color: var(--b-blue); }
.v-b .pill--white:hover { background: var(--b-deep); border-color: var(--b-deep); color: #fff; }
.v-b .pill--ghost-w { border-color: #fff; color: #fff; }
.v-b .pill--ghost-w:hover { background: #fff; color: var(--b-blue); }
.b-top { background: var(--b-blue); color: #fff; text-align: center; padding: 0.55rem 1rem; font-size: 0.9375rem; }
.b-top a { color: #fff; border-bottom: 1px solid currentColor; }
.b-top a:hover { color: #fff; }
/* Kopf */
.b-hd { position: sticky; top: 0; z-index: 40; background: oklch(98.8% 0.004 245 / 0.94); backdrop-filter: blur(10px); }
.b-hd__in { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 1rem; padding-block: 0.75rem; }
.b-hd__logo img { height: 2.75rem; width: auto; }
.b-hd__right { justify-self: end; display: flex; align-items: center; gap: 1rem; }
.b-hd__phone { display: none; font-weight: 600; }
.b-hd .pill { min-height: 2.6rem; padding: 0.45rem 1.2rem; font-size: 0.9375rem; }
@media (min-width: 48rem) { .b-hd__phone { display: inline; } }
.b-menu { justify-self: start; }
.b-menu summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 0.6rem; min-height: var(--tap); font-weight: 600; }
.b-menu summary::-webkit-details-marker { display: none; }
.b-menu .burger { display: grid; gap: 5px; }
.b-menu .burger span { width: 1.6rem; height: 2px; background: currentColor; display: block; }
.b-menu__panel { position: absolute; left: 0; right: 0; top: 100%; background: var(--b-bg); border-top: 1px solid var(--b-line); padding: 1.5rem clamp(1.25rem, 3vw, 3rem) 2rem; display: flex; flex-wrap: wrap; gap: 0.6rem 2.25rem; box-shadow: 0 30px 40px -30px oklch(25% 0.06 258 / 0.3); }
.b-menu__panel a { font-family: var(--b-sans); font-weight: 600; font-size: 1.5rem; }
/* Hero */
.b-hero { text-align: center; padding-top: clamp(1.5rem, 1rem + 3vw, 3.5rem); }
.b-hero h1 { font-family: var(--f-script); font-weight: 400; font-size: clamp(4.25rem, 1.5rem + 11vw, 12rem); line-height: 1.02; letter-spacing: 0; padding-inline: 1rem; }
.b-hero__sub { margin: 0.75rem auto 0; max-width: 34rem; font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem); line-height: 1.55; padding-inline: 1.25rem; }
.b-hero__ctas { display: flex; justify-content: center; gap: 0.75rem; flex-wrap: wrap; margin-top: 1.5rem; padding-inline: 1.25rem; }
.b-arc { margin: clamp(2.25rem, 1.5rem + 3vw, 4rem) auto 0; width: min(100%, 87.5rem); aspect-ratio: 2 / 1; max-height: 40rem; border-radius: 50% 50% 0 0 / 100% 100% 0 0; }
@media (max-width: 40rem) { .b-arc { aspect-ratio: 4 / 3; border-radius: 50% 50% 0 0 / 60% 60% 0 0; } }
@media (prefers-reduced-motion: no-preference) { .b-hero h1 { animation: b-in 1.3s var(--ease) both 0.1s; } @keyframes b-in { from { opacity: 0; transform: translateY(1.5rem) scale(0.98); } } }
/* Wartezeiten */
.b-wait { display: flex; justify-content: center; flex-wrap: wrap; gap: 0.6rem; padding: 1.5rem 1.25rem 0; }
.b-chip { display: inline-flex; gap: 0.45rem; align-items: baseline; padding: 0.5rem 1rem; border-radius: 999px; background: var(--b-wash); font-size: 0.9375rem; }
.b-chip b { font-weight: 600; color: var(--b-blue); }
/* Abschnitte */
.b-sec { padding-block: clamp(4.5rem, 3rem + 6vw, 8.5rem); }
.b-head { text-align: center; display: grid; gap: 0.6rem; justify-items: center; margin-bottom: clamp(2.5rem, 2rem + 3vw, 4.5rem); padding-inline: 1.25rem; }
.b-head .script { font-size: clamp(2.75rem, 2rem + 2.5vw, 4rem); line-height: 1; }
.b-head h2 { font-size: clamp(2rem, 1.4rem + 2.6vw, 3.5rem); line-height: 1.08; max-width: 40rem; }
.b-head p { max-width: 36rem; color: var(--b-ink-2); }
/* Bogen-Karten */
.b-arches { display: grid; gap: 2.5rem; max-width: 64rem; margin-inline: auto; }
.arch-card { display: grid; gap: 1rem; justify-items: center; text-align: center; color: inherit; }
.arch-card .fig { width: 100%; aspect-ratio: 4 / 5; border-radius: 999px 999px 0 0; }
.arch-card h3 { font-size: 1.625rem; line-height: 1.15; }
.arch-card p { font-size: 1rem; color: var(--b-ink-2); max-width: 20rem; }
.arch-card__price { font-weight: 600; color: var(--b-ink); }
.arch-card:hover { color: inherit; }
.arch-card:hover h3 { color: var(--b-deep); }
@media (min-width: 48rem) {
.b-arches { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(1.5rem, 3vw, 2.5rem); align-items: start; }
.arch-card:nth-child(2) { margin-top: 4rem; }
}
.b-center { display: flex; justify-content: center; flex-wrap: wrap; gap: 0.75rem; margin-top: clamp(2.5rem, 2rem + 2vw, 4rem); }
/* Ergebnisse */
.b-cases { display: grid; gap: 3rem; max-width: 72rem; margin-inline: auto; }
.b-case { display: grid; gap: 1rem; text-align: center; }
.b-case__pics { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
.b-case__pics .fig { aspect-ratio: 3 / 4; border-radius: 999px 999px 0 0; }
.b-case__pics .fig:last-child { border-radius: 999px 999px 0 0; }
.b-case h3 { font-size: 1.375rem; }
.b-case p { font-size: 0.9375rem; color: var(--b-ink-2); }
.b-tag { position: absolute; left: 50%; bottom: 0.6rem; transform: translateX(-50%); background: #fff; color: var(--b-ink); font-size: 0.8125rem; font-weight: 600; padding: 0.25rem 0.7rem; border-radius: 999px; }
@media (min-width: 56rem) { .b-cases { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2.5rem; } }
/* Team */
.b-team { display: grid; }
.b-team__box { background: var(--b-wash); padding: clamp(2.5rem, 2rem + 3vw, 4.5rem); display: grid; gap: 1.25rem; align-content: start; }
.b-team__box h2 { font-size: clamp(1.75rem, 1.4rem + 1.2vw, 2.375rem); }
.b-team__box p { max-width: 30rem; font-size: 1.0625rem; line-height: 1.7; }
.b-stats { display: flex; gap: 2rem; flex-wrap: wrap; margin-top: 1rem; }
.b-stats div { display: grid; }
.b-stats b { font-family: var(--b-sans); font-weight: 700; font-size: 2.75rem; line-height: 1; color: var(--b-blue); }
.b-stats span { font-size: 0.875rem; font-weight: 500; color: var(--b-ink-2); }
.b-team__pic { min-height: 24rem; }
@media (min-width: 56rem) { .b-team { grid-template-columns: 1fr 1fr; } .b-team__pic { min-height: 34rem; } }
/* Bewertungen */
.b-revs { display: grid; gap: 1.25rem; max-width: 72rem; margin-inline: auto; }
.b-rev { background: #fff; border: 1px solid var(--b-line); border-radius: 2rem 2rem 0.5rem 0.5rem; padding: 2rem 1.75rem; display: grid; gap: 1rem; align-content: space-between; }
.b-rev q { font-family: var(--b-sans); font-weight: 600; font-size: 1.375rem; line-height: 1.3; color: var(--b-ink); quotes: '„' '“'; }
.b-rev figcaption { font-size: 0.875rem; color: var(--b-ink-2); display: flex; gap: 0.5rem; align-items: center; }
.b-rev .stars { color: var(--b-blue); }
.b-note { font-size: 0.875rem; color: var(--b-ink-2); max-width: 46rem; margin: 1.75rem auto 0; text-align: center; padding-inline: 1.25rem; }
@media (min-width: 56rem) { .b-revs { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
/* Schritte */
.b-steps { display: grid; gap: 1.25rem; max-width: 72rem; margin-inline: auto; }
.b-step { background: var(--b-wash); border-radius: 999px 999px 1rem 1rem; padding: 3.25rem 1.75rem 2rem; text-align: center; display: grid; gap: 0.6rem; justify-items: center; }
.b-step .script { font-size: 3.25rem; line-height: 0.8; }
.b-step h3 { font-size: 1.3125rem; }
.b-step p { font-size: 1rem; color: var(--b-ink-2); max-width: 20rem; }
@media (min-width: 56rem) { .b-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
/* Preise */
.b-prices { max-width: 56rem; margin-inline: auto; }
.b-price { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.3rem 1.25rem; padding-block: 1.3rem; border-bottom: 1px solid var(--b-line); color: inherit; }
.b-price__t { font-family: var(--b-sans); font-weight: 600; font-size: 1.3125rem; }
.b-price__p { font-weight: 600; color: var(--b-blue); white-space: nowrap; }
.b-price__d { font-size: 0.9375rem; color: var(--b-ink-2); grid-column: 1 / -1; }
a.b-price:hover .b-price__t { color: var(--b-blue); }
/* Kontakt-Bogen */
.b-ct { padding: 0 clamp(0.75rem, 2vw, 2.5rem) clamp(0.75rem, 2vw, 2.5rem); }
.b-ct__in { max-width: 87.5rem; margin: 0 auto; background: var(--b-blue); color: #fff; border-radius: clamp(9rem, 22vw, 21rem) clamp(9rem, 22vw, 21rem) 0 0; padding: clamp(6rem, 4rem + 8vw, 10rem) clamp(1.25rem, 1rem + 4vw, 4.5rem) clamp(2.5rem, 2rem + 3vw, 4.5rem); display: grid; justify-items: center; text-align: center; gap: 1.5rem; }
.b-ct .script { color: #fff; font-size: clamp(4rem, 2.5rem + 5vw, 6.5rem); line-height: 1; }
.b-ct p { max-width: 34rem; font-size: 1.125rem; line-height: 1.6; color: oklch(98% 0.01 245); }
.b-ct__hours { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.8rem 1.5rem; width: 100%; max-width: 40rem; text-align: left; margin-top: 1rem; font-size: 1rem; }
.b-ct__hours div { display: grid; border-top: 1px solid oklch(100% 0 0 / 0.35); padding-top: 0.5rem; }
.b-ct__hours b { font-weight: 600; }
@media (min-width: 40rem) { .b-ct__hours { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.b-ct__base { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 1rem; width: 100%; margin-top: 2.5rem; padding-top: 1.3rem; border-top: 1px solid oklch(100% 0 0 / 0.3); font-size: 0.875rem; }
.b-ct__base a { color: #fff; }
.b-ct__base a:hover { color: oklch(90% 0.04 240); }
.b-ct__base div { display: flex; gap: 1.25rem; flex-wrap: wrap; }
/* Entwürfe-Übersicht */
.ent { padding-block: 3rem 5rem; }
.ent__grid { display: grid; gap: 2rem; margin-top: 2.5rem; }
@media (min-width: 56rem) { .ent__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.ent__item { display: grid; gap: 0.8rem; align-content: start; color: inherit; }
.ent__item .fig { aspect-ratio: 4 / 3; border: 1px solid var(--line); }
.ent__item h2 { font-size: var(--t-h3); }
.ent__item:hover h2 { color: var(--blue); }
.v-a .mbar a, .v-b .mbar a { font-family: var(--f-text); font-size: 1rem; font-weight: 600; }
.v-b .mbar a + a { background: var(--b-blue); }
.v-a .mbar a + a { background: var(--a-blue); }