From 35fdd1102018bf7271588ca36079295dd4a1eb75 Mon Sep 17 00:00:00 2001 From: BFlat Date: Thu, 9 Jul 2026 09:38:40 +0700 Subject: [PATCH] landing restyle version 1 --- frontend/apps/artcraft-website/index.html | 5 + .../apps/artcraft-website/src/app/app.tsx | 8 +- .../pages/landing4/components/brut-footer.tsx | 104 +++++++ .../pages/landing4/components/brut-navbar.tsx | 141 ++++++++++ .../landing4/components/section-community.tsx | 58 ++++ .../landing4/components/section-features.tsx | 127 +++++++++ .../landing4/components/section-final-cta.tsx | 61 ++++ .../landing4/components/section-hero.tsx | 121 ++++++++ .../landing4/components/section-made-with.tsx | 50 ++++ .../landing4/components/section-manifesto.tsx | 45 +++ .../components/section-model-wall.tsx | 61 ++++ .../landing4/components/section-ownership.tsx | 75 +++++ .../src/pages/landing4/components/ui.tsx | 163 +++++++++++ .../src/pages/landing4/data.ts | 165 +++++++++++ .../src/pages/landing4/index.ts | 1 + .../src/pages/landing4/landing4-animations.ts | 262 ++++++++++++++++++ .../src/pages/landing4/landing4.css | 104 +++++++ .../src/pages/landing4/landing4.tsx | 106 +++++++ .../apps/artcraft-website/tailwind.config.js | 21 ++ 19 files changed, 1677 insertions(+), 1 deletion(-) create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/components/brut-footer.tsx create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/components/brut-navbar.tsx create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/components/section-community.tsx create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/components/section-features.tsx create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/components/section-final-cta.tsx create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/components/section-hero.tsx create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/components/section-made-with.tsx create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/components/section-manifesto.tsx create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/components/section-model-wall.tsx create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/components/section-ownership.tsx create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/components/ui.tsx create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/data.ts create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/index.ts create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/landing4-animations.ts create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/landing4.css create mode 100644 frontend/apps/artcraft-website/src/pages/landing4/landing4.tsx diff --git a/frontend/apps/artcraft-website/index.html b/frontend/apps/artcraft-website/index.html index d248e26af6..a11a43a312 100644 --- a/frontend/apps/artcraft-website/index.html +++ b/frontend/apps/artcraft-website/index.html @@ -37,6 +37,11 @@ href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&family=Instrument+Serif:ital@0;1&display=swap" rel="stylesheet" /> + +
diff --git a/frontend/apps/artcraft-website/src/app/app.tsx b/frontend/apps/artcraft-website/src/app/app.tsx index 7a301b7e5e..d0a6aca1c7 100644 --- a/frontend/apps/artcraft-website/src/app/app.tsx +++ b/frontend/apps/artcraft-website/src/app/app.tsx @@ -17,6 +17,7 @@ import CreateVideo from "../pages/create-video"; import CreateVFX from "../pages/create-vfx"; //import Landing2 from "../pages/landing2"; import Landing3 from "../pages/landing3"; +import Landing4 from "../pages/landing4"; import LandingSD2 from "../pages/landing-sd2"; import LandingSD25 from "../pages/landing-sd25"; import TutorialsPage from "../pages/tutorials"; @@ -59,14 +60,19 @@ function appOrWebapp(localElement: ReactNode, webappPath: string): ReactNode { } export function App() { + // Landing4 renders its own scoped navbar/footer; hide the global chrome. + const { pathname } = useLocation(); + const hideGlobalChrome = pathname === "/landing4"; + return (
- + {!hideGlobalChrome && } } /> } /> + } /> } /> } /> } /> diff --git a/frontend/apps/artcraft-website/src/pages/landing4/components/brut-footer.tsx b/frontend/apps/artcraft-website/src/pages/landing4/components/brut-footer.tsx new file mode 100644 index 0000000000..88060082c3 --- /dev/null +++ b/frontend/apps/artcraft-website/src/pages/landing4/components/brut-footer.tsx @@ -0,0 +1,104 @@ +import { Link } from "react-router-dom"; +import { SOCIAL_LINKS, SUPPORT_EMAIL } from "../../../config/links"; +import { MonoLabel } from "./ui"; + +const SITEMAP: ReadonlyArray<{ label: string; to: string }> = [ + { label: "Home", to: "/" }, + { label: "Download", to: "/download" }, + { label: "Pricing", to: "/pricing" }, + { label: "Tutorials", to: "/tutorials" }, + { label: "FAQ", to: "/faq" }, + { label: "News", to: "/news" }, + { label: "Press Kit", to: "/press-kit" }, + { label: "Support", to: "/support" }, +]; + +const SOCIALS: ReadonlyArray<{ label: string; href: string }> = [ + { label: "GitHub", href: SOCIAL_LINKS.GITHUB }, + { label: "Discord", href: SOCIAL_LINKS.DISCORD }, + { label: "YouTube", href: SOCIAL_LINKS.YOUTUBE }, + { label: "Instagram", href: SOCIAL_LINKS.INSTAGRAM }, + { label: "TikTok", href: SOCIAL_LINKS.TIKTOK }, + { label: "Reddit", href: SOCIAL_LINKS.REDDIT }, +]; + +// Landing4-only footer. Dark chapter: mono column grid over a hairline, then +// a giant clipped wordmark bleeding off the bottom edge. +export const BrutFooter = () => ( +
+
+
+
+ SITEMAP +
    + {SITEMAP.map((item) => ( +
  • + + {item.label} + +
  • + ))} +
+
+
+ SOCIAL + +
+
+ CONTACT + +
+
+ COLOPHON + + SET IN BRICOLAGE GROTESQUE + + + + SPACE MONO — {new Date().getFullYear()} + +
+
+ +
+ + © {new Date().getFullYear()} ArtCraft. All rights reserved. + + MADE BY ARTISTS +
+
+ + {/* Giant clipped wordmark */} +
+
+
+ ArtCraft® +
+
+
+
+); diff --git a/frontend/apps/artcraft-website/src/pages/landing4/components/brut-navbar.tsx b/frontend/apps/artcraft-website/src/pages/landing4/components/brut-navbar.tsx new file mode 100644 index 0000000000..8e81b516d8 --- /dev/null +++ b/frontend/apps/artcraft-website/src/pages/landing4/components/brut-navbar.tsx @@ -0,0 +1,141 @@ +import { useEffect, useState } from "react"; +import { Link } from "react-router-dom"; +import { SOCIAL_LINKS } from "../../../config/links"; +import { MonoLabel } from "./ui"; + +const NAV_LINKS: ReadonlyArray<{ + label: string; + index: string; + to?: string; + href?: string; +}> = [ + { label: "PRICING", index: "01", to: "/pricing" }, + { label: "TUTORIALS", index: "02", to: "/tutorials" }, + { label: "NEWS", index: "03", to: "/news" }, + { label: "GITHUB ↗", index: "04", href: SOCIAL_LINKS.GITHUB }, +]; + +// Landing4-only fixed navbar. Chapter-aware: text and hairlines read the +// --l4-* vars so the bar recolors as the page scrubs between ink and paper. +// A backdrop tinted with the current --l4-bg keeps links legible over content. +// Mobile: a full-screen ink overlay with numbered index-style rows. +export const BrutNavbar = ({ + onDownloadClick, +}: { + onDownloadClick: () => void; +}) => { + const [menuOpen, setMenuOpen] = useState(false); + + // Lock page scroll behind the full-screen menu. + useEffect(() => { + if (!menuOpen) return; + const previous = document.body.style.overflow; + document.body.style.overflow = "hidden"; + return () => { + document.body.style.overflow = previous; + }; + }, [menuOpen]); + + return ( + <> +
+
+ + ArtCraft® + + + + +
+ + +
+
+
+ + {/* Mobile full-screen index */} + {menuOpen && ( +
+ + + ARTCRAFT — IMG / VID / 3D — OPEN SOURCE + +
+ )} + + ); +}; diff --git a/frontend/apps/artcraft-website/src/pages/landing4/components/section-community.tsx b/frontend/apps/artcraft-website/src/pages/landing4/components/section-community.tsx new file mode 100644 index 0000000000..4bd6993dcd --- /dev/null +++ b/frontend/apps/artcraft-website/src/pages/landing4/components/section-community.tsx @@ -0,0 +1,58 @@ +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faDiscord, faGithub } from "@fortawesome/free-brands-svg-icons"; +import { SOCIAL_LINKS } from "../../../config/links"; +import { LineMaskHeading, MonoLabel, SectionHeader } from "./ui"; + +// /07 — Community. Back to the dark chapter (the boundary sentinel before +// this section scrubs the root vars). Two 50/50 hairline cells; the whole +// cell is the anchor and inverts to flare on hover. +export const SectionCommunity = () => ( + <> + {/* Chapter boundary: paper → dark */} +
+
+ +
+ BUILT IN, <>THE OPEN.]} + /> +
+ + +
+ +); diff --git a/frontend/apps/artcraft-website/src/pages/landing4/components/section-features.tsx b/frontend/apps/artcraft-website/src/pages/landing4/components/section-features.tsx new file mode 100644 index 0000000000..1f5f90a895 --- /dev/null +++ b/frontend/apps/artcraft-website/src/pages/landing4/components/section-features.tsx @@ -0,0 +1,127 @@ +import { useEffect, useRef, useState } from "react"; +import { FEATURES } from "../data"; +import { + HairlineFrame, + LazyAutoplayVideo, + LineMaskHeading, + MonoLabel, + SectionHeader, +} from "./ui"; + +// /03 — Features. Paper chapter. Desktop: an index list on the left with a +// sticky hairline-framed preview on the right; an IntersectionObserver with a +// center-band root margin marks the row crossing mid-viewport as active, +// which drives the preview video swap. Mobile: each row embeds its own video +// and the observer never activates (rows are hidden from it via lg gating in +// markup, and the sticky preview is display:none). +export const SectionFeatures = () => { + const [activeIndex, setActiveIndex] = useState(0); + const listRef = useRef(null); + const active = FEATURES[activeIndex]; + + useEffect(() => { + const list = listRef.current; + if (!list) return; + const rows = Array.from( + list.querySelectorAll("[data-l4-feature-row]"), + ); + // Center band: a row becomes active while it overlaps the middle 20% of + // the viewport. Cheap, and unlike per-row ScrollTriggers it needs no + // cleanup coordination with the GSAP context. + const observer = new IntersectionObserver( + (entries) => { + for (const entry of entries) { + if (entry.isIntersecting) { + const index = Number( + (entry.target as HTMLElement).dataset.l4FeatureRow, + ); + if (!Number.isNaN(index)) setActiveIndex(index); + } + } + }, + { rootMargin: "-40% 0px -40% 0px" }, + ); + rows.forEach((row) => observer.observe(row)); + return () => observer.disconnect(); + }, []); + + return ( +
+ +
+ THE TOOLKIT]} + /> +
+ +
+ {/* Index list */} +
    + {FEATURES.map((feature, i) => ( +
  1. +
    + + {String(i + 1).padStart(2, "0")} + +
    + {feature.label} +

    + {feature.title} +

    +

    + {feature.description} +

    +
    + + + + +
    + {/* Mobile-only inline video */} +
    + + + +
    +
  2. + ))} +
+ + {/* Sticky preview (desktop) */} +
+
+ +
+ +
+
+
+
+
+
+ ); +}; diff --git a/frontend/apps/artcraft-website/src/pages/landing4/components/section-final-cta.tsx b/frontend/apps/artcraft-website/src/pages/landing4/components/section-final-cta.tsx new file mode 100644 index 0000000000..c8b9483e22 --- /dev/null +++ b/frontend/apps/artcraft-website/src/pages/landing4/components/section-final-cta.tsx @@ -0,0 +1,61 @@ +import { Link } from "react-router-dom"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { + faApple, + faWindows, + faLinux, +} from "@fortawesome/free-brands-svg-icons"; +import { LineMaskHeading, MonoLabel } from "./ui"; + +// /08 — Final CTA. Dark chapter, near-full-viewport, giant type with the last +// line clipped at the section edge. +export const SectionFinalCta = ({ + onDownloadClick, +}: { + onDownloadClick: () => void; +}) => ( +
+
+
+ /08 — DOWNLOAD + + V2.X — PUBLIC BUILD — {new Date().getFullYear()} + +
+ +
+ OWN YOUR, + TOOLS., + ]} + /> + +
+ + + Or use on Web → + +
+ + + +
+
+
+
+
+); diff --git a/frontend/apps/artcraft-website/src/pages/landing4/components/section-hero.tsx b/frontend/apps/artcraft-website/src/pages/landing4/components/section-hero.tsx new file mode 100644 index 0000000000..63385aae12 --- /dev/null +++ b/frontend/apps/artcraft-website/src/pages/landing4/components/section-hero.tsx @@ -0,0 +1,121 @@ +import { Link } from "react-router-dom"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { + faApple, + faWindows, + faLinux, +} from "@fortawesome/free-brands-svg-icons"; +import { HairlineFrame, LineMaskHeading, MonoLabel, PlusCorners } from "./ui"; + +// /01 — Hero. Dark chapter. Swiss grid with visible column rules, stacked +// oversized display type, mono metadata at the corners, and a hairline-framed +// canvas video in the right column. +export const SectionHero = ({ + onDownloadClick, +}: { + onDownloadClick: () => void; +}) => ( +
+ {/* Vertical gridlines (desktop only) */} +
+ {[25, 50, 75].map((left) => ( + + ))} +
+ +
+ {/* Top metadata row */} +
+ EST. 2024 — OPEN SOURCE + + IMG / VID / 3D + + N 37°46′ — W 122°25′ +
+ + {/* Headline */} +
+ CONTROLLABLE, + <> + AI FOR + , + ARTISTS, + ]} + /> +

+ ArtCraft is an open desktop app for AI image, video, and 3D. Every + model, one canvas, zero prompt-wrestling. +

+ + {/* CTAs */} +
+ + + Use on Web + + + MAC OS — WINDOWS — LINUX + +
+
+ + {/* Bottom row: figure video right, mono coordinates left */} +
+
+ ARTCRAFT — DESKTOP + WEB + V2.X — PUBLIC BUILD +
+ + + +
+
+
+ + + +
+
+
+
+); diff --git a/frontend/apps/artcraft-website/src/pages/landing4/components/section-made-with.tsx b/frontend/apps/artcraft-website/src/pages/landing4/components/section-made-with.tsx new file mode 100644 index 0000000000..8dd489b02f --- /dev/null +++ b/frontend/apps/artcraft-website/src/pages/landing4/components/section-made-with.tsx @@ -0,0 +1,50 @@ +import { MADE_WITH_VIDEOS } from "../data"; +import { HairlineFrame, LineMaskHeading, SectionHeader } from "./ui"; + +// /06 — Output. Paper chapter. Asymmetric editorial grid: one large frame plus +// two stacked small frames, all lazy YouTube embeds with mono figure captions. +export const SectionMadeWith = () => { + const [featureFilm, ...smallFilms] = MADE_WITH_VIDEOS; + return ( +
+ +
+ MADE WITH, <>ARTCRAFT]} + /> +
+ +
+
+ +