add shadcraft landing

This commit is contained in:
Sahaj Jain
2025-08-01 16:27:52 +05:30
parent 021fa655f1
commit 0057c8fe68
7 changed files with 511 additions and 44 deletions
+41
View File
@@ -0,0 +1,41 @@
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Apply Your tweakcn Theme to Shadcraft Figma UI Kit | Professional Design System",
description:
"Transform your tweakcn themes into stunning Figma designs with Shadcraft's premium UI kit. 51 components, 44 blocks, dark mode support, and 1500+ icons. Professional Figma design system for shadcn/ui themes.",
keywords:
"figma ui kit, shadcn ui figma, tweakcn themes, figma design system, ui components figma, design tokens figma, figma plugin, shadcraft, figma templates, design system integration",
authors: [{ name: "tweakcn Team" }],
openGraph: {
title: "Apply Your tweakcn Theme to Shadcraft Figma UI Kit",
description:
"Professional Figma UI kit with 51 components, 44 blocks, and seamless tweakcn theme integration. Get the ultimate design system for your projects.",
url: "https://tweakcn.com/figma",
siteName: "tweakcn",
images: [
{
url: "https://tweakcn.com/figma-onboarding/shadcraft-preview.jpg",
width: 1200,
height: 630,
alt: "Shadcraft Figma UI Kit Preview",
},
],
type: "website",
},
twitter: {
card: "summary_large_image",
title: "Apply Your tweakcn Theme to Shadcraft Figma UI Kit",
description:
"Professional Figma UI kit with 51 components, 44 blocks, and seamless tweakcn theme integration.",
images: ["https://tweakcn.com/figma-onboarding/shadcraft-preview.jpg"],
},
robots: "index, follow",
alternates: {
canonical: "https://tweakcn.com/figma",
},
};
export default function FigmaLayout({ children }: { children: React.ReactNode }) {
return <>{children}</>;
}
+280
View File
@@ -0,0 +1,280 @@
"use client";
import { useState, useEffect } from "react";
import { FigmaHeader } from "@/components/figma-header";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import Logo from "@/assets/logo.svg";
import Shadcraft from "@/assets/shadcraft.svg";
import FigmaIcon from "@/assets/figma.svg";
import { Check, X, ArrowUpRight, Figma, Cable, Paintbrush } from "lucide-react";
import Link from "next/link";
import { FIGMA_CONSTANTS, createPurchaseUrl } from "@/lib/figma-constants";
export default function FigmaPage() {
const [isScrolled, setIsScrolled] = useState(false);
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const steps = FIGMA_CONSTANTS.steps.map((step, index) => ({
...step,
icon:
index === 0 ? (
<Figma className="h-6 w-6" />
) : index === 1 ? (
<Cable className="h-6 w-6" />
) : (
<Paintbrush className="h-6 w-6" />
),
}));
const handlePurchase = () => {
const url = createPurchaseUrl("/");
window.open(url, "_blank");
};
useEffect(() => {
const handleScroll = () => {
if (window.scrollY > 10) {
setIsScrolled(true);
} else {
setIsScrolled(false);
}
};
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
// Structured data for SEO
const structuredData = {
"@context": "https://schema.org",
"@type": "Product",
name: "Shadcraft Figma UI Kit - tweakcn Integration",
description:
"Professional Figma UI kit with 51 components, 44 blocks, dark mode support, and seamless tweakcn theme integration",
image: "https://tweakcn.com/figma-onboarding/shadcraft-preview.jpg",
brand: {
"@type": "Brand",
name: "Shadcraft",
},
offers: {
"@type": "Offer",
price: "89",
priceCurrency: "USD",
priceValidUntil: "2025-12-31",
availability: "https://schema.org/InStock",
url: FIGMA_CONSTANTS.shadcraftUrl,
seller: {
"@type": "Organization",
name: "Shadcraft",
},
},
aggregateRating: {
"@type": "AggregateRating",
ratingValue: "5",
reviewCount: "100+",
},
category: "Design Software",
additionalProperty: [
{
"@type": "PropertyValue",
name: "Components",
value: "51",
},
{
"@type": "PropertyValue",
name: "Blocks",
value: "44",
},
{
"@type": "PropertyValue",
name: "Icons",
value: "1500+",
},
],
};
return (
<>
{/* Structured Data */}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
/>
<div className="relative min-h-screen">
{/* Gradient Background using CSS variables */}
<div className="from-background via-muted/20 to-accent/10 fixed inset-0 -z-10 bg-gradient-to-br" />
<div className="from-primary/5 to-secondary/10 fixed inset-0 -z-10 bg-gradient-to-tr via-transparent" />
{/* Header */}
<FigmaHeader
isScrolled={isScrolled}
mobileMenuOpen={mobileMenuOpen}
setMobileMenuOpen={setMobileMenuOpen}
/>
{/* Main Content */}
<main className="container mx-auto max-w-[600px] p-4 pt-8">
{/* Header Section */}
<header className="p-8 pb-5">
<div className="flex items-center justify-center gap-2">
<div className="flex items-center gap-2">
<Logo className="h-6 w-6" alt="tweakcn logo" />
<div className="text-lg font-bold">tweakcn</div>
</div>
<X className="h-4 w-4" aria-hidden="true" />
<Link href={FIGMA_CONSTANTS.shadcraftUrl} target="_blank" rel="noopener noreferrer">
<div className="flex items-center gap-2">
<Shadcraft className="h-6 w-6" alt="Shadcraft logo" />
<div className="text-lg font-bold">shadcraft</div>
</div>
</Link>
</div>
</header>
<div className="space-y-16 px-8 pb-32">
{/* Hero Section */}
<section className="space-y-6 text-center">
<h1 className="text-5xl leading-12 font-semibold tracking-tight">
Apply your theme to the ultimate Figma UI kit
</h1>
<div className="flex justify-center gap-3.5">
<Button size="lg" className="h-10 px-8" onClick={handlePurchase}>
Get started
</Button>
<Link href={FIGMA_CONSTANTS.previewUrl} target="_blank" rel="noopener noreferrer">
<Button variant="outline" size="lg" className="h-10 gap-2 px-8">
<FigmaIcon className="h-4 w-4" />
Preview
</Button>
</Link>
</div>
<div className="space-y-1.5 pt-1">
<p className="text-muted-foreground text-sm">Trusted by top designers</p>
<div
className="flex justify-center -space-x-3"
role="group"
aria-label="Designer avatars"
>
{FIGMA_CONSTANTS.designers.map((designer, index) => (
<Avatar key={index} className="border-background h-8 w-8 border-2">
<AvatarImage src={designer.avatar} alt={`${designer.name} avatar`} />
<AvatarFallback className="text-xs">{designer.fallback}</AvatarFallback>
</Avatar>
))}
</div>
</div>
</section>
{/* How it works */}
<section className="space-y-4">
<h2 className="text-center text-2xl font-semibold">How it works</h2>
<div className="border-border rounded-2xl border px-6">
<div className="divide-border grid grid-cols-3 divide-x">
{steps.map((step, index) => (
<article
key={index}
className="space-y-2 px-6 py-6 text-center first:pl-0 last:pr-0"
>
<div className="text-foreground mb-2 flex justify-center" aria-hidden="true">
{step.icon}
</div>
<p className="text-muted-foreground text-sm">{step.step}</p>
<h3 className="font-semibold">{step.title}</h3>
<p className="text-muted-foreground sr-only text-sm">{step.description}</p>
</article>
))}
</div>
</div>
</section>
{/* Feature Description */}
<section className="space-y-6 text-center">
<div className="mx-auto max-w-sm space-y-1.5">
<h2 className="text-2xl font-semibold">
Top quality Figma UI kit for professionals
</h2>
<p className="text-muted-foreground">
Shadcraft is packed with top quality components, true to the shadcn/ui ethos.
</p>
</div>
{/* Demo UI Preview */}
<figure className="border-border relative overflow-hidden rounded-2xl border">
<img
src="/figma-onboarding/shadcraft-preview.jpg"
alt="Shadcraft Figma UI Kit Preview showing various components and design blocks"
className="h-auto w-full"
loading="lazy"
width="600"
height="400"
/>
</figure>
<Link href={FIGMA_CONSTANTS.shadcraftUrl} target="_blank" rel="noopener noreferrer">
<Button variant="link" className="gap-1 text-sm">
More on Shadcraft
<ArrowUpRight className="h-3 w-3" />
</Button>
</Link>
</section>
{/* Pricing */}
<section className="space-y-6">
<h2 className="text-center text-2xl font-semibold">Pricing</h2>
<Card className="p-6">
<div className="grid gap-7 md:grid-cols-2">
<div className="space-y-4">
<h3 className="font-semibold">What you get with Shadcraft</h3>
<ul className="space-y-2" role="list">
{FIGMA_CONSTANTS.features.map((feature, index) => (
<li key={index} className="flex items-center gap-1.5">
<Check className="h-4 w-4 text-green-600" aria-hidden="true" />
<span className="text-sm">{feature}</span>
</li>
))}
</ul>
</div>
<div className="space-y-4">
<Badge variant="secondary" className="w-fit">
Introductory offer
</Badge>
<div className="space-y-1.5">
<div className="flex items-end gap-1">
<span className="text-5xl font-semibold">$89</span>
</div>
<div className="text-muted-foreground text-sm line-through">$119</div>
</div>
<div className="flex gap-3">
<Button className="flex-1" onClick={handlePurchase}>
Get started
</Button>
<Link
href={FIGMA_CONSTANTS.previewUrl}
target="_blank"
rel="noopener noreferrer"
>
<Button variant="outline" className="gap-2">
<FigmaIcon className="h-4 w-4" />
Preview
</Button>
</Link>
</div>
</div>
</div>
</Card>
<p className="text-muted-foreground text-center text-xs">Prices in USD</p>
</section>
</div>
</main>
</div>
</>
);
}
+8
View File
@@ -11,6 +11,7 @@ import type { Metadata, Viewport } from "next";
import { NuqsAdapter } from "nuqs/adapters/next/app";
import { Suspense } from "react";
import "./globals.css";
import Script from "next/script";
export const metadata: Metadata = {
title: "Beautiful themes for shadcn/ui — tweakcn | Theme Editor & Generator",
@@ -56,6 +57,13 @@ export default function RootLayout({ children }: { children: React.ReactNode })
<head>
<ThemeScript />
<DynamicFontLoader />
<Script
id="shadcraft"
dangerouslySetInnerHTML={{
__html: `window.lemonSqueezyAffiliateConfig = { store: "shadcraft" };`,
}}
/>
<Script id="affiliate" src="https://lmsqueezy.com/affiliate.js" defer />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="icon" href="/favicon.ico" sizes="any" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
+6
View File
@@ -28,5 +28,11 @@ export default function sitemap(): MetadataRoute.Sitemap {
changeFrequency: "weekly",
priority: 0.6,
},
{
url: `${baseUrl}/figma`,
lastModified: new Date(),
changeFrequency: "monthly",
priority: 0.7,
},
];
}
+24 -44
View File
@@ -10,49 +10,27 @@ import Shadcraft from "@/assets/shadcraft.svg";
import FigmaIcon from "@/assets/figma.svg";
import { Check, X, ArrowUpRight, Figma, Cable, Paintbrush } from "lucide-react";
import Link from "next/link";
import { FIGMA_CONSTANTS, createPurchaseUrl } from "@/lib/figma-constants";
interface FigmaExportDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
}
export function FigmaExportDialog({ open, onOpenChange }: FigmaExportDialogProps) {
const previewUrl =
"https://www.figma.com/design/J1e0cfCkDffMx6I0D0g5Nd/PREVIEW-%E2%80%A2-Shadcraft-%E2%80%A2-Beta-0.1.0?node-id=7050-2702&p=f&m=dev";
const designers = [
{ name: "Designer 1", avatar: "/figma-onboarding/avatar-1.png", fallback: "D1" },
{ name: "Designer 2", avatar: "/figma-onboarding/avatar-2.png", fallback: "D2" },
{ name: "Designer 3", avatar: "/figma-onboarding/avatar-3.png", fallback: "D3" },
{ name: "Designer 4", avatar: "/figma-onboarding/avatar-4.png", fallback: "D4" },
{ name: "Designer 5", avatar: "/figma-onboarding/avatar-5.png", fallback: "D5" },
{ name: "Designer 6", avatar: "/figma-onboarding/avatar-6.png", fallback: "D6" },
];
const steps = [
{
step: "Step 1",
title: "Download the kit",
icon: <Figma className="h-6 w-6" />,
},
{
step: "Step 2",
title: "Open the plugin",
icon: <Cable className="h-6 w-6" />,
},
{
step: "Step 3",
title: "Apply your theme",
icon: <Paintbrush className="h-6 w-6" />,
},
];
const features = ["51 components", "44 blocks", "Dark mode", "1500+ icons"];
const steps = FIGMA_CONSTANTS.steps.map((step, index) => ({
...step,
icon:
index === 0 ? (
<Figma className="h-6 w-6" />
) : index === 1 ? (
<Cable className="h-6 w-6" />
) : (
<Paintbrush className="h-6 w-6" />
),
}));
const handlePurchase = () => {
const baseUrl = "https://shadcraft.lemonsqueezy.com/buy/ce9ced1d-3119-413d-82b8-a4baef6aab36";
// const affiliateCode = process.env.NEXT_PUBLIC_AFFILIATE_CODE || "YOUR_AFFILIATE_CODE";
const successRedirectUrl = "/";
const url = `${baseUrl}?embed=1&redirect_url=${encodeURIComponent(successRedirectUrl)}`;
const url = createPurchaseUrl("/");
window.open(url, "_blank");
};
@@ -67,10 +45,12 @@ export function FigmaExportDialog({ open, onOpenChange }: FigmaExportDialogProps
<div className="text-lg font-bold">tweakcn</div>
</div>
<X className="h-4 w-4" />
<div className="flex items-center gap-2">
<Shadcraft className="h-6 w-6" />
<div className="text-lg font-bold">shadcraft</div>
</div>
<Link href={FIGMA_CONSTANTS.shadcraftUrl} target="_blank">
<div className="flex items-center gap-2">
<Shadcraft className="h-6 w-6" />
<div className="text-lg font-bold">shadcraft</div>
</div>
</Link>
</div>
</div>
@@ -85,7 +65,7 @@ export function FigmaExportDialog({ open, onOpenChange }: FigmaExportDialogProps
<Button size="lg" className="h-10 px-8" onClick={handlePurchase}>
Get started
</Button>
<Link href={previewUrl} target="_blank">
<Link href={FIGMA_CONSTANTS.previewUrl} target="_blank">
<Button variant="outline" size="lg" className="h-10 gap-2 px-8">
<FigmaIcon className="h-4 w-4" />
Preview
@@ -96,7 +76,7 @@ export function FigmaExportDialog({ open, onOpenChange }: FigmaExportDialogProps
<div className="space-y-1.5 pt-1">
<p className="text-muted-foreground text-sm">Trusted by top designers</p>
<div className="flex justify-center -space-x-3">
{designers.map((designer, index) => (
{FIGMA_CONSTANTS.designers.map((designer, index) => (
<Avatar key={index} className="border-background h-8 w-8 border-2">
<AvatarImage src={designer.avatar} alt={designer.name} />
<AvatarFallback className="text-xs">{designer.fallback}</AvatarFallback>
@@ -140,7 +120,7 @@ export function FigmaExportDialog({ open, onOpenChange }: FigmaExportDialogProps
/>
</div>
<Link href="https://shadcraft.com" target="_blank">
<Link href={FIGMA_CONSTANTS.shadcraftUrl} target="_blank">
<Button variant="link" className="gap-1 text-sm">
More on Shadcraft
<ArrowUpRight className="h-3 w-3" />
@@ -157,7 +137,7 @@ export function FigmaExportDialog({ open, onOpenChange }: FigmaExportDialogProps
<div className="space-y-4">
<h3 className="font-semibold">What you get with Shadcraft</h3>
<div className="space-y-2">
{features.map((feature, index) => (
{FIGMA_CONSTANTS.features.map((feature, index) => (
<div key={index} className="flex items-center gap-1.5">
<Check className="h-4 w-4 text-green-600" />
<span className="text-sm">{feature}</span>
@@ -180,7 +160,7 @@ export function FigmaExportDialog({ open, onOpenChange }: FigmaExportDialogProps
<Button className="flex-1" onClick={handlePurchase}>
Get started
</Button>
<Link href={previewUrl} target="_blank">
<Link href={FIGMA_CONSTANTS.previewUrl} target="_blank">
<Button variant="outline" className="gap-2">
<FigmaIcon className="h-4 w-4" />
Preview
+111
View File
@@ -0,0 +1,111 @@
"use client";
import GitHubIcon from "@/assets/github.svg";
import Logo from "@/assets/logo.svg";
import { Button } from "@/components/ui/button";
import { useGithubStars } from "@/hooks/use-github-stars";
import { cn } from "@/lib/utils";
import { formatCompactNumber } from "@/utils/format";
import { Menu, X } from "lucide-react";
import { motion } from "motion/react";
import Link from "next/link";
import { ThemeToggle } from "./theme-toggle";
interface FigmaHeaderProps {
isScrolled: boolean;
mobileMenuOpen: boolean;
setMobileMenuOpen: (open: boolean) => void;
}
export function FigmaHeader({ isScrolled, mobileMenuOpen, setMobileMenuOpen }: FigmaHeaderProps) {
const { stargazersCount } = useGithubStars("jnsahaj", "tweakcn");
return (
<header
className={cn(
"sticky top-0 z-50 w-full backdrop-blur-lg",
isScrolled ? "bg-background/90 border-border/20 border-b shadow-xs" : "bg-transparent"
)}
>
<div className="container mx-auto flex h-16 items-center justify-between px-4 md:px-6">
<Link href="/">
<div className="flex items-center gap-2 font-bold">
<Logo className="size-6" />
<span className="hidden lg:block">tweakcn</span>
</div>
</Link>
<div className="hidden cursor-pointer items-center gap-4 md:flex">
<motion.div
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.3, delay: 0.2 }}
>
<Button variant="ghost" asChild>
<a
href="https://github.com/jnsahaj/tweakcn"
target="_blank"
rel="noopener noreferrer"
className="font-semibold"
>
<GitHubIcon className="size-5" />
{stargazersCount > 0 && formatCompactNumber(stargazersCount)}
</a>
</Button>
</motion.div>
<motion.div
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.3, delay: 0.3 }}
>
<ThemeToggle
variant="secondary"
size="icon"
className="rounded-full transition-transform hover:scale-105"
/>
</motion.div>
</div>
<div className="flex items-center gap-2 md:hidden">
<ThemeToggle variant="ghost" size="icon" />
<Button variant="ghost" size="icon" onClick={() => setMobileMenuOpen(!mobileMenuOpen)}>
{mobileMenuOpen ? <X className="size-5" /> : <Menu className="size-5" />}
<span className="sr-only">Toggle menu</span>
</Button>
</div>
</div>
{/* Mobile menu - simplified */}
{mobileMenuOpen && (
<motion.div
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
className="bg-background/95 absolute inset-x-0 top-16 border-b backdrop-blur-lg md:hidden"
>
<div className="container mx-auto flex flex-col gap-4 px-4 py-4">
<motion.div
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3, delay: 0.1 }}
className="border-border/30 border-t pt-2"
>
<Button variant="ghost" asChild className="w-full justify-start">
<a
href="https://github.com/jnsahaj/tweakcn"
target="_blank"
rel="noopener noreferrer"
onClick={() => setMobileMenuOpen(false)}
>
<GitHubIcon className="mr-2 size-5" />
GitHub {stargazersCount > 0 && `(${formatCompactNumber(stargazersCount)})`}
</a>
</Button>
</motion.div>
</div>
</motion.div>
)}
</header>
);
}
+41
View File
@@ -0,0 +1,41 @@
export const FIGMA_CONSTANTS = {
shadcraftUrl: "https://shadcraft.com?aff=6NjlYZ",
previewUrl:
"https://www.figma.com/design/J1e0cfCkDffMx6I0D0g5Nd/PREVIEW-%E2%80%A2-Shadcraft-%E2%80%A2-Beta-0.1.0?node-id=7050-2702&p=f&m=dev",
purchaseUrl: "https://shadcraft.lemonsqueezy.com/buy/ce9ced1d-3119-413d-82b8-a4baef6aab36",
designers: [
{ name: "Designer 1", avatar: "/figma-onboarding/avatar-1.png", fallback: "D1" },
{ name: "Designer 2", avatar: "/figma-onboarding/avatar-2.png", fallback: "D2" },
{ name: "Designer 3", avatar: "/figma-onboarding/avatar-3.png", fallback: "D3" },
{ name: "Designer 4", avatar: "/figma-onboarding/avatar-4.png", fallback: "D4" },
{ name: "Designer 5", avatar: "/figma-onboarding/avatar-5.png", fallback: "D5" },
{ name: "Designer 6", avatar: "/figma-onboarding/avatar-6.png", fallback: "D6" },
],
steps: [
{
step: "Step 1",
title: "Download the kit",
description: "Get the comprehensive Shadcraft Figma UI kit",
},
{
step: "Step 2",
title: "Open the plugin",
description: "Launch the tweakcn Figma plugin",
},
{
step: "Step 3",
title: "Apply your theme",
description: "Transform components with your custom theme",
},
],
features: [
"51 premium components",
"44 responsive blocks",
"Dark mode support",
"1500+ vector icons",
],
};
export const createPurchaseUrl = (successRedirectUrl: string = "/") => {
return `${FIGMA_CONSTANTS.purchaseUrl}?embed=1&aff=6NjlYZ&redirect_url=${encodeURIComponent(successRedirectUrl)}`;
};