dashboard tweaks
This commit is contained in:
parent
683cdeb86b
commit
514b34dc88
1 changed files with 188 additions and 196 deletions
|
|
@ -14,18 +14,15 @@ import {
|
||||||
Sparkles,
|
Sparkles,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
|
|
||||||
// If you have shadcn/ui Card/Button/Badge already, keep these.
|
// shadcn/ui
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App Dashboard: Support CTA (simplified hero, no progress meter)
|
* App Dashboard: Support CTA (polished)
|
||||||
* ---------------------------------------------------------------
|
* - Stable custom buttons (no hover flicker)
|
||||||
* - Minimal hero to match site chrome.
|
* - Perks on their own lines
|
||||||
* - No goal/progress UI.
|
* - Copy + outline adjustments per request
|
||||||
* - Consistent CTA buttons with solid, high-contrast fills.
|
|
||||||
* - Tips/perks render as inline chips so they wrap smoothly.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const perks = [
|
const perks = [
|
||||||
|
|
@ -79,205 +76,200 @@ const adVsCommunity = {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Page() {
|
// Reusable button styles (anchors styled as buttons to avoid shadcn hover conflicts)
|
||||||
return (
|
const btn =
|
||||||
<div className="min-h-[calc(100dvh-4rem)] w-full">
|
"inline-flex items-center justify-center rounded-2xl px-5 py-3 text-sm font-medium text-white shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2";
|
||||||
{/* Hero (clean + minimal to match site) */}
|
const btnTeal = `${btn} bg-teal-600 hover:bg-teal-700 focus-visible:ring-teal-500`;
|
||||||
<section className="mx-auto w-full max-w-6xl px-6 py-14 sm:py-16">
|
const btnRose = `${btn} bg-rose-600 hover:bg-rose-700 focus-visible:ring-rose-500`;
|
||||||
<div className="text-center">
|
const btnSky = `${btn} bg-sky-600 hover:bg-sky-700 focus-visible:ring-sky-500`;
|
||||||
<Badge variant="secondary" className="mb-4">
|
|
||||||
Community-Funded • Ad-Free • Open Resources
|
|
||||||
</Badge>
|
|
||||||
|
|
||||||
<h1 className="text-3xl font-extrabold tracking-tight sm:text-4xl">
|
export default function Page() {
|
||||||
Keep Laser Everything & MakeArmy free for everyone
|
return (
|
||||||
</h1>
|
<div className="min-h-[calc(100dvh-4rem)] w-full">
|
||||||
|
{/* Hero */}
|
||||||
|
<section className="mx-auto w-full max-w-6xl px-6 py-14 sm:py-16">
|
||||||
|
<div className="text-center">
|
||||||
|
<Badge variant="secondary" className="mb-4">
|
||||||
|
Community-Funded • Ad-Free • Open Resources
|
||||||
|
</Badge>
|
||||||
|
|
||||||
<p className="mx-auto mt-3 max-w-3xl text-balance text-sm text-muted-foreground sm:text-base">
|
<h1 className="text-3xl font-extrabold tracking-tight sm:text-4xl">
|
||||||
The videos, tools, and docs you use today exist because previous supporters paid it forward.
|
Keep Laser Everything & MakeArmy free for everyone
|
||||||
We want to stay independent — no ads, no sponsors, no strings — and that only works if we fund it together.
|
</h1>
|
||||||
</p>
|
|
||||||
|
|
||||||
{/* Slim CTA row (consistent shape + solid, high-contrast fills) */}
|
<p className="mx-auto mt-3 max-w-3xl text-balance text-sm text-muted-foreground sm:text-base">
|
||||||
<div className="mt-6 flex flex-wrap items-center justify-center gap-3">
|
The videos, tools, and docs you use today exist because previous supporters paid it forward.
|
||||||
{/* Laser Master Academy — teal */}
|
We want to stay independent — no ads, no sponsors, no strings — and that only works if we fund it together.
|
||||||
<Button
|
</p>
|
||||||
asChild
|
|
||||||
size="lg"
|
|
||||||
className="rounded-2xl bg-teal-600 text-white shadow-sm hover:bg-teal-700 focus-visible:ring-2 focus-visible:ring-teal-500"
|
|
||||||
>
|
|
||||||
<Link
|
|
||||||
href="https://masters.lasereverything.net"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
aria-label="Join Laser Master Academy"
|
|
||||||
>
|
|
||||||
Join Laser Master Academy <ArrowRight className="ml-2 h-4 w-4" />
|
|
||||||
</Link>
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
{/* Patreon — rose */}
|
{/* CTA row (custom anchors = stable hover) */}
|
||||||
<Button
|
<div className="mt-6 flex flex-wrap items-center justify-center gap-3">
|
||||||
asChild
|
<Link
|
||||||
size="lg"
|
href="https://masters.lasereverything.net"
|
||||||
className="rounded-2xl bg-rose-600 text-white shadow-sm hover:bg-rose-700 focus-visible:ring-2 focus-visible:ring-rose-500"
|
target="_blank"
|
||||||
>
|
rel="noopener noreferrer"
|
||||||
<Link
|
aria-label="Join Laser Master Academy"
|
||||||
href="https://www.patreon.com/c/LaserEverything"
|
className={btnTeal}
|
||||||
target="_blank"
|
>
|
||||||
rel="noopener noreferrer"
|
Join Laser Master Academy <ArrowRight className="ml-2 h-4 w-4" />
|
||||||
aria-label="Back Laser Everything on Patreon"
|
</Link>
|
||||||
>
|
|
||||||
Back on Patreon
|
|
||||||
</Link>
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
{/* Ko-Fi — sky (high-contrast; no yellow) */}
|
<Link
|
||||||
<Button
|
href="https://www.patreon.com/c/LaserEverything"
|
||||||
asChild
|
target="_blank"
|
||||||
size="lg"
|
rel="noopener noreferrer"
|
||||||
className="rounded-2xl bg-sky-600 text-white shadow-sm hover:bg-sky-700 focus-visible:ring-2 focus-visible:ring-sky-500"
|
aria-label="Back Laser Everything on Patreon"
|
||||||
>
|
className={btnRose}
|
||||||
<Link
|
>
|
||||||
href="https://ko-fi.com/lasereverything"
|
Back on Patreon
|
||||||
target="_blank"
|
</Link>
|
||||||
rel="noopener noreferrer"
|
|
||||||
aria-label="Tip Laser Everything on Ko-Fi"
|
|
||||||
>
|
|
||||||
Tip on Ko-Fi
|
|
||||||
</Link>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Perks as inline chips (flows naturally, no awkward line breaks) */}
|
<Link
|
||||||
<ul className="mx-auto mt-5 flex max-w-4xl flex-wrap items-center justify-center gap-x-6 gap-y-2 text-muted-foreground">
|
href="https://ko-fi.com/lasereverything"
|
||||||
{perks.map((p, i) => (
|
target="_blank"
|
||||||
<li key={i} className="inline-flex items-center gap-2 text-sm">
|
rel="noopener noreferrer"
|
||||||
{p.icon}
|
aria-label="Tip Laser Everything on Ko-Fi"
|
||||||
<span>{p.text}</span>
|
className={btnSky}
|
||||||
</li>
|
>
|
||||||
))}
|
Tip on Ko-Fi
|
||||||
</ul>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* Support Options */}
|
{/* Perks: each on its own line, centered */}
|
||||||
<section className="mx-auto -mt-2 max-w-6xl px-6 pb-12">
|
<ul className="mx-auto mt-5 max-w-xl space-y-2 text-muted-foreground">
|
||||||
<div className="rounded-3xl border bg-card p-6 shadow-sm sm:p-8">
|
{perks.map((p, i) => (
|
||||||
<div className="mx-auto max-w-3xl text-center">
|
<li key={i} className="flex items-center justify-center gap-2 text-sm">
|
||||||
<h2 className="text-2xl font-bold tracking-tight sm:text-3xl">How you can help—pick what fits</h2>
|
{p.icon}
|
||||||
<p className="mt-2 text-muted-foreground">
|
<span>{p.text}</span>
|
||||||
Whether you join the Academy, pledge monthly, or tip once, every contribution sustains the whole community.
|
</li>
|
||||||
</p>
|
))}
|
||||||
</div>
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<div className="mt-8 grid grid-cols-1 gap-6 md:grid-cols-3">
|
{/* Support Options */}
|
||||||
{supportTiers.map((tier) => (
|
<section className="mx-auto -mt-2 max-w-6xl px-6 pb-12">
|
||||||
<Card key={tier.name} className="group rounded-2xl transition hover:shadow-lg">
|
<div className="rounded-3xl border bg-card p-6 shadow-sm sm:p-8">
|
||||||
<CardHeader>
|
<div className="mx-auto max-w-3xl text-center">
|
||||||
<div className="mb-2 flex items-center gap-2 text-teal-600 dark:text-teal-400">
|
<h2 className="text-2xl font-bold tracking-tight sm:text-3xl">How you can help—pick what fits</h2>
|
||||||
{tier.icon}
|
<p className="mt-2 text-muted-foreground">
|
||||||
<CardTitle className="text-lg">{tier.name}</CardTitle>
|
Whether you join the Academy, pledge monthly, or tip once, every contribution sustains the whole community.
|
||||||
</div>
|
</p>
|
||||||
<p className="text-sm text-muted-foreground">{tier.blurb}</p>
|
</div>
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<ul className="space-y-2 text-sm">
|
|
||||||
{tier.perks.map((perk) => (
|
|
||||||
<li key={perk} className="flex items-center gap-2">
|
|
||||||
<CheckCircle2 className="h-4 w-4" aria-hidden="true" /> {perk}
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
<Button asChild className="mt-4 w-full rounded-xl">
|
|
||||||
<Link href={tier.href} target="_blank" rel="noopener noreferrer">
|
|
||||||
{tier.cta}
|
|
||||||
</Link>
|
|
||||||
</Button>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Philosophy: Ads vs Community */}
|
<div className="mt-8 grid grid-cols-1 gap-6 md:grid-cols-3">
|
||||||
<div className="mt-10">
|
{supportTiers.map((tier) => (
|
||||||
<div className="mx-auto max-w-3xl text-center">
|
<Card key={tier.name} className="group rounded-2xl transition hover:shadow-lg">
|
||||||
<h3 className="text-xl font-semibold">Why not just run ads & sponsors?</h3>
|
<CardHeader>
|
||||||
<p className="mt-2 text-sm text-muted-foreground">
|
<div className="mb-2 flex items-center gap-2 text-teal-600 dark:text-teal-400">
|
||||||
Because it quietly changes what we make and who we serve. We’d rather be accountable to you.
|
{tier.icon}
|
||||||
</p>
|
<CardTitle className="text-lg">{tier.name}</CardTitle>
|
||||||
</div>
|
</div>
|
||||||
|
<p className="text-sm text-muted-foreground">{tier.blurb}</p>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<ul className="space-y-2 text-sm">
|
||||||
|
{tier.perks.map((perk) => (
|
||||||
|
<li key={perk} className="flex items-center gap-2">
|
||||||
|
<CheckCircle2 className="h-4 w-4" aria-hidden="true" /> {perk}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<Link
|
||||||
|
href={tier.href}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="mt-4 inline-flex w-full items-center justify-center rounded-xl bg-foreground px-4 py-2.5 text-sm font-medium text-background transition-colors hover:bg-foreground/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground"
|
||||||
|
>
|
||||||
|
{tier.cta}
|
||||||
|
</Link>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="mt-6 grid grid-cols-1 gap-6 md:grid-cols-2">
|
{/* Philosophy: Ads vs Community */}
|
||||||
<Card className="rounded-2xl">
|
<div className="mt-10">
|
||||||
<CardHeader>
|
<div className="mx-auto max-w-3xl text-center">
|
||||||
<div className="flex items-center gap-2 text-rose-600 dark:text-rose-400">
|
<h3 className="text-xl font-semibold">Why not just run ads & sponsors?</h3>
|
||||||
<CircleX className="h-5 w-5" aria-hidden="true" />
|
<p className="mt-2 text-sm text-muted-foreground">
|
||||||
<CardTitle className="text-base">Advertising / Sponsorship Model</CardTitle>
|
Because it quietly changes what we make and who we serve.
|
||||||
</div>
|
</p>
|
||||||
</CardHeader>
|
<p className="mt-1 text-sm text-muted-foreground">We’d rather be accountable to you.</p>
|
||||||
<CardContent>
|
</div>
|
||||||
<ul className="space-y-2 text-sm text-muted-foreground">
|
|
||||||
{adVsCommunity.ads.map((t) => (
|
|
||||||
<li key={t} className="flex items-center gap-2">
|
|
||||||
<CircleX className="h-4 w-4" aria-hidden="true" /> {t}
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card className="rounded-2xl border-teal-600/30">
|
<div className="mt-6 grid grid-cols-1 gap-6 md:grid-cols-2">
|
||||||
<CardHeader>
|
{/* Dim outline for Advertising box */}
|
||||||
<div className="flex items-center gap-2 text-teal-700 dark:text-teal-300">
|
<Card className="rounded-2xl border border-foreground/10 dark:border-foreground/15">
|
||||||
<CheckCircle2 className="h-5 w-5" aria-hidden="true" />
|
<CardHeader>
|
||||||
<CardTitle className="text-base">Community-Funded Model</CardTitle>
|
<div className="flex items-center gap-2 text-rose-600 dark:text-rose-400">
|
||||||
</div>
|
<CircleX className="h-5 w-5" aria-hidden="true" />
|
||||||
</CardHeader>
|
<CardTitle className="text-base">Advertising / Sponsorship Model</CardTitle>
|
||||||
<CardContent>
|
</div>
|
||||||
<ul className="space-y-2 text-sm">
|
</CardHeader>
|
||||||
{adVsCommunity.community.map((t) => (
|
<CardContent>
|
||||||
<li key={t} className="flex items-center gap-2">
|
<ul className="space-y-2 text-sm text-muted-foreground">
|
||||||
<CheckCircle2 className="h-4 w-4" aria-hidden="true" /> {t}
|
{adVsCommunity.ads.map((t) => (
|
||||||
</li>
|
<li key={t} className="flex items-center gap-2">
|
||||||
))}
|
<CircleX className="h-4 w-4" aria-hidden="true" /> {t}
|
||||||
</ul>
|
</li>
|
||||||
</CardContent>
|
))}
|
||||||
</Card>
|
</ul>
|
||||||
</div>
|
</CardContent>
|
||||||
</div>
|
</Card>
|
||||||
|
|
||||||
{/* Divider */}
|
{/* Brighter outline for Community box */}
|
||||||
<div className="my-10 h-px w-full bg-border" />
|
<Card className="rounded-2xl border border-teal-500/50 shadow-sm">
|
||||||
|
<CardHeader>
|
||||||
|
<div className="flex items-center gap-2 text-teal-700 dark:text-teal-300">
|
||||||
|
<CheckCircle2 className="h-5 w-5" aria-hidden="true" />
|
||||||
|
<CardTitle className="text-base">Community-Funded Model</CardTitle>
|
||||||
|
</div>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<ul className="space-y-2 text-sm">
|
||||||
|
{adVsCommunity.community.map((t) => (
|
||||||
|
<li key={t} className="flex items-center gap-2">
|
||||||
|
<CheckCircle2 className="h-4 w-4" aria-hidden="true" /> {t}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Other ways */}
|
{/* Divider */}
|
||||||
<div className="mt-10">
|
<div className="my-10 h-px w-full bg-border" />
|
||||||
<h3 className="text-center text-xl font-semibold">No budget? No problem—here’s how to help for free</h3>
|
|
||||||
<div className="mx-auto mt-4 max-w-3xl">
|
|
||||||
<ul className="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
|
||||||
{[
|
|
||||||
"Share our videos with a friend",
|
|
||||||
"Star + share our repos/tools",
|
|
||||||
"Submit laser settings & materials",
|
|
||||||
"Report bugs and suggest features",
|
|
||||||
].map((item) => (
|
|
||||||
<li key={item} className="flex items-center gap-2 text-sm text-muted-foreground">
|
|
||||||
<HandCoins className="h-4 w-4" aria-hidden="true" /> {item}
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Closing statement */}
|
{/* Other ways */}
|
||||||
<div className="mx-auto mt-10 max-w-3xl text-center">
|
<div className="mt-10">
|
||||||
<p className="text-balance text-sm text-muted-foreground">
|
<h3 className="text-center text-xl font-semibold">No budget? No problem—here’s how to help for free</h3>
|
||||||
Laser Everything exists because makers before you chose to keep the ladder down. If we each do a small part—
|
<div className="mx-auto mt-4 max-w-3xl">
|
||||||
<span className="font-medium text-foreground"> we never need a paywall</span>.
|
<ul className="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
||||||
</p>
|
{[
|
||||||
</div>
|
"Share our videos with a friend",
|
||||||
</div>
|
"Star + share our repos/tools",
|
||||||
</section>
|
"Submit laser settings & materials",
|
||||||
</div>
|
"Report bugs and suggest features",
|
||||||
);
|
].map((item) => (
|
||||||
}
|
<li key={item} className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||||
|
<HandCoins className="h-4 w-4" aria-hidden="true" /> {item}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Closing statement */}
|
||||||
|
<div className="mx-auto mt-10 max-w-3xl text-center">
|
||||||
|
<p className="text-balance text-sm text-muted-foreground">
|
||||||
|
Laser Everything exists because makers before you chose to keep the ladder down. If we each do a small part—
|
||||||
|
<span className="font-medium text-foreground"> we never need a paywall</span>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue