aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/docs/components/pages/home-shared
diff options
context:
space:
mode:
authorHsiangNianian <admin@jyunko.cn>2023-04-22 19:52:26 +0800
committerHsiangNianian <admin@jyunko.cn>2023-04-22 19:52:26 +0800
commit4838df315931bb883f704ec3e1abe2685f296cdf (patch)
tree57a8550c4cd5338f1126364bb518c6cde8d96e7d /docs/components/pages/home-shared
parentdb74ade0234a40c2120ad5f2a41bee50ce13de02 (diff)
downloadHydroRoll-4838df315931bb883f704ec3e1abe2685f296cdf.tar.gz
HydroRoll-4838df315931bb883f704ec3e1abe2685f296cdf.zip
😀
Diffstat (limited to 'docs/components/pages/home-shared')
-rw-r--r--docs/components/pages/home-shared/CTAButton.tsx43
-rw-r--r--docs/components/pages/home-shared/FadeIn.tsx50
-rw-r--r--docs/components/pages/home-shared/FeatureBox.tsx42
-rw-r--r--docs/components/pages/home-shared/FeaturesBento.tsx38
-rw-r--r--docs/components/pages/home-shared/GlobalStyles.tsx20
-rw-r--r--docs/components/pages/home-shared/Gradient.tsx47
-rw-r--r--docs/components/pages/home-shared/GradientSectionBorder.tsx37
-rw-r--r--docs/components/pages/home-shared/Headings.tsx56
-rw-r--r--docs/components/pages/home-shared/gradients.module.css231
9 files changed, 564 insertions, 0 deletions
diff --git a/docs/components/pages/home-shared/CTAButton.tsx b/docs/components/pages/home-shared/CTAButton.tsx
new file mode 100644
index 0000000..57da227
--- /dev/null
+++ b/docs/components/pages/home-shared/CTAButton.tsx
@@ -0,0 +1,43 @@
+import cn from "classnames";
+import { MouseEventHandler } from "react";
+import gradients from "./gradients.module.css";
+
+export function CTAButton({
+ children,
+ outline,
+ onClick,
+ monospace,
+}: {
+ outline?: boolean;
+ children: React.ReactNode;
+ onClick?: MouseEventHandler<HTMLButtonElement>;
+ monospace?: boolean;
+}) {
+ const outlineClasses =
+ "border dark:border-neutral-400 dark:text-neutral-200 dark:hover:border-white dark:hover:text-white border-[#EAEAEA] text-neutral-800 hover:border-black hover:text-black";
+ const filledClasses =
+ "dark:text-black text-white border-transparent bg-black dark:bg-white";
+
+ return (
+ <div className="relative w-full group">
+ <button
+ onClick={onClick}
+ className={`w-full min-w-[120px] text-base font-medium no-underline ${
+ outline ? outlineClasses : filledClasses
+ } rounded md:leading-6 transition-all duration-300 ${
+ monospace ? "font-mono" : ""
+ }`}
+ >
+ {children}
+ </button>
+ {!outline && (
+ <div
+ className={cn(
+ "absolute bg-red-100 w-full h-full top-0 -z-10 rounded-full transition-all duration-300 blur-xl group-hover:opacity-70 opacity-0",
+ gradients.translatingGlow
+ )}
+ />
+ )}
+ </div>
+ );
+}
diff --git a/docs/components/pages/home-shared/FadeIn.tsx b/docs/components/pages/home-shared/FadeIn.tsx
new file mode 100644
index 0000000..826a078
--- /dev/null
+++ b/docs/components/pages/home-shared/FadeIn.tsx
@@ -0,0 +1,50 @@
+import { motion, useInView } from "framer-motion";
+import { useRef } from "react";
+
+export function FadeIn({
+ children,
+ className,
+ noVertical,
+ delay,
+ viewTriggerOffset,
+}: {
+ children: React.ReactNode;
+ className?: string;
+ noVertical?: boolean;
+ delay?: number;
+ viewTriggerOffset?: boolean;
+}) {
+ const ref = useRef(null);
+ const inView = useInView(ref, {
+ once: true,
+ margin: viewTriggerOffset ? "-128px" : "0px",
+ });
+
+ const fadeUpVariants = {
+ initial: {
+ opacity: 0,
+ y: noVertical ? 0 : 24,
+ },
+ animate: {
+ opacity: 1,
+ y: 0,
+ },
+ };
+
+ return (
+ <motion.div
+ ref={ref}
+ animate={inView ? "animate" : "initial"}
+ variants={fadeUpVariants}
+ className={className}
+ initial={false}
+ transition={{
+ duration: 1,
+ delay: delay || 0,
+ ease: [0.21, 0.47, 0.32, 0.98],
+ }}
+ >
+ {children}
+ </motion.div>
+ );
+}
diff --git a/docs/components/pages/home-shared/FeatureBox.tsx b/docs/components/pages/home-shared/FeatureBox.tsx
new file mode 100644
index 0000000..c9d46c1
--- /dev/null
+++ b/docs/components/pages/home-shared/FeatureBox.tsx
@@ -0,0 +1,42 @@
+import Image from "next/image";
+import type { ReactNode } from "react";
+
+export function FeatureBox({
+ name,
+ description,
+ iconDark,
+ iconLight,
+}: {
+ iconDark: Parameters<typeof Image>[0]["src"];
+ iconLight: Parameters<typeof Image>[0]["src"];
+ name: string;
+ description: ReactNode;
+}) {
+ return (
+ <div className="box-border relative flex flex-col gap-5 p-8 overflow-hidden text-black no-underline border dark:text-white rounded-xl dark:border-neutral-800">
+ <Image
+ src={iconDark}
+ width={64}
+ height={64}
+ aria-hidden="true"
+ alt=""
+ className="hidden dark:block"
+ />
+ <Image
+ src={iconLight}
+ width={64}
+ height={64}
+ aria-hidden="true"
+ alt=""
+ className="block dark:hidden"
+ />
+ <div className="flex flex-col gap-2">
+ <h3 className="m-0 font-bold leading-5 text-gray-900 font-space-grotesk dark:text-white">
+ {name}
+ </h3>
+
+ <p className="m-0 leading-6 opacity-70">{description}</p>
+ </div>
+ </div>
+ );
+}
diff --git a/docs/components/pages/home-shared/FeaturesBento.tsx b/docs/components/pages/home-shared/FeaturesBento.tsx
new file mode 100644
index 0000000..f2664db
--- /dev/null
+++ b/docs/components/pages/home-shared/FeaturesBento.tsx
@@ -0,0 +1,38 @@
+import type { Features } from "../../../content/features";
+import { FadeIn } from "./FadeIn";
+import { SectionHeader, SectionSubtext } from "./Headings";
+import { FeatureBox } from "./FeatureBox";
+
+export function FeaturesBento({
+ header,
+ body,
+ features,
+}: {
+ header: string;
+ body: string;
+ features: Features;
+}) {
+ return (
+ <section className="relative flex flex-col items-center px-6 pb-16 font-sans md:pb-24 lg:pb-32 gap-9 lg:gap-14">
+ <FadeIn className="flex flex-col items-center gap-5 md:gap-6">
+ <SectionHeader>{header}</SectionHeader>
+ <SectionSubtext>{body}</SectionSubtext>
+ </FadeIn>
+ <div className="grid grid-cols-1 gap-x-4 gap-y-4 sm:grid-cols-2 lg:grid-cols-3 lg:gap-x-6 lg:gap-y-6 max-w-[1200px]">
+ {features.map((feature) => (
+ <FadeIn
+ className="flex"
+ key={feature.name.replace(/\s+/g, "-").toLowerCase()}
+ >
+ <FeatureBox
+ name={feature.name}
+ description={feature.description}
+ iconDark={feature.iconDark}
+ iconLight={feature.iconLight}
+ />
+ </FadeIn>
+ ))}
+ </div>
+ </section>
+ );
+}
diff --git a/docs/components/pages/home-shared/GlobalStyles.tsx b/docs/components/pages/home-shared/GlobalStyles.tsx
new file mode 100644
index 0000000..5f695f3
--- /dev/null
+++ b/docs/components/pages/home-shared/GlobalStyles.tsx
@@ -0,0 +1,20 @@
+import Head from "next/head";
+
+export function LandingPageGlobalStyles() {
+ return (
+ <Head>
+ <style>
+ {`
+ .dark footer,
+ .dark body {
+ background-color: black !important;
+ }
+
+ .dark .nextra-nav-container .nextra-nav-container-blur {
+ background-color: rgba(0,0,0,.5) !important;
+ }
+ `}
+ </style>
+ </Head>
+ );
+}
diff --git a/docs/components/pages/home-shared/Gradient.tsx b/docs/components/pages/home-shared/Gradient.tsx
new file mode 100644
index 0000000..9a03a99
--- /dev/null
+++ b/docs/components/pages/home-shared/Gradient.tsx
@@ -0,0 +1,47 @@
+import cn from "classnames";
+import gradients from "./gradients.module.css";
+
+export function Gradient({
+ width = 1000,
+ height = 200,
+ opacity,
+ pink,
+ blue,
+ conic,
+ gray,
+ className,
+ small,
+}: {
+ width?: number | string;
+ height?: number | string;
+ opacity?: number;
+ pink?: boolean;
+ blue?: boolean;
+ conic?: boolean;
+ gray?: boolean;
+ className?: string;
+ small?: boolean;
+}) {
+ return (
+ <span
+ className={cn(
+ "absolute",
+ gradients.glow,
+ {
+ [gradients.glowPink]: pink,
+ [gradients.glowBlue]: blue,
+ [gradients.glowConic]: conic,
+ [gradients.glowSmall]: small,
+ [gradients.glowGray]: gray,
+ },
+ className
+ )}
+ style={{
+ width,
+ height,
+ opacity,
+ borderRadius: "100%",
+ }}
+ />
+ );
+}
diff --git a/docs/components/pages/home-shared/GradientSectionBorder.tsx b/docs/components/pages/home-shared/GradientSectionBorder.tsx
new file mode 100644
index 0000000..ef1e824
--- /dev/null
+++ b/docs/components/pages/home-shared/GradientSectionBorder.tsx
@@ -0,0 +1,37 @@
+import cn from "classnames";
+import { FadeIn } from "./FadeIn";
+import gradients from "../home-shared/gradients.module.css";
+
+export function GradientSectionBorder({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ return (
+ <section className={cn("relative overflow-hidden")}>
+ <FadeIn noVertical viewTriggerOffset>
+ <span
+ className={cn(
+ "w-full absolute white h-[1px] top-0 opacity-25",
+ gradients.gradientSectionBorderDivider
+ )}
+ />
+ <span
+ className={cn(
+ gradients.gradientSectionBorder,
+ gradients.gradientSectionBorderLeft,
+ "dark:opacity-35 opacity-[0.15]"
+ )}
+ />
+ <span
+ className={cn(
+ gradients.gradientSectionBorder,
+ gradients.gradientSectionBorderRight,
+ "dark:opacity-35 opacity-[0.15]"
+ )}
+ />
+ </FadeIn>
+ {children}
+ </section>
+ );
+}
diff --git a/docs/components/pages/home-shared/Headings.tsx b/docs/components/pages/home-shared/Headings.tsx
new file mode 100644
index 0000000..43a5e52
--- /dev/null
+++ b/docs/components/pages/home-shared/Headings.tsx
@@ -0,0 +1,56 @@
+import cn from "classnames";
+import gradients from "./gradients.module.css";
+
+export function HeroText({
+ children,
+ className,
+ h1,
+}: {
+ children: React.ReactNode;
+ className?: string;
+ h1?: boolean;
+}) {
+ const combinedClassname = cn(
+ gradients.heroHeading,
+ "font-extrabold tracking-[-0.04em] leading-none text-[40px] md:text-5xl lg:text-[80px] max-w-lg md:max-w-xl lg:max-w-4xl text-center text-transparent",
+ className
+ );
+
+ if (h1) {
+ return <h1 className={combinedClassname}>{children}</h1>;
+ }
+ return <h2 className={combinedClassname}>{children}</h2>;
+}
+
+export function SectionHeader({ children }: { children: React.ReactNode }) {
+ return (
+ <h2
+ className={cn(
+ gradients.heroHeading,
+ "font-bold tracking-[-0.01em] pb-1 text-[32px] md:text-4xl lg:text-[40px] max-w-sm md:max-w-md lg:max-w-2xl text-center text-transparent"
+ )}
+ >
+ {children}
+ </h2>
+ );
+}
+
+export function SectionSubtext({
+ hero,
+ children,
+}: {
+ hero?: boolean;
+ children: React.ReactNode;
+}) {
+ const textClasses = hero
+ ? "text-[20px] lg:text-xl"
+ : "text-[16px] lg:text-[20px]";
+
+ return (
+ <p
+ className={`font-space-grotesk leading-snug dark:text-[#FFFFFFB2] text-[#00000080] ${textClasses} max-w-md md:max-w-xl lg:max-w-[640px] text-center`}
+ >
+ {children}
+ </p>
+ );
+}
diff --git a/docs/components/pages/home-shared/gradients.module.css b/docs/components/pages/home-shared/gradients.module.css
new file mode 100644
index 0000000..b9c50a9
--- /dev/null
+++ b/docs/components/pages/home-shared/gradients.module.css
@@ -0,0 +1,231 @@
+.benchmarkTurbo {
+ background: linear-gradient(288.43deg, #ff1e56 28.29%, #9c51a1 78.78%);
+ box-shadow: 0px 0px 16px #f02662;
+ :global(.light) & {
+ background: linear-gradient(
+ 268.86deg,
+ #ff1e56 -5.68%,
+ #d67fdc 107.63%,
+ #9c51a1 107.64%
+ );
+ box-shadow: none;
+ }
+}
+
+.benchmarkActiveTab {
+ background: radial-gradient(
+ 50% 50% at 50% 100%,
+ rgba(255, 255, 255, 0.2) 0%,
+ rgba(255, 255, 255, 0) 100%
+ ),
+ linear-gradient(0deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.12)),
+ radial-gradient(
+ 128.57% 128.57% at 50% 0%,
+ rgba(255, 255, 255, 0.1) 0%,
+ rgba(255, 255, 255, 0) 100%
+ ),
+ radial-gradient(
+ 100% 427.04% at 100% 0%,
+ rgba(255, 255, 255, 0.1) 0%,
+ rgba(255, 255, 255, 0) 100%
+ ),
+ radial-gradient(
+ 100% 462.63% at 0% 0%,
+ rgba(255, 255, 255, 0.1) 0%,
+ rgba(255, 255, 255, 0) 100%
+ );
+ :global(.light) & {
+ background: linear-gradient(
+ 0deg,
+ rgba(255, 255, 255, 0.8),
+ rgba(255, 255, 255, 0.8)
+ ),
+ radial-gradient(
+ 50% 50% at 49.66% 0%,
+ rgba(255, 255, 255, 0.1) 0%,
+ rgba(255, 255, 255, 0) 100%
+ );
+ }
+}
+
+.benchmarkTurboLabel {
+ background: linear-gradient(288.43deg, #ff1e56 28.29%, #9c51a1 78.78%);
+ color: transparent;
+ background-clip: text;
+ :global(.light) & {
+ background: linear-gradient(
+ 268.86deg,
+ #ff1e56 -5.68%,
+ #d67fdc 107.63%,
+ #9c51a1 107.64%
+ ),
+ linear-gradient(288.43deg, #ff1e56 28.29%, #9c51a1 78.78%);
+ color: transparent;
+ background-clip: text;
+ }
+}
+
+.benchmark {
+ background: linear-gradient(270deg, #5c5c5c 0%, #1f1f1f 100%);
+ :global(.light) & {
+ background: linear-gradient(89.98deg, #e0e0e0 0.01%, #9c9c9c 99.49%);
+ }
+}
+
+.barBorder {
+ border: rgba(255, 255, 255, 0.4) 1px solid;
+ :global(.light) & {
+ border: rgba(0, 0, 0, 0.6) 1px solid;
+ }
+}
+
+.tooltipArrow {
+ display: block;
+ border-left: 8px solid transparent;
+ border-bottom: 8px solid #333333;
+ border-right: 8px solid transparent;
+ :global(.light) & {
+ border-bottom: 8px solid #f5f5f5;
+ }
+}
+.translatingGlow {
+ background: linear-gradient(32deg, #2a8af6 0%, #a853ba 50%, #e92a67 100%);
+ background-size: 200% 200%;
+ animation: translateGlow 7s linear infinite;
+ will-change: filter;
+}
+
+@keyframes translateGlow {
+ 0% {
+ background-position: -20% -20%;
+ }
+ 25% {
+ background-position: 30% 80%;
+ }
+ 50% {
+ background-position: 110% 110%;
+ }
+ 75% {
+ background-position: 80% 30%;
+ }
+ 100% {
+ background-position: -20% -20%;
+ }
+}
+
+.turbopackHeaderText {
+ background: linear-gradient(
+ 90deg,
+ rgba(200, 221, 255, 0.75) 0%,
+ rgba(255, 202, 222, 0.75) 100%
+ ),
+ linear-gradient(0deg, #ffffff, #ffffff);
+
+ :global(.light) & {
+ background: linear-gradient(
+ 90deg,
+ rgba(200, 221, 255, 0.1) 0%,
+ rgba(255, 202, 222, 0.1) 100%
+ ),
+ #000000;
+ background-clip: text;
+ }
+ background-clip: text;
+}
+
+.heroHeading {
+ background: linear-gradient(180deg, #ffffff 0%, #aaaaaa 100%), #ffffff;
+ :global(.light) & {
+ background: linear-gradient(180deg, rgba(0, 0, 0, 0.8) 0%, #000000 100%);
+ background-clip: text;
+ }
+ background-clip: text;
+}
+
+.letterLine {
+ opacity: 0.2;
+ background: linear-gradient(
+ 90deg,
+ #000000 0%,
+ #ffffff 20%,
+ #ffffff 80%,
+ #000000 100%
+ );
+ :global(.light) & {
+ background: linear-gradient(
+ 90deg,
+ #ffffff 0%,
+ #000000 20%,
+ #000000 80%,
+ #ffffff 100%
+ );
+ }
+}
+
+.glow {
+ mix-blend-mode: normal;
+ filter: blur(75px);
+ will-change: filter;
+}
+
+.glowSmall {
+ filter: blur(32px);
+}
+
+.glowBlue {
+ background: linear-gradient(180deg, #58a5ff 0%, #a67af4 100%);
+}
+
+.glowPink {
+ background: linear-gradient(180deg, #ff3358 0%, #ff4fd8 100%);
+}
+
+.glowConic {
+ background: conic-gradient(
+ from 180deg at 50% 50%,
+ #2a8af6 0deg,
+ #a853ba 180deg,
+ #e92a67 360deg
+ );
+}
+
+.glowGray {
+ background: rgba(255, 255, 255, 0.15);
+}
+
+.gradientSectionBorder {
+ --gradient-y-offset: -200px;
+ --gradient-x-offset: -200px;
+ --height: 255px;
+ position: relative;
+ overflow: hidden;
+ will-change: filter;
+}
+
+.gradientSectionBorderLeft {
+ position: absolute;
+ width: 60vw;
+ height: var(--height);
+ left: var(--gradient-x-offset);
+ top: var(--gradient-y-offset);
+ background: linear-gradient(180deg, #58a5ff 0%, #a67af4 100%);
+ border-radius: 100%;
+ mix-blend-mode: normal;
+ filter: blur(50px);
+}
+
+.gradientSectionBorderRight {
+ width: 60vw;
+ position: absolute;
+ height: var(--height);
+ right: var(--gradient-x-offset);
+ top: var(--gradient-y-offset);
+ background: linear-gradient(180deg, #ff3358 0%, #ff4fd8 100%);
+ border-radius: 100%;
+ mix-blend-mode: normal;
+ filter: blur(50px);
+}
+
+.gradientSectionBorderDivider {
+ background: linear-gradient(90deg, #288cf9 0%, #e32c6b 100%);
+}