feat(landing): Add i18n
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<UApp>
|
||||
<!-- Skip link for accessibility -->
|
||||
<a href="#main-content" class="skip-link"> Zum Hauptinhalt springen </a>
|
||||
<a href="#main-content" class="skip-link"> {{ $t('common.skipToContent') }} </a>
|
||||
|
||||
<NuxtRouteAnnouncer />
|
||||
|
||||
@@ -40,6 +40,14 @@
|
||||
/>
|
||||
|
||||
<template #right>
|
||||
<USelectMenu
|
||||
v-model="selectedLocale"
|
||||
:items="localeItems"
|
||||
class="w-[100px]"
|
||||
:ui="{
|
||||
base: 'text-sm'
|
||||
}"
|
||||
/>
|
||||
<UColorModeButton
|
||||
:ui="{
|
||||
base: 'text-gray-600 dark:text-gray-300 hover:text-primary-600 dark:hover:text-primary-400'
|
||||
@@ -49,7 +57,7 @@
|
||||
to="#newsletter"
|
||||
class="btn-gradient px-5 py-2.5 rounded-xl font-semibold shadow-lg shadow-primary-500/25 hover:shadow-primary-500/40 transition-shadow"
|
||||
>
|
||||
<span>Informiert bleiben</span>
|
||||
<span>{{ $t('common.stayInformed') }}</span>
|
||||
</UButton>
|
||||
</template>
|
||||
|
||||
@@ -64,7 +72,7 @@
|
||||
/>
|
||||
<div class="mt-6 pt-6 border-t border-gray-200 dark:border-gray-800">
|
||||
<UButton to="#newsletter" size="lg" block class="btn-gradient rounded-xl font-semibold">
|
||||
Informiert bleiben
|
||||
{{ $t('common.stayInformed') }}
|
||||
</UButton>
|
||||
</div>
|
||||
</template>
|
||||
@@ -90,7 +98,7 @@
|
||||
<span class="font-heading text-xl font-bold text-gray-900 dark:text-white"> LegalConsentHub </span>
|
||||
</NuxtLink>
|
||||
<p class="text-gray-600 dark:text-gray-400 max-w-sm mb-6">
|
||||
Digitale Mitbestimmung für IT- und KI-Systeme. Strukturierte Prozesse, revisionssichere Dokumentation.
|
||||
{{ $t('footer.brandDescription') }}
|
||||
</p>
|
||||
<div class="flex items-center gap-3">
|
||||
<UButton
|
||||
@@ -115,7 +123,7 @@
|
||||
|
||||
<!-- Links column -->
|
||||
<div>
|
||||
<h4 class="font-heading font-bold text-gray-900 dark:text-white mb-4">Navigation</h4>
|
||||
<h4 class="font-heading font-bold text-gray-900 dark:text-white mb-4">{{ $t('common.navigation') }}</h4>
|
||||
<ul class="space-y-3">
|
||||
<li v-for="item in navigationItems" :key="item.label">
|
||||
<NuxtLink
|
||||
@@ -130,7 +138,7 @@
|
||||
|
||||
<!-- Legal column -->
|
||||
<div>
|
||||
<h4 class="font-heading font-bold text-gray-900 dark:text-white mb-4">Rechtliches</h4>
|
||||
<h4 class="font-heading font-bold text-gray-900 dark:text-white mb-4">{{ $t('common.legal') }}</h4>
|
||||
<ul class="space-y-3">
|
||||
<li v-for="item in footerLinks" :key="item.label">
|
||||
<NuxtLink
|
||||
@@ -148,16 +156,16 @@
|
||||
<div class="mt-12 pt-8 border-t border-gray-200 dark:border-gray-800">
|
||||
<div class="flex flex-col sm:flex-row justify-between items-center gap-4">
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||
© {{ new Date().getFullYear() }} LegalConsentHub. Alle Rechte vorbehalten.
|
||||
© {{ new Date().getFullYear() }} LegalConsentHub. {{ $t('common.allRightsReserved') }}
|
||||
</p>
|
||||
<div class="flex items-center gap-6 text-sm text-gray-500 dark:text-gray-400">
|
||||
<div class="flex items-center gap-2">
|
||||
<UIcon name="i-lucide-server" class="w-4 h-4" />
|
||||
<span>Hosted in Germany</span>
|
||||
<span>{{ $t('common.hostedInGermany') }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<UIcon name="i-lucide-shield-check" class="w-4 h-4" />
|
||||
<span>DSGVO-konform</span>
|
||||
<span>{{ $t('common.gdprCompliant') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -170,6 +178,26 @@
|
||||
<script setup lang="ts">
|
||||
import type { NavigationMenuItem } from '@nuxt/ui'
|
||||
|
||||
const { t, locale, locales, setLocale } = useI18n()
|
||||
|
||||
// Locale selector items
|
||||
const localeItems = computed(() =>
|
||||
(locales.value as Array<{ code: string; name: string }>).map((l) => ({
|
||||
label: l.name,
|
||||
value: l.code
|
||||
}))
|
||||
)
|
||||
|
||||
// Selected locale for the dropdown
|
||||
const selectedLocale = computed({
|
||||
get: () => localeItems.value.find((l) => l.value === locale.value),
|
||||
set: (item) => {
|
||||
if (item) {
|
||||
setLocale(item.value as 'en' | 'de')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Track scroll position for header styling
|
||||
const isScrolled = ref(false)
|
||||
|
||||
@@ -188,34 +216,34 @@ onMounted(() => {
|
||||
|
||||
const navigationItems = computed<NavigationMenuItem[]>(() => [
|
||||
{
|
||||
label: 'Für Betriebsräte',
|
||||
label: t('nav.forWorksCouncils'),
|
||||
to: '#betriebsraete'
|
||||
},
|
||||
{
|
||||
label: 'Für Unternehmen',
|
||||
label: t('nav.forCompanies'),
|
||||
to: '#unternehmen'
|
||||
},
|
||||
{
|
||||
label: 'Features',
|
||||
label: t('nav.features'),
|
||||
to: '#features'
|
||||
},
|
||||
{
|
||||
label: 'Kontakt',
|
||||
label: t('nav.contact'),
|
||||
to: '#kontakt'
|
||||
}
|
||||
])
|
||||
|
||||
const footerLinks = computed<NavigationMenuItem[]>(() => [
|
||||
{
|
||||
label: 'Impressum',
|
||||
label: t('footer.imprint'),
|
||||
to: '/impressum'
|
||||
},
|
||||
{
|
||||
label: 'Datenschutz',
|
||||
label: t('footer.privacy'),
|
||||
to: '/datenschutz'
|
||||
},
|
||||
{
|
||||
label: 'AGB',
|
||||
label: t('footer.terms'),
|
||||
to: '/agb'
|
||||
}
|
||||
])
|
||||
|
||||
@@ -10,19 +10,20 @@
|
||||
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
|
||||
{{ $t('additionalFeatures.badge') }}
|
||||
</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>
|
||||
{{ $t('additionalFeatures.title', { highlight: '' })
|
||||
}}<span class="gradient-text">{{ $t('additionalFeatures.titleHighlight') }}</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.
|
||||
{{ $t('additionalFeatures.description') }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
@@ -74,50 +75,32 @@
|
||||
|
||||
<!-- 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>
|
||||
<p class="text-gray-500 dark:text-gray-400 mb-4">{{ $t('additionalFeatures.ctaQuestion') }}</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
|
||||
{{ $t('additionalFeatures.ctaButton') }}
|
||||
</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.'
|
||||
}
|
||||
const { t } = useI18n()
|
||||
|
||||
const featureIcons = [
|
||||
'i-lucide-puzzle',
|
||||
'i-lucide-server',
|
||||
'i-lucide-lock',
|
||||
'i-lucide-sparkles',
|
||||
'i-lucide-settings',
|
||||
'i-lucide-headphones'
|
||||
]
|
||||
|
||||
const features = computed(() =>
|
||||
featureIcons.map((icon, index) => ({
|
||||
icon,
|
||||
title: t(`additionalFeatures.items[${index}].title`),
|
||||
description: t(`additionalFeatures.items[${index}].description`)
|
||||
}))
|
||||
)
|
||||
</script>
|
||||
|
||||
@@ -11,19 +11,20 @@
|
||||
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
|
||||
{{ $t('company.badge') }}
|
||||
</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>
|
||||
{{ $t('company.title', { highlight: '' })
|
||||
}}<span class="gradient-text">{{ $t('company.titleHighlight') }}</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.
|
||||
{{ $t('company.description') }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
@@ -38,8 +39,10 @@
|
||||
<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>
|
||||
<h3 class="font-heading text-xl font-bold text-gray-900 dark:text-white">
|
||||
{{ $t('company.awayFrom.title') }}
|
||||
</h3>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">{{ $t('company.awayFrom.subtitle') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -69,8 +72,10 @@
|
||||
<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>
|
||||
<h3 class="font-heading text-xl font-bold text-gray-900 dark:text-white">
|
||||
{{ $t('company.towards.title') }}
|
||||
</h3>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">{{ $t('company.towards.subtitle') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -96,7 +101,8 @@
|
||||
<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>
|
||||
{{ $t('company.highlightsTitle', { highlight: '' })
|
||||
}}<span class="gradient-text">{{ $t('company.highlightsTitleHighlight') }}</span>
|
||||
</h3>
|
||||
|
||||
<div class="grid sm:grid-cols-3 gap-6">
|
||||
@@ -124,62 +130,48 @@
|
||||
</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 { t } = useI18n()
|
||||
|
||||
const painPointIcons = [
|
||||
'i-lucide-refresh-cw',
|
||||
'i-lucide-ban',
|
||||
'i-lucide-files',
|
||||
'i-lucide-puzzle',
|
||||
'i-lucide-help-circle',
|
||||
'i-lucide-hourglass',
|
||||
'i-lucide-wallet'
|
||||
]
|
||||
|
||||
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 benefitIcons = [
|
||||
'i-lucide-calendar-check',
|
||||
'i-lucide-users',
|
||||
'i-lucide-gauge',
|
||||
'i-lucide-thumbs-up',
|
||||
'i-lucide-file-check-2',
|
||||
'i-lucide-sparkles'
|
||||
]
|
||||
|
||||
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.'
|
||||
}
|
||||
]
|
||||
const highlightIcons = ['i-lucide-repeat', 'i-lucide-rocket', 'i-lucide-refresh-cw']
|
||||
|
||||
const painPoints = computed(() =>
|
||||
painPointIcons.map((icon, index) => ({
|
||||
icon,
|
||||
text: t(`company.painPoints[${index}]`)
|
||||
}))
|
||||
)
|
||||
|
||||
const benefits = computed(() =>
|
||||
benefitIcons.map((icon, index) => ({
|
||||
icon,
|
||||
text: t(`company.benefits[${index}]`)
|
||||
}))
|
||||
)
|
||||
|
||||
const highlights = computed(() =>
|
||||
highlightIcons.map((icon, index) => ({
|
||||
icon,
|
||||
title: t(`company.highlights[${index}].title`),
|
||||
description: t(`company.highlights[${index}].description`)
|
||||
}))
|
||||
)
|
||||
</script>
|
||||
|
||||
@@ -11,19 +11,20 @@
|
||||
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
|
||||
{{ $t('worksCouncil.badge') }}
|
||||
</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>
|
||||
{{ $t('worksCouncil.title', { highlight: '' })
|
||||
}}<span class="gradient-text">{{ $t('worksCouncil.titleHighlight') }}</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.
|
||||
{{ $t('worksCouncil.description') }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
@@ -42,7 +43,7 @@
|
||||
@click="activeTab = 'pain'"
|
||||
>
|
||||
<UIcon name="i-lucide-x-circle" class="w-4 h-4 inline mr-2" />
|
||||
Weg von
|
||||
{{ $t('worksCouncil.tabs.awayFrom') }}
|
||||
</button>
|
||||
<button
|
||||
:class="[
|
||||
@@ -54,7 +55,7 @@
|
||||
@click="activeTab = 'benefit'"
|
||||
>
|
||||
<UIcon name="i-lucide-check-circle" class="w-4 h-4 inline mr-2" />
|
||||
Hin zu
|
||||
{{ $t('worksCouncil.tabs.towards') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -117,7 +118,8 @@
|
||||
<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>
|
||||
{{ $t('worksCouncil.highlightsTitle', { highlight: '' })
|
||||
}}<span class="gradient-text">{{ $t('worksCouncil.highlightsTitleHighlight') }}</span>
|
||||
</h3>
|
||||
|
||||
<div class="grid sm:grid-cols-3 gap-6">
|
||||
@@ -145,65 +147,51 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { t } = useI18n()
|
||||
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 painPointIcons = [
|
||||
'i-lucide-search',
|
||||
'i-lucide-git-branch',
|
||||
'i-lucide-timer',
|
||||
'i-lucide-brain',
|
||||
'i-lucide-eye-off',
|
||||
'i-lucide-file-question',
|
||||
'i-lucide-calendar-x'
|
||||
]
|
||||
|
||||
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 benefitIcons = [
|
||||
'i-lucide-layout-list',
|
||||
'i-lucide-route',
|
||||
'i-lucide-file-check',
|
||||
'i-lucide-scan-eye',
|
||||
'i-lucide-git-compare',
|
||||
'i-lucide-clock',
|
||||
'i-lucide-shield-check',
|
||||
'i-lucide-heart-handshake'
|
||||
]
|
||||
|
||||
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.'
|
||||
}
|
||||
]
|
||||
const highlightIcons = ['i-lucide-zap', 'i-lucide-handshake', 'i-lucide-shield']
|
||||
|
||||
const painPoints = computed(() =>
|
||||
painPointIcons.map((icon, index) => ({
|
||||
icon,
|
||||
text: t(`worksCouncil.painPoints[${index}]`)
|
||||
}))
|
||||
)
|
||||
|
||||
const benefits = computed(() =>
|
||||
benefitIcons.map((icon, index) => ({
|
||||
icon,
|
||||
text: t(`worksCouncil.benefits[${index}]`)
|
||||
}))
|
||||
)
|
||||
|
||||
const highlights = computed(() =>
|
||||
highlightIcons.map((icon, index) => ({
|
||||
icon,
|
||||
title: t(`worksCouncil.highlights[${index}].title`),
|
||||
description: t(`worksCouncil.highlights[${index}].description`)
|
||||
}))
|
||||
)
|
||||
</script>
|
||||
|
||||
@@ -30,16 +30,15 @@
|
||||
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
|
||||
{{ $t('expertAccess.badge') }}
|
||||
</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
|
||||
{{ $t('expertAccess.title') }}
|
||||
</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.
|
||||
{{ $t('expertAccess.description') }}
|
||||
</p>
|
||||
|
||||
<!-- CTA buttons -->
|
||||
@@ -52,7 +51,7 @@
|
||||
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
|
||||
{{ $t('expertAccess.cta.contact') }}
|
||||
<UIcon name="i-lucide-arrow-right" class="w-5 h-5 ml-2" />
|
||||
</UButton>
|
||||
<UButton
|
||||
@@ -60,7 +59,7 @@
|
||||
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
|
||||
{{ $t('expertAccess.cta.learnMore') }}
|
||||
</UButton>
|
||||
</div>
|
||||
</div>
|
||||
@@ -125,8 +124,8 @@
|
||||
<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>
|
||||
<h4 class="font-heading font-bold text-white mb-1">{{ $t('expertAccess.experts.labor.title') }}</h4>
|
||||
<p class="text-sm text-white/70">{{ $t('expertAccess.experts.labor.description') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -138,8 +137,10 @@
|
||||
<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>
|
||||
<h4 class="font-heading font-bold text-white mb-1">
|
||||
{{ $t('expertAccess.experts.technical.title') }}
|
||||
</h4>
|
||||
<p class="text-sm text-white/70">{{ $t('expertAccess.experts.technical.description') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -156,8 +157,10 @@
|
||||
<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>
|
||||
<h4 class="font-heading font-bold text-white mb-1">
|
||||
{{ $t('expertAccess.experts.process.title') }}
|
||||
</h4>
|
||||
<p class="text-sm text-white/70">{{ $t('expertAccess.experts.process.description') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -171,5 +174,5 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// No additional script needed
|
||||
// No additional script needed - using $t() from i18n
|
||||
</script>
|
||||
|
||||
@@ -10,24 +10,21 @@
|
||||
<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
|
||||
<UIcon name="i-lucide-sparkles" class="w-4 h-4" />
|
||||
{{ $t('features.badge') }}
|
||||
</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
|
||||
{{ $t('features.title', { highlight: '' })
|
||||
}}<span class="gradient-text">{{ $t('features.titleHighlight') }}</span>
|
||||
</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.
|
||||
{{ $t('features.description') }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
@@ -49,57 +46,25 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
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-history',
|
||||
title: 'Versionierung & Audit-Trail',
|
||||
description:
|
||||
'Änderungen werden versioniert und lückenlos nachvollziehbar dokumentiert – inklusive Historie und Vergleich.'
|
||||
},
|
||||
{
|
||||
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-file-text',
|
||||
title: 'Automatische BV-/DV-Generierung',
|
||||
description:
|
||||
'Nach Abschluss der Eingaben erzeugt das System strukturierte, übersichtliche und signaturbereite Betriebs-/Dienstvereinbarungen.'
|
||||
},
|
||||
{
|
||||
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.'
|
||||
}
|
||||
const { t } = useI18n()
|
||||
|
||||
const featureIcons = [
|
||||
'i-lucide-route',
|
||||
'i-lucide-shield-alert',
|
||||
'i-lucide-gauge',
|
||||
'i-lucide-history',
|
||||
'i-lucide-message-square',
|
||||
'i-lucide-file-text',
|
||||
'i-lucide-pen-tool',
|
||||
'i-lucide-bell',
|
||||
'i-lucide-shield-check'
|
||||
]
|
||||
|
||||
const features = computed(() =>
|
||||
featureIcons.map((icon, index) => ({
|
||||
icon,
|
||||
title: t(`features.items[${index}].title`),
|
||||
description: t(`features.items[${index}].description`)
|
||||
}))
|
||||
)
|
||||
</script>
|
||||
|
||||
@@ -11,19 +11,18 @@
|
||||
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
|
||||
{{ $t('frameworkAgreement.badge') }}
|
||||
</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>
|
||||
{{ $t('frameworkAgreement.title', { highlight: '' })
|
||||
}}<span class="gradient-text">{{ $t('frameworkAgreement.titleHighlight') }}</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.
|
||||
{{ $t('frameworkAgreement.description') }}
|
||||
</p>
|
||||
|
||||
<!-- Animated checklist -->
|
||||
@@ -54,8 +53,8 @@
|
||||
<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>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">{{ $t('common.price') }}</p>
|
||||
<p class="font-heading text-lg font-bold text-gray-900 dark:text-white">{{ $t('common.onRequest') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,7 +66,7 @@
|
||||
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>
|
||||
<span>{{ $t('common.learnMore') }}</span>
|
||||
<UIcon name="i-lucide-arrow-right" class="w-5 h-5 ml-2" />
|
||||
</UButton>
|
||||
</div>
|
||||
@@ -99,8 +98,10 @@
|
||||
<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>
|
||||
<h4 class="font-heading font-bold text-white text-lg">
|
||||
{{ $t('frameworkAgreement.document.title') }}
|
||||
</h4>
|
||||
<p class="text-sm text-white/80">{{ $t('frameworkAgreement.document.subtitle') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -110,7 +111,7 @@
|
||||
<!-- 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
|
||||
{{ $t('frameworkAgreement.document.tableOfContents') }}
|
||||
</div>
|
||||
|
||||
<!-- Section items with staggered animation -->
|
||||
@@ -142,11 +143,13 @@
|
||||
<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>
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400">{{
|
||||
$t('frameworkAgreement.document.regulationBlocks')
|
||||
}}</span>
|
||||
</div>
|
||||
<UBadge color="success" variant="soft" size="sm">
|
||||
<UIcon name="i-lucide-check-circle" class="w-3 h-3 mr-1" />
|
||||
Praxiserprobt
|
||||
{{ $t('frameworkAgreement.document.fieldTested') }}
|
||||
</UBadge>
|
||||
</div>
|
||||
</div>
|
||||
@@ -159,7 +162,7 @@
|
||||
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
|
||||
{{ $t('common.onRequest') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -177,34 +180,21 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { t } = useI18n()
|
||||
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 bulletPointCount = 3
|
||||
const bulletPoints = computed(() =>
|
||||
Array.from({ length: bulletPointCount }, (_, index) => t(`frameworkAgreement.bulletPoints[${index}]`))
|
||||
)
|
||||
|
||||
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'
|
||||
}
|
||||
]
|
||||
const sectionIcons = ['i-lucide-target', 'i-lucide-git-branch', 'i-lucide-shield', 'i-lucide-refresh-cw']
|
||||
|
||||
const documentSections = computed(() =>
|
||||
sectionIcons.map((icon, index) => ({
|
||||
icon,
|
||||
title: t(`frameworkAgreement.document.sections[${index}].title`),
|
||||
description: t(`frameworkAgreement.document.sections[${index}].description`)
|
||||
}))
|
||||
)
|
||||
</script>
|
||||
|
||||
@@ -39,17 +39,17 @@
|
||||
<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
|
||||
{{ $t('hero.badge') }}
|
||||
</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
|
||||
{{ $t('hero.title1') }}
|
||||
</span>
|
||||
<span class="animate-fade-in-up block gradient-text" style="animation-delay: 200ms">
|
||||
für IT- und KI-Systeme
|
||||
{{ $t('hero.title2') }}
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
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 }}
|
||||
{{ $t('hero.description') }}
|
||||
</p>
|
||||
|
||||
<!-- CTA Buttons -->
|
||||
@@ -69,7 +69,7 @@
|
||||
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>
|
||||
<span>{{ $t('hero.cta.requestDemo') }}</span>
|
||||
</UButton>
|
||||
<UButton
|
||||
size="xl"
|
||||
@@ -77,7 +77,7 @@
|
||||
variant="outline"
|
||||
class="btn-outline-gradient px-8 py-4 text-lg font-semibold rounded-xl"
|
||||
>
|
||||
Features entdecken
|
||||
{{ $t('hero.cta.discoverFeatures') }}
|
||||
</UButton>
|
||||
</div>
|
||||
</div>
|
||||
@@ -97,8 +97,10 @@
|
||||
<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>
|
||||
<p class="font-semibold text-gray-900 dark:text-white text-sm">
|
||||
{{ $t('hero.cards.riskAssessment') }}
|
||||
</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">{{ $t('hero.cards.pointsOpen') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
@@ -106,19 +108,19 @@
|
||||
<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>
|
||||
<span class="text-xs text-gray-600 dark:text-gray-300">{{ $t('hero.cards.privacyImpact') }}</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>
|
||||
<span class="text-xs text-gray-600 dark:text-gray-300">{{ $t('hero.cards.performanceCheck') }}</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>
|
||||
<span class="text-xs text-gray-600 dark:text-gray-300">{{ $t('hero.cards.accessDefined') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -139,10 +141,10 @@
|
||||
</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>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">{{ $t('hero.cards.operatingAgreement') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<UBadge color="primary" variant="soft" size="sm">In Bearbeitung</UBadge>
|
||||
<UBadge color="primary" variant="soft" size="sm">{{ $t('hero.cards.inProgress') }}</UBadge>
|
||||
</div>
|
||||
|
||||
<!-- Mock content -->
|
||||
@@ -150,7 +152,7 @@
|
||||
<!-- 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-gray-600 dark:text-gray-300 font-medium">{{ $t('hero.cards.progress') }}</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">
|
||||
@@ -165,8 +167,10 @@
|
||||
>
|
||||
<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>
|
||||
<p class="text-xs font-medium text-success-700 dark:text-success-300">
|
||||
{{ $t('hero.cards.sectionsCompleted') }}
|
||||
</p>
|
||||
<p class="text-xs text-success-600 dark:text-success-400">{{ $t('hero.cards.completed') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -174,8 +178,10 @@
|
||||
>
|
||||
<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>
|
||||
<p class="text-xs font-medium text-primary-700 dark:text-primary-300">
|
||||
{{ $t('hero.cards.commentsNew') }}
|
||||
</p>
|
||||
<p class="text-xs text-primary-600 dark:text-primary-400">{{ $t('hero.cards.new') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -184,7 +190,7 @@
|
||||
<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
|
||||
{{ $t('hero.cards.continueEditing') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -202,8 +208,10 @@
|
||||
<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>
|
||||
<p class="font-semibold text-gray-900 dark:text-white text-sm">
|
||||
{{ $t('hero.cards.completedTitle') }}
|
||||
</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">{{ $t('hero.cards.lastWeek') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
@@ -236,8 +244,8 @@
|
||||
<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>
|
||||
<p class="text-sm font-semibold text-gray-900 dark:text-white">{{ $t('hero.cards.bvCreated') }}</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">{{ $t('hero.cards.readyForSignature') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -249,7 +257,7 @@
|
||||
<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"
|
||||
:aria-label="$t('hero.scrollDown')"
|
||||
>
|
||||
<UIcon name="i-lucide-chevron-down" class="w-6 h-6" />
|
||||
</a>
|
||||
@@ -258,6 +266,5 @@
|
||||
</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.'
|
||||
// No additional script needed - using $t() from i18n
|
||||
</script>
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
<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>
|
||||
{{ $t('newsletter.title', { highlight: '' })
|
||||
}}<span class="gradient-text">{{ $t('newsletter.titleHighlight') }}</span>
|
||||
</h2>
|
||||
|
||||
<!-- Description -->
|
||||
@@ -49,8 +50,7 @@
|
||||
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.
|
||||
{{ $t('newsletter.description') }}
|
||||
</p>
|
||||
|
||||
<!-- Form -->
|
||||
@@ -66,7 +66,7 @@
|
||||
<UInput
|
||||
v-model="formState.email"
|
||||
type="email"
|
||||
placeholder="Ihre E-Mail-Adresse"
|
||||
:placeholder="$t('newsletter.placeholder')"
|
||||
size="xl"
|
||||
:disabled="isLoading || isSuccess"
|
||||
:ui="{
|
||||
@@ -89,10 +89,10 @@
|
||||
>
|
||||
<template v-if="isSuccess">
|
||||
<UIcon name="i-lucide-check" class="w-5 h-5 mr-2" />
|
||||
<span>Angemeldet!</span>
|
||||
<span>{{ $t('newsletter.submitted') }}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span>Anmelden</span>
|
||||
<span>{{ $t('newsletter.submit') }}</span>
|
||||
</template>
|
||||
</UButton>
|
||||
</div>
|
||||
@@ -115,7 +115,7 @@
|
||||
<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>
|
||||
<span class="font-medium">{{ $t('newsletter.success') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
@@ -125,11 +125,13 @@
|
||||
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.
|
||||
<i18n-t keypath="newsletter.privacyNote" tag="span">
|
||||
<template #link>
|
||||
<NuxtLink to="/datenschutz" class="text-primary-600 dark:text-primary-400 hover:underline font-medium">
|
||||
{{ $t('newsletter.privacyLink') }}
|
||||
</NuxtLink>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</p>
|
||||
|
||||
<!-- Trust indicators -->
|
||||
@@ -141,19 +143,19 @@
|
||||
<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>
|
||||
<span>{{ $t('newsletter.trust.gdpr') }}</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>
|
||||
<span>{{ $t('newsletter.trust.encrypted') }}</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>
|
||||
<span>{{ $t('newsletter.trust.noSpam') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -166,22 +168,20 @@
|
||||
import { z } from 'zod'
|
||||
import type { FormSubmitEvent } from '@nuxt/ui'
|
||||
|
||||
const { t } = useI18n()
|
||||
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')
|
||||
})
|
||||
const schema = computed(() =>
|
||||
z.object({
|
||||
email: z.string().min(1, t('newsletter.validation.required')).email(t('newsletter.validation.invalid'))
|
||||
})
|
||||
)
|
||||
|
||||
type Schema = z.output<typeof schema>
|
||||
|
||||
const formState = reactive<Partial<Schema>>({
|
||||
const formState = reactive<{ email: string }>({
|
||||
email: ''
|
||||
})
|
||||
|
||||
async function onSubmit(event: FormSubmitEvent<Schema>) {
|
||||
async function onSubmit(event: FormSubmitEvent<{ email: string }>) {
|
||||
await submitEmail(event.data.email)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
<!-- 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>
|
||||
<p class="text-center text-sm text-gray-500 dark:text-gray-400 mb-8">{{ $t('stats.trustAndSecurity') }}</p>
|
||||
|
||||
<div class="flex flex-wrap justify-center items-center gap-8 lg:gap-12">
|
||||
<div
|
||||
@@ -52,22 +52,24 @@
|
||||
</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 { t } = useI18n()
|
||||
|
||||
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' }
|
||||
]
|
||||
const stats = computed(() => [
|
||||
{ value: 70, suffix: '%', label: t('stats.timeSaved') },
|
||||
{ value: 100, suffix: '%', label: t('stats.auditProof') },
|
||||
{ value: 24, suffix: '/7', label: t('stats.availability') },
|
||||
{ value: 0, suffix: '', label: t('stats.mediaBreaks') }
|
||||
])
|
||||
|
||||
const trustBadges = computed(() => [
|
||||
{ icon: 'i-lucide-shield-check', label: t('stats.badges.gdpr') },
|
||||
{ icon: 'i-lucide-server', label: t('stats.badges.hosting') },
|
||||
{ icon: 'i-lucide-lock', label: t('stats.badges.encrypted') },
|
||||
{ icon: 'i-lucide-key', label: t('stats.badges.sso') }
|
||||
])
|
||||
|
||||
// Animated counter values
|
||||
const animatedValues = ref(stats.map(() => 0))
|
||||
const animatedValues = ref(stats.value.map(() => 0))
|
||||
const hasAnimated = ref(false)
|
||||
|
||||
// Counter animation function
|
||||
@@ -99,7 +101,7 @@ onMounted(() => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting && !hasAnimated.value) {
|
||||
hasAnimated.value = true
|
||||
stats.forEach((stat, index) => {
|
||||
stats.value.forEach((stat, index) => {
|
||||
setTimeout(() => {
|
||||
animateCounter(index, stat.value)
|
||||
}, index * 200)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export function useNewsletterSignup() {
|
||||
const { t } = useI18n()
|
||||
const isLoading = ref(false)
|
||||
const isSuccess = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
@@ -20,7 +21,7 @@ export function useNewsletterSignup() {
|
||||
|
||||
isSuccess.value = true
|
||||
} catch (e: unknown) {
|
||||
error.value = e instanceof Error ? e.message : 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.'
|
||||
error.value = e instanceof Error ? e.message : t('errors.generic')
|
||||
throw e
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
|
||||
@@ -30,13 +30,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { t, locale } = useI18n()
|
||||
|
||||
// SEO Meta
|
||||
useSeoMeta({
|
||||
title: 'LegalConsentHub - Digitale Mitbestimmung für IT- und KI-Systeme',
|
||||
description:
|
||||
'Struktur statt Hauruck: Alle relevanten Informationen an einem Ort, klare Prozessschritte und nachvollziehbare Dokumentation – damit Mitbestimmung schneller, belastbarer und dauerhaft updatefähig wird.',
|
||||
ogTitle: 'LegalConsentHub - Digitale Mitbestimmung für IT- und KI-Systeme',
|
||||
ogDescription: 'Strukturierte IT-Mitbestimmung mit klaren Prozessen und revisionssicherer Dokumentation.',
|
||||
title: () => t('meta.title'),
|
||||
description: () => t('meta.description'),
|
||||
ogTitle: () => t('meta.title'),
|
||||
ogDescription: () => t('meta.ogDescription'),
|
||||
ogImage: '/og-image.png',
|
||||
ogType: 'website',
|
||||
twitterCard: 'summary_large_image'
|
||||
@@ -44,6 +45,9 @@ useSeoMeta({
|
||||
|
||||
// Structured data for SEO
|
||||
useHead({
|
||||
htmlAttrs: {
|
||||
lang: () => locale.value
|
||||
},
|
||||
script: [
|
||||
{
|
||||
type: 'application/ld+json',
|
||||
@@ -53,20 +57,19 @@ useHead({
|
||||
name: 'LegalConsentHub',
|
||||
applicationCategory: 'BusinessApplication',
|
||||
operatingSystem: 'Web',
|
||||
description:
|
||||
'Digitale Mitbestimmung für IT- und KI-Systeme. Strukturierte Eingabelogik, klare Prozesse und revisionssichere Dokumentation.',
|
||||
description: t('meta.description'),
|
||||
offers: {
|
||||
'@type': 'Offer',
|
||||
price: '0',
|
||||
priceCurrency: 'EUR',
|
||||
description: 'Kontaktieren Sie uns für Preisdetails'
|
||||
description: t('common.onRequest')
|
||||
},
|
||||
featureList: [
|
||||
'Geführter Mitbestimmungsprozess',
|
||||
'Risikobasierter Assistent',
|
||||
'Versionierung & Audit-Trail',
|
||||
'Automatische BV-/DV-Generierung',
|
||||
'SSO & Governance'
|
||||
t('features.items[0].title'),
|
||||
t('features.items[1].title'),
|
||||
t('features.items[3].title'),
|
||||
t('features.items[5].title'),
|
||||
t('features.items[8].title')
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user