chore: heygermany customer project
Some checks failed
Main / Setup and Test (push) Has been cancelled
Main / Build Website (push) Has been cancelled

This commit is contained in:
e2e
2026-07-11 11:03:59 +02:00
commit 36f1b746bd
370 changed files with 35585 additions and 0 deletions

View File

@@ -0,0 +1,963 @@
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap');
.page {
--background: hsl(210 20% 98%);
--foreground: hsl(210 50% 10%);
--card: hsl(0 0% 100%);
--card-foreground: hsl(210 50% 10%);
--primary: hsl(199 89% 28%);
--primary-foreground: hsl(0 0% 100%);
--secondary: hsl(160 60% 40%);
--muted: hsl(210 20% 95%);
--muted-foreground: hsl(210 15% 45%);
--accent: hsl(36 100% 55%);
--border: hsl(210 20% 90%);
--radius: 0.75rem;
--shadow-card: 0 4px 24px -4px hsl(199 89% 28% / 0.08);
--shadow-card-hover: 0 12px 40px -8px hsl(199 89% 28% / 0.15);
background: var(--background);
color: var(--foreground);
font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.container {
width: 100%;
max-width: 1400px;
margin: 0 auto;
padding-inline: 2rem;
}
.navbar {
position: fixed;
inset: 0 0 auto;
z-index: 50;
background: color-mix(in srgb, var(--primary) 90%, transparent);
backdrop-filter: blur(12px);
border-bottom: 1px solid color-mix(in srgb, var(--primary-foreground) 10%, transparent);
}
.navbarInner {
display: flex;
align-items: center;
justify-content: space-between;
min-height: 4rem;
}
.brand {
font-size: 1.25rem;
font-weight: 800;
color: var(--primary-foreground);
}
.navLinks {
display: flex;
align-items: center;
gap: 2rem;
}
.navLinks button,
.mobileMenu button,
.mobileToggle,
.headerButton,
.heroButton,
.submitButton,
.heroOutlineButton {
font-family: inherit;
}
.navLinks button:not(.headerButton),
.mobileMenu button:not(.headerButton),
.mobileToggle {
border: 0;
background: transparent;
color: color-mix(in srgb, var(--primary-foreground) 80%, transparent);
font-size: 0.875rem;
cursor: pointer;
transition: color 160ms ease;
}
.navLinks button:not(.headerButton):hover,
.mobileMenu button:not(.headerButton):hover,
.mobileToggle:hover {
color: var(--primary-foreground);
}
.heroButton,
.headerButton,
.submitButton,
.heroOutlineButton {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
white-space: nowrap;
cursor: pointer;
transition: all 200ms ease;
}
.heroButton,
.headerButton,
.submitButton {
border: 0;
background: var(--accent);
color: var(--foreground);
font-weight: 700;
box-shadow:
0 10px 15px -3px rgb(0 0 0 / 0.1),
0 4px 6px -4px rgb(0 0 0 / 0.1);
}
.heroButton:hover,
.headerButton:hover,
.submitButton:hover {
background: color-mix(in srgb, var(--accent) 90%, transparent);
box-shadow:
0 20px 25px -5px rgb(0 0 0 / 0.1),
0 8px 10px -6px rgb(0 0 0 / 0.1);
}
.headerButton {
height: 2.25rem;
padding-inline: 0.75rem;
border-radius: calc(var(--radius) - 0.125rem);
font-size: 1rem;
line-height: 1.5rem;
font-weight: 700;
}
.heroButton {
height: clamp(3rem, 6vh, 3.5rem);
padding-inline: clamp(1.5rem, 2.5vw, 2.5rem);
border-radius: calc(var(--radius) + 0.25rem);
font-size: clamp(1rem, 0.95rem + 0.35vw, 1.125rem);
}
.submitButton {
width: 100%;
height: 2.875rem;
padding-inline: 2rem;
border-radius: calc(var(--radius) + 0.25rem);
font-size: 1rem;
}
.heroOutlineButton {
border: 2px solid color-mix(in srgb, var(--primary-foreground) 30%, transparent);
height: clamp(3rem, 6vh, 3.5rem);
padding-inline: clamp(1.5rem, 2.5vw, 2.5rem);
border-radius: calc(var(--radius) + 0.25rem);
background: color-mix(in srgb, var(--primary-foreground) 10%, transparent);
color: var(--primary-foreground);
font-size: clamp(1rem, 0.95rem + 0.35vw, 1.125rem);
font-weight: 600;
backdrop-filter: blur(4px);
}
.heroOutlineButton:hover {
background: color-mix(in srgb, var(--primary-foreground) 20%, transparent);
}
.mobileToggle {
display: none;
}
.mobileHeaderActions {
display: none;
}
.mobileMenu {
display: none;
}
.hero {
position: relative;
min-height: 100svh;
display: flex;
align-items: stretch;
overflow: hidden;
}
.heroMedia {
position: absolute;
inset: 0;
}
.heroImage {
object-fit: cover;
}
.heroOverlay {
position: absolute;
inset: 0;
background: linear-gradient(
90deg,
color-mix(in srgb, var(--primary) 95%, transparent) 0%,
color-mix(in srgb, var(--primary) 85%, transparent) 50%,
color-mix(in srgb, var(--primary) 60%, transparent) 100%
);
}
.heroInner {
position: relative;
z-index: 1;
display: flex;
align-items: center;
box-sizing: border-box;
min-height: 100svh;
padding-top: clamp(5.5rem, 9vh, 8rem);
padding-bottom: clamp(4rem, 8vh, 7rem);
}
.heroCopy {
max-width: 46rem;
display: grid;
gap: clamp(0.875rem, 1.75vh, 1.5rem);
text-align: left;
}
.heroBadge {
display: inline-block;
width: fit-content;
padding: 0.375rem 1rem;
margin-bottom: 0;
border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
border-radius: 999px;
background: color-mix(in srgb, var(--accent) 20%, transparent);
color: var(--accent);
font-size: 0.875rem;
font-weight: 600;
}
.heroTitle {
margin: 0;
color: var(--primary-foreground);
font-size: clamp(2rem, 1.3rem + 2.5vw, 3.5rem);
line-height: 1.1;
font-weight: 800;
}
.heroTitle span {
color: var(--accent);
}
.heroDescription {
max-width: 42rem;
margin: 0;
color: color-mix(in srgb, var(--primary-foreground) 80%, transparent);
font-size: clamp(1rem, 0.92rem + 0.5vw, 1.2rem);
line-height: 1.65;
}
.heroActions {
margin-top: clamp(0.25rem, 1vh, 0.75rem);
display: flex;
flex-wrap: wrap;
gap: clamp(0.75rem, 1.2vw, 1rem);
align-items: flex-start;
}
.scrollIndicator {
position: absolute;
left: 50%;
bottom: clamp(1rem, 3vh, 2rem);
z-index: 1;
color: color-mix(in srgb, var(--primary-foreground) 50%, transparent);
transform: translateX(-50%);
animation: pilot-bounce 2s infinite;
}
@keyframes pilot-bounce {
0%, 100% { transform: translateX(-50%) translateY(0); }
50% { transform: translateX(-50%) translateY(10px); }
}
.section {
padding: 5rem 0 7rem;
}
.sectionMuted {
background: color-mix(in srgb, var(--muted) 50%, transparent);
}
.sectionFaq {
background: var(--muted);
}
.sectionHeader {
margin-bottom: 4rem;
}
.sectionHeaderCentered {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.sectionHeaderCentered .sectionEyebrow,
.sectionHeaderCentered h2,
.sectionHeaderCentered p {
text-align: center;
}
.sectionHeaderCentered p {
margin-inline: auto;
}
.sectionEyebrow,
.registerEyebrow {
color: var(--secondary);
font-size: 0.875rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.sectionHeader h2,
.registerCopy h2,
.successWrap h2 {
margin: 0.75rem 0 0;
font-size: clamp(2rem, 4vw, 2.75rem);
font-weight: 800;
line-height: 1.2;
color: var(--foreground);
}
.sectionHeader p,
.registerCopy p,
.successWrap p {
margin: 1rem 0 0;
max-width: 42rem;
color: var(--muted-foreground);
font-size: 1.125rem;
line-height: 1.7;
}
.problemGrid,
.offerGrid,
.benefitGrid {
display: grid;
gap: 1.5rem;
}
.problemGrid {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.problemCard,
.offerCard,
.faqItem,
.formCard,
.successWrap {
border: 1px solid var(--border);
background: var(--card);
box-shadow: var(--shadow-card);
}
.problemCard {
border-radius: 1rem;
padding: 1.5rem;
transition:
box-shadow 180ms ease,
transform 180ms ease;
}
.problemCard:hover,
.offerCard:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-card-hover);
}
.problemIcon,
.offerIcon {
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 0.75rem;
background: color-mix(in srgb, var(--primary) 10%, white);
color: var(--primary);
}
.problemIcon {
width: 3rem;
height: 3rem;
margin-bottom: 1rem;
}
.problemCard h3,
.offerCard h3,
.benefitItem h3,
.formCard h3 {
margin: 0 0 0.5rem;
font-size: 1.125rem;
font-weight: 700;
color: var(--card-foreground);
}
.problemCard p,
.offerCard p,
.benefitItem p,
.faqAnswer p,
.formHint,
.footerCopyright {
margin: 0;
color: var(--muted-foreground);
line-height: 1.7;
}
.offerGrid {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.offerCard {
position: relative;
overflow: hidden;
border-radius: 1rem;
padding: 2rem;
transition:
box-shadow 180ms ease,
transform 180ms ease;
}
.offerStep {
position: absolute;
top: 1rem;
right: 1.5rem;
color: color-mix(in srgb, var(--primary) 5%, white);
font-size: 3.75rem;
font-weight: 800;
line-height: 1;
}
.offerIcon {
width: 3.5rem;
height: 3.5rem;
margin-bottom: 1.5rem;
}
.offerCard p {
margin-bottom: 1.25rem;
}
.offerHighlights {
display: grid;
gap: 0.5rem;
padding: 0;
margin: 0;
list-style: none;
}
.offerHighlights li {
display: flex;
align-items: center;
gap: 0.5rem;
color: var(--foreground);
font-size: 0.9375rem;
}
.offerHighlights svg {
flex: none;
color: var(--secondary);
}
.benefitGrid {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
.benefitItem {
text-align: center;
}
.benefitIcon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 4rem;
height: 4rem;
margin-bottom: 1.25rem;
border-radius: 1rem;
background: color-mix(in srgb, var(--secondary) 10%, white);
color: var(--secondary);
}
.benefitItem h3 {
margin-bottom: 0.5rem;
}
.faqList {
max-width: 48rem;
margin: 0 auto;
display: grid;
gap: 0.75rem;
}
.faqItem {
border-radius: 1rem;
padding: 0 1.5rem;
box-shadow: 0 1px 2px hsl(210 50% 10% / 0.04);
}
.faqItem summary {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: 1.25rem 0;
list-style: none;
cursor: pointer;
color: var(--card-foreground);
font-size: 1.0625rem;
line-height: 1.5;
font-weight: 700;
}
.faqItem summary::-webkit-details-marker {
display: none;
}
.faqItem[open] summary svg {
transform: rotate(180deg);
}
.faqItem summary svg {
transition: transform 160ms ease;
}
.faqAnswer {
padding-bottom: 1.25rem;
}
.faqAnswer p + p {
margin-top: 1rem;
}
.registerSection {
background: var(--primary);
}
.registerGrid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 4rem;
align-items: center;
}
.registerCopy h2 {
color: var(--primary-foreground);
}
.registerCopy p {
color: color-mix(in srgb, var(--primary-foreground) 80%, transparent);
}
.registerEyebrow {
color: var(--accent);
}
.registerBenefits {
display: grid;
gap: 1rem;
padding: 0;
margin: 2rem 0 0;
list-style: none;
}
.registerBenefits li {
display: flex;
align-items: flex-start;
gap: 0.75rem;
color: color-mix(in srgb, var(--primary-foreground) 90%, transparent);
}
.registerBenefits svg {
flex: none;
margin-top: 0.1rem;
color: var(--accent);
}
.formWrap {
min-width: 0;
}
.formCard {
display: grid;
gap: 1rem;
padding: 1.75rem;
border-radius: 1rem;
box-shadow: var(--shadow-card-hover);
}
.fieldGrid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0.875rem;
}
.formCard label {
display: grid;
gap: 0.375rem;
}
.formCard label span {
color: var(--foreground);
font-size: 0.8125rem;
font-weight: 500;
}
.formCard input,
.formCard select,
.formCard textarea {
width: 100%;
min-width: 0;
padding: 0.75rem 0.9rem;
border: 1px solid var(--border);
border-radius: var(--radius);
background: white;
color: var(--foreground);
font: inherit;
}
.formCard input:focus,
.formCard select:focus,
.formCard textarea:focus {
outline: 2px solid color-mix(in srgb, var(--primary) 20%, transparent);
border-color: var(--primary);
}
.formCard textarea {
resize: vertical;
}
.heroButton:disabled,
.headerButton:disabled,
.submitButton:disabled,
.heroOutlineButton:disabled {
opacity: 0.75;
cursor: progress;
}
.formHint {
text-align: center;
font-size: 0.75rem;
}
.errorMessage {
margin: 0;
padding: 0.85rem 1rem;
border-radius: var(--radius);
background: hsl(0 84% 60% / 0.1);
color: hsl(0 72% 42%);
font-size: 0.875rem;
}
.successWrap {
max-width: 32rem;
margin: 0 auto;
padding: 3rem 2rem;
border: 0;
box-shadow: none;
background: transparent;
text-align: center;
}
.successWrap h2 {
color: var(--primary-foreground);
}
.successWrap p {
color: color-mix(in srgb, var(--primary-foreground) 80%, transparent);
}
.successIcon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 5rem;
height: 5rem;
margin-bottom: 1.5rem;
border-radius: 999px;
background: color-mix(in srgb, var(--secondary) 20%, transparent);
color: var(--secondary);
}
.footer {
background: var(--foreground);
padding: 2.25rem 0;
}
.footerCenter {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
width: 100%;
}
.footerLogoList {
display: flex;
flex-wrap: nowrap;
align-items: center;
justify-content: center;
gap: 1.35rem 2.75rem;
width: 100%;
padding: 0.9rem 1.25rem;
border: 1px solid color-mix(in srgb, var(--background) 16%, transparent);
border-radius: 1rem;
box-sizing: border-box;
}
.footerLogoPair {
display: flex;
flex-wrap: nowrap;
align-items: center;
justify-content: center;
gap: 0.7rem 1rem;
flex: 0 1 auto;
min-width: 0;
}
.footerLogoItem {
display: flex;
align-items: center;
justify-content: center;
flex: 0 1 auto;
min-width: 0;
}
.footerLogoImage {
display: block;
object-fit: contain;
width: auto;
max-width: none;
height: clamp(2.2rem, 3.6vw, 3.1rem);
}
.footerLinks {
display: flex;
flex-wrap: nowrap;
justify-content: center;
gap: 0.75rem;
width: 100%;
min-width: 0;
}
.footerLinks a {
color: color-mix(in srgb, var(--background) 78%, transparent);
font-size: 0.875rem;
text-decoration: none;
transition: color 180ms ease;
white-space: nowrap;
}
.footerLinks a:hover,
.footerLinks a:focus-visible {
color: var(--background);
}
.footerMetaText {
margin: 0;
text-align: center;
color: color-mix(in srgb, var(--background) 60%, transparent);
font-size: 1rem;
font-weight: 700;
white-space: nowrap;
}
.footerCopyright {
margin: 0;
text-align: center;
color: color-mix(in srgb, var(--background) 40%, transparent);
font-size: 0.875rem;
}
@media (max-width: 1024px) {
.problemGrid,
.offerGrid,
.benefitGrid,
.registerGrid {
grid-template-columns: 1fr;
}
.benefitGrid {
gap: 2rem;
}
}
@media (max-width: 768px) {
.container {
padding-inline: 1rem;
}
.brand {
font-size: 1.125rem;
}
.navLinks {
display: none;
}
.mobileHeaderActions {
display: flex;
align-items: center;
gap: 0.5rem;
margin-left: auto;
}
.mobileHeaderButton {
height: 2.25rem;
padding-inline: 0.75rem;
font-size: 0.875rem;
}
.mobileToggle {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2.25rem;
height: 2.25rem;
border-radius: calc(var(--radius) - 0.125rem);
}
.mobileMenu {
display: grid;
gap: 0.75rem;
padding: 0 0 1rem;
}
.mobileMenu .heroButton {
width: 100%;
}
.heroInner {
padding-top: clamp(5.5rem, 13vh, 7rem);
padding-bottom: clamp(4rem, 8vh, 5rem);
}
.heroCopy {
max-width: 100%;
}
.heroActions,
.fieldGrid {
grid-template-columns: 1fr;
}
.heroActions {
flex-direction: column;
}
.heroButton,
.heroOutlineButton {
width: 100%;
}
.section {
padding: 4.5rem 0 5rem;
}
.footerLogoList {
gap: 0.55rem;
padding: 0.65rem 0.75rem;
}
.footerLogoPair {
gap: 0.3rem;
}
.footerLogoImage {
height: clamp(0.8rem, 4vw, 1.55rem);
}
.footerMetaText {
font-size: clamp(0.58rem, 2.4vw, 0.82rem);
}
.footerLinks {
gap: 0.3rem;
}
.footerLinks a {
font-size: clamp(0.42rem, 1.9vw, 0.66rem);
}
}
@media (max-width: 420px) {
.brand {
font-size: 1rem;
}
.mobileHeaderButton {
padding-inline: 0.625rem;
font-size: 0.8125rem;
}
}
@media (max-height: 860px) {
.heroInner {
padding-top: 5rem;
padding-bottom: 3.75rem;
}
.heroCopy {
gap: 0.875rem;
}
.heroTitle {
font-size: clamp(1.9rem, 1.35rem + 2vw, 3rem);
}
.heroDescription {
font-size: clamp(0.975rem, 0.9rem + 0.35vw, 1.0625rem);
line-height: 1.55;
}
.heroButton,
.heroOutlineButton {
height: 3rem;
padding-inline: 1.5rem;
}
.scrollIndicator {
display: none;
}
}
@media (max-height: 720px) {
.heroInner {
padding-top: 4.5rem;
padding-bottom: 3rem;
}
.heroBadge {
padding: 0.3rem 0.875rem;
font-size: 0.8125rem;
}
.heroCopy {
gap: 0.75rem;
}
.heroTitle {
font-size: clamp(1.75rem, 1.3rem + 1.6vw, 2.6rem);
}
.heroDescription {
font-size: 0.9375rem;
line-height: 1.5;
}
.heroActions {
gap: 0.625rem;
}
.heroButton,
.heroOutlineButton {
height: 2.875rem;
font-size: 0.9375rem;
}
}
@media (min-width: 768px) {
.heroCopy {
max-width: 48rem;
}
}

View File

@@ -0,0 +1,766 @@
import { Link } from '@tanstack/react-router'
import { useState, type ChangeEvent, type FormEvent } from 'react'
import {
IconAlertTriangle,
IconArrowDown,
IconArrowsLeftRight,
IconBolt,
IconChevronDown,
IconCircleCheck,
IconClock,
IconCurrencyEuro,
IconHeart,
IconMenu2,
IconSettings,
IconShield,
IconTrendingDown,
IconUserCheck,
IconX,
} from '@tabler/icons-react'
import styles from './PilotLandingPage.module.css'
const facilityTypes = [
{ value: 'krankenhaus', label: 'Krankenhaus' },
{ value: 'altenpflege', label: 'Altenpflegeeinrichtung' },
{ value: 'ambulant', label: 'Ambulanter Pflegedienst' },
{ value: 'reha', label: 'Reha-Klinik' },
{ value: 'sonstige', label: 'Sonstige' },
]
const nursesNeededRanges = [
{ value: '1-5', label: '15' },
{ value: '6-15', label: '615' },
{ value: '16-30', label: '1630' },
{ value: '30+', label: 'Mehr als 30' },
]
const problems = [
{
icon: IconClock,
title: 'Langwierige Prozesse',
description:
'Bürokratie, Anerkennungsverfahren und Visaprozesse kosten wertvolle Zeit. Für zusätzliche Recruiting-Aufgaben fehlen im laufenden Betrieb oft die Ressourcen.',
},
{
icon: IconCurrencyEuro,
title: 'Hohe Agenturkosten',
description:
'Vermittlungsagenturen verlangen hohe Gebühren ohne nachhaltige Lösungen. Unklare Kommunikation kann zu falschen Erwartungen und mehr Fluktuation führen.',
},
{
icon: IconAlertTriangle,
title: 'Agenturabhängigkeit',
description:
'Ohne eigene Prozesse bleiben Sie dauerhaft auf externe Vermittler angewiesen. Sie geben Kontrolle über Ihr Recruiting aus der Hand.',
},
]
const offers = [
{
icon: IconUserCheck,
step: '01',
title: 'Vorqualifizierte Pflegefachkräfte',
description:
'Wir verschaffen Ihnen direkten Zugang zu vorqualifizierten internationalen Pflegefachkräften. Unser Fokus liegt auf Kandidatinnen und Kandidaten in Deutschland, ergänzt durch qualifizierte Fachkräfte aus Drittstaaten.',
highlights: [
'Geprüfte Abschlüsse und Lizenzen',
'Deutschkenntnisse mindestens B1',
'ggfs. Defizitbescheid',
],
},
{
icon: IconArrowsLeftRight,
step: '02',
title: 'Full-Service Recruiting',
description:
'Vom ersten Kontakt bis zur erfolgreichen Integration: Wir begleiten den gesamten Prozess von der Anerkennung bis zum Onboarding. Auf Wunsch unterstützen wir Sie auch gezielt in einzelnen Prozessschritten.',
highlights: [
'Unterstützung im Anerkennungsverfahren',
'Begleitung bei behördlichen und administrativen Prozessen',
'Onboarding und Integration in Ihrer Einrichtung',
],
},
{
icon: IconSettings,
step: '03',
title: 'Digitale Prozesse aufbauen',
description:
'Das Besondere: Während wir Sie operativ unterstützen, entwickeln wir gemeinsam mit Ihnen die Strukturen, mit denen Sie künftig selbst internationale Pflegekräfte rekrutieren und integrieren.',
highlights: [
'Klare, praxistaugliche Abläufe für Ihr Team',
'Entlastung durch vereinfachte und digital unterstützte Prozesse',
'Weniger Abhängigkeit von externen Vermittlern',
],
},
]
const benefits = [
{
icon: IconTrendingDown,
title: 'Kosten senken',
description:
'Deutlich günstiger als klassische Vermittlungsagenturen und langfristig noch wirtschaftlicher durch geringere Fluktuation.',
},
{
icon: IconBolt,
title: 'Schneller besetzen',
description:
'Vermeiden Sie Verzögerungen bei den Behörden durch vollständige und fehlerfreie Anträge.',
},
{
icon: IconShield,
title: 'Unabhängig werden',
description:
'Durch eigene Prozesse reduzieren Sie dauerhaft die Abhängigkeit von externen Dienstleistern.',
},
{
icon: IconHeart,
title: 'Nachhaltig integrieren',
description:
'Mehr Kontrolle über Auswahl, Kommunikation und Onboarding sorgt für realistische Erwartungen und stärkt die langfristige Bindung Ihrer Mitarbeitenden.',
},
]
const faqs = [
{
question: 'Für wen ist HeyGermany gedacht?',
answers: [
'HeyGermany richtet sich an Pflegeeinrichtungen in Deutschland stationäre Pflegeeinrichtungen, ambulante Pflegedienste, Langzeitpflege, Reha-Kliniken die internationale Pflegefachkräfte gewinnen und langfristig unabhängig rekrutieren und nachhaltig integrieren möchten.',
],
},
{
question: 'Was unterscheidet HeyGermany von klassischen Vermittlungsagenturen?',
answers: [
'Wir vermitteln nicht nur Pflegefachkräfte, sondern bauen gemeinsam mit Ihnen klare, praxistaugliche Recruiting-Strukturen auf, mit denen Sie künftig selbst international rekrutieren können. Sie werden Schritt für Schritt durch alle notwendigen Abläufe geführt und durch die Digitalisierung manueller Prozesse sparen Sie Zeit und personelle Ressourcen.',
'So werden Sie unabhängiger von externen Agenturen und reduzieren dauerhaft Ihre Kosten.',
],
},
{
question: 'Welche Qualifikationen bringen die Pflegefachkräfte mit?',
answers: [
'Alle Pflegefachkräfte sind fachlich vorqualifiziert, verfügen über Deutschkenntnisse und werden gezielt auf den Einsatz in Deutschland vorbereitet.',
'In unserem Talentpool befinden sich sowohl Fachkräfte mit bereits vorliegendem Defizitbescheid als auch Kandidat:innen ohne gestellten Anerkennungsantrag, bei denen nach sorgfältiger Prüfung eine hohe Wahrscheinlichkeit für die Anerkennung als Pflegefachmann/Pflegefachfrau besteht.',
],
},
{
question: 'Was bedeutet es, Pilot-Partner zu werden?',
answers: [
'Als Pilot-Partner gestalten Sie unser Angebot aktiv mit und profitieren von exklusivem Zugang zu Pflegekräften, vergünstigten Konditionen und direktem Austausch mit unserem Gründerteam.',
'Für eine erfolgreiche Zusammenarbeit ist ein regelmäßiger, unkomplizierter Austausch wichtig. So können wir Ihre bestehenden Abläufe verstehen und gezielt Prozesse entwickeln, die Sie im Alltag spürbar entlasten. Dabei halten wir den Abstimmungsaufwand für Sie so gering wie möglich.'
],
},
{
question: 'Welche Kosten kommen auf mich zu?',
answers: [
'Wohlfahrtsorganisationen, gemeinnützigen Trägern und Einrichtungen in Brandenburg bieten wir die Teilnahme an unserem Pilotprogramm kostenfrei an.',
'Für alle weiteren Pilotpartner stellen wir unseren Service zum Selbstkostenpreis bereit. Dieser liegt aktuell bei einem festen, reduzierten Preis von ca. 3.500 € pro erfolgreicher Vermittlung. Zusätzlich fallen ausschließlich tatsächlich entstehende externe Kosten an, etwa für Visa, Behörden oder Übersetzungen, transparent und ohne versteckte Gebühren.',
'In der Pilotphase liegt unser Fokus darauf, die größten Herausforderungen im Recruiting internationaler Pflegefachkräfte zu verstehen und gezielt digitale Lösungen zu entwickeln. Es geht uns derzeit nicht um Gewinnmaximierung, sondern darum, Prozesse nachhaltig zu verbessern.'
],
},
{
question: 'Warum gibt es HeyGermany?',
answers: [
'HeyGermany versteht sich als soziales Impact-Projekt. Wir wollen eine Brücke zwischen internationalen Bewerber:innen und deutschen Pflegeeinrichtungen bauen, um zwei der größten Herausforderungen unserer Zeit gemeinsam zu bewältigen: den Fachkräftemangel in der Pflege und die erfolgreiche Arbeitsmarktintegration internationaler Fachkräfte.',
],
},
]
const footerLogos = [
{
src: '/footer-logos/hwr-logo-alt.svg',
alt: 'HWR Berlin logo mark',
width: 40,
height: 66,
},
{
src: '/footer-logos/hwr-type.svg',
alt: 'HWR Berlin wordmark',
width: 247,
height: 65,
},
{
src: '/footer-logos/sib-logo.png',
alt: 'Startup Incubator Berlin logo',
width: 1215,
height: 314,
},
{
src: '/footer-logos/berlin-logo.webp',
alt: 'Berlin logo',
width: 866,
height: 650,
},
{
src: '/footer-logos/eu-funded-by-eu.png',
alt: 'Kofinanziert von der Europäischen Union',
width: 3955,
height: 788,
},
] as const
const [hwrMarkLogo, hwrWordmarkLogo, sibLogo, berlinLogo, euLogo] = footerLogos
type LeadFormState = {
firstName: string
lastName: string
email: string
phone: string
facilityName: string
facilityType: string
nursesNeededRange: string
message: string
}
const initialFormState: LeadFormState = {
firstName: '',
lastName: '',
email: '',
phone: '',
facilityName: '',
facilityType: '',
nursesNeededRange: '',
message: '',
}
const getApiBaseUrl = () => {
if (import.meta.env.VITE_API_BASE_URL) {
return import.meta.env.VITE_API_BASE_URL
}
if (typeof window === 'undefined') {
return ''
}
if (
window.location.hostname === 'localhost' ||
window.location.hostname === '127.0.0.1'
) {
return 'http://localhost:3000'
}
return 'https://api.hey-germany.com'
}
export const PilotLandingPage = () => {
const [open, setOpen] = useState(false)
const [submitted, setSubmitted] = useState(false)
const [isSubmitting, setIsSubmitting] = useState(false)
const [errorMessage, setErrorMessage] = useState<string | null>(null)
const [formState, setFormState] = useState<LeadFormState>(initialFormState)
const scrollTo = (id: string) => {
document.getElementById(id)?.scrollIntoView({ behavior: 'smooth' })
setOpen(false)
}
const handleChange = (
event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>
) => {
const { name, value } = event.currentTarget
setFormState((current) => ({
...current,
[name]: value,
}))
}
const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault()
setIsSubmitting(true)
setErrorMessage(null)
try {
const response = await fetch(`${getApiBaseUrl()}/leads`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formState),
})
if (!response.ok) {
throw new Error('Lead submission failed')
}
setSubmitted(true)
setFormState(initialFormState)
} catch (error) {
console.error('Lead submission failed', error)
setErrorMessage('Die Anfrage konnte gerade nicht übermittelt werden. Bitte versuchen Sie es erneut.')
} finally {
setIsSubmitting(false)
}
}
return (
<main className={styles.page}>
<nav className={styles.navbar}>
<div className={styles.container}>
<div className={styles.navbarInner}>
<span className={styles.brand}>HeyGermany</span>
<div className={styles.navLinks}>
<button type="button" onClick={() => scrollTo('angebot')}>
Angebot
</button>
<button type="button" onClick={() => scrollTo('register')}>
Registrieren
</button>
<button
type="button"
className={styles.headerButton}
onClick={() => scrollTo('register')}
>
Pilot-Partner werden
</button>
</div>
<div className={styles.mobileHeaderActions}>
<button
type="button"
className={`${styles.headerButton} ${styles.mobileHeaderButton}`}
onClick={() => scrollTo('register')}
>
Pilot-Partner werden
</button>
<button
type="button"
className={styles.mobileToggle}
onClick={() => setOpen(!open)}
aria-label="Menü umschalten"
>
{open ? <IconX size={22} /> : <IconMenu2 size={22} />}
</button>
</div>
</div>
{open ? (
<div className={styles.mobileMenu}>
<button type="button" onClick={() => scrollTo('angebot')}>
Angebot
</button>
<button type="button" onClick={() => scrollTo('register')}>
Registrieren
</button>
<button
type="button"
className={styles.headerButton}
onClick={() => scrollTo('register')}
>
Pilot-Partner werden
</button>
</div>
) : null}
</div>
</nav>
<section className={styles.hero}>
<div className={styles.heroMedia}>
<img
src="/images/pilot-hero-nurses.jpg"
alt="Internationale Pflegekräfte in einem deutschen Krankenhaus"
loading="eager"
sizes="100vw"
className={styles.heroImage}
style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }}
/>
<div className={styles.heroOverlay} />
</div>
<div className={`${styles.container} ${styles.heroInner}`}>
<div className={styles.heroCopy}>
<span className={styles.heroBadge}>🚀 Jetzt als Pilot-Partner bewerben</span>
<h1 className={styles.heroTitle}>
Internationale Pflegekräfte
<br />
<span>ohne Agenturen</span> gewinnen.
</h1>
<p className={styles.heroDescription}>
Erhalten Sie direkten Zugang zu vorqualifizierten internationalen Pflegefachkräften und
bauen Sie gleichzeitig eigene, nachhaltige Strukturen für Rekrutierung und Integration auf.
</p>
<p className={styles.heroDescription}>
Unsere Lösung vereinfacht und automatisiert die Prozesse der Erwerbsmigration genau dort,
wo sie für Sie den größten Mehrwert schafft. So besetzen Sie Stellen schneller, reduzieren
Kosten und machen sich unabhängig von Agenturen. Dabei entwickeln wir eine passgenaue
Lösung, individuell abgestimmt auf die Bedarfe Ihrer Einrichtung.
</p>
<div className={styles.heroActions}>
<button
type="button"
className={styles.heroButton}
onClick={() => scrollTo('register')}
>
Pilot-Partner werden
</button>
<button
type="button"
className={styles.heroOutlineButton}
onClick={() => scrollTo('angebot')}
>
Mehr erfahren
</button>
</div>
</div>
</div>
<div className={styles.scrollIndicator} aria-hidden="true">
<IconArrowDown size={24} />
</div>
</section>
<section className={styles.section}>
<div className={styles.container}>
<div className={`${styles.sectionHeader} ${styles.sectionHeaderCentered}`}>
<span className={styles.sectionEyebrow}>Das Problem</span>
<h2>Pflege in der Krise und kein Ende in Sicht</h2>
<p>
Deutsche Pflegeeinrichtungen stehen vor enormen Herausforderungen bei der Gewinnung
qualifizierter Fachkräfte.
</p>
</div>
<div className={styles.problemGrid}>
{problems.map(({ icon: Icon, title, description }) => (
<article key={title} className={styles.problemCard}>
<div className={styles.problemIcon}>
<Icon size={24} />
</div>
<h3>{title}</h3>
<p>{description}</p>
</article>
))}
</div>
</div>
</section>
<section id="angebot" className={`${styles.section} ${styles.sectionMuted}`}>
<div className={styles.container}>
<div className={`${styles.sectionHeader} ${styles.sectionHeaderCentered}`}>
<span className={styles.sectionEyebrow}>Unser Angebot</span>
<h2>Mehr als nur Vermittlung</h2>
<p>
HeyGermany verbindet Fachkräftegewinnung mit dem Aufbau Ihrer eigenen Recruiting-Kompetenz.
</p>
</div>
<div className={styles.offerGrid}>
{offers.map(({ icon: Icon, step, title, description, highlights }) => (
<article key={step} className={styles.offerCard}>
<span className={styles.offerStep}>{step}</span>
<div className={styles.offerIcon}>
<Icon size={28} />
</div>
<h3>{title}</h3>
<p>{description}</p>
<ul className={styles.offerHighlights}>
{highlights.map((highlight) => (
<li key={highlight}>
<IconCircleCheck size={16} />
<span>{highlight}</span>
</li>
))}
</ul>
</article>
))}
</div>
</div>
</section>
<section className={styles.section}>
<div className={styles.container}>
<div className={`${styles.sectionHeader} ${styles.sectionHeaderCentered}`}>
<span className={styles.sectionEyebrow}>Ihre Vorteile</span>
<h2>Warum Pflegeeinrichtungen HeyGermany wählen</h2>
</div>
<div className={styles.benefitGrid}>
{benefits.map(({ icon: Icon, title, description }) => (
<article key={title} className={styles.benefitItem}>
<div className={styles.benefitIcon}>
<Icon size={32} />
</div>
<h3>{title}</h3>
<p>{description}</p>
</article>
))}
</div>
</div>
</section>
<section className={`${styles.section} ${styles.sectionFaq}`}>
<div className={styles.container}>
<div className={`${styles.sectionHeader} ${styles.sectionHeaderCentered}`}>
<span className={styles.sectionEyebrow}>FAQ</span>
<h2>Häufig gestellte Fragen</h2>
<p>Hier finden Sie Antworten auf die wichtigsten Fragen rund um HeyGermany.</p>
</div>
<div className={styles.faqList}>
{faqs.map((faq, index) => (
<details key={faq.question} className={styles.faqItem} name="pilot-faq">
<summary>
<span>{faq.question}</span>
<IconChevronDown size={18} />
</summary>
<div className={styles.faqAnswer}>
{faq.answers.map((answer) => (
<p key={`${index}-${answer}`}>{answer}</p>
))}
</div>
</details>
))}
</div>
</div>
</section>
<section id="register" className={`${styles.section} ${styles.registerSection}`}>
<div className={styles.container}>
{submitted ? (
<div className={styles.successWrap}>
<div className={styles.successIcon}>
<IconCircleCheck size={40} />
</div>
<h2>Bewerbung eingegangen!</h2>
<p>
Vielen Dank für Ihr Interesse. Unser Team wird sich innerhalb von 48 Stunden bei Ihnen
melden, um die nächsten Schritte zu besprechen.
</p>
</div>
) : (
<div className={styles.registerGrid}>
<div className={styles.registerCopy}>
<span className={styles.registerEyebrow}>Limitierte Plätze</span>
<h2>Jetzt als Pilot-Partner bewerben</h2>
<p>
Wir suchen ausgewählte Pflegeeinrichtungen in Deutschland, die als Pilot-Partner unser
Projekt mitgestalten möchten. Als Pilot-Partner profitieren Sie von:
</p>
<ul className={styles.registerBenefits}>
{[
'Exklusiver Zugang zu vorqualifizierten Pflegekräften',
'Langfristig vergünstigte Konditionen',
'Direkter Draht zu unserem Gründerteam',
'Mitgestaltung der Lösung nach Ihren Bedürfnissen',
].map((benefit) => (
<li key={benefit}>
<IconCircleCheck size={20} />
<span>{benefit}</span>
</li>
))}
</ul>
</div>
<div className={styles.formWrap}>
<form onSubmit={handleSubmit} className={styles.formCard}>
<h3>Kontaktdaten</h3>
<div className={styles.fieldGrid}>
<label>
<span>Vorname *</span>
<input
required
name="firstName"
value={formState.firstName}
onChange={handleChange}
placeholder="Max"
/>
</label>
<label>
<span>Nachname *</span>
<input
required
name="lastName"
value={formState.lastName}
onChange={handleChange}
placeholder="Mustermann"
/>
</label>
</div>
<div className={styles.fieldGrid}>
<label>
<span>E-Mail *</span>
<input
required
type="email"
name="email"
value={formState.email}
onChange={handleChange}
placeholder="max@pflegeeinrichtung.de"
/>
</label>
<label>
<span>Telefon</span>
<input
type="tel"
name="phone"
value={formState.phone}
onChange={handleChange}
placeholder="+49 123 456789"
/>
</label>
</div>
<div className={styles.fieldGrid}>
<label>
<span>Name der Einrichtung *</span>
<input
required
name="facilityName"
value={formState.facilityName}
onChange={handleChange}
placeholder="Pflegezentrum Musterstadt"
/>
</label>
<label>
<span>Art der Einrichtung *</span>
<select
required
name="facilityType"
value={formState.facilityType}
onChange={handleChange}
>
<option value="">Bitte wählen</option>
{facilityTypes.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
</label>
</div>
<label>
<span>Wie viele Pflegekräfte suchen Sie aktuell?</span>
<select
name="nursesNeededRange"
value={formState.nursesNeededRange}
onChange={handleChange}
>
<option value="">Bitte wählen</option>
{nursesNeededRanges.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
</label>
<label>
<span>Nachricht (optional)</span>
<textarea
name="message"
rows={3}
value={formState.message}
onChange={handleChange}
placeholder="Erzählen Sie uns kurz von Ihren Herausforderungen..."
/>
</label>
{errorMessage ? <p className={styles.errorMessage}>{errorMessage}</p> : null}
<button
type="submit"
className={styles.submitButton}
disabled={isSubmitting}
>
{isSubmitting ? 'Wird gesendet ...' : 'Jetzt als Pilot-Partner bewerben'}
</button>
<p className={styles.formHint}>
Ihre Daten werden vertraulich behandelt. Wir melden uns innerhalb von 48 Stunden.
</p>
</form>
</div>
</div>
)}
</div>
</section>
<footer className={styles.footer}>
<div className={styles.container}>
<div className={styles.footerCenter}>
<p className={styles.footerMetaText}>
HeyGermany | Internationale Pflegekräfte für Deutschland
</p>
<div className={styles.footerLogoList} aria-label="Partner und Förderlogos">
<div className={styles.footerLogoPair}>
<div className={styles.footerLogoItem}>
<img
src={hwrMarkLogo.src}
alt={hwrMarkLogo.alt}
width={hwrMarkLogo.width}
height={hwrMarkLogo.height}
sizes="(max-width: 640px) 42vw, (max-width: 1024px) 28vw, 220px"
className={styles.footerLogoImage}
/>
</div>
<div className={styles.footerLogoItem}>
<img
src={hwrWordmarkLogo.src}
alt={hwrWordmarkLogo.alt}
width={hwrWordmarkLogo.width}
height={hwrWordmarkLogo.height}
sizes="(max-width: 640px) 42vw, (max-width: 1024px) 28vw, 220px"
className={styles.footerLogoImage}
/>
</div>
</div>
<div className={styles.footerLogoItem}>
<img
src={sibLogo.src}
alt={sibLogo.alt}
width={sibLogo.width}
height={sibLogo.height}
sizes="(max-width: 640px) 42vw, (max-width: 1024px) 28vw, 220px"
className={styles.footerLogoImage}
/>
</div>
<div className={styles.footerLogoItem}>
<img
src={berlinLogo.src}
alt={berlinLogo.alt}
width={berlinLogo.width}
height={berlinLogo.height}
sizes="(max-width: 640px) 42vw, (max-width: 1024px) 28vw, 220px"
className={styles.footerLogoImage}
/>
</div>
<div className={styles.footerLogoItem}>
<img
src={euLogo.src}
alt={euLogo.alt}
width={euLogo.width}
height={euLogo.height}
sizes="(max-width: 640px) 42vw, (max-width: 1024px) 28vw, 220px"
className={styles.footerLogoImage}
/>
</div>
</div>
<nav className={styles.footerLinks} aria-label="Rechtliches und Kontakt">
<Link to="/de/legal/imprint">Impressum</Link>
<Link to="/de/legal/terms-and-conditions">Nutzungsbedingungen</Link>
<Link to="/de/legal/privacy">Datenschutzhinweis</Link>
<a href="mailto:info@hey-germany.com">Kontakt</a>
</nav>
<p className={styles.footerCopyright}>
© {new Date().getFullYear()} HeyGermany. Alle Rechte vorbehalten.
</p>
</div>
</div>
</footer>
</main>
)
}