Revision vor Kundenübergabe: Plausibilität, SEO, A11y, OpenPanel
This commit is contained in:
@@ -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.
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 |
@@ -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"
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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: '€€',
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user