feat: Musik global, Dennis-Teil auf eigene Seite, Mobile-Autoplay

- MusicPlayer ins Layout verschoben (läuft auf allen Seiten)
- Mobile-Autoplay: Desktop startet stumm + fade-in bei Scroll,
  Mobile wartet auf ersten Touch und startet dann mit Fade-In
- Dennis-Perspektive auf eigene Seite /meine-oma ausgelagert,
  dezenter Link "Von Dennis" am Ende der Tribute-Sektion
- "Berge von Essen" entfernt
- "Jacky und Niklas" → "ihre Enkelin" / "Meine Schwester"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
denshooter
2026-02-16 03:57:48 +01:00
parent 4d56d4904a
commit 6363d1327b
6 changed files with 253 additions and 170 deletions
+7 -1
View File
@@ -1,5 +1,6 @@
import type { Metadata } from 'next'
import { Cormorant_Garamond, Lora } from 'next/font/google'
import GlobalMusicPlayer from '@/components/GlobalMusicPlayer'
import './globals.css'
const cormorant = Cormorant_Garamond({
@@ -18,6 +19,8 @@ const lora = Lora({
display: 'swap',
})
export const dynamic = 'force-dynamic'
export const metadata: Metadata = {
title: 'In Erinnerung an Maria Malejka',
description:
@@ -36,7 +39,10 @@ export default function RootLayout({
}) {
return (
<html lang="de" className={`${cormorant.variable} ${lora.variable}`}>
<body className="font-lora antialiased">{children}</body>
<body className="font-lora antialiased">
{children}
<GlobalMusicPlayer />
</body>
</html>
)
}
+147
View File
@@ -0,0 +1,147 @@
'use client'
import { motion } from 'framer-motion'
import { ArrowLeft } from 'lucide-react'
const fade = {
initial: { opacity: 0, y: 20 },
whileInView: { opacity: 1, y: 0 },
viewport: { once: true },
transition: { duration: 0.8 },
}
export default function MeineOmaPage() {
return (
<main className="min-h-screen bg-cream">
<div className="max-w-2xl mx-auto px-6 py-20 sm:py-28">
<a
href="/"
className="inline-flex items-center gap-1.5 text-warm-brown-light/50 hover:text-warm-gold text-sm font-lora transition-colors mb-16"
>
<ArrowLeft size={14} />
Zurück
</a>
<motion.div {...fade} className="text-center mb-16">
<p className="text-warm-gold/50 text-xs tracking-[0.5em] uppercase font-lora mb-4">
Von Dennis
</p>
<h1 className="font-cormorant italic text-5xl sm:text-6xl text-warm-brown mb-4">
Meine Oma
</h1>
<div className="flex items-center justify-center gap-4">
<div className="h-px w-16 bg-warm-gold/30" />
<span className="text-warm-gold/40 text-lg">&#10045;</span>
<div className="h-px w-16 bg-warm-gold/30" />
</div>
</motion.div>
<div className="space-y-8 font-lora text-warm-brown/80 text-base sm:text-lg leading-relaxed">
<motion.p {...fade}>
Ich kam aus der Schule und das Essen stand schon da. Jedes Mal.
Rahmsauce. Ich weiß nicht, wie oft ich die gegessen habe, aber
es war nie genug. Ich würde alles dafür geben, noch einmal an
ihrem Küchentisch zu sitzen.
</motion.p>
<motion.p {...fade}>
Oma roch nach Oma. Ich weiß nicht, wie ich das anders beschreiben
soll. Nicht nach Parfum. Nicht nach irgendwas, das man kaufen kann.
Einfach nach ihr. Wenn ich an sie denke, ist das Erste, was
kommt, dieses Gefühl. Diese Wärme. Der Geruch von ihrem Haus.
</motion.p>
<motion.p {...fade}>
Bei ihr war es immer heiß. Immer. Der Kamin lief, die Heizung
lief, man hat geschwitzt und es war trotzdem schön. An Weihnachten
war der Karpfen in der Badewanne und die Geschenke im Wohnzimmer.
Aber die Tür blieb zu. Erst essen, dann Geschenke. Das war Gesetz.
Und wir haben uns jedes Mal gefreut, als wären wir fünf.
</motion.p>
<motion.p {...fade}>
Wenn Pico bei ihr war, hab ich nicht mehr existiert. Sie hat mit
ihm geredet, ihn gefüttert, ihn verwöhnt. Ich saß daneben und
war Luft. Aber das war okay. Weil sie so glücklich war dabei.
</motion.p>
<motion.p {...fade}>
Pico ist letztes Jahr gestorben. Und jetzt Oma. Ich stelle mir
vor, wie sie irgendwo sitzt und er neben ihr liegt und sie ihm
wieder irgendwas erzählt, was er nicht versteht. Und er hört
trotzdem zu.
</motion.p>
<motion.p {...fade}>
Sie war stur. Richtig stur. Deswegen hatte sie auch den
Oberschenkelhalsbruch. Weil sie alles alleine machen wollte.
Weil sie sich nichts sagen lassen hat. Man konnte sich aufregen.
Aber im Nachhinein war das auch das, was sie so stark gemacht hat.
</motion.p>
<motion.div
{...fade}
className="border-l-2 border-warm-gold/30 pl-6 py-2 my-12"
>
<p className="font-cormorant italic text-2xl sm:text-3xl text-warm-brown/70 leading-snug">
Ich habe es dir viel zu selten gesagt, Oma.
<br />
Aber ich habe dich geliebt. Sehr.
</p>
</motion.div>
<motion.p {...fade}>
Das letzte Mal hab ich sie im Krankenhaus besucht. In der
Geriatrie. Sie lief schon wieder, es ging ihr gut. Sie hat
im Aufenthaltsraum Blumenvasen gesehen und meinte, die könnte
man ja mitnehmen. Ich hab gelacht. So war sie halt.
</motion.p>
<motion.p {...fade}>
Ihr Zimmer war gegenüber von dem Zimmer, in dem meine Mutter
wochenlang gelegen hatte, als sie mit mir schwanger war. Mama
durfte sich kaum bewegen damals. Im selben Flur, in dem ich auf
die Welt kam, ist Oma gegangen. Das lässt mich nicht los.
</motion.p>
<motion.p {...fade}>
Am 10. Februar, um 13:13 Uhr, schrieb mir meine Schwester
auf Telegram: <span className="italic text-warm-brown">Sie
möchten die Reanimation abbrechen."</span>
</motion.p>
<motion.p {...fade}>
Meine Schwester ist schwanger. Sie hat den Ultraschall mit in
den Sarg gelegt. Ein Kind, das Oma nie treffen wird, aber das
in ihrem Haus aufwachsen wird. In den Wänden, die nach Oma
riechen. In der Küche, in der die Rahmsauce stand.
</motion.p>
<motion.p {...fade}>
Diese Seite ist für dich. Damit ich nicht vergesse. Damit
niemand vergisst.
</motion.p>
</div>
{/* Footer */}
<motion.div
{...fade}
className="mt-20 text-center"
>
<div className="flex items-center justify-center gap-4 mb-8">
<div className="h-px w-12 bg-warm-gold/20" />
<span className="text-warm-gold/30">&#10045;</span>
<div className="h-px w-12 bg-warm-gold/20" />
</div>
<a
href="/"
className="font-lora text-warm-brown-light/40 hover:text-warm-gold text-sm transition-colors"
>
Zurück zur Gedenkseite
</a>
</motion.div>
</div>
</main>
)
}
+1 -8
View File
@@ -5,7 +5,6 @@ import PhotoSlideshow from '@/components/PhotoSlideshow'
import PhotoGallery from '@/components/PhotoGallery'
import MemorySection from '@/components/MemorySection'
import WriteSection from '@/components/WriteSection'
import MusicPlayer from '@/components/MusicPlayer'
import VideoGallery from '@/components/VideoGallery'
import TributeSection from '@/components/TributeSection'
@@ -25,10 +24,7 @@ export default async function HomePage() {
const videos = plain<MediaItem>(
db.prepare("SELECT * FROM media WHERE type = 'video' ORDER BY sort_order, created_at").all()
)
const music = plain<MediaItem>(
db.prepare("SELECT * FROM media WHERE type = 'music' ORDER BY sort_order, created_at").all()
)
const memories = plain<Memory>(
const memories = plain<Memory>(
db.prepare('SELECT * FROM memories ORDER BY created_at DESC').all()
)
@@ -93,9 +89,6 @@ export default async function HomePage() {
{/* Videos */}
<VideoGallery videos={videos} />
{/* Floating music player */}
<MusicPlayer tracks={music} />
{/* Footer */}
<footer className="py-12 text-center border-t border-warm-border bg-amber-50/30">
<div className="max-w-lg mx-auto px-4">