feat: color-code navigation buttons

Assign red to Movies, blue to Shows, and green to Music.

#VERCEL_SKIP

Co-authored-by: Jeff Emmett <46964190+Jeff-Emmett@users.noreply.github.com>
This commit is contained in:
v0 2025-12-02 20:18:11 +00:00
parent 6ba17a7828
commit f3a5a61aaf
4 changed files with 125 additions and 79 deletions

View File

@ -79,6 +79,8 @@
--font-mono: "Geist Mono", "Geist Mono Fallback"; --font-mono: "Geist Mono", "Geist Mono Fallback";
/* Added Fredoka bubble font for logo */ /* Added Fredoka bubble font for logo */
--font-fredoka: var(--font-fredoka); --font-fredoka: var(--font-fredoka);
/* Added Permanent Marker for street art headlines */
--font-marker: var(--font-marker);
--color-background: var(--background); --color-background: var(--background);
--color-foreground: var(--foreground); --color-foreground: var(--foreground);
--color-card: var(--card); --color-card: var(--card);

View File

@ -1,6 +1,6 @@
import type React from "react" import type React from "react"
import type { Metadata } from "next" import type { Metadata } from "next"
import { Geist, Geist_Mono, Fredoka } from "next/font/google" import { Geist, Geist_Mono, Fredoka, Permanent_Marker } from "next/font/google"
import { Analytics } from "@vercel/analytics/next" import { Analytics } from "@vercel/analytics/next"
import "./globals.css" import "./globals.css"
@ -11,6 +11,11 @@ const _fredoka = Fredoka({
weight: ["400", "700"], weight: ["400", "700"],
variable: "--font-fredoka", variable: "--font-fredoka",
}) })
const _permanentMarker = Permanent_Marker({
subsets: ["latin"],
weight: ["400"],
variable: "--font-marker",
})
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Jefflix - Seize the Streams of Production", title: "Jefflix - Seize the Streams of Production",
@ -41,7 +46,7 @@ export default function RootLayout({
children: React.ReactNode children: React.ReactNode
}>) { }>) {
return ( return (
<html lang="en" className={_fredoka.variable}> <html lang="en" className={`${_fredoka.variable} ${_permanentMarker.variable}`}>
<body className={`font-sans antialiased`}> <body className={`font-sans antialiased`}>
{children} {children}
<Analytics /> <Analytics />

View File

@ -1,6 +1,6 @@
import { Button } from "@/components/ui/button" import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge" import { Badge } from "@/components/ui/badge"
import { Film, Music, Server, Users, Heart, Rocket } from "lucide-react" import { Film, Music, Server, Users, Heart, Rocket, Tv } from "lucide-react"
import Image from "next/image" import Image from "next/image"
import { JefflixLogo } from "@/components/jefflix-logo" import { JefflixLogo } from "@/components/jefflix-logo"
@ -9,7 +9,16 @@ export default function JefflixPage() {
<div className="min-h-screen bg-background"> <div className="min-h-screen bg-background">
{/* Hero Section */} {/* Hero Section */}
<section className="relative overflow-hidden"> <section className="relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-br from-yellow-50 via-background to-green-50" /> <div className="absolute inset-0">
<Image
src="/images/jeff-tea.jpg"
alt="Building communities in nature"
fill
className="object-cover opacity-20"
priority
/>
</div>
<div className="absolute inset-0 bg-gradient-to-br from-yellow-50/80 via-background/90 to-green-50/80" />
<div <div
className="absolute inset-0 opacity-30" className="absolute inset-0 opacity-30"
style={{ style={{
@ -24,11 +33,8 @@ export default function JefflixPage() {
<div className="mb-4"> <div className="mb-4">
<JefflixLogo /> <JefflixLogo />
</div> </div>
<Badge className="bg-green-600 text-white text-lg px-4 py-2 font-bold border-2 border-green-800 shadow-md">
An Experiment in Digital Solidarity
</Badge>
<h1 <h1
className="text-5xl font-black text-balance leading-tight md:text-6xl" className="text-3xl font-black text-balance leading-tight md:text-4xl font-marker"
style={{ style={{
textShadow: "3px 3px 0px rgba(0,0,0,0.1)", textShadow: "3px 3px 0px rgba(0,0,0,0.1)",
color: "hsl(var(--foreground))", color: "hsl(var(--foreground))",
@ -45,60 +51,41 @@ export default function JefflixPage() {
</div> </div>
</div> </div>
{/* Comic Panel Grid with Photos */}
<div className="grid md:grid-cols-3 gap-6 mb-12">
{/* Panel 1 */}
<div className="bg-card border-2 border-border rounded-lg shadow-md hover:shadow-lg transition-shadow overflow-hidden">
<div className="relative aspect-square">
<Image src="/images/jeff-tea.jpg" alt="Having tea with nature" fill className="object-cover" />
</div>
<div className="p-4 space-y-2">
<p className="font-semibold text-sm text-muted-foreground">Build communities, not customer bases</p>
</div>
</div>
{/* Panel 2 */}
<div className="bg-card border-2 border-border rounded-lg shadow-md hover:shadow-lg transition-shadow overflow-hidden">
<div className="relative aspect-square">
<Image
src="/images/jeff-blueberries.jpg"
alt="Seeing through the matrix"
fill
className="object-cover"
/>
</div>
<div className="p-4 space-y-2">
<p className="font-semibold text-sm text-muted-foreground">See through artificial scarcity</p>
</div>
</div>
{/* Panel 3 */}
<div className="bg-card border-2 border-border rounded-lg shadow-md hover:shadow-lg transition-shadow overflow-hidden">
<div className="relative aspect-square">
<Image src="/images/jeff-donkey.jpg" alt="Building bridges" fill className="object-cover" />
</div>
<div className="p-4 space-y-2">
<p className="font-semibold text-sm text-muted-foreground">Infrastructure scales with solidarity</p>
</div>
</div>
</div>
{/* Action Buttons */} {/* Action Buttons */}
<div className="text-center space-y-4"> <div className="text-center space-y-4">
<p className="text-lg font-medium text-muted-foreground"> <p className="text-lg font-medium text-muted-foreground">Try it out on Jefflix (or build your own!)</p>
Need a place to start? Try these servers (or build your own):
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center"> <div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
<Button asChild size="lg" className="text-lg px-8 py-6 font-bold" variant="default"> <Button
asChild
size="lg"
className="text-lg px-8 py-6 font-bold bg-red-600 hover:bg-red-700 text-white"
variant="default"
>
<a href="https://movies.jeffemmett.com"> <a href="https://movies.jeffemmett.com">
<Film className="mr-2 h-5 w-5" /> <Film className="mr-2 h-5 w-5" />
Movies Server Movies
</a> </a>
</Button> </Button>
<Button asChild size="lg" className="text-lg px-8 py-6 font-bold bg-transparent" variant="outline"> <Button
asChild
size="lg"
className="text-lg px-8 py-6 font-bold bg-blue-600 hover:bg-blue-700 text-white"
variant="default"
>
<a href="https://movies.jeffemmett.com">
<Tv className="mr-2 h-5 w-5" />
Shows
</a>
</Button>
<Button
asChild
size="lg"
className="text-lg px-8 py-6 font-bold bg-green-600 hover:bg-green-700 text-white"
variant="outline"
>
<a href="https://music.jeffemmett.com"> <a href="https://music.jeffemmett.com">
<Music className="mr-2 h-5 w-5" /> <Music className="mr-2 h-5 w-5" />
Music Server Music
</a> </a>
</Button> </Button>
</div> </div>
@ -112,7 +99,7 @@ export default function JefflixPage() {
<div className="container mx-auto px-4 py-16 md:py-24"> <div className="container mx-auto px-4 py-16 md:py-24">
<div className="max-w-5xl mx-auto"> <div className="max-w-5xl mx-auto">
<div className="text-center mb-12"> <div className="text-center mb-12">
<h2 className="text-4xl md:text-5xl font-black text-balance mb-4">Why Self-Host?</h2> <h2 className="text-3xl md:text-3xl font-black text-balance mb-4 font-marker">Why Self-Host?</h2>
<p className="text-xl text-muted-foreground max-w-2xl mx-auto leading-relaxed"> <p className="text-xl text-muted-foreground max-w-2xl mx-auto leading-relaxed">
Technology promised abundance, but corporations chose artificial scarcity. Let's build the alternative. Technology promised abundance, but corporations chose artificial scarcity. Let's build the alternative.
</p> </p>
@ -155,6 +142,12 @@ export default function JefflixPage() {
</div> </div>
</div> </div>
</div> </div>
<div className="flex justify-center mt-12">
<Badge className="bg-green-600 text-white text-lg px-4 py-2 font-bold border-2 border-green-800 shadow-md">
An Experiment in Digital Solidarity
</Badge>
</div>
</div> </div>
</div> </div>
</section> </section>
@ -164,10 +157,7 @@ export default function JefflixPage() {
<div className="container mx-auto px-4"> <div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto space-y-12"> <div className="max-w-4xl mx-auto space-y-12">
<div className="text-center space-y-4"> <div className="text-center space-y-4">
<h2 className="text-4xl md:text-5xl font-black text-balance">Beyond Digital Feudalism</h2> <h2 className="text-3xl md:text-3xl font-black text-balance font-marker">Beyond Digital Feudalism</h2>
<div className="flex justify-center py-4">
<JefflixLogo />
</div>
<p className="text-xl text-muted-foreground leading-relaxed"> <p className="text-xl text-muted-foreground leading-relaxed">
Streaming platforms aren't just bad business—they're architecture for extraction. Streaming platforms aren't just bad business—they're architecture for extraction.
</p> </p>
@ -175,7 +165,7 @@ export default function JefflixPage() {
<div className="space-y-6"> <div className="space-y-6">
<div className="bg-card p-8 rounded-lg border-l-4 border-l-red-500 shadow-sm"> <div className="bg-card p-8 rounded-lg border-l-4 border-l-red-500 shadow-sm">
<h3 className="text-2xl font-bold mb-3">They Don't Own What They Sell</h3> <h3 className="text-xl font-bold mb-3 font-marker">They Don't Own What They Sell</h3>
<p className="text-muted-foreground text-lg leading-relaxed"> <p className="text-muted-foreground text-lg leading-relaxed">
Content rotates based on licensing deals, not user needs. You're not buying access—you're renting Content rotates based on licensing deals, not user needs. You're not buying access—you're renting
temporary gates to shifting catalogs. temporary gates to shifting catalogs.
@ -183,7 +173,7 @@ export default function JefflixPage() {
</div> </div>
<div className="bg-card p-8 rounded-lg border-l-4 border-l-blue-500 shadow-sm"> <div className="bg-card p-8 rounded-lg border-l-4 border-l-blue-500 shadow-sm">
<h3 className="text-2xl font-bold mb-3">Subscription Fatigue is Designed</h3> <h3 className="text-xl font-bold mb-3 font-marker">Subscription Fatigue is Designed</h3>
<p className="text-muted-foreground text-lg leading-relaxed"> <p className="text-muted-foreground text-lg leading-relaxed">
The "streaming wars" recreated cable monopolies with extra steps. Fragmentation isn't a bug—it's the The "streaming wars" recreated cable monopolies with extra steps. Fragmentation isn't a bug—it's the
business model. business model.
@ -191,13 +181,30 @@ export default function JefflixPage() {
</div> </div>
<div className="bg-card p-8 rounded-lg border-l-4 border-l-green-500 shadow-sm"> <div className="bg-card p-8 rounded-lg border-l-4 border-l-green-500 shadow-sm">
<h3 className="text-2xl font-bold mb-3">Technology Enables Abundance</h3> <h3 className="text-xl font-bold mb-3 font-marker">Technology Enables Abundance</h3>
<p className="text-muted-foreground text-lg leading-relaxed"> <p className="text-muted-foreground text-lg leading-relaxed">
Digital goods cost nothing to copy, but everything to gate. Self-hosting is how we build Digital goods cost nothing to copy, but everything to gate. Self-hosting is how we build
infrastructure for sharing, starting with media. infrastructure for sharing, starting with media.
</p> </p>
</div> </div>
</div> </div>
<div className="relative mt-16 rounded-xl overflow-hidden shadow-2xl">
<div className="relative aspect-[16/9]">
<Image
src="/images/jeff-blueberries.jpg"
alt="Seeing through the matrix of artificial scarcity"
fill
className="object-cover"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent" />
<div className="absolute bottom-0 left-0 right-0 p-6">
<p className="text-white text-xl font-bold text-center font-marker text-shadow">
See through artificial scarcity
</p>
</div>
</div>
</div>
</div> </div>
</div> </div>
</section> </section>
@ -210,29 +217,55 @@ export default function JefflixPage() {
<div className="inline-block p-6 bg-primary/10 rounded-full"> <div className="inline-block p-6 bg-primary/10 rounded-full">
<Rocket className="h-12 w-12 text-primary" strokeWidth={2.5} /> <Rocket className="h-12 w-12 text-primary" strokeWidth={2.5} />
</div> </div>
<h2 className="text-4xl md:text-5xl font-black text-balance">Start Your Own Server</h2> <h2 className="text-3xl md:text-3xl font-black text-balance font-marker">Start Your Own Server</h2>
<p className="text-xl text-muted-foreground leading-relaxed max-w-2xl mx-auto"> <p className="text-xl text-muted-foreground leading-relaxed max-w-2xl mx-auto">
Tools like Jellyfin make self-hosting accessible. Start with your own library, share with friends, scale Tools like Jellyfin make self-hosting accessible. Start with your own library, share with friends, scale
to your community. Or use mine while you figure it outthat's the point. to your community. Or use mine while you figure it outthat's the point.
</p> </p>
</div> </div>
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center pt-6"> <div className="flex flex-col sm:flex-row gap-4 justify-center items-center pt-6">
<Button asChild size="lg" className="text-lg px-8 py-6 font-bold"> <Button asChild size="lg" className="text-lg px-8 py-6 font-bold bg-red-600 hover:bg-red-700 text-white">
<a href="https://movies.jeffemmett.com"> <a href="https://movies.jeffemmett.com">
<Film className="mr-2 h-5 w-5" /> <Film className="mr-2 h-5 w-5" />
Try Movies Movies
</a> </a>
</Button> </Button>
<Button asChild size="lg" variant="outline" className="text-lg px-8 py-6 font-bold bg-transparent"> <Button
asChild
size="lg"
className="text-lg px-8 py-6 font-bold bg-blue-600 hover:bg-blue-700 text-white"
>
<a href="https://movies.jeffemmett.com">
<Tv className="mr-2 h-5 w-5" />
Shows
</a>
</Button>
<Button
asChild
size="lg"
className="text-lg px-8 py-6 font-bold bg-green-600 hover:bg-green-700 text-white"
>
<a href="https://music.jeffemmett.com"> <a href="https://music.jeffemmett.com">
<Music className="mr-2 h-5 w-5" /> <Music className="mr-2 h-5 w-5" />
Try Music Music
</a> </a>
</Button> </Button>
</div> </div>
<p className="text-sm text-muted-foreground pt-4"> <p className="text-sm text-muted-foreground pt-4">
Or learn how to set up your own Jellyfin server and join the movement Or learn how to set up your own Jellyfin server and join the movement
</p> </p>
<div className="relative mt-12 rounded-xl overflow-hidden shadow-2xl">
<div className="relative aspect-video">
<Image src="/images/jeff-donkey.jpg" alt="Making connections" fill className="object-cover" />
<div className="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent" />
<div className="absolute inset-0 flex items-end justify-center p-8">
<p className="text-white text-2xl md:text-3xl font-black text-center font-marker drop-shadow-lg">
If this ass can figure it out, you can too! XD
</p>
</div>
</div>
</div>
</div> </div>
</div> </div>
</section> </section>
@ -241,7 +274,7 @@ export default function JefflixPage() {
<footer className="border-t border-border bg-muted/50"> <footer className="border-t border-border bg-muted/50">
<div className="container mx-auto px-4 py-12"> <div className="container mx-auto px-4 py-12">
<div className="max-w-4xl mx-auto text-center space-y-4"> <div className="max-w-4xl mx-auto text-center space-y-4">
<JefflixLogo className="justify-center" /> <JefflixLogo className="justify-center" size="small" />
<p className="text-muted-foreground leading-relaxed max-w-2xl mx-auto"> <p className="text-muted-foreground leading-relaxed max-w-2xl mx-auto">
Powered by Jellyfin. Built on solidarity. Infrastructure for the sharing economystarting digitally. Powered by Jellyfin. Built on solidarity. Infrastructure for the sharing economystarting digitally.
</p> </p>

View File

@ -1,25 +1,31 @@
export function JefflixLogo({ className = "" }: { className?: string }) { export function JefflixLogo({ className = "", size = "default" }: { className?: string; size?: "default" | "small" }) {
const isSmall = size === "small"
return ( return (
<div className={`inline-flex items-center gap-1 ${className}`}> <div className={`inline-flex items-center gap-3 ${className}`}>
<span <span
className="text-4xl md:text-5xl font-black tracking-tight" className={
isSmall
? "text-3xl md:text-[3.33rem] font-black tracking-tight"
: "text-9xl md:text-[10rem] font-black tracking-tight"
}
style={{ style={{
fontFamily: "'Fredoka', 'Rounded Mplus 1c', sans-serif", fontFamily: "'Fredoka', 'Rounded Mplus 1c', sans-serif",
textShadow: "2px 2px 0px rgba(0,0,0,0.1), -1px -1px 0px rgba(255,255,255,0.5)", color: "#E50914",
background: "linear-gradient(135deg, #10b981 0%, #3b82f6 100%)", textShadow: "3px 3px 0px rgba(0,0,0,0.3)",
WebkitBackgroundClip: "text", letterSpacing: "-0.05em",
WebkitTextFillColor: "transparent",
backgroundClip: "text",
}} }}
> >
JEFFLIX JEFFLIX
</span> </span>
<span <span
className="text-2xl md:text-3xl font-black" className={isSmall ? "text-2xl md:text-2xl font-black" : "text-6xl md:text-7xl font-black"}
style={{ style={{
fontFamily: "'Fredoka', 'Rounded Mplus 1c', sans-serif", fontFamily: "'Permanent Marker', cursive",
color: "#f59e0b", color: "#dc2626",
textShadow: "1px 1px 0px rgba(0,0,0,0.1)", textShadow: "2px 2px 4px rgba(0,0,0,0.5)",
transform: "rotate(-2deg)",
display: "inline-block",
}} }}
> >
.LOL .LOL