feat: single-page redesign with text-only hero, team section, services grid, mobile nav
- Replace component-based index with unified inline page - Add text-only hero with warm editorial typography - Add team section with avatars and bios - Convert services to responsive grid layout - Add contact labels and editorial images - Implement mobile hamburger navigation with slide-in panel - Polish typography, spacing, and accessibility - Remove design variant pages (1-6)
This commit is contained in:
@@ -1,17 +1,850 @@
|
||||
---
|
||||
import Layout from "@/layouts/main.astro"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { siteContent } from "@/content/site-content"
|
||||
|
||||
const navItems = [
|
||||
{ label: "Leistungen", href: "#leistungen" },
|
||||
{ label: "Team", href: "#team" },
|
||||
{ label: "Zeiten", href: "#zeiten" },
|
||||
{ label: "Kontakt", href: "#kontakt" },
|
||||
]
|
||||
---
|
||||
|
||||
<Layout>
|
||||
<div class="flex min-h-svh p-6">
|
||||
<div class="flex max-w-md min-w-0 flex-col gap-4 text-sm leading-loose">
|
||||
<div>
|
||||
<h1 class="font-medium">Project ready!</h1>
|
||||
<p>You may now add components and start building.</p>
|
||||
<p>We've already added the button component for you.</p>
|
||||
<Button client:load className="mt-2">Button</Button>
|
||||
</div>
|
||||
<Layout title="Haarscharf Crimmitschau | Friseur in der Annenstraße">
|
||||
<a class="skip-link" href="#top">Zum Inhalt springen</a>
|
||||
|
||||
<header class="site-header">
|
||||
<a class="brand-lockup" href="#top" aria-label="Haarscharf Startseite">
|
||||
<span class="brand-mark">H</span>
|
||||
<span>
|
||||
<span class="block font-heading text-lg leading-none">{siteContent.business.name}</span>
|
||||
<span class="brand-descriptor">{siteContent.business.descriptor}</span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav aria-label="Hauptnavigation" class="hidden items-center gap-1 md:flex">
|
||||
{navItems.map((item) => <a class="nav-link" href={item.href}>{item.label}</a>)}
|
||||
</nav>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<button
|
||||
class="mobile-nav-toggle md:hidden"
|
||||
aria-expanded="false"
|
||||
aria-controls="mobile-nav"
|
||||
aria-label="Menü öffnen"
|
||||
type="button"
|
||||
>
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" aria-hidden="true">
|
||||
<line x1="3" y1="5" x2="17" y2="5" />
|
||||
<line x1="3" y1="10" x2="17" y2="10" />
|
||||
<line x1="3" y1="15" x2="17" y2="15" />
|
||||
</svg>
|
||||
</button>
|
||||
<a class="button-link button-link--compact" href={siteContent.cta.primary.href}>
|
||||
Anrufen
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div id="mobile-nav" class="mobile-nav" aria-label="Mobile Navigation" role="dialog" aria-modal="true">
|
||||
<div class="mobile-nav-backdrop"></div>
|
||||
<div class="mobile-nav-panel">
|
||||
<button class="mobile-nav-close" aria-label="Menü schließen" type="button">
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" aria-hidden="true">
|
||||
<line x1="4" y1="4" x2="16" y2="16" />
|
||||
<line x1="16" y1="4" x2="4" y2="16" />
|
||||
</svg>
|
||||
</button>
|
||||
<ul class="mobile-nav-list">
|
||||
{navItems.map((item) => (
|
||||
<li><a class="mobile-nav-link" href={item.href}>{item.label}</a></li>
|
||||
))}
|
||||
</ul>
|
||||
<a class="mobile-nav-phone" href={siteContent.business.phone.href}>
|
||||
<span class="contact-label">Telefon</span>
|
||||
<strong>{siteContent.business.phone.display}</strong>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main>
|
||||
<!-- Hero: text-only, centered, warm typography -->
|
||||
<section id="top" class="hero-section hero-section--text-only" aria-labelledby="hero-title">
|
||||
<div class="hero-copy hero-copy--centered">
|
||||
<p class="eyebrow">{siteContent.hero.eyebrow}</p>
|
||||
<h1 id="hero-title">{siteContent.hero.title}</h1>
|
||||
<p class="hero-intro">{siteContent.hero.intro}</p>
|
||||
|
||||
<div class="hero-actions hero-actions--centered">
|
||||
<a class="button-link" href={siteContent.cta.primary.href}>
|
||||
{siteContent.cta.primary.label}
|
||||
</a>
|
||||
<a class="button-link button-link--secondary" href={siteContent.cta.secondary.href} target="_blank" rel="noreferrer">
|
||||
{siteContent.cta.secondary.label}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<dl class="salon-meta salon-meta--centered" aria-label="Saloninformationen">
|
||||
<div>
|
||||
<dt>Adresse</dt>
|
||||
<dd>{siteContent.business.address.display}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Telefon</dt>
|
||||
<dd>{siteContent.business.phone.display}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>{siteContent.hours[0].day}</dt>
|
||||
<dd>{siteContent.hours[0].time}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Salon Promise -->
|
||||
<section class="section-shell promise-section cut-line" aria-labelledby="promise-title">
|
||||
<div class="promise-intro">
|
||||
<p class="eyebrow">Salonversprechen</p>
|
||||
<h2 id="promise-title">Haare dürfen leicht aussehen, auch wenn dahinter Präzision steckt.</h2>
|
||||
</div>
|
||||
|
||||
<div class="promise-grid">
|
||||
{
|
||||
siteContent.promise.map((item, index) => (
|
||||
<article class="promise-card">
|
||||
<span class="index-label">{String(index + 1).padStart(2, "0")}</span>
|
||||
<h3>{item.title}</h3>
|
||||
<p>{item.text}</p>
|
||||
</article>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Editorial image break: salon atmosphere -->
|
||||
<figure class="editorial-image">
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1562322140-8baeececf3df?auto=format&fit=crop&w=1600&q=80"
|
||||
alt="Warm beleuchteter Salon-Innenraum mit Friseurstühlen und Spiegeln"
|
||||
width="1600"
|
||||
height="900"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
<figcaption>Atmosphäre im Salon</figcaption>
|
||||
</figure>
|
||||
|
||||
<!-- Services: Grid instead of list -->
|
||||
<section id="leistungen" class="section-shell services-section" aria-labelledby="services-title">
|
||||
<div class="section-heading section-heading--centered">
|
||||
<p class="eyebrow">Leistungen</p>
|
||||
<h2 id="services-title">Alles, was ein guter Salonbesuch braucht.</h2>
|
||||
<p>Die Auswahl bleibt bewusst klar. Details, Wünsche und Termine werden am besten direkt telefonisch besprochen.</p>
|
||||
</div>
|
||||
|
||||
<div class="service-grid">
|
||||
{
|
||||
siteContent.services.map((service, index) => (
|
||||
<article class="service-card">
|
||||
<span class="service-index">{String(index + 1).padStart(2, "0")}</span>
|
||||
<h3>{service.title}</h3>
|
||||
<p>{service.text}</p>
|
||||
</article>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Team: adapted from /2.astro -->
|
||||
<section id="team" class="section-shell team-section cut-line" aria-labelledby="team-title">
|
||||
<div class="section-heading section-heading--centered">
|
||||
<p class="eyebrow">Unser Team</p>
|
||||
<h2 id="team-title">Die Menschen hinter den Scheren.</h2>
|
||||
</div>
|
||||
|
||||
<figure class="team-image">
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1711274093746-b588a17d2716?auto=format&fit=crop&w=1200&q=82"
|
||||
alt="Eine Friseurin bei der Arbeit mit Schere"
|
||||
width="1200"
|
||||
height="600"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
<figcaption>Handwerk mit Präzision</figcaption>
|
||||
</figure>
|
||||
|
||||
<div class="team-grid">
|
||||
{
|
||||
siteContent.team.map((member) => (
|
||||
<article class="team-card">
|
||||
<div class="team-avatar">
|
||||
<span>{member.initials}</span>
|
||||
</div>
|
||||
<h3>{member.name}</h3>
|
||||
<p class="team-role">{member.role}</p>
|
||||
<p>{member.bio}</p>
|
||||
</article>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Hours -->
|
||||
<section id="zeiten" class="section-shell hours-section cut-line" aria-labelledby="hours-title">
|
||||
<div class="section-heading">
|
||||
<p class="eyebrow">Öffnungszeiten</p>
|
||||
<h2 id="hours-title">Planbar von Montag bis Samstag.</h2>
|
||||
<p>Für Termine bitte kurz anrufen. So lässt sich direkt klären, wann genug Zeit für Beratung, Schnitt oder Farbe frei ist.</p>
|
||||
</div>
|
||||
|
||||
<div class="hours-panel">
|
||||
{
|
||||
siteContent.hours.map((entry) => (
|
||||
<div class="hours-row">
|
||||
<span>{entry.day}</span>
|
||||
<time>{entry.time}</time>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Trust -->
|
||||
<section class="trust-band" aria-labelledby="trust-title">
|
||||
<div>
|
||||
<p class="eyebrow">Lokales Vertrauen</p>
|
||||
<h2 id="trust-title">{siteContent.reviewSummary.rating}</h2>
|
||||
</div>
|
||||
<p class="trust-copy">
|
||||
<strong>{siteContent.reviewSummary.count}</strong>
|
||||
<span>{siteContent.reviewSummary.text}</span>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- Contact: with labels adapted from /2.astro -->
|
||||
<section id="kontakt" class="section-shell contact-section" aria-labelledby="contact-title">
|
||||
<div class="section-heading">
|
||||
<p class="eyebrow">Kontakt & Anfahrt</p>
|
||||
<h2 id="contact-title">Mitten in Crimmitschau.</h2>
|
||||
<p class="contact-note">Der schnellste Weg zum Termin bleibt ein kurzer Anruf im Salon.</p>
|
||||
</div>
|
||||
|
||||
<div class="contact-layout">
|
||||
<div class="contact-left">
|
||||
<address class="contact-address">
|
||||
<span>{siteContent.business.name}</span>
|
||||
<span>{siteContent.business.address.street}</span>
|
||||
<span>{siteContent.business.address.postalCode} {siteContent.business.address.city}</span>
|
||||
</address>
|
||||
|
||||
<figure class="contact-image">
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1522337360788-8b13dee7a37e?auto=format&fit=crop&w=800&q=80"
|
||||
alt="Friseur-Werkzeuge: Schere und Kamm auf einer Marmor-Arbeitsfläche"
|
||||
width="800"
|
||||
height="600"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
<figcaption>Detail & Sorgfalt</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<div class="contact-actions contact-card">
|
||||
<a class="contact-line" href={siteContent.business.phone.href}>
|
||||
<span class="contact-label">Telefon</span>
|
||||
<strong>{siteContent.business.phone.display}</strong>
|
||||
</a>
|
||||
<a class="contact-line" href={`mailto:${siteContent.business.email}`}>
|
||||
<span class="contact-label">E-Mail</span>
|
||||
<strong>{siteContent.business.email}</strong>
|
||||
</a>
|
||||
<a class="button-link" href={siteContent.cta.secondary.href} target="_blank" rel="noreferrer">
|
||||
Route über Google Maps
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Final CTA -->
|
||||
<section class="final-cta" aria-labelledby="final-cta-title">
|
||||
<p class="eyebrow">Bereit für den nächsten Schnitt?</p>
|
||||
<h2 id="final-cta-title">Kurz anrufen, Termin abstimmen, vorbeikommen.</h2>
|
||||
<div class="final-cta-actions">
|
||||
<a class="button-link button-link--light" href={siteContent.cta.primary.href}>
|
||||
{siteContent.business.phone.display}
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<script is:inline>
|
||||
(function() {
|
||||
const toggle = document.querySelector('.mobile-nav-toggle');
|
||||
const nav = document.querySelector('#mobile-nav');
|
||||
if (!toggle || !nav) return;
|
||||
|
||||
const closeBtn = nav.querySelector('.mobile-nav-close');
|
||||
const backdrop = nav.querySelector('.mobile-nav-backdrop');
|
||||
const links = nav.querySelectorAll('a');
|
||||
|
||||
function open() {
|
||||
nav.classList.add('is-open');
|
||||
toggle.setAttribute('aria-expanded', 'true');
|
||||
document.body.style.overflow = 'hidden';
|
||||
if (links.length) {
|
||||
setTimeout(() => links[0].focus(), 0);
|
||||
}
|
||||
document.addEventListener('keydown', onKeyDown);
|
||||
}
|
||||
|
||||
function close() {
|
||||
nav.classList.remove('is-open');
|
||||
toggle.setAttribute('aria-expanded', 'false');
|
||||
document.body.style.overflow = '';
|
||||
document.removeEventListener('keydown', onKeyDown);
|
||||
toggle.focus();
|
||||
}
|
||||
|
||||
function onKeyDown(e) {
|
||||
if (e.key === 'Escape') close();
|
||||
}
|
||||
|
||||
toggle.addEventListener('click', open);
|
||||
if (closeBtn) closeBtn.addEventListener('click', close);
|
||||
if (backdrop) backdrop.addEventListener('click', close);
|
||||
links.forEach(link => link.addEventListener('click', close));
|
||||
})();
|
||||
</script>
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
/* ─── Hero: text-only, centered ─── */
|
||||
.hero-section--text-only {
|
||||
position: relative;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
min-height: 92svh;
|
||||
overflow: hidden;
|
||||
padding: clamp(7rem, 14vw, 10rem) clamp(1rem, 5vw, 5rem) clamp(3.75rem, 7vw, 6rem);
|
||||
background:
|
||||
linear-gradient(180deg, color-mix(in oklch, var(--surface-warm) 55%, transparent) 0%, var(--background) 40%);
|
||||
color: var(--foreground);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hero-section--text-only::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
radial-gradient(ellipse 80% 50% at 50% 120%, color-mix(in oklch, var(--secondary) 25%, transparent) 0%, transparent 70%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.hero-copy--centered {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
align-self: end;
|
||||
max-width: 58rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.hero-copy--centered .eyebrow {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.hero-copy--centered h1 {
|
||||
max-width: 18ch;
|
||||
margin: 1rem auto 1.4rem;
|
||||
font-family: var(--font-heading);
|
||||
font-size: clamp(3.4rem, 9vw, 7.5rem);
|
||||
font-weight: 600;
|
||||
line-height: 1.0;
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.hero-copy--centered .hero-intro {
|
||||
max-width: 42ch;
|
||||
margin: 0 auto;
|
||||
color: var(--muted-foreground);
|
||||
font-size: clamp(1.15rem, 2vw, 1.45rem);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.hero-actions--centered {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 0.75rem;
|
||||
padding-top: 1.35rem;
|
||||
}
|
||||
|
||||
.hero-actions--centered .button-link--secondary {
|
||||
border-color: var(--foreground);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.hero-actions--centered .button-link--secondary:hover,
|
||||
.hero-actions--centered .button-link--secondary:focus-visible {
|
||||
background: var(--foreground);
|
||||
border-color: var(--foreground);
|
||||
color: var(--background);
|
||||
}
|
||||
|
||||
.salon-meta--centered {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 0;
|
||||
max-width: 50rem;
|
||||
margin: clamp(2.5rem, 5vw, 4rem) auto 0;
|
||||
border-top: 1px solid var(--hairline);
|
||||
border-bottom: 1px solid var(--hairline);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.salon-meta--centered div {
|
||||
display: grid;
|
||||
gap: 0.25rem;
|
||||
padding: 1rem clamp(0.8rem, 2vw, 1.2rem);
|
||||
}
|
||||
|
||||
.salon-meta--centered div + div {
|
||||
border-left: 1px solid var(--hairline);
|
||||
}
|
||||
|
||||
.salon-meta--centered dt {
|
||||
color: var(--muted-foreground);
|
||||
font-size: 0.72rem;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.salon-meta--centered dd {
|
||||
margin: 0;
|
||||
font-weight: 700;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
/* ─── Services: grid layout ─── */
|
||||
.service-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 0;
|
||||
margin-top: clamp(2rem, 4vw, 4rem);
|
||||
border-top: 1px solid oklch(0.62 0.042 49 / 45%);
|
||||
border-left: 1px solid oklch(0.62 0.042 49 / 45%);
|
||||
}
|
||||
|
||||
.service-card {
|
||||
display: grid;
|
||||
gap: 0.75rem;
|
||||
border-bottom: 1px solid oklch(0.62 0.042 49 / 45%);
|
||||
border-right: 1px solid oklch(0.62 0.042 49 / 45%);
|
||||
padding: clamp(1.5rem, 3vw, 2.5rem);
|
||||
transition: background-color 180ms ease;
|
||||
}
|
||||
|
||||
.service-card:hover {
|
||||
background: color-mix(in oklch, oklch(0.62 0.042 49 / 45%) 12%, transparent);
|
||||
}
|
||||
|
||||
.service-card .service-index {
|
||||
color: oklch(0.82 0.104 65);
|
||||
font-family: var(--font-heading);
|
||||
font-size: clamp(2rem, 4vw, 4rem);
|
||||
line-height: 0.85;
|
||||
}
|
||||
|
||||
.service-card h3 {
|
||||
font-family: var(--font-heading);
|
||||
font-size: clamp(1.3rem, 2vw, 1.65rem);
|
||||
line-height: 1.15;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.service-card p {
|
||||
color: oklch(0.84 0.019 83);
|
||||
line-height: 1.65;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ─── Team section ─── */
|
||||
.team-section {
|
||||
background: var(--surface-warm);
|
||||
}
|
||||
|
||||
.team-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
||||
gap: 0;
|
||||
margin-top: clamp(2rem, 4vw, 4rem);
|
||||
border-top: 1px solid var(--hairline);
|
||||
border-left: 1px solid var(--hairline);
|
||||
}
|
||||
|
||||
.team-card {
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
gap: 0.625rem;
|
||||
border-bottom: 1px solid var(--hairline);
|
||||
border-right: 1px solid var(--hairline);
|
||||
padding: clamp(2rem, 4vw, 3rem) clamp(1.5rem, 3vw, 2.5rem);
|
||||
text-align: center;
|
||||
transition: background-color 180ms ease;
|
||||
}
|
||||
|
||||
.team-card:hover {
|
||||
background: color-mix(in oklch, var(--background) 55%, transparent);
|
||||
}
|
||||
|
||||
.team-avatar {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
border-radius: 999px;
|
||||
background: var(--muted);
|
||||
font-family: var(--font-heading);
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: var(--muted-foreground);
|
||||
}
|
||||
|
||||
.team-card h3 {
|
||||
font-family: var(--font-heading);
|
||||
font-size: clamp(1.2rem, 1.8vw, 1.5rem);
|
||||
line-height: 1.2;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.team-role {
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.02em;
|
||||
text-transform: uppercase;
|
||||
color: var(--accent);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.team-card > p:last-child {
|
||||
color: var(--muted-foreground);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.65;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ─── Contact labels ─── */
|
||||
.contact-label {
|
||||
display: block;
|
||||
color: var(--muted-foreground);
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ─── Editorial image break ─── */
|
||||
.editorial-image {
|
||||
margin: 0;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: clamp(18rem, 45vw, 32rem);
|
||||
overflow: hidden;
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
.editorial-image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.editorial-image figcaption {
|
||||
position: absolute;
|
||||
right: clamp(1rem, 4vw, 3rem);
|
||||
bottom: 1rem;
|
||||
z-index: 2;
|
||||
padding: 0.25rem 0.6rem;
|
||||
border-radius: var(--radius-sm);
|
||||
background: oklch(0.1 0.02 28 / 55%);
|
||||
color: oklch(0.95 0.01 84);
|
||||
font-size: 0.78rem;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/* ─── Team image ─── */
|
||||
.team-image {
|
||||
margin: clamp(1.5rem, 3vw, 2.5rem) auto 0;
|
||||
max-width: var(--measure);
|
||||
position: relative;
|
||||
border-radius: var(--radius);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.team-image img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
aspect-ratio: 2 / 1;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.team-image figcaption {
|
||||
position: absolute;
|
||||
right: 1rem;
|
||||
bottom: 0.75rem;
|
||||
color: oklch(0.95 0.01 84);
|
||||
font-size: 0.78rem;
|
||||
text-shadow: 0 1px 3px oklch(0.1 0.02 28 / 50%);
|
||||
}
|
||||
|
||||
/* ─── Contact image ─── */
|
||||
.contact-left {
|
||||
display: grid;
|
||||
gap: clamp(1.5rem, 3vw, 2.5rem);
|
||||
align-content: start;
|
||||
}
|
||||
|
||||
.contact-image {
|
||||
margin: 0;
|
||||
border-radius: var(--radius);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.contact-image img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
aspect-ratio: 4 / 3;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.contact-image figcaption {
|
||||
color: var(--muted-foreground);
|
||||
font-size: 0.82rem;
|
||||
margin-top: 0.375rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* ─── Centered section headings ─── */
|
||||
.section-heading--centered {
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.section-heading--centered h2 {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.section-heading--centered p:not(.eyebrow) {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* ─── Mobile overrides ─── */
|
||||
@media (max-width: 820px) {
|
||||
.hero-section--text-only {
|
||||
min-height: 94svh;
|
||||
}
|
||||
|
||||
.hero-copy--centered h1 {
|
||||
font-size: clamp(2.6rem, 10vw, 4rem);
|
||||
}
|
||||
|
||||
.salon-meta--centered {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.salon-meta--centered div + div {
|
||||
border-top: 1px solid var(--hairline);
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.service-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.team-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
/* ─── Header override for light hero ─── */
|
||||
.site-header {
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.site-header .nav-link {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.site-header .nav-link:hover,
|
||||
.site-header .nav-link:focus-visible {
|
||||
background: color-mix(in oklch, var(--foreground) 10%, transparent);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.site-header .button-link--compact {
|
||||
background: color-mix(in oklch, var(--foreground) 10%, transparent);
|
||||
border-color: color-mix(in oklch, var(--foreground) 35%, transparent);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.site-header .button-link--compact:hover,
|
||||
.site-header .button-link--compact:focus-visible {
|
||||
background: var(--foreground);
|
||||
border-color: var(--foreground);
|
||||
color: var(--background);
|
||||
}
|
||||
|
||||
/* ─── Mobile navigation ─── */
|
||||
.mobile-nav-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
border: 1px solid color-mix(in oklch, var(--foreground) 25%, transparent);
|
||||
border-radius: var(--radius);
|
||||
background: color-mix(in oklch, var(--foreground) 8%, transparent);
|
||||
color: var(--foreground);
|
||||
cursor: pointer;
|
||||
transition: background-color 180ms ease, border-color 180ms ease;
|
||||
}
|
||||
|
||||
.mobile-nav-toggle:hover,
|
||||
.mobile-nav-toggle:focus-visible {
|
||||
background: color-mix(in oklch, var(--foreground) 16%, transparent);
|
||||
border-color: color-mix(in oklch, var(--foreground) 45%, transparent);
|
||||
}
|
||||
|
||||
@media (min-width: 821px) {
|
||||
.mobile-nav-toggle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-nav {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 60;
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.mobile-nav.is-open {
|
||||
pointer-events: auto;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.mobile-nav-backdrop {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: oklch(0.1 0.02 28 / 55%);
|
||||
opacity: 0;
|
||||
transition: opacity 200ms ease;
|
||||
}
|
||||
|
||||
.mobile-nav.is-open .mobile-nav-backdrop {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.mobile-nav-panel {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: min(20rem, 85vw);
|
||||
background: var(--background);
|
||||
color: var(--foreground);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
padding: 1.5rem;
|
||||
transform: translateX(100%);
|
||||
transition: transform 220ms ease;
|
||||
box-shadow: -4px 0 24px oklch(0.1 0.02 28 / 12%);
|
||||
}
|
||||
|
||||
.mobile-nav.is-open .mobile-nav-panel {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.mobile-nav-close {
|
||||
align-self: flex-end;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
border: 1px solid var(--hairline);
|
||||
border-radius: var(--radius);
|
||||
background: transparent;
|
||||
color: var(--foreground);
|
||||
cursor: pointer;
|
||||
transition: background-color 180ms ease;
|
||||
}
|
||||
|
||||
.mobile-nav-close:hover,
|
||||
.mobile-nav-close:focus-visible {
|
||||
background: var(--muted);
|
||||
}
|
||||
|
||||
.mobile-nav-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.mobile-nav-link {
|
||||
display: block;
|
||||
padding: 0.85rem 0.5rem;
|
||||
border-radius: var(--radius);
|
||||
color: var(--foreground);
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
transition: background-color 180ms ease;
|
||||
min-height: 44px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.mobile-nav-link:hover,
|
||||
.mobile-nav-link:focus-visible {
|
||||
background: var(--muted);
|
||||
}
|
||||
|
||||
.mobile-nav-phone {
|
||||
margin-top: auto;
|
||||
display: grid;
|
||||
gap: 0.3rem;
|
||||
padding: 1rem;
|
||||
border-radius: var(--radius);
|
||||
border: 1px solid var(--hairline);
|
||||
background: var(--card);
|
||||
color: var(--foreground);
|
||||
text-decoration: none;
|
||||
transition: background-color 180ms ease, border-color 180ms ease;
|
||||
}
|
||||
|
||||
.mobile-nav-phone:hover,
|
||||
.mobile-nav-phone:focus-visible {
|
||||
background: var(--muted);
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.mobile-nav-phone strong {
|
||||
font-size: 1.35rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user