Revision vor Kundenübergabe: Plausibilität, SEO, A11y, OpenPanel

This commit is contained in:
2026-09-10 18:14:26 +02:00
parent b6cbc9239f
commit 6438dd73f2
16 changed files with 19 additions and 102 deletions
-1
View File
@@ -24,7 +24,6 @@
},
"dependencies": {
"@calcom/embed-react": "^1.5.3",
"@fontsource-variable/nunito-sans": "^5.3.0",
"@fontsource-variable/public-sans": "^5.3.0",
"@openpanel/web": "^1.4.1",
"@tailwindcss/vite": "^4.1.18",
Binary file not shown.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 486 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 790 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

+1 -1
View File
@@ -38,7 +38,7 @@ export function AppShell({ session, nav, children }: AppShellProps) {
<div className="mx-auto flex max-w-6xl items-center justify-between gap-4 px-4 py-2 md:px-6">
<p className="flex items-center gap-2 text-sm">
<UserCog className="size-4" />
Du bist als <strong>{session.user.name}</strong> ({session.user.email}) eingeloggt.
Sie sind als <strong>{session.user.name}</strong> ({session.user.email}) eingeloggt.
</p>
<Button
type="button"
+1 -1
View File
@@ -19,7 +19,7 @@ export const Footer = () => {
<p className="max-w-xl text-(--sea-ink-soft) sm:text-lg">
Buchen Sie sich einen Termin direkt online - 30 Minuten,
kostenlos, keine Warteschleifen. Wenn Sie lieber telefonieren,
melde ich mich innerhalb eines Werktags zurück.
melden wir uns innerhalb eines Werktags zurück.
</p>
</div>
<div className="flex flex-col gap-3 sm:flex-row lg:flex-col">
+3 -3
View File
@@ -14,12 +14,12 @@ const steps = [
{
icon: Wrench,
title: "Umsetzung",
text: "Ich baue Ihre Seite. Zwischenstände zeige ich Ihnen regelmäßig, Anpassungen sind normaler Teil des Prozesses.",
text: "Wir bauen Ihre Seite. Zwischenstände zeigen wir Ihnen regelmäßig, Anpassungen sind normaler Teil des Prozesses.",
},
{
icon: Rocket,
title: "Übergabe",
text: "Sie bekommen Ihre neue Webseite, wir helfen Ihnen mit Ihrem Hosting-Anbieter oder betreuen Sie in einem unserer Betreuung und Hosting-Tarif.",
text: "Sie bekommen Ihre neue Webseite. Auf Wunsch übernehmen wir den Betrieb in einem unserer Betreuungs- und Hosting-Tarife oder helfen bei der Übergabe an Ihren Hosting-Anbieter.",
},
];
@@ -27,7 +27,7 @@ export const Process = () => {
return (
<section id="ablauf" className="mx-auto max-w-6xl px-4 py-16 md:px-6 md:py-24">
<div className="mx-auto max-w-2xl text-center">
<span className="island-kicker">So arbeite ich</span>
<span className="island-kicker">So arbeiten wir</span>
<h2 className="mt-3 font-heading text-3xl font-bold leading-tight tracking-tight text-(--sea-ink) sm:text-4xl">
In vier Schritten zur neuen Webseite
</h2>
+1 -1
View File
@@ -30,7 +30,7 @@ export const Services = () => {
Finden Sie sich wieder?
</h2>
<p className="mt-4 text-(--sea-ink-soft) sm:text-lg">
Meine Kunden verbindet eines: Sie sind Meister ihres Fachs -
Unsere Kunden verbindet eines: Sie sind Meister ihres Fachs -
und wollen sich nicht mit ihrer Webseite herumärgern.
</p>
</div>
+8 -6
View File
@@ -79,20 +79,22 @@ export const Route = createRootRouteWithContext<RouterAppContext>()({
content:
'Handgemachte Webseiten blitzschnell, sicher und individuell.',
},
{ property: 'og:image', content: 'https://webkulisse.de/img/og-cover.png' },
{ property: 'og:image:width', content: '1200' },
{ property: 'og:image:height', content: '630' },
{ property: 'og:image:alt', content: 'webkulisse Webdesign für Handwerk, Praxis & Therapie' },
// Übergangslösung: Logo als Preview-Bild. Wird ersetzt, sobald ein
// dediziertes 1200×630-Cover vorliegt (og:image:width/height dann anpassen).
{ property: 'og:image', content: 'https://webkulisse.de/img/logo.png' },
{ property: 'og:image:width', content: '690' },
{ property: 'og:image:height', content: '520' },
{ property: 'og:image:alt', content: 'webkulisse Logo' },
{ property: 'og:url', content: 'https://webkulisse.de/' },
// Twitter/X Card
{ name: 'twitter:card', content: 'summary_large_image' },
{ name: 'twitter:card', content: 'summary' },
{ name: 'twitter:title', content: 'webkulisse' },
{
name: 'twitter:description',
content:
'Handgemachte Webseiten blitzschnell, sicher und individuell.',
},
{ name: 'twitter:image', content: 'https://webkulisse.de/img/og-cover.png' },
{ name: 'twitter:image', content: 'https://webkulisse.de/img/logo.png' },
],
links: [
{ rel: 'stylesheet', href: appCss },
+1 -1
View File
@@ -16,7 +16,7 @@ const structuredData = {
'Handgemachte Webseiten für Handwerk, Praxis und Therapie in Bayern schnell, sicher und persönlich betreut.',
url: 'https://webkulisse.de/',
logo: 'https://webkulisse.de/img/logo.png',
image: 'https://webkulisse.de/img/og-cover.png',
image: 'https://webkulisse.de/img/logo.png',
telephone: '+49 171 8084830',
email: 'info@webkulisse.de',
priceRange: '€€',
+4 -4
View File
@@ -41,9 +41,9 @@ function LoginPage() {
if (code === 'INVALID_EMAIL_OR_PASSWORD') {
setError('E-Mail oder Passwort ist falsch.')
} else if (code === 'INVALID_EMAIL') {
setError('Bitte eine gueltige E-Mail-Adresse eingeben.')
setError('Bitte geben Sie eine gültige E-Mail-Adresse ein.')
} else if (code === 'USER_BANNED') {
setError('Dieser Zugang ist gesperrt. Bitte kontaktiere uns.')
setError('Dieser Zugang ist gesperrt. Bitte kontaktieren Sie uns.')
} else {
setError(res.error.message ?? 'Anmeldung fehlgeschlagen.')
}
@@ -70,7 +70,7 @@ function LoginPage() {
Kundenlogin
</h1>
<p className="text-sm text-muted-foreground">
Melde dich mit deinen Zugangsdaten an.
Melden Sie sich mit Ihren Zugangsdaten an.
</p>
</div>
</div>
@@ -120,7 +120,7 @@ function LoginPage() {
</Button>
<p className="text-center text-xs text-muted-foreground">
Kein Konto? Neue Zugaenge legt dein Ansprechpartner bei webkulisse an.
Kein Konto? Neue Zugänge legt Ihr Ansprechpartner bei webkulisse an.
</p>
</form>
</div>
-84
View File
@@ -1,7 +1,6 @@
@import 'tailwindcss';
@import 'tw-animate-css';
@import "shadcn/tailwind.css";
@import "@fontsource-variable/nunito-sans";
@import "@fontsource-variable/public-sans";
@font-face {
@@ -261,10 +260,6 @@ pre code {
margin-inline: auto;
}
.display-title {
font-family: 'Fraunces', Georgia, serif;
}
.island-shell {
border: 1px solid var(--line);
background: linear-gradient(165deg, var(--surface-strong), var(--surface));
@@ -419,82 +414,3 @@ img {
@apply font-sans;
}
}
/* Theme Toggle */
.theme-toggle {
display: none;
}
.theme-toggle__label {
/* Groesse ueber diese zwei Variablen steuern -- alles andere wird berechnet.
Overriden per Style-Attribut, Elternklasse, oder Utility (--tta-size: ...). */
--tta-size: 2em; /* Hoehe des Switches — ggf. an euren size(10)-Wert anpassen */
--tta-ratio: 2; /* Breite = Hoehe × Ratio (2 = Pill 2:1) */
/* Abgeleitete Werte -- nicht ueberschreiben. */
--tta-width: calc(var(--tta-size) * var(--tta-ratio));
--tta-pad: calc(var(--tta-size) * 0.1);
--tta-knob: calc(var(--tta-size) - var(--tta-pad) * 2);
--tta-icon: calc(var(--tta-size) * 0.6);
--tta-travel: calc(var(--tta-width) - var(--tta-knob) - var(--tta-pad) * 2);
width: var(--tta-width);
height: var(--tta-size);
position: relative;
display: block;
background: white;
border-radius: var(--tta-size);
box-shadow: inset 0 5px 15px rgba(0, 0, 0, 0.4),
inset 0 -5px 15px rgba(0, 0, 0, 0.4);
cursor: pointer;
transition: background-color 0.3s ease;
}
.theme-toggle__label::after {
content: '';
width: var(--tta-knob);
height: var(--tta-knob);
position: absolute;
top: var(--tta-pad);
left: var(--tta-pad);
background: linear-gradient(180deg, #ffcc89, #d8860b);
border-radius: var(--tta-knob);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
transition: transform 0.3s ease;
}
.theme-toggle__label svg {
position: absolute;
width: var(--tta-icon);
top: calc((var(--tta-size) - var(--tta-icon)) / 2);
z-index: 1;
}
/* Icon-Positionierung symmetrisch: mittig im jeweiligen "Knubbel-Slot". */
.theme-toggle__sun {
left: calc(var(--tta-pad) + (var(--tta-knob) - var(--tta-icon)) / 2);
fill: gold;
transition: fill 0.3s ease;
}
.theme-toggle__moon {
right: calc(var(--tta-pad) + (var(--tta-knob) - var(--tta-icon)) / 2);
fill: dimgray;
transition: fill 0.3s ease;
}
.theme-toggle:checked + .theme-toggle__label {
background: #242424;
}
.theme-toggle:checked + .theme-toggle__label::after {
transform: translateX(var(--tta-travel));
background: linear-gradient(180deg, #777, #3a3a3a);
}
.theme-toggle:checked + .theme-toggle__label .theme-toggle__sun {
fill: dimgray;
}
.theme-toggle:checked + .theme-toggle__label .theme-toggle__moon {
fill: deepskyblue;
}