update landing page styles

This commit is contained in:
Aman Varshney
2025-04-05 22:57:09 +05:30
parent 6b2cde8030
commit b5f106dd47
10 changed files with 169 additions and 321 deletions

View File

@@ -7,10 +7,7 @@
"bin": { "bin": {
"create-better-t-stack": "dist/index.js" "create-better-t-stack": "dist/index.js"
}, },
"files": [ "files": ["template", "dist"],
"template",
"dist"
],
"keywords": [ "keywords": [
"better-t-stack", "better-t-stack",
"typescript", "typescript",
@@ -39,7 +36,7 @@
], ],
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/better-t-stack/create-better-t-stack.git", "url": "git+https://github.com/AmanVarshney01/create-better-t-stack.git",
"directory": "apps/cli" "directory": "apps/cli"
}, },
"homepage": "https://better-t-stack.pages.dev/", "homepage": "https://better-t-stack.pages.dev/",

View File

@@ -43,7 +43,7 @@ function generateReadmeContent(options: ProjectConfig): string {
return `# ${projectName} return `# ${projectName}
This project was created with [Better-T-Stack](https://github.com/better-t-stack/Better-T-Stack), a modern TypeScript stack that combines React, ${hasTanstackRouter ? "TanStack Router" : "React Router"}, Hono, tRPC, and more. This project was created with [Better-T-Stack](https://github.com/AmanVarshney01/create-better-t-stack), a modern TypeScript stack that combines React, ${hasTanstackRouter ? "TanStack Router" : "React Router"}, Hono, tRPC, and more.
## Features ## Features

View File

@@ -60,7 +60,7 @@ ${
}${pc.cyan("•")} API: http://localhost:3000 }${pc.cyan("•")} API: http://localhost:3000
${nativeInstructions ? `\n${nativeInstructions.trim()}` : ""}${databaseInstructions ? `\n${databaseInstructions.trim()}` : ""}${tauriInstructions ? `\n${tauriInstructions.trim()}` : ""}${lintingInstructions ? `\n${lintingInstructions.trim()}` : ""}${pwaInstructions ? `\n${pwaInstructions.trim()}` : ""} ${nativeInstructions ? `\n${nativeInstructions.trim()}` : ""}${databaseInstructions ? `\n${databaseInstructions.trim()}` : ""}${tauriInstructions ? `\n${tauriInstructions.trim()}` : ""}${lintingInstructions ? `\n${lintingInstructions.trim()}` : ""}${pwaInstructions ? `\n${pwaInstructions.trim()}` : ""}
\n${pc.bold("Like Better-T Stack?")} Please consider giving us a star on GitHub: \n${pc.bold("Like Better-T Stack?")} Please consider giving us a star on GitHub:
${pc.cyan("https://github.com/better-t-stack/create-better-t-stack")}`, ${pc.cyan("https://github.com/AmanVarshney01/create-better-t-stack")}`,
"Next steps", "Next steps",
); );
} }

View File

@@ -1,7 +1,7 @@
@import "tailwindcss"; @import "tailwindcss";
@import "tw-animate-css"; @import "tw-animate-css";
@custom-variant dark (&:is(.dark *)); @custom-variant dark (&:where(.dark, .dark *));
@theme { @theme {
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif, --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif,

View File

@@ -1,6 +1,6 @@
"use client"; "use client";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import { Check, CircleCheck, ClipboardCopy, Terminal } from "lucide-react"; import { Check, ClipboardCopy, Terminal } from "lucide-react";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
const CodeContainer = () => { const CodeContainer = () => {
@@ -8,24 +8,37 @@ const CodeContainer = () => {
const [selectedPM, setSelectedPM] = useState<"npm" | "pnpm" | "bun">("bun"); const [selectedPM, setSelectedPM] = useState<"npm" | "pnpm" | "bun">("bun");
const [copied, setCopied] = useState(false); const [copied, setCopied] = useState(false);
const menuRef = useRef<HTMLDivElement>(null); const menuRef = useRef<HTMLDivElement>(null);
const [typingComplete, setTypingComplete] = useState(false); const [showCursor, setShowCursor] = useState(true);
const [currentStep, setCurrentStep] = useState(0); const [step, setStep] = useState(0);
useEffect(() => { useEffect(() => {
const handleClickOutside = (event: MouseEvent) => { const handleClickOutside = (e: MouseEvent) => {
if (menuRef.current && !menuRef.current.contains(event.target as Node)) { if (menuRef.current && !menuRef.current.contains(e.target as Node))
setIsOpen(false); setIsOpen(false);
}
}; };
document.addEventListener("mousedown", handleClickOutside); document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside);
}, []); }, []);
useEffect(() => {
const interval = setInterval(() => setShowCursor((p) => !p), 500);
return () => clearInterval(interval);
}, []);
useEffect(() => {
if (step < 5) {
const timer = setTimeout(
() => setStep((s) => s + 1),
step === 0 ? 1000 : 400,
);
return () => clearTimeout(timer);
}
}, [step]);
const commands = { const commands = {
npm: "npx create-better-t-stack@latest my-better-t-app --yes", npm: "npx create-better-t-stack@latest my-app",
pnpm: "pnpm create better-t-stack@latest my-better-t-app --yes", pnpm: "pnpm create better-t-stack@latest my-app",
bun: "bun create better-t-stack@latest my-better-t-app --yes", bun: "bun create better-t-stack@latest my-app",
}; };
const copyToClipboard = async (pm: "npm" | "pnpm" | "bun") => { const copyToClipboard = async (pm: "npm" | "pnpm" | "bun") => {
@@ -36,54 +49,35 @@ const CodeContainer = () => {
setTimeout(() => setCopied(false), 2000); setTimeout(() => setCopied(false), 2000);
}; };
useEffect(() => {
if (!typingComplete) {
const timer = setTimeout(() => {
setTypingComplete(true);
}, 1000);
return () => clearTimeout(timer);
}
if (typingComplete && currentStep < 5) {
const timer = setTimeout(() => {
setCurrentStep((prev) => prev + 1);
}, 800);
return () => clearTimeout(timer);
}
}, [typingComplete, currentStep]);
return ( return (
<div className="mx-auto mt-4 w-full max-w-3xl sm:mt-8"> <div className="mx-auto mt-4 w-full max-w-3xl">
<div className="overflow-hidden rounded-xl border border-gray-300 bg-gray-100 text-gray-800 shadow-xl dark:border-gray-700 dark:bg-black dark:text-white"> <div className="overflow-hidden rounded-lg border border-gray-200 bg-white shadow-md dark:border-gray-800 dark:bg-gray-950">
<div className="flex items-center justify-between bg-gray-200 px-3 py-2 sm:px-4 dark:bg-gray-800"> <div className="flex items-center justify-between bg-gray-100 px-3 py-2 dark:bg-gray-900">
<div className="flex space-x-2"> <div className="flex gap-1.5">
<div className="h-3 w-3 rounded-full bg-red-500" /> <div className="h-2.5 w-2.5 rounded-full bg-red-500" />
<div className="h-3 w-3 rounded-full bg-yellow-500" /> <div className="h-2.5 w-2.5 rounded-full bg-yellow-500" />
<div className="h-3 w-3 rounded-full bg-green-500" /> <div className="h-2.5 w-2.5 rounded-full bg-green-500" />
</div> </div>
<div className="xs:block hidden font-mono text-[10px] text-gray-600 sm:text-xs dark:text-gray-400">
Quick Install Terminal <div className="text-gray-600 text-xs dark:text-gray-400">
Terminal
</div> </div>
<div className="relative" ref={menuRef}> <div className="relative" ref={menuRef}>
<button <button
type="button" type="button"
onClick={() => setIsOpen(!isOpen)} onClick={() => setIsOpen(!isOpen)}
className="flex items-center rounded border border-gray-300 bg-gray-300/50 px-1.5 py-1 text-[10px] hover:bg-gray-300/80 sm:px-2 sm:text-xs dark:border-gray-700 dark:bg-gray-800/50 dark:hover:bg-gray-700/50" className="flex items-center gap-1 rounded border border-gray-200 bg-white px-2 py-1 text-gray-700 text-xs hover:bg-gray-50 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700"
> >
<Terminal className="mr-1 h-3 w-3 text-gray-600 dark:text-gray-400"> <Terminal className="h-3 w-3 text-gray-600 dark:text-gray-400" />
<title>Package Manager</title> <span>{selectedPM}</span>
</Terminal>
<span className="mr-1 text-gray-700 dark:text-gray-300">
{selectedPM}
</span>
<svg <svg
className="h-3 w-3 text-gray-700 dark:text-gray-400" className="h-3 w-3 text-gray-500"
fill="none" fill="none"
stroke="currentColor" stroke="currentColor"
viewBox="0 0 24 24" viewBox="0 0 24 24"
> >
<title>Toggle Dropdown</title> <title>arrow</title>
<path <path
strokeLinecap="round" strokeLinecap="round"
strokeLinejoin="round" strokeLinejoin="round"
@@ -97,254 +91,137 @@ const CodeContainer = () => {
<motion.div <motion.div
initial={{ opacity: 0, y: -5 }} initial={{ opacity: 0, y: -5 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
className="absolute right-0 z-50 mt-1 w-32 rounded-md border border-gray-300 bg-white shadow-lg sm:w-36 dark:border-gray-700 dark:bg-gray-900" className="absolute right-0 z-50 mt-1 w-28 rounded-md border border-gray-200 bg-white shadow-lg dark:border-gray-700 dark:bg-gray-800"
> >
<ul> {(["npm", "pnpm", "bun"] as const).map((pm) => (
{(Object.keys(commands) as Array<"npm" | "pnpm" | "bun">).map( <button
(pm) => ( type="button"
<li key={pm}> key={pm}
<button className={`block w-full px-3 py-1.5 text-left text-xs ${
type="button" selectedPM === pm
className={`block w-full px-3 py-1.5 text-left text-[10px] sm:text-xs ${ ? "bg-gray-200 text-gray-800 dark:bg-gray-700 dark:text-gray-200"
selectedPM === pm : "text-gray-700 hover:bg-gray-50 dark:text-gray-300 dark:hover:bg-gray-700/50"
? "border-blue-500 border-l-2 bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300" }`}
: "text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-800" onClick={() => copyToClipboard(pm)}
}`} >
onClick={() => copyToClipboard(pm)} {pm === "bun" ? "🥟 bun" : pm}
> </button>
{pm === "npm" && "npm"} ))}
{pm === "pnpm" && "pnpm"}
{pm === "bun" && (
<span className="flex items-center">
<span className="mr-1">🥟</span> bun
</span>
)}
</button>
</li>
),
)}
</ul>
</motion.div> </motion.div>
)} )}
</div> </div>
</div> </div>
<div className="overflow-x-auto bg-gray-50 p-3 font-mono text-xs sm:p-4 sm:text-sm dark:bg-gray-900"> <div className="bg-gray-50 p-4 text-left font-mono text-sm dark:bg-gray-900">
<div className="flex items-center"> <div className="flex items-center">
<div className="flex-grow overflow-x-auto"> <span className="mr-2 text-gray-600 dark:text-gray-400">$</span>
<span className="mr-2 text-green-600 dark:text-green-400">$</span> <div className="flex-grow">
<span className="text-gray-700 dark:text-gray-300"> <span className="text-gray-800 dark:text-gray-200">
{commands[selectedPM]} {commands[selectedPM]}
</span> </span>
<span {step === 0 && (
className={ <span
typingComplete className={`ml-0.5 inline-block h-4 w-2 bg-gray-800 dark:bg-white ${showCursor ? "opacity-100" : "opacity-0"}`}
? "hidden" />
: "ml-1 animate-pulse text-blue-600 dark:text-blue-500" )}
}
>
</span>
</div> </div>
<motion.button <button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
type="button" type="button"
onClick={() => copyToClipboard(selectedPM)} onClick={() => copyToClipboard(selectedPM)}
className="ml-2 flex-shrink-0 text-gray-600 transition-colors hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200" className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
title="Copy command"
> >
{copied ? ( {copied ? (
<Check className="h-4 w-4"> <Check className="h-4 w-4 text-gray-600 dark:text-gray-400" />
<title>Copied!</title>
</Check>
) : ( ) : (
<ClipboardCopy className="h-4 w-4"> <ClipboardCopy className="h-4 w-4" />
<title>Copy to clipboard</title>
</ClipboardCopy>
)} )}
</motion.button> </button>
</div> </div>
{typingComplete && ( {step > 0 && (
<motion.div <div className="mt-3 space-y-1.5 text-sm">
initial={{ opacity: 0 }} {step > 0 && (
animate={{ opacity: 1 }} <div className="text-gray-600 dark:text-gray-400">
className="overflow-x-auto" Creating a new Better-T-Stack project
> </div>
<div className="mt-3 pl-2 text-amber-600 sm:pl-4 dark:text-amber-400"> )}
{currentStep >= 1 && (
<motion.p
initial={{ opacity: 0, y: -5 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.1 }}
>
Creating a new Better-T-Stack project
</motion.p>
)}
{currentStep >= 2 && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.2 }}
className="mt-2"
>
<p className="text-gray-700 dark:text-gray-300">
Project name:{" "}
<span className="text-amber-600 dark:text-amber-400">
my-better-t-app
</span>
</p>
<p className="text-gray-700 dark:text-gray-300">
Frontend:{" "}
<span className="text-amber-600 dark:text-amber-400">
React Web
</span>
</p>
<p className="text-gray-700 dark:text-gray-300">
Runtime:{" "}
<span className="text-amber-600 dark:text-amber-400">
Bun
</span>
</p>
<p className="text-gray-700 dark:text-gray-300">
Backend:{" "}
<span className="text-amber-600 dark:text-amber-400">
Hono
</span>
</p>
<p className="text-gray-700 dark:text-gray-300">
Database:{" "}
<span className="text-amber-600 dark:text-amber-400">
SQLite + Drizzle
</span>
</p>
</motion.div>
)}
</div>
<motion.div {step > 1 && (
initial={{ opacity: 0 }} <div className="ml-2 grid grid-cols-[80px_1fr] gap-x-2 text-gray-700 text-xs dark:text-gray-300">
animate={{ opacity: 1 }} <span>Project:</span>
transition={{ delay: 0.3 }} <span className="text-gray-800 dark:text-gray-200">
className="mt-3 pl-2 sm:pl-4" my-app
> </span>
{currentStep >= 3 && ( <span>Frontend:</span>
<motion.p <span className="text-gray-800 dark:text-gray-200">
initial={{ opacity: 0, x: -5 }} React Web
animate={{ opacity: 1, x: 0 }} </span>
transition={{ delay: 0.4 }} <span>Backend:</span>
className="flex items-center text-blue-600 dark:text-blue-400" <span className="text-gray-800 dark:text-gray-200">Hono</span>
> <span>Database:</span>
<CircleCheck className="mr-1 h-4 w-4 flex-shrink-0"> <span className="text-gray-800 dark:text-gray-200">
<title>Completed</title> SQLite + Drizzle
</CircleCheck> </span>
<span>Creating project structure</span> </div>
</motion.p> )}
)}
{currentStep >= 4 && ( {step > 2 && (
<motion.p <div className="text-gray-600 dark:text-gray-400">
initial={{ opacity: 0, x: -5 }} Creating project structure
animate={{ opacity: 1, x: 0 }} </div>
transition={{ delay: 0.5 }} )}
className="flex items-center text-blue-600 dark:text-blue-400"
> {step > 3 && (
<CircleCheck className="mr-1 h-4 w-4 flex-shrink-0"> <div className="text-gray-600 dark:text-gray-400">
<title>Completed</title> Installing dependencies
</CircleCheck> </div>
<span>Installing dependencies</span> )}
</motion.p>
)} {step > 4 && (
{currentStep >= 5 && ( <div className="mt-2 border-gray-400 border-l-2 bg-gray-100 py-2 pl-3 text-xs dark:border-gray-600 dark:bg-gray-800">
<motion.div <span className="font-semibold text-gray-800 dark:text-gray-200">
initial={{ opacity: 0 }} Project created successfully! Run:
animate={{ opacity: 1 }} </span>
transition={{ delay: 0.6 }} <div className="mt-1 flex flex-wrap gap-1">
> <code className="rounded bg-gray-200 px-1 py-0.5 text-gray-800 dark:bg-gray-700 dark:text-white">
<motion.p cd my-app
initial={{ opacity: 0, x: -5 }} </code>
animate={{ opacity: 1, x: 0 }} <span className="text-gray-700 dark:text-gray-300">
transition={{ delay: 0.7 }} and
className="flex items-center text-blue-600 dark:text-blue-400" </span>
> <code className="rounded bg-gray-200 px-1 py-0.5 text-gray-800 dark:bg-gray-700 dark:text-white">
<CircleCheck className="mr-1 h-4 w-4 flex-shrink-0"> {selectedPM === "npm"
<title>Completed</title> ? "npm run dev"
</CircleCheck> : selectedPM === "pnpm"
<span>Setting up database schema</span> ? "pnpm dev"
</motion.p> : "bun dev"}
<motion.p </code>
initial={{ opacity: 0, x: -5 }} </div>
animate={{ opacity: 1, x: 0 }} </div>
transition={{ delay: 0.8 }} )}
className="flex items-center text-blue-600 dark:text-blue-400" </div>
>
<CircleCheck className="mr-1 h-4 w-4 flex-shrink-0">
<title>Completed</title>
</CircleCheck>
<span>Configuring authentication</span>
</motion.p>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.9 }}
className="mt-4 flex xs:flex-row flex-col xs:items-center rounded border border-blue-300 bg-blue-100 px-2 py-2 text-[10px] text-blue-800 sm:text-xs dark:border-blue-800/30 dark:bg-blue-900/20 dark:text-blue-300"
>
<svg
className="xs:mr-2 mb-1 xs:mb-0 h-4 w-4 flex-shrink-0 text-blue-600 dark:text-blue-400"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<title>Success</title>
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" />
<polyline points="22 4 12 14.01 9 11.01" />
</svg>
<div className="flex flex-wrap">
<span className="mr-1">Project ready! Run</span>
<code className="mr-1 mb-1 xs:mb-0 rounded bg-blue-200 px-1 py-0.5 dark:bg-blue-800/50">
cd my-better-t-app
</code>
<span className="mr-1">and</span>
<code className="rounded bg-blue-200 px-1 py-0.5 dark:bg-blue-800/50">
{selectedPM === "npm" && "npm run dev"}
{selectedPM === "pnpm" && "pnpm dev"}
{selectedPM === "bun" && "bun dev"}
</code>
</div>
</motion.div>
</motion.div>
)}
</motion.div>
</motion.div>
)} )}
<div {step > 4 && (
className={`mt-4 flex ${ <div className="mt-3 flex items-center">
currentStep >= 5 && typingComplete ? "" : "hidden" <span className="mr-2 text-gray-600 dark:text-gray-400">$</span>
}`} <span
> className={`inline-block h-4 w-2 bg-gray-800 dark:bg-white ${showCursor ? "opacity-100" : "opacity-0"}`}
<span className="mr-2 text-green-600 dark:text-green-400">$</span> />
<span className="animate-pulse text-blue-600 dark:text-blue-500"> </div>
)}
</span>
</div>
</div> </div>
<div className="border-gray-300 border-t bg-gray-200 px-2 py-2 sm:px-4 dark:border-gray-700 dark:bg-gray-900"> <div className="border-gray-200 border-t bg-gray-50 px-4 py-1.5 text-left text-gray-600 text-xs dark:border-gray-800 dark:bg-gray-900 dark:text-gray-400">
<div className="flex items-center justify-center text-center text-[10px] text-gray-600 sm:text-xs dark:text-gray-400"> For customization options:{" "}
<span className="inline-flex flex-wrap items-center justify-center gap-1"> <code className="rounded bg-gray-200 px-1 py-0.5 text-gray-700 dark:bg-gray-700 dark:text-gray-300">
<span>For custom options, use</span> {selectedPM === "npm"
<code className="whitespace-nowrap rounded bg-gray-300 px-1 py-0.5 dark:bg-gray-700"> ? "npx"
{selectedPM === "npm" && "npx"} : selectedPM === "pnpm"
{selectedPM === "pnpm" && "pnpm dlx"} ? "pnpm dlx"
{selectedPM === "bun" && "bunx"} create-better-t-stack : "bunx"}{" "}
</code> create-better-t-stack
<span>without flags</span> </code>
</span>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -13,11 +13,8 @@ export default function CustomizableSection() {
transition={{ duration: 0.5 }} transition={{ duration: 0.5 }}
className="relative" className="relative"
> >
<h2 className="font-bold text-3xl sm:text-4xl"> <h2 className="font-bold font-mono text-2xl tracking-tight sm:text-3xl md:text-4xl lg:text-5xl">
<span className="mr-1 font-mono text-blue-500 dark:text-blue-400"> <span className="border-blue-500 border-b-2 pb-1 text-gray-900 dark:text-blue-100">
{">"}
</span>
<span className="bg-gradient-to-r from-blue-500 to-indigo-600 bg-clip-text text-transparent dark:from-blue-400 dark:to-indigo-500">
Your Stack, Your Choice Your Stack, Your Choice
</span> </span>
</h2> </h2>

View File

@@ -1,18 +0,0 @@
const SideCircles = () => {
return (
<>
<div>
<div className="-translate-y-1/2 -left-[30%] fixed top-1/2 z-40 h-[50vh] w-[40vw] rounded-full bg-gradient-to-b from-transparent via-violet-950/20 to-transparent backdrop-blur-xl" />
<div className="-translate-y-1/2 -left-[35%] fixed top-1/2 z-50 h-[40vh] w-[40vw] rounded-full bg-gradient-to-b from-transparent via-violet-950/20 to-transparent backdrop-blur-xl" />
<div className="-translate-y-1/2 -left-[25%] fixed top-1/2 z-30 h-[60vh] w-[40vw] rounded-full bg-gradient-to-b from-transparent via-violet-950/20 to-transparent backdrop-blur-xl" />
</div>
<div>
<div className="-translate-y-1/2 -right-[35%] fixed top-1/2 z-50 h-[40vh] w-[40vw] rounded-full bg-gradient-to-b from-transparent via-violet-950/20 to-transparent backdrop-blur-xl" />
<div className="-translate-y-1/2 -right-[30%] fixed top-1/2 z-40 h-[50vh] w-[40vw] rounded-full bg-gradient-to-b from-transparent via-violet-950/20 to-transparent backdrop-blur-xl" />
<div className="-translate-y-1/2 -right-[25%] fixed top-1/2 z-30 h-[60vh] w-[40vw] rounded-full bg-gradient-to-b from-transparent via-violet-950/20 to-transparent backdrop-blur-xl" />
</div>
</>
);
};
export default SideCircles;

View File

@@ -19,7 +19,9 @@ const TWEET_IDS = [
"1904301540422070671", "1904301540422070671",
"1904338606409531710", "1904338606409531710",
"1904318186750652606", "1904318186750652606",
"1908568583799484519",
"1904179661086556412", "1904179661086556412",
"1908558365128876311",
"1907772878139072851", "1907772878139072851",
"1906149740095705265", "1906149740095705265",
"1906001923456790710", "1906001923456790710",
@@ -82,11 +84,8 @@ export default function Testimonials() {
transition={{ duration: 0.5 }} transition={{ duration: 0.5 }}
className="relative" className="relative"
> >
<h2 className="font-bold text-3xl sm:text-4xl"> <h2 className="font-bold font-mono text-2xl tracking-tight sm:text-3xl md:text-4xl lg:text-5xl">
<span className="mr-1 font-mono text-blue-500 dark:text-blue-400"> <span className="border-blue-500 border-b-2 pb-1 text-gray-900 dark:text-blue-100">
{">"}
</span>
<span className="bg-gradient-to-r from-blue-500 to-indigo-600 bg-clip-text text-transparent dark:from-blue-400 dark:to-indigo-500">
Developer Feedback Developer Feedback
</span> </span>
</h2> </h2>

View File

@@ -9,13 +9,13 @@ import Testimonials from "./_components/Testimonials";
export default function HomePage() { export default function HomePage() {
return ( return (
<main className="flex flex-col items-center justify-start px-2 pt-24 pb-10 sm:px-4 sm:pb-16 md:px-8 md:pt-28"> <main className="flex flex-col items-center justify-start px-2 pt-24 pb-10 sm:px-4 sm:pb-16 md:px-8 md:pt-28 lg:pt-36">
<BackgroundGradients /> <BackgroundGradients />
<div className="relative z-10 mx-auto mb-10 max-w-5xl text-center sm:mb-16"> <div className="relative z-10 mx-auto mb-10 max-w-5xl text-center sm:mb-16">
<div className="px-1 sm:px-6 lg:px-8"> <div className="px-1 sm:px-6 lg:px-8">
<div className="flex flex-col items-center justify-center space-y-3 text-center sm:space-y-4"> <div className="flex flex-col items-center justify-center space-y-3 text-center sm:space-y-4">
<h1 className="font-bold text-4xl text-gray-900 xs:text-5xl tracking-tight sm:text-6xl md:text-7xl dark:text-white"> <h1 className="font-bold font-mono text-4xl xs:text-5xl tracking-tight sm:text-6xl md:text-7xl">
<span className="block bg-gradient-to-r from-blue-500 to-indigo-600 bg-clip-text pb-1 text-transparent"> <span className="border-blue-500 border-b-2 pb-1 text-gray-900 dark:text-blue-100">
Better-T Stack Better-T Stack
</span> </span>
</h1> </h1>
@@ -24,7 +24,7 @@ export default function HomePage() {
<NpmPackage /> <NpmPackage />
</div> </div>
<p className="max-w-2xl px-1 font-medium text-gray-600 text-lg sm:text-xl dark:text-gray-300"> <p className="max-w-2xl px-1 font-mono text-gray-600 text-lg sm:text-xl dark:text-gray-300">
A modern CLI tool for scaffolding end-to-end type-safe TypeScript A modern CLI tool for scaffolding end-to-end type-safe TypeScript
projects with best practices and customizable configurations projects with best practices and customizable configurations
</p> </p>
@@ -36,14 +36,10 @@ export default function HomePage() {
<ShinyText <ShinyText
text="Type-safe. Modern. Minimal. Fast." text="Type-safe. Modern. Minimal. Fast."
speed={3} speed={3}
className="text-gray-600 text-xs xs:text-sm sm:text-base dark:text-gray-400" className="font-mono text-gray-600 text-xs xs:text-sm sm:text-base dark:text-gray-400"
/> />
</div> </div>
</div> </div>
<div className="-z-10 absolute inset-0">
<div className="-skew-y-12 absolute inset-0 transform bg-gradient-to-r from-blue-300/20 to-indigo-300/20 blur-2xl dark:from-purple-500/20 dark:to-indigo-500/20 dark:blur-3xl" />
</div>
</div> </div>
<CustomizableSection /> <CustomizableSection />
@@ -57,10 +53,10 @@ export default function HomePage() {
</div> </div>
<div className="px-4 sm:px-6"> <div className="px-4 sm:px-6">
<div className="flex h-7 w-7 items-center justify-center rounded-full bg-gradient-to-br from-blue-500 to-indigo-600 shadow-md sm:h-8 sm:w-8"> <div className="flex h-7 w-7 items-center justify-center rounded-full border border-blue-500 bg-white sm:h-8 sm:w-8 dark:bg-gray-900">
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
className="h-3.5 w-3.5 text-white sm:h-4 sm:w-4" className="h-3.5 w-3.5 text-blue-500 sm:h-4 sm:w-4"
viewBox="0 0 20 20" viewBox="0 0 20 20"
fill="currentColor" fill="currentColor"
> >
@@ -75,12 +71,12 @@ export default function HomePage() {
</div> </div>
<div className="hidden w-1/3 items-center sm:flex"> <div className="hidden w-1/3 items-center sm:flex">
<div className="h-2 w-2 rounded-full bg-indigo-500/50" /> <div className="h-2 w-2 rounded-full bg-blue-500/50" />
<div className="h-px flex-grow bg-gradient-to-l from-transparent to-indigo-500/40" /> <div className="h-px flex-grow bg-gradient-to-l from-transparent to-blue-500/40" />
</div> </div>
</div> </div>
<div className="mt-6 h-px w-full bg-gradient-to-r from-blue-500/20 via-indigo-500/40 to-blue-500/20 sm:hidden" /> <div className="mt-6 h-px w-full bg-blue-500/20 sm:hidden" />
</div> </div>
</div> </div>

View File

@@ -72,7 +72,7 @@
} }
/* custom scrollbar */ /* custom scrollbar */
::-webkit-scrollbar { /* ::-webkit-scrollbar {
width: 8px; width: 8px;
} }
@@ -90,4 +90,4 @@
::-webkit-scrollbar-thumb:hover { ::-webkit-scrollbar-thumb:hover {
background: linear-gradient(45deg, #888, #aaa); background: linear-gradient(45deg, #888, #aaa);
} } */