PageSourceSearch

https://wunschzettel.io/

html wunschzettel.io collected 2026-10-02 01:58:02 UTC 19,937 bytes, 219 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en" class="overflow-x-hidden">
3<head>
4    <meta charset="UTF-8">
5    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
6    <title>Wunschzettel Dashboard</title>
7    <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
8    <meta http-equiv="Pragma" content="no-cache">
9    <meta http-equiv="Expires" content="0">
10    <link rel="icon" type="image/png" href="/assets/favicon.png">
11    <link rel="apple-touch-icon" href="/assets/favicon.png">
12    
13    <!-- SEO Meta Tags -->
14    <meta name="description" content="Erstelle und teile deine Wünsche ganz einfach online.">
15    <meta name="robots" content="index, follow">
16    
17    <!-- OG_TAGS -->
18    
19    <!-- Google reCAPTCHA v3 & Cloudflare Turnstile -->
20    <!-- Preload Critical Assets -->
21    <link rel="preload" href="/style_v4.css?v=cw117" as="style">
22    <link rel="preload" href="/assets/vendor/fonts/QGYvz_MVcBeNP4NJtEtqUYLknw.woff2" as="font" type="font/woff2" crossorigin>
23    
24    <!-- Fonts & Icons (GDPR Compliant Local Hosting) -->
25    <style>@font-face{font-family:'Outfit';font-style:normal;font-weight:300;font-display:swap;src:url(/assets/vendor/fonts/QGYvz_MVcBeNP4NJuktqUYLkn8BJ.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Outfit';font-style:normal;font-weight:300;font-display:swap;src:url(/assets/vendor/fonts/QGYvz_MVcBeNP4NJtEtqUYLknw.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Outfit';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/vendor/fonts/QGYvz_MVcBeNP4NJuktqUYLkn8BJ.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Outfit';font-style:normal;font-weight:400;font-display:swap;src:url(/assets/vendor/fonts/QGYvz_MVcBeNP4NJtEtqUYLknw.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Outfit';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/vendor/fonts/QGYvz_MVcBeNP4NJuktqUYLkn8BJ.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Outfit';font-style:normal;font-weight:500;font-display:swap;src:url(/assets/vendor/fonts/QGYvz_MVcBeNP4NJtEtqUYLknw.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Outfit';font-style:normal;font-weight:600;font-display:swap;src:url(/assets/vendor/fonts/QGYvz_MVcBeNP4NJuktqUYLkn8BJ.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Outfit';font-style:normal;font-weight:600;font-display:swap;src:url(/assets/vendor/fonts/QGYvz_MVcBeNP4NJtEtqUYLknw.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Outfit';font-style:normal;font-weight:700;font-display:swap;src:url(/assets/vendor/fonts/QGYvz_MVcBeNP4NJuktqUYLkn8BJ.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1D
25BF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'Outfit';font-style:normal;font-weight:700;font-display:swap;src:url(/assets/vendor/fonts/QGYvz_MVcBeNP4NJtEtqUYLknw.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}</style>
26    <!-- Defer Icon CSS to unblock rendering -->
27    <link rel="stylesheet" href="/assets/vendor/bootstrap-icons/bootstrap-icons.css" media="print" onload="this.media='all'">
28    <noscript><link rel="stylesheet" href="/assets/vendor/bootstrap-icons/bootstrap-icons.css"></noscript>
29    
30    <!-- Scripts (GDPR Compliant Local Hosting) -->
31    
31<script src="/assets/vendor/vue.global.js" defer></script>
31
32    
32<script src="/assets/vendor/qrcode.min.js?v=2" defer></script>
32
33    
33<script src="/assets/vendor/purify.min.js" defer></script>
33
34    
34<script src="/assets/vendor/Sortable.min.js" defer></script>
34
35    <!-- Custom Styles (Compiled Tailwind + Base Styles) -->
36    <link rel="stylesheet" href="/style_v4.css?v=cw117">
37</head>
38<body class="bg-slate-50 text-slate-800 min-h-screen font-sans antialiased overflow-x-hidden relative">
39    <div id="app" class="min-h-screen flex flex-col overflow-x-hidden w-full max-w-[100vw]">
40        <!-- Global Toast -->
41        <transition enter-active-class="transition duration-300 ease-out transform"
42                    enter-from-class="-translate-y-10 opacity-0"
43                    enter-to-class="translate-y-0 opacity-100"
44                    leave-active-class="transition duration-200 ease-in transform"
45                    leave-from-class="translate-y-0 opacity-100"
46                    leave-to-class="-translate-y-10 opacity-0">
47            <div v-if="toastMessage" 
48                 class="fixed top-6 left-1/2 transform -translate-x-1/2 z-[100] px-6 py-3 rounded-full font-medium text-sm shadow-xl flex items-center space-x-3 pointer-events-none max-w-[90vw] text-center leading-tight"
49                 :class="{
50                    'bg-emerald-500 text-white shadow-emerald-500/20': toastType === 'success',
51                    'bg-red-500 text-white shadow-red-500/20': toastType === 'error',
52                    'bg-slate-800 text-white shadow-slate-800/20': toastType === 'info'
53                 }">
54                <i class="bi shrink-0" :class="{
55                    'bi-check-circle-fill': toastType === 'success',
56                    'bi-exclamation-triangle-fill': toastType === 'error',
57                    'bi-info-circle-fill': toastType === 'info'
58                }"></i>
59                <span>{{ toastMessage }}</span>
60            </div>
61        </transition>
62        
63    
64    <!-- Background Elements (Optimized without blur) -->
65    <div v-if="!isEmbed" class="fixed top-[-20%] left-[-10%] w-[50%] h-[50%] rounded-full pointer-events-none" style="background: radial-gradient(circle, rgba(99,102,241,0.15) 0%, rgba(99,102,241,0) 70%);"></div>
66    <div v-if="!isEmbed" class="fixed bottom-[-20%] right-[-10%] w-[50%] h-[50%] rounded-full pointer-events-none" style="background: radial-gradient(circle, rgba(236,72,153,0.15) 0%, rgba(236,72,153,0) 70%);"></div>
67
68    <!-- Navigation Bar -->
69    <nav v-if="!isEmbed" class="glass-nav fixed w-full z-50 top-0 border-b border-white/5 transition-all" style="padding-top: env(safe-area-inset-top);">
70        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
71            <div class="flex justify-between h-16 items-center">
72                <div class="flex-shrink-0 flex items-center cursor-pointer lg:w-1/4" @click="goHome">
73                    <i class="bi bi-gift text-2xl text-primary mr-2"></i>
74                    <span class="font-bold text-xl tracking-tight bg-clip-text text-transparent bg-gradient-to-r from-primary to-secondary">Wunschzettel</span><span class="font-bold text-sm text-pink-600 ml-0.5">.io</span>
75                </div>
76                
77                <!-- Main Desktop Navigation -->
78                <div class="hidden lg:flex flex-1 justify-center items-center space-x-8">
79                    <a :href="'/' + lang + '/' + (lang === 'en' ? 'wedding-registry' : 'hochzeitstisch') + '/'" @click.prevent="navigate({view: 'LandingPageView', args: {topic: 'hochzeit'}, path: '/' + (lang === 'en' ? 'wedding-registry' : 'hochzeitstisch') + '/'})" class="text-sm font-bold text-slate-600 hover:text-primary transition-colors">{{ $t('lp_hochzeit.breadcrumb') }}</a>
80                    <a :href="'/' + lang + '/' + (lang === 'en' ? 'christmas-wishlist' : 'weihnachten') + '/'" @click.prevent="navigate({view: 'LandingPageView', args: {topic: 'weihnachten'}, path: '/' + (lang === 'en' ? 'christmas-wishlist' : 'weihnachten') + '/'})" class="text-sm font-bold text-slate-600 hover:text-primary transition-colors">{{ $t('lp_weihnachten.breadcrumb') }}</a>
81                    <a :href="'/' + lang + '/' + (lang === 'en' ? 'kids-birthday' : 'kindergeburtstag') + '/'" @click.prevent="navigate({view: 'LandingPageView', args: {topic: 'kinder'}, path: '/' + (lang === 'en' ? 'kids-birthday' : 'kindergeburtstag') + '/'})" class="text-sm font-bold text-slate-600 hover:text-primary transition-colors">{{ $t('lp_kinder.breadcrumb') }}</a>
82                    <a :href="'/' + lang + '/' + (lang === 'en' ? 'baby-registry' : 'baby-geschenke') + '/'" @click.prevent="navigate({view: 'LandingPageView', args: {topic: 'baby'}, path: '/' + (lang === 'en' ? 'baby-registry' : 'baby-geschenke') + '/'})" class="text-sm font-bold text-slate-600 hover:text-primary transition-colors">{{ $t('lp_baby.breadcrumb') }}</a>
83                    <a :href="'/' + lang + '/faq'" @click.prevent="navigate({view: 'FaqView', path: '/faq'})" class="text-sm font-bold text-slate-600 hover:text-primary transition-colors">FAQ</a>
84                </div>
85
86                <div class="flex items-center justify-end space-x-4 lg:w-1/4">
87                    <template v-if="user">
88                        <a :href="'/' + lang + '/search/'" class="text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors mr-4 hidden sm:inline-block"><i class="bi bi-search mr-1"></i> {{ $t('nav.search') }}</a>
89                        <a :href="'/' + lang + '/'" @click.prevent="navigate({view: 'ProfileView', path: '/'})" class="text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors mr-4">
90                            <i class="bi bi-person-circle mr-1"></i> {{ user.name }}
91                        </a>
92                        <button @click="logout" class="text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors border border-slate-300 px-3 py-1.5 rounded-lg hover:bg-slate-100">
93                            {{ $t('nav.logout') }}
94                        </button>
95                    </template>
96                    <template v-else>
97                        <a :href="'/' + lang + '/search/'" class="text-sm font-medium text-slate-600 hover:text-slate-900 transition-colors mr-4 hidden sm:inline-block"><i class="bi bi-search mr-1"></i> {{ $t('nav.search') }}</a>
98                        <a :href="'/' + lang + '/'" @click.prevent="navigate({view: 'LoginView', path: '/'})" class="text-sm font-medium text-white bg-indigo-700 hover:bg-indigo-800 border border-indigo-700/50 transition-all px-4 py-2 rounded-lg shadow-sm inline-block">{{ $t('nav.login') }}</a>
99                    </template>
100                </div>
101            </div>
102        </div>
103    </nav>
104    
105    <!-- Main Content Area -->
106    <main class="px-4 sm:px-6 lg:px-8 max-w-7xl w-full mx-auto transition-all duration-300" :style="isEmbed ? 'padding: 1rem; flex-grow: 1;' : 'padding-top: calc(7rem + env(safe-area-inset-top)); padding-bottom: max(3rem, env(safe-area-inset-bottom)); flex-grow: 1;'">
107        
108        <!-- Loading State -->
109        <div v-if="loading" class="flex justify-center items-center h-64">
110            <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary"></div>
111        </div>
112
113        <!-- Dynamic View Injection -->
114        <component :is="currentView" v-else-if="currentView" :user="user" :args="viewArgs" @login-success="handleLogin" @navigate="navigate"></component>
115
116    </main>
117    
118    <!-- Footer -->
119    <footer v-if="!isEmbed" class="bg-darker border-t border-white/5 mt-24 md:mt-32 pt-20 md:pt-32 pb-16 overflow-hidden text-sm text-slate-400" style="padding-bottom: max(4rem, env(safe-area-inset-bottom));">
120        <div class="max-w-7xl mx-auto px-8 sm:px-12 lg:px-16">
121            <!-- Grid Layout -->
122            <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-x-12 gap-y-12 mb-16">
123                
124                <!-- Col 1: Brand / App Links -->
125                <div class="space-y-6">
126                    <div class="flex items-center cursor-pointer" @click="goHome">
127                        <i class="bi bi-gift text-2xl text-primary mr-2 animate-pulse"></i>
128                        <span class="font-bold text-xl tracking-tight bg-clip-text text-transparent bg-gradient-to-r from-primary to-secondary">Wunschzettel</span><span class="font-bold text-sm text-pink-600 ml-0.5">.io</span>
129                    </div>
130                    <p class="text-slate-400 text-sm leading-relaxed max-w-xs">
131                        {{ $t('footer.slogan') }} – {{ $t('hero.subtitle') }}
132                    </p>
133                    <!-- Badges -->
134                    <div v-if="!isNative && !isEmbed" class="flex items-center gap-3">
135                        <a href="https://apps.apple.com/de/app/wunschzettel-io-wunschliste/id6762308060" target="_blank" class="hover:-translate-y-0.5 transition-transform flex items-center">
136                            <img alt="Laden im App Store" src="/assets/app-store-badge.svg" class="object-contain rounded-md" style="height: 35px;"/>
137                        </a>
138                        <a href="https://play.google.com/store/apps/details?id=io.wunschzettel.app" target="_blank" class="hover:-translate-y-0.5 transition-transform flex items-center">
139                            <img alt="Jetzt bei Google Play" src="/assets/google-play-badge.png" class="object-contain mix-blend-screen" style="height: 47px;"/>
140                        </a>
141                    </div>
142                </div>
143
144                <!-- Col 2: Landing Pages -->
145                <div>
146                    <h4 class="font-semibold text-white tracking-wider uppercase text-xs mb-4">{{ lang === 'en' ? 'Wishlist for...' : 'Wunschzettel für...' }}</h4>
147                    <ul class="space-y-3">
148                        <li>
149                            <a :href="'/' + lang + '/' + (lang === 'en' ? 'wedding-registry' : 'hochzeitstisch') + '/'" @click.prevent="navigate({view: 'LandingPageView', args: {topic: 'hochzeit'}, path: '/' + (lang === 'en' ? 'wedding-registry' : 'hochzeitstisch') + '/'})" class="hover:text-primary transition-colors block">{{ $t('lp_hochzeit.breadcrumb') }}</a>
150                        </li>
151                        <li>
152                            <a :href="'/' + lang + '/' + (lang === 'en' ? 'christmas-wishlist' : 'weihnachten') + '/'" @click.prevent="navigate({view: 'LandingPageView', args: {topic: 'weihnachten'}, path: '/' + (lang === 'en' ? 'christmas-wishlist' : 'weihnachten') + '/'})" class="hover:text-primary transition-colors block">{{ $t('lp_weihnachten.breadcrumb') }}</a>
153                        </li>
154                        <li>
155                            <a :href="'/' + lang + '/' + (lang === 'en' ? 'kids-birthday' : 'kindergeburtstag') + '/'" @click.prevent="navigate({view: 'LandingPageView', args: {topic: 'kinder'}, path: '/' + (lang === 'en' ? 'kids-birthday' : 'kindergeburtstag') + '/'})" class="hover:text-primary transition-colors block">{{ $t('lp_kinder.breadcrumb') }}</a>
156                        </li>
157                        <li>
158                            <a :href="'/' + lang + '/' + (lang === 'en' ? 'baby-registry' : 'baby-geschenke') + '/'" @click.prevent="navigate({view: 'LandingPageView', args: {topic: 'baby'}, path: '/' + (lang === 'en' ? 'baby-registry' : 'baby-geschenke') + '/'})" class="hover:text-primary transition-colors block">{{ $t('lp_baby.breadcrumb') }}</a>
159                        </li>
160                    </ul>
161                </div>
162
163                <!-- Col 3: Support -->
164                <div>
165                    <h4 class="font-semibold text-white tracking-wider up
165percase text-xs mb-4">Support</h4>
166                    <ul class="space-y-3">
167                        <li>
168                            <a @click.prevent="navigate({view: 'FaqView', path: '/faq/'})" :href="'/' + lang + '/faq/'" class="hover:text-primary transition-colors block">FAQ</a>
169                        </li>
170                        <li>
171                            <a @click.prevent="navigate({view: 'SupportView', path: '/support/'})" :href="'/' + lang + '/support/'" class="hover:text-primary transition-colors block">Support</a>
172                        </li>
173                        <li>
174                            <a @click.prevent="navigate({view: 'PublicSearchView', path: '/search/'})" :href="'/' + lang + '/search/'" class="hover:text-primary transition-colors block">{{ $t('footer.search') }}</a>
175                        </li>
176                    </ul>
177                </div>
178
179                <!-- Col 4: Rechtliches -->
180                <div>
181                    <h4 class="font-semibold text-white tracking-wider uppercase text-xs mb-4">{{ lang === 'en' ? 'Legal' : 'Rechtliches' }}</h4>
182                    <ul class="space-y-3">
183                        <li>
184                            <a @click.prevent="navigate({view: 'NutzungsbedingungenView', path: '/nutzungsbedingungen/'})" :href="'/' + lang + '/nutzungsbedingungen/'" class="hover:text-primary transition-colors block">{{ $t('footer.tos') }}</a>
185                        </li>
186                        <li>
187                            <a @click.prevent="navigate({view: 'DatenschutzView', path: '/datenschutz/'})" :href="'/' + lang + '/datenschutz/'" class="hover:text-primary transition-colors block">{{ $t('footer.privacy') }}</a>
188                        </li>
189                        <li>
190                            <a @click.prevent="navigate({view: 'ImpressumView', path: '/impressum/'})" :href="'/' + lang + '/impressum/'" class="hover:text-primary transition-colors block">{{ $t('footer.imprint') }}</a>
191                        </li>
192                    </ul>
193                </div>
194
195            </div>
196
197            <!-- Divider Line -->
198            <div class="border-t border-white/5 pt-8 flex flex-col md:flex-row justify-between items-center gap-6">
199                <div class="flex items-center space-x-3 text-slate-500 text-xs text-center md:text-left">
200                    <span>&copy; 2026 Wunschzettel.io. {{ lang === 'en' ? 'All rights reserved.' : 'Alle Rechte vorbehalten.' }}</span>
201                </div>
202                
203                <!-- Language Selector -->
204                <div class="flex items-center space-x-2">
205                    <i class="bi bi-globe text-slate-500 text-sm"></i>
206                    <select v-model="lang" @change="switchLang" aria-label="Sprache auswählen" class="bg-dark relative text-slate-300 border border-slate-700/80 hover:border-slate-500 rounded-lg px-2.5 py-1 text-xs outline-none cursor-pointer transition-colors focus:ring-1 focus:ring-primary/50">
207                        <option value="de">DEUTSCH</option>
208                        <option value="en">ENGLISH</option>
209                    </select>
210                </div>
211            </div>
212        </div>
213    </footer>
214    </div>
215    
216    
216<script src="/i18n.js?v=cw21" defer></script>
216
217    
217<script src="/app.js?v=cw194" defer></script>
217
218</body>
219</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.