feat(landing): Add landing Nuxt page

This commit is contained in:
2026-01-03 10:19:39 +01:00
parent 0803b59f0f
commit b3311155c7
28 changed files with 13620 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
<template>
<UPageSection
:ui="{
root: 'py-16 lg:py-20 bg-gray-50 dark:bg-gray-900/50'
}"
>
<template #title>
<div class="flex flex-col items-center text-center mb-4">
<span
class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-success-100 dark:bg-success-900/30 text-success-700 dark:text-success-300 text-sm font-medium mb-4"
>
<UIcon name="i-lucide-shield" class="w-4 h-4" />
Vertrauen & Sicherheit
</span>
<h2
class="font-heading text-3xl sm:text-4xl lg:text-5xl text-pretty tracking-tight font-bold text-gray-900 dark:text-white"
>
Weitere <span class="gradient-text">Vorteile</span>
</h2>
</div>
</template>
<template #description>
<p class="text-center text-lg text-gray-600 dark:text-gray-300 max-w-2xl mx-auto">
Alles aus einer Hand ohne Drittanbieter, mit Serverstandort in Deutschland.
</p>
</template>
<!-- Icon grid with hover animations -->
<div class="mt-12 grid sm:grid-cols-2 lg:grid-cols-3 gap-6">
<div
v-for="(feature, index) in features"
:key="index"
class="group animate-fade-in-up"
:style="{ animationDelay: `${index * 100}ms` }"
>
<div
class="h-full p-6 rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 hover:border-transparent transition-all relative overflow-hidden"
>
<!-- Gradient border on hover -->
<div
class="absolute inset-0 rounded-2xl bg-gradient-to-br from-primary-500 via-cyan-500 to-accent-500 opacity-0 group-hover:opacity-100 transition-opacity -z-10"
/>
<div class="absolute inset-[2px] rounded-[14px] bg-white dark:bg-gray-900 -z-10" />
<div class="flex items-start gap-4">
<!-- Icon with gradient background -->
<div class="relative shrink-0">
<div
class="w-14 h-14 rounded-2xl bg-gradient-to-br from-primary-100 to-cyan-100 dark:from-primary-900/50 dark:to-cyan-900/50 flex items-center justify-center group-hover:scale-110 transition-transform"
>
<UIcon :name="feature.icon" class="w-7 h-7 text-primary-600 dark:text-primary-400" />
</div>
<!-- Animated ring on hover -->
<div
class="absolute inset-0 rounded-2xl ring-2 ring-primary-500/0 group-hover:ring-primary-500/50 transition-all scale-100 group-hover:scale-125 opacity-0 group-hover:opacity-100"
/>
</div>
<div class="flex-1">
<h3
class="font-heading text-lg font-bold text-gray-900 dark:text-white mb-2 group-hover:text-primary-600 dark:group-hover:text-primary-400 transition-colors"
>
{{ feature.title }}
</h3>
<p class="text-sm text-gray-600 dark:text-gray-300 leading-relaxed">
{{ feature.description }}
</p>
</div>
</div>
</div>
</div>
</div>
<!-- Bottom CTA -->
<div class="mt-12 text-center">
<p class="text-gray-500 dark:text-gray-400 mb-4">Haben Sie Fragen zu unseren Sicherheitsstandards?</p>
<UButton to="#kontakt" variant="outline" class="btn-outline-gradient">
<UIcon name="i-lucide-message-circle" class="w-4 h-4 mr-2" />
Kontakt aufnehmen
</UButton>
</div>
</UPageSection>
</template>
<script setup lang="ts">
const features = [
{
icon: 'i-lucide-puzzle',
title: 'Keine Zusatztools erforderlich',
description:
'Keine externen Zusatzlösungen für Prozess, Abstimmung und Dokumentenerstellung alles läuft in einem System.'
},
{
icon: 'i-lucide-server',
title: 'Hosting & Backups in Deutschland',
description:
'Betrieb und Datensicherung erfolgen in Deutschland transparente Datenflüsse ohne unerwartete Auslandsverarbeitung.'
},
{
icon: 'i-lucide-lock',
title: 'Verschlüsselte Übertragung',
description:
'Alle Verbindungen sind per TLS/HTTPS verschlüsselt, damit Inhalte und Zugangsdaten beim Transport geschützt sind.'
},
{
icon: 'i-lucide-sparkles',
title: 'Einfach zu bedienen',
description: 'Nutzerfreundliche, selbsterklärende Oberfläche mit geführten Eingaben reduziert Schulungsaufwand.'
},
{
icon: 'i-lucide-settings',
title: 'Hohe Anpassbarkeit',
description:
'Templates, Felder und Prozessschritte lassen sich auf Organisation und Abläufe konkret anpassen (auf Anfrage).'
},
{
icon: 'i-lucide-headphones',
title: 'Persönlicher Support',
description: 'Bei Fragen steht Ihnen unser Support-Team zur Verfügung schnell, kompetent und auf Deutsch.'
}
]
</script>

View File

@@ -0,0 +1,101 @@
<template>
<div class="absolute inset-0 overflow-hidden pointer-events-none" :class="variant">
<!-- Animated gradient orbs -->
<div
v-for="(orb, index) in orbs"
:key="index"
class="absolute rounded-full blur-3xl animate-float"
:class="orb.color"
:style="{
width: orb.size,
height: orb.size,
top: orb.top,
left: orb.left,
right: orb.right,
bottom: orb.bottom,
animationDelay: `${index * 2}s`,
animationDuration: `${6 + index * 2}s`
}"
/>
<!-- Grid pattern -->
<div v-if="showGrid" class="absolute inset-0 dots-pattern opacity-20" />
<!-- Animated lines (for tech feel) -->
<svg v-if="showLines" class="absolute inset-0 w-full h-full opacity-10" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="lineGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" class="[stop-color:var(--color-primary-500)]" stop-opacity="0" />
<stop offset="50%" class="[stop-color:var(--color-primary-500)]" stop-opacity="1" />
<stop offset="100%" class="[stop-color:var(--color-primary-500)]" stop-opacity="0" />
</linearGradient>
</defs>
<!-- Horizontal animated lines -->
<g v-for="i in 3" :key="`h-${i}`">
<line
x1="0"
:y1="`${20 + i * 25}%`"
x2="100%"
:y2="`${20 + i * 25}%`"
stroke="url(#lineGradient)"
stroke-width="1"
class="animate-pulse-soft"
:style="{ animationDelay: `${i * 0.5}s` }"
/>
</g>
</svg>
<!-- Floating particles -->
<div v-if="showParticles" class="absolute inset-0">
<div
v-for="i in 12"
:key="`particle-${i}`"
class="absolute w-1 h-1 rounded-full bg-primary-400/30 animate-float"
:style="{
top: `${Math.random() * 100}%`,
left: `${Math.random() * 100}%`,
animationDelay: `${Math.random() * 5}s`,
animationDuration: `${4 + Math.random() * 4}s`
}"
/>
</div>
</div>
</template>
<script setup lang="ts">
interface Props {
variant?: 'hero' | 'section' | 'cta'
showGrid?: boolean
showLines?: boolean
showParticles?: boolean
}
const props = withDefaults(defineProps<Props>(), {
variant: 'section',
showGrid: true,
showLines: false,
showParticles: false
})
const orbs = computed(() => {
switch (props.variant) {
case 'hero':
return [
{ size: '400px', top: '-100px', left: '-100px', color: 'bg-primary-500/20' },
{ size: '300px', top: '200px', right: '-50px', color: 'bg-success-500/15' },
{ size: '250px', bottom: '-50px', left: '30%', color: 'bg-primary-400/15' }
]
case 'cta':
return [
{ size: '300px', top: '-50px', right: '-100px', color: 'bg-white/10' },
{ size: '200px', bottom: '-50px', left: '-50px', color: 'bg-white/5' }
]
default:
return [
{ size: '200px', top: '10%', left: '-50px', color: 'bg-primary-500/10' },
{ size: '150px', bottom: '20%', right: '-30px', color: 'bg-success-500/10' }
]
}
})
</script>

View File

@@ -0,0 +1,185 @@
<template>
<UPageSection
id="unternehmen"
:ui="{
root: 'scroll-mt-20 py-16 lg:py-20 bg-gray-50 dark:bg-gray-900/50'
}"
>
<template #title>
<div class="flex flex-col items-center text-center mb-4">
<span
class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-accent-100 dark:bg-accent-900/30 text-accent-700 dark:text-accent-300 text-sm font-medium mb-4"
>
<UIcon name="i-lucide-building-2" class="w-4 h-4" />
Für Unternehmen
</span>
<h2
class="font-heading text-3xl sm:text-4xl lg:text-5xl text-pretty tracking-tight font-bold text-gray-900 dark:text-white"
>
Vorteile für <span class="gradient-text">Unternehmen</span>
</h2>
</div>
</template>
<template #description>
<p class="text-center text-lg text-gray-600 dark:text-gray-300 max-w-2xl mx-auto">
Schneller zur abgestimmten Einführung von IT- und KI-Systemen mit planbaren Timelines.
</p>
</template>
<!-- Comparison view -->
<div class="mt-12 grid lg:grid-cols-2 gap-8 lg:gap-12">
<!-- Pain points column -->
<div class="space-y-6">
<div class="flex items-center gap-3 mb-6">
<div
class="w-12 h-12 rounded-2xl bg-gradient-to-br from-warning-500 to-orange-500 flex items-center justify-center shadow-lg shadow-warning-500/25"
>
<UIcon name="i-lucide-x" class="w-6 h-6 text-white" />
</div>
<div>
<h3 class="font-heading text-xl font-bold text-gray-900 dark:text-white">Weg von</h3>
<p class="text-sm text-gray-500 dark:text-gray-400">Typische Herausforderungen</p>
</div>
</div>
<div class="space-y-3">
<div
v-for="(point, index) in painPoints"
:key="index"
class="group flex gap-4 p-4 rounded-xl bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 hover:border-warning-300 dark:hover:border-warning-600 transition-all animate-fade-in-up"
:style="{ animationDelay: `${index * 75}ms` }"
>
<div
class="mt-0.5 w-8 h-8 rounded-lg bg-warning-100 dark:bg-warning-900/30 flex items-center justify-center shrink-0 group-hover:scale-110 transition-transform"
>
<UIcon :name="point.icon" class="w-4 h-4 text-warning-600 dark:text-warning-400" />
</div>
<p class="text-sm text-gray-700 dark:text-gray-300 leading-relaxed">{{ point.text }}</p>
</div>
</div>
</div>
<!-- Benefits column -->
<div class="space-y-6">
<div class="flex items-center gap-3 mb-6">
<div
class="w-12 h-12 rounded-2xl bg-gradient-to-br from-success-500 to-emerald-500 flex items-center justify-center shadow-lg shadow-success-500/25"
>
<UIcon name="i-lucide-check" class="w-6 h-6 text-white" />
</div>
<div>
<h3 class="font-heading text-xl font-bold text-gray-900 dark:text-white">Hin zu</h3>
<p class="text-sm text-gray-500 dark:text-gray-400">Mit LegalConsentHub</p>
</div>
</div>
<div class="space-y-3">
<div
v-for="(benefit, index) in benefits"
:key="index"
class="group flex gap-4 p-4 rounded-xl bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 hover:border-success-300 dark:hover:border-success-600 transition-all animate-fade-in-up"
:style="{ animationDelay: `${index * 75 + 100}ms` }"
>
<div
class="mt-0.5 w-8 h-8 rounded-lg bg-success-100 dark:bg-success-900/30 flex items-center justify-center shrink-0 group-hover:scale-110 transition-transform"
>
<UIcon :name="benefit.icon" class="w-4 h-4 text-success-600 dark:text-success-400" />
</div>
<p class="text-sm text-gray-700 dark:text-gray-300 leading-relaxed">{{ benefit.text }}</p>
</div>
</div>
</div>
</div>
<!-- Highlights section -->
<div class="mt-12">
<div class="section-divider mb-8" />
<h3 class="font-heading text-2xl sm:text-3xl text-gray-900 dark:text-white text-center mb-10">
So wirkt es in der <span class="gradient-text">Praxis</span>
</h3>
<div class="grid sm:grid-cols-3 gap-6">
<div
v-for="(highlight, index) in highlights"
:key="index"
class="group animate-fade-in-up"
:style="{ animationDelay: `${index * 150}ms` }"
>
<div
class="h-full p-6 rounded-2xl bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 hover:shadow-xl hover:shadow-accent-500/10 hover:border-accent-200 dark:hover:border-accent-700 transition-all"
>
<div
class="w-12 h-12 rounded-2xl bg-gradient-to-br from-accent-500 to-violet-500 flex items-center justify-center mb-4 group-hover:scale-110 transition-transform shadow-lg shadow-accent-500/25"
>
<UIcon :name="highlight.icon" class="w-6 h-6 text-white" />
</div>
<h4 class="font-heading text-lg font-bold text-gray-900 dark:text-white mb-2">{{ highlight.title }}</h4>
<p class="text-sm text-gray-600 dark:text-gray-300">{{ highlight.description }}</p>
</div>
</div>
</div>
</div>
</UPageSection>
</template>
<script setup lang="ts">
const painPoints = [
{
icon: 'i-lucide-refresh-cw',
text: 'Unkalkulierbare Schleifen im Mitbestimmungsverfahren (fehlende Infos, Nachforderungen)'
},
{ icon: 'i-lucide-ban', text: 'Verzögerungen, Projektstopps und Last-Minute-Änderungen kurz vor Go-live' },
{ icon: 'i-lucide-files', text: 'Hoher Koordinationsaufwand (E-Mail/Excel/Word) und Versionschaos' },
{
icon: 'i-lucide-puzzle',
text: 'Komplexität und Reibung durch uneinheitliche Prozesse und unterschiedliche Erwartungshaltungen'
},
{ icon: 'i-lucide-help-circle', text: 'Unklarer Änderungsumfang bei Updates/Modulerweiterungen' },
{ icon: 'i-lucide-hourglass', text: 'Verlust wertvoller Zeit und begrenzter Ressourcen' },
{ icon: 'i-lucide-wallet', text: 'Vermeidbare Kosten (Einigungsstelle, externe Beratung, Eskalationen)' }
]
const benefits = [
{
icon: 'i-lucide-calendar-check',
text: 'Planbare, schnellere Verfahren durch Standardisierung & klare Prozessschritte'
},
{
icon: 'i-lucide-users',
text: 'Bessere Zusammenarbeit mit BR/PR durch Transparenz und nachvollziehbare Dokumentation'
},
{
icon: 'i-lucide-gauge',
text: 'Risikobasierter Ansatz: Schnellverfahren für Standard-/Low-Risk-Systeme, Fokus auf High-Risk'
},
{
icon: 'i-lucide-thumbs-up',
text: 'Höhere Einigungswahrscheinlichkeit, weil die Verhandlungsgrundlage strukturiert ist'
},
{
icon: 'i-lucide-file-check-2',
text: 'Qualitativ konsistente, robuste Betriebs-/Dienstvereinbarungen (auch bei Änderungen updatefähig)'
},
{ icon: 'i-lucide-sparkles', text: 'Entlastung von Fachbereichen/IT/HR mehr Zeit für Wertschöpfung' }
]
const highlights = [
{
icon: 'i-lucide-repeat',
title: 'Weniger Iterationen',
description: 'Unterlagen sind vollständig und vergleichbar Nachforderungen sinken.'
},
{
icon: 'i-lucide-rocket',
title: 'Schneller zur Freigabe',
description: 'Klare Schritte statt „Hauruck" und kurzfristiger Umplanungen.'
},
{
icon: 'i-lucide-refresh-cw',
title: 'Change-ready',
description:
'Updates, neue Module oder neue Auswertungen werden strukturiert nachgezogen, ohne jedes Mal neu zu starten.'
}
]
</script>

View File

@@ -0,0 +1,209 @@
<template>
<UPageSection
id="betriebsraete"
:ui="{
root: 'scroll-mt-20 py-16 lg:py-20'
}"
>
<template #title>
<div class="flex flex-col items-center text-center mb-4">
<span
class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-primary-100 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300 text-sm font-medium mb-4"
>
<UIcon name="i-lucide-users" class="w-4 h-4" />
Für Betriebsräte
</span>
<h2
class="font-heading text-3xl sm:text-4xl lg:text-5xl text-pretty tracking-tight font-bold text-gray-900 dark:text-white"
>
Vorteile für <span class="gradient-text">Betriebsräte</span>
</h2>
</div>
</template>
<template #description>
<p class="text-center text-lg text-gray-600 dark:text-gray-300 max-w-2xl mx-auto">
Weg von Informationsjagd und Blackbox-Systemen hin zu Transparenz und belastbaren Vereinbarungen.
</p>
</template>
<!-- Toggle between pain points and benefits -->
<div class="mt-12">
<!-- Tab switcher -->
<div class="flex justify-center mb-10">
<div class="inline-flex p-1.5 rounded-2xl glass">
<button
:class="[
'px-6 py-3 rounded-xl text-sm font-semibold transition-all duration-300',
activeTab === 'pain'
? 'bg-gradient-to-r from-warning-500 to-warning-600 text-white shadow-lg'
: 'text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white'
]"
@click="activeTab = 'pain'"
>
<UIcon name="i-lucide-x-circle" class="w-4 h-4 inline mr-2" />
Weg von
</button>
<button
:class="[
'px-6 py-3 rounded-xl text-sm font-semibold transition-all duration-300',
activeTab === 'benefit'
? 'bg-gradient-to-r from-success-500 to-success-600 text-white shadow-lg'
: 'text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white'
]"
@click="activeTab = 'benefit'"
>
<UIcon name="i-lucide-check-circle" class="w-4 h-4 inline mr-2" />
Hin zu
</button>
</div>
</div>
<!-- Cards carousel -->
<div class="relative">
<!-- Pain points cards -->
<Transition
enter-active-class="transition-all duration-500 ease-out"
enter-from-class="opacity-0 translate-x-8"
enter-to-class="opacity-100 translate-x-0"
leave-active-class="transition-all duration-300 ease-in absolute inset-0"
leave-from-class="opacity-100 translate-x-0"
leave-to-class="opacity-0 -translate-x-8"
>
<div v-if="activeTab === 'pain'" class="grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-5">
<div v-for="(point, index) in painPoints" :key="index" class="group">
<div
class="h-full p-5 rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 hover:border-warning-300 dark:hover:border-warning-700 shadow-sm hover:shadow-lg transition-all duration-300"
>
<div
class="w-10 h-10 rounded-xl bg-warning-100 dark:bg-warning-900/30 flex items-center justify-center mb-4 group-hover:scale-110 transition-transform"
>
<UIcon :name="point.icon" class="w-5 h-5 text-warning-600 dark:text-warning-400" />
</div>
<p class="text-sm text-gray-700 dark:text-gray-300 leading-relaxed">{{ point.text }}</p>
</div>
</div>
</div>
</Transition>
<!-- Benefits cards -->
<Transition
enter-active-class="transition-all duration-500 ease-out"
enter-from-class="opacity-0 translate-x-8"
enter-to-class="opacity-100 translate-x-0"
leave-active-class="transition-all duration-300 ease-in absolute inset-0"
leave-from-class="opacity-100 translate-x-0"
leave-to-class="opacity-0 -translate-x-8"
>
<div v-if="activeTab === 'benefit'" class="grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-5">
<div v-for="(benefit, index) in benefits" :key="index" class="group">
<div
class="h-full p-5 rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 hover:border-success-300 dark:hover:border-success-700 shadow-sm hover:shadow-lg transition-all duration-300"
>
<div
class="w-10 h-10 rounded-xl bg-success-100 dark:bg-success-900/30 flex items-center justify-center mb-4 group-hover:scale-110 transition-transform"
>
<UIcon :name="benefit.icon" class="w-5 h-5 text-success-600 dark:text-success-400" />
</div>
<p class="text-sm text-gray-700 dark:text-gray-300 leading-relaxed">{{ benefit.text }}</p>
</div>
</div>
</div>
</Transition>
</div>
</div>
<!-- Highlights section -->
<div class="mt-12">
<div class="section-divider mb-8" />
<h3 class="font-heading text-2xl sm:text-3xl text-gray-900 dark:text-white text-center mb-10">
So hilft es im <span class="gradient-text">Alltag</span>
</h3>
<div class="grid sm:grid-cols-3 gap-6">
<div
v-for="(highlight, index) in highlights"
:key="index"
class="group animate-fade-in-up"
:style="{ animationDelay: `${index * 150}ms` }"
>
<div
class="h-full p-6 rounded-2xl bg-gradient-to-br from-primary-50 to-cyan-50 dark:from-primary-950/50 dark:to-cyan-950/50 border border-primary-100 dark:border-primary-900 hover:shadow-xl hover:shadow-primary-500/10 transition-all"
>
<div
class="w-12 h-12 rounded-2xl bg-gradient-to-br from-primary-500 to-cyan-500 flex items-center justify-center mb-4 group-hover:scale-110 transition-transform shadow-lg shadow-primary-500/25"
>
<UIcon :name="highlight.icon" class="w-6 h-6 text-white" />
</div>
<h4 class="font-heading text-lg font-bold text-gray-900 dark:text-white mb-2">{{ highlight.title }}</h4>
<p class="text-sm text-gray-600 dark:text-gray-300">{{ highlight.description }}</p>
</div>
</div>
</div>
</div>
</UPageSection>
</template>
<script setup lang="ts">
const activeTab = ref<'pain' | 'benefit'>('benefit')
const painPoints = [
{
icon: 'i-lucide-search',
text: 'Informationen zu IT-/KI-Systemen mühsam zusammensuchen (E-Mails, PDFs, PowerPoint, Excel-Chaos)'
},
{ icon: 'i-lucide-git-branch', text: 'Medienbrüche, Versionschaos und wiederkehrende Rückfragen' },
{ icon: 'i-lucide-timer', text: 'Ad-hoc-Systemeinführungen unter Zeitdruck („Hauruck" statt Prozess)' },
{ icon: 'i-lucide-brain', text: 'Überforderung durch Menge und Komplexität der Systeme' },
{ icon: 'i-lucide-eye-off', text: 'Blackbox bei Funktionen, Auswertungen, Schnittstellen und Änderungen' },
{ icon: 'i-lucide-file-question', text: 'Verhandlungen ohne belastbare Datenbasis' },
{ icon: 'i-lucide-calendar-x', text: 'Heute geregelt, morgen veraltet' }
]
const benefits = [
{
icon: 'i-lucide-layout-list',
text: 'Strukturierte, vollständige Informationsgrundlage (einheitlich je System/Verarbeitung)'
},
{ icon: 'i-lucide-route', text: 'Klarer Mitbestimmungsprozess mit bewährten Schritten und Zuständigkeiten' },
{
icon: 'i-lucide-file-check',
text: 'Betriebs-/Dienstvereinbarungen auf belastbarer Grundlage schneller, konsistenter, leicht aktualisierbar'
},
{
icon: 'i-lucide-scan-eye',
text: 'Transparenz über Systemfähigkeiten inkl. möglicher Leistungs-/Verhaltenskontrolle'
},
{
icon: 'i-lucide-git-compare',
text: 'Vergleichbarkeit über viele Systeme hinweg durch Standardisierung und einheitliche Templates'
},
{ icon: 'i-lucide-clock', text: 'Große Zeitersparnis gegenüber konventionellem Verfahren' },
{
icon: 'i-lucide-shield-check',
text: 'Schutzmaßnahmen konsequent dokumentiert und pro Auswertung/Verarbeitung nachvollziehbar'
},
{
icon: 'i-lucide-heart-handshake',
text: 'Spürbare Entlastung: mehr Zeit für andere Mitbestimmungsthemen und kontinuierlichen Arbeitnehmerschutz'
}
]
const highlights = [
{
icon: 'i-lucide-zap',
title: 'Schneller prüfen',
description: 'Relevante Funktionen und Risiken sind auf einen Blick sichtbar.'
},
{
icon: 'i-lucide-handshake',
title: 'Besser verhandeln',
description: 'Klare, konsistente Unterlagen statt Interpretationsspielräumen.'
},
{
icon: 'i-lucide-shield',
title: 'Nachhaltig absichern',
description: 'Änderungen und neue Auswertungen lassen sich strukturiert nachziehen.'
}
]
</script>

View File

@@ -0,0 +1,175 @@
<template>
<section id="kontakt" class="relative py-16 lg:py-20 overflow-hidden scroll-mt-20">
<!-- Mesh gradient background -->
<div class="absolute inset-0 mesh-gradient-cta" />
<!-- Animated gradient overlay -->
<div class="absolute inset-0 bg-gradient-to-br from-primary-600/90 via-cyan-600/90 to-accent-600/90" />
<!-- Grid pattern -->
<div class="absolute inset-0 grid-pattern opacity-10" />
<!-- Floating elements -->
<div class="absolute inset-0 overflow-hidden pointer-events-none">
<div class="absolute top-10 left-10 w-20 h-20 rounded-full bg-white/10 animate-float-slow" />
<div
class="absolute bottom-20 right-20 w-32 h-32 rounded-full bg-white/5 animate-float-slow"
style="animation-delay: 2s"
/>
<div
class="absolute top-1/2 left-1/4 w-16 h-16 rounded-full bg-white/10 animate-float-fast"
style="animation-delay: 1s"
/>
</div>
<div class="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="grid lg:grid-cols-2 gap-12 lg:gap-16 items-center">
<!-- Left: Content -->
<div class="text-center lg:text-left">
<span
class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-white/20 backdrop-blur-sm text-white text-sm font-medium mb-6"
>
<UIcon name="i-lucide-users" class="w-4 h-4" />
Expertennetzwerk
</span>
<h2 class="font-heading text-3xl sm:text-4xl lg:text-5xl font-bold text-white mb-6 animate-fade-in-up">
Externer Sachverstand direkt aus dem Verfahren
</h2>
<p class="text-lg text-white/90 mb-8 animate-fade-in-up" style="animation-delay: 100ms">
Wenn Betriebsparteien bei einzelnen Fragen nicht weiterkommen, kann optional externer Sachverstand direkt im
System angefragt werden. Anfragen, Rückfragen und Ergebnisse bleiben nachvollziehbar dokumentiert.
</p>
<!-- CTA buttons -->
<div
class="flex flex-wrap justify-center lg:justify-start gap-4 animate-fade-in-up"
style="animation-delay: 200ms"
>
<UButton
to="mailto:info@legalconsenthub.de"
size="xl"
class="bg-white text-primary-700 hover:bg-white/90 px-8 py-4 text-lg font-semibold rounded-xl shadow-lg"
>
Kontakt aufnehmen
<UIcon name="i-lucide-arrow-right" class="w-5 h-5 ml-2" />
</UButton>
<UButton
to="#features"
size="xl"
class="bg-white/10 text-white border-2 border-white/30 hover:bg-white/20 px-8 py-4 text-lg font-semibold rounded-xl backdrop-blur-sm"
>
Mehr erfahren
</UButton>
</div>
</div>
<!-- Right: Expert cards with connection lines -->
<div class="flex justify-center animate-scale-in" style="animation-delay: 300ms">
<div class="relative">
<!-- Connection lines SVG -->
<svg class="absolute inset-0 w-full h-full pointer-events-none" viewBox="0 0 400 300">
<defs>
<linearGradient id="lineGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color: rgba(255, 255, 255, 0.3)" />
<stop offset="50%" style="stop-color: rgba(255, 255, 255, 0.6)" />
<stop offset="100%" style="stop-color: rgba(255, 255, 255, 0.3)" />
</linearGradient>
</defs>
<!-- Animated connection lines -->
<path
d="M200,150 L100,80"
stroke="url(#lineGradient)"
stroke-width="2"
fill="none"
stroke-dasharray="5,5"
class="animate-pulse"
/>
<path
d="M200,150 L300,80"
stroke="url(#lineGradient)"
stroke-width="2"
fill="none"
stroke-dasharray="5,5"
class="animate-pulse"
style="animation-delay: 0.5s"
/>
<path
d="M200,150 L200,250"
stroke="url(#lineGradient)"
stroke-width="2"
fill="none"
stroke-dasharray="5,5"
class="animate-pulse"
style="animation-delay: 1s"
/>
</svg>
<!-- Center hub -->
<div class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-10">
<div
class="w-20 h-20 rounded-full bg-white/20 backdrop-blur-sm border-2 border-white/40 flex items-center justify-center animate-pulse-glow"
>
<UIcon name="i-lucide-link" class="w-8 h-8 text-white" />
</div>
</div>
<!-- Expert cards -->
<div class="grid grid-cols-2 gap-6 w-80 sm:w-96">
<!-- Legal expert card -->
<div class="col-span-1 animate-float-slow">
<div
class="bg-white/15 backdrop-blur-md rounded-2xl p-5 border border-white/20 hover:bg-white/20 transition-all"
>
<div class="w-12 h-12 rounded-xl bg-white/20 flex items-center justify-center mb-4">
<UIcon name="i-lucide-scale" class="w-6 h-6 text-white" />
</div>
<h4 class="font-heading font-bold text-white mb-1">Arbeitsrecht</h4>
<p class="text-sm text-white/70">Fachanwälte für Arbeitsrecht</p>
</div>
</div>
<!-- Technical expert card -->
<div class="col-span-1 animate-float-slow" style="animation-delay: 1s">
<div
class="bg-white/15 backdrop-blur-md rounded-2xl p-5 border border-white/20 hover:bg-white/20 transition-all"
>
<div class="w-12 h-12 rounded-xl bg-white/20 flex items-center justify-center mb-4">
<UIcon name="i-lucide-cpu" class="w-6 h-6 text-white" />
</div>
<h4 class="font-heading font-bold text-white mb-1">Technik</h4>
<p class="text-sm text-white/70">IT-Sachverständige</p>
</div>
</div>
<!-- Spacer for center positioning -->
<div class="col-span-2 h-24" />
<!-- Process integration card -->
<div class="col-span-2 animate-float-slow" style="animation-delay: 2s">
<div
class="bg-white/15 backdrop-blur-md rounded-2xl p-5 border border-white/20 hover:bg-white/20 transition-all"
>
<div class="flex items-center gap-4">
<div class="w-12 h-12 rounded-xl bg-white/20 flex items-center justify-center shrink-0">
<UIcon name="i-lucide-file-check" class="w-6 h-6 text-white" />
</div>
<div>
<h4 class="font-heading font-bold text-white mb-1">Direkt im Verfahren</h4>
<p class="text-sm text-white/70">Dokumentiert & nachvollziehbar</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<script setup lang="ts">
// No additional script needed
</script>

View File

@@ -0,0 +1,242 @@
<template>
<UPageSection
id="features"
:ui="{
root: 'scroll-mt-20 py-16 lg:py-20'
}"
>
<template #title>
<div class="flex flex-col items-center text-center mb-4">
<span
class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-cyan-100 dark:bg-cyan-900/30 text-cyan-700 dark:text-cyan-300 text-sm font-medium mb-4"
>
<UIcon name="i-lucide-sparkles" class="w-4 h-4" />
Features
</span>
<h2
class="font-heading text-3xl sm:text-4xl lg:text-5xl text-pretty tracking-tight font-bold text-gray-900 dark:text-white"
>
Features, die Mitbestimmung <span class="gradient-text">effizient</span> machen
</h2>
</div>
</template>
<template #description>
<p class="text-center text-lg text-gray-600 dark:text-gray-300 max-w-3xl mx-auto">
Eine strukturierte Eingabelogik, klare Prozesse und revisionssichere Dokumentation damit IT-/KI-Systeme
schneller bewertet, abgestimmt und sauber vereinbart werden können.
</p>
</template>
<!-- Bento Grid -->
<div ref="gridRef" class="mt-12 bento-grid">
<!-- Large featured card -->
<div class="bento-item-large group card-spotlight animate-fade-in-up" @mousemove="handleMouseMove">
<div
class="h-full p-8 rounded-3xl bg-gradient-to-br from-primary-500 to-cyan-500 text-white relative overflow-hidden"
>
<!-- Background pattern -->
<div class="absolute inset-0 opacity-10">
<div class="absolute inset-0 grid-pattern" />
</div>
<div class="relative z-10">
<div
class="w-14 h-14 rounded-2xl bg-white/20 backdrop-blur-sm flex items-center justify-center mb-6 group-hover:scale-110 transition-transform"
>
<UIcon name="i-lucide-route" class="w-7 h-7 text-white" />
</div>
<h3 class="font-heading text-2xl sm:text-3xl font-bold mb-4">Geführter Mitbestimmungsprozess</h3>
<p class="text-white/90 text-lg leading-relaxed mb-6">
Vorgegebene, erweiterbare Eingabeparameter strukturieren den gesamten Ablauf von der Systembeschreibung
bis zur Vereinbarung.
</p>
<!-- Visual element -->
<div class="flex items-center gap-3 mt-8">
<div class="flex -space-x-2">
<div class="w-8 h-8 rounded-full bg-white/30 flex items-center justify-center text-xs font-bold">1</div>
<div class="w-8 h-8 rounded-full bg-white/30 flex items-center justify-center text-xs font-bold">2</div>
<div class="w-8 h-8 rounded-full bg-white/30 flex items-center justify-center text-xs font-bold">3</div>
<div class="w-8 h-8 rounded-full bg-white/30 flex items-center justify-center text-xs font-bold">4</div>
</div>
<span class="text-sm text-white/80">Strukturierte Prozessschritte</span>
</div>
</div>
</div>
</div>
<!-- Regular cards -->
<div
v-for="(feature, index) in features.slice(1, 5)"
:key="index"
class="group card-spotlight animate-fade-in-up"
:style="{ animationDelay: `${(index + 1) * 100}ms` }"
@mousemove="handleMouseMove"
>
<div
class="h-full p-6 rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 hover:border-primary-300 dark:hover:border-primary-700 transition-all hover:shadow-xl hover:shadow-primary-500/10"
>
<div
class="w-12 h-12 rounded-xl bg-gradient-to-br from-primary-100 to-cyan-100 dark:from-primary-900/50 dark:to-cyan-900/50 flex items-center justify-center mb-4 group-hover:scale-110 transition-transform"
>
<UIcon :name="feature.icon" class="w-6 h-6 text-primary-600 dark:text-primary-400" />
</div>
<h3 class="font-heading text-lg font-bold text-gray-900 dark:text-white mb-2">{{ feature.title }}</h3>
<p class="text-sm text-gray-600 dark:text-gray-300 leading-relaxed">{{ feature.description }}</p>
</div>
</div>
<!-- Tall card -->
<div
class="bento-item-tall group card-spotlight animate-fade-in-up"
style="animation-delay: 500ms"
@mousemove="handleMouseMove"
>
<div
class="h-full p-6 rounded-2xl bg-gradient-to-b from-accent-50 to-violet-50 dark:from-accent-950/50 dark:to-violet-950/50 border border-accent-200 dark:border-accent-800 hover:shadow-xl hover:shadow-accent-500/10 transition-all"
>
<div
class="w-12 h-12 rounded-xl bg-gradient-to-br from-accent-500 to-violet-500 flex items-center justify-center mb-4 group-hover:scale-110 transition-transform shadow-lg shadow-accent-500/25"
>
<UIcon name="i-lucide-history" class="w-6 h-6 text-white" />
</div>
<h3 class="font-heading text-lg font-bold text-gray-900 dark:text-white mb-2">Versionierung & Audit-Trail</h3>
<p class="text-sm text-gray-600 dark:text-gray-300 leading-relaxed mb-6">
Änderungen werden versioniert und lückenlos nachvollziehbar dokumentiert inklusive Historie und Vergleich.
</p>
<!-- Visual timeline -->
<div class="space-y-3 mt-auto">
<div class="flex items-center gap-3">
<div class="w-2 h-2 rounded-full bg-accent-500" />
<div class="flex-1 h-px bg-accent-200 dark:bg-accent-800" />
<span class="text-xs text-accent-600 dark:text-accent-400">v1.0</span>
</div>
<div class="flex items-center gap-3">
<div class="w-2 h-2 rounded-full bg-accent-500" />
<div class="flex-1 h-px bg-accent-200 dark:bg-accent-800" />
<span class="text-xs text-accent-600 dark:text-accent-400">v1.1</span>
</div>
<div class="flex items-center gap-3">
<div class="w-3 h-3 rounded-full bg-accent-500 ring-4 ring-accent-200 dark:ring-accent-800" />
<div class="flex-1 h-px bg-accent-300 dark:bg-accent-700" />
<span class="text-xs font-semibold text-accent-700 dark:text-accent-300">v2.0</span>
</div>
</div>
</div>
</div>
<!-- Wide card -->
<div
class="bento-item-wide group card-spotlight animate-fade-in-up"
style="animation-delay: 600ms"
@mousemove="handleMouseMove"
>
<div
class="h-full p-6 rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 hover:border-primary-300 dark:hover:border-primary-700 transition-all hover:shadow-xl hover:shadow-primary-500/10"
>
<div class="flex flex-col sm:flex-row sm:items-start gap-6">
<div
class="w-12 h-12 rounded-xl bg-gradient-to-br from-primary-100 to-cyan-100 dark:from-primary-900/50 dark:to-cyan-900/50 flex items-center justify-center shrink-0 group-hover:scale-110 transition-transform"
>
<UIcon name="i-lucide-file-text" class="w-6 h-6 text-primary-600 dark:text-primary-400" />
</div>
<div>
<h3 class="font-heading text-lg font-bold text-gray-900 dark:text-white mb-2">
Automatische BV-/DV-Generierung
</h3>
<p class="text-sm text-gray-600 dark:text-gray-300 leading-relaxed">
Nach Abschluss der Eingaben erzeugt das System strukturierte, übersichtliche und signaturbereite
Betriebs-/Dienstvereinbarungen.
</p>
</div>
</div>
</div>
</div>
<!-- Remaining cards -->
<div
v-for="(feature, index) in features.slice(5)"
:key="index + 5"
class="group card-spotlight animate-fade-in-up"
:style="{ animationDelay: `${(index + 7) * 100}ms` }"
@mousemove="handleMouseMove"
>
<div
class="h-full p-6 rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 hover:border-primary-300 dark:hover:border-primary-700 transition-all hover:shadow-xl hover:shadow-primary-500/10"
>
<div
class="w-12 h-12 rounded-xl bg-gradient-to-br from-primary-100 to-cyan-100 dark:from-primary-900/50 dark:to-cyan-900/50 flex items-center justify-center mb-4 group-hover:scale-110 transition-transform"
>
<UIcon :name="feature.icon" class="w-6 h-6 text-primary-600 dark:text-primary-400" />
</div>
<h3 class="font-heading text-lg font-bold text-gray-900 dark:text-white mb-2">{{ feature.title }}</h3>
<p class="text-sm text-gray-600 dark:text-gray-300 leading-relaxed">{{ feature.description }}</p>
</div>
</div>
</div>
</UPageSection>
</template>
<script setup lang="ts">
const gridRef = ref<HTMLElement | null>(null)
// Spotlight effect handler
function handleMouseMove(event: MouseEvent) {
const card = event.currentTarget as HTMLElement
const rect = card.getBoundingClientRect()
const x = ((event.clientX - rect.left) / rect.width) * 100
const y = ((event.clientY - rect.top) / rect.height) * 100
card.style.setProperty('--mouse-x', `${x}%`)
card.style.setProperty('--mouse-y', `${y}%`)
}
const features = [
{
icon: 'i-lucide-route',
title: 'Geführter Mitbestimmungsprozess',
description:
'Vorgegebene, erweiterbare Eingabeparameter strukturieren den gesamten Ablauf von der Systembeschreibung bis zur Vereinbarung.'
},
{
icon: 'i-lucide-shield-alert',
title: 'Risikobasierter Assistent',
description:
'Ein regelbasierter, risikoorientierter Assistent passt die Eingabemaske an Komplexität, Umfang und Potenziale zur Leistungs-/Verhaltensauswertung an.'
},
{
icon: 'i-lucide-gauge',
title: 'Ampelsystem & Direktfeedback',
description:
'Kritikalität wird transparent bewertet und direkt beim Ausfüllen zurückgespielt für schnelle Orientierung und weniger Schleifen.'
},
{
icon: 'i-lucide-message-square',
title: 'Zusammenarbeit per Kommentaren',
description: 'Inline-Kommentare ermöglichen Abstimmung direkt an einzelnen Inhalten ohne Medienbrüche.'
},
{
icon: 'i-lucide-history',
title: 'Versionierung & Audit-Trail',
description:
'Änderungen werden versioniert und lückenlos nachvollziehbar dokumentiert inklusive Historie und Vergleich.'
},
{
icon: 'i-lucide-pen-tool',
title: 'Signaturfähig mit QES (eIDAS)',
description: 'Optional rechtsverbindliche Unterzeichnung per qualifizierter elektronischer Signatur nach eIDAS.'
},
{
icon: 'i-lucide-bell',
title: 'Benachrichtigungen & News-Center',
description: 'Aktuell bleiben über Status-Updates, Änderungen und Aufgaben per Nachrichten-Center und E-Mail.'
},
{
icon: 'i-lucide-shield-check',
title: 'SSO & Governance',
description:
'SSO-Integration via SAML oder OIDC sowie ein umfangreich konfigurierbares Rollen- und Berechtigungskonzept.'
}
]
</script>

View File

@@ -0,0 +1,210 @@
<template>
<UPageSection
:ui="{
root: 'py-16 lg:py-20 scroll-mt-20'
}"
>
<div class="grid lg:grid-cols-2 gap-12 lg:gap-16 items-center">
<!-- Left: Content -->
<div class="order-2 lg:order-1">
<span
class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-accent-100 dark:bg-accent-900/30 text-accent-700 dark:text-accent-300 text-sm font-medium mb-6"
>
<UIcon name="i-lucide-file-text" class="w-4 h-4" />
Optional verfügbar
</span>
<h2
class="font-heading text-3xl sm:text-4xl lg:text-5xl text-pretty tracking-tight font-bold text-gray-900 dark:text-white mb-6"
>
Rahmenbetriebsvereinbarung <span class="gradient-text">IT/KI</span>
</h2>
<p class="text-lg text-gray-600 dark:text-gray-300 mb-8">
Für den Einstieg stellen wir auf Nachfrage eine optionale Rahmenbetriebs-/Rahmendienstvereinbarung für IT- und
KI-Systeme bereit. Sie ist auf die Struktur des Tools zugeschnitten und enthält praxiserprobte
Regelungsbausteine.
</p>
<!-- Animated checklist -->
<ul class="space-y-4 mb-8">
<li
v-for="(point, index) in bulletPoints"
:key="index"
class="flex gap-4 animate-fade-in-up"
:style="{ animationDelay: `${index * 100}ms` }"
>
<div
class="mt-1 w-6 h-6 rounded-full bg-gradient-to-br from-primary-500 to-cyan-500 flex items-center justify-center shrink-0"
>
<UIcon name="i-lucide-check" class="w-3.5 h-3.5 text-white" />
</div>
<p class="text-gray-700 dark:text-gray-300">{{ point }}</p>
</li>
</ul>
<!-- Price info -->
<div
class="p-4 rounded-xl bg-gradient-to-r from-primary-50 to-cyan-50 dark:from-primary-950/50 dark:to-cyan-950/50 border border-primary-200 dark:border-primary-800"
>
<div class="flex items-center gap-3">
<div
class="w-10 h-10 rounded-xl bg-gradient-to-br from-primary-500 to-cyan-500 flex items-center justify-center"
>
<UIcon name="i-lucide-tag" class="w-5 h-5 text-white" />
</div>
<div>
<p class="text-sm text-gray-500 dark:text-gray-400">Preis</p>
<p class="font-heading text-lg font-bold text-gray-900 dark:text-white">Auf Anfrage</p>
</div>
</div>
</div>
<!-- CTA -->
<div class="mt-8">
<UButton
to="#kontakt"
size="xl"
class="btn-gradient px-8 py-4 text-lg font-semibold rounded-xl shadow-lg shadow-primary-500/25"
>
<span>Mehr erfahren</span>
<UIcon name="i-lucide-arrow-right" class="w-5 h-5 ml-2" />
</UButton>
</div>
</div>
<!-- Right: 3D Document Preview -->
<div class="order-1 lg:order-2 flex justify-center">
<div class="relative animate-scale-in">
<!-- 3D Document with tilt effect -->
<div
class="relative transform-gpu transition-transform duration-500 hover:rotate-0"
style="transform: perspective(1000px) rotateY(-8deg) rotateX(5deg)"
@mouseenter="isHovered = true"
@mouseleave="isHovered = false"
>
<!-- Shadow layer -->
<div
class="absolute inset-0 bg-gray-900/20 dark:bg-black/40 blur-2xl rounded-3xl translate-x-4 translate-y-4"
/>
<!-- Document card -->
<div
class="relative bg-white dark:bg-gray-900 rounded-2xl border border-gray-200 dark:border-gray-700 shadow-2xl overflow-hidden max-w-sm"
>
<!-- Document header -->
<div class="bg-gradient-to-r from-primary-600 to-cyan-600 px-6 py-5">
<div class="flex items-center gap-4">
<div class="w-12 h-12 rounded-xl bg-white/20 backdrop-blur-sm flex items-center justify-center">
<UIcon name="i-lucide-file-text" class="w-6 h-6 text-white" />
</div>
<div>
<h4 class="font-heading font-bold text-white text-lg">Rahmen-BV IT/KI</h4>
<p class="text-sm text-white/80">Betriebsvereinbarung Vorlage</p>
</div>
</div>
</div>
<!-- Document content preview -->
<div class="p-6">
<!-- Table of contents -->
<div class="space-y-4">
<div class="text-xs uppercase tracking-wider text-gray-500 dark:text-gray-400 font-semibold">
Inhaltsverzeichnis
</div>
<!-- Section items with staggered animation -->
<div
v-for="(section, index) in documentSections"
:key="index"
class="group flex items-center gap-3 p-3 rounded-xl bg-gray-50 dark:bg-gray-800 hover:bg-primary-50 dark:hover:bg-primary-900/20 transition-colors cursor-pointer"
:class="{ 'animate-fade-in-up': isHovered }"
:style="{ animationDelay: `${index * 100}ms` }"
>
<div
class="w-8 h-8 rounded-lg bg-gradient-to-br from-primary-100 to-cyan-100 dark:from-primary-900/50 dark:to-cyan-900/50 flex items-center justify-center text-sm font-bold text-primary-600 dark:text-primary-400 group-hover:scale-110 transition-transform"
>
{{ index + 1 }}
</div>
<div class="flex-1 min-w-0">
<div class="text-sm font-medium text-gray-900 dark:text-white truncate">{{ section.title }}</div>
<div class="text-xs text-gray-500 dark:text-gray-400 truncate">{{ section.description }}</div>
</div>
<UIcon
:name="section.icon"
class="w-4 h-4 text-gray-400 group-hover:text-primary-500 transition-colors"
/>
</div>
</div>
<!-- Footer info -->
<div class="mt-6 pt-4 border-t border-gray-200 dark:border-gray-700">
<div class="flex items-center justify-between">
<div class="flex items-center gap-2">
<UIcon name="i-lucide-layers" class="w-4 h-4 text-gray-400" />
<span class="text-xs text-gray-500 dark:text-gray-400">12 Regelungsbausteine</span>
</div>
<UBadge color="success" variant="soft" size="sm">
<UIcon name="i-lucide-check-circle" class="w-3 h-3 mr-1" />
Praxiserprobt
</UBadge>
</div>
</div>
</div>
</div>
<!-- Floating badge -->
<div class="absolute -top-4 -right-4 z-10 animate-float-fast">
<div
class="bg-gradient-to-r from-accent-500 to-violet-500 text-white px-4 py-2 rounded-full shadow-lg text-sm font-semibold flex items-center gap-2"
>
<UIcon name="i-lucide-download" class="w-4 h-4" />
Auf Anfrage
</div>
</div>
</div>
<!-- Decorative elements -->
<div class="absolute -top-8 -left-8 w-32 h-32 bg-primary-400/20 rounded-full blur-3xl animate-pulse-glow" />
<div
class="absolute -bottom-8 -right-8 w-40 h-40 bg-accent-400/20 rounded-full blur-3xl animate-pulse-glow"
style="animation-delay: 1s"
/>
</div>
</div>
</div>
</UPageSection>
</template>
<script setup lang="ts">
const isHovered = ref(false)
const bulletPoints = [
'Vorlage für eine Rahmen-BV/DV zu IT- und KI-Systemen',
'Auf die Tool-Logik und Dokumentationsstruktur zugeschnitten',
'Enthält praxiserprobte Regelungsbausteine als Startpunkt für systembezogene Vereinbarungen'
]
const documentSections = [
{
title: 'Geltungsbereich',
description: 'Definition der betroffenen Systeme',
icon: 'i-lucide-target'
},
{
title: 'Mitbestimmungsverfahren',
description: 'Prozessschritte und Zuständigkeiten',
icon: 'i-lucide-git-branch'
},
{
title: 'Datenschutz & Kontrolle',
description: 'Schutzmaßnahmen und Auswertungen',
icon: 'i-lucide-shield'
},
{
title: 'Änderungsmanagement',
description: 'Updates und Erweiterungen',
icon: 'i-lucide-refresh-cw'
}
]
</script>

View File

@@ -0,0 +1,263 @@
<template>
<section class="relative min-h-screen flex items-center justify-center overflow-hidden hero-gradient-light">
<!-- Animated gradient orbs -->
<div class="absolute inset-0 overflow-hidden pointer-events-none">
<!-- Large teal orb -->
<div
class="gradient-orb gradient-orb-teal w-[600px] h-[600px] -top-40 -left-40 animate-orb-float"
style="animation-delay: 0s"
/>
<!-- Violet orb -->
<div
class="gradient-orb gradient-orb-violet w-[500px] h-[500px] top-1/4 -right-32 animate-orb-float"
style="animation-delay: 3s"
/>
<!-- Cyan orb -->
<div
class="gradient-orb gradient-orb-cyan w-[400px] h-[400px] bottom-0 left-1/4 animate-orb-float"
style="animation-delay: 6s"
/>
<!-- Small accent orb -->
<div
class="gradient-orb gradient-orb-violet w-[200px] h-[200px] top-1/2 left-10 animate-orb-float opacity-40"
style="animation-delay: 9s"
/>
<!-- Grid pattern overlay -->
<div class="absolute inset-0 grid-pattern opacity-30" />
</div>
<!-- Content -->
<div class="relative z-10 w-full max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-20 lg:py-32">
<div class="text-center max-w-4xl mx-auto">
<!-- Badge -->
<div class="animate-fade-in-up mb-8">
<span
class="inline-flex items-center gap-2 px-4 py-2 rounded-full glass text-sm font-medium text-gray-700 dark:text-gray-200"
>
<span class="relative flex h-2 w-2">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-primary-400 opacity-75" />
<span class="relative inline-flex rounded-full h-2 w-2 bg-primary-500" />
</span>
Jetzt verfügbar
</span>
</div>
<!-- Title with gradient text -->
<h1 class="font-heading text-4xl sm:text-5xl md:text-6xl lg:text-7xl tracking-tight mb-6">
<span class="animate-fade-in-up block text-gray-900 dark:text-white" style="animation-delay: 100ms">
Digitale Mitbestimmung
</span>
<span class="animate-fade-in-up block gradient-text" style="animation-delay: 200ms">
für IT- und KI-Systeme
</span>
</h1>
<!-- Description -->
<p
class="animate-fade-in-up text-lg sm:text-xl text-gray-600 dark:text-gray-300 max-w-2xl mx-auto mb-10"
style="animation-delay: 300ms"
>
{{ description }}
</p>
<!-- CTA Buttons -->
<div class="flex flex-wrap justify-center gap-4 animate-fade-in-up" style="animation-delay: 400ms">
<UButton
size="xl"
to="#kontakt"
trailing-icon="i-lucide-arrow-right"
class="btn-gradient px-8 py-4 text-lg font-semibold rounded-xl shadow-lg shadow-primary-500/25 hover:shadow-xl hover:shadow-primary-500/30 transition-all"
>
<span>Demo anfragen</span>
</UButton>
<UButton
size="xl"
to="#features"
variant="outline"
class="btn-outline-gradient px-8 py-4 text-lg font-semibold rounded-xl"
>
Features entdecken
</UButton>
</div>
</div>
<!-- Floating product preview cards -->
<div class="mt-16 lg:mt-24 relative animate-scale-in" style="animation-delay: 600ms">
<div class="flex flex-col lg:flex-row items-center justify-center gap-6 lg:gap-8">
<!-- Left card - tilted -->
<div class="card-3d w-full max-w-xs lg:-mr-8 lg:mt-12 order-2 lg:order-1">
<div
class="card-3d-inner glass rounded-2xl p-5 shadow-xl transform lg:-rotate-6 hover:rotate-0 transition-transform duration-500"
>
<div class="flex items-center gap-3 mb-4">
<div
class="w-10 h-10 rounded-xl bg-gradient-to-br from-warning-400 to-warning-500 flex items-center justify-center"
>
<UIcon name="i-lucide-alert-triangle" class="w-5 h-5 text-white" />
</div>
<div>
<p class="font-semibold text-gray-900 dark:text-white text-sm">Risikoprüfung</p>
<p class="text-xs text-gray-500 dark:text-gray-400">3 Punkte offen</p>
</div>
</div>
<div class="space-y-2">
<div class="flex items-center gap-2">
<div class="w-4 h-4 rounded bg-warning-100 dark:bg-warning-900/50 flex items-center justify-center">
<UIcon name="i-lucide-clock" class="w-2.5 h-2.5 text-warning-600" />
</div>
<span class="text-xs text-gray-600 dark:text-gray-300">Datenschutz-Folgenabschätzung</span>
</div>
<div class="flex items-center gap-2">
<div class="w-4 h-4 rounded bg-warning-100 dark:bg-warning-900/50 flex items-center justify-center">
<UIcon name="i-lucide-clock" class="w-2.5 h-2.5 text-warning-600" />
</div>
<span class="text-xs text-gray-600 dark:text-gray-300">Leistungskontrolle prüfen</span>
</div>
<div class="flex items-center gap-2">
<div class="w-4 h-4 rounded bg-success-100 dark:bg-success-900/50 flex items-center justify-center">
<UIcon name="i-lucide-check" class="w-2.5 h-2.5 text-success-600" />
</div>
<span class="text-xs text-gray-600 dark:text-gray-300">Zugriffsrechte definiert</span>
</div>
</div>
</div>
</div>
<!-- Center card - main -->
<div class="w-full max-w-md z-10 order-1 lg:order-2">
<div class="glass rounded-2xl overflow-hidden shadow-2xl border border-white/50 dark:border-white/10">
<!-- Mock header -->
<div
class="flex items-center justify-between px-5 py-4 bg-white/50 dark:bg-gray-900/50 border-b border-gray-200/50 dark:border-gray-700/50"
>
<div class="flex items-center gap-3">
<div
class="w-8 h-8 rounded-lg bg-gradient-to-br from-primary-500 to-cyan-500 flex items-center justify-center"
>
<UIcon name="i-lucide-file-text" class="w-4 h-4 text-white" />
</div>
<div>
<p class="font-semibold text-gray-900 dark:text-white text-sm">Microsoft 365</p>
<p class="text-xs text-gray-500 dark:text-gray-400">Betriebsvereinbarung</p>
</div>
</div>
<UBadge color="primary" variant="soft" size="sm">In Bearbeitung</UBadge>
</div>
<!-- Mock content -->
<div class="p-5 space-y-4">
<!-- Progress section -->
<div>
<div class="flex justify-between text-sm mb-2">
<span class="text-gray-600 dark:text-gray-300 font-medium">Fortschritt</span>
<span class="text-primary-600 dark:text-primary-400 font-semibold">67%</span>
</div>
<div class="h-2 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden">
<div class="h-full w-[67%] bg-gradient-to-r from-primary-500 to-cyan-500 rounded-full" />
</div>
</div>
<!-- Status items -->
<div class="grid grid-cols-2 gap-3">
<div
class="flex items-center gap-2 p-3 rounded-xl bg-success-50 dark:bg-success-900/20 border border-success-200 dark:border-success-800"
>
<UIcon name="i-lucide-check-circle" class="w-5 h-5 text-success-500" />
<div>
<p class="text-xs font-medium text-success-700 dark:text-success-300">8 Abschnitte</p>
<p class="text-xs text-success-600 dark:text-success-400">abgeschlossen</p>
</div>
</div>
<div
class="flex items-center gap-2 p-3 rounded-xl bg-primary-50 dark:bg-primary-900/20 border border-primary-200 dark:border-primary-800"
>
<UIcon name="i-lucide-message-square" class="w-5 h-5 text-primary-500" />
<div>
<p class="text-xs font-medium text-primary-700 dark:text-primary-300">4 Kommentare</p>
<p class="text-xs text-primary-600 dark:text-primary-400">neu</p>
</div>
</div>
</div>
<!-- Action button -->
<button
class="w-full py-3 px-4 rounded-xl bg-gradient-to-r from-primary-500 to-cyan-500 text-white font-semibold text-sm hover:from-primary-600 hover:to-cyan-600 transition-all shadow-lg shadow-primary-500/25"
>
Weiter bearbeiten
</button>
</div>
</div>
</div>
<!-- Right card - tilted -->
<div class="card-3d w-full max-w-xs lg:-ml-8 lg:mt-12 order-3">
<div
class="card-3d-inner glass rounded-2xl p-5 shadow-xl transform lg:rotate-6 hover:rotate-0 transition-transform duration-500"
>
<div class="flex items-center gap-3 mb-4">
<div
class="w-10 h-10 rounded-xl bg-gradient-to-br from-success-400 to-success-500 flex items-center justify-center"
>
<UIcon name="i-lucide-check-circle" class="w-5 h-5 text-white" />
</div>
<div>
<p class="font-semibold text-gray-900 dark:text-white text-sm">Abgeschlossen</p>
<p class="text-xs text-gray-500 dark:text-gray-400">Letzte Woche</p>
</div>
</div>
<div class="space-y-2">
<div class="flex items-center justify-between p-2 rounded-lg bg-success-50 dark:bg-success-900/30">
<span class="text-xs text-gray-700 dark:text-gray-200">SAP S/4HANA</span>
<UIcon name="i-lucide-check" class="w-4 h-4 text-success-500" />
</div>
<div class="flex items-center justify-between p-2 rounded-lg bg-success-50 dark:bg-success-900/30">
<span class="text-xs text-gray-700 dark:text-gray-200">Workday HCM</span>
<UIcon name="i-lucide-check" class="w-4 h-4 text-success-500" />
</div>
<div class="flex items-center justify-between p-2 rounded-lg bg-success-50 dark:bg-success-900/30">
<span class="text-xs text-gray-700 dark:text-gray-200">Salesforce CRM</span>
<UIcon name="i-lucide-check" class="w-4 h-4 text-success-500" />
</div>
</div>
</div>
</div>
</div>
<!-- Floating notification - positioned above all cards with higher z-index -->
<div
class="absolute top-0 right-8 lg:right-16 xl:right-24 z-20 animate-float-slow hidden lg:block"
style="animation-delay: 1s"
>
<div class="glass rounded-xl px-4 py-3 shadow-lg flex items-center gap-3">
<div
class="w-8 h-8 rounded-full bg-gradient-to-br from-success-400 to-success-500 flex items-center justify-center"
>
<UIcon name="i-lucide-sparkles" class="w-4 h-4 text-white" />
</div>
<div>
<p class="text-sm font-semibold text-gray-900 dark:text-white">BV erstellt!</p>
<p class="text-xs text-gray-500 dark:text-gray-400">Bereit zur Unterschrift</p>
</div>
</div>
</div>
</div>
</div>
<!-- Scroll indicator -->
<div class="absolute bottom-8 left-1/2 -translate-x-1/2 animate-bounce">
<a
href="#betriebsraete"
class="flex items-center justify-center w-12 h-12 rounded-full glass text-gray-600 dark:text-gray-300 hover:bg-white/80 dark:hover:bg-gray-800/80 transition-colors"
aria-label="Nach unten scrollen"
>
<UIcon name="i-lucide-chevron-down" class="w-6 h-6" />
</a>
</div>
</section>
</template>
<script setup lang="ts">
const description =
'Struktur statt Hauruck: Alle relevanten Informationen an einem Ort, klare Prozessschritte und nachvollziehbare Dokumentation damit Mitbestimmung schneller, belastbarer und dauerhaft updatefähig wird.'
</script>

View File

@@ -0,0 +1,187 @@
<template>
<section id="newsletter" class="relative py-16 lg:py-20 overflow-hidden scroll-mt-20">
<!-- Background with gradient and particles -->
<div
class="absolute inset-0 bg-gradient-to-br from-primary-50 via-cyan-50 to-accent-50 dark:from-gray-950 dark:via-primary-950/30 dark:to-accent-950/30"
/>
<!-- Animated particles -->
<div class="absolute inset-0 overflow-hidden pointer-events-none">
<div class="particle" />
<div class="particle" />
<div class="particle" />
<div class="particle" />
<div class="particle" />
<div class="particle" />
<div class="particle" />
<div class="particle" />
</div>
<!-- Gradient orbs -->
<div class="absolute top-0 left-1/4 w-96 h-96 bg-primary-400/20 rounded-full blur-3xl animate-orb-float" />
<div
class="absolute bottom-0 right-1/4 w-80 h-80 bg-accent-400/20 rounded-full blur-3xl animate-orb-float"
style="animation-delay: 3s"
/>
<div class="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<!-- Glass card -->
<div class="max-w-2xl mx-auto">
<div class="glass rounded-3xl p-8 sm:p-12 shadow-2xl">
<!-- Icon -->
<div class="flex justify-center mb-6">
<div
class="w-16 h-16 rounded-2xl bg-gradient-to-br from-primary-500 to-cyan-500 flex items-center justify-center animate-float-slow shadow-lg shadow-primary-500/25"
>
<UIcon name="i-lucide-mail" class="w-8 h-8 text-white" />
</div>
</div>
<!-- Title -->
<h2
class="font-heading text-3xl sm:text-4xl font-bold text-center text-gray-900 dark:text-white mb-4 animate-fade-in-up"
>
Bleiben Sie <span class="gradient-text">informiert</span>
</h2>
<!-- Description -->
<p
class="text-center text-lg text-gray-600 dark:text-gray-300 mb-8 animate-fade-in-up"
style="animation-delay: 100ms"
>
Erhalten Sie Updates zur Entwicklung von LegalConsentHub und seien Sie unter den Ersten, die von neuen
Funktionen erfahren.
</p>
<!-- Form -->
<UForm
:state="formState"
:schema="schema"
class="animate-fade-in-up"
style="animation-delay: 200ms"
@submit="onSubmit"
>
<div class="flex flex-col sm:flex-row gap-3">
<UFormField name="email" class="flex-1">
<UInput
v-model="formState.email"
type="email"
placeholder="Ihre E-Mail-Adresse"
size="xl"
:disabled="isLoading || isSuccess"
:ui="{
root: 'w-full',
base: 'rounded-xl bg-white dark:bg-gray-900 border-gray-200 dark:border-gray-700 focus:ring-2 focus:ring-primary-500 focus:border-transparent'
}"
>
<template #leading>
<UIcon name="i-lucide-mail" class="w-5 h-5 text-gray-400" />
</template>
</UInput>
</UFormField>
<UButton
type="submit"
size="xl"
:loading="isLoading"
:disabled="isSuccess"
class="btn-gradient px-8 rounded-xl font-semibold shadow-lg shadow-primary-500/25 whitespace-nowrap"
>
<template v-if="isSuccess">
<UIcon name="i-lucide-check" class="w-5 h-5 mr-2" />
<span>Angemeldet!</span>
</template>
<template v-else>
<span>Anmelden</span>
</template>
</UButton>
</div>
</UForm>
<!-- Success message with animation -->
<Transition
enter-active-class="transition-all duration-500 ease-out"
enter-from-class="opacity-0 scale-95 translate-y-4"
enter-to-class="opacity-100 scale-100 translate-y-0"
leave-active-class="transition-all duration-300 ease-in"
leave-from-class="opacity-100 scale-100 translate-y-0"
leave-to-class="opacity-0 scale-95 translate-y-4"
>
<div
v-if="isSuccess"
class="mt-6 p-4 rounded-xl bg-success-100 dark:bg-success-900/30 border border-success-200 dark:border-success-800"
>
<div class="flex items-center justify-center gap-3 text-success-700 dark:text-success-300">
<div class="w-8 h-8 rounded-full bg-success-500 flex items-center justify-center">
<UIcon name="i-lucide-check" class="w-5 h-5 text-white" />
</div>
<span class="font-medium">Vielen Dank! Wir halten Sie auf dem Laufenden.</span>
</div>
</div>
</Transition>
<!-- Privacy note -->
<p
class="mt-6 text-sm text-center text-gray-500 dark:text-gray-400 animate-fade-in-up"
style="animation-delay: 300ms"
>
Mit der Anmeldung stimmen Sie unserer
<NuxtLink to="/datenschutz" class="text-primary-600 dark:text-primary-400 hover:underline font-medium">
Datenschutzerklärung
</NuxtLink>
zu. Wir versenden keinen Spam.
</p>
<!-- Trust indicators -->
<div
class="mt-8 flex flex-wrap justify-center gap-6 text-sm animate-fade-in-up"
style="animation-delay: 400ms"
>
<div class="flex items-center gap-2 text-gray-600 dark:text-gray-300">
<div class="w-6 h-6 rounded-full bg-success-100 dark:bg-success-900/30 flex items-center justify-center">
<UIcon name="i-lucide-shield-check" class="w-3.5 h-3.5 text-success-600 dark:text-success-400" />
</div>
<span>DSGVO-konform</span>
</div>
<div class="flex items-center gap-2 text-gray-600 dark:text-gray-300">
<div class="w-6 h-6 rounded-full bg-success-100 dark:bg-success-900/30 flex items-center justify-center">
<UIcon name="i-lucide-lock" class="w-3.5 h-3.5 text-success-600 dark:text-success-400" />
</div>
<span>Verschlüsselt</span>
</div>
<div class="flex items-center gap-2 text-gray-600 dark:text-gray-300">
<div class="w-6 h-6 rounded-full bg-success-100 dark:bg-success-900/30 flex items-center justify-center">
<UIcon name="i-lucide-x-circle" class="w-3.5 h-3.5 text-success-600 dark:text-success-400" />
</div>
<span>Kein Spam</span>
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<script setup lang="ts">
import { z } from 'zod'
import type { FormSubmitEvent } from '@nuxt/ui'
const { isLoading, isSuccess, submitEmail } = useNewsletterSignup()
const schema = z.object({
email: z
.string()
.min(1, 'Bitte geben Sie eine E-Mail-Adresse ein')
.email('Bitte geben Sie eine gültige E-Mail-Adresse ein')
})
type Schema = z.output<typeof schema>
const formState = reactive<Partial<Schema>>({
email: ''
})
async function onSubmit(event: FormSubmitEvent<Schema>) {
await submitEmail(event.data.email)
}
</script>

View File

@@ -0,0 +1,122 @@
<template>
<section
class="py-10 lg:py-12 bg-gradient-to-r from-primary-50 via-cyan-50 to-accent-50 dark:from-primary-950/30 dark:via-cyan-950/30 dark:to-accent-950/30"
>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<!-- Stats grid -->
<div class="grid grid-cols-2 lg:grid-cols-4 gap-8 lg:gap-12">
<div
v-for="(stat, index) in stats"
:key="index"
class="text-center animate-fade-in-up"
:style="{ animationDelay: `${index * 100}ms` }"
>
<div class="relative inline-block mb-3">
<!-- Animated number -->
<span ref="counterRefs" class="font-heading text-4xl sm:text-5xl lg:text-6xl font-bold gradient-text">
{{ animatedValues[index] }}{{ stat.suffix }}
</span>
<!-- Decorative glow -->
<div class="absolute -inset-4 bg-primary-400/20 blur-2xl rounded-full -z-10 animate-pulse-glow" />
</div>
<p class="text-sm sm:text-base text-gray-600 dark:text-gray-300 font-medium">
{{ stat.label }}
</p>
</div>
</div>
<!-- Trust badges -->
<div class="mt-10 pt-8 border-t border-gray-200 dark:border-gray-800">
<p class="text-center text-sm text-gray-500 dark:text-gray-400 mb-8">Vertrauen & Sicherheit</p>
<div class="flex flex-wrap justify-center items-center gap-8 lg:gap-12">
<div
v-for="(badge, index) in trustBadges"
:key="index"
class="flex items-center gap-3 px-4 py-2 rounded-full bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 shadow-sm hover:shadow-md transition-shadow animate-fade-in-up"
:style="{ animationDelay: `${(index + 4) * 100}ms` }"
>
<div
class="w-8 h-8 rounded-full bg-gradient-to-br from-primary-100 to-cyan-100 dark:from-primary-900/50 dark:to-cyan-900/50 flex items-center justify-center"
>
<UIcon :name="badge.icon" class="w-4 h-4 text-primary-600 dark:text-primary-400" />
</div>
<span class="text-sm font-medium text-gray-700 dark:text-gray-200">{{ badge.label }}</span>
</div>
</div>
</div>
</div>
</section>
</template>
<script setup lang="ts">
const stats = [
{ value: 70, suffix: '%', label: 'Zeitersparnis im Verfahren' },
{ value: 100, suffix: '%', label: 'Revisionssicher dokumentiert' },
{ value: 24, suffix: '/7', label: 'Verfügbarkeit' },
{ value: 0, suffix: '', label: 'Medienbrüche' }
]
const trustBadges = [
{ icon: 'i-lucide-shield-check', label: 'DSGVO-konform' },
{ icon: 'i-lucide-server', label: 'Hosting in Deutschland' },
{ icon: 'i-lucide-lock', label: 'Ende-zu-Ende verschlüsselt' },
{ icon: 'i-lucide-key', label: 'SSO-fähig' }
]
// Animated counter values
const animatedValues = ref(stats.map(() => 0))
const hasAnimated = ref(false)
// Counter animation function
function animateCounter(index: number, target: number, duration: number = 2000) {
const start = 0
const startTime = performance.now()
function update(currentTime: number) {
const elapsed = currentTime - startTime
const progress = Math.min(elapsed / duration, 1)
// Easing function (ease-out cubic)
const easeOut = 1 - Math.pow(1 - progress, 3)
animatedValues.value[index] = Math.round(start + (target - start) * easeOut)
if (progress < 1) {
requestAnimationFrame(update)
}
}
requestAnimationFrame(update)
}
// Start animation when section is visible
onMounted(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting && !hasAnimated.value) {
hasAnimated.value = true
stats.forEach((stat, index) => {
setTimeout(() => {
animateCounter(index, stat.value)
}, index * 200)
})
}
})
},
{ threshold: 0.3 }
)
const section = document.querySelector('section')
if (section) {
observer.observe(section)
}
onUnmounted(() => {
observer.disconnect()
})
})
</script>