style: Hero, Leistungen und Abschnittsrhythmus ueberarbeitet
- Hero: Schlagzeile zweizeilig direkt unter dem Masthead, Buchung im ersten Bildschirm; Termin, Ort und Preis als Cover-Line-Leiste - Leistungen: Inklusivleistungen in Bodoni ohne Linie unter jeder Zeile, Beispielablauf ruhiger, Hinweis unter statt neben der Ueberschrift - Unterkunft ohne Split-Header, Ueber ARTISTA kompakter - FAQ-Symbol gezeichnet statt Textzeichen, groesserer Abschnittsabstand - Header auf Mobil ohne doppeltes "Modelcamp 2027" Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
00c7118c10
commit
2ef92db9ed
5 files changed
+80
-74
No files matched your search
@@ -10,7 +10,7 @@ export function CampSection({ showDrafts }: { showDrafts: boolean }) {
|
||||
const { camp } = site;
|
||||
const showAudience = camp.audience.confirmed || showDrafts;
|
||||
return (
|
||||
<section id="camp" aria-labelledby="camp-title" className="py-20 md:py-32">
|
||||
<section id="camp" aria-labelledby="camp-title" className="py-24 md:py-36">
|
||||
<div className="container-edge grid gap-10 md:grid-cols-12">
|
||||
<div className="md:col-span-6 lg:col-span-5">
|
||||
<h2 id="camp-title" className="section-title">{camp.title}</h2>
|
||||
@@ -48,48 +48,44 @@ export function ServicesSection({ showDrafts }: { showDrafts: boolean }) {
|
||||
const { services } = site;
|
||||
const included = services.included.filter((s) => s.confirmed || showDrafts);
|
||||
return (
|
||||
<section id="leistungen" aria-labelledby="leistungen-title" className="on-dark bg-ink py-20 text-paper md:py-32">
|
||||
<section id="leistungen" aria-labelledby="leistungen-title" className="on-dark bg-ink py-24 text-paper md:py-36">
|
||||
<div className="container-edge">
|
||||
<h2 id="leistungen-title" className="section-title max-w-3xl">{services.title}</h2>
|
||||
<div className="mt-14 grid gap-12 md:grid-cols-2 md:gap-16">
|
||||
<div>
|
||||
<h3 className="border-b border-paper/30 pb-3 text-lg font-semibold">Im Preis enthalten</h3>
|
||||
<ul className="mt-2 divide-y divide-paper/15">
|
||||
<div className="grid gap-14 md:grid-cols-12 md:gap-10">
|
||||
<h2 id="leistungen-title" className="section-title md:col-span-5">{services.title}</h2>
|
||||
<div className="md:col-span-7 md:col-start-6 lg:col-span-6 lg:col-start-7">
|
||||
<h3 className="text-[0.9375rem] font-semibold text-paper/75">Im Preis enthalten</h3>
|
||||
<ul className="mt-5 space-y-4">
|
||||
{included.map((item) => (
|
||||
<li key={item.text} className="py-4 text-lg">
|
||||
<li key={item.text} className="display text-[1.625rem] leading-[1.2] md:text-[2rem]">
|
||||
{item.text}
|
||||
{!item.confirmed && <DraftFlag show />}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{!showDrafts && included.length < services.included.length && (
|
||||
<p className="mt-4 text-paper/75">Weitere Leistungen veröffentlichen wir, sobald sie verbindlich feststehen.</p>
|
||||
<p className="mt-6 text-paper/75">Weitere Leistungen veröffentlichen wir, sobald sie verbindlich feststehen.</p>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="border-b border-paper/30 pb-3 text-lg font-semibold">Nicht enthalten</h3>
|
||||
<ul className="mt-2 divide-y divide-paper/15">
|
||||
{services.excluded.map((item) => (
|
||||
<li key={item} className="py-4 text-lg text-paper/85">
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<h3 className="mt-14 text-[0.9375rem] font-semibold text-paper/75">Nicht enthalten</h3>
|
||||
<p className="mt-3 max-w-xl text-lg text-paper/85">{services.excluded.join(", ")}.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-20 border-t border-paper/30 pt-10">
|
||||
<div className="flex flex-wrap items-baseline justify-between gap-4">
|
||||
<h3 className="display text-3xl">So könnte ein Tag im Camp aussehen</h3>
|
||||
<p className="max-w-md text-[0.9375rem] text-paper/75">{services.exampleSchedule.note}</p>
|
||||
</div>
|
||||
{/* Nummeriert, weil es eine Abfolge ist — ausdruecklich als Beispiel gekennzeichnet. */}
|
||||
<ol className="mt-10 grid gap-8 md:grid-cols-3">
|
||||
<div className="mt-24 md:mt-32">
|
||||
<h3 className="display max-w-2xl text-[2rem] leading-[1.1] md:text-[2.5rem]">So könnte ein Tag im Camp aussehen</h3>
|
||||
<p className="mt-4 max-w-xl text-[0.9375rem] text-paper/75">{services.exampleSchedule.note}</p>
|
||||
{/* Nummeriert, weil es eine Abfolge ist; ausdruecklich als Beispiel gekennzeichnet. */}
|
||||
<ol className="mt-12 grid border-t border-paper/30 md:grid-cols-3">
|
||||
{services.exampleSchedule.steps.map((step, index) => (
|
||||
<li key={step.title} className="border-t border-paper/30 pt-5">
|
||||
<span className="display text-5xl text-paper/40">{index + 1}</span>
|
||||
<p className="mt-3 text-lg font-semibold">{step.title}</p>
|
||||
<p className="mt-2 text-paper/80">{step.text}</p>
|
||||
<li
|
||||
key={step.title}
|
||||
className={`border-b border-paper/15 py-7 md:border-b-0 md:py-9 ${index > 0 ? "md:border-l md:border-paper/15 md:pl-8" : "md:pr-8"}`}
|
||||
>
|
||||
<p className="flex items-baseline gap-4">
|
||||
<span className="text-sm tabular-nums text-paper/60">{index + 1}</span>
|
||||
<span className="display text-[1.75rem] italic">{step.title}</span>
|
||||
</p>
|
||||
<p className="mt-3 max-w-xs text-paper/80">{step.text}</p>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
@@ -102,12 +98,10 @@ export function ServicesSection({ showDrafts }: { showDrafts: boolean }) {
|
||||
export function AccommodationSection({ facts, showDrafts }: { facts: PublicCampFacts; showDrafts: boolean }) {
|
||||
const { accommodation } = site;
|
||||
return (
|
||||
<section id="unterkunft" aria-labelledby="unterkunft-title" className="py-20 md:py-32">
|
||||
<section id="unterkunft" aria-labelledby="unterkunft-title" className="py-24 md:py-36">
|
||||
<div className="container-edge">
|
||||
<div className="grid gap-8 md:grid-cols-12">
|
||||
<h2 id="unterkunft-title" className="section-title md:col-span-6">{accommodation.title}</h2>
|
||||
<p className="text-lg text-ink/85 md:col-span-5 md:col-start-8 md:self-end">{accommodation.lead}</p>
|
||||
</div>
|
||||
<h2 id="unterkunft-title" className="section-title">{accommodation.title}</h2>
|
||||
<p className="display mt-6 max-w-2xl text-[1.5rem] leading-[1.25] text-ink/85 md:text-[1.875rem]">{accommodation.lead}</p>
|
||||
<Gallery images={accommodation.images} showLabels={showDrafts} />
|
||||
<div className="mt-12 grid gap-8 md:grid-cols-12">
|
||||
<div className="md:col-span-7">
|
||||
|
||||
@@ -62,16 +62,17 @@ function faqs(facts: PublicCampFacts, pricing: PublicPricing): Faq[] {
|
||||
|
||||
export function FaqSection({ facts, pricing }: { facts: PublicCampFacts; pricing: PublicPricing }) {
|
||||
return (
|
||||
<section id="fragen" aria-labelledby="fragen-title" className="py-20 md:py-32">
|
||||
<section id="fragen" aria-labelledby="fragen-title" className="py-24 md:py-36">
|
||||
<div className="container-edge grid gap-10 md:grid-cols-12">
|
||||
<h2 id="fragen-title" className="section-title md:col-span-4">{site.faq.title}</h2>
|
||||
<div className="md:col-span-8">
|
||||
{faqs(facts, pricing).map((item) => (
|
||||
<details key={item.q} className="group border-b border-line py-1 first:border-t">
|
||||
<summary className="flex cursor-pointer list-none items-center justify-between gap-6 py-4 text-lg font-semibold [&::-webkit-details-marker]:hidden">
|
||||
<summary className="flex cursor-pointer list-none items-center justify-between gap-6 py-5 text-lg font-semibold transition-colors hover:text-rosso [&::-webkit-details-marker]:hidden">
|
||||
{item.q}
|
||||
<span aria-hidden className="text-2xl font-normal text-rosso transition-transform duration-200 group-open:rotate-45">
|
||||
+
|
||||
<span aria-hidden className="relative h-4 w-4 shrink-0 text-rosso transition-transform duration-300 ease-[var(--ease-editorial)] group-open:rotate-45">
|
||||
<span className="absolute inset-x-0 top-1/2 h-[1.5px] -translate-y-1/2 bg-current" />
|
||||
<span className="absolute inset-y-0 left-1/2 w-[1.5px] -translate-x-1/2 bg-current" />
|
||||
</span>
|
||||
</summary>
|
||||
<div className="max-w-2xl pb-5 text-ink/85">{item.a}</div>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { VideoSlot } from "../VideoSlot";
|
||||
export function TeachersSection({ showDrafts }: { showDrafts: boolean }) {
|
||||
const { teachers } = site;
|
||||
return (
|
||||
<section id="dozentinnen" aria-labelledby="dozentinnen-title" className="bg-paper py-20 md:py-32">
|
||||
<section id="dozentinnen" aria-labelledby="dozentinnen-title" className="bg-paper py-24 md:py-36">
|
||||
<div className="container-edge">
|
||||
<h2 id="dozentinnen-title" className="section-title">{teachers.title}</h2>
|
||||
<div className="mt-14 grid gap-16 md:grid-cols-12 md:gap-10">
|
||||
@@ -39,10 +39,10 @@ export function TeachersSection({ showDrafts }: { showDrafts: boolean }) {
|
||||
export function AboutSection({ showDrafts }: { showDrafts: boolean }) {
|
||||
const { about } = site;
|
||||
return (
|
||||
<section id="artista" aria-labelledby="artista-title" className="py-20 md:py-32">
|
||||
<div className="container-edge grid gap-8 md:grid-cols-12">
|
||||
<h2 id="artista-title" className="section-title md:col-span-5">{about.title}</h2>
|
||||
<div className="prose-body md:col-span-6 md:col-start-7">
|
||||
<section id="artista" aria-labelledby="artista-title" className="py-20 md:py-28">
|
||||
<div className="container-edge grid gap-6 border-t border-ink pt-10 md:grid-cols-12 md:gap-10 md:pt-14">
|
||||
<h2 id="artista-title" className="display text-[2.25rem] leading-none md:col-span-5 md:text-[3rem]">{about.title}</h2>
|
||||
<div className="prose-body text-lg md:col-span-6 md:col-start-7 md:pt-2">
|
||||
{about.paragraphs.length > 0 ? (
|
||||
about.paragraphs.map((p) => <p key={p}>{p}</p>)
|
||||
) : (
|
||||
|
||||
Reference in new issue
Block a user