feat(marketing): passwortgeschützte /preview App-Vorschau für FAGS/Ilona

Private, noindex App-Tour mit Client-seitigem Passwort-Gate (Cookie). 16 echte
Screenshots (Onboarding, Blocker, Block-Seite, Lyra, Atemübung, Mail-Schutz +
-Connect, Community-Feed/Chat/Anruf, Streak, Geräte, Eigene Domains, Admin-
Moderation) via PreviewPhone-Mockups. Admin-Shot als Handy-Rahmen (PreviewPhone).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
chahinebrini 2026-06-09 04:39:02 +02:00
parent 4987d05f10
commit 9fdb0d3a2e
21 changed files with 541 additions and 0 deletions

View File

@ -0,0 +1,46 @@
<script setup lang="ts">
/** Browser-/Admin-Fenster-Mockup mit Auto-Platzhalter, wenn die PNG fehlt. */
const props = defineProps<{
file: string
title: string
icon: string
url?: string
}>()
const failed = ref(false)
</script>
<template>
<div
class="w-full rounded-xl overflow-hidden border border-white/10 bg-gray-900 shadow-2xl shadow-primary-950/40"
>
<div class="flex items-center gap-1.5 px-3 h-8 bg-gray-800/80 border-b border-white/5">
<span class="w-2.5 h-2.5 rounded-full bg-red-400/70" />
<span class="w-2.5 h-2.5 rounded-full bg-yellow-400/70" />
<span class="w-2.5 h-2.5 rounded-full bg-green-400/70" />
<span class="ml-3 text-[11px] text-muted font-mono">{{ props.url || "admin.rebreak.org" }}</span>
</div>
<div class="aspect-[16/10] bg-black">
<img
v-if="!failed"
:src="`/preview/${props.file}`"
:alt="props.title"
class="w-full h-full object-cover"
loading="lazy"
@error="failed = true"
/>
<div
v-else
class="w-full h-full flex flex-col items-center justify-center gap-3 bg-linear-to-b from-gray-900 to-gray-950 px-6 text-center"
>
<div class="w-12 h-12 rounded-2xl bg-primary-500/15 flex items-center justify-center">
<UIcon :name="props.icon" class="text-primary-400 text-2xl" />
</div>
<p class="text-sm font-bold text-highlighted">{{ props.title }}</p>
<p class="text-[11px] text-muted leading-snug">
Screenshot folgt<br />
<span class="font-mono">preview/{{ props.file }}</span>
</p>
</div>
</div>
</div>
</template>

View File

@ -0,0 +1,46 @@
<script setup lang="ts">
/** iPhone-Mockup mit Auto-Platzhalter, wenn die PNG fehlt. */
const props = defineProps<{
file: string
title: string
icon: string
width?: string
}>()
const failed = ref(false)
</script>
<template>
<div
class="relative shrink-0 rounded-[2.4rem] bg-gray-900 border border-white/10 p-2 shadow-2xl shadow-primary-950/40"
:style="{ width: props.width || '240px' }"
>
<div
class="absolute top-3.5 left-1/2 -translate-x-1/2 w-16 h-4 bg-black rounded-full z-10"
/>
<div class="rounded-[1.9rem] overflow-hidden bg-black aspect-[9/19.5]">
<img
v-if="!failed"
:src="`/preview/${props.file}`"
:alt="props.title"
class="w-full h-full object-cover"
loading="lazy"
@error="failed = true"
/>
<div
v-else
class="w-full h-full flex flex-col items-center justify-center gap-2.5 bg-linear-to-b from-gray-900 to-gray-950 px-4 text-center"
>
<div
class="w-11 h-11 rounded-2xl bg-primary-500/15 flex items-center justify-center"
>
<UIcon :name="props.icon" class="text-primary-400 text-xl" />
</div>
<p class="text-[13px] font-bold text-highlighted leading-tight">{{ props.title }}</p>
<p class="text-[10px] text-muted leading-snug">
Screenshot folgt<br />
<span class="font-mono">preview/{{ props.file }}</span>
</p>
</div>
</div>
</div>
</template>

View File

@ -0,0 +1,406 @@
<script setup lang="ts">
/**
* /preview — Passwortgeschützte App-Vorschau (für FAGS / Ilona).
*
* - Einfaches Frontend-Gate (Cookie). Passwort unten ändern.
* - Screenshots: PNGs nach `apps/marketing/public/preview/` legen (Namen s. u.).
* Fehlt eine Datei, zeigt das Mockup automatisch einen Platzhalter.
*/
definePageMeta({ layout: false })
useHead({
title: "Rebreak App-Vorschau",
meta: [{ name: "robots", content: "noindex, nofollow" }],
})
// Passwort-Gate
const PREVIEW_PASSWORD = "rebreak-fags" // TODO vor dem Teilen ändern
const unlockedCookie = useCookie<string>("rebreak_preview", {
maxAge: 60 * 60 * 24 * 30,
sameSite: "lax",
})
const unlocked = ref(unlockedCookie.value === "1")
const passwordInput = ref("")
const wrong = ref(false)
function tryUnlock() {
if (passwordInput.value.trim() === PREVIEW_PASSWORD) {
unlockedCookie.value = "1"
unlocked.value = true
wrong.value = false
} else {
wrong.value = true
}
}
// Reduced-Motion-respektierende Animationen
const reduce = usePreferredReducedMotion()
const fadeUp = computed(() =>
reduce.value === "reduce"
? { initial: { opacity: 1 }, visibleOnce: { opacity: 1 } }
: {
initial: { opacity: 0, y: 40 },
visibleOnce: { opacity: 1, y: 0, transition: { duration: 600 } },
},
)
const steps = [
{ icon: "i-heroicons-arrow-down-tray", title: "Installieren", text: "In wenigen Minuten eingerichtet, ohne Vorkenntnisse." },
{ icon: "i-heroicons-shield-check", title: "Schutz aktivieren", text: "Glücksspiel wird geräteweit gesperrt." },
{ icon: "i-heroicons-heart", title: "Begleitet bleiben", text: "In schweren und guten Momenten ist Rebreak da." },
]
const mailProviders = [
{ name: "Gmail", icon: "i-simple-icons-gmail" },
{ name: "iCloud", icon: "i-simple-icons-icloud" },
{ name: "Outlook", icon: "i-simple-icons-microsoftoutlook" },
{ name: "GMX", icon: "i-simple-icons-gmx" },
{ name: "Yahoo", icon: "i-simple-icons-yahoo" },
{ name: "IONOS", icon: "i-simple-icons-ionos" },
{ name: "Freenet", icon: "i-simple-icons-freenet" },
{ name: "Proton", icon: "i-simple-icons-proton" },
]
const onboardingSteps = [
{ file: "01a-onboarding.png", title: "Konto & Spitzname", icon: "i-heroicons-user-circle", caption: "Anmelden und Spitzname wählen, nie mit Klarnamen." },
{ file: "01b-onboarding.png", title: "Schutz einrichten", icon: "i-heroicons-shield-check", caption: "Schritt für Schritt den Geräteschutz aktivieren." },
{ file: "01c-onboarding.png", title: "Los geht's", icon: "i-heroicons-check-circle", caption: "Fertig, ab jetzt begleitet Rebreak dich." },
]
</script>
<template>
<div class="bg-default min-h-dvh text-default font-sans overflow-x-hidden">
<!-- PASSWORT-GATE -->
<div v-if="!unlocked" class="min-h-dvh 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="relative w-full max-w-sm">
<img src="/app-icon.png" alt="Rebreak" class="w-16 h-16 rounded-2xl mx-auto mb-6 shadow-lg" />
<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-6">
<UIcon name="i-heroicons-lock-closed" class="text-primary-400" />
Geschützte Vorschau
</div>
<h1 class="text-2xl font-black text-highlighted mb-2">Rebreak App-Vorschau</h1>
<p class="text-sm text-muted mb-8">
Diese Seite ist privat. Bitte gib das Passwort ein, das du erhalten hast.
</p>
<form class="flex flex-col gap-3" @submit.prevent="tryUnlock">
<UInput v-model="passwordInput" type="password" size="xl" placeholder="Passwort" autofocus aria-label="Passwort" />
<p v-if="wrong" class="text-sm text-error">Das Passwort stimmt nicht. Bitte versuche es erneut.</p>
<UButton type="submit" size="xl" block class="mt-1">
<UIcon name="i-heroicons-arrow-right-on-rectangle" />
Vorschau öffnen
</UButton>
</form>
</div>
</div>
<!-- INHALT -->
<template v-else>
<header class="sticky top-0 z-30 backdrop-blur-md bg-gray-950/70 border-b border-white/5">
<div class="max-w-6xl mx-auto px-4 h-14 flex items-center gap-3">
<img src="/app-icon.png" alt="Rebreak" class="w-8 h-8 rounded-lg" />
<span class="font-extrabold text-highlighted">Rebreak</span>
<span class="text-xs text-muted ml-1">App-Vorschau</span>
</div>
</header>
<!-- HERO -->
<section class="relative px-4 pt-16 pb-10 text-center">
<div class="absolute top-0 left-1/2 -translate-x-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">
<img src="/app-icon.png" alt="Rebreak" class="w-20 h-20 rounded-3xl mx-auto mb-8 shadow-xl" />
<h1 class="text-3xl md:text-6xl font-black text-highlighted leading-[1.05] tracking-tight mb-6">
So sieht Rebreak aus,
<span class="block text-transparent bg-clip-text bg-linear-to-r from-primary-300 to-primary-500">und so hilft es.</span>
</h1>
<p class="text-base text-muted max-w-xl mx-auto leading-relaxed">
Ein kurzer, ehrlicher Eindruck der App. Vom ersten Einrichten über den Schutz im
Alltag bis zur Begleitung in den schweren Momenten.
</p>
</div>
</section>
<!-- 3-SCHRITT-WORKFLOW -->
<section class="px-4 py-10">
<div class="max-w-5xl mx-auto grid sm:grid-cols-3 gap-4">
<div
v-for="(s, i) in steps"
:key="s.title"
v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce"
class="rounded-2xl border border-white/10 bg-white/[0.03] p-6 text-center"
>
<div class="w-11 h-11 mx-auto mb-4 rounded-xl bg-primary-500/15 flex items-center justify-center">
<UIcon :name="s.icon" class="text-primary-400 text-xl" />
</div>
<div class="text-xs font-bold text-primary-400 mb-1">Schritt {{ i + 1 }}</div>
<h3 class="font-extrabold text-highlighted mb-1">{{ s.title }}</h3>
<p class="text-sm text-muted leading-relaxed">{{ s.text }}</p>
</div>
</div>
</section>
<!-- ONBOARDING (3 Schritte) -->
<section class="px-4 py-10">
<div class="max-w-6xl mx-auto">
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="text-center max-w-2xl mx-auto mb-10">
<span 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-5"><UIcon name="i-heroicons-sparkles" />Start</span>
<h2 class="text-2xl md:text-3xl font-black text-highlighted leading-tight mb-4">Ein ruhiger Einstieg</h2>
<p class="text-base text-muted leading-relaxed">Kein Druck, keine Hürden. In wenigen Schritten eingerichtet, jeder Schritt verständlich erklärt.</p>
</div>
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="flex flex-wrap justify-center items-start gap-6 md:gap-10">
<div v-for="(s, i) in onboardingSteps" :key="s.file" class="flex flex-col items-center gap-3 w-[220px]">
<PreviewPhone :file="s.file" :title="s.title" :icon="s.icon" width="220px" />
<div class="text-xs font-bold text-primary-400">Schritt {{ i + 1 }}</div>
<p class="text-sm font-semibold text-default -mt-1">{{ s.title }}</p>
<p class="text-xs text-muted text-center leading-snug -mt-1">{{ s.caption }}</p>
</div>
</div>
</div>
</section>
<div class="max-w-6xl mx-auto px-4 flex flex-col gap-24 md:gap-32 py-10">
<!-- 02 BLOCKER -->
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="grid md:grid-cols-2 gap-10 md:gap-16 items-center">
<div class="flex justify-center md:order-2">
<PreviewPhone file="02-blocker.png" title="Glücksspiel sperren" icon="i-heroicons-shield-check" />
</div>
<div class="md:order-1">
<span 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-5"><UIcon name="i-heroicons-shield-check" />Schutz</span>
<h2 class="text-2xl md:text-3xl font-black text-highlighted leading-tight mb-4">Glücksspiel geräteweit sperren</h2>
<p class="text-base text-muted leading-relaxed">Über 300.000 Domains werden blockiert, auch die nicht-lizenzierten Offshore-Seiten, die OASIS nicht erreicht. Der Schutz lässt sich so verankern, dass er im Drang-Moment nicht einfach löschbar ist.</p>
</div>
</div>
<!-- 03 BLOCK-SCREEN -->
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="grid md:grid-cols-2 gap-10 md:gap-16 items-center">
<div class="flex justify-center">
<PreviewPhone file="03-blocked.png" title="Sofort wirksam" icon="i-heroicons-no-symbol" />
</div>
<div>
<span 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-5"><UIcon name="i-heroicons-no-symbol" />Schutz</span>
<h2 class="text-2xl md:text-3xl font-black text-highlighted leading-tight mb-4">Sofort wirksam</h2>
<p class="text-base text-muted leading-relaxed">Wird eine gesperrte Seite aufgerufen, greift Rebreak sofort, ruhig und ohne zu beschämen.</p>
</div>
</div>
</div>
<!-- MAIL-SCHUTZ (eigene Sektion) -->
<section class="px-4 py-14 bg-white/[0.02] border-y border-white/5">
<div class="max-w-6xl mx-auto">
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="grid md:grid-cols-2 gap-10 md:gap-16 items-center">
<div class="flex justify-center gap-4">
<PreviewPhone file="06-mail-schutz.png" title="Mail-Schutz" icon="i-heroicons-envelope" />
<PreviewPhone file="06b-mail-connect.png" title="Konto verbinden" icon="i-heroicons-link" width="200px" class="hidden lg:block mt-8" />
</div>
<div>
<span 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-5"><UIcon name="i-heroicons-envelope" />Mail-Schutz</span>
<h2 class="text-2xl md:text-3xl font-black text-highlighted leading-tight mb-4">Casino-Werbung verschwindet, bevor sie wirkt</h2>
<p class="text-base text-muted leading-relaxed mb-5">Rebreak entfernt Casino-Werbemails in Echtzeit aus dem Postfach, bevor die Push-Benachrichtigung überhaupt einen Rückfall auslösen kann.</p>
<div class="flex items-start gap-3 rounded-xl border border-primary-800/40 bg-primary-950/40 p-4 mb-6">
<UIcon name="i-heroicons-lock-closed" class="text-primary-400 text-xl shrink-0 mt-0.5" />
<p class="text-sm text-default leading-relaxed"><span class="font-bold text-highlighted">Datenschutz by Design.</span> Rebreak liest niemals den Inhalt deiner Mails. Verarbeitet werden ausschließlich <span class="text-highlighted">Absender und Betreff</span>, nur um Glücksspiel-Werbung zu erkennen. DSGVO-konform, auf Servern in Deutschland.</p>
</div>
<p class="text-xs text-muted mb-4">Konto in wenigen Sekunden verbinden, unterstützt u. a.:</p>
<div class="flex flex-wrap items-center gap-x-5 gap-y-3">
<div v-for="p in mailProviders" :key="p.name" class="flex items-center gap-1.5" :title="p.name">
<UIcon :name="p.icon" class="text-highlighted text-2xl" />
<span class="text-sm font-semibold text-muted">{{ p.name }}</span>
</div>
<span class="text-sm font-semibold text-muted">u. v. m.</span>
</div>
</div>
</div>
</div>
</section>
<div class="max-w-6xl mx-auto px-4 flex flex-col gap-24 md:gap-32 py-14">
<!-- 04 LYRA (Coaching + Krise) -->
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="grid md:grid-cols-2 gap-10 md:gap-16 items-center">
<div class="flex justify-center md:order-2">
<PreviewPhone file="04-sos-lyra.png" title="Lyra begleitet" icon="i-heroicons-chat-bubble-left-right" />
</div>
<div class="md:order-1">
<span 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-5"><UIcon name="i-heroicons-chat-bubble-left-right" />Begleitung & Coaching</span>
<h2 class="text-2xl md:text-3xl font-black text-highlighted leading-tight mb-4">Lyra: nicht nur im Notfall</h2>
<p class="text-base text-muted leading-relaxed mb-4">Lyra ist eine ruhige, psychologisch orientierte Begleiterin, rund um die Uhr. In akuten Druckmomenten deeskalierend und nicht wertend, mit klarem Verweis an menschliche, professionelle Hilfe.</p>
<p class="text-base text-muted leading-relaxed">Aber auch zwischendurch: Lyra begleitet in schweren <span class="text-highlighted">und</span> guten Momenten, gibt Anstöße, hört zu und nimmt sogar Feedback und Wünsche zu neuen Funktionen auf.</p>
</div>
</div>
<!-- 05 ATEMÜBUNG / SPIELE -->
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="grid md:grid-cols-2 gap-10 md:gap-16 items-center">
<div class="flex justify-center">
<PreviewPhone file="05-breathing.png" title="Runterkommen" icon="i-heroicons-sparkles" />
</div>
<div>
<span 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-5"><UIcon name="i-heroicons-sparkles" />Im Druckmoment</span>
<h2 class="text-2xl md:text-3xl font-black text-highlighted leading-tight mb-4">Runterkommen statt rückfallen</h2>
<p class="text-base text-muted leading-relaxed">Geführte Atemübungen und kleine, beruhigende Spiele helfen, den Drang abzufangen, wenn er am stärksten ist.</p>
</div>
</div>
</div>
<!-- COMMUNITY (3er-Reihe) -->
<section class="px-4 py-14 bg-white/[0.02] border-y border-white/5">
<div class="max-w-6xl mx-auto">
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="text-center max-w-2xl mx-auto mb-12">
<span 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-5"><UIcon name="i-heroicons-user-group" />Gemeinschaft</span>
<h2 class="text-2xl md:text-3xl font-black text-highlighted leading-tight mb-4">Eine Community, die trägt</h2>
<p class="text-base text-muted leading-relaxed">Menschen halten und stärken sich gegenseitig, ausschließlich über einen selbstgewählten Spitznamen, nie über den Klarnamen. Austausch im Feed, vertraulich per Chat, und wenn nötig auch im Gespräch.</p>
</div>
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="flex flex-wrap justify-center items-start gap-6 md:gap-10">
<div class="flex flex-col items-center gap-3">
<PreviewPhone file="07-community.png" title="Feed & Posts" icon="i-heroicons-newspaper" width="220px" />
<p class="text-sm font-semibold text-default">Feed & Posts</p>
</div>
<div class="flex flex-col items-center gap-3 md:mt-8">
<PreviewPhone file="07b-dm.png" title="Verschlüsselter Chat" icon="i-heroicons-chat-bubble-left-right" width="220px" />
<p class="text-sm font-semibold text-default">Verschlüsselter Chat</p>
</div>
<div class="flex flex-col items-center gap-3">
<PreviewPhone file="07c-calls.png" title="Anrufe (nur Spitzname)" icon="i-heroicons-phone" width="220px" />
<p class="text-sm font-semibold text-default">Anrufe, anonym</p>
</div>
</div>
<p class="text-center text-xs text-muted mt-6 max-w-xl mx-auto">Anrufe laufen nur über den Spitznamen und tauchen nicht in der Anrufliste des Telefons auf.</p>
</div>
</section>
<!-- CUSTOM DOMAINS + ADMIN-MODERATION -->
<section class="px-4 py-16">
<div class="max-w-6xl mx-auto">
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="grid md:grid-cols-2 gap-10 md:gap-16 items-center mb-16">
<div class="flex justify-center">
<PreviewPhone file="12-domains.png" title="Eigene Domains verwalten" icon="i-heroicons-globe-alt" />
</div>
<div>
<span 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-5"><UIcon name="i-heroicons-globe-alt" />Eigene Domains</span>
<h2 class="text-2xl md:text-3xl font-black text-highlighted leading-tight mb-4">Eigene Sperren, ein Anreiz für alle</h2>
<p class="text-base text-muted leading-relaxed mb-4">Du kannst eigene Glücksspiel-Domains für <span class="text-highlighted">Web und E-Mail</span> hinzufügen. Die Slots sind bewusst begrenzt, aber auffüllbar.</p>
<p class="text-base text-muted leading-relaxed">Nicht aus Geiz, sondern als Motivation: Wer eine Domain zur Veröffentlichung freigibt, macht seinen Slot wieder frei und schützt zugleich die ganze Community. Aus vielen einzelnen Funden wird so eine gemeinsame, stärkere Sperrliste.</p>
</div>
</div>
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="grid md:grid-cols-2 gap-10 md:gap-16 items-center">
<div class="flex justify-center md:order-2">
<PreviewPhone file="13-admin-approve.png" title="Admin: Domains prüfen" icon="i-heroicons-check-badge" />
</div>
<div class="md:order-1">
<span 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-5"><UIcon name="i-heroicons-check-badge" />Geprüft, nicht automatisch</span>
<h2 class="text-2xl md:text-3xl font-black text-highlighted leading-tight mb-4">Jede öffentliche Domain wird von Hand geprüft</h2>
<p class="text-base text-muted leading-relaxed mb-4">Öffentlich vorgeschlagene Domains gehen nicht automatisch live. Im Admin-Bereich gibt das Rebreak-Team jede Anfrage frei oder lehnt sie ab.</p>
<p class="text-base text-muted leading-relaxed">Das verhindert Missbrauch: Bei automatischer Freigabe könnte jemand versehentlich eine harmlose Seite (z. B. google.de) global sperren, und alle hätten ein Problem. Die Prüfung hält die gemeinsame Liste sauber und vertrauenswürdig.</p>
</div>
</div>
</div>
</section>
<!-- 08 STREAK -->
<section class="px-4 py-10">
<div class="max-w-6xl mx-auto">
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="grid md:grid-cols-2 gap-10 md:gap-16 items-center">
<div class="flex justify-center md:order-2">
<PreviewPhone file="08-streak.png" title="Spielfreie Tage" icon="i-heroicons-trophy" />
</div>
<div class="md:order-1">
<span 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-5"><UIcon name="i-heroicons-trophy" />Fortschritt</span>
<h2 class="text-2xl md:text-3xl font-black text-highlighted leading-tight mb-4">Spielfreie Tage sichtbar machen</h2>
<p class="text-base text-muted leading-relaxed">Jeder Tag zählt. Rebreak hält Fortschritte fest und macht sie zu etwas, worauf man stolz sein kann.</p>
</div>
</div>
</div>
</section>
<!-- WIE WIR SCHÜTZEN (Kern / Vertrauen) -->
<section class="px-4 py-16 bg-white/[0.02] border-t border-white/5">
<div class="max-w-6xl mx-auto">
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="grid md:grid-cols-2 gap-10 md:gap-16 items-center mb-12">
<div class="flex justify-center">
<PreviewPhone file="09-geraete.png" title="Alle Geräte" icon="i-heroicons-device-phone-mobile" />
</div>
<div>
<span 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-5"><UIcon name="i-heroicons-lock-closed" />So hält der Schutz</span>
<h2 class="text-2xl md:text-3xl font-black text-highlighted leading-tight mb-4">Aus jedem System das Maximum herausgeholt</h2>
<p class="text-base text-muted leading-relaxed">Auf jeder Plattform anders gelöst, mit demselben Ziel: eine Bindung, die im Drang-Moment hält. Wir holen aus jedem Betriebssystem heraus, was an verlässlichem Schutz möglich ist.</p>
</div>
</div>
<!-- Plattform-Karten mit Schutz-Schichten -->
<div class="grid md:grid-cols-3 gap-4 mb-8">
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="rounded-2xl border border-primary-700/50 bg-primary-950/30 p-6">
<div class="flex items-center gap-2 mb-4">
<UIcon name="i-simple-icons-apple" class="text-highlighted text-xl" />
<h3 class="font-extrabold text-highlighted">iPhone & iPad</h3>
</div>
<ul class="space-y-2.5 text-sm text-default">
<li class="flex gap-2"><UIcon name="i-heroicons-lock-closed" class="text-primary-400 shrink-0 mt-0.5" /><span>Mit Supervision (MDM): NEFilter-Schutz, der sich <span class="text-highlighted font-semibold">nicht entfernen</span> lässt.</span></li>
<li class="flex gap-2"><UIcon name="i-heroicons-shield-check" class="text-primary-400 shrink-0 mt-0.5" /><span>Ohne Supervision: 3 Schichten, Bildschirmzeit-Code (Family Controls) + VPN-Filter.</span></li>
</ul>
<p class="text-xs text-primary-300 font-semibold mt-4">Der härteste Schutz, den iOS erlaubt.</p>
</div>
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="rounded-2xl border border-white/10 bg-white/[0.03] p-6">
<div class="flex items-center gap-2 mb-4">
<UIcon name="i-simple-icons-android" class="text-primary-400 text-xl" />
<h3 class="font-extrabold text-highlighted">Android</h3>
</div>
<ul class="space-y-2.5 text-sm text-default">
<li class="flex gap-2"><UIcon name="i-heroicons-check" class="text-primary-400 shrink-0 mt-0.5" />VPN-Filter</li>
<li class="flex gap-2"><UIcon name="i-heroicons-check" class="text-primary-400 shrink-0 mt-0.5" />Bedienungshilfe (Accessibility)</li>
<li class="flex gap-2"><UIcon name="i-heroicons-check" class="text-primary-400 shrink-0 mt-0.5" />Geräte-Administrator</li>
</ul>
<p class="text-xs text-muted mt-4">Schutz auf MDM-Niveau, nicht einfach abschaltbar.</p>
</div>
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="rounded-2xl border border-white/10 bg-white/[0.03] p-6">
<div class="flex items-center gap-2 mb-4">
<UIcon name="i-heroicons-computer-desktop" class="text-primary-400 text-xl" />
<h3 class="font-extrabold text-highlighted">Mac & Windows</h3>
</div>
<ul class="space-y-2.5 text-sm text-default">
<li class="flex gap-2"><UIcon name="i-heroicons-check" class="text-primary-400 shrink-0 mt-0.5" />Rebreak Magic: systemweiter DNS-Filter</li>
<li class="flex gap-2"><UIcon name="i-heroicons-check" class="text-primary-400 shrink-0 mt-0.5" />Passwortgeschütztes Konfigurationsprofil</li>
</ul>
<p class="text-xs text-muted mt-4">Umgehung sehr schwierig.</p>
</div>
</div>
<!-- Gamban-Differenzierung (iOS) -->
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="rounded-2xl border border-primary-700/40 bg-primary-950/20 p-6 md:p-8 mb-4">
<div class="flex items-start gap-3">
<UIcon name="i-heroicons-sparkles" class="text-primary-400 text-2xl shrink-0 mt-0.5" />
<div>
<h3 class="font-extrabold text-highlighted mb-2">Der entscheidende Unterschied auf dem iPhone</h3>
<p class="text-sm text-default leading-relaxed">Übliche iOS-Blocker, auch Gamban, laufen als normale App ohne MDM, die sich im Zweifel einfach entfernen lässt. Rebreak nutzt MDM + NEFilter für <span class="text-highlighted font-semibold">nicht-entfernbaren Schutz</span>. Das ist der Kern der App und genau das, was klassische Blocker auf iOS nicht bieten.</p>
</div>
</div>
</div>
<!-- Cooldown / kein Gefängnis -->
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="rounded-2xl border border-white/10 bg-white/[0.03] p-6 md:p-8">
<div class="flex items-start gap-3">
<UIcon name="i-heroicons-heart" class="text-primary-400 text-2xl shrink-0 mt-0.5" />
<div>
<h3 class="font-extrabold text-highlighted mb-2">Schutz, kein Gefängnis</h3>
<p class="text-sm text-default leading-relaxed">Rebreak ist Selbstschutz, kein Einbahnweg. Man kommt wieder heraus, aber bewusst und mit Bedacht: über eine Abkühlphase (Cooldown) oder eine Vertrauensperson, nicht impulsiv im Drang-Moment. Genau diese kleine, gewollte Hürde schützt, ohne einzusperren.</p>
</div>
</div>
</div>
</div>
</section>
<!-- ABSCHLUSS -->
<section class="px-4 py-20">
<div v-motion :initial="fadeUp.initial" :visible-once="fadeUp.visibleOnce" class="max-w-2xl mx-auto text-center rounded-3xl border border-white/10 bg-white/[0.03] p-10">
<img src="/app-icon.png" alt="Rebreak" class="w-14 h-14 rounded-2xl mx-auto mb-6 shadow-lg" />
<h2 class="text-2xl md:text-3xl font-black text-highlighted mb-4">Mehr als ein Blocker</h2>
<p class="text-base text-muted leading-relaxed">Rebreak verbindet technischen Schutz mit echter Begleitung und einer Gemeinschaft, die sich gegenseitig trägt. Datenschutz steht an erster Stelle: sichtbar nur über einen Spitznamen, DSGVO-konform auf Servern in Deutschland.</p>
<p class="text-sm text-muted mt-6">Fragen oder Feedback? Sehr gern, ich erkläre jederzeit alles im Detail.</p>
</div>
</section>
<footer class="px-4 py-8 text-center border-t border-white/5">
<p class="text-xs text-muted">rebreak.org · Vertrauliche Vorschau</p>
</footer>
</template>
</div>
</template>

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 856 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 KiB

View File

@ -0,0 +1,43 @@
# App-Vorschau-Screenshots (für /preview)
Lege die echten Screenshots als PNG hier ab. Solange eine Datei fehlt, zeigt die
Vorschau-Seite automatisch einen beschrifteten Platzhalter (kein Code-Eingriff nötig).
**Telefon-Screens:** Hochformat (z. B. 1170×2532). **Admin-Screen:** Querformat 16:10.
## Erwartete Dateinamen
| Datei | Screen | Was zeigen |
|---|---|---|
| `01a-onboarding.png` | Onboarding 1 | Konto & Spitzname |
| `01b-onboarding.png` | Onboarding 2 | Schutz einrichten |
| `01c-onboarding.png` | Onboarding 3 | Fertig / Los geht's |
| `02-blocker.png` | Blocker aktiv | Status „aktiv", Domain-Zähler |
| `03-blocked.png` | Gesperrte Seite | Block-Screen bei Casino-Aufruf |
| `04-sos-lyra.png` | Lyra | Chat mit Lyra (Coaching/Krise) |
| `05-breathing.png` | Atemübung/Spiel | Atemübung oder Mini-Spiel |
| `06-mail-schutz.png` | Mail-Schutz | Mail-Schutz-Übersicht / entfernte Mails |
| `06b-mail-connect.png` | Konto verbinden | Provider-Auswahl / Konto-Anbindung |
| `07-community.png` | Feed | Community-Feed / Posts (nur Spitznamen) |
| `07b-dm.png` | Chat | Verschlüsselter DM-Chat |
| `07c-calls.png` | Anrufe | Anruf-Screen (Spitzname) |
| `08-streak.png` | Streak | Spielfreie Tage / Statistik |
| `09-geraete.png` | Geräte | Geräte-Übersicht (iPhone/Android/Mac/Windows) |
| `12-domains.png` | Eigene Domains | Custom-Domain-Verwaltung (Web/E-Mail) |
| `13-admin-approve.png` | **Admin** (Querformat) | Admin-App: Domain-Anfragen approve/reject |
Dateinamen exakt so benennen, dann erscheinen die Bilder automatisch.
Texte/Reihenfolge: `apps/marketing/app/pages/preview.vue`.
## Maestro-Pipeline
`apps/rebreak-native/.maestro/screens/capture-marketing.sh` erzeugt aktuell die
Screens **0109** automatisch. NEU hinzugekommen und noch ohne Auto-Flow:
`06b-mail-connect`, `07b-dm`, `07c-calls`, `12-domains` (App) und `13-admin-approve`
(Admin-App, separat). Diese ggf. manuell schießen oder die Flows erweitern (ahmed).
## Passwort
`preview.vue``PREVIEW_PASSWORD` (aktuell `rebreak-fags`). Vor dem Teilen ändern.
## Logo
Nutzt `apps/marketing/public/app-icon.png` (Kopie von `apps/rebreak-native/assets/icon.png`,
dem App-Icon für iOS/Android/Magic). Bei Logo-Update einfach diese Datei ersetzen.