feat(landing): Add landing Nuxt page
This commit is contained in:
123
landing/app/components/landing/AdditionalFeatures.vue
Normal file
123
landing/app/components/landing/AdditionalFeatures.vue
Normal 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>
|
||||
101
landing/app/components/landing/AnimatedBackground.vue
Normal file
101
landing/app/components/landing/AnimatedBackground.vue
Normal 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>
|
||||
185
landing/app/components/landing/BenefitsCompany.vue
Normal file
185
landing/app/components/landing/BenefitsCompany.vue
Normal 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>
|
||||
209
landing/app/components/landing/BenefitsWorksCouncil.vue
Normal file
209
landing/app/components/landing/BenefitsWorksCouncil.vue
Normal 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>
|
||||
175
landing/app/components/landing/ExpertAccess.vue
Normal file
175
landing/app/components/landing/ExpertAccess.vue
Normal 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>
|
||||
242
landing/app/components/landing/FeaturesGrid.vue
Normal file
242
landing/app/components/landing/FeaturesGrid.vue
Normal 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>
|
||||
210
landing/app/components/landing/FrameworkAgreement.vue
Normal file
210
landing/app/components/landing/FrameworkAgreement.vue
Normal 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>
|
||||
263
landing/app/components/landing/HeroSection.vue
Normal file
263
landing/app/components/landing/HeroSection.vue
Normal 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>
|
||||
187
landing/app/components/landing/NewsletterSignup.vue
Normal file
187
landing/app/components/landing/NewsletterSignup.vue
Normal 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>
|
||||
122
landing/app/components/landing/StatsSection.vue
Normal file
122
landing/app/components/landing/StatsSection.vue
Normal 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>
|
||||
Reference in New Issue
Block a user