Files
gremiumhub/landing/app/components/landing/FrameworkAgreement.vue

194 lines
8.4 KiB
Vue

<template>
<UPageSection
:ui="{
root: 'scroll-mt-20'
}"
>
<div class="grid lg:grid-cols-2 gap-12 lg:gap-16 items-center">
<!-- Left: Content (first on mobile, first on desktop) -->
<div>
<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" />
{{ $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"
>
{{ $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">
{{ $t('frameworkAgreement.description') }}
</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 shrink-0"
>
<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">{{ $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>
<!-- 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>{{ $t('common.learnMore') }}</span>
<UIcon name="i-lucide-arrow-right" class="w-5 h-5 ml-2" />
</UButton>
</div>
</div>
<!-- Right: 3D Document Preview (second on mobile, second on desktop) -->
<div class="flex justify-center px-4 sm:px-0 py-8 overflow-visible">
<div class="relative animate-scale-in overflow-visible">
<!-- 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 w-full max-w-[320px] sm: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">
{{ $t('frameworkAgreement.document.title') }}
</h4>
<p class="text-sm text-white/80">{{ $t('frameworkAgreement.document.subtitle') }}</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">
{{ $t('frameworkAgreement.document.tableOfContents') }}
</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">{{
$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" />
{{ $t('frameworkAgreement.document.fieldTested') }}
</UBadge>
</div>
</div>
</div>
</div>
<!-- Floating badge - hidden on very small screens to prevent overflow -->
<div class="absolute -top-4 right-0 sm:-right-4 z-10 animate-float-fast">
<div
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" />
{{ $t('common.onRequest') }}
</div>
</div>
</div>
</div>
</div>
</div>
</UPageSection>
</template>
<script setup lang="ts">
const { t } = useI18n()
const isHovered = ref(false)
const bulletPointCount = 3
const bulletPoints = computed(() =>
Array.from({ length: bulletPointCount }, (_, index) => t(`frameworkAgreement.bulletPoints[${index}]`))
)
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>