Add LandingSD2 page at /seedance-2 for Seedance marketing (#1109)

This commit is contained in:
BFlat authored and GitHub committed 2026-03-07 19:12:42 +07:00
1 parent 338210a568
commit 650cf55421
5 files changed
+850 -3

No files matched your search

@@ -67,3 +67,7 @@
/password-reset /index.html 200
/password-reset/ /index.html 200
/password-reset/* /index.html 200
/seedance-2 /index.html 200
/seedance-2/ /index.html 200
/seedance-2/* /index.html 200
@@ -4,6 +4,7 @@ import Media from "../pages/media";
import PressKit from "../pages/press-kit";
import Navbar from "../components/navbar";
import Landing2 from "../pages/landing2";
import LandingSD2 from "../pages/landing-sd2";
import TutorialsPage from "../pages/tutorials";
import TutorialsArticle from "../pages/tutorials/article";
import FaqIndex from "../pages/faq/index";
@@ -25,6 +26,7 @@ export function App() {
<Routes>
<Route path="/" element={<Landing2 />} />
<Route path="/seedance-2" element={<LandingSD2 />} />
<Route path="/download" element={<Download />} />
<Route path="/media" element={<Media />} />
<Route path="/media/:id" element={<Media />} />
@@ -0,0 +1 @@
export { default } from "./landing-sd2";
@@ -0,0 +1,840 @@
import { DiscordButton } from "../../components/discord-button";
import { Button } from "@storyteller/ui-button";
import { isMobile } from "react-device-detect";
import { faGithub } from "@fortawesome/free-brands-svg-icons";
import {
faFilm,
faPaintBrush,
faCamera,
faMapMarkerAlt,
faCube,
faLayerGroup,
faUser,
faTools,
faShapes,
faEraser,
} from "@fortawesome/pro-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import Footer from "../../components/footer";
import { useState, useRef, useEffect, useLayoutEffect } from "react";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import ModelBadgeGrid from "../../components/model-badge-grid";
import Seo from "../../components/seo";
import { OwnershipComparison } from "../../components/ownership-comparison/ownership-comparison";
import { DownloadModal } from "../../components/download-modal";
import { UsersApi } from "@storyteller/api";
import { LandingActionButtons } from "../../components/landing-action-buttons";
gsap.registerPlugin(ScrollTrigger);
const HERO_VIMEO_URL =
"https://player.vimeo.com/video/1169289718?autoplay=1&muted=1&loop=1&background=0&byline=0&portrait=0&title=0";
const LandingSD2 = () => {
const videos = [
{
src: "https://www.youtube.com/embed/oqoCWdOwr2U?si=ILMPk8hGHo9hP8RU",
},
{
src: "https://www.youtube.com/embed/H4NFXGMuwpY?si=wPuQl5cJOu1v8MJu",
},
{
src: "https://www.youtube.com/embed/7x7IZkHiGD8?si=tL8nK4CULigpfHQR",
},
];
const [activeFeature, setActiveFeature] = useState(0);
const [activeVideo, setActiveVideo] = useState<number | null>(null);
const [showDownloadModal, setShowDownloadModal] = useState(false);
const [isLoggedIn, setIsLoggedIn] = useState(false);
useEffect(() => {
const checkSession = async () => {
const api = new UsersApi();
const response = await api.GetSession();
if (response.success && response.data?.loggedIn) {
setIsLoggedIn(true);
}
};
checkSession();
}, []);
const onDownloadClick = (e: React.MouseEvent) => {
if (isLoggedIn) {
return;
}
setShowDownloadModal(true);
localStorage.setItem("artcraft_download_initiated", "true");
};
const features = [
{
icon: faMapMarkerAlt,
title: "Image to Location",
description:
"Placing virtual actors into physical environments establishes single-location consistency. You can film multiple shots within a room without having things disappear.",
src: "/videos/features/WorldLabs_Demo_2.webm",
},
{
icon: faCube,
title: "3D Image Compositing",
description:
"Use images (backdrops, foreground elements, props, etc.) in scenes with depth and blend them naturally together. Just a couple of images usually leads to great compositions.",
src: "/videos/features/Panel.webm",
},
{
icon: faLayerGroup,
title: "2D Image Compositing",
description:
"Use images, background removal, layers, and simple drawing tools to precisely compose a scene.",
src: "/videos/features/Editor.webm",
},
{
icon: faShapes,
title: "Image to 3D Mesh",
description:
"It's almost impossible to lay out complicated objects or block complicated scenes; turning images into 3D helps position elements exactingly and intentionally.",
src: "/videos/features/Make_3D.webm",
},
{
icon: faTools,
title: "Mixed Asset Crafting",
description:
"You can use image cutouts, worlds, and simple 3D meshes all together to precisely and intentionally lay out your scenes.",
src: "/videos/features/Mixed.webm",
},
{
icon: faUser,
title: "Character Posing",
description:
'You can dynamically pose your characters to achieve the precise character, scene, and camera blocking before calling "action".',
src: "/videos/features/Pose_Second_Version.webm",
},
{
icon: faEraser,
title: "Background Removal",
description:
"Instantly remove backgrounds from images to create assets for your scenes. Clean, precise, and ready for compositing.",
src: "/videos/features/Background.webm",
},
];
// Refs for GSAP animations
const mainRef = useRef<HTMLDivElement>(null);
const containerRef = useRef<HTMLDivElement>(null);
const featureRefs = useRef<(HTMLDivElement | null)[]>([]);
const cardRefs = useRef<(HTMLDivElement | null)[]>([]);
const mobileMediaRef = useRef<HTMLDivElement>(null);
const mobileDescRef = useRef<HTMLDivElement>(null);
// GSAP ScrollTrigger setup for page animations
useLayoutEffect(() => {
const mm = gsap.matchMedia();
const ctx = gsap.context(() => {
// Animate elements with data-animate attribute on scroll
// ONLY on non-mobile devices to ensure performance and prevent content loading issues
if (!isMobile) {
const elements = gsap.utils.toArray<HTMLElement>("[data-animate]");
gsap.set(elements, { autoAlpha: 0, y: 20 });
elements.forEach((el) => {
gsap.to(el, {
autoAlpha: 1,
y: 0,
duration: 0.8,
ease: "power1.out",
scrollTrigger: {
trigger: el,
start: "top 90%",
toggleActions: "play none none none",
},
});
});
}
// Feature section pinning and active state - Desktop Only (lg breakpoint)
mm.add("(min-width: 1024px)", () => {
ScrollTrigger.create({
trigger: ".right-column",
start: "top top",
endTrigger: ".left-column",
end: "bottom bottom",
pin: true,
pinSpacing: false,
invalidateOnRefresh: true,
});
featureRefs.current.forEach((el, index) => {
if (!el) return;
ScrollTrigger.create({
trigger: el,
start: "top 40%",
end: "bottom 40%",
onEnter: () => setActiveFeature(index),
onEnterBack: () => setActiveFeature(index),
});
});
});
}, mainRef);
return () => {
ctx.revert();
mm.revert();
};
}, []);
// GSAP animation for card stack (desktop feature images)
useEffect(() => {
cardRefs.current.forEach((card, index) => {
if (!card) return;
const isFuture = index > activeFeature;
const isPast = index < activeFeature;
gsap.to(card, {
y: isFuture ? "110%" : "0%",
scale: isPast ? 0.9 : 1,
opacity: isPast ? 0.4 : 1,
duration: 0.5,
ease: "power3.out",
});
});
}, [activeFeature]);
// GSAP animation for mobile media and description
useEffect(() => {
if (mobileMediaRef.current) {
gsap.fromTo(
mobileMediaRef.current,
{ opacity: 0 },
{ opacity: 1, duration: 0.4, ease: "power2.out" },
);
}
if (mobileDescRef.current) {
gsap.fromTo(
mobileDescRef.current,
{ opacity: 0, y: 10 },
{ opacity: 1, y: 0, duration: 0.3, ease: "power2.out" },
);
}
}, [activeFeature]);
return (
<div
ref={mainRef}
className="relative min-h-screen bg-[#101014] text-white overflow-x-hidden bg-dots"
>
<Seo
title="Seedance 2.0 in ArtCraft. AI Video Generation. Fast and Open Desktop App."
description="Seedance 2.0 is available now in ArtCraft. Generate jaw-dropping AI videos with the fastest open desktop app for artists."
/>
{/* Hero Section */}
<main className="relative mb-8 md:mb-16 pt-24 sm:pt-24 min-h-[400px] sm:min-h-[600px] md:min-h-[700px] flex items-center justify-center px-2 sm:px-4 md:px-0">
{/* Glowing Gradient Orb Background */}
<div
className="absolute inset-0 flex items-center justify-center pointer-events-none z-0 overflow-hidden"
data-animate
>
<div className="w-[900px] h-[900px] rounded-full bg-gradient-to-br from-blue-700 via-blue-500 to-[#00AABA] opacity-40 blur-[80px] md:blur-[120px] transform-gpu"></div>
</div>
<div className="relative z-10 px-2 sm:px-4 md:px-6 py-8 w-full flex flex-col items-center justify-center">
<div className="w-full max-w-[1200px] mx-auto text-center flex flex-col items-center">
{/* Main Heading */}
<h1
className="text-4xl sm:text-5xl md:text-6xl lg:text-7xl xl:text-8xl font-bold leading-tight mb-4 sm:mb-6 drop-shadow-[0_4px_32px_rgba(80,80,255,0.25)]"
data-animate
>
<span className="text-white">
Seedance 2.0
<br />
now in{" "}
<span className="relative after:absolute after:bottom-0 after:left-0 after:w-full after:h-[6px] md:after:h-[11px] after:bg-primary/80 after:mb-0 after:xl:mb-2">
ArtCraft
</span>
</span>
</h1>
{/* Subtitle */}
<p
className="text-base mt-4 sm:text-xl md:text-2xl lg:text-2xl text-white/70 mb-8 sm:mb-14 max-w-2xl mx-auto font-medium drop-shadow-[0_2px_12px_rgba(80,80,255,0.10)]"
data-animate
>
Generate jaw-dropping AI videos with Seedance 2.0 before
it&rsquo;s available anywhere else.
</p>
{/* CTA Buttons */}
<div
className="relative flex flex-col sm:flex-row items-center justify-center mb-10 sm:mb-16 w-full"
data-animate
>
<LandingActionButtons
onDownloadClick={onDownloadClick}
className="w-fit max-w-xs sm:max-w-none mx-auto z-10"
/>
<img
src="/images/buy-credits.png"
alt="Buy Credits"
draggable={false}
className="absolute left-[10%] -top-2 h-40 pointer-events-none select-none hidden md:block"
/>
<img
src="/images/try-download.png"
alt="Try Download"
draggable={false}
className="absolute right-[9.5%] -bottom-2 h-40 pointer-events-none select-none hidden md:block"
/>
</div>
{/* Vimeo Video Embed */}
<div
className="relative mx-auto mt-4 w-full max-w-[1200px]"
data-animate
>
<div
className="relative rounded-[20px] sm:rounded-[32px] overflow-hidden bg-white/10 backdrop-blur-md md:backdrop-blur-xl shadow-2xl p-2 sm:p-4 w-full mx-auto transition-transform duration-300 transform-gpu"
>
<div style={{ paddingTop: "56.25%" }} className="relative">
<iframe
src={HERO_VIMEO_URL}
className="absolute inset-0 w-full h-full rounded-2xl"
allow="autoplay; fullscreen; picture-in-picture"
allowFullScreen
title="Seedance in ArtCraft"
/>
</div>
</div>
</div>
</div>
</div>
</main>
<div className="relative z-10 py-12 md:py-24 px-4 sm:px-8 lg:px-12 max-w-[1400px] mx-auto overflow-visible">
{/* Gradient Orb for Section */}
<div className="absolute left-[-200px] top-[-100px] w-[600px] h-[600px] rounded-full bg-gradient-to-br from-[#00AABA] via-blue-500 to-blue-700 opacity-15 blur-[80px] md:blur-[120px] z-0 pointer-events-none transform-gpu" />
{/* Title Area */}
<div className="relative z-10 mb-6 md:-mb-12 min-[1980px]:-mb-48 pointer-events-none">
<div className="max-w-3xl mx-auto text-center" data-animate>
<h2 className="text-primary font-bold text-sm md:text-base mb-6 tracking-widest uppercase">
Advanced Crafting Features
</h2>
<h1 className="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-bold leading-[1.1] mb-8">
We're Pulling You <br />{" "}
<span className="text-white">Out of Prompting</span>
</h1>
<p className="text-lg md:text-xl text-white/60 leading-relaxed max-w-2xl mx-auto">
Text prompting is neat, but artists <em>crave control</em>.
</p>
<br />
<p className="text-lg md:text-xl text-white/60 leading-relaxed max-w-2xl mx-auto">
Before you type "rotate arm thirty degrees", try ArtCraft and let
our advanced toolset help you achieve consistency and
repeatability.
</p>
<br />
<p className="text-lg md:text-xl text-white/60 leading-relaxed max-w-2xl mx-auto">
ArtCraft is the control that mere words cannot buy.
</p>
</div>
</div>
<div className="relative">
{/* Mobile Layout */}
<div className="lg:hidden flex flex-col gap-6">
{/* Mobile Navigation (Tabs) */}
<div className="w-full overflow-x-auto pb-4 no-scrollbar flex gap-3 snap-x px-1">
{features.map((feature, index) => (
<button
key={index}
onClick={() => setActiveFeature(index)}
className={`snap-center shrink-0 px-5 py-2.5 rounded-full text-sm font-bold border transition-all duration-300 whitespace-nowrap ${
activeFeature === index
? "bg-primary border-primary text-white shadow-lg shadow-primary/20"
: "bg-white/5 border-white/10 text-white/60 hover:bg-white/10"
}`}
>
{feature.title}
</button>
))}
</div>
{/* Mobile Media Preview */}
<div className="relative aspect-[4/3] w-full bg-[#050505] rounded-xl overflow-hidden shadow-2xl border border-white/10 ring-1 ring-white/5">
<div
key={activeFeature}
ref={mobileMediaRef}
className="absolute inset-0"
>
<video
src={features[activeFeature].src}
className="w-full h-full object-cover select-none"
autoPlay
loop
muted
playsInline
/>
<div className="absolute inset-0 pointer-events-none bg-gradient-to-t from-black/60 via-transparent to-transparent opacity-60" />
</div>
</div>
{/* Mobile Description */}
<div
key={activeFeature}
ref={mobileDescRef}
className="bg-white/5 border border-white/10 rounded-2xl p-5"
>
<h3 className="text-lg font-bold text-white mb-2">
{features[activeFeature].title}
</h3>
<p className="text-white/70 text-sm leading-relaxed">
{features[activeFeature].description}
</p>
</div>
</div>
{/* Desktop Sticky Scroll Layout */}
{!isMobile && (
<div
className="hidden lg:flex flex-row relative items-start"
ref={containerRef}
>
{/* Left Column: Scrolling Text */}
<div className="w-[40%] flex flex-col relative z-20 left-column py-[10vh]">
{features.map((feature, index) => (
<div
key={index}
ref={(el) => {
featureRefs.current[index] = el;
}}
className="min-h-[80vh] flex flex-col justify-center pr-8 xl:pr-16"
>
<div className="max-w-lg">
<div
className={`w-12 h-12 mb-6 rounded-2xl flex items-center justify-center text-2xl transition-all duration-500 ${
activeFeature === index
? "bg-primary text-white shadow-lg shadow-primary/30 scale-110"
: "bg-white/10 text-white/50"
}`}
>
<FontAwesomeIcon icon={feature.icon} />
</div>
<h3
className={`text-3xl xl:text-4xl font-bold mb-6 transition-all duration-500 ${
activeFeature === index
? "text-white"
: "text-white/40"
}`}
>
{feature.title}
</h3>
<p
className={`text-xl leading-relaxed transition-all duration-500 ${
activeFeature === index
? "text-white/80"
: "text-white/30"
}`}
>
{feature.description}
</p>
</div>
</div>
))}
</div>
{/* Right Column: Sticky Image */}
<div className="w-[60%] h-screen flex items-center justify-center pl-4 py-8 z-10 right-column">
<div className="relative w-full aspect-[4/3] max-h-[80vh] rounded-[32px] overflow-hidden shadow-2xl border-[4px] border-white/5 bg-[#050505]">
{features.map((feature, index) => (
<div
key={index}
ref={(el) => {
cardRefs.current[index] = el;
}}
className="absolute inset-0 w-full h-full bg-[#050505] shadow-2xl origin-bottom"
style={{
zIndex: index,
transform:
index === 0 ? "translateY(0%)" : "translateY(110%)",
}}
>
<video
src={feature.src}
className="w-full h-full object-cover"
autoPlay
loop
muted
playsInline
/>
{/* Gradient overlay */}
<div className="absolute inset-0 bg-gradient-to-t from-black/40 via-transparent to-transparent pointer-events-none" />
</div>
))}
{/* Decorative Elements */}
<div className="absolute top-4 right-4 px-4 py-2 bg-black/40 backdrop-blur-md rounded-full border border-white/10 z-20">
<span className="text-white/80 text-sm font-medium tracking-wide">
{activeFeature + 1} / {features.length}
</span>
</div>
</div>
</div>
</div>
)}
</div>
</div>
<OwnershipComparison />
<div className="relative flex overflow-visible xl:items-center xl:pt-0 mb-4 md:mb-12 px-2 sm:px-4 md:px-0">
{/* Gradient Orb for Section */}
<div className="absolute left-[-200px] top-[-100px] w-[600px] h-[600px] rounded-full bg-gradient-to-br from-[#00AABA] via-blue-500 to-blue-700 opacity-15 blur-[80px] md:blur-[120px] z-0 pointer-events-none transform-gpu" />
<div
className="w-full flex flex-col items-center justify-center text-center pt-16 sm:pt-24 md:pt-32 px-2 sm:px-6 md:px-10"
data-animate
>
<div className="relative">
<h1 className="relative mb-4 sm:mb-6 md:mb-10 font-bold text-3xl sm:text-4xl md:text-[3rem] lg:text-[4rem] xl:text-[4.5rem] !leading-tight text-shadow-lg">
<span
className="text-primary"
style={{ textShadow: "0 0 15px var(--color-primary)" }}
>
Five Reasons{" "}
</span>
Why
<br />
ArtCraft is the
<span
className="text-primary"
style={{ textShadow: "0 0 15px var(--color-primary)" }}
>
{" "}
Best Tool
</span>
</h1>
</div>
</div>
</div>
{/* Bento Box Grid Section */}
<div className="overflow-visible pb-10 sm:pb-20 md:pb-28 lg:pb-32 relative px-4">
{/* Gradient Orbs for Section */}
<div className="absolute right-[-150px] top-[-100px] w-[500px] h-[500px] rounded-full bg-gradient-to-br from-[#00AABA] via-blue-500 to-blue-700 opacity-10 blur-[80px] md:blur-[110px] z-0 pointer-events-none transform-gpu" />
<div className="mx-auto max-w-[88rem] md:px-6 lg:px-8" data-animate>
{/* Bento Grid Container */}
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-12 gap-6 sm:gap-8">
{/* Reason #1 - Large Box */}
<div className="xl:col-span-6 bg-[#28282C] rounded-2xl sm:rounded-3xl p-6 lg:p-8 shadow-2xl transition-all duration-300 group">
<div className="flex xl:flex-col gap-4 lg:gap-8 h-full flex-col-reverse">
<div className="grow h-40">
<img
src="/images/2d-3d.png"
alt="2D and 3D"
className="w-full h-full object-cover rounded-2xl"
/>
</div>
<div className="flex flex-col justify-between">
<div>
<h3 className="font-bold text-xl sm:text-2xl lg:text-3xl mb-3 sm:mb-4 leading-tight">
Text Prompting Sucks
</h3>
<p className="text-white/80 text-sm sm:text-base lg:text-lg leading-relaxed">
<span className="text-primary-400 font-semibold">
Create images and videos with our easy-to-use AI tool.
</span>{" "}
Draw on a canvas or work in a 3D space as if you're
playing a video game.
</p>
</div>
</div>
</div>
</div>
{/* Reason #2 - Medium Box */}
<div className="xl:col-span-6 bg-[#28282C] rounded-2xl sm:rounded-3xl p-6 lg:p-8 pb-0 lg:pb-0 shadow-2xl transition-all duration-300 group">
<div className="relative flex flex-col h-full">
<h3 className="font-bold text-xl sm:text-2xl lg:text-3xl mb-3 sm:mb-4 leading-tight ">
Desktop App
</h3>
<p className="text-white/80 text-sm sm:text-base mb-4 sm:mb-6 lg:text-lg leading-relaxed">
<span className="text-primary-400 font-semibold">
No more hunting for the hundredth tab.
</span>{" "}
Works on Windows, Mac, and soon Linux and Tablets. First class
experience for real artists.
</p>
<div className="h-20 md:h-24 lg:h-36 xl:h-36 bg-white/[3%] border-[5px] border-white/[2%] rounded-t-2xl relative mt-12 lg:mt-16 xl:mt-24 select-none">
<div className="absolute -top-20 left-1/2 -translate-x-1/2 flex gap-9 items-center justify-center drop-shadow-2xl z-20 scale-50 lg:scale-75 xl:scale-100">
<img
src="/images/windows-logo.png"
alt="Windows Logo"
draggable={false}
className="h-32 rotate-6"
/>
<img
src="/images/apple-logo.png"
alt="Windows Logo"
draggable={false}
className="h-36 -rotate-6"
/>
<img
src="/images/linux-logo.png"
alt="Windows Logo"
draggable={false}
className="h-36 rotate-6"
/>
</div>
</div>
<div className="absolute left-0 bottom-0 w-full h-28 bg-gradient-to-t from-[#28282C] to-transparent z-10 pointer-events-none" />
</div>
</div>
{/* Reason #3 - Medium Box */}
<div className="xl:col-span-4 bg-[#28282C] rounded-2xl sm:rounded-3xl p-6 lg:p-8 shadow-2xl transition-all duration-300 group">
<div className="flex flex-col h-full">
<h3 className="font-bold text-xl sm:text-2xl lg:text-3xl mb-3 sm:mb-4 leading-tight">
It's Open Source
</h3>
<p className="text-white/80 text-sm sm:text-base lg:text-lg mb-4 sm:mb-6 leading-relaxed flex-1">
Our desktop app's code and infrastructure are all{" "}
<a
href="https://github.com/storytold/artcraft"
target="_blank"
rel="noopener noreferrer"
className="text-primary-400 font-semibold hover:text-primary-300 underline underline-offset-2 transition-colors"
>
open source on GitHub.
</a>{" "}
Join us and contribute!
</p>
<div className="flex justify-center items-center h-full p-4 lg:p-6 select-none">
<img
src="/images/github-logo.png"
alt="GitHub Logo"
className="h-20 md:h-32 lg:h-36"
draggable={false}
/>
</div>
</div>
</div>
{/* Reason #4 - Large Box */}
<div className="xl:col-span-8 bg-[#28282C] rounded-2xl sm:rounded-3xl shadow-2xl transition-all duration-300 group overflow-hidden">
<div className="lg:flex-1 flex flex-col justify-between">
<div className="p-6 lg:p-8">
<h3 className="font-bold text-xl sm:text-2xl lg:text-3xl mb-3 sm:mb-4 leading-tight">
Use Every Model
</h3>
<p className="text-white/80 text-sm sm:text-base lg:text-lg leading-relaxed">
You'll be able to use{" "}
<span className="text-primary-400 font-semibold">
EVERY image and video model
</span>{" "}
all in one place. Log in with your existing subscriptions.
</p>
</div>
<ModelBadgeGrid
highlight="gpt-image-1"
rowOffsets={[-70, -90, -160]}
className="mt-3"
/>
</div>
</div>
{/* Reason #5 - Full Width Box */}
<div className="xl:col-span-12 md:col-span-2 bg-[#28282C] rounded-2xl sm:rounded-3xl p-6 lg:p-8 shadow-2xl transition-all duration-300 group">
<div className="flex flex-col lg:flex-row gap-4 lg:gap-8 items-center">
<div className="lg:flex-1">
<h3 className="font-bold text-xl sm:text-2xl lg:text-3xl mb-3 sm:mb-4 leading-tight">
Created by Artists and Filmmakers
</h3>
<p className="text-white/80 text-sm sm:text-base lg:text-lg leading-relaxed">
<span className="text-primary-400 font-semibold">
The other leading platforms were created by the Google ad
team, crypto bros, and other non-artists.
</span>{" "}
<br />
Not us. We're one of you.
</p>
</div>
<div className="flex justify-center items-center h-24 lg:h-28">
<div className="w-16 h-16 lg:w-20 lg:h-20 bg-pink-900 rounded-full flex items-center justify-center border-2 border-pink-600 shadow-lg z-10">
<FontAwesomeIcon
icon={faFilm}
className="text-white text-xl lg:text-2xl"
/>
</div>
<div className="w-20 h-20 lg:w-24 lg:h-24 bg-emerald-600 rounded-full flex items-center justify-center border-2 border-emerald-400 shadow-lg -ml-2 z-30">
<FontAwesomeIcon
icon={faPaintBrush}
className="text-white text-2xl lg:text-3xl"
/>
</div>
<div className="w-16 h-16 lg:w-20 lg:h-20 bg-purple-900 rounded-full flex items-center justify-center border-2 border-purple-600 shadow-lg -ml-2 z-20">
<FontAwesomeIcon
icon={faCamera}
className="text-white text-xl lg:text-2xl"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div className="relative z-10 mx-auto w-full max-w-screen py-10 sm:py-20 md:py-32 sm:px-8 lg:px-32 overflow-visible px-4">
{/* Gradient Orb for Section */}
<div className="absolute left-[-250px] top-[-150px] w-[700px] h-[700px] rounded-full bg-gradient-to-br from-[#00AABA] via-blue-500 to-blue-700 opacity-[0.07] blur-[100px] md:blur-[150px] z-0 pointer-events-none transform-gpu" />
{/* Videos Section */}
<div className="space-y-12" data-animate>
<div className="text-center">
<h1 className="md:mb-8 text-3xl sm:text-4xl md:text-6xl font-bold mb-4">
Made using{" "}
<span className="relative after:absolute after:bottom-0 after:left-0 after:w-full after:h-[5px] md:after:h-[12px] after:bg-primary/60 after:mb-1">
ArtCraft
</span>
</h1>
<p className="md:text-xl text-lg text-white/80 max-w-2xl mx-auto">
Check out the videos below!
</p>
</div>
<div className="grid gap-6 sm:gap-8 xl:grid-cols-3">
{videos.map((video, index) => (
<div
key={index}
className="group relative rounded-2xl bg-white/10 backdrop-blur-md p-2 sm:p-4 transition-all duration-300 hover:bg-white/20 hover:scale-[1.02] hover:shadow-2xl hover:shadow-primary/20"
>
<div
className="aspect-video overflow-hidden rounded-xl shadow-lg w-full relative group-hover:cursor-pointer"
onClick={() => setActiveVideo(index)}
>
{activeVideo === index ? (
<iframe
width="100%"
height="100%"
src={video.src + "&autoplay=1"}
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
className="w-full h-full min-h-[180px]"
style={{ minHeight: "180px" }}
/>
) : (
<div className="w-full h-full bg-black/50 flex items-center justify-center relative">
{/* Placeholder Thumbnail - In a real app we'd fetch the YT thumb */}
<div className="absolute inset-0 bg-[#28282C]">
<img
src={`https://img.youtube.com/vi/${video.src.split("/").pop()?.split("?")[0]}/maxresdefault.jpg`}
alt="Video Thumbnail"
className="w-full h-full object-cover opacity-60 group-hover:opacity-80 transition-opacity duration-300"
/>
</div>
<div className="w-16 h-16 rounded-full bg-white/10 backdrop-blur-md flex items-center justify-center border border-white/20 group-hover:scale-110 transition-transform duration-300 z-10">
<FontAwesomeIcon
icon={faFilm}
className="text-white text-2xl"
/>
</div>
</div>
)}
</div>
</div>
))}
</div>
</div>
</div>
<div className="relative z-10 mx-auto w-full max-w-[1400px] pt-10 sm:pt-20 md:pt-32 pb-12 sm:pb-24 md:pb-40 lg:pb-56 sm:px-8 overflow-visible px-4">
{/* Gradient Orb for Section */}
<div className="absolute right-[-300px] bottom-[-100px] w-[800px] h-[800px] rounded-full bg-gradient-to-br from-blue-700 via-[#00AABA] to-pink-500 opacity-10 blur-[160px] z-0 pointer-events-none" />
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-12">
{/* Discord CTA Section */}
<div
className="flex flex-col items-center justify-center text-center p-8 sm:p-12 lg:p-16 rounded-[24px] sm:rounded-[40px] bg-[#1a1b36] backdrop-blur-lg border-[3px] sm:border-[6px] border-[#3f415c] shadow-2xl"
data-animate
>
<h2 className="relative mb-4 sm:mb-6 font-bold text-2xl sm:text-3xl lg:text-4xl max-w-lg !leading-tight text-white">
Join the Discord
</h2>
<p className="text-base sm:text-lg text-[#aab3c9] mb-6 sm:mb-8 max-w-md leading-relaxed">
Connect with other creators, share your work, get feedback, and
stay updated.
</p>
<DiscordButton />
</div>
{/* GitHub CTA Section */}
<div
className="flex flex-col items-center justify-center text-center p-8 sm:p-12 rounded-[24px] sm:rounded-[40px] bg-[#161b22] backdrop-blur-lg border-[3px] sm:border-[6px] border-[#30363d] shadow-2xl"
data-animate
>
<h2 className="relative mb-4 sm:mb-6 font-bold text-2xl sm:text-3xl lg:text-4xl max-w-lg !leading-tight text-white">
We're Open Source
</h2>
<p className="text-base sm:text-lg text-[#8b949e] mb-6 sm:mb-8 max-w-md leading-relaxed">
Help us build the future of creative tools. Contribute code,
report bugs, or just star the repo.
</p>
<Button
className="text-md px-6 py-3 font-semibold rounded-xl shadow-lg gap-3 bg-white text-black hover:bg-gray-200"
as="link"
href="https://github.com/storytold/artcraft"
target="_blank"
rel="noopener noreferrer"
>
<FontAwesomeIcon icon={faGithub} className="text-xl" />
Star on GitHub
</Button>
</div>
{/* Download CTA Section - New */}
<div
className="flex flex-col items-center justify-center text-center p-8 sm:p-12 lg:col-span-2 rounded-[24px] sm:rounded-[40px] bg-gradient-to-br from-primary/30 to-primary/50 backdrop-blur-lg border-[3px] sm:border-[6px] border-primary/70 shadow-2xl shadow-primary/30 overflow-hidden relative"
data-animate
>
<div className="absolute inset-0 bg-gradient-to-br from-primary/20 via-transparent to-purple-500/20 opacity-30 pointer-events-none" />
<div className="absolute top-0 left-0 w-full h-[1px] bg-gradient-to-r from-transparent via-white/20 to-transparent" />
<h2 className="relative mb-4 sm:mb-6 font-bold text-3xl sm:text-4xl lg:text-5xl max-w-2xl !leading-tight text-white z-10">
Ready to Create?
</h2>
<p className="text-base sm:text-l md:text-xl text-white/90 mb-8 sm:mb-10 max-w-xl leading-relaxed z-10">
Join thousands of artists and filmmakers using ArtCraft to bring
their vision to life.
</p>
<div className="relative z-10 w-full flex flex-col items-center">
<LandingActionButtons onDownloadClick={onDownloadClick} />
<div className="mt-8 text-sm text-white/80 font-medium">
Free to use.
</div>
</div>
</div>
</div>
</div>
<DownloadModal
isOpen={showDownloadModal}
onClose={() => setShowDownloadModal(false)}
/>
<Footer />
</div>
);
};
export default LandingSD2;
@@ -31,7 +31,7 @@ export const SUBSCRIPTION_PLANS: SubscriptionPlanDetails[] = [
{ text: "~50 GPT-Image-1.5 images", included: true },
{ text: "~8 minutes Kling video", included: true },
{
text: "~12 Seedance 2.0 videos",
text: "Seedance 2.0 videos",
included: true,
},
{ text: "You Own ArtCraft Forever", included: true },
@@ -51,7 +51,7 @@ export const SUBSCRIPTION_PLANS: SubscriptionPlanDetails[] = [
{ text: "~300 Nano Banana Pro 4K images", included: true },
{ text: "~300 GPT-Image-1.5 images", included: true },
{ text: "~15 minutes Kling video", included: true },
{ text: "~46 Seedance 2.0 videos", included: true },
{ text: "Seedance 2.0 videos", included: true },
{ text: "You Own ArtCraft Forever", included: true },
],
colorScheme: "purple" as const,
@@ -69,7 +69,7 @@ export const SUBSCRIPTION_PLANS: SubscriptionPlanDetails[] = [
{ text: "~10,000 Nano Banana Pro 4K images", included: true },
{ text: "~10,000 GPT-Image-1.5 images", included: true },
{ text: "~30 minutes Kling video", included: true },
{ text: "~82 Seedance 2.0 videos", included: true },
{ text: "Seedance 2.0 videos", included: true },
{ text: "You Own ArtCraft Forever", included: true },
],
colorScheme: "orange" as const,