Sheets via neuer KeyboardAwareSheet-Composable (in Modal pattern, auto-grow mit Tastatur, paddingBottom-Lift): EditMail, AddDomain, CreateRoom, ConnectMail. GameOverScreen behält Spring-Slide-In, nutzt RN Keyboard.addListener für Lift. - KeyboardAwareSheet.tsx — universal modal with sheet-grow + keyboard-padding - react-native-keyboard-controller installiert + KeyboardProvider in Root - Snake: time + ScoreProgressBar + useSnakeSounds (haptic, audio TODO) - Tetris: title weg, Buttons zentriert, kein Pressable mit style-fn - DPad-Buttons 60→48, more bg, no scale - useMe: pub-sub listener pattern für app-weite avatar/nickname-Updates - dm.tsx: resolveAvatar wrap (iron.png-Warning) - Mail-error-humanizer + locales Recovery-Doc-Update in docs/internal/RECOVERY_LOG_2026-05-10.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
450 lines
22 KiB
Vue
450 lines
22 KiB
Vue
<template>
|
|
<div class="bg-default overflow-x-hidden">
|
|
<!-- ─── HERO ─── -->
|
|
<section class="relative min-h-[80dvh] flex flex-col items-center justify-center px-4 text-center">
|
|
<div class="absolute inset-0 bg-linear-to-b from-gray-950 via-primary-950/20 to-gray-950 pointer-events-none" />
|
|
<div
|
|
class="absolute top-1/3 left-1/2 -translate-x-1/2 -translate-y-1/2 w-175 h-175 bg-primary-900/15 rounded-full blur-3xl pointer-events-none" />
|
|
|
|
<div class="relative max-w-3xl mx-auto">
|
|
<div
|
|
class="inline-flex items-center gap-2 bg-primary-950/60 border border-primary-800/40 rounded-full px-4 py-1.5 text-sm text-primary-300 mb-8">
|
|
<UIcon name="i-heroicons-user-group" class="text-primary-400" />
|
|
{{ $t('landing.hero_badge') }}
|
|
</div>
|
|
|
|
<h1 class="text-3xl md:text-7xl font-black text-highlighted leading-[1.05] tracking-tight mb-6">
|
|
{{ $t('landing.hero_title') }}
|
|
<span class="block text-2xl text-transparent bg-clip-text bg-linear-to-r from-primary-300 to-primary-500">
|
|
{{ $t('landing.hero_subtitle') }}
|
|
</span>
|
|
</h1>
|
|
|
|
<p class="text-sm text-muted max-w-lg mx-auto mb-10 leading-relaxed">
|
|
{{ $t('landing.hero_text') }}
|
|
</p>
|
|
|
|
<img src="/encrypted.svg" alt="Community Illustration" class="w-15 max-w-md mx-auto mb-10" />
|
|
|
|
<div class="flex flex-col sm:flex-row items-center justify-center gap-4">
|
|
<a href="https://apps.apple.com/app/rebreak" target="_blank" rel="noopener">
|
|
<UButton size="xl" class="px-8">
|
|
<UIcon name="i-heroicons-bolt" />
|
|
{{ $t('landing.cta_start') }}
|
|
</UButton>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="flex justify-center gap-x-10 mt-16 text-center">
|
|
<div>
|
|
<div class="text-3xl font-extrabold text-highlighted">
|
|
<AnimatedCounter :target="300" :duration="2000" />k+
|
|
</div>
|
|
<div class="text-xs text-muted mt-1">{{ $t('landing.stat_affected') }}</div>
|
|
</div>
|
|
<div>
|
|
<div class="text-3xl font-extrabold text-primary-400">
|
|
<AnimatedCounter :target="208" :duration="1600" :delay="200" />k+
|
|
</div>
|
|
<div class="text-xs text-muted mt-1">{{ $t('landing.stat_blocked') }}</div>
|
|
</div>
|
|
<div>
|
|
<div class="text-3xl font-extrabold text-primary-400">0€</div>
|
|
<div class="text-xs text-muted mt-1">{{ $t('landing.stat_free') }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-8">
|
|
<UButton size="lg" variant="ghost" color="neutral" @click="scrollToInfo">
|
|
{{ $t('landing.more_info') }}
|
|
<UIcon name="i-heroicons-chevron-down" />
|
|
</UButton>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ─── INFO SECTIONS ─── -->
|
|
<div v-if="showInfoSections" ref="infoSections">
|
|
<!-- Blocker -->
|
|
<section class="py-8 px-4">
|
|
<div v-motion :initial="{ opacity: 0, y: 50 }" :visible="{ opacity: 1, y: 0, transition: { duration: 700 } }"
|
|
class="max-w-6xl mx-auto grid lg:grid-cols-2 gap-16 items-center">
|
|
<div class="order-2 lg:order-1">
|
|
<div
|
|
class="inline-flex items-center gap-2 bg-primary-950/60 border border-primary-800/40 rounded-full px-3 py-1 text-xs text-primary-300 mb-6">
|
|
<UIcon name="i-heroicons-shield-exclamation" />
|
|
{{ $t('landing.blocker_badge') }}
|
|
</div>
|
|
<h2 class="text-4xl md:text-5xl font-black text-highlighted leading-tight mb-6">
|
|
<AnimatedCounter :target="100" :duration="2500" />k+ {{ $t('landing.blocker_title_domains') }}<br />
|
|
<span class="text-primary-400">{{ $t('landing.blocker_title_activated') }}</span>
|
|
</h2>
|
|
<p class="text-lg text-muted leading-relaxed mb-8">
|
|
{{ $t('landing.blocker_desc') }}
|
|
</p>
|
|
<ul class="space-y-3 text-sm text-default">
|
|
<li v-for="f in blockerFeatures" :key="f" class="flex items-center gap-3">
|
|
<UIcon name="i-heroicons-check-circle" class="text-primary-400 shrink-0" />{{ f }}
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="order-1 lg:order-2 flex items-center justify-center">
|
|
<div
|
|
class="w-72 h-72 rounded-3xl bg-linear-to-br from-primary-950/60 to-primary-900/20 border border-primary-800/20 flex items-center justify-center shadow-2xl shadow-primary-950/50">
|
|
<UIcon name="i-heroicons-shield-check" class="text-primary-400 w-32 h-32" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- OASIS Warning -->
|
|
<section class="py-8 px-4">
|
|
<div v-motion :initial="{ opacity: 0, y: 40 }" :visible="{ opacity: 1, y: 0, transition: { duration: 700 } }"
|
|
class="max-w-4xl mx-auto">
|
|
<div class="bg-orange-950/20 border border-orange-800/20 rounded-3xl p-6 md:p-8">
|
|
<div
|
|
class="inline-flex items-center gap-2 bg-orange-950/60 border border-orange-800/40 rounded-full px-3 py-1 text-xs text-orange-300 mb-5">
|
|
<UIcon name="i-heroicons-exclamation-triangle" />
|
|
{{ $t('landing.oasis_badge') }}
|
|
</div>
|
|
<h2 class="text-2xl md:text-3xl font-black text-highlighted leading-tight mb-4">
|
|
{{ $t('landing.oasis_title') }}<br class="hidden sm:block" />
|
|
<span class="text-orange-400">{{ $t('landing.oasis_subtitle') }}</span>
|
|
</h2>
|
|
<p class="text-muted leading-relaxed mb-6 max-w-2xl">
|
|
{{ $t('landing.oasis_desc') }}
|
|
</p>
|
|
<div class="grid sm:grid-cols-3 gap-3">
|
|
<div class="bg-elevated rounded-2xl p-4">
|
|
<div class="text-orange-400 font-black text-2xl mb-1">50+</div>
|
|
<div class="text-xs text-muted leading-relaxed">{{ $t('landing.oasis_new_domains') }}</div>
|
|
</div>
|
|
<div class="bg-elevated rounded-2xl p-4">
|
|
<div class="text-orange-400 font-black text-2xl mb-1">Offshore</div>
|
|
<div class="text-xs text-muted leading-relaxed">{{ $t('landing.oasis_offshore') }}</div>
|
|
</div>
|
|
<div class="bg-elevated rounded-2xl p-4">
|
|
<div class="text-primary-400 font-black text-2xl mb-1">208.000+</div>
|
|
<div class="text-xs text-muted leading-relaxed">{{ $t('landing.oasis_updated') }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Streak -->
|
|
<section class="py-8 px-4 bg-linear-to-b from-transparent via-orange-950/10 to-transparent">
|
|
<div v-motion :initial="{ opacity: 0, y: 50 }" :visible="{ opacity: 1, y: 0, transition: { duration: 700 } }"
|
|
class="max-w-6xl mx-auto grid lg:grid-cols-2 gap-16 items-center">
|
|
<div class="flex items-center justify-center">
|
|
<div class="relative">
|
|
<div
|
|
class="w-72 h-72 rounded-3xl bg-linear-to-br from-orange-950/60 to-yellow-900/20 border border-orange-800/20 flex flex-col items-center justify-center shadow-2xl shadow-orange-950/50 gap-2">
|
|
<UIcon name="i-heroicons-fire" class="text-orange-400 w-20 h-20" />
|
|
<div class="text-5xl font-black text-highlighted">
|
|
<AnimatedCounter :target="47" :duration="2800" />
|
|
</div>
|
|
<div class="text-orange-300 text-sm font-medium">{{ $t('landing.streak_days_free') }}</div>
|
|
</div>
|
|
<div
|
|
class="absolute -bottom-4 -right-4 bg-green-950 border border-green-700/40 rounded-2xl px-4 py-2 text-sm">
|
|
<span class="text-green-400 font-bold">+€
|
|
<AnimatedCounter :target="423" :duration="3000" />
|
|
</span>
|
|
<span class="text-muted ml-1">{{ $t('landing.streak_saved') }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div
|
|
class="inline-flex items-center gap-2 bg-orange-950/60 border border-orange-800/40 rounded-full px-3 py-1 text-xs text-orange-300 mb-6">
|
|
<UIcon name="i-heroicons-fire" />
|
|
{{ $t('landing.streak_badge') }}
|
|
</div>
|
|
<h2 class="text-4xl md:text-5xl font-black text-highlighted leading-tight mb-6">
|
|
{{ $t('landing.streak_title') }}<br />
|
|
<span class="text-orange-400">{{ $t('landing.streak_subtitle') }}</span>
|
|
</h2>
|
|
<p class="text-lg text-muted leading-relaxed">
|
|
{{ $t('landing.streak_desc') }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- SOS + Atemübungen -->
|
|
<section class="py-8 px-4">
|
|
<div v-motion :initial="{ opacity: 0, y: 50 }" :visible="{ opacity: 1, y: 0, transition: { duration: 700 } }"
|
|
class="max-w-6xl mx-auto">
|
|
<div class="text-center mb-10">
|
|
<div
|
|
class="inline-flex items-center gap-2 bg-orange-950/60 border border-orange-800/40 rounded-full px-3 py-1 text-xs text-orange-300 mb-5">
|
|
<UIcon name="i-heroicons-bolt" />
|
|
{{ $t('landing.crisis_badge') }}
|
|
</div>
|
|
<h2 class="text-4xl md:text-5xl font-black text-highlighted leading-tight">
|
|
{{ $t('landing.crisis_title') }}<br />
|
|
<span class="text-orange-400">{{ $t('landing.crisis_subtitle') }}</span>
|
|
</h2>
|
|
</div>
|
|
<div class="grid md:grid-cols-2 gap-6">
|
|
<!-- SOS -->
|
|
<div class="bg-orange-950/20 border border-orange-800/20 rounded-3xl p-6 flex flex-col gap-4">
|
|
<div class="flex items-center gap-3">
|
|
<div
|
|
class="w-10 h-10 rounded-xl bg-orange-900/60 border border-orange-700/30 flex items-center justify-center shrink-0">
|
|
<UIcon name="i-heroicons-bolt" class="text-orange-400 text-xl" />
|
|
</div>
|
|
<div>
|
|
<div class="font-bold text-highlighted">{{ $t('landing.sos_title') }}</div>
|
|
<div class="text-xs text-orange-400">{{ $t('landing.sos_subtitle') }}</div>
|
|
</div>
|
|
</div>
|
|
<p class="text-sm text-muted leading-relaxed">
|
|
{{ $t('landing.sos_desc') }}
|
|
</p>
|
|
<div class="grid grid-cols-2 gap-2">
|
|
<div class="bg-elevated rounded-xl px-3 py-2.5 flex items-center gap-2">
|
|
<span class="text-xl">😤</span>
|
|
<span class="text-sm text-default">{{ $t('landing.sos_angry') }}</span>
|
|
</div>
|
|
<div class="bg-elevated rounded-xl px-3 py-2.5 flex items-center gap-2">
|
|
<span class="text-xl">😔</span>
|
|
<span class="text-sm text-default">{{ $t('landing.sos_sad') }}</span>
|
|
</div>
|
|
<div class="bg-elevated rounded-xl px-3 py-2.5 flex items-center gap-2">
|
|
<span class="text-xl">😰</span>
|
|
<span class="text-sm text-default">{{ $t('landing.sos_stressed') }}</span>
|
|
</div>
|
|
<div class="bg-elevated rounded-xl px-3 py-2.5 flex items-center gap-2">
|
|
<span class="text-xl">😶</span>
|
|
<span class="text-sm text-default">{{ $t('landing.sos_empty') }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Atemübungen -->
|
|
<div class="bg-primary-950/20 border border-primary-800/20 rounded-3xl p-6 flex flex-col gap-4">
|
|
<div class="flex items-center gap-3">
|
|
<div
|
|
class="w-10 h-10 rounded-xl bg-primary-900/60 border border-primary-700/30 flex items-center justify-center shrink-0">
|
|
<UIcon name="i-heroicons-heart" class="text-primary-400 text-xl" />
|
|
</div>
|
|
<div>
|
|
<div class="font-bold text-highlighted">{{ $t('landing.breathing_title') }}</div>
|
|
<div class="text-xs text-primary-400">{{ $t('landing.breathing_subtitle') }}</div>
|
|
</div>
|
|
</div>
|
|
<p class="text-sm text-muted leading-relaxed">
|
|
{{ $t('landing.breathing_desc') }}
|
|
</p>
|
|
<div class="flex items-center justify-center py-6">
|
|
<div class="relative flex items-center justify-center">
|
|
<div
|
|
class="w-24 h-24 rounded-full bg-primary-900/20 border border-primary-700/20 absolute animate-ping opacity-20">
|
|
</div>
|
|
<div
|
|
class="w-20 h-20 rounded-full bg-primary-900/30 border border-primary-700/30 absolute opacity-40 scale-110">
|
|
</div>
|
|
<div
|
|
class="w-16 h-16 rounded-full bg-primary-900/50 border border-primary-600/40 flex items-center justify-center">
|
|
<span class="text-primary-200 text-xs font-bold">{{ $t('landing.breathing_breathe') }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="flex justify-between text-[11px] px-2">
|
|
<span class="text-primary-400 font-medium">{{ $t('landing.breathing_inhale') }}</span>
|
|
<span class="text-dimmed">→</span>
|
|
<span class="text-muted">{{ $t('landing.breathing_hold') }}</span>
|
|
<span class="text-dimmed">→</span>
|
|
<span class="text-muted">{{ $t('landing.breathing_exhale') }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Coach + Community -->
|
|
<section class="py-8 px-4 bg-linear-to-b from-transparent via-primary-950/10 to-transparent">
|
|
<div v-motion :initial="{ opacity: 0, y: 50 }" :visible="{ opacity: 1, y: 0, transition: { duration: 700 } }"
|
|
class="max-w-6xl mx-auto grid lg:grid-cols-2 gap-16 items-center">
|
|
<div class="flex items-center justify-center">
|
|
<div class="w-72 bg-elevated border border-default rounded-3xl p-6 space-y-3 shadow-2xl">
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<div class="w-8 h-8 rounded-full bg-primary-900 flex items-center justify-center">
|
|
<UIcon name="i-heroicons-cpu-chip" class="text-primary-400 text-sm" />
|
|
</div>
|
|
<span class="text-sm font-medium text-highlighted">{{ $t('landing.coach_label') }}</span>
|
|
</div>
|
|
<div v-for="msg in chatMessages" :key="msg.text" :class="msg.isBot ? 'mr-8' : 'ml-8 text-right'">
|
|
<div :class="msg.isBot
|
|
? 'bg-muted text-default rounded-2xl rounded-tl-sm'
|
|
: 'bg-primary-600 text-white rounded-2xl rounded-tr-sm'
|
|
" class="inline-block px-3 py-2 text-xs leading-relaxed max-w-[90%]">
|
|
{{ msg.text }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div
|
|
class="inline-flex items-center gap-2 bg-primary-950/60 border border-primary-800/40 rounded-full px-3 py-1 text-xs text-primary-300 mb-6">
|
|
<UIcon name="i-heroicons-user-group" />
|
|
{{ $t('landing.coach_badge') }}
|
|
</div>
|
|
<h2 class="text-4xl md:text-5xl font-black text-highlighted leading-tight mb-6">
|
|
{{ $t('landing.coach_title') }}<br />
|
|
<span class="text-primary-400">{{ $t('landing.coach_subtitle') }}</span>
|
|
</h2>
|
|
<p class="text-lg text-muted leading-relaxed mb-6">
|
|
{{ $t('landing.coach_desc') }}
|
|
</p>
|
|
<div class="bg-primary-950/30 border border-primary-800/20 rounded-2xl p-4 space-y-3">
|
|
<div class="flex items-center gap-2">
|
|
<UIcon name="i-heroicons-rocket-launch" class="text-primary-400" />
|
|
<span class="text-xs font-bold text-primary-300 uppercase tracking-wider">{{
|
|
$t('landing.founding_badge') }}</span>
|
|
</div>
|
|
<p class="text-sm text-muted">{{ $t('landing.founding_desc', { count: 50 }) }}</p>
|
|
<div class="flex items-center gap-3">
|
|
<div class="flex-1 bg-muted rounded-full h-1.5 overflow-hidden">
|
|
<div class="bg-linear-to-r from-primary-500 to-orange-500 h-full rounded-full" style="width: 34%">
|
|
</div>
|
|
</div>
|
|
<span class="text-xs text-muted shrink-0">{{ $t('landing.founding_slots', { current: 17, total: 50 })
|
|
}}</span>
|
|
</div>
|
|
<a href="https://apps.apple.com/app/rebreak" target="_blank" rel="noopener">
|
|
<UButton size="sm" class="w-full">
|
|
<UIcon name="i-heroicons-bolt" />
|
|
{{ $t('landing.founding_cta') }}
|
|
</UButton>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Mail Agent -->
|
|
<section class="py-8 px-4 bg-linear-to-b from-transparent via-primary-950/10 to-transparent">
|
|
<div v-motion :initial="{ opacity: 0, y: 50 }" :visible="{ opacity: 1, y: 0, transition: { duration: 700 } }"
|
|
class="max-w-6xl mx-auto grid lg:grid-cols-2 gap-16 items-center">
|
|
<div>
|
|
<div
|
|
class="inline-flex items-center gap-2 bg-primary-950/60 border border-primary-800/40 rounded-full px-3 py-1 text-xs text-primary-300 mb-6">
|
|
<UIcon name="i-heroicons-envelope" />
|
|
{{ $t('landing.mail_badge') }}
|
|
</div>
|
|
<h2 class="text-4xl md:text-5xl font-black text-highlighted leading-tight mb-6">
|
|
{{ $t('landing.mail_title') }}<br />
|
|
<span class="text-primary-400">{{ $t('landing.mail_subtitle') }}</span>
|
|
</h2>
|
|
<p class="text-lg text-muted leading-relaxed mb-6">
|
|
{{ $t('landing.mail_desc') }}
|
|
</p>
|
|
<ul class="space-y-3 text-sm text-default">
|
|
<li class="flex items-center gap-3">
|
|
<UIcon name="i-heroicons-check-circle" class="text-primary-400 shrink-0" />
|
|
{{ $t('landing.mail_feat_providers') }}
|
|
</li>
|
|
<li class="flex items-center gap-3">
|
|
<UIcon name="i-heroicons-check-circle" class="text-primary-400 shrink-0" />
|
|
{{ $t('landing.mail_feat_intervals') }}
|
|
</li>
|
|
<li class="flex items-center gap-3">
|
|
<UIcon name="i-heroicons-check-circle" class="text-primary-400 shrink-0" />
|
|
{{ $t('landing.mail_feat_privacy') }}
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<!-- Mock Mail-App UI -->
|
|
<div class="flex items-center justify-center">
|
|
<div class="w-72 bg-elevated border border-default rounded-3xl p-5 shadow-2xl space-y-4">
|
|
<div class="grid grid-cols-3 gap-2 text-center">
|
|
<div class="bg-muted rounded-xl p-2.5">
|
|
<div class="text-xl font-black text-primary-400">276</div>
|
|
<div class="text-[10px] text-muted mt-0.5">{{ $t('landing.mail_mock_blocked') }}</div>
|
|
</div>
|
|
<div class="bg-muted rounded-xl p-2.5">
|
|
<div class="text-xl font-black text-highlighted">1450</div>
|
|
<div class="text-[10px] text-muted mt-0.5">{{ $t('landing.mail_mock_scanned') }}</div>
|
|
</div>
|
|
<div class="bg-muted rounded-xl p-2.5">
|
|
<div class="text-xl font-black text-orange-400">19%</div>
|
|
<div class="text-[10px] text-muted mt-0.5">{{ $t('landing.mail_mock_rate') }}</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div class="flex items-center justify-between mb-2">
|
|
<div class="text-xs text-muted font-medium">{{ $t('landing.mail_mock_accounts') }}</div>
|
|
<span class="text-xs text-primary-400 font-medium">2/5</span>
|
|
</div>
|
|
<div class="bg-muted rounded-xl p-3">
|
|
<div class="flex items-center gap-2">
|
|
<div
|
|
class="w-6 h-6 rounded-full bg-primary-900/60 border border-primary-800/30 flex items-center justify-center shrink-0">
|
|
<UIcon name="i-heroicons-envelope" class="text-primary-400 text-xs" />
|
|
</div>
|
|
<div class="flex-1 min-w-0">
|
|
<div class="text-xs text-highlighted font-medium truncate">user@example.com</div>
|
|
<div class="text-[10px] text-primary-400">4 blockiert · 06.04.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ─── FINAL CTA ─── -->
|
|
<section class="py-16 px-4 pb-24 text-center relative">
|
|
<div class="absolute inset-0 bg-linear-to-t from-primary-950/20 to-transparent pointer-events-none" />
|
|
<div class="relative max-w-2xl mx-auto">
|
|
<h2 class="text-5xl font-black text-highlighted mb-4">{{ $t('landing.final_title') }}</h2>
|
|
<p class="text-muted mb-10 text-lg">
|
|
{{ $t('landing.final_desc') }}
|
|
</p>
|
|
<a href="https://apps.apple.com/app/rebreak" target="_blank" rel="noopener">
|
|
<UButton size="xl" class="px-12">
|
|
<UIcon name="i-heroicons-bolt" />
|
|
{{ $t('landing.final_cta') }}
|
|
</UButton>
|
|
</a>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
definePageMeta({ layout: "default" });
|
|
|
|
const { t } = useI18n();
|
|
|
|
const infoSections = ref<HTMLElement | null>(null);
|
|
const showInfoSections = ref(true);
|
|
|
|
onMounted(() => {
|
|
if (window.innerWidth < 768) showInfoSections.value = false;
|
|
});
|
|
|
|
function scrollToInfo() {
|
|
showInfoSections.value = true;
|
|
nextTick(() => infoSections.value?.scrollIntoView({ behavior: "smooth" }));
|
|
}
|
|
|
|
const blockerFeatures = computed(() => [
|
|
t('landing.blocker_feat_platforms'),
|
|
t('landing.blocker_feat_updated'),
|
|
t('landing.blocker_feat_custom'),
|
|
t('landing.blocker_feat_cooldown'),
|
|
]);
|
|
|
|
const chatMessages = computed(() => [
|
|
{ text: t('landing.chat_msg_1'), isBot: false },
|
|
{ text: t('landing.chat_msg_2'), isBot: true },
|
|
{ text: t('landing.chat_msg_3'), isBot: false },
|
|
{ text: t('landing.chat_msg_4'), isBot: true },
|
|
]);
|
|
</script>
|