feat(landing): Mobile viewport optimizations
This commit is contained in:
@@ -18,14 +18,14 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<template #title>
|
<template #title>
|
||||||
<NuxtLink to="/" class="flex items-center gap-3 group">
|
<NuxtLink to="/" class="flex items-center gap-2 sm:gap-3 group">
|
||||||
<div
|
<div
|
||||||
class="w-10 h-10 rounded-xl bg-gradient-to-br from-primary-500 to-cyan-500 flex items-center justify-center shadow-lg shadow-primary-500/25 group-hover:shadow-primary-500/40 transition-shadow"
|
class="w-10 h-10 rounded-xl bg-gradient-to-br from-primary-500 to-cyan-500 flex items-center justify-center shadow-lg shadow-primary-500/25 group-hover:shadow-primary-500/40 transition-shadow"
|
||||||
>
|
>
|
||||||
<UIcon name="i-lucide-scale" class="w-5 h-5 text-white" />
|
<UIcon name="i-lucide-scale" class="w-5 h-5 text-white" />
|
||||||
</div>
|
</div>
|
||||||
<span
|
<span
|
||||||
class="font-heading text-xl font-bold bg-gradient-to-r from-primary-600 to-cyan-600 bg-clip-text text-transparent"
|
class="hidden sm:inline font-heading text-xl font-bold bg-gradient-to-r from-primary-600 to-cyan-600 bg-clip-text text-transparent"
|
||||||
>
|
>
|
||||||
LegalConsentHub
|
LegalConsentHub
|
||||||
</span>
|
</span>
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
<USelectMenu
|
<USelectMenu
|
||||||
v-model="selectedLocale"
|
v-model="selectedLocale"
|
||||||
:items="localeItems"
|
:items="localeItems"
|
||||||
class="w-[100px]"
|
class="w-[90px] sm:w-[100px]"
|
||||||
:ui="{
|
:ui="{
|
||||||
base: 'text-sm'
|
base: 'text-sm'
|
||||||
}"
|
}"
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
/>
|
/>
|
||||||
<UButton
|
<UButton
|
||||||
to="#newsletter"
|
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"
|
class="hidden sm:flex 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>{{ $t('common.stayInformed') }}</span>
|
<span>{{ $t('common.stayInformed') }}</span>
|
||||||
</UButton>
|
</UButton>
|
||||||
|
|||||||
@@ -1,6 +1,23 @@
|
|||||||
@import 'tailwindcss';
|
@import 'tailwindcss';
|
||||||
@import '@nuxt/ui';
|
@import '@nuxt/ui';
|
||||||
|
|
||||||
|
/* Prevent horizontal overflow from decorative elements (gradient orbs, etc.) */
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure all content respects container boundaries on mobile (accounts for scrollbar) */
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.grid {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
.grid > * {
|
||||||
|
min-width: 0;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Theme configuration with new teal/cyan/violet palette */
|
/* Theme configuration with new teal/cyan/violet palette */
|
||||||
@theme {
|
@theme {
|
||||||
/* Typography - Bricolage Grotesque for headings, DM Sans for body */
|
/* Typography - Bricolage Grotesque for headings, DM Sans for body */
|
||||||
|
|||||||
@@ -16,8 +16,7 @@
|
|||||||
<h2
|
<h2
|
||||||
class="font-heading text-3xl sm:text-4xl lg:text-5xl text-pretty tracking-tight font-bold text-gray-900 dark:text-white"
|
class="font-heading text-3xl sm:text-4xl lg:text-5xl text-pretty tracking-tight font-bold text-gray-900 dark:text-white"
|
||||||
>
|
>
|
||||||
{{ $t('features.title', { highlight: '' })
|
{{ $t('features.title') }}<span class="gradient-text">{{ $t('features.titleHighlight') }}</span>{{ $t('features.titleSuffix') }}
|
||||||
}}<span class="gradient-text">{{ $t('features.titleHighlight') }}</span>
|
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="grid lg:grid-cols-2 gap-12 lg:gap-16 items-center">
|
<div class="grid lg:grid-cols-2 gap-12 lg:gap-16 items-center">
|
||||||
<!-- Left: Content -->
|
<!-- Left: Content (first on mobile, first on desktop) -->
|
||||||
<div class="order-2 lg:order-1">
|
<div>
|
||||||
<span
|
<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"
|
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"
|
||||||
>
|
>
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
>
|
>
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<div
|
<div
|
||||||
class="w-10 h-10 rounded-xl bg-gradient-to-br from-primary-500 to-cyan-500 flex items-center justify-center"
|
class="w-10 h-10 rounded-xl bg-gradient-to-br from-primary-500 to-cyan-500 flex items-center justify-center shrink-0"
|
||||||
>
|
>
|
||||||
<UIcon name="i-lucide-tag" class="w-5 h-5 text-white" />
|
<UIcon name="i-lucide-tag" class="w-5 h-5 text-white" />
|
||||||
</div>
|
</div>
|
||||||
@@ -72,9 +72,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Right: 3D Document Preview -->
|
<!-- Right: 3D Document Preview (second on mobile, second on desktop) -->
|
||||||
<div class="order-1 lg:order-2 flex justify-center">
|
<div class="flex justify-center px-4 sm:px-0 py-8 overflow-visible">
|
||||||
<div class="relative animate-scale-in">
|
<div class="relative animate-scale-in overflow-visible">
|
||||||
<!-- 3D Document with tilt effect -->
|
<!-- 3D Document with tilt effect -->
|
||||||
<div
|
<div
|
||||||
class="relative transform-gpu transition-transform duration-500 hover:rotate-0"
|
class="relative transform-gpu transition-transform duration-500 hover:rotate-0"
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
|
|
||||||
<!-- Document card -->
|
<!-- Document card -->
|
||||||
<div
|
<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"
|
class="relative bg-white dark:bg-gray-900 rounded-2xl border border-gray-200 dark:border-gray-700 shadow-2xl overflow-hidden w-full max-w-[320px] sm:max-w-sm"
|
||||||
>
|
>
|
||||||
<!-- Document header -->
|
<!-- Document header -->
|
||||||
<div class="bg-gradient-to-r from-primary-600 to-cyan-600 px-6 py-5">
|
<div class="bg-gradient-to-r from-primary-600 to-cyan-600 px-6 py-5">
|
||||||
@@ -156,23 +156,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Floating badge -->
|
<!-- Floating badge - hidden on very small screens to prevent overflow -->
|
||||||
<div class="absolute -top-4 -right-4 z-10 animate-float-fast">
|
<div class="absolute -top-4 right-0 sm:-right-4 z-10 animate-float-fast">
|
||||||
<div
|
<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"
|
class="bg-gradient-to-r from-accent-500 to-violet-500 text-white px-3 sm:px-4 py-2 rounded-full shadow-lg text-xs sm:text-sm font-semibold flex items-center gap-2"
|
||||||
>
|
>
|
||||||
<UIcon name="i-lucide-download" class="w-4 h-4" />
|
<UIcon name="i-lucide-download" class="w-4 h-4" />
|
||||||
{{ $t('common.onRequest') }}
|
{{ $t('common.onRequest') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -84,150 +84,38 @@
|
|||||||
|
|
||||||
<!-- Floating product preview cards -->
|
<!-- Floating product preview cards -->
|
||||||
<div class="mt-16 lg:mt-24 relative animate-scale-in" style="animation-delay: 600ms">
|
<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">
|
<!-- Mobile layout: Main card first, then status cards side-by-side -->
|
||||||
<!-- Left card - tilted -->
|
<div class="flex flex-col items-center gap-6 lg:hidden px-2">
|
||||||
<div class="card-3d w-full max-w-xs lg:-mr-8 lg:mt-12 order-2 lg:order-1">
|
<!-- Main Card (Microsoft 365) -->
|
||||||
<div
|
<div class="w-full max-w-sm">
|
||||||
class="card-3d-inner glass rounded-2xl p-5 shadow-xl transform lg:-rotate-6 hover:rotate-0 transition-transform duration-500"
|
<LandingHeroMainCard />
|
||||||
>
|
</div>
|
||||||
<div class="flex items-center gap-3 mb-4">
|
|
||||||
<div
|
<!-- Status cards wrapper - side-by-side on mobile with overflow protection -->
|
||||||
class="w-10 h-10 rounded-xl bg-gradient-to-br from-warning-400 to-warning-500 flex items-center justify-center"
|
<div class="flex flex-row gap-3 w-full max-w-sm overflow-hidden">
|
||||||
>
|
<LandingHeroStatusCardRisk compact />
|
||||||
<UIcon name="i-lucide-alert-triangle" class="w-5 h-5 text-white" />
|
<LandingHeroStatusCardCompleted compact />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
</div>
|
||||||
<p class="font-semibold text-gray-900 dark:text-white text-sm">
|
|
||||||
{{ $t('hero.cards.riskAssessment') }}
|
<!-- Desktop layout: 3 cards in a row with tilted side cards -->
|
||||||
</p>
|
<div class="hidden lg:flex flex-row items-center justify-center gap-8">
|
||||||
<p class="text-xs text-gray-500 dark:text-gray-400">{{ $t('hero.cards.pointsOpen') }}</p>
|
<!-- Left card - tilted (Risk Assessment) -->
|
||||||
</div>
|
<div class="card-3d w-full max-w-xs -mr-8 mt-12">
|
||||||
</div>
|
<div class="card-3d-inner transform -rotate-6 hover:rotate-0 transition-transform duration-500">
|
||||||
<div class="space-y-2">
|
<LandingHeroStatusCardRisk />
|
||||||
<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">{{ $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">{{ $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">{{ $t('hero.cards.accessDefined') }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Center card - main -->
|
<!-- Center card - main (Microsoft 365) -->
|
||||||
<div class="w-full max-w-md z-10 order-1 lg:order-2">
|
<div class="w-full max-w-md z-10">
|
||||||
<div class="glass rounded-2xl overflow-hidden shadow-2xl border border-white/50 dark:border-white/10">
|
<LandingHeroMainCard />
|
||||||
<!-- 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">{{ $t('hero.cards.operatingAgreement') }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<UBadge color="primary" variant="soft" size="sm">{{ $t('hero.cards.inProgress') }}</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">{{ $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">
|
|
||||||
<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">
|
|
||||||
{{ $t('hero.cards.sectionsCompleted') }}
|
|
||||||
</p>
|
|
||||||
<p class="text-xs text-success-600 dark:text-success-400">{{ $t('hero.cards.completed') }}</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">
|
|
||||||
{{ $t('hero.cards.commentsNew') }}
|
|
||||||
</p>
|
|
||||||
<p class="text-xs text-primary-600 dark:text-primary-400">{{ $t('hero.cards.new') }}</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"
|
|
||||||
>
|
|
||||||
{{ $t('hero.cards.continueEditing') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Right card - tilted -->
|
<!-- Right card - tilted (Completed) -->
|
||||||
<div class="card-3d w-full max-w-xs lg:-ml-8 lg:mt-12 order-3">
|
<div class="card-3d w-full max-w-xs -ml-8 mt-12">
|
||||||
<div
|
<div class="card-3d-inner transform rotate-6 hover:rotate-0 transition-transform duration-500">
|
||||||
class="card-3d-inner glass rounded-2xl p-5 shadow-xl transform lg:rotate-6 hover:rotate-0 transition-transform duration-500"
|
<LandingHeroStatusCardCompleted />
|
||||||
>
|
|
||||||
<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">
|
|
||||||
{{ $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">
|
|
||||||
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -252,19 +140,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Scroll indicator -->
|
<!-- Scroll indicator - stable wrapper for click target, animated inner element -->
|
||||||
<div class="absolute bottom-8 left-1/2 -translate-x-1/2 animate-bounce">
|
<div class="absolute bottom-8 left-1/2 -translate-x-1/2 z-20">
|
||||||
<a
|
<a
|
||||||
href="#betriebsraete"
|
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"
|
class="block"
|
||||||
:aria-label="$t('hero.scrollDown')"
|
:aria-label="$t('hero.scrollDown')"
|
||||||
|
@click.prevent="scrollToSection"
|
||||||
>
|
>
|
||||||
<UIcon name="i-lucide-chevron-down" class="w-6 h-6" />
|
<div
|
||||||
|
class="animate-bounce 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"
|
||||||
|
>
|
||||||
|
<UIcon name="i-lucide-chevron-down" class="w-6 h-6" />
|
||||||
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
// No additional script needed - using $t() from i18n
|
const scrollToSection = () => {
|
||||||
|
const target = document.querySelector('#betriebsraete')
|
||||||
|
if (target) {
|
||||||
|
target.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
81
landing/app/components/landing/hero/MainCard.vue
Normal file
81
landing/app/components/landing/hero/MainCard.vue
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<template>
|
||||||
|
<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">
|
||||||
|
{{ $t('hero.cards.operatingAgreement') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<UBadge color="primary" variant="soft" size="sm">
|
||||||
|
{{ $t('hero.cards.inProgress') }}
|
||||||
|
</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">
|
||||||
|
{{ $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">
|
||||||
|
<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">
|
||||||
|
{{ $t('hero.cards.sectionsCompleted') }}
|
||||||
|
</p>
|
||||||
|
<p class="text-xs text-success-600 dark:text-success-400">
|
||||||
|
{{ $t('hero.cards.completed') }}
|
||||||
|
</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">
|
||||||
|
{{ $t('hero.cards.commentsNew') }}
|
||||||
|
</p>
|
||||||
|
<p class="text-xs text-primary-600 dark:text-primary-400">
|
||||||
|
{{ $t('hero.cards.new') }}
|
||||||
|
</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"
|
||||||
|
>
|
||||||
|
{{ $t('hero.cards.continueEditing') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
54
landing/app/components/landing/hero/StatusCardCompleted.vue
Normal file
54
landing/app/components/landing/hero/StatusCardCompleted.vue
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="bg-white dark:bg-gray-900 rounded-2xl shadow-lg border border-gray-100 dark:border-gray-800"
|
||||||
|
:class="compact ? 'p-4 flex-1 min-w-0' : 'p-5'"
|
||||||
|
>
|
||||||
|
<div :class="compact ? 'flex items-center gap-2 mb-3' : 'flex items-center gap-3 mb-4'">
|
||||||
|
<div
|
||||||
|
class="bg-gradient-to-br from-success-400 to-success-500 flex items-center justify-center shrink-0"
|
||||||
|
:class="compact ? 'w-8 h-8 rounded-lg' : 'w-10 h-10 rounded-xl'"
|
||||||
|
>
|
||||||
|
<UIcon name="i-lucide-check-circle" :class="compact ? 'w-4 h-4' : 'w-5 h-5'" class="text-white" />
|
||||||
|
</div>
|
||||||
|
<div class="min-w-0">
|
||||||
|
<p
|
||||||
|
class="font-semibold text-gray-900 dark:text-white"
|
||||||
|
:class="compact ? 'text-xs truncate' : '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="compact ? 'space-y-1.5' : 'space-y-2'">
|
||||||
|
<div
|
||||||
|
class="flex items-center justify-between bg-success-50 dark:bg-success-900/30"
|
||||||
|
:class="compact ? 'p-1.5 rounded' : 'p-2 rounded-lg'"
|
||||||
|
>
|
||||||
|
<span class="text-xs text-gray-700 dark:text-gray-200 truncate">SAP S/4HANA</span>
|
||||||
|
<UIcon name="i-lucide-check" :class="compact ? 'w-3 h-3' : 'w-4 h-4'" class="text-success-500 shrink-0" />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex items-center justify-between bg-success-50 dark:bg-success-900/30"
|
||||||
|
:class="compact ? 'p-1.5 rounded' : 'p-2 rounded-lg'"
|
||||||
|
>
|
||||||
|
<span class="text-xs text-gray-700 dark:text-gray-200 truncate">Workday HCM</span>
|
||||||
|
<UIcon name="i-lucide-check" :class="compact ? 'w-3 h-3' : 'w-4 h-4'" class="text-success-500 shrink-0" />
|
||||||
|
</div>
|
||||||
|
<!-- Desktop-only: Salesforce item -->
|
||||||
|
<div v-if="!compact" 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>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
defineProps<{
|
||||||
|
compact?: boolean
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
66
landing/app/components/landing/hero/StatusCardRisk.vue
Normal file
66
landing/app/components/landing/hero/StatusCardRisk.vue
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="bg-white dark:bg-gray-900 rounded-2xl shadow-lg border border-gray-100 dark:border-gray-800"
|
||||||
|
:class="compact ? 'p-4 flex-1 min-w-0' : 'p-5'"
|
||||||
|
>
|
||||||
|
<div :class="compact ? 'flex items-center gap-2 mb-3' : 'flex items-center gap-3 mb-4'">
|
||||||
|
<div
|
||||||
|
class="bg-gradient-to-br from-warning-400 to-warning-500 flex items-center justify-center shrink-0"
|
||||||
|
:class="compact ? 'w-8 h-8 rounded-lg' : 'w-10 h-10 rounded-xl'"
|
||||||
|
>
|
||||||
|
<UIcon name="i-lucide-alert-triangle" :class="compact ? 'w-4 h-4' : 'w-5 h-5'" class="text-white" />
|
||||||
|
</div>
|
||||||
|
<div class="min-w-0">
|
||||||
|
<p
|
||||||
|
class="font-semibold text-gray-900 dark:text-white"
|
||||||
|
:class="compact ? 'text-xs truncate' : '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="compact ? 'space-y-1.5' : 'space-y-2'">
|
||||||
|
<div class="flex items-center" :class="compact ? 'gap-1.5' : 'gap-2'">
|
||||||
|
<div
|
||||||
|
class="rounded bg-warning-100 dark:bg-warning-900/50 flex items-center justify-center shrink-0"
|
||||||
|
:class="compact ? 'w-3 h-3' : 'w-4 h-4'"
|
||||||
|
>
|
||||||
|
<UIcon name="i-lucide-clock" :class="compact ? 'w-2 h-2' : 'w-2.5 h-2.5'" class="text-warning-600" />
|
||||||
|
</div>
|
||||||
|
<span class="text-xs text-gray-600 dark:text-gray-300" :class="{ 'truncate': compact }">
|
||||||
|
{{ $t('hero.cards.privacyImpact') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!-- Desktop-only: Performance check item -->
|
||||||
|
<div v-if="!compact" 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">
|
||||||
|
{{ $t('hero.cards.performanceCheck') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center" :class="compact ? 'gap-1.5' : 'gap-2'">
|
||||||
|
<div
|
||||||
|
class="rounded bg-success-100 dark:bg-success-900/50 flex items-center justify-center shrink-0"
|
||||||
|
:class="compact ? 'w-3 h-3' : 'w-4 h-4'"
|
||||||
|
>
|
||||||
|
<UIcon name="i-lucide-check" :class="compact ? 'w-2 h-2' : 'w-2.5 h-2.5'" class="text-success-600" />
|
||||||
|
</div>
|
||||||
|
<span class="text-xs text-gray-600 dark:text-gray-300" :class="{ 'truncate': compact }">
|
||||||
|
{{ $t('hero.cards.accessDefined') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
defineProps<{
|
||||||
|
compact?: boolean
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
Reference in New Issue
Block a user