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";
/* Added Fredoka bubble font for logo */
--font-fredoka: var(--font-fredoka);
/* Added Permanent Marker for street art headlines */
--font-marker: var(--font-marker);
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);

View File

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

View File

@ -1,6 +1,6 @@
import { Button } from "@/components/ui/button"
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 { JefflixLogo } from "@/components/jefflix-logo"
@ -9,7 +9,16 @@ export default function JefflixPage() {
<div className="min-h-screen bg-background">
{/* Hero Section */}
<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
className="absolute inset-0 opacity-30"
style={{
@ -24,11 +33,8 @@ export default function JefflixPage() {
<div className="mb-4">
<JefflixLogo />
</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
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={{
textShadow: "3px 3px 0px rgba(0,0,0,0.1)",
color: "hsl(var(--foreground))",
@ -45,60 +51,41 @@ export default function JefflixPage() {
</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 */}
<div className="text-center space-y-4">
<p className="text-lg font-medium text-muted-foreground">
Need a place to start? Try these servers (or build your own):
</p>
<p className="text-lg font-medium text-muted-foreground">Try it out on Jefflix (or build your own!)</p>
<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">
<Film className="mr-2 h-5 w-5" />
Movies Server
Movies
</a>
</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">
<Music className="mr-2 h-5 w-5" />
Music Server
Music
</a>
</Button>
</div>
@ -112,7 +99,7 @@ export default function JefflixPage() {
<div className="container mx-auto px-4 py-16 md:py-24">
<div className="max-w-5xl mx-auto">
<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">
Technology promised abundance, but corporations chose artificial scarcity. Let's build the alternative.
</p>
@ -155,6 +142,12 @@ export default function JefflixPage() {
</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>
</section>
@ -164,10 +157,7 @@ export default function JefflixPage() {
<div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto space-y-12">
<div className="text-center space-y-4">
<h2 className="text-4xl md:text-5xl font-black text-balance">Beyond Digital Feudalism</h2>
<div className="flex justify-center py-4">
<JefflixLogo />
</div>
<h2 className="text-3xl md:text-3xl font-black text-balance font-marker">Beyond Digital Feudalism</h2>
<p className="text-xl text-muted-foreground leading-relaxed">
Streaming platforms aren't just bad business—they're architecture for extraction.
</p>
@ -175,7 +165,7 @@ export default function JefflixPage() {
<div className="space-y-6">
<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">
Content rotates based on licensing deals, not user needs. You're not buying access—you're renting
temporary gates to shifting catalogs.
@ -183,7 +173,7 @@ export default function JefflixPage() {
</div>
<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">
The "streaming wars" recreated cable monopolies with extra steps. Fragmentation isn't a bug—it's the
business model.
@ -191,13 +181,30 @@ export default function JefflixPage() {
</div>
<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">
Digital goods cost nothing to copy, but everything to gate. Self-hosting is how we build
infrastructure for sharing, starting with media.
</p>
</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>
</section>
@ -210,29 +217,55 @@ export default function JefflixPage() {
<div className="inline-block p-6 bg-primary/10 rounded-full">
<Rocket className="h-12 w-12 text-primary" strokeWidth={2.5} />
</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">
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.
</p>
</div>
<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">
<Film className="mr-2 h-5 w-5" />
Try Movies
Movies
</a>
</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">
<Music className="mr-2 h-5 w-5" />
Try Music
Music
</a>
</Button>
</div>
<p className="text-sm text-muted-foreground pt-4">
Or learn how to set up your own Jellyfin server and join the movement
</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>
</section>
@ -241,7 +274,7 @@ export default function JefflixPage() {
<footer className="border-t border-border bg-muted/50">
<div className="container mx-auto px-4 py-12">
<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">
Powered by Jellyfin. Built on solidarity. Infrastructure for the sharing economystarting digitally.
</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 (
<div className={`inline-flex items-center gap-1 ${className}`}>
<div className={`inline-flex items-center gap-3 ${className}`}>
<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={{
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)",
background: "linear-gradient(135deg, #10b981 0%, #3b82f6 100%)",
WebkitBackgroundClip: "text",
WebkitTextFillColor: "transparent",
backgroundClip: "text",
color: "#E50914",
textShadow: "3px 3px 0px rgba(0,0,0,0.3)",
letterSpacing: "-0.05em",
}}
>
JEFFLIX
</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={{
fontFamily: "'Fredoka', 'Rounded Mplus 1c', sans-serif",
color: "#f59e0b",
textShadow: "1px 1px 0px rgba(0,0,0,0.1)",
fontFamily: "'Permanent Marker', cursive",
color: "#dc2626",
textShadow: "2px 2px 4px rgba(0,0,0,0.5)",
transform: "rotate(-2deg)",
display: "inline-block",
}}
>
.LOL