Die Anfrageseite lief unter der Kopfleiste durch
Die Kopfleiste des Layouts ist fixed und schwebt: 56 px hoch, 16 px vom Rand, also rund 72 px hoch. Die Seite begann mit pt-14 — 56 px — und schob ihre Ueberschrift damit zwangslaeufig darunter. Sie haelt jetzt denselben Abstand wie die Startseite, und dieser Abstand ist der Grund fuer die Zahl, nicht Geschmack. Dabei zwei weitere Dinge behoben, die beim Nachsehen auffielen: die Seite brachte ein zweites <main> mit, obwohl das Layout bereits eines stellt (pro Dokument darf es nur eines geben), und ein `sm:col-span-2` am x-ui.input haette nichts getan — das Bauteil reicht mitgegebene Klassen an das INPUT weiter, nicht an seinen Rahmen, und der Rahmen ist das Rasterkind. Und die Seite steht jetzt in der Formensprache der Startseite statt daneben: derselbe warme Schimmer hinter der Ueberschrift, Haarlinien-Karten, lbl-Etiketten, gestaffelte Einblendungen, die echten Bauteile fuer Feld und Knopf statt handgeschriebener Klassen. Neu daneben: was nach dem Absenden passiert. Das ist die Frage, die jeder hat, der ein Formular vor sich sieht, und die ein Formular allein nicht beantwortet — bei Enterprise steht dort, dass Speicher, Nutzerzahl und Sicherung die Maschine ergeben, sonst die Antwort am selben Werktag. Versprochen wird nichts, was nicht schon vorher dastand. Am Bildschirm nachgesehen, nicht nur im Test: Ueberschrift frei unter der Kopfleiste, zwei Spalten ab lg, Formular und Spalte in einer Flucht. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>main
parent
413826f3d7
commit
c062776a5b
|
|
@ -5,110 +5,176 @@
|
|||
schon entschieden zu fragen — also steht hier ein Formular und keine zweite
|
||||
Verkaufsseite. Vorher zeigte der Knopf auf `mailto:`, was auf den meisten
|
||||
Geräten sichtbar gar nichts tut. Siehe App\Http\Controllers\ContactController.
|
||||
|
||||
Zum Aufbau, nach dem Umbau vom 1. August 2026:
|
||||
|
||||
Die Kopfleiste des Layouts ist `fixed` und schwebt (56 px hoch, 16 px vom
|
||||
Rand). Diese Seite begann mit `pt-14` — 56 px — und lief damit zwangsläufig
|
||||
darunter. Der Einstieg hält jetzt denselben Abstand wie die Startseite
|
||||
(`pt-32`, ab `lg` mehr), und dieser Abstand ist der Grund für die Zahl, nicht
|
||||
Geschmack.
|
||||
|
||||
Das zweite `<main>` ist weg: das Layout stellt bereits eines, und pro
|
||||
Dokument darf es nur eines geben.
|
||||
|
||||
Und die Seite steht jetzt in der Formensprache der Startseite statt daneben:
|
||||
ein Schimmer hinter der Überschrift, Haarlinien-Karten, `lbl`-Etiketten,
|
||||
gestaffelte Einblendungen. Rechts neben dem Formular steht, was danach
|
||||
passiert — die Frage, die jeder hat, der ein Formular vor sich sieht, und die
|
||||
ein Formular allein nicht beantwortet.
|
||||
--}}
|
||||
<x-layouts.site title="Anfrage — CluPilot Cloud" robots="noindex">
|
||||
|
||||
<main class="mx-auto w-full max-w-[860px] px-5 pt-14 pb-24 sm:px-8">
|
||||
<section class="relative overflow-hidden">
|
||||
{{-- Derselbe warme Schimmer wie über der Startseiten-Überschrift, aus dem
|
||||
Token gezeichnet statt aus einem literalen rgba(), das niemand
|
||||
nachzöge. Etwas schwächer und höher: hier steht ein Formular, kein
|
||||
Aufmacher. --}}
|
||||
<div class="pointer-events-none absolute -top-64 left-1/2 size-[620px] -translate-x-1/2 rounded-pill bg-accent opacity-[0.07] blur-3xl" aria-hidden="true"></div>
|
||||
|
||||
<header class="rv">
|
||||
<p class="lbl">Anfrage</p>
|
||||
<h1 class="mt-3 text-[clamp(2rem,4vw,2.8rem)] font-bold leading-[1.06] tracking-[-0.035em] text-ink">
|
||||
@if ($topic === 'enterprise')
|
||||
Eine eigene Maschine.
|
||||
@else
|
||||
Sprechen Sie uns an.
|
||||
@endif
|
||||
</h1>
|
||||
<p class="mt-4 max-w-[58ch] text-md leading-relaxed text-muted">
|
||||
@if ($topic === 'enterprise')
|
||||
Sagen Sie uns, wie viel Speicher Sie brauchen und wie viele Menschen damit
|
||||
arbeiten. Wir rechnen Ihnen einen Server durch, auf dem nur Ihre Cloud läuft
|
||||
— und melden uns am selben Werktag.
|
||||
@else
|
||||
Schreiben Sie uns, was Sie vorhaben. Wir antworten am selben Werktag,
|
||||
auf Deutsch, ohne Warteschleife.
|
||||
@endif
|
||||
</p>
|
||||
</header>
|
||||
<div class="relative mx-auto max-w-[1120px] px-5 pb-24 pt-32 sm:px-6 lg:pt-40">
|
||||
|
||||
@if ($sent)
|
||||
{{-- Der Bestätigungszustand ersetzt das Formular, statt darüber zu
|
||||
stehen: ein Formular, das nach dem Absenden weiter dasteht, lädt
|
||||
zum zweiten Absenden ein. --}}
|
||||
<div class="rv mt-10 rounded-xl border border-accent-border bg-accent-subtle p-7">
|
||||
<h2 class="text-lg font-bold tracking-[-0.02em] text-ink">Ihre Anfrage ist da.</h2>
|
||||
<p class="mt-2 max-w-[58ch] text-sm leading-relaxed text-body">
|
||||
Wir haben sie bekommen und melden uns am selben Werktag. Eine Kopie geht
|
||||
nicht automatisch an Sie — falls Sie etwas nachreichen möchten, antworten
|
||||
Sie einfach auf unsere Rückmeldung.
|
||||
<header class="rv mx-auto max-w-[60ch] text-center">
|
||||
<p class="lbl">Anfrage</p>
|
||||
<h1 class="mt-4 text-[clamp(2.2rem,4.6vw,3.2rem)] font-bold leading-[1.04] tracking-[-0.038em] text-ink">
|
||||
@if ($topic === 'enterprise')
|
||||
Eine eigene Maschine.
|
||||
@else
|
||||
Sprechen Sie uns an.
|
||||
@endif
|
||||
</h1>
|
||||
<p class="mx-auto mt-5 max-w-[56ch] text-lg leading-relaxed text-muted">
|
||||
@if ($topic === 'enterprise')
|
||||
Sagen Sie uns, wie viel Speicher Sie brauchen und wie viele Menschen damit
|
||||
arbeiten. Wir rechnen Ihnen einen Server durch, auf dem nur Ihre Cloud läuft
|
||||
— und melden uns am selben Werktag.
|
||||
@else
|
||||
Schreiben Sie uns, was Sie vorhaben. Wir antworten am selben Werktag,
|
||||
auf Deutsch, ohne Warteschleife.
|
||||
@endif
|
||||
</p>
|
||||
<a href="{{ route('home') }}" class="mt-5 inline-flex items-center gap-2 text-sm font-medium text-accent-text underline-offset-4 hover:underline">
|
||||
Zurück zur Übersicht
|
||||
</a>
|
||||
</div>
|
||||
@else
|
||||
<form method="POST" action="{{ route('contact.send') }}" class="rv mt-10">
|
||||
@csrf
|
||||
<input type="hidden" name="topic" value="{{ $topic }}">
|
||||
</header>
|
||||
|
||||
{{-- Der Honigtopf. Aus dem Lesefluss genommen statt display:none —
|
||||
ein Feld, das gar nicht existiert, füllt auch kein Roboter aus,
|
||||
und genau das Ausfüllen ist hier das Erkennungszeichen.
|
||||
aria-hidden und tabindex=-1, damit ein Screenreader und die
|
||||
Tabulatortaste es überspringen. --}}
|
||||
<div class="absolute left-[-9999px] top-auto h-px w-px overflow-hidden" aria-hidden="true">
|
||||
<label for="website">Website (bitte frei lassen)</label>
|
||||
<input type="text" id="website" name="website" tabindex="-1" autocomplete="off" value="">
|
||||
</div>
|
||||
|
||||
<div class="overflow-hidden rounded-xl border border-line bg-surface shadow-xs">
|
||||
@foreach ([
|
||||
['company', 'Firma', 'text', false, 'organization'],
|
||||
['name', 'Ihr Name', 'text', true, 'name'],
|
||||
['email', 'E-Mail', 'email', true, 'email'],
|
||||
['phone', 'Telefon (optional)', 'tel', false, 'tel'],
|
||||
] as [$field, $label, $type, $required, $autocomplete])
|
||||
<div class="border-b border-line px-6 py-5">
|
||||
<label for="{{ $field }}" class="block text-sm font-medium text-ink">
|
||||
{{ $label }}@if ($required)<span class="text-danger" aria-hidden="true"> *</span>@endif
|
||||
</label>
|
||||
<input type="{{ $type }}" id="{{ $field }}" name="{{ $field }}"
|
||||
value="{{ old($field) }}" autocomplete="{{ $autocomplete }}"
|
||||
@if ($required) required @endif
|
||||
class="mt-2 block w-full rounded border border-line bg-surface px-3 py-2 text-sm text-ink transition focus:border-accent-border focus:outline-none">
|
||||
@error($field)
|
||||
<p class="mt-1.5 text-xs text-danger">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
<div class="px-6 py-5">
|
||||
<label for="message" class="block text-sm font-medium text-ink">
|
||||
Ihre Nachricht<span class="text-danger" aria-hidden="true"> *</span>
|
||||
</label>
|
||||
<textarea id="message" name="message" rows="7" required
|
||||
placeholder="{{ $topic === 'enterprise'
|
||||
? 'Wie viel Speicher brauchen Sie, und wie viele Menschen arbeiten damit?'
|
||||
: 'Worum geht es?' }}"
|
||||
class="mt-2 block w-full rounded border border-line bg-surface px-3 py-2 text-sm leading-relaxed text-ink transition focus:border-accent-border focus:outline-none">{{ old('message') }}</textarea>
|
||||
@error('message')
|
||||
<p class="mt-1.5 text-xs text-danger">{{ $message }}</p>
|
||||
@enderror
|
||||
@if ($sent)
|
||||
{{-- Der Bestätigungszustand ersetzt das Formular, statt darüber zu
|
||||
stehen: ein Formular, das nach dem Absenden weiter dasteht, lädt
|
||||
zum zweiten Absenden ein. --}}
|
||||
<div class="rv d1 mx-auto mt-12 max-w-[640px] rounded-xl border border-accent-border bg-accent-subtle p-8 text-center shadow-xs">
|
||||
<span class="mx-auto grid size-11 place-items-center rounded-pill bg-surface shadow-xs">
|
||||
<x-ui.icon name="check" class="size-5 text-accent-text" />
|
||||
</span>
|
||||
<h2 class="mt-5 text-xl font-bold tracking-[-0.02em] text-ink">Ihre Anfrage ist da.</h2>
|
||||
<p class="mx-auto mt-3 max-w-[52ch] text-sm leading-relaxed text-body">
|
||||
Wir haben sie bekommen und melden uns am selben Werktag. Eine Kopie geht
|
||||
nicht automatisch an Sie — falls Sie etwas nachreichen möchten, antworten
|
||||
Sie einfach auf unsere Rückmeldung.
|
||||
</p>
|
||||
<div class="mt-7 flex flex-wrap justify-center gap-3">
|
||||
<x-ui.button href="{{ route('home') }}" variant="ink" size="md">Zurück zur Übersicht</x-ui.button>
|
||||
<x-ui.button href="{{ route('home') }}#pricing" variant="secondary" size="md">Preise ansehen</x-ui.button>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
{{-- Asymmetrisch: das Formular trägt die Seite, die Spalte daneben
|
||||
beantwortet die Frage, die ein Formular offen lässt — was
|
||||
passiert, nachdem ich auf Senden gedrückt habe. Auf dem Telefon
|
||||
steht sie darunter, weil dort zuerst das Feld zählt. --}}
|
||||
<div class="mt-14 grid items-start gap-8 lg:grid-cols-[minmax(0,1fr)_310px]">
|
||||
|
||||
<form method="POST" action="{{ route('contact.send') }}" class="rv d1">
|
||||
@csrf
|
||||
<input type="hidden" name="topic" value="{{ $topic }}">
|
||||
|
||||
{{-- Der Honigtopf. Aus dem Lesefluss genommen statt display:none —
|
||||
ein Feld, das gar nicht existiert, füllt auch kein Roboter aus,
|
||||
und genau das Ausfüllen ist hier das Erkennungszeichen.
|
||||
aria-hidden und tabindex=-1, damit ein Screenreader und die
|
||||
Tabulatortaste es überspringen. --}}
|
||||
<div class="absolute left-[-9999px] top-auto h-px w-px overflow-hidden" aria-hidden="true">
|
||||
<label for="website">Website (bitte frei lassen)</label>
|
||||
<input type="text" id="website" name="website" tabindex="-1" autocomplete="off" value="">
|
||||
</div>
|
||||
|
||||
<div class="rounded-xl border border-line bg-surface p-6 shadow-xs sm:p-7">
|
||||
{{-- Die Spaltenbreite gehört an ein eigenes Element, nicht
|
||||
an das Bauteil: x-ui.input reicht mitgegebene Klassen
|
||||
an das INPUT weiter, nicht an seinen Rahmen — ein
|
||||
`sm:col-span-2` am Bauteil landete also am Feld und
|
||||
täte im Raster nichts. --}}
|
||||
<div class="grid gap-5 sm:grid-cols-2">
|
||||
<div class="sm:col-span-2">
|
||||
<x-ui.input name="company" label="Firma" autocomplete="organization" :value="old('company')" />
|
||||
</div>
|
||||
<x-ui.input name="name" label="Ihr Name *" autocomplete="name" :value="old('name')" required />
|
||||
<x-ui.input name="email" label="E-Mail *" type="email" autocomplete="email" :value="old('email')" required />
|
||||
<div class="sm:col-span-2">
|
||||
<x-ui.input name="phone" label="Telefon (optional)" type="tel" autocomplete="tel" :value="old('phone')" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Kein eigenes Textfeld-Bauteil im Haus; die Klassen sind
|
||||
deshalb aus x-ui.input übernommen, damit die beiden
|
||||
Felder nicht nebeneinander unterschiedlich aussehen. --}}
|
||||
<div class="mt-5 space-y-1.5">
|
||||
<label for="message" class="block text-sm font-medium text-body">Ihre Nachricht *</label>
|
||||
<textarea id="message" name="message" rows="7" required
|
||||
@error('message') aria-invalid="true" aria-describedby="message-error" @enderror
|
||||
placeholder="{{ $topic === 'enterprise'
|
||||
? 'Wie viel Speicher brauchen Sie, und wie viele Menschen arbeiten damit?'
|
||||
: 'Worum geht es?' }}"
|
||||
class="block w-full rounded border bg-surface px-3.5 py-2.5 text-sm leading-relaxed text-ink placeholder:text-faint transition @error('message') border-danger bg-danger-bg @else border-line @enderror">{{ old('message') }}</textarea>
|
||||
@error('message')
|
||||
<p id="message-error" class="text-xs text-danger">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex flex-wrap items-center justify-between gap-4 border-t border-line pt-6">
|
||||
<p class="max-w-[42ch] text-xs leading-relaxed text-muted">
|
||||
Wir benutzen Ihre Angaben nur, um Ihre Anfrage zu beantworten.
|
||||
Näheres in der <a href="{{ route('legal.datenschutz') }}" class="underline underline-offset-2 transition-colors hover:text-body">Datenschutzerklärung</a>.
|
||||
</p>
|
||||
<x-ui.button type="submit" variant="ink" size="lg">Anfrage senden</x-ui.button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<aside class="rv d2 flex flex-col gap-6">
|
||||
<div class="rounded-xl border border-line bg-surface p-6 shadow-xs">
|
||||
<p class="lbl">Was danach passiert</p>
|
||||
<ol class="mt-4 flex flex-col gap-4">
|
||||
@foreach ([
|
||||
['Wir lesen mit.', 'Ihre Anfrage landet bei einem Menschen, nicht in einer Warteschlange.'],
|
||||
$topic === 'enterprise'
|
||||
? ['Wir rechnen durch.', 'Speicher, Nutzerzahl und Sicherung ergeben die Maschine — und den Preis.']
|
||||
: ['Wir antworten.', 'Am selben Werktag, auf Deutsch, mit einer Antwort statt einer Rückfrage.'],
|
||||
['Sie entscheiden.', 'Kein Vertrag, kein Rückruf-Rad — Sie bekommen etwas Schriftliches.'],
|
||||
] as $i => [$head, $body])
|
||||
<li class="flex gap-3.5">
|
||||
<span class="mt-0.5 grid size-6 shrink-0 place-items-center rounded-pill border border-line text-[11px] font-semibold tabular-nums text-muted">{{ $i + 1 }}</span>
|
||||
<span>
|
||||
<span class="block text-sm font-semibold text-ink">{{ $head }}</span>
|
||||
<span class="mt-1 block text-sm leading-relaxed text-muted">{{ $body }}</span>
|
||||
</span>
|
||||
</li>
|
||||
@endforeach
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="rounded-xl border border-line bg-surface p-6 shadow-xs">
|
||||
<p class="lbl">Lieber direkt</p>
|
||||
<a href="mailto:office@clupilot.com" class="mt-3 inline-flex items-center gap-2 text-sm font-medium text-accent-text underline-offset-4 hover:underline">
|
||||
<x-ui.icon name="mail" class="size-4" />office@clupilot.com
|
||||
</a>
|
||||
<p class="mt-4 text-sm leading-relaxed text-muted">
|
||||
Serverstandort EU, Betreuung auf Deutsch, AV-Vertrag inklusive.
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<div class="mt-5 flex flex-wrap items-center justify-between gap-4">
|
||||
<p class="max-w-[46ch] text-xs leading-relaxed text-muted">
|
||||
Wir benutzen Ihre Angaben nur, um Ihre Anfrage zu beantworten.
|
||||
Näheres in der <a href="{{ route('legal.datenschutz') }}" class="underline underline-offset-2 hover:text-body">Datenschutzerklärung</a>.
|
||||
</p>
|
||||
<button type="submit" class="inline-flex min-h-[46px] items-center justify-center rounded-[10px] bg-ink px-[22px] text-[15px] font-semibold leading-none text-white transition hover:opacity-90">
|
||||
Anfrage senden
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
</main>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</x-layouts.site>
|
||||
|
|
|
|||
Loading…
Reference in New Issue