diff options
| author | 2023-04-22 19:52:26 +0800 | |
|---|---|---|
| committer | 2023-04-22 19:52:26 +0800 | |
| commit | 4838df315931bb883f704ec3e1abe2685f296cdf (patch) | |
| tree | 57a8550c4cd5338f1126364bb518c6cde8d96e7d /docs/components/pages/landing | |
| parent | db74ade0234a40c2120ad5f2a41bee50ce13de02 (diff) | |
| download | HydroRoll-4838df315931bb883f704ec3e1abe2685f296cdf.tar.gz HydroRoll-4838df315931bb883f704ec3e1abe2685f296cdf.zip | |
😀
Diffstat (limited to 'docs/components/pages/landing')
| -rw-r--r-- | docs/components/pages/landing/TurboHeroBackground.tsx | 33 | ||||
| -rw-r--r-- | docs/components/pages/landing/Turbopack.tsx | 27 | ||||
| -rw-r--r-- | docs/components/pages/landing/Turborepo.tsx | 27 | ||||
| -rw-r--r-- | docs/components/pages/landing/index.module.css | 184 | ||||
| -rw-r--r-- | docs/components/pages/landing/index.tsx | 199 | ||||
| -rw-r--r-- | docs/components/pages/landing/turbohero-background.module.css | 108 |
6 files changed, 578 insertions, 0 deletions
diff --git a/docs/components/pages/landing/TurboHeroBackground.tsx b/docs/components/pages/landing/TurboHeroBackground.tsx new file mode 100644 index 0000000..dffa5b6 --- /dev/null +++ b/docs/components/pages/landing/TurboHeroBackground.tsx @@ -0,0 +1,33 @@ +import cn from "classnames"; +import styles from "./turbohero-background.module.css"; + +export function TurboheroBackground(): JSX.Element { + return ( + <div + className={cn( + "![perspective:1000px] sm:![perspective:1000px] md:![perspective:1000px] lg:![perspective:1000px]", + styles.container + )} + > + <div + className="z-[100] absolute inset-0 [--gradient-stop-1:0px] [--gradient-stop-2:50%]" + style={{ + background: + "linear-gradient(to top, rgba(0,0,0,0) 0px, var(--geist-foreground) 50%)", + }} + /> + <div + style={{ + transform: "rotateX(75deg)", + position: "absolute", + top: 0, + bottom: 0, + left: 0, + right: 0, + }} + > + <div className={styles.lines} /> + </div> + </div> + ); +} diff --git a/docs/components/pages/landing/Turbopack.tsx b/docs/components/pages/landing/Turbopack.tsx new file mode 100644 index 0000000..1db1076 --- /dev/null +++ b/docs/components/pages/landing/Turbopack.tsx @@ -0,0 +1,27 @@ +import Image from "next/image"; + +export function Turbopack() { + return ( + <div className="relative w-24 h-24"> + <div className="pointer-events-none absolute w-[261px] h-[261px] top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-gradient-to-b from-[#4EBFFF] to-[#BD69FF] mix-blend-normal opacity-5 dark:opacity-[0.15] blur-[60px]" /> + <div className="contents dark:hidden"> + <Image + alt="" + src={`/images/docs/pack/turbopack-hero-logo-light.svg`} + width={120} + height={136.15} + className="absolute w-[84px] top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2" + /> + </div> + <div className="dark:contents hidden"> + <Image + alt="" + src={`/images/docs/pack/turbopack-hero-logo-dark.svg`} + width={120} + height={136.15} + className="hidden dark:block absolute w-[84px] top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2" + /> + </div> + </div> + ); +} diff --git a/docs/components/pages/landing/Turborepo.tsx b/docs/components/pages/landing/Turborepo.tsx new file mode 100644 index 0000000..022f37f --- /dev/null +++ b/docs/components/pages/landing/Turborepo.tsx @@ -0,0 +1,27 @@ +import Image from "next/image"; + +export function Turborepo() { + return ( + <div className="relative w-24 h-24"> + <div className="pointer-events-none absolute w-[261px] h-[261px] top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-gradient-to-b from-[#FF3358] to-[#FF4FD8] mix-blend-normal opacity-5 dark:opacity-[0.15] blur-[60px]" /> + <div className="contents dark:hidden"> + <Image + alt="Turborepo Logo" + src={`/images/docs/repo/repo-hero-logo-light.svg`} + width={120} + height={120} + className="absolute w-[84px] top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2" + /> + </div> + <div className="dark:contents hidden"> + <Image + alt="Turborepo Logo" + src={`/images/docs/repo/repo-hero-logo-dark.svg`} + width={120} + height={120} + className="hidden dark:block absolute w-[84px] top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2" + /> + </div> + </div> + ); +} diff --git a/docs/components/pages/landing/index.module.css b/docs/components/pages/landing/index.module.css new file mode 100644 index 0000000..ac18d80 --- /dev/null +++ b/docs/components/pages/landing/index.module.css @@ -0,0 +1,184 @@ +.leftLights::before { + content: ""; + position: absolute; + pointer-events: none; + width: 25%; + height: 900px; + left: -12.5%; + top: calc(50% - 900px / 2 + 151px); + opacity: 0.2; + background: linear-gradient(180deg, #77b8ff 0%, rgba(42, 138, 246, 0.4) 100%); + filter: blur(125px); + transform: rotate(-15deg); + border-bottom-left-radius: 25% 25%; + border-bottom-right-radius: 25% 25%; + border-top-left-radius: 100% 100%; + border-top-right-radius: 100% 100%; + z-index: 200; + will-change: filter; + mix-blend-mode: normal; +} + +.leftLights::after { + content: ""; + position: absolute; + pointer-events: none; + width: 40%; + height: 422px; + left: 0px; + top: calc(50% - 422px / 2 + 298px); + opacity: 0.5; + background: linear-gradient( + 180deg, + rgba(29, 92, 162, 0.2) 0%, + rgba(42, 138, 246, 0.4) 100% + ); + filter: blur(125px); + will-change: filter; + mix-blend-mode: normal; +} + +.rightLights::before { + z-index: 200; + content: ""; + position: absolute; + pointer-events: none; + width: 25%; + height: 900px; + right: -12.5%; + top: calc(50% - 900px / 2 + 151px); + background-image: linear-gradient( + 180deg, + rgba(236, 151, 207, 0.4) 0%, + rgba(233, 42, 103, 1) 100% + ); + filter: blur(125px); + transform: rotate(15deg); + border-bottom-left-radius: 25% 25%; + border-bottom-right-radius: 25% 25%; + border-top-left-radius: 100% 100%; + border-top-right-radius: 100% 100%; + opacity: 0.2; + overflow: hidden; + will-change: filter; + mix-blend-mode: normal; +} + +.rightLights::after { + content: ""; + position: absolute; + pointer-events: none; + width: 40%; + height: 422px; + right: 0px; + top: calc(50% - 422px / 2 + 298px); + opacity: 0.25; + + background: linear-gradient( + 180deg, + rgba(236, 151, 207, 0.4) 0%, + rgba(233, 42, 103, 1) 100% + ); + transform: matrix(-1, 0, 0, 1, 0, 0); + filter: blur(125px); + will-change: filter; + mix-blend-mode: normal; +} + +.counter-border { + --border-radius: 12px; + --border-size: 1px; + --padding: 1px; + --border-bg: conic-gradient( + from 180deg at 50% 50%, + #e92a67 0deg, + #a853ba 112.5deg, + #2a8af6 228.75deg, + rgba(42, 138, 246, 0) 360deg + ); + position: relative; + overflow: hidden; + font-size: 2rem; + padding: calc(var(--padding) + var(--border-size)); + border-radius: var(--border-radius); + display: inline-block; + z-index: 0; + backface-visibility: hidden; + perspective: 1000; + transform: translate3d(0, 0, 0); +} + +.counter-border:hover { + cursor: pointer; +} + +.counter-border i { + content: ""; + position: absolute; + top: var(--border-size); + right: var(--border-size); + bottom: var(--border-size); + left: var(--border-size); + padding: var(--border-size); + mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); + mask-composite: exclude; + z-index: -1; + border-radius: calc(var(--border-radius) + var(--border-size)); +} + +.counter-border i::before { + content: ""; + display: block; + background: var(--border-bg); + box-shadow: 0px 0px 40px 20px --var(--border-bg); + width: calc(100% * 1.41421356237); + padding-bottom: calc(100% * 1.41421356237); + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + border-radius: 100%; + z-index: -2; + animation: spin 5s linear infinite; +} + +@media (prefers-reduced-motion) { + .counter-border i::before { + animation: none; + } +} + +@keyframes spin { + from { + transform: translate(-50%, -50%) rotate(360deg); + } + to { + transform: translate(-50%, -50%) rotate(0); + } +} + +.leftBottomLights { + position: absolute; + width: 387px; + height: 404px; + left: calc(50% - 387px / 2 - 80px); + bottom: -32px; + background: linear-gradient(180deg, #58a5ff 0%, #a67af4 100%); + mix-blend-mode: normal; + opacity: 0.15; + filter: blur(50px); + will-change: filter; +} + +.rightBottomLights { + position: absolute; + width: 387px; + height: 404px; + left: calc(50% - 387px / 2 + 81px); + bottom: -32px; + background: linear-gradient(180deg, #ff3358 0%, #ff4fd8 100%); + mix-blend-mode: normal; + opacity: 0.15; + filter: blur(50px); + will-change: filter; +} diff --git a/docs/components/pages/landing/index.tsx b/docs/components/pages/landing/index.tsx new file mode 100644 index 0000000..deb63f3 --- /dev/null +++ b/docs/components/pages/landing/index.tsx @@ -0,0 +1,199 @@ +import React from "react"; +import Head from "next/head"; +import cn from "classnames"; +import Link from "next/link"; +import { motion } from "framer-motion"; +import { Clients } from "../../clients/Clients"; +import { Marquee } from "../../clients/Marquee"; +import { TurboheroBackground } from "./TurboHeroBackground"; +import { Turborepo } from "./Turborepo"; +import { Turbopack } from "./Turbopack"; +import { FadeIn } from "../home-shared/FadeIn"; +import { LandingPageGlobalStyles } from "../home-shared/GlobalStyles"; +import styles from "./index.module.css"; +import PackLogo from "../../logos/PackLogo"; +import RepoLogo from "../../logos/RepoLogo"; + +function Background() { + return ( + <div className="absolute top-0 left-0 w-full h-full overflow-hidden pointer-events-none"> + <div + className={cn( + "z-[-1] absolute w-full h-full [--gradient-stop-1:60%] [--gradient-stop-2:85%] lg:[--gradient-stop-1:50%] lg:[--gradient-stop-2:90%]", + "[--gradient-color-1=rgba(0,0,0,1)] [--gradient-color-2=rgba(0,0,0,0.8)] [--gradient-color-3=rgba(0,0,0,0)]", + "dark:[--gradient-color-1=rgba(255,255,255,1)] dark:[--gradient-color-2=rgba(255,255,255,0.8)] dark:[--gradient-color-3=rgba(255,255,255,0)]" + )} + style={{ + background: + "linear-gradient(180deg, var(--gradient-color-1) 0%, var(--gradient-color-2) var(--gradient-stop-1), var(--gradient-color-3) var(--gradient-stop-2), 100% transparent)", + }} + /> + <span className={cn(styles.leftLights, "opacity-50 dark:opacity-100")} /> + <span className={cn(styles.rightLights, "opacity-50 dark:opacity-100")} /> + <span className="absolute bottom-0 left-0 w-full h-48 bg-gradient-to-t dark:from-black from-white to-transparent" /> + <span className="bg-gradient-to-b dark:from-black from-white to-transparent absolute top-[20vh] left-0 w-full h-[50vh]" /> + <TurboheroBackground /> + </div> + ); +} + +export function CardBadge({ children }: { children: React.ReactNode }) { + return ( + <div className="font-mono font-bold text-xs text-black/50 dark:text-white/50 px-[6px] py-[3.25px] tracking-[-0.01em] rounded-[6px] uppercase flex justify-center items-center bg-black/5 dark:bg-white/[0.15] border border-black/[0.1] dark:border-white/[0.1]"> + {children} + </div> + ); +} + +const variants = { + hidden: { opacity: 0 }, + active: { opacity: 1 }, +}; + +function Card({ + alt, + href, + title, + icon: Icon, + className, + children, +}: { + href: string; + icon: React.ElementType; + title: "repo" | "pack"; + alt?: string; + className?: string; + children: React.ReactNode; +}) { + const [hovering, setHovering] = React.useState(false); + return ( + <Link + href={href} + className={cn( + styles["counter-border"], + "w-[calc(100%_-_0px)] h-[304]px sm:!w-[488px] sm:h-[352px]" + )} + onMouseEnter={() => setHovering(true)} + onMouseLeave={() => setHovering(false)} + > + <motion.i + initial="hidden" + animate={hovering ? "active" : "hidden"} + variants={variants} + aria-hidden="true" + ></motion.i> + <div + className={cn( + "relative w-full h-full max-w-full !pb-12 pt-8 md:!pb-4 md:!pt-4 p-3 rounded-xl overflow-hidden flex flex-col items-center justify-center border border-[rgba(255,255,255,0.05)]", + className + )} + > + <div className="flex items-center justify-center flex-1 mb-7 md:mb-0"> + <Icon /> + </div> + + <div className="flex flex-col items-center flex-1"> + {title == "pack" ? ( + <PackLogo + alt={alt} + className="w-[160px] md:w-[220px] mb-3 fill-black dark:fill-white" + /> + ) : ( + <RepoLogo + alt={alt} + className="w-[160px] md:w-[220px] mb-3 fill-black dark:fill-white" + /> + )} + {children} + </div> + </div> + </Link> + ); +} + +function SiteCards() { + return ( + <div className="flex w-full container items-center justify-center gap-6 px-6 sm:mx-0 mt-8 md:!mt-14 lg:!mt-15 md:mb-0 flex-col lg:!flex-row z-10 lg:!translate-y-0"> + <FadeIn delay={0.1}> + <Card + title="repo" + alt="Turborepo" + icon={Turborepo} + href="/repo" + className="turborepoCardBg" + > + <p className="text-lg !w-[280px] md:!w-[340px] font-space-grotesk text-center opacity-50 dark:opacity-70"> + High-performance build system for JavaScript and TypeScript + codebases. + </p> + </Card> + </FadeIn> + <FadeIn delay={0.2}> + <Card + title="pack" + alt="Turbopack" + icon={Turbopack} + href="/pack" + className="turbopackCardBg" + > + <div className="absolute top-3 left-3"> + <CardBadge>alpha</CardBadge> + </div> + <p className="text-lg !w-[280px] md:!w-[340px] font-space-grotesk text-center opacity-50 dark:opacity-70 "> + Introducing the Rust-powered successor to Webpack. + </p> + </Card> + </FadeIn> + </div> + ); +} + +function Teams() { + return ( + <div className="mx-auto "> + <p className="bg-contain mb-2 md:!mb-4 text-sm font-semibold tracking-wide text-center text-[#666666] dark:text-[#888888] uppercase"> + Trusted by teams from + <br className="inline md:hidden" /> around the world + </p> + <div className="z-50 grid grid-flow-col grid-rows-6 sm:grid-rows-3 md:grid-rows-2 lg:grid-rows-1"> + <Clients + companyList={[ + "Vercel", + "AWS", + "Microsoft", + "Adobe", + "Disney", + "Netflix", + ]} + staticWidth + /> + </div> + </div> + ); +} + +function LandingPage() { + return ( + <> + <LandingPageGlobalStyles /> + <main className="relative flex flex-col items-center justify-center w-full h-full overflow-hidden [--geist-foreground:#fff] dark:[--geist-foreground:#000] [--gradient-stop-1:0px] [--gradient-stop-2:120px] sm:[--gradient-stop-1:0px] sm:[--gradient-stop-2:120px]"> + <Background /> + <FadeIn className="z-10 flex flex-col items-center justify-center w-full h-full"> + <h1 className="mt-12 lg:!mt-20 mx-6 w-[300px] md:!w-full font-extrabold text-5xl lg:text-6xl leading-tight text-center mb-4 bg-clip-text text-transparent bg-gradient-to-b from-black/80 to-black dark:from-white dark:to-[#AAAAAA]"> + Make Ship Happen + </h1> + <p className="mx-6 text-xl max-h-[112px] md:max-h-[96px] w-[315px] md:w-[660px] md:text-2xl font-space-grotesk text-center text-[#666666] dark:text-[#888888]"> + Turbo is an incremental bundler and build system optimized for + JavaScript and TypeScript, written in Rust. + </p> + </FadeIn> + <SiteCards /> + <FadeIn delay={0.3} className="z-10 py-16"> + <Teams /> + </FadeIn> + </main> + </> + ); +} + +export default LandingPage; diff --git a/docs/components/pages/landing/turbohero-background.module.css b/docs/components/pages/landing/turbohero-background.module.css new file mode 100644 index 0000000..8f157e1 --- /dev/null +++ b/docs/components/pages/landing/turbohero-background.module.css @@ -0,0 +1,108 @@ +.container { + position: absolute; + z-index: -6; + overflow: hidden; + inset: 0; + transition: perspective 3000ms ease 0s; +} + +.lines { + --right: #f8cde8; + --left: #b9ddff; + position: absolute; + width: 200vw; + margin-left: -50%; + transform: translateY(0); + background-image: linear-gradient( + to right, + var(--left) 45%, + rgba(0, 0, 0, 0) 50%, + var(--right) 55% + ); + mask-image: linear-gradient( + to right, + rgba(0, 0, 0, 1) 2px, + rgba(0, 0, 0, 0) 1px + ), + linear-gradient(to bottom, rgba(0, 0, 0, 1) 2px, rgba(0, 0, 0, 0) 1px); + mask-size: 60px 60px; + overflow: hidden; + mask-repeat: repeat repeat; + display: flex; + align-items: center; + justify-content: center; + inset: -100% 0px; + background-position-y: 100%; + mask-position: 50% 0px; + animation: go-up 60s linear infinite; +} + +@media (min-width: 1024px) { + .lines { + animation-duration: 30s; + mask-size: 80px 80px; + } +} + +:global(.dark) .lines { + --right: #4c2638; + --left: #223b67; +} + +@keyframes go-up { + 0% { + transform: translateY(0); + } + + 100% { + transform: translateY(calc(50% + 28px)); + } +} + +.pulse::before { + content: ""; + position: absolute; + inset: 0px; + animation: pulse-frames ease-out 8s infinite; + animation-delay: 0s; + background: rgba(0, 0, 0, 0) + linear-gradient( + to top, + rgba(0, 0, 0, 0) 45%, + var(--pulse-color) 50%, + rgba(0, 0, 0, 0) 90% + ) + no-repeat; + z-index: 211; + animation-delay: var(--delay); +} + +@keyframes pulse-frames { + 0% { + transform: translateY(0%); + } + 50% { + transform: translateY(200%); + } + 100% { + transform: translateY(200%); + } +} + +@media (prefers-reduced-motion) { + .lines { + animation: none; + } + .pulse::before { + animation: none; + } +} + +@media (prefers-reduced-motion) { + .lines { + animation: none; + } + .pulse::before { + animation: none; + } +} |
