style: apply frosted glass design to all components\n\nUpdate bottom nav, feed, search, log, diary, lists, profile, movie detail, and auth pages.
This commit is contained in:
parent
6dbc116704
commit
e42ff51f31
@ -112,7 +112,7 @@ function LogPageContent() {
|
|||||||
if (step === "search") {
|
if (step === "search") {
|
||||||
return (
|
return (
|
||||||
<main className="mx-auto max-w-lg">
|
<main className="mx-auto max-w-lg">
|
||||||
<header className="sticky top-0 z-40 border-b border-border bg-background/95 px-4 py-3 backdrop-blur-md">
|
<header className="sticky top-0 z-40 glass-header px-4 py-3">
|
||||||
<h1 className="mb-3 font-heading text-lg font-bold text-foreground">
|
<h1 className="mb-3 font-heading text-lg font-bold text-foreground">
|
||||||
Film loggen
|
Film loggen
|
||||||
</h1>
|
</h1>
|
||||||
@ -123,7 +123,7 @@ function LogPageContent() {
|
|||||||
value={query}
|
value={query}
|
||||||
onChange={(e) => setQuery(e.target.value)}
|
onChange={(e) => setQuery(e.target.value)}
|
||||||
placeholder="Welchen Film hast du gesehen?"
|
placeholder="Welchen Film hast du gesehen?"
|
||||||
className="h-11 w-full rounded-lg border border-border bg-secondary pl-10 pr-4 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
className="glass-input h-11 w-full pl-10 pr-4 text-sm"
|
||||||
autoFocus
|
autoFocus
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -147,7 +147,7 @@ function LogPageContent() {
|
|||||||
<button
|
<button
|
||||||
key={movie.id}
|
key={movie.id}
|
||||||
onClick={() => selectMovie(movie)}
|
onClick={() => selectMovie(movie)}
|
||||||
className="flex items-center gap-3 rounded-xl border border-border bg-card p-3 text-left transition-colors hover:bg-secondary"
|
className="glass-card flex items-center gap-3 p-3 text-left transition-all hover:bg-white/[0.08] active:scale-[0.98]"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<div className="relative h-16 w-11 shrink-0 overflow-hidden rounded bg-secondary">
|
<div className="relative h-16 w-11 shrink-0 overflow-hidden rounded bg-secondary">
|
||||||
@ -184,7 +184,7 @@ function LogPageContent() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="mx-auto max-w-lg">
|
<main className="mx-auto max-w-lg">
|
||||||
<header className="sticky top-0 z-40 flex items-center justify-between border-b border-border bg-background/95 px-4 py-3 backdrop-blur-md">
|
<header className="sticky top-0 z-40 flex items-center justify-between glass-header px-4 py-3">
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setStep("search")
|
setStep("search")
|
||||||
@ -252,7 +252,7 @@ function LogPageContent() {
|
|||||||
type="date"
|
type="date"
|
||||||
value={watchedAt}
|
value={watchedAt}
|
||||||
onChange={(e) => setWatchedAt(e.target.value)}
|
onChange={(e) => setWatchedAt(e.target.value)}
|
||||||
className="h-11 w-full rounded-lg border border-border bg-secondary px-4 text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
className="glass-input h-11 w-full px-4 text-sm"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -270,14 +270,14 @@ function LogPageContent() {
|
|||||||
onChange={(e) => setReview(e.target.value)}
|
onChange={(e) => setReview(e.target.value)}
|
||||||
placeholder="Was denkst du ueber den Film?"
|
placeholder="Was denkst du ueber den Film?"
|
||||||
rows={4}
|
rows={4}
|
||||||
className="w-full rounded-lg border border-border bg-secondary px-4 py-3 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
className="glass-input w-full px-4 py-3 text-sm"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={saving}
|
disabled={saving}
|
||||||
className="mt-6 flex h-12 w-full items-center justify-center gap-2 rounded-lg bg-primary font-semibold text-primary-foreground transition-colors hover:bg-primary/90 disabled:opacity-50"
|
className="mt-6 flex h-12 w-full items-center justify-center gap-2 rounded-xl bg-primary font-semibold text-primary-foreground shadow-lg shadow-primary/25 transition-all hover:bg-primary/90 active:scale-[0.98] disabled:opacity-50"
|
||||||
>
|
>
|
||||||
{saving ? (
|
{saving ? (
|
||||||
<Loader2 className="h-5 w-5 animate-spin" />
|
<Loader2 className="h-5 w-5 animate-spin" />
|
||||||
|
|||||||
@ -45,7 +45,7 @@ export default function SearchPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="mx-auto max-w-lg">
|
<main className="mx-auto max-w-lg">
|
||||||
<header className="sticky top-0 z-40 border-b border-border bg-background/95 px-4 py-3 backdrop-blur-md">
|
<header className="sticky top-0 z-40 glass-header px-4 py-3">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<Search className="absolute left-3 top-1/2 h-5 w-5 -translate-y-1/2 text-muted-foreground" />
|
<Search className="absolute left-3 top-1/2 h-5 w-5 -translate-y-1/2 text-muted-foreground" />
|
||||||
<input
|
<input
|
||||||
@ -53,7 +53,7 @@ export default function SearchPage() {
|
|||||||
value={query}
|
value={query}
|
||||||
onChange={(e) => setQuery(e.target.value)}
|
onChange={(e) => setQuery(e.target.value)}
|
||||||
placeholder="Filme suchen..."
|
placeholder="Filme suchen..."
|
||||||
className="h-11 w-full rounded-lg border border-border bg-secondary pl-10 pr-4 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
className="glass-input h-11 w-full pl-10 pr-4 text-sm"
|
||||||
autoFocus
|
autoFocus
|
||||||
/>
|
/>
|
||||||
{loading && (
|
{loading && (
|
||||||
@ -95,7 +95,7 @@ function SearchResultCard({ movie }: { movie: TMDBMovie }) {
|
|||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
href={`/movie/${movie.id}`}
|
href={`/movie/${movie.id}`}
|
||||||
className="flex gap-3 rounded-xl border border-border bg-card p-3 transition-colors hover:bg-secondary"
|
className="glass-card flex gap-3 p-3 transition-all hover:bg-white/[0.08] active:scale-[0.98]"
|
||||||
>
|
>
|
||||||
<div className="relative h-24 w-16 shrink-0 overflow-hidden rounded-lg bg-secondary">
|
<div className="relative h-24 w-16 shrink-0 overflow-hidden rounded-lg bg-secondary">
|
||||||
{url ? (
|
{url ? (
|
||||||
|
|||||||
@ -10,31 +10,33 @@
|
|||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
:root {
|
:root {
|
||||||
--background: 220 20% 7%;
|
--background: 228 18% 7%;
|
||||||
--foreground: 210 20% 95%;
|
--foreground: 210 20% 95%;
|
||||||
--card: 220 18% 10%;
|
--card: 225 15% 12%;
|
||||||
--card-foreground: 210 20% 95%;
|
--card-foreground: 210 20% 95%;
|
||||||
--popover: 220 18% 10%;
|
--popover: 225 15% 12%;
|
||||||
--popover-foreground: 210 20% 95%;
|
--popover-foreground: 210 20% 95%;
|
||||||
--primary: 24 100% 55%;
|
--primary: 24 95% 53%;
|
||||||
--primary-foreground: 220 20% 7%;
|
--primary-foreground: 0 0% 100%;
|
||||||
--secondary: 220 15% 16%;
|
--secondary: 225 12% 15%;
|
||||||
--secondary-foreground: 210 20% 90%;
|
--secondary-foreground: 210 20% 90%;
|
||||||
--muted: 220 15% 14%;
|
--muted: 225 12% 15%;
|
||||||
--muted-foreground: 215 15% 55%;
|
--muted-foreground: 215 12% 50%;
|
||||||
--accent: 24 80% 50%;
|
--accent: 24 80% 50%;
|
||||||
--accent-foreground: 220 20% 7%;
|
--accent-foreground: 0 0% 100%;
|
||||||
--destructive: 0 72% 51%;
|
--destructive: 0 72% 51%;
|
||||||
--destructive-foreground: 210 20% 95%;
|
--destructive-foreground: 210 20% 95%;
|
||||||
--border: 220 15% 18%;
|
--border: 220 10% 20%;
|
||||||
--input: 220 15% 18%;
|
--input: 220 10% 20%;
|
||||||
--ring: 24 100% 55%;
|
--ring: 24 95% 53%;
|
||||||
--chart-1: 24 100% 55%;
|
--chart-1: 24 95% 53%;
|
||||||
--chart-2: 173 58% 39%;
|
--chart-2: 173 58% 39%;
|
||||||
--chart-3: 197 37% 24%;
|
--chart-3: 197 37% 24%;
|
||||||
--chart-4: 43 74% 66%;
|
--chart-4: 43 74% 66%;
|
||||||
--chart-5: 27 87% 67%;
|
--chart-5: 27 87% 67%;
|
||||||
--radius: 0.75rem;
|
--radius: 1rem;
|
||||||
|
--glass: 225 15% 14%;
|
||||||
|
--glass-border: 220 15% 24%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +49,37 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Apple Frosted Glass utilities */
|
||||||
|
@layer components {
|
||||||
|
.glass {
|
||||||
|
@apply border-white/[0.08] bg-white/[0.04] backdrop-blur-2xl;
|
||||||
|
}
|
||||||
|
.glass-strong {
|
||||||
|
@apply border-white/[0.12] bg-white/[0.07] backdrop-blur-3xl;
|
||||||
|
}
|
||||||
|
.glass-card {
|
||||||
|
@apply rounded-2xl border border-white/[0.08] bg-white/[0.05] backdrop-blur-2xl shadow-lg shadow-black/10;
|
||||||
|
}
|
||||||
|
.glass-input {
|
||||||
|
@apply rounded-xl border border-white/[0.1] bg-white/[0.06] backdrop-blur-xl text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary/30 transition-all;
|
||||||
|
}
|
||||||
|
.glass-button {
|
||||||
|
@apply rounded-xl border border-white/[0.1] bg-white/[0.06] backdrop-blur-xl text-foreground transition-all hover:bg-white/[0.1] active:scale-[0.98];
|
||||||
|
}
|
||||||
|
.glass-nav {
|
||||||
|
@apply border-t border-white/[0.08] bg-black/40 backdrop-blur-3xl supports-[backdrop-filter]:bg-black/30;
|
||||||
|
}
|
||||||
|
.glass-header {
|
||||||
|
@apply border-b border-white/[0.06] bg-background/60 backdrop-blur-2xl supports-[backdrop-filter]:bg-background/40;
|
||||||
|
}
|
||||||
|
.glass-tag {
|
||||||
|
@apply rounded-full border border-white/[0.1] bg-white/[0.06] px-2.5 py-0.5 text-[10px] font-medium backdrop-blur-sm;
|
||||||
|
}
|
||||||
|
.glass-avatar {
|
||||||
|
@apply rounded-full border border-white/[0.1] bg-white/[0.08] backdrop-blur-xl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Smooth scrolling */
|
/* Smooth scrolling */
|
||||||
html {
|
html {
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
@ -68,3 +101,14 @@ html {
|
|||||||
padding-bottom: max(1rem, env(safe-area-inset-bottom));
|
padding-bottom: max(1rem, env(safe-area-inset-bottom));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Subtle noise texture for depth */
|
||||||
|
body::before {
|
||||||
|
content: "";
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: -1;
|
||||||
|
opacity: 0.015;
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export function BottomNav() {
|
|||||||
const pathname = usePathname()
|
const pathname = usePathname()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav className="fixed bottom-0 left-0 right-0 z-50 border-t border-border bg-background/95 backdrop-blur-md safe-bottom">
|
<nav className="fixed bottom-0 left-0 right-0 z-50 glass-nav safe-bottom">
|
||||||
<div className="mx-auto flex max-w-lg items-center justify-around py-2">
|
<div className="mx-auto flex max-w-lg items-center justify-around py-2">
|
||||||
{navItems.map((item) => {
|
{navItems.map((item) => {
|
||||||
const isActive =
|
const isActive =
|
||||||
|
|||||||
@ -42,7 +42,7 @@ export function FeedContent({ profile, entries, trending }: FeedContentProps) {
|
|||||||
return (
|
return (
|
||||||
<main className="mx-auto max-w-lg">
|
<main className="mx-auto max-w-lg">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<header className="sticky top-0 z-40 flex items-center justify-between border-b border-border bg-background/95 px-4 py-3 backdrop-blur-md">
|
<header className="sticky top-0 z-40 flex items-center justify-between glass-header px-4 py-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Film className="h-6 w-6 text-primary" />
|
<Film className="h-6 w-6 text-primary" />
|
||||||
<h1 className="font-heading text-xl font-bold text-foreground">
|
<h1 className="font-heading text-xl font-bold text-foreground">
|
||||||
@ -81,14 +81,14 @@ export function FeedContent({ profile, entries, trending }: FeedContentProps) {
|
|||||||
Familien-Aktivität
|
Familien-Aktivität
|
||||||
</h2>
|
</h2>
|
||||||
{entries.length === 0 ? (
|
{entries.length === 0 ? (
|
||||||
<div className="flex flex-col items-center gap-3 rounded-xl border border-border bg-card px-6 py-12 text-center">
|
<div className="glass-card flex flex-col items-center gap-3 px-6 py-12 text-center">
|
||||||
<Clock className="h-10 w-10 text-muted-foreground" />
|
<Clock className="h-10 w-10 text-muted-foreground" />
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
Noch keine Einträge. Logge deinen ersten Film!
|
Noch keine Einträge. Logge deinen ersten Film!
|
||||||
</p>
|
</p>
|
||||||
<Link
|
<Link
|
||||||
href="/log"
|
href="/log"
|
||||||
className="mt-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground"
|
className="mt-2 rounded-xl bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground shadow-lg shadow-primary/20 active:scale-[0.98] transition-transform"
|
||||||
>
|
>
|
||||||
Film loggen
|
Film loggen
|
||||||
</Link>
|
</Link>
|
||||||
@ -143,7 +143,7 @@ function FeedCard({ entry }: { entry: FeedEntry }) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<article className="overflow-hidden rounded-xl border border-border bg-card">
|
<article className="glass-card overflow-hidden">
|
||||||
<div className="flex gap-3 p-4">
|
<div className="flex gap-3 p-4">
|
||||||
{/* Poster */}
|
{/* Poster */}
|
||||||
<Link href={`/movie/${entry.tmdb_id}`} className="shrink-0">
|
<Link href={`/movie/${entry.tmdb_id}`} className="shrink-0">
|
||||||
@ -167,7 +167,7 @@ function FeedCard({ entry }: { entry: FeedEntry }) {
|
|||||||
{/* Content */}
|
{/* Content */}
|
||||||
<div className="flex min-w-0 flex-1 flex-col gap-1.5">
|
<div className="flex min-w-0 flex-1 flex-col gap-1.5">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-primary/20 text-[10px] font-bold text-primary">
|
<div className="glass-avatar flex h-6 w-6 items-center justify-center text-[10px] font-bold text-primary">
|
||||||
{entry.profiles?.display_name?.charAt(0).toUpperCase() || "?"}
|
{entry.profiles?.display_name?.charAt(0).toUpperCase() || "?"}
|
||||||
</div>
|
</div>
|
||||||
<span className="text-xs font-medium text-foreground">
|
<span className="text-xs font-medium text-foreground">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user