Repository: Shreyas-29/astra
Branch: main
Commit: 8e9cd78b5bab
Files: 43
Total size: 136.7 KB
Directory structure:
gitextract_hcimz5hd/
├── .eslintrc.json
├── .gitignore
├── .vscode/
│ └── settings.json
├── LICENSE
├── README.md
├── components.json
├── next.config.mjs
├── package.json
├── postcss.config.mjs
├── src/
│ ├── app/
│ │ ├── (auth)/
│ │ │ ├── layout.tsx
│ │ │ ├── sign-in/
│ │ │ │ └── [[...sign-in]]/
│ │ │ │ └── page.tsx
│ │ │ └── sign-up/
│ │ │ └── [[...sign-up]]/
│ │ │ └── page.tsx
│ │ ├── (marketing)/
│ │ │ ├── layout.tsx
│ │ │ └── page.tsx
│ │ └── layout.tsx
│ ├── components/
│ │ ├── global/
│ │ │ ├── container.tsx
│ │ │ ├── icons.tsx
│ │ │ └── wrapper.tsx
│ │ ├── home/
│ │ │ └── navigation/
│ │ │ ├── footer.tsx
│ │ │ └── navbar.tsx
│ │ ├── index.ts
│ │ ├── providers/
│ │ │ ├── providers.tsx
│ │ │ └── theme-provider.tsx
│ │ └── ui/
│ │ ├── border-beam.tsx
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ ├── dialog.tsx
│ │ ├── input.tsx
│ │ ├── label.tsx
│ │ ├── lamp.tsx
│ │ ├── marquee.tsx
│ │ ├── section-badge.tsx
│ │ ├── select.tsx
│ │ ├── sheet.tsx
│ │ ├── sonner.tsx
│ │ └── textarea.tsx
│ ├── config/
│ │ └── index.ts
│ ├── constants/
│ │ └── index.ts
│ ├── lib/
│ │ └── utils.ts
│ ├── middleware.ts
│ └── styles/
│ └── globals.css
├── tailwind.config.ts
└── tsconfig.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .eslintrc.json
================================================
{
"extends": "next/core-web-vitals"
}
================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env*.local
.env
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
================================================
FILE: .vscode/settings.json
================================================
{
"WillLuke.nextjs.addTypesOnSave": true,
"WillLuke.nextjs.hasPrompted": true
}
================================================
FILE: LICENSE
================================================
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.
================================================
FILE: README.md
================================================
<h1 align="start">
Astra - AI Powered Website Builder
</h1>
<img width="1280" alt="Astra Thumbnail" src="https://github.com/user-attachments/assets/8d11fc9c-8220-4d36-a0e3-271b73a7f23d">
## Introduction
Astra is a modern, fully responsive website built with a powerful tech stack. This project showcases the use of Next.js for server-side rendering, TailwindCSS for sleek styling, shadcn UI for elegant components, and Clerk for secure authentication.
## Watch Tutorial on YouTube
Check out the preivew to see how this website was built: [Astra Website Tutorial](https://youtu.be/zSz67kLPbZY?si=mVBTTh23pv_roRHQ)
## Tech Stack
- **Next.js**: For building the React-based website.
- **TailwindCSS**: For styling with utility-first CSS.
- **Shadcn UI**: For UI components.
- **Magic UI**: For UI components.
- **Clerk**: For user authentication.
## Quick Start
### Prerequisites
Make sure that you have installed
- Node.js
- Git
- npm / yarn / pnpm / bun
1. Clone this repository:
```bash
git clone https://github.com/Shreyas-29/astra-website.git
cd astra-website
```
2. Install dependencies:
```bash
npm install
```
3. Setup env variables:
```bash
# app
NEXT_PUBLIC_URL=http://localhost:3000
NEXT_PUBLIC_DOMAIN=localhost:3000
# clerk
CLERK_SECRET_KEY=
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/
```
5. Run the development server:
```bash
npm run dev
```
6. Open your browser and navigate to http://localhost:3000 to see the website in action.
## Assets
Download all the assets required for this project [here](https://drive.google.com).
## ☕ Buy Me a Coffee
If you enjoy using caps.ai, consider supporting my work!
[Buy Me a Coffee ☕](https://buymeacoffee.com/shreyas29)
================================================
FILE: components.json
================================================
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
================================================
FILE: next.config.mjs
================================================
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
domains: [
'utfs.io',
'img.clerk.com',
'subdomain',
],
},
reactStrictMode: false,
};
export default nextConfig;
================================================
FILE: package.json
================================================
{
"name": "astra",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@clerk/nextjs": "^5.2.3",
"@clerk/themes": "^2.1.7",
"@hookform/resolvers": "^3.4.2",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-aspect-ratio": "^1.0.3",
"@radix-ui/react-avatar": "^1.0.4",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-collapsible": "^1.0.3",
"@radix-ui/react-context-menu": "^2.1.5",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-hover-card": "^1.0.7",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-menubar": "^1.0.4",
"@radix-ui/react-navigation-menu": "^1.1.4",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-progress": "^1.0.3",
"@radix-ui/react-radio-group": "^1.1.3",
"@radix-ui/react-scroll-area": "^1.0.5",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slider": "^1.1.2",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toast": "^1.1.5",
"@radix-ui/react-toggle": "^1.0.3",
"@radix-ui/react-toggle-group": "^1.0.4",
"@radix-ui/react-tooltip": "^1.0.7",
"@react-three/drei": "^9.105.6",
"@react-three/fiber": "^8.16.6",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cmdk": "^1.0.0",
"date-fns": "^3.6.0",
"embla-carousel-react": "^8.1.3",
"framer-motion": "^11.2.6",
"input-otp": "^1.2.4",
"lucide-react": "^0.379.0",
"next": "14.2.3",
"next-themes": "^0.3.0",
"react": "^18",
"react-day-picker": "^8.10.1",
"react-dom": "^18",
"react-hook-form": "^7.51.5",
"react-resizable-panels": "^2.0.19",
"sonner": "^1.4.41",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7",
"three": "^0.164.1",
"three-globe": "^2.31.0",
"vaul": "^0.9.1",
"zod": "^3.23.8"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"eslint": "^8",
"eslint-config-next": "14.2.3",
"postcss": "^8",
"tailwindcss": "^3.4.1",
"typescript": "^5"
}
}
================================================
FILE: postcss.config.mjs
================================================
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
tailwindcss: {},
},
};
export default config;
================================================
FILE: src/app/(auth)/layout.tsx
================================================
import React from 'react'
interface Props {
children: React.ReactNode;
}
const AuthLayout = ({ children }: Props) => {
return (
<div className="flex items-center justify-center h-screen">
{children}
</div>
)
};
export default AuthLayout
================================================
FILE: src/app/(auth)/sign-in/[[...sign-in]]/page.tsx
================================================
import { SignIn } from "@clerk/nextjs";
const SignInPage = () => {
return <SignIn />;
};
export default SignInPage;
================================================
FILE: src/app/(auth)/sign-up/[[...sign-up]]/page.tsx
================================================
import { SignUp } from "@clerk/nextjs";
const SignUpPage = () => {
return <SignUp />;
};
export default SignUpPage;
================================================
FILE: src/app/(marketing)/layout.tsx
================================================
import { Footer, Navbar } from "@/components";
import React from 'react'
interface Props {
children: React.ReactNode;
}
const MarketingLayout = ({ children }: Props) => {
return (
<div className="flex flex-col items-center w-full">
<Navbar />
{children}
<Footer />
</div>
)
};
export default MarketingLayout
================================================
FILE: src/app/(marketing)/page.tsx
================================================
import { Container, Icons, Wrapper } from "@/components";
import { BorderBeam } from "@/components/ui/border-beam";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { LampContainer } from "@/components/ui/lamp";
import Marquee from "@/components/ui/marquee";
import SectionBadge from "@/components/ui/section-badge";
import { features, perks, pricingCards, reviews } from "@/constants";
import { cn } from "@/lib/utils";
import { ArrowRight, ChevronRight, UserIcon, Zap } from "lucide-react";
import Image from "next/image";
import Link from "next/link";
const HomePage = () => {
const firstRow = reviews.slice(0, reviews.length / 2);
const secondRow = reviews.slice(reviews.length / 2);
return (
<section className="w-full relative flex items-center justify-center flex-col px-4 md:px-0 py-8">
{/* hero */}
<Wrapper>
<div className="absolute inset-0 dark:bg-[linear-gradient(to_right,#e2e8f0_1px,transparent_1px),linear-gradient(to_bottom,#e2e8f0_1px,transparent_1px)] bg-[linear-gradient(to_right,#161616_1px,transparent_1px),linear-gradient(to_bottom,#161616_1px,transparent_1px)] bg-[size:4rem_4rem] [mask-image:radial-gradient(ellipse_60%_50%_at_50%_0%,#000_70%,transparent_110%)] -z-10 h-[150vh]" />
<Container>
<div className="flex flex-col items-center justify-center py-20 h-full">
<button className="group relative grid overflow-hidden rounded-full px-4 py-1 shadow-[0_1000px_0_0_hsl(0_0%_20%)_inset] transition-colors duration-200">
<span>
<span className="spark mask-gradient absolute inset-0 h-[100%] w-[100%] animate-flip overflow-hidden rounded-full [mask:linear-gradient(white,_transparent_50%)] before:absolute before:aspect-square before:w-[200%] before:rotate-[-90deg] before:animate-rotate before:bg-[conic-gradient(from_0deg,transparent_0_340deg,white_360deg)] before:content-[''] before:[inset:0_auto_auto_50%] before:[translate:-50%_-15%]" />
</span>
<span className="backdrop absolute inset-[1px] rounded-full bg-neutral-950 transition-colors duration-200 group-hover:bg-neutral-900" />
<span className="h-full w-full blur-md absolute bottom-0 inset-x-0 bg-gradient-to-tr from-primary/40"></span>
<span className="z-10 py-0.5 text-sm text-neutral-100 flex items-center justify-center gap-1.5">
<Image src="/icons/sparkles-dark.svg" alt="✨" width={24} height={24} className="w-4 h-4" />
Introducing Astra AI
<ChevronRight className="w-4 h-4" />
</span>
</button>
<div className="flex flex-col items-center mt-8 max-w-3xl w-11/12 md:w-full">
<h1 className="text-4xl md:text-6xl lg:textxl md:!leading-snug font-semibold text-center bg-clip-text bg-gradient-to-b from-gray-50 to-gray-50 text-transparent">
Build your next idea and ship your dream site
</h1>
<p className="text-base md:text-lg text-foreground/80 mt-6 text-center">
Zero code, maximum speed. Make professional sites easy, fast and fun while delivering best-in-class SEO, performance.
</p>
<div className="hidden md:flex relative items-center justify-center mt-8 md:mt-12 w-full">
<Link href="#" className="flex items-center justify-center w-max rounded-full border-t border-foreground/30 bg-white/20 backdrop-blur-lg px-2 py-1 md:py-2 gap-2 md:gap-8 shadow-3xl shadow-background/40 cursor-pointer select-none">
<p className="text-foreground text-sm text-center md:text-base font-medium pl-4 pr-4 lg:pr-0">
✨ {" "} Start building your dream website now!
</p>
<Button size="sm" className="rounded-full hidden lg:flex border border-foreground/20">
Get Started
<ArrowRight className="w-4 h-4 ml-1" />
</Button>
</Link>
</div>
</div>
<div className="relative flex items-center py-10 md:py-20 w-full">
<div className="absolute top-1/2 left-1/2 -z-10 gradient w-3/4 -translate-x-1/2 h-3/4 -translate-y-1/2 inset-0 blur-[10rem]"></div>
<div className="-m-2 rounded-xl p-2 ring-1 ring-inset ring-foreground/20 lg:-m-4 lg:rounded-2xl bg-opacity-50 backdrop-blur-3xl">
<Image
src="/assets/dashboard.svg"
alt="banner image"
width={1200}
height={1200}
quality={100}
className="rounded-md lg:rounded-xl bg-foreground/10 shadow-2xl ring-1 ring-border"
/>
<BorderBeam size={250} duration={12} delay={9} />
</div>
</div>
</div>
</Container>
</Wrapper>
{/* how it works */}
<Wrapper className="flex flex-col items-center justify-center py-12 relative">
<Container>
<div className="max-w-md mx-auto text-start md:text-center">
<SectionBadge title="The Process" />
<h2 className="text-3xl lg:text-4xl font-semibold mt-6">
Three steps to build your dream website
</h2>
<p className="text-muted-foreground mt-6">
Turn your vision into reality in just 3 simple steps
</p>
</div>
</Container>
<Container>
<div className="flex flex-col items-center justify-center py-10 md:py-20 w-full">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 w-full divide-x-0 md:divide-x divide-y md:divide-y-0 divide-gray-900 first:border-l-2 lg:first:border-none first:border-gray-900">
{perks.map((perk) => (
<div key={perk.title} className="flex flex-col items-start px-4 md:px-6 lg:px-8 lg:py-6 py-4">
<div className="flex items-center justify-center">
<perk.icon className="w-8 h-8" />
</div>
<h3 className="text-lg font-medium mt-4">
{perk.title}
</h3>
<p className="text-muted-foreground mt-2 text-start lg:text-start">
{perk.info}
</p>
</div>
))}
</div>
</div>
</Container>
</Wrapper>
{/* features */}
<Wrapper className="flex flex-col items-center justify-center py-12 relative">
<div className="hidden md:block absolute top-0 -right-1/3 w-72 h-72 bg-primary rounded-full blur-[10rem] -z-10"></div>
<div className="hidden md:block absolute bottom-0 -left-1/3 w-72 h-72 bg-indigo-600 rounded-full blur-[10rem] -z-10"></div>
<Container>
<div className="max-w-md mx-auto text-start md:text-center">
<SectionBadge title="Features" />
<h2 className="text-3xl lg:text-4xl font-semibold mt-6">
Discover our powerful features
</h2>
<p className="text-muted-foreground mt-6">
Astra offers a range of features to help you build a stunning website in no time
</p>
</div>
</Container>
<Container>
<div className="flex items-center justify-center mx-auto mt-8">
<Icons.feature className="w-auto h-80" />
</div>
</Container>
<Container>
<div className="flex flex-col items-center justify-center py-10 md:py-20 w-full">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 w-full gap-8">
{features.map((feature) => (
<div key={feature.title} className="flex flex-col items-start lg:items-start px-0 md:px-0">
<div className="flex items-center justify-center">
<feature.icon className="w-8 h-8" />
</div>
<h3 className="text-lg font-medium mt-4">
{feature.title}
</h3>
<p className="text-muted-foreground mt-2 text-start lg:text-start">
{feature.info}
</p>
</div>
))}
</div>
</div>
</Container>
</Wrapper>
{/* pricing */}
<Wrapper className="flex flex-col items-center justify-center py-12 relative">
<div className="hidden md:block absolute top-0 -right-1/3 w-72 h-72 bg-blue-500 rounded-full blur-[10rem] -z-10"></div>
<Container>
<div className="max-w-md mx-auto text-start md:text-center">
<SectionBadge title="Pricing" />
<h2 className="text-3xl lg:text-4xl font-semibold mt-6">
Unlock the right plan for your business
</h2>
<p className="text-muted-foreground mt-6">
Choose the best plan for your business and start building your dream website today
</p>
</div>
</Container>
<Container className="flex items-center justify-center">
<div className="grid grid-cols-1 lg:grid-cols-3 gap-5 w-full md:gap-8 py-10 md:py-20 flex-wrap max-w-4xl">
{pricingCards.map((card) => (
<Card
key={card.title}
className={cn("flex flex-col w-full border-neutral-700",
card.title === "Unlimited Saas" && "border-2 border-primary"
)}
>
<CardHeader className="border-b border-border">
<span>
{card.title}
</span>
<CardTitle className={cn(card.title !== "Unlimited Saas" && "text-muted-foreground")}>
{card.price}
</CardTitle>
<CardDescription>
{card.description}
</CardDescription>
</CardHeader>
<CardContent className="pt-6 space-y-3">
{card.features.map((feature) => (
<div key={feature} className="flex items-center gap-2">
<Zap className="w-4 h-4 fill-primary text-primary" />
<p>{feature}</p>
</div>
))}
</CardContent>
<CardFooter className="mt-auto">
<Link
href="#"
className={cn(
"w-full text-center text-primary-foreground bg-primary p-2 rounded-md text-sm font-medium",
card.title !== "Unlimited Saas" && "!bg-foreground !text-background"
)}
>
{card.buttonText}
</Link>
</CardFooter>
</Card>
))}
</div>
</Container>
</Wrapper>
{/* testimonials */}
<Wrapper className="flex flex-col items-center justify-center py-12 relative">
<div className="hidden md:block absolute -top-1/4 -left-1/3 w-72 h-72 bg-indigo-500 rounded-full blur-[10rem] -z-10"></div>
<Container>
<div className="max-w-md mx-auto text-start md:text-center">
<SectionBadge title="Our Customers" />
<h2 className="text-3xl lg:text-4xl font-semibold mt-6">
What people are saying
</h2>
<p className="text-muted-foreground mt-6">
See how Astra empowers businesses of all sizes. Here's what real people are saying on Twitter
</p>
</div>
</Container>
<Container>
<div className="py-10 md:py-20 w-full">
<div className="relative flex h-full w-full flex-col items-center justify-center overflow-hidden py-10">
<Marquee pauseOnHover className="[--duration:20s] select-none">
{firstRow.map((review) => (
<figure
key={review.name}
className={cn(
"relative w-64 cursor-pointer overflow-hidden rounded-xl border p-4",
"border-zinc-50/[.1] bg-background over:bg-zinc-50/[.15]",
)}
>
<div className="flex flex-row items-center gap-2">
<UserIcon className="w-6 h-6" />
<div className="flex flex-col">
<figcaption className="text-sm font-medium">
{review.name}
</figcaption>
<p className="text-xs font-medium text-muted-foreground">{review.username}</p>
</div>
</div>
<blockquote className="mt-2 text-sm">{review.body}</blockquote>
</figure>
))}
</Marquee>
<Marquee reverse pauseOnHover className="[--duration:20s] select-none">
{secondRow.map((review) => (
<figure
key={review.name}
className={cn(
"relative w-64 cursor-pointer overflow-hidden rounded-xl border p-4",
"border-zinc-50/[.1] bg-background over:bg-zinc-50/[.15]",
)}
>
<div className="flex flex-row items-center gap-2">
<UserIcon className="w-6 h-6" />
<div className="flex flex-col">
<figcaption className="text-sm font-medium">
{review.name}
</figcaption>
<p className="text-xs font-medium text-muted-foreground">{review.username}</p>
</div>
</div>
<blockquote className="mt-2 text-sm">{review.body}</blockquote>
</figure>
))}
</Marquee>
<div className="pointer-events-none absolute inset-y-0 left-0 w-1/3 bg-gradient-to-r from-background"></div>
<div className="pointer-events-none absolute inset-y-0 right-0 w-1/3 bg-gradient-to-l from-background"></div>
</div>
</div>
</Container>
</Wrapper>
{/* newsletter */}
<Wrapper className="flex flex-col items-center justify-center py-12 relative">
<Container>
<LampContainer>
<div className="flex flex-col items-center justify-center relative w-full text-center">
<h2 className="text-4xl lg:text-5xl xl:text-6xl lg:!leading-snug font-semibold mt-8">
From Idea to Launch <br /> Faster Than Ever
</h2>
<p className="text-muted-foreground mt-6 max-w-md mx-auto">
Build stunning websites with Astra's intuitive drag-and-drop builder and powerful AI assistant
</p>
<Button variant="white" className="mt-6" asChild>
<Link href="/sign-in">
Get started for free
<ArrowRight className="w-4 h-4 ml-2" />
</Link>
</Button>
</div>
</LampContainer>
</Container>
<Container className="relative z-[999999]">
<div className="flex items-center justify-center w-full -mt-40">
<div className="flex flex-col md:flex-row items-start md:items-center justify-start md:justify-between w-full px-4 md:px-8 rounded-lg lg:rounded-2xl border border-border/80 py-4 md:py-8">
<div className="flex flex-col items-start gap-4 w-full">
<h4 className="text-xl md:text-2xl font-semibold">
Join our newsletter
</h4>
<p className="text-base text-muted-foreground">
Be up to date with everything about AI builder
</p>
</div>
<div className="flex flex-col items-start gap-2 md:min-w-80 mt-5 md:mt-0 w-full md:w-max">
<form action="#" className="flex flex-col md:flex-row items-center gap-2 w-full md:max-w-xs">
<Input
required
type="email"
placeholder="Enter your email"
className="focus-visible:ring-0 focus-visible:ring-transparent focus-visible:border-primary duration-300 w-full"
/>
<Button type="submit" size="sm" variant="secondary" className="w-full md:w-max">
Subscribe
</Button>
</form>
<p className="text-xs text-muted-foreground">
By subscribing you agree with our{" "}
<Link href="#">
Privacy Policy
</Link>
</p>
</div>
</div>
</div>
</Container>
</Wrapper>
</section>
)
};
export default HomePage
================================================
FILE: src/app/layout.tsx
================================================
import { Footer, Navbar } from "@/components";
import { SITE_CONFIG } from "@/config";
import { cn } from "@/lib/utils";
import "@/styles/globals.css";
import { ClerkProvider } from '@clerk/nextjs';
import { dark } from '@clerk/themes';
import { Inter } from "next/font/google";
const font = Inter({ subsets: ["latin"] });
export const metadata = SITE_CONFIG;
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en" suppressHydrationWarning>
<body
className={cn(
"min-h-screen bg-background text-foreground antialiased max-w-full overflow-x-hidden",
font.className
)}
>
<ClerkProvider appearance={{ baseTheme: dark }}>
{children}
</ClerkProvider>
</body>
</html>
);
};
================================================
FILE: src/components/global/container.tsx
================================================
"use client";
import { cn } from "@/lib/utils";
import { motion } from "framer-motion";
interface Props {
className?: string;
children: React.ReactNode;
delay?: number;
reverse?: boolean;
}
const Container = ({ children, className, delay = 0.2, reverse }: Props) => {
return (
<motion.div
className={cn("w-full h-full", className)}
initial={{ opacity: 0, y: reverse ? -20 : 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: false }}
transition={{ delay: delay, duration: 0.4, ease: "easeInOut", }}
>
{children}
</motion.div>
)
};
export default Container
================================================
FILE: src/components/global/icons.tsx
================================================
import { LucideProps } from "lucide-react";
type IconType = {
[key: string]: (props: LucideProps) => JSX.Element;
};
const Icons: IconType = {
logo: (props: LucideProps) => (
<svg {...props} width="186" height="186" viewBox="0 0 186 186" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="186" height="186" rx="36" fill="url(#paint0_linear_12_165)" />
<path d="M40.4109 85.8641C39.7491 86.1624 39 85.6783 39 84.9524V60.6142C39 60.2374 39.2117 59.8926 39.5478 59.7223L73.9958 42.2557C74.3087 42.097 74.6818 42.1139 74.979 42.3002L111.452 65.1567C111.786 65.3656 112.211 65.3596 112.538 65.1414L144.945 43.5365C145.61 43.0934 146.5 43.5698 146.5 44.3685V70.4449C146.5 70.7902 146.322 71.111 146.029 71.2936L112.513 92.1801C112.198 92.3768 111.799 92.3821 111.478 92.194L74.9458 70.7615C74.6662 70.5975 74.3244 70.5792 74.0288 70.7124L40.4109 85.8641Z" fill="white" />
<path d="M40.4109 138.364C39.7491 138.662 39 138.178 39 137.452V113.614C39 113.237 39.2117 112.893 39.5478 112.722L74.0014 95.2528C74.3113 95.0957 74.6804 95.1106 74.9765 95.2923L111.455 117.666C111.787 117.869 112.208 117.861 112.532 117.645L144.945 96.0365C145.61 95.5934 146.5 96.0698 146.5 96.8685V123.438C146.5 123.787 146.318 124.111 146.02 124.292L112.51 144.689C112.196 144.881 111.802 144.884 111.485 144.698L74.9458 123.262C74.6662 123.097 74.3244 123.079 74.0288 123.212L40.4109 138.364Z" fill="white" />
<defs>
<linearGradient id="paint0_linear_12_165" x1="93" y1="0" x2="93" y2="186" gradientUnits="userSpaceOnUse">
<stop stopColor="#2563EB" />
<stop offset="1" stopColor="#153885" />
</linearGradient>
</defs>
</svg>
),
astra: (props: LucideProps) => (
<svg {...props} width="120" height="36" viewBox="0 0 120 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M25.75 35L23.65 28.7H9.7L7.6 35H0.15L12.4 -2.38419e-06H20.95L33.25 35H25.75ZM11.9 22.25H21.5L16.7 7.95L11.9 22.25ZM42.0543 17.1C42.0543 17.7667 42.4876 18.3167 43.3543 18.75C44.2543 19.15 45.3376 19.5167 46.6043 19.85C47.871 20.15 49.1376 20.55 50.4043 21.05C51.671 21.5167 52.7376 22.3167 53.6043 23.45C54.5043 24.5833 54.9543 26 54.9543 27.7C54.9543 30.2667 53.9876 32.25 52.0543 33.65C50.1543 35.0167 47.771 35.7 44.9043 35.7C39.771 35.7 36.271 33.7167 34.4043 29.75L40.0043 26.6C40.7376 28.7667 42.371 29.85 44.9043 29.85C47.2043 29.85 48.3543 29.1333 48.3543 27.7C48.3543 27.0333 47.9043 26.5 47.0043 26.1C46.1376 25.6667 45.071 25.2833 43.8043 24.95C42.5376 24.6167 41.271 24.2 40.0043 23.7C38.7376 23.2 37.6543 22.4167 36.7543 21.35C35.8876 20.25 35.4543 18.8833 35.4543 17.25C35.4543 14.7833 36.3543 12.85 38.1543 11.45C39.9876 10.0167 42.2543 9.3 44.9543 9.3C46.9876 9.3 48.8376 9.76667 50.5043 10.7C52.171 11.6 53.4876 12.9 54.4543 14.6L48.9543 17.6C48.1543 15.9 46.821 15.05 44.9543 15.05C44.121 15.05 43.421 15.2333 42.8543 15.6C42.321 15.9667 42.0543 16.4667 42.0543 17.1ZM72.6699 16.2H67.0199V26.6C67.0199 27.4667 67.2366 28.1 67.6699 28.5C68.1033 28.9 68.7366 29.1333 69.5699 29.2C70.4033 29.2333 71.4366 29.2167 72.6699 29.15V35C68.2366 35.5 65.1033 35.0833 63.2699 33.75C61.4699 32.4167 60.5699 30.0333 60.5699 26.6V16.2H56.2199V10H60.5699V4.95L67.0199 3V10H72.6699V16.2ZM84.0582 14.3C84.6582 12.7 85.6415 11.5 87.0082 10.7C88.4082 9.9 89.9582 9.5 91.6582 9.5V16.7C89.6915 16.4667 87.9249 16.8667 86.3582 17.9C84.8249 18.9333 84.0582 20.65 84.0582 23.05V35H77.6082V10H84.0582V14.3ZM113.503 10H119.953V35H113.503V32.05C111.569 34.4833 108.853 35.7 105.353 35.7C102.019 35.7 99.1527 34.4333 96.7527 31.9C94.3861 29.3333 93.2027 26.2 93.2027 22.5C93.2027 18.8 94.3861 15.6833 96.7527 13.15C99.1527 10.5833 102.019 9.3 105.353 9.3C108.853 9.3 111.569 10.5167 113.503 12.95V10ZM101.603 27.6C102.903 28.9 104.553 29.55 106.553 29.55C108.553 29.55 110.203 28.9 111.503 27.6C112.836 26.2667 113.503 24.5667 113.503 22.5C113.503 20.4333 112.836 18.75 111.503 17.45C110.203 16.1167 108.553 15.45 106.553 15.45C104.553 15.45 102.903 16.1167 101.603 17.45C100.303 18.75 99.6527 20.4333 99.6527 22.5C99.6527 24.5667 100.303 26.2667 101.603 27.6Z" fill="url(#paint0_linear_13_171)" />
<defs>
<linearGradient id="paint0_linear_13_171" x1="-4.57438" y1="21" x2="123" y2="21" gradientUnits="userSpaceOnUse">
<stop stopColor="#fff" />
<stop offset="1" stopColor="#fff" />
</linearGradient>
</defs>
</svg>
),
sparkles: (props: LucideProps) => (
<svg {...props} width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M8.00044 3.5C8.1634 3.50003 8.32192 3.55315 8.45201 3.6513C8.5821 3.74945 8.67667 3.8873 8.72144 4.044L9.53444 6.89C9.70949 7.50292 10.0379 8.0611 10.4886 8.51183C10.9393 8.96255 11.4975 9.29095 12.1104 9.466L14.9564 10.279C15.113 10.3239 15.2508 10.4185 15.3488 10.5486C15.4469 10.6786 15.4999 10.8371 15.4999 11C15.4999 11.1629 15.4469 11.3214 15.3488 11.4514C15.2508 11.5815 15.113 11.6761 14.9564 11.721L12.1104 12.534C11.4975 12.709 10.9393 13.0374 10.4886 13.4882C10.0379 13.9389 9.70949 14.4971 9.53444 15.11L8.72144 17.956C8.67658 18.1126 8.58195 18.2503 8.45187 18.3484C8.32179 18.4464 8.16333 18.4995 8.00044 18.4995C7.83754 18.4995 7.67908 18.4464 7.549 18.3484C7.41892 18.2503 7.32429 18.1126 7.27944 17.956L6.46644 15.11C6.29139 14.4971 5.96299 13.9389 5.51226 13.4882C5.06154 13.0374 4.50335 12.709 3.89044 12.534L1.04444 11.721C0.887841 11.6761 0.750108 11.5815 0.652059 11.4514C0.55401 11.3214 0.500977 11.1629 0.500977 11C0.500977 10.8371 0.55401 10.6786 0.652059 10.5486C0.750108 10.4185 0.887841 10.3239 1.04444 10.279L3.89044 9.466C4.50335 9.29095 5.06154 8.96255 5.51226 8.51183C5.96299 8.0611 6.29139 7.50292 6.46644 6.89L7.27944 4.044C7.3242 3.8873 7.41878 3.74945 7.54887 3.6513C7.67895 3.55315 7.83747 3.50003 8.00044 3.5ZM17.0004 0.5C17.1678 0.499907 17.3303 0.555764 17.4622 0.658686C17.5941 0.761609 17.6878 0.905686 17.7284 1.068L17.9864 2.104C18.1023 2.56533 18.3412 2.98659 18.6775 3.32294C19.0138 3.65928 19.4351 3.89811 19.8964 4.014L20.9324 4.272C21.0951 4.31228 21.2395 4.40586 21.3428 4.5378C21.446 4.66974 21.5021 4.83246 21.5021 5C21.5021 5.16754 21.446 5.33026 21.3428 5.4622C21.2395 5.59414 21.0951 5.68772 20.9324 5.728L19.8964 5.986C19.4351 6.10189 19.0138 6.34072 18.6775 6.67706C18.3412 7.01341 18.1023 7.43467 17.9864 7.896L17.7284 8.932C17.6882 9.09463 17.5946 9.23908 17.4626 9.34233C17.3307 9.44558 17.168 9.50168 17.0004 9.50168C16.8329 9.50168 16.6702 9.44558 16.5382 9.34233C16.4063 9.23908 16.3127 9.09463 16.2724 8.932L16.0144 7.896C15.8985 7.43467 15.6597 7.01341 15.3234 6.67706C14.987 6.34072 14.5658 6.10189 14.1044 5.986L13.0684 5.728C12.9058 5.68772 12.7614 5.59414 12.6581 5.4622C12.5549 5.33026 12.4988 5.16754 12.4988 5C12.4988 4.83246 12.5549 4.66974 12.6581 4.5378C12.7614 4.40586 12.9058 4.31228 13.0684 4.272L14.1044 4.014C14.5658 3.89811 14.987 3.65928 15.3234 3.32294C15.6597 2.98659 15.8985 2.56533 16.0144 2.104L16.2724 1.068C16.313 0.905686 16.4067 0.761609 16.5387 0.658686C16.6706 0.555764 16.8331 0.499907 17.0004 0.5ZM15.5004 14C15.658 13.9999 15.8115 14.0494 15.9393 14.1415C16.0671 14.2336 16.1627 14.3636 16.2124 14.513L16.6064 15.696C16.7564 16.143 17.1064 16.495 17.5544 16.644L18.7374 17.039C18.8864 17.089 19.0159 17.1845 19.1076 17.3121C19.1994 17.4397 19.2487 17.5929 19.2487 17.75C19.2487 17.9071 19.1994 18.0603 19.1076 18.1879C19.0159 18.3155 18.8864 18.411 18.7374 18.461L17.5544 18.856C17.3337 18.9297 17.1332 19.0537 16.9686 19.2182C16.8041 19.3827 16.6801 19.5833 16.6064 19.804L16.2114 20.987C16.1614 21.136 16.0659 21.2655 15.9383 21.3572C15.8107 21.4489 15.6576 21.4983 15.5004 21.4983C15.3433 21.4983 15.1901 21.4489 15.0626 21.3572C14.935 21.2655 14.8394 21.136 14.7894 20.987L14.3944 19.804C14.3208 19.5833 14.1968 19.3827 14.0322 19.2182C13.8677 19.0537 13.6672 18.9297 13.4464 18.856L12.2634 18.461C12.1145 18.411 11.985 18.3155 11.8932 18.1879C11.8015 18.0603 11.7521 17.9071 11.7521 17.75C11.7521 17.5929 11.8015 17.4397 11.8932 17.3121C11.985 17.1845 12.1145 17.089 12.2634 17.039L13.4464 16.644C13.6672 16.5703 13.8677 16.4463 14.0322 16.2818C14.1968 16.1173 14.3208 15.9167 14.3944 15.696L14.7894 14.513C14.8392 14.3637 14.9346 14.2339 15.0622 14.1418C15.1898 14.0497 15.3431 14.0001 15.5004 14Z" fill="white" />
</svg>
),
bolt: (props: LucideProps) => (
<svg {...props} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.926 9.70541C13.5474 9.33386 13.5474 8.74151 13.5474 7.55682V7.24712C13.5474 3.96249 13.5474 2.32018 12.6241 2.03721C11.7007 1.75425 10.711 3.09327 8.73167 5.77133L5.66953 9.91436C4.3848 11.6526 3.74244 12.5217 4.09639 13.205C4.10225 13.2164 4.10829 13.2276 4.1145 13.2387C4.48945 13.9117 5.59888 13.9117 7.81775 13.9117C9.05079 13.9117 9.6673 13.9117 10.054 14.2754" stroke="white" strokeWidth="1.5" />
<path opacity="0.5" d="M13.9256 9.70557L13.9456 9.72481C14.3323 10.0885 14.9489 10.0885 16.1819 10.0885C18.4008 10.0885 19.5102 10.0885 19.8851 10.7615C19.8914 10.7726 19.8974 10.7838 19.9033 10.7951C20.2572 11.4785 19.6148 12.3476 18.3301 14.0858L15.2679 18.2288C13.2885 20.9069 12.2988 22.2459 11.3755 21.9629C10.4521 21.68 10.4521 20.0376 10.4522 16.753V16.4434C10.4522 15.2587 10.4522 14.6663 10.0737 14.2948L10.0537 14.2755" stroke="white" strokeWidth="1.5" />
</svg>
),
palette: (props: LucideProps) => (
<svg {...props} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2 12.0261C2 17.1723 5.86713 21.413 10.8468 21.9863C11.5816 22.0709 12.2938 21.7576 12.8168 21.2333C13.4703 20.5781 13.4703 19.5159 12.8168 18.8607C12.2938 18.3364 11.8674 17.5541 12.2619 16.9268C13.8385 14.4192 22 20.178 22 12.0261C22 6.48884 17.5228 2 12 2C6.47715 2 2 6.48884 2 12.0261Z" stroke="white" strokeWidth="1.5" />
<path opacity="0.5" d="M17.5 13C18.3284 13 19 12.3284 19 11.5C19 10.6716 18.3284 10 17.5 10C16.6716 10 16 10.6716 16 11.5C16 12.3284 16.6716 13 17.5 13Z" stroke="white" strokeWidth="1.5" />
<path opacity="0.5" d="M6.5 13C7.32843 13 8 12.3284 8 11.5C8 10.6716 7.32843 10 6.5 10C5.67157 10 5 10.6716 5 11.5C5 12.3284 5.67157 13 6.5 13Z" stroke="white" strokeWidth="1.5" />
<path opacity="0.5" d="M11 7C11 7.82842 10.3284 8.5 9.5 8.5C8.67157 8.5 8 7.82842 8 7C8 6.17157 8.67157 5.5 9.5 5.5C10.3284 5.5 11 6.17157 11 7Z" stroke="white" strokeWidth="1.5" />
<path opacity="0.5" d="M16 7C16 7.82843 15.3284 8.5 14.5 8.5C13.6716 8.5 13 7.82843 13 7C13 6.17157 13.6716 5.5 14.5 5.5C15.3284 5.5 16 6.17157 16 7Z" stroke="white" strokeWidth="1.5" />
</svg>
),
seo: (props: LucideProps) => (
<svg {...props} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22 13V12C22 8.22876 22 6.34315 20.8284 5.17157C19.6569 4 17.7712 4 14 4H10C6.22876 4 4.34315 4 3.17157 5.17157C2 6.34315 2 8.22876 2 12C2 15.7712 2 17.6569 3.17157 18.8284C4.34315 20 6.22876 20 10 20H13" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
<path opacity="0.4" d="M10 16H6" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
<path opacity="0.4" d="M2 10H22" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
<path d="M18 20C19.6569 20 21 18.6569 21 17C21 15.3431 19.6569 14 18 14C16.3431 14 15 15.3431 15 17C15 18.6569 16.3431 20 18 20Z" stroke="white" strokeWidth="1.5" />
<path d="M20.5 19.5L21.5 20.5" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
</svg>
),
monitor: (props: LucideProps) => (
<svg {...props} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11 17H8C5.17157 17 3.75736 17 2.87868 16.1213C2 15.2426 2 13.8284 2 11V10C2 6.22876 2 4.34315 3.17157 3.17157C4.34315 2 6.22876 2 10 2H15.5C17.8346 2 19.0019 2 19.8856 2.47231C20.5833 2.84525 21.1548 3.4167 21.5277 4.11441C22 4.99805 22 6.16537 22 8.5" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
<path d="M14 15C14 13.1144 14 12.1716 14.5858 11.5858C15.1716 11 16.1144 11 18 11C19.8856 11 20.8284 11 21.4142 11.5858C22 12.1716 22 13.1144 22 15V18C22 19.8856 22 20.8284 21.4142 21.4142C20.8284 22 19.8856 22 18 22C16.1144 22 15.1716 22 14.5858 21.4142C14 20.8284 14 19.8856 14 18V15Z" stroke="white" strokeWidth="1.5" />
<path opacity="0.5" d="M19 20H17" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
<path opacity="0.5" d="M11 22V22.75C11.4142 22.75 11.75 22.4142 11.75 22H11ZM8 21.25C7.58579 21.25 7.25 21.5858 7.25 22C7.25 22.4142 7.58579 22.75 8 22.75V21.25ZM11.75 17C11.75 16.5858 11.4142 16.25 11 16.25C10.5858 16.25 10.25 16.5858 10.25 17H11.75ZM11 21.25H8V22.75H11V21.25ZM11.75 22V17H10.25V22H11.75Z" fill="white" />
<path opacity="0.5" d="M11 13H2" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
</svg>
),
shop: (props: LucideProps) => (
<svg {...props} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.4998 2H14.4998L15.1516 8.51737C15.338 10.382 13.8738 12 11.9998 12C10.1259 12 8.6616 10.382 8.84806 8.51737L9.4998 2Z" stroke="white" strokeWidth="1.5" />
<path d="M3.32926 5.35133C3.50734 4.46093 3.59638 4.01573 3.77742 3.65484C4.15889 2.89439 4.8453 2.33168 5.66579 2.10675C6.05518 2 6.5092 2 7.41722 2H9.49953L8.775 9.24527C8.61862 10.8091 7.30269 12 5.73106 12C3.80061 12 2.35275 10.2339 2.73134 8.34093L3.32926 5.35133Z" stroke="white" strokeWidth="1.5" />
<path d="M20.6703 5.35133C20.4922 4.46093 20.4031 4.01573 20.2221 3.65484C19.8406 2.89439 19.1542 2.33168 18.3337 2.10675C17.9443 2 17.4903 2 16.5823 2H14.5L15.2245 9.24527C15.3809 10.8091 16.6968 12 18.2685 12C20.1989 12 21.6468 10.2339 21.2682 8.34093L20.6703 5.35133Z" stroke="white" strokeWidth="1.5" />
<path opacity="0.5" d="M8.75 21.5C8.75 21.9142 9.08579 22.25 9.5 22.25C9.91421 22.25 10.25 21.9142 10.25 21.5H8.75ZM13.75 21.5C13.75 21.9142 14.0858 22.25 14.5 22.25C14.9142 22.25 15.25 21.9142 15.25 21.5H13.75ZM12.5 21.25H11.5V22.75H12.5V21.25ZM4.25 14V11H2.75V14H4.25ZM19.75 11V14H21.25V11H19.75ZM11.5 21.25C9.59318 21.25 8.23851 21.2484 7.21085 21.1102C6.20476 20.975 5.62511 20.7213 5.2019 20.2981L4.14124 21.3588C4.88961 22.1071 5.83855 22.4392 7.01098 22.5969C8.16182 22.7516 9.63558 22.75 11.5 22.75V21.25ZM2.75 14C2.75 15.8644 2.74841 17.3382 2.90313 18.489C3.06076 19.6614 3.39288 20.6104 4.14124 21.3588L5.2019 20.2981C4.77869 19.8749 4.52502 19.2952 4.38976 18.2892C4.25159 17.2615 4.25 15.9068 4.25 14H2.75ZM12.5 22.75C14.3644 22.75 15.8382 22.7516 16.989 22.5969C18.1614 22.4392 19.1104 22.1071 19.8588 21.3588L18.7981 20.2981C18.3749 20.7213 17.7952 20.975 16.7892 21.1102C15.7615 21.2484 14.4068 21.25 12.5 21.25V22.75ZM19.75 14C19.75 15.9068 19.7484 17.2615 19.6102 18.2892C19.475 19.2952 19.2213 19.8749 18.7981 20.2981L19.8588 21.3588C20.6071 20.6104 20.9392 19.6614 21.0969 18.489C21.2516 17.3382 21.25 15.8644 21.25 14H19.75ZM10.25 21.5V18.5H8.75V21.5H10.25ZM13.75 18.5V21.5H15.25V18.5H13.75ZM12 16.75C12.4811 16.75 12.7918 16.7507 13.0273 16.7721C13.2524 16.7925 13.3341 16.8269 13.375 16.8505L14.125 15.5514C13.8178 15.3741 13.4918 15.308 13.1627 15.2782C12.8438 15.2493 12.4535 15.25 12 15.25V16.75ZM15.25 18.5C15.25 18.0465 15.2507 17.6562 15.2218 17.3373C15.192 17.0082 15.1259 16.6822 14.9486 16.375L13.6495 17.125C13.6731 17.1659 13.7075 17.2476 13.7279 17.4727C13.7493 17.7082 13.75 18.0189 13.75 18.5H15.25ZM13.375 16.8505C13.489 16.9163 13.5837 17.011 13.6495 17.125L14.9486 16.375C14.7511 16.033 14.467 15.7489 14.125 15.5514L13.375 16.8505ZM10.25 18.5C10.25 18.0189 10.2507 17.7082 10.2721 17.4727C10.2925 17.2476 10.3269 17.1659 10.3505 17.125L9.05144 16.375C8.87407 16.6822 8.80802 17.0082 8.77818 17.3373C8.74928 17.6562 8.75 18.0465 8.75 18.5H10.25ZM12 15.25C11.5465 15.25 11.1562 15.2493 10.8373 15.2782C10.5082 15.308 10.1822 15.3741 9.875 15.5514L10.625 16.8505C10.6659 16.8269 10.7476 16.7925 10.9727 16.7721C11.2082 16.7507 11.5189 16.75 12 16.75V15.25ZM10.3505 17.125C10.4163 17.011 10.511 16.9163 10.625 16.8505L9.875 15.5514C9.53296 15.7489 9.24892 16.033 9.05144 16.375L10.3505 17.125Z" fill="white" />
</svg>
),
server: (props: LucideProps) => (
<svg {...props} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.5" d="M2 17C2 15.1144 2 14.1716 2.58579 13.5858C3.17157 13 4.11438 13 6 13H18C19.8856 13 20.8284 13 21.4142 13.5858C22 14.1716 22 15.1144 22 17C22 18.8856 22 19.8284 21.4142 20.4142C20.8284 21 19.8856 21 18 21H6C4.11438 21 3.17157 21 2.58579 20.4142C2 19.8284 2 18.8856 2 17Z" stroke="white" strokeWidth="1.5" />
<path opacity="0.5" d="M2 6C2 4.11438 2 3.17157 2.58579 2.58579C3.17157 2 4.11438 2 6 2H18C19.8856 2 20.8284 2 21.4142 2.58579C22 3.17157 22 4.11438 22 6C22 7.88562 22 8.82843 21.4142 9.41421C20.8284 10 19.8856 10 18 10H6C4.11438 10 3.17157 10 2.58579 9.41421C2 8.82843 2 7.88562 2 6Z" stroke="white" strokeWidth="1.5" />
<path d="M11 6H18" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
<path d="M6 6H8" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
<path d="M11 17H18" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
<path d="M6 17H8" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
</svg>
),
auth: (props: LucideProps) => (
<svg {...props} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 16C9.85038 16.6303 10.8846 17 12 17C13.1154 17 14.1496 16.6303 15 16" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
<path d="M15 12C15.5523 12 16 11.3284 16 10.5C16 9.67157 15.5523 9 15 9C14.4477 9 14 9.67157 14 10.5C14 11.3284 14.4477 12 15 12Z" fill="white" />
<path d="M9 12C9.55228 12 10 11.3284 10 10.5C10 9.67157 9.55228 9 9 9C8.44772 9 8 9.67157 8 10.5C8 11.3284 8.44772 12 9 12Z" fill="white" />
<path opacity="0.5" d="M22 14C22 17.7712 22 19.6569 20.8284 20.8284C19.6569 22 17.7712 22 14 22" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
<path opacity="0.5" d="M10 22C6.22876 22 4.34315 22 3.17157 20.8284C2 19.6569 2 17.7712 2 14" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
<path opacity="0.5" d="M10 2C6.22876 2 4.34315 2 3.17157 3.17157C2 4.34315 2 6.22876 2 10" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
<path opacity="0.5" d="M14 2C17.7712 2 19.6569 2 20.8284 3.17157C22 4.34315 22 6.22876 22 10" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
</svg>
),
customize: (props: LucideProps) => (
<svg {...props} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.84453 7.92226C2.71849 6.79623 2.71849 4.97056 3.84453 3.84453C4.97056 2.71849 6.79623 2.71849 7.92226 3.84453L20.1555 16.0777C21.2815 17.2038 21.2815 19.0294 20.1555 20.1555C19.0294 21.2815 17.2038 21.2815 16.0777 20.1555L3.84453 7.92226Z" stroke="white" strokeWidth="1.5" />
<path opacity="0.5" d="M6 10L10 6" stroke="white" strokeWidth="1.5" strokeLinecap="round" />
<path d="M16.1 2.30719C16.261 1.8976 16.8385 1.8976 16.9994 2.30719L17.4298 3.40247C17.479 3.52752 17.5776 3.62651 17.7022 3.67583L18.7934 4.1078C19.2015 4.26934 19.2015 4.849 18.7934 5.01054L17.7022 5.44252C17.5776 5.49184 17.479 5.59082 17.4298 5.71587L16.9995 6.81115C16.8385 7.22074 16.261 7.22074 16.1 6.81116L15.6697 5.71587C15.6205 5.59082 15.5219 5.49184 15.3973 5.44252L14.3061 5.01054C13.898 4.849 13.898 4.26934 14.3061 4.1078L15.3973 3.67583C15.5219 3.62651 15.6205 3.52752 15.6697 3.40247L16.1 2.30719Z" stroke="white" />
<path opacity="0.5" d="M19.9672 9.12945C20.1281 8.71987 20.7057 8.71987 20.8666 9.12945L21.0235 9.5288C21.0727 9.65385 21.1713 9.75284 21.2959 9.80215L21.6937 9.95965C22.1018 10.1212 22.1018 10.7009 21.6937 10.8624L21.2959 11.0199C21.1713 11.0692 21.0727 11.1682 21.0235 11.2932L20.8666 11.6926C20.7057 12.1022 20.1281 12.1022 19.9672 11.6926L19.8103 11.2932C19.7611 11.1682 19.6625 11.0692 19.5379 11.0199L19.14 10.8624C18.732 10.7009 18.732 10.1212 19.14 9.95965L19.5379 9.80215C19.6625 9.75284 19.7611 9.65385 19.8103 9.5288L19.9672 9.12945Z" stroke="white" />
<path opacity="0.5" d="M5.1332 15.3072C5.29414 14.8976 5.87167 14.8976 6.03261 15.3072L6.18953 15.7065C6.23867 15.8316 6.33729 15.9306 6.46188 15.9799L6.85975 16.1374C7.26783 16.2989 7.26783 16.8786 6.85975 17.0401L6.46188 17.1976C6.33729 17.2469 6.23867 17.3459 6.18953 17.471L6.03261 17.8703C5.87167 18.2799 5.29414 18.2799 5.1332 17.8703L4.97628 17.471C4.92714 17.3459 4.82852 17.2469 4.70393 17.1976L4.30606 17.0401C3.89798 16.8786 3.89798 16.2989 4.30606 16.1374L4.70393 15.9799C4.82852 15.9306 4.92714 15.8316 4.97628 15.7065L5.1332 15.3072Z" stroke="white" />
</svg>
),
launch: (props: LucideProps) => (
<svg {...props} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.764 10.0166L13.9171 15.8459L14.9762 16.9082L20.8231 11.0789L19.764 10.0166ZM9.48279 15.8459L8.10944 14.4767L7.05037 15.5389L8.42373 16.9082L9.48279 15.8459ZM8.10944 10.062L13.9563 4.23268L12.8972 3.17043L7.05038 8.99974L8.10944 10.062ZM17.5468 2.75009H18.1157V1.25009H17.5468V2.75009ZM21.2501 5.87286V6.44002H22.7501V5.87286H21.2501ZM18.1157 2.75009C19.0524 2.75009 19.6797 2.75167 20.1472 2.81434C20.5933 2.87414 20.7799 2.97697 20.9017 3.09837L21.9608 2.03612C21.5137 1.59036 20.9581 1.40962 20.3465 1.32763C19.7562 1.24851 19.0101 1.25009 18.1157 1.25009V2.75009ZM22.7501 5.87286C22.7501 4.98131 22.7517 4.23697 22.6723 3.64789C22.5899 3.03701 22.4082 2.48218 21.9608 2.03612L20.9017 3.09837C21.0232 3.21946 21.1259 3.40462 21.1857 3.84835C21.2485 4.31389 21.2501 4.93878 21.2501 5.87286H22.7501ZM8.10944 14.4767C7.44701 13.8162 7.00477 13.3731 6.71885 12.9995C6.44611 12.6431 6.3877 12.4398 6.3877 12.2693H4.8877C4.8877 12.901 5.15298 13.4215 5.52764 13.9111C5.88913 14.3834 6.418 14.9085 7.05037 15.5389L8.10944 14.4767ZM8.42373 16.9082C9.05613 17.5387 9.58271 18.0659 10.0564 18.4263C10.5475 18.7998 11.0685 19.0634 11.7 19.0634V17.5634C11.5269 17.5634 11.322 17.5043 10.9646 17.2324C10.5897 16.9473 10.1452 16.5063 9.48279 15.8459L8.42373 16.9082ZM20.8231 11.0789C21.6216 10.2827 22.1785 9.74622 22.4709 9.04242L21.0857 8.46692C20.9346 8.83068 20.6495 9.13374 19.764 10.0166L20.8231 11.0789ZM21.2501 6.44002C21.2501 7.68861 21.2368 8.10341 21.0857 8.46692L22.4709 9.04242C22.7634 8.33837 22.7501 7.56593 22.7501 6.44002H21.2501ZM13.9563 4.23268C14.8415 3.35009 15.1458 3.06541 15.5115 2.9144L14.9389 1.52797C14.2338 1.81917 13.6961 2.37399 12.8972 3.17043L13.9563 4.23268ZM17.5468 1.25009C16.4171 1.25009 15.6438 1.23688 14.9389 1.52797L15.5115 2.9144C15.8774 2.7633 16.2949 2.75009 17.5468 2.75009V1.25009ZM13.9171 15.8459C13.4058 16.3557 13.0211 16.7387 12.6905 17.0242C12.3587 17.3107 12.1351 17.4505 11.9597 17.5151L12.4781 18.9227C12.906 18.7651 13.2919 18.4868 13.6709 18.1594C14.0513 17.8309 14.4788 17.4041 14.9762 16.9082L13.9171 15.8459ZM11.9597 17.5151C11.8673 17.5492 11.7848 17.5634 11.7 17.5634V19.0634C11.9707 19.0634 12.2283 19.0147 12.4781 18.9227L11.9597 17.5151ZM7.05038 8.99974C6.5649 9.48376 6.14575 9.90112 5.82033 10.2725C5.49625 10.6424 5.21908 11.0168 5.05382 11.4278L6.44551 11.9874C6.51649 11.8109 6.66249 11.5875 6.94849 11.2611C7.23315 10.9362 7.611 10.5589 8.10944 10.062L7.05038 8.99974ZM5.05382 11.4278C4.94592 11.6961 4.8877 11.9744 4.8877 12.2693H6.3877C6.3877 12.1792 6.40412 12.0903 6.44551 11.9874L5.05382 11.4278Z" fill="white" />
<path opacity="0.5" d="M5.57362 11.5317L6.10395 11.0013L6.10316 11.0005L5.57362 11.5317ZM9.91988 7.42238C10.2682 7.64656 10.7323 7.54593 10.9565 7.19762C11.1806 6.84932 11.08 6.38523 10.7317 6.16105L9.91988 7.42238ZM12.5003 18.5004L11.97 19.0307C11.9816 19.0423 11.9935 19.0535 12.0059 19.0644L12.5003 18.5004ZM17.8241 13.2323C17.599 12.8846 17.1347 12.7852 16.787 13.0104C16.4393 13.2355 16.3399 13.6999 16.565 14.0475L17.8241 13.2323ZM13.0232 18.9589L13.5527 18.4277L13.5357 18.4108L13.5176 18.3949L13.0232 18.9589ZM10.7317 6.16105L10.1025 5.75608L9.29066 7.01741L9.91988 7.42238L10.7317 6.16105ZM10.1025 5.75608C9.48105 5.35612 8.97949 5.03269 8.54781 4.80008C8.1067 4.56239 7.69349 4.39381 7.23659 4.32629L7.0173 5.81017C7.2367 5.84259 7.47719 5.92708 7.83627 6.12057C8.20477 6.31914 8.64987 6.60499 9.29066 7.01741L10.1025 5.75608ZM2.75497 8.5548C3.31803 7.99344 3.92197 7.39153 4.46471 6.89641C4.73588 6.64903 4.98282 6.43659 5.19464 6.27333C5.41808 6.10111 5.55981 6.0173 5.62714 5.98937L5.05228 4.60389C4.79504 4.71063 4.52524 4.89542 4.27893 5.08527C4.02101 5.28407 3.74001 5.52713 3.45378 5.78824C2.88173 6.3101 2.2531 6.93704 1.69592 7.49253L2.75497 8.5548ZM7.23659 4.32629C6.50192 4.21771 5.7465 4.31585 5.05228 4.60389L5.62714 5.98937C6.07781 5.80238 6.55915 5.74246 7.0173 5.81017L7.23659 4.32629ZM2.20851 9.97368L2.58715 10.1237L3.13972 8.7292L2.76108 8.57917L2.20851 9.97368ZM4.08336 11.1049L5.04409 12.0628L6.10316 11.0005L5.14242 10.0427L4.08336 11.1049ZM2.58715 10.1237C2.65078 10.1489 2.67626 10.159 2.70095 10.1692L3.27236 8.78231C3.23613 8.76739 3.19977 8.75299 3.13972 8.7292L2.58715 10.1237ZM5.14242 10.0427C5.09674 9.99714 5.06907 9.96953 5.04096 9.94226L3.99641 11.0188C4.01555 11.0373 4.03494 11.0567 4.08336 11.1049L5.14242 10.0427ZM2.70095 10.1692C3.18311 10.3679 3.62275 10.6562 3.99641 11.0188L5.04096 9.94226C4.53056 9.44703 3.93031 9.05339 3.27236 8.78231L2.70095 10.1692ZM1.69592 7.49253C0.922128 8.26398 1.19496 9.57206 2.20851 9.97368L2.76108 8.57917C2.75663 8.5774 2.75482 8.57608 2.75454 8.57587C2.75467 8.57604 2.75416 8.57559 2.75454 8.57587C2.75407 8.57531 2.75175 8.57224 2.75081 8.5677C2.74987 8.56317 2.75049 8.56041 2.75058 8.56007C2.75046 8.56028 2.75059 8.56004 2.75058 8.56007C2.75064 8.55998 2.75173 8.55802 2.75497 8.5548L1.69592 7.49253ZM16.565 14.0475L16.9712 14.6749L18.2303 13.8596L17.8241 13.2323L16.565 14.0475ZM15.4294 21.1848L15.3454 21.2686L16.4044 22.3309L16.4885 22.2471L15.4294 21.1848ZM16.9712 14.6749C17.3849 15.3138 17.6716 15.7574 17.8706 16.1247C18.0646 16.4825 18.1491 16.7217 18.1814 16.9395L19.6651 16.7189C19.5972 16.2623 19.4278 15.8498 19.1893 15.4098C18.956 14.9793 18.6315 14.4791 18.2303 13.8596L16.9712 14.6749ZM16.4885 22.2471C17.0456 21.6916 17.6745 21.0648 18.1979 20.4945C18.4598 20.2091 18.7036 19.9289 18.9031 19.6717C19.0934 19.4262 19.279 19.1569 19.3863 18.8999L18.0021 18.3221C17.9743 18.3887 17.8904 18.5298 17.7177 18.7526C17.5539 18.9637 17.3409 19.2099 17.0928 19.4802C16.5962 20.0213 15.9925 20.6235 15.4294 21.1848L16.4885 22.2471ZM18.1814 16.9395C18.2491 17.3949 18.1893 17.8736 18.0021 18.3221L19.3863 18.8999C19.6756 18.207 19.7742 17.4526 19.6651 16.7189L18.1814 16.9395ZM13.5176 18.3949L12.9947 17.9365L12.0059 19.0644L12.5287 19.5228L13.5176 18.3949ZM15.446 21.2974C15.2313 20.7588 15.1023 20.4317 14.9327 20.1225L13.6176 20.8439C13.7329 21.0541 13.825 21.2818 14.0526 21.8528L15.446 21.2974ZM12.4936 19.49C12.9294 19.9245 13.1028 20.0991 13.2508 20.288L14.4314 19.3627C14.2139 19.0851 13.9638 18.8375 13.5527 18.4277L12.4936 19.49ZM14.9327 20.1225C14.7866 19.8561 14.6189 19.6019 14.4314 19.3627L13.2508 20.288C13.388 20.463 13.5107 20.649 13.6176 20.8439L14.9327 20.1225ZM15.3454 21.2686C15.3517 21.2623 15.3622 21.2558 15.3738 21.2526C15.3836 21.2498 15.391 21.2501 15.3962 21.2512C15.4013 21.2522 15.4099 21.2551 15.4202 21.2632C15.4319 21.2726 15.4413 21.2856 15.446 21.2974L14.0526 21.8528C14.4366 22.8159 15.6845 23.0486 16.4044 22.3309L15.3454 21.2686ZM13.0306 17.9701L12.7494 17.6889L11.6888 18.7495L11.97 19.0307L13.0306 17.9701ZM5.04329 12.062L5.21953 12.2382L6.28019 11.1776L6.10395 11.0013L5.04329 12.062Z" fill="white" />
<path opacity="0.5" d="M10.8564 14.17C11.1497 13.8776 11.1504 13.4027 10.858 13.1094C10.5655 12.816 10.0906 12.8153 9.79733 13.1078L10.8564 14.17ZM8.79636 16.2239L10.8564 14.17L9.79733 13.1078L7.7373 15.1616L8.79636 16.2239ZM16.6641 9.00008C16.1983 9.46445 15.4422 9.46445 14.9764 9.00008L13.9174 10.0623C14.9685 11.1104 16.6719 11.1104 17.7231 10.0623L16.6641 9.00008ZM14.9764 9.00008C14.5119 8.53695 14.5119 7.787 14.9764 7.32387L13.9174 6.26161C12.8649 7.31089 12.8649 9.01305 13.9174 10.0623L14.9764 9.00008ZM14.9764 7.32387C15.4422 6.85949 16.1983 6.85949 16.6641 7.32387L17.7231 6.26161C16.6719 5.21358 14.9685 5.21358 13.9174 6.26161L14.9764 7.32387ZM16.6641 7.32387C17.1286 7.787 17.1286 8.53695 16.6641 9.00008L17.7231 10.0623C18.7756 9.01305 18.7756 7.31089 17.7231 6.26161L16.6641 7.32387Z" fill="white" />
</svg>
),
feature: (props: LucideProps) => (
<svg {...props} width="328" height="401" viewBox="0 0 328 401" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="131" y="56" width="60" height="315" fill="url(#paint0_linear_50_493)" />
<g clipPath="url(#clip0_50_493)">
<rect x="131" y="341" width="60" height="60" rx="10" fill="#004BE0" />
<rect x="174.5" y="333.5" width="24" height="24" rx="4.5" fill="#006EFF" stroke="#3B82F6" />
<rect x="123.5" y="333.5" width="24" height="24" rx="4.5" fill="#006EFF" stroke="#3B82F6" />
<rect x="123.5" y="384.5" width="24" height="24" rx="4.5" fill="#006EFF" stroke="#3B82F6" />
<rect x="146.5" y="356.5" width="29" height="29" rx="4.5" fill="#006EFF" stroke="#3B82F6" />
<path d="M162.606 369.088C162.29 368.778 162.29 368.284 162.29 367.297V367.039C162.29 364.302 162.29 362.933 161.521 362.698C160.751 362.462 159.926 363.578 158.277 365.809L155.725 369.262C154.655 370.71 154.119 371.435 154.414 372.004C154.419 372.014 154.424 372.023 154.429 372.032C154.742 372.593 155.666 372.593 157.515 372.593C158.543 372.593 159.057 372.593 159.379 372.896" stroke="white" strokeWidth="1.5" />
<path d="M162.605 369.088L162.622 369.104C162.944 369.407 163.458 369.407 164.486 369.407C166.335 369.407 167.259 369.407 167.572 369.968C167.577 369.977 167.582 369.986 167.587 369.996C167.882 370.565 167.346 371.29 166.276 372.738L163.724 376.191C162.075 378.422 161.25 379.538 160.48 379.302C159.711 379.067 159.711 377.698 159.711 374.961V374.703C159.711 373.715 159.711 373.222 159.396 372.912L159.379 372.896" stroke="white" strokeWidth="1.5" />
<rect x="174.5" y="384.5" width="24" height="24" rx="4.5" fill="#006EFF" stroke="#3B82F6" />
</g>
<rect x="131.5" y="341.5" width="59" height="59" rx="9.5" stroke="url(#paint1_linear_50_493)" strokeOpacity="0.95" />
<rect x="250" y="9" width="50" height="315" fill="url(#paint2_linear_50_493)" />
<g clipPath="url(#clip1_50_493)">
<rect x="250" y="299" width="50" height="50" rx="8" fill="#004BE0" />
<rect x="287.5" y="288.5" width="24" height="24" rx="3.5" fill="#006EFF" stroke="#3B82F6" />
<rect x="238.5" y="288.5" width="24" height="24" rx="3.5" fill="#006EFF" stroke="#3B82F6" />
<rect x="238.5" y="335.5" width="24" height="24" rx="3.5" fill="#006EFF" stroke="#3B82F6" />
<rect x="262.5" y="311.5" width="25" height="25" rx="3.5" fill="#006EFF" stroke="#3B82F6" />
<rect x="287.5" y="335.5" width="24" height="24" rx="3.5" fill="#006EFF" stroke="#3B82F6" />
<path d="M272.36 317.896C272.634 317.201 273.616 317.201 273.89 317.896L274.739 320.048C274.822 320.26 274.99 320.427 275.202 320.511L277.354 321.36C278.049 321.634 278.049 322.616 277.354 322.89L275.202 323.739C274.99 323.822 274.822 323.99 274.739 324.202L273.89 326.354C273.616 327.049 272.634 327.049 272.36 326.354L271.511 324.202C271.427 323.99 271.26 323.822 271.048 323.739L268.896 322.89C268.201 322.616 268.201 321.634 268.896 321.36L271.048 320.511C271.26 320.427 271.427 320.26 271.511 320.048L272.36 317.896Z" stroke="white" strokeWidth="1.5" />
<path d="M279.053 325.567C279.198 325.2 279.718 325.2 279.863 325.567L280.496 327.174C280.541 327.286 280.629 327.375 280.742 327.419L282.349 328.053C282.716 328.198 282.716 328.718 282.349 328.863L280.742 329.497C280.629 329.541 280.541 329.63 280.496 329.742L279.863 331.349C279.718 331.717 279.198 331.717 279.053 331.349L278.419 329.742C278.375 329.63 278.286 329.541 278.174 329.497L276.567 328.863C276.199 328.718 276.199 328.198 276.567 328.053L278.174 327.419C278.286 327.375 278.375 327.286 278.419 327.174L279.053 325.567Z" stroke="white" strokeWidth="1.5" />
</g>
<rect x="250.5" y="299.5" width="49" height="49" rx="7.5" stroke="url(#paint3_linear_50_493)" strokeOpacity="0.95" />
<rect x="31" width="40" height="315" fill="url(#paint4_linear_50_493)" />
<g clipPath="url(#clip2_50_493)">
<rect x="31" y="295" width="40" height="40" rx="6" fill="#004BE0" />
<rect x="60.5" y="282.5" width="24" height="24" rx="2.5" fill="#006EFF" stroke="#3B82F6" />
<rect x="17.5" y="282.5" width="24" height="24" rx="2.5" fill="#006EFF" stroke="#3B82F6" />
<rect x="17.5" y="323.5" width="24" height="24" rx="2.5" fill="#006EFF" stroke="#3B82F6" />
<rect x="41.5" y="305.5" width="19" height="19" rx="2.5" fill="#006EFF" stroke="#3B82F6" />
<rect x="60.5" y="323.5" width="24" height="24" rx="2.5" fill="#006EFF" stroke="#3B82F6" />
<path d="M54.7064 314.426L51.5394 317.583L52.113 318.159L55.2801 315.001L54.7064 314.426ZM49.1374 317.583L48.3935 316.842L47.8199 317.417L48.5638 318.159L49.1374 317.583ZM48.3935 314.45L51.5606 311.293L50.9869 310.717L47.8199 313.875L48.3935 314.45ZM53.5055 310.49H53.8136V309.677H53.5055V310.49ZM55.5114 312.181V312.489H56.3239V312.181H55.5114ZM53.8136 310.49C54.321 310.49 54.6608 310.491 54.914 310.525C55.1556 310.557 55.2567 310.613 55.3227 310.678L55.8964 310.103C55.6542 309.862 55.3532 309.764 55.022 309.719C54.7022 309.676 54.2981 309.677 53.8136 309.677V310.49ZM56.3239 312.181C56.3239 311.698 56.3248 311.295 56.2818 310.976C56.2371 310.645 56.1387 310.345 55.8964 310.103L55.3227 310.678C55.3885 310.744 55.4441 310.844 55.4765 311.085C55.5105 311.337 55.5114 311.675 55.5114 312.181H56.3239ZM48.3935 316.842C48.0347 316.484 47.7952 316.244 47.6403 316.042C47.4926 315.849 47.4609 315.738 47.4609 315.646H46.6484C46.6484 315.988 46.7921 316.27 46.9951 316.535C47.1909 316.791 47.4774 317.076 47.8199 317.417L48.3935 316.842ZM48.5638 318.159C48.9063 318.5 49.1916 318.786 49.4482 318.981C49.7142 319.183 49.9964 319.326 50.3384 319.326V318.514C50.2447 318.514 50.1337 318.482 49.9401 318.334C49.737 318.18 49.4963 317.941 49.1374 317.583L48.5638 318.159ZM55.2801 315.001C55.7126 314.57 56.0143 314.279 56.1727 313.898L55.4224 313.586C55.3405 313.783 55.1861 313.948 54.7064 314.426L55.2801 315.001ZM55.5114 312.489C55.5114 313.165 55.5042 313.39 55.4224 313.586L56.1727 313.898C56.3311 313.517 56.3239 313.098 56.3239 312.489H55.5114ZM51.5606 311.293C52.0401 310.815 52.2049 310.661 52.403 310.579L52.0928 309.828C51.7109 309.986 51.4197 310.286 50.9869 310.717L51.5606 311.293ZM53.5055 309.677C52.8935 309.677 52.4747 309.67 52.0928 309.828L52.403 310.579C52.6012 310.497 52.8273 310.49 53.5055 310.49V309.677ZM51.5394 317.583C51.2624 317.859 51.054 318.067 50.875 318.222C50.6952 318.377 50.5741 318.453 50.4791 318.488L50.7599 319.25C50.9917 319.165 51.2007 319.014 51.406 318.837C51.6121 318.659 51.8436 318.427 52.113 318.159L51.5394 317.583ZM50.4791 318.488C50.4291 318.506 50.3844 318.514 50.3384 318.514V319.326C50.4851 319.326 50.6246 319.3 50.7599 319.25L50.4791 318.488ZM47.8199 313.875C47.5569 314.137 47.3299 314.363 47.1536 314.564C46.9781 314.765 46.8279 314.968 46.7384 315.19L47.4923 315.493C47.5307 315.398 47.6098 315.277 47.7647 315.1C47.9189 314.924 48.1236 314.72 48.3935 314.45L47.8199 313.875ZM46.7384 315.19C46.68 315.336 46.6484 315.486 46.6484 315.646H47.4609C47.4609 315.597 47.4698 315.549 47.4923 315.493L46.7384 315.19Z" fill="white" />
<path d="M47.0197 315.246L47.307 314.959L47.3065 314.958L47.0197 315.246ZM49.3739 313.02C49.5626 313.142 49.814 313.087 49.9354 312.898C50.0568 312.71 50.0023 312.458 49.8137 312.337L49.3739 313.02ZM50.7716 319.021L50.4844 319.308C50.4907 319.314 50.4971 319.32 50.5038 319.326L50.7716 319.021ZM53.6554 316.167C53.5334 315.979 53.2819 315.925 53.0936 316.047C52.9053 316.169 52.8514 316.421 52.9734 316.609L53.6554 316.167ZM51.0549 319.269L51.3417 318.981L51.3325 318.972L51.3227 318.964L51.0549 319.269ZM49.8137 312.337L49.4728 312.118L49.0331 312.801L49.3739 313.02L49.8137 312.337ZM49.4728 312.118C49.1362 311.901 48.8645 311.726 48.6307 311.6C48.3918 311.471 48.168 311.38 47.9205 311.343L47.8017 312.147C47.9205 312.164 48.0508 312.21 48.2453 312.315C48.4449 312.423 48.686 312.577 49.0331 312.801L49.4728 312.118ZM45.4929 313.634C45.7979 313.33 46.1251 313.003 46.419 312.735C46.5659 312.601 46.6997 312.486 46.8144 312.398C46.9354 312.305 47.0122 312.259 47.0487 312.244L46.7373 311.494C46.598 311.551 46.4518 311.651 46.3184 311.754C46.1787 311.862 46.0265 311.994 45.8714 312.135C45.5616 312.418 45.2211 312.757 44.9193 313.058L45.4929 313.634ZM47.9205 311.343C47.5225 311.284 47.1133 311.338 46.7373 311.494L47.0487 312.244C47.2928 312.143 47.5535 312.11 47.8017 312.147L47.9205 311.343ZM45.1969 314.402L45.402 314.483L45.7013 313.728L45.4962 313.647L45.1969 314.402ZM46.2125 315.015L46.7329 315.534L47.3065 314.958L46.7861 314.44L46.2125 315.015ZM45.402 314.483C45.4365 314.497 45.4503 314.503 45.4637 314.508L45.7732 313.757C45.7536 313.749 45.7339 313.741 45.7013 313.728L45.402 314.483ZM46.7861 314.44C46.7614 314.415 46.7464 314.4 46.7312 314.385L46.1654 314.968C46.1757 314.978 46.1862 314.989 46.2125 315.015L46.7861 314.44ZM45.4637 314.508C45.7248 314.616 45.963 314.772 46.1654 314.968L46.7312 314.385C46.4547 314.117 46.1296 313.904 45.7732 313.757L45.4637 314.508ZM44.9193 313.058C44.5001 313.476 44.6479 314.185 45.1969 314.402L45.4962 313.647C45.4938 313.646 45.4928 313.645 45.4927 313.645C45.4928 313.645 45.4925 313.645 45.4927 313.645C45.4924 313.645 45.4912 313.643 45.4907 313.641C45.4902 313.638 45.4905 313.637 45.4905 313.636C45.4905 313.637 45.4906 313.636 45.4905 313.636C45.4906 313.636 45.4912 313.635 45.4929 313.634L44.9193 313.058ZM52.9734 316.609L53.1934 316.949L53.8754 316.507L53.6554 316.167L52.9734 316.609ZM52.3582 320.475L52.3127 320.52L52.8864 321.096L52.9319 321.05L52.3582 320.475ZM53.1934 316.949C53.4175 317.295 53.5728 317.535 53.6806 317.734C53.7856 317.928 53.8314 318.057 53.8489 318.175L54.6526 318.056C54.6158 317.809 54.524 317.585 54.3949 317.347C54.2685 317.114 54.0927 316.843 53.8754 316.507L53.1934 316.949ZM52.9319 321.05C53.2337 320.749 53.5743 320.41 53.8578 320.101C53.9997 319.946 54.1318 319.795 54.2398 319.655C54.3429 319.522 54.4434 319.376 54.5016 319.237L53.7518 318.924C53.7367 318.96 53.6913 319.037 53.5977 319.157C53.509 319.272 53.3936 319.405 53.2593 319.552C52.9903 319.845 52.6633 320.171 52.3582 320.475L52.9319 321.05ZM53.8489 318.175C53.8856 318.422 53.8532 318.681 53.7518 318.924L54.5016 319.237C54.6583 318.862 54.7117 318.453 54.6526 318.056L53.8489 318.175ZM51.3227 318.964L51.0394 318.715L50.5038 319.326L50.787 319.575L51.3227 318.964ZM52.3672 320.536C52.2509 320.244 52.1811 320.067 52.0892 319.899L51.3769 320.29C51.4393 320.404 51.4892 320.527 51.6125 320.837L52.3672 320.536ZM50.768 319.557C51.0041 319.792 51.098 319.887 51.1782 319.989L51.8177 319.488C51.6998 319.338 51.5644 319.203 51.3417 318.981L50.768 319.557ZM52.0892 319.899C52.0101 319.755 51.9192 319.617 51.8177 319.488L51.1782 319.989C51.2525 320.084 51.3189 320.185 51.3769 320.29L52.0892 319.899ZM52.3127 320.52C52.3162 320.517 52.3218 320.513 52.3281 320.512C52.3334 320.51 52.3374 320.51 52.3403 320.511C52.343 320.511 52.3477 320.513 52.3533 320.517C52.3596 320.522 52.3647 320.529 52.3672 320.536L51.6125 320.837C51.8205 321.358 52.4964 321.484 52.8864 321.096L52.3127 320.52ZM51.0589 318.734L50.9066 318.581L50.3321 319.156L50.4844 319.308L51.0589 318.734ZM46.7324 315.533L46.8279 315.629L47.4024 315.054L47.307 314.959L46.7324 315.533Z" fill="white" />
<path d="M49.8809 316.675C50.0398 316.517 50.0402 316.26 49.8818 316.101C49.7234 315.942 49.4661 315.941 49.3073 316.1L49.8809 316.675ZM48.7651 317.788L49.8809 316.675L49.3073 316.1L48.1914 317.212L48.7651 317.788ZM53.0268 313.875C52.7745 314.126 52.3649 314.126 52.1126 313.875L51.539 314.45C52.1083 315.018 53.031 315.018 53.6004 314.45L53.0268 313.875ZM52.1126 313.875C51.861 313.624 51.861 313.218 52.1126 312.967L51.539 312.392C50.9689 312.96 50.9689 313.882 51.539 314.45L52.1126 313.875ZM52.1126 312.967C52.3649 312.715 52.7745 312.715 53.0268 312.967L53.6004 312.392C53.031 311.824 52.1083 311.824 51.539 312.392L52.1126 312.967ZM53.0268 312.967C53.2784 313.218 53.2784 313.624 53.0268 313.875L53.6004 314.45C54.1705 313.882 54.1705 312.96 53.6004 312.392L53.0268 312.967Z" fill="white" />
</g>
<rect x="31.5" y="295.5" width="39" height="39" rx="5.5" stroke="url(#paint5_linear_50_493)" strokeOpacity="0.95" />
<circle cx="217" cy="372.605" r="2" fill="#004BE0" />
<path d="M217 296L217 371.263" stroke="url(#paint6_linear_50_493)" strokeLinecap="round" />
<g filter="url(#filter0_f_50_493)">
<circle cx="217" cy="373" r="4" fill="#004BE0" />
</g>
<circle cx="316" cy="283.605" r="2" fill="#004BE0" />
<path d="M316 207L316 282.263" stroke="url(#paint7_linear_50_493)" strokeLinecap="round" />
<g filter="url(#filter1_f_50_493)">
<circle cx="316" cy="284" r="4" fill="#004BE0" />
</g>
<circle cx="82" cy="286.605" r="2" fill="#004BE0" />
<path d="M82 210L82 285.263" stroke="url(#paint8_linear_50_493)" strokeLinecap="round" />
<g filter="url(#filter2_f_50_493)">
<circle cx="82" cy="287" r="4" fill="#004BE0" />
</g>
<circle cx="12" cy="246.605" r="2" fill="#004BE0" />
<path d="M12 170L12 245.263" stroke="url(#paint9_linear_50_493)" strokeLinecap="round" />
<g filter="url(#filter3_f_50_493)">
<circle cx="12" cy="247" r="4" fill="#004BE0" />
</g>
<circle cx="115" cy="321.605" r="2" fill="#004BE0" />
<path d="M115 245L115 320.263" stroke="url(#paint10_linear_50_493)" strokeLinecap="round" />
<g filter="url(#filter4_f_50_493)">
<circle cx="115" cy="322" r="4" fill="#004BE0" />
</g>
<defs>
<filter id="filter0_f_50_493" x="205" y="361" width="24" height="24" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
<feFlood floodOpacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="4" result="effect1_foregroundBlur_50_493" />
</filter>
<filter id="filter1_f_50_493" x="304" y="272" width="24" height="24" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
<feFlood floodOpacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="4" result="effect1_foregroundBlur_50_493" />
</filter>
<filter id="filter2_f_50_493" x="70" y="275" width="24" height="24" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
<feFlood floodOpacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="4" result="effect1_foregroundBlur_50_493" />
</filter>
<filter id="filter3_f_50_493" x="0" y="235" width="24" height="24" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
<feFlood floodOpacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="4" result="effect1_foregroundBlur_50_493" />
</filter>
<filter id="filter4_f_50_493" x="103" y="310" width="24" height="24" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
<feFlood floodOpacity="0" result="BackgroundImageFix" />
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
<feGaussianBlur stdDeviation="4" result="effect1_foregroundBlur_50_493" />
</filter>
<linearGradient id="paint0_linear_50_493" x1="161" y1="56" x2="161" y2="371" gradientUnits="userSpaceOnUse">
<stop stopOpacity="0" />
<stop offset="1" stopColor="#006EFF" />
</linearGradient>
<linearGradient id="paint1_linear_50_493" x1="161" y1="341" x2="161" y2="401" gradientUnits="userSpaceOnUse">
<stop stopColor="white" stopOpacity="0.5" />
<stop offset="1" stopColor="#004BE0" stopOpacity="0.5" />
</linearGradient>
<linearGradient id="paint2_linear_50_493" x1="275" y1="9" x2="275" y2="324" gradientUnits="userSpaceOnUse">
<stop stopOpacity="0" />
<stop offset="1" stopColor="#006EFF" />
</linearGradient>
<linearGradient id="paint3_linear_50_493" x1="275" y1="299" x2="275" y2="349" gradientUnits="userSpaceOnUse">
<stop stopColor="white" stopOpacity="0.5" />
<stop offset="1" stopColor="#004BE0" stopOpacity="0.5" />
</linearGradient>
<linearGradient id="paint4_linear_50_493" x1="51" y1="0" x2="51" y2="315" gradientUnits="userSpaceOnUse">
<stop stopOpacity="0" />
<stop offset="1" stopColor="#006EFF" />
</linearGradient>
<linearGradient id="paint5_linear_50_493" x1="51" y1="295" x2="51" y2="335" gradientUnits="userSpaceOnUse">
<stop stopColor="white" stopOpacity="0.5" />
<stop offset="1" stopColor="#004BE0" stopOpacity="0.5" />
</linearGradient>
<linearGradient id="paint6_linear_50_493" x1="216.5" y1="296" x2="216.5" y2="371.263" gradientUnits="userSpaceOnUse">
<stop stopColor="#040102" stopOpacity="0" />
<stop offset="1" stopColor="#004BE0" />
</linearGradient>
<linearGradient id="paint7_linear_50_493" x1="315.5" y1="207" x2="315.5" y2="282.263" gradientUnits="userSpaceOnUse">
<stop stopColor="#040102" stopOpacity="0" />
<stop offset="1" stopColor="#004BE0" />
</linearGradient>
<linearGradient id="paint8_linear_50_493" x1="81.5" y1="210" x2="81.5" y2="285.263" gradientUnits="userSpaceOnUse">
<stop stopColor="#040102" />
<stop offset="1" stopColor="#004BE0" />
</linearGradient>
<linearGradient id="paint9_linear_50_493" x1="11.5" y1="170" x2="11.5" y2="245.263" gradientUnits="userSpaceOnUse">
<stop stopColor="#040102" />
<stop offset="1" stopColor="#004BE0" />
</linearGradient>
<linearGradient id="paint10_linear_50_493" x1="114.5" y1="245" x2="114.5" y2="320.263" gradientUnits="userSpaceOnUse">
<stop stopColor="#040102" stopOpacity="0" />
<stop offset="1" stopColor="#004BE0" />
</linearGradient>
<clipPath id="clip0_50_493">
<rect x="131" y="341" width="60" height="60" rx="10" fill="white" />
</clipPath>
<clipPath id="clip1_50_493">
<rect x="250" y="299" width="50" height="50" rx="8" fill="white" />
</clipPath>
<clipPath id="clip2_50_493">
<rect x="31" y="295" width="40" height="40" rx="6" fill="white" />
</clipPath>
</defs>
</svg>
),
};
export default Icons;
================================================
FILE: src/components/global/wrapper.tsx
================================================
import React from 'react'
import { cn } from "@/lib/utils";
interface Props {
className?: string;
children: React.ReactNode;
}
const Wrapper = ({ children, className }: Props) => {
return (
<div className={cn(
"h-full mx-auto w-full max-w-screen-xl px-4 md:px-20",
className
)}>
{children}
</div>
)
};
export default Wrapper
================================================
FILE: src/components/home/navigation/footer.tsx
================================================
import Icons from "@/components/global/icons"
import { Heart } from 'lucide-react'
import Link from 'next/link'
const Footer = () => {
return (
<footer className="flex flex-col relative items-center justify-center border-t border-border pt-16 pb-8 px-6 lg:px-8 w-full max-w-6xl mx-auto lg:pt-32">
<div className="hidden lg:block absolute -top-1/3 -right-1/4 bg-primary w-72 h-72 rounded-full -z-10 blur-[14rem]"></div>
<div className="hidden lg:block absolute bottom-0 -left-1/4 bg-primary w-72 h-72 rounded-full -z-10 blur-[14rem]"></div>
<div className="grid gap-8 xl:grid-cols-3 xl:gap-8 w-full">
<div className="flex flex-col items-start justify-start md:max-w-[200px]">
<div className="flex items-start">
<Icons.logo className="w-7 h-7" />
</div>
<p className="text-muted-foreground mt-4 text-sm text-start">
Build beautiful, functional websites, without writing code
</p>
<span className="mt-4 text-neutral-200 text-sm flex items-center">
Made in India with
<Heart className="w-3.5 h-3.5 ml-1 fill-primary text-primary" />
</span>
</div>
<div className="grid-cols-2 gap-8 grid mt-16 xl:col-span-2 xl:mt-0">
<div className="md:grid md:grid-cols-2 md:gap-8">
<div className="">
<h3 className="text-base font-medium text-white">
Product
</h3>
<ul className="mt-4 text-sm text-muted-foreground">
<li className="mt-2">
<Link href="" className="hover:text-foreground transition-all duration-300">
Features
</Link>
</li>
<li className="mt-2">
<Link href="" className="hover:text-foreground transition-all duration-300">
Pricing
</Link>
</li>
<li className="mt-2">
<Link href="" className="hover:text-foreground transition-all duration-300">
Testimonials
</Link>
</li>
<li className="mt-2">
<Link href="" className="hover:text-foreground transition-all duration-300">
Integration
</Link>
</li>
</ul>
</div>
<div className="mt-10 md:mt-0 flex flex-col">
<h3 className="text-base font-medium text-white">
Integrations
</h3>
<ul className="mt-4 text-sm text-muted-foreground">
<li className="">
<Link href="" className="hover:text-foreground transition-all duration-300">
Facebook
</Link>
</li>
<li className="mt-2">
<Link href="" className="hover:text-foreground transition-all duration-300">
Instagram
</Link>
</li>
<li className="mt-2">
<Link href="" className="hover:text-foreground transition-all duration-300">
Twitter
</Link>
</li>
<li className="mt-2">
<Link href="" className="hover:text-foreground transition-all duration-300">
LinkedIn
</Link>
</li>
</ul>
</div>
</div>
<div className="md:grid md:grid-cols-2 md:gap-8">
<div className="">
<h3 className="text-base font-medium text-white">
Resources
</h3>
<ul className="mt-4 text-sm text-muted-foreground">
<li className="mt-2">
<Link href="" className="hover:text-foreground transition-all duration-300">
Blog
</Link>
</li>
<li className="mt-2">
<Link href="" className="hover:text-foreground transition-all duration-300">
Case Studies
</Link>
</li>
<li className="mt-2">
<Link href="" className="hover:text-foreground transition-all duration-300">
Support
</Link>
</li>
</ul>
</div>
<div className="mt-10 md:mt-0 flex flex-col">
<h3 className="text-base font-medium text-white">
Company
</h3>
<ul className="mt-4 text-sm text-muted-foreground">
<li className="">
<Link href="" className="hover:text-foreground transition-all duration-300">
About Us
</Link>
</li>
<li className="mt-2">
<Link href="" className="hover:text-foreground transition-all duration-300">
Privacy Policy
</Link>
</li>
<li className="mt-2">
<Link href="" className="hover:text-foreground transition-all duration-300">
Terms & Conditions
</Link>
</li>
</ul>
</div>
</div>
</div>
</div>
<div className="mt-8 border-t border-border/40 pt-4 md:pt-8 md:flex md:items-center md:justify-between w-full">
<p className="text-sm text-muted-foreground mt-8 md:mt-0">
© {new Date().getFullYear()} Astra AI INC. All rights reserved.
</p>
</div>
</footer>
)
}
export default Footer
================================================
FILE: src/components/home/navigation/navbar.tsx
================================================
import { Container, Icons } from "@/components";
import { buttonVariants } from "@/components/ui/button";
import { UserButton, } from "@clerk/nextjs";
import { currentUser } from "@clerk/nextjs/server";
import Link from "next/link";
const Navbar = async () => {
const user = await currentUser();
return (
<header className="px-4 h-14 sticky top-0 inset-x-0 w-full bg-background/40 backdrop-blur-lg border-b border-border z-50">
<Container reverse>
<div className="flex items-center justify-between h-full mx-auto md:max-w-screen-xl">
<div className="flex items-start">
<Link href="/" className="flex items-center gap-2">
<Icons.logo className="w-8 h-8" />
<span className="text-lg font-medium">
Astra
</span>
</Link>
</div>
<nav className="hidden md:block absolute left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2">
<ul className="flex items-center justify-center gap-8">
<Link href="#" className="hover:text-foreground/80 text-sm">Pricing</Link>
<Link href="#" className="hover:text-foreground/80 text-sm">About</Link>
<Link href="#" className="hover:text-foreground/80 text-sm">Features</Link>
<Link href="#" className="hover:text-foreground/80 text-sm">Blog</Link>
</ul>
</nav>
<div className="flex items-center gap-4">
{user ? (
<UserButton />
) : (
<>
<Link href="/sign-in" className={buttonVariants({ size: "sm", variant: "ghost" })}>
Login
</Link>
<Link href="/sign-up" className={buttonVariants({ size: "sm", className: "hidden md:flex" })}>
Start free trial
</Link>
</>
)}
</div>
</div>
</Container>
</header>
)
};
export default Navbar
================================================
FILE: src/components/index.ts
================================================
import Providers from "./providers/providers";
import ThemeProvider from "./providers/theme-provider";
import Navbar from "./home/navigation/navbar";
import Footer from "./home/navigation/footer";
import Icons from "./global/icons";
import Wrapper from "./global/wrapper";
import Container from "./global/container";
export {
Providers,
ThemeProvider,
Navbar,
Icons,
Wrapper,
Footer,
Container,
}
================================================
FILE: src/components/providers/providers.tsx
================================================
"use client";
import React from 'react';
import { dark } from "@clerk/themes";
import { ClerkProvider } from '@clerk/nextjs';
interface Props {
children: React.ReactNode;
}
const Providers = ({ children }: Props) => {
return (
<ClerkProvider appearance={{ baseTheme: dark }}>
{children}
</ClerkProvider>
)
};
export default Providers
================================================
FILE: src/components/providers/theme-provider.tsx
================================================
"use client"
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
import { type ThemeProviderProps } from "next-themes/dist/types"
const ThemeProvider = ({ children, ...props }: ThemeProviderProps) => {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
};
export default ThemeProvider
================================================
FILE: src/components/ui/border-beam.tsx
================================================
import { cn } from "@/lib/utils";
interface BorderBeamProps {
className?: string;
size?: number;
duration?: number;
borderWidth?: number;
anchor?: number;
colorFrom?: string;
colorTo?: string;
delay?: number;
}
export const BorderBeam = ({
className,
size = 200,
duration = 15,
anchor = 90,
borderWidth = 2,
colorFrom = "#ffaa40",
colorTo = "#9c40ff",
delay = 0,
}: BorderBeamProps) => {
return (
<div
style={
{
"--size": size,
"--duration": duration,
"--anchor": anchor,
"--border-width": borderWidth,
"--color-from": colorFrom,
"--color-to": colorTo,
"--delay": `-${delay}s`,
} as React.CSSProperties
}
className={cn(
"absolute inset-[0] rounded-[inherit] [border:calc(var(--border-width)*1px)_solid_transparent]",
// mask styles
"![mask-clip:padding-box,border-box] ![mask-composite:intersect] [mask:linear-gradient(transparent,transparent),linear-gradient(white,white)]",
// pseudo styles
"after:absolute after:aspect-square after:w-[calc(var(--size)*1px)] after:animate-border-beam after:[animation-delay:var(--delay)] after:[background:linear-gradient(to_left,var(--color-from),var(--color-to),transparent)] after:[offset-anchor:calc(var(--anchor)*1%)_50%] after:[offset-path:rect(0_auto_auto_0_round_calc(var(--size)*1px))]",
className,
)}
/>
);
};
================================================
FILE: src/components/ui/button.tsx
================================================
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-[#001633] text-primary hover:bg-[#00214c]",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
white: "bg-foreground text-background hover:bg-foreground/90",
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 px-3",
lg: "h-11 px-8",
iconx: "h-8 w-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
}
)
Button.displayName = "Button"
export { Button, buttonVariants }
================================================
FILE: src/components/ui/card.tsx
================================================
import * as React from "react"
import { cn } from "@/lib/utils"
const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-lg border bg-card text-card-foreground shadow-sm",
className
)}
{...props}
/>
))
Card.displayName = "Card"
const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props}
/>
))
CardHeader.displayName = "CardHeader"
const CardTitle = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLHeadingElement>
>(({ className, ...props }, ref) => (
<h3
ref={ref}
className={cn(
"text-2xl font-semibold leading-none tracking-tight",
className
)}
{...props}
/>
))
CardTitle.displayName = "CardTitle"
const CardDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<p
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
CardDescription.displayName = "CardDescription"
const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
))
CardContent.displayName = "CardContent"
const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex items-center p-6 pt-0", className)}
{...props}
/>
))
CardFooter.displayName = "CardFooter"
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
================================================
FILE: src/components/ui/dialog.tsx
================================================
"use client"
import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { X } from "lucide-react"
import { cn } from "@/lib/utils"
const Dialog = DialogPrimitive.Root
const DialogTrigger = DialogPrimitive.Trigger
const DialogPortal = DialogPrimitive.Portal
const DialogClose = DialogPrimitive.Close
const DialogOverlay = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Overlay
ref={ref}
className={cn(
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
/>
))
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<DialogPortal>
<DialogOverlay />
<DialogPrimitive.Content
ref={ref}
className={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
className
)}
{...props}
>
{children}
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</DialogPortal>
))
DialogContent.displayName = DialogPrimitive.Content.displayName
const DialogHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col space-y-1.5 text-center sm:text-left",
className
)}
{...props}
/>
)
DialogHeader.displayName = "DialogHeader"
const DialogFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
)}
{...props}
/>
)
DialogFooter.displayName = "DialogFooter"
const DialogTitle = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Title
ref={ref}
className={cn(
"text-lg font-semibold leading-none tracking-tight",
className
)}
{...props}
/>
))
DialogTitle.displayName = DialogPrimitive.Title.displayName
const DialogDescription = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
DialogDescription.displayName = DialogPrimitive.Description.displayName
export {
Dialog,
DialogPortal,
DialogOverlay,
DialogClose,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
}
================================================
FILE: src/components/ui/input.tsx
================================================
import * as React from "react"
import { cn } from "@/lib/utils"
export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}
const Input = React.forwardRef<HTMLInputElement, InputProps>(
({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref}
{...props}
/>
)
}
)
Input.displayName = "Input"
export { Input }
================================================
FILE: src/components/ui/label.tsx
================================================
"use client"
import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
)
const Label = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
VariantProps<typeof labelVariants>
>(({ className, ...props }, ref) => (
<LabelPrimitive.Root
ref={ref}
className={cn(labelVariants(), className)}
{...props}
/>
))
Label.displayName = LabelPrimitive.Root.displayName
export { Label }
================================================
FILE: src/components/ui/lamp.tsx
================================================
"use client";
import React from "react";
import { motion } from "framer-motion";
import { cn } from "@/lib/utils";
export const LampContainer = ({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) => {
return (
<div
className={cn(
"relative flex min-h-screen flex-col items-center justify-center overflow-hidden w-full rounded-md z-0",
className
)}
>
<div className="relative flex w-full flex-1 scale-y-125 items-center justify-center isolate z-0 ">
<motion.div
initial={{ opacity: 0.5, width: "15rem" }}
whileInView={{ opacity: 1, width: "30rem" }}
transition={{
delay: 0.3,
duration: 0.8,
ease: "easeInOut",
}}
style={{
backgroundImage: `conic-gradient(var(--conic-position), var(--tw-gradient-stops))`,
}}
className="absolute inset-auto right-1/2 h-56 overflow-visible w-[30rem] bg-gradient-conic from-blue-500 via-transparent to-transparent text-white [--conic-position:from_70deg_at_center_top]"
>
<div className="absolute w-[100%] left-0 bg-background h-40 bottom-0 z-20 [mask-image:linear-gradient(to_top,white,transparent)]" />
<div className="absolute w-40 h-[100%] left-0 bg-background bottom-0 z-20 [mask-image:linear-gradient(to_right,white,transparent)]" />
</motion.div>
<motion.div
initial={{ opacity: 0.5, width: "15rem" }}
whileInView={{ opacity: 1, width: "30rem" }}
transition={{
delay: 0.3,
duration: 0.8,
ease: "easeInOut",
}}
style={{
backgroundImage: `conic-gradient(var(--conic-position), var(--tw-gradient-stops))`,
}}
className="absolute inset-auto left-1/2 h-56 w-[30rem] bg-gradient-conic from-transparent via-transparent to-blue-500 text-white [--conic-position:from_290deg_at_center_top]"
>
<div className="absolute w-40 h-[100%] right-0 bg-background bottom-0 z-20 [mask-image:linear-gradient(to_left,white,transparent)]" />
<div className="absolute w-[100%] right-0 bg-background h-40 bottom-0 z-20 [mask-image:linear-gradient(to_top,white,transparent)]" />
</motion.div>
<div className="absolute top-1/2 h-48 w-full translate-y-12 scale-x-150 bg-background blur-[8rem]"></div>
<div className="absolute top-1/2 z-50 h-48 w-full bg-transparent opacity-10 backdrop-blur-md"></div>
<motion.div
initial={{ width: "8rem" }}
whileInView={{ width: "16rem" }}
transition={{
delay: 0.3,
duration: 0.8,
ease: "easeInOut",
}}
className="absolute inset-auto z-30 h-36 w-64 -translate-y-[6rem] rounded-full bg-primary blur-2xl"
></motion.div>
<motion.div
initial={{ width: "15rem" }}
whileInView={{ width: "30rem" }}
transition={{
delay: 0.3,
duration: 0.8,
ease: "easeInOut",
}}
className="absolute inset-auto z-50 h-0.5 w-[30rem] -translate-y-[7rem] bg-blue-500"
></motion.div>
<div className="absolute inset-auto z-40 h-44 w-full -translate-y-[12.5rem] bg-background "></div>
</div>
<div className="relative z-50 flex -translate-y-80 flex-col items-center px-5">
{children}
</div>
</div>
);
};
================================================
FILE: src/components/ui/marquee.tsx
================================================
import { cn } from "@/lib/utils";
interface MarqueeProps {
className?: string;
reverse?: boolean;
pauseOnHover?: boolean;
children?: React.ReactNode;
vertical?: boolean;
repeat?: number;
[key: string]: any;
}
export default function Marquee({
className,
reverse,
pauseOnHover = false,
children,
vertical = false,
repeat = 4,
...props
}: MarqueeProps) {
return (
<div
{...props}
className={cn(
"group flex overflow-hidden p-2 [--duration:40s] [--gap:1rem] [gap:var(--gap)]",
{
"flex-row": !vertical,
"flex-col": vertical,
},
className,
)}
>
{Array(repeat)
.fill(0)
.map((_, i) => (
<div
key={i}
className={cn("flex shrink-0 justify-around [gap:var(--gap)]", {
"animate-marquee flex-row": !vertical,
"animate-marquee-vertical flex-col": vertical,
"group-hover:[animation-play-state:paused]": pauseOnHover,
"[animation-direction:reverse]": reverse,
})}
>
{children}
</div>
))}
</div>
);
};
================================================
FILE: src/components/ui/section-badge.tsx
================================================
import React from 'react'
interface Props {
title: string;
}
const SectionBadge = ({ title }: Props) => {
return (
<div className="relative inline-flex h-8 overflow-hidden rounded-full p-[1.5px] focus:outline-none select-none">
<span className="absolute inset-[-1000%] animate-[spin_3s_linear_infinite] bg-[conic-gradient(from_90deg_at_50%_50%,#1d4ed8_0%,#a5b4fc_50%,#1d4ed8_100%)]" />
<span className="inline-flex h-full w-full cursor-pointer items-center justify-center rounded-full bg-slate-950 px-4 py-1 text-sm font-medium text-white backdrop-blur-3xl">
{title}
</span>
</div>
)
};
export default SectionBadge
================================================
FILE: src/components/ui/select.tsx
================================================
"use client"
import * as React from "react"
import * as SelectPrimitive from "@radix-ui/react-select"
import { Check, ChevronDown, ChevronUp } from "lucide-react"
import { cn } from "@/lib/utils"
const Select = SelectPrimitive.Root
const SelectGroup = SelectPrimitive.Group
const SelectValue = SelectPrimitive.Value
const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Trigger
ref={ref}
className={cn(
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
className
)}
{...props}
>
{children}
<SelectPrimitive.Icon asChild>
<ChevronDown className="h-4 w-4 opacity-50" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
))
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
const SelectScrollUpButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollUpButton
ref={ref}
className={cn(
"flex cursor-pointer items-center justify-center py-1",
className
)}
{...props}
>
<ChevronUp className="h-4 w-4" />
</SelectPrimitive.ScrollUpButton>
))
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
const SelectScrollDownButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollDownButton
ref={ref}
className={cn(
"flex cursor-pointer items-center justify-center py-1",
className
)}
{...props}
>
<ChevronDown className="h-4 w-4" />
</SelectPrimitive.ScrollDownButton>
))
SelectScrollDownButton.displayName =
SelectPrimitive.ScrollDownButton.displayName
const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
>(({ className, children, position = "popper", ...props }, ref) => (
<SelectPrimitive.Portal>
<SelectPrimitive.Content
ref={ref}
className={cn(
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
position === "popper" &&
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
className
)}
position={position}
{...props}
>
<SelectScrollUpButton />
<SelectPrimitive.Viewport
className={cn(
"p-1",
position === "popper" &&
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
)}
>
{children}
</SelectPrimitive.Viewport>
<SelectScrollDownButton />
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
))
SelectContent.displayName = SelectPrimitive.Content.displayName
const SelectLabel = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Label
ref={ref}
className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
{...props}
/>
))
SelectLabel.displayName = SelectPrimitive.Label.displayName
const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Item
ref={ref}
className={cn(
"relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
))
SelectItem.displayName = SelectPrimitive.Item.displayName
const SelectSeparator = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Separator
ref={ref}
className={cn("-mx-1 my-1 h-px bg-muted", className)}
{...props}
/>
))
SelectSeparator.displayName = SelectPrimitive.Separator.displayName
export {
Select,
SelectGroup,
SelectValue,
SelectTrigger,
SelectContent,
SelectLabel,
SelectItem,
SelectSeparator,
SelectScrollUpButton,
SelectScrollDownButton,
}
================================================
FILE: src/components/ui/sheet.tsx
================================================
"use client"
import * as React from "react"
import * as SheetPrimitive from "@radix-ui/react-dialog"
import { cva, type VariantProps } from "class-variance-authority"
import { X } from "lucide-react"
import { cn } from "@/lib/utils"
const Sheet = SheetPrimitive.Root
const SheetTrigger = SheetPrimitive.Trigger
const SheetClose = SheetPrimitive.Close
const SheetPortal = SheetPrimitive.Portal
const SheetOverlay = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Overlay
className={cn(
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
ref={ref}
/>
))
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
const sheetVariants = cva(
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
{
variants: {
side: {
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
bottom:
"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
right:
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
},
},
defaultVariants: {
side: "right",
},
}
)
interface SheetContentProps
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
VariantProps<typeof sheetVariants> {}
const SheetContent = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Content>,
SheetContentProps
>(({ side = "right", className, children, ...props }, ref) => (
<SheetPortal>
<SheetOverlay />
<SheetPrimitive.Content
ref={ref}
className={cn(sheetVariants({ side }), className)}
{...props}
>
{children}
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</SheetPrimitive.Close>
</SheetPrimitive.Content>
</SheetPortal>
))
SheetContent.displayName = SheetPrimitive.Content.displayName
const SheetHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col space-y-2 text-center sm:text-left",
className
)}
{...props}
/>
)
SheetHeader.displayName = "SheetHeader"
const SheetFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
)}
{...props}
/>
)
SheetFooter.displayName = "SheetFooter"
const SheetTitle = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Title
ref={ref}
className={cn("text-lg font-semibold text-foreground", className)}
{...props}
/>
))
SheetTitle.displayName = SheetPrimitive.Title.displayName
const SheetDescription = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
SheetDescription.displayName = SheetPrimitive.Description.displayName
export {
Sheet,
SheetPortal,
SheetOverlay,
SheetTrigger,
SheetClose,
SheetContent,
SheetHeader,
SheetFooter,
SheetTitle,
SheetDescription,
}
================================================
FILE: src/components/ui/sonner.tsx
================================================
"use client"
import { useTheme } from "next-themes"
import { Toaster as Sonner } from "sonner"
type ToasterProps = React.ComponentProps<typeof Sonner>
const Toaster = ({ ...props }: ToasterProps) => {
const { theme = "system" } = useTheme()
return (
<Sonner
theme={theme as ToasterProps["theme"]}
className="toaster group"
toastOptions={{
classNames: {
toast:
"group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg",
description: "group-[.toast]:text-muted-foreground",
actionButton:
"group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
cancelButton:
"group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
},
}}
{...props}
/>
)
}
export { Toaster }
================================================
FILE: src/components/ui/textarea.tsx
================================================
import * as React from "react"
import { cn } from "@/lib/utils"
export interface TextareaProps
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, ...props }, ref) => {
return (
<textarea
className={cn(
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref}
{...props}
/>
)
}
)
Textarea.displayName = "Textarea"
export { Textarea }
================================================
FILE: src/config/index.ts
================================================
import { Metadata } from "next";
export const SITE_CONFIG: Metadata = {
title: {
// write a default title for astra a ai powered website builder suggest something unique and catchy don't use the same words of ai powered website builder give a unique name
default: "Astra - AI Powered Website Builder",
template: `%s | Astra`
},
description: "Astra is an AI powered website builder that helps you create a website in minutes. No coding skills required. Get started for free!",
icons: {
icon: [
{
url: "/icons/favicon.ico",
href: "/icons/favicon.ico",
}
]
},
openGraph: {
title: "Astra - AI Powered Website Builder",
description: "Astra is an AI powered website builder that helps you create a website in minutes. No coding skills required. Get started for free!",
images: [
{
url: "/assets/og-image.png",
}
]
},
twitter: {
card: "summary_large_image",
creator: "@shreyassihasane",
title: "Astra - AI Powered Website Builder",
description: "Astra is an AI powered website builder that helps you create a website in minutes. No coding skills required. Get started for free!",
images: [
{
url: "/assets/og-image.png",
}
]
},
metadataBase: new URL("https://astra-app.vercel.app"),
};
================================================
FILE: src/constants/index.ts
================================================
import { Icons } from "@/components";
export const perks = [
{
icon: Icons.auth,
title: "Sign Up",
info: "Create your free account to get started with Astra.",
},
{
icon: Icons.customize,
title: "Customize",
info: "Choose a template and customize it to fit your needs.",
},
{
icon: Icons.launch,
title: "Launch",
info: "Publish your website and share it with the world.",
},
];
export const features = [
{
icon: Icons.bolt,
title: "Fast Setup",
info: "Get your website up and running in minutes with our intuitive AI-powered builder.",
},
{
icon: Icons.palette,
title: "Customizable Templates",
info: "Choose from a variety of stunning templates and customize them to suit your brand.",
},
{
icon: Icons.seo,
title: "SEO Optimized",
info: "Built-in SEO features ensure your website ranks well on search engines.",
},
{
icon: Icons.monitor,
title: "Responsive Design",
info: "Your website will look great on any device, from desktops to mobile phones.",
},
{
icon: Icons.shop,
title: "E-Commerce Ready",
info: "Start selling online with our e-commerce features and integrations.",
},
{
icon: Icons.server,
title: "Secure Hosting",
info: "Enjoy peace of mind with secure and reliable hosting for your website.",
},
];
export const pricingCards = [
{
title: "Starter",
description: "Perfect for trying out plura",
price: "Free",
duration: "",
highlight: "Key features",
buttonText: "Start for free",
features: ["Limited projects", "1 Team member", "Basic features"],
priceId: "",
},
{
title: "Unlimited Saas",
description: "The ultimate agency kit",
price: "$199",
duration: "month",
highlight: "Key features",
buttonText: "Upgrade to Pro",
features: ["Unlimited projects", "5 Team members", "Advanced design tools", "Customizable domain"],
priceId: "price_1OYxkqFj9oKEERu1KfJGWxgN",
},
{
title: "Enterprise",
description: "For serious agency owners",
price: "$399",
duration: "month",
highlight: "Everything in Starter, plus",
buttonText: "Upgrade to Enterprise",
features: ["Unlimited projects", "Unlimited Team members", "Custom branding", "Priority support (24/7)"],
priceId: "price_1OYxkqFj9oKEERu1NbKUxXxN",
},
];
export const bentoCards = [
{
title: 'Start with Inspiration',
info: 'Browse our vast library of pre-designed templates or upload your own images.',
imgSrc: '/assets/bento-1.svg', // Lightbulb or Inspiration icon
alt: 'Inspiration for website creation'
},
{
title: 'AI Assists Your Vision',
info: 'Our intelligent AI tailors suggestions and functionalities based on your goals.',
imgSrc: '/assets/bento1.svg', // AI Assistant icon
alt: 'AI website building assistant'
},
{
title: 'Drag & Drop Customization',
info: 'Effortlessly personalize your website with our intuitive drag-and-drop editor.',
imgSrc: '/assets/bento1.svg', // Drag and Drop icon or hand editing a website
alt: 'Website customization with drag and drop'
},
{
title: 'Launch & Shine Online',
info: 'Publish your website with a single click and take your brand to the world.',
imgSrc: '/assets/bento1.svg', // Rocket launching or website going live
alt: 'Website launch and publication'
},
];
export const reviews = [
{
name: "Jack",
username: "@jack",
body: "I've never seen anything like this before. It's amazing. I love it.",
},
{
name: "Jill",
username: "@jill",
body: "I don't know what to say. I'm speechless. This is amazing.",
},
{
name: "John",
username: "@john",
body: "I'm at a loss for words. This is amazing. I love it.",
},
{
name: "Jane",
username: "@jane",
body: "I'm at a loss for words. This is amazing. I love it.",
},
{
name: "Jenny",
username: "@jenny",
body: "I'm at a loss for words. This is amazing. I love it.",
},
{
name: "James",
username: "@james",
body: "I'm at a loss for words. This is amazing. I love it.",
},
];
================================================
FILE: src/lib/utils.ts
================================================
import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
================================================
FILE: src/middleware.ts
================================================
import { NextResponse } from "next/server";
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
const isHomeRoute = createRouteMatcher(["/"]);
export default clerkMiddleware((auth, req) => {
const { userId } = auth();
// if there is user and home route is accessed, redirect to dashboard or any other protected route
if (userId && isHomeRoute(req)) {
return NextResponse.rewrite(new URL("/", req.url));
}
});
export const config = {
matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"],
};
================================================
FILE: src/styles/globals.css
================================================
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
/* Name: custom color palette
Author: Ilias Ism
URL: https://gradient.page */
/* CSS: .bg-gradient { background: var(--gradient) } */
--gradient: linear-gradient(to top left, #007adf, #00ecbc);
--background: 220 65% 3.52%;
--foreground: 220 10% 97.2%;
--muted: 220 50% 13.2%;
--muted-foreground: 220 10% 54.4%;
--popover: 220 45% 5.72%;
--popover-foreground: 220 10% 97.2%;
--card: 220 45% 5.72%;
--card-foreground: 220 10% 97.2%;
--border: 220 50% 13.2%;
--input: 220 50% 13.2%;
--primary: 220 100% 44%;
--primary-foreground: 220 10% 97.2%;
--secondary: 220 50% 13.2%;
--secondary-foreground: 220 10% 97.2%;
--accent: 220 50% 13.2%;
--accent-foreground: 220 10% 97.2%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 220 10% 97.2%;
--ring: 220 100% 44%;
--radius: 0.5rem;
}
.dark {
--background: 216 100% 98.04%;
--foreground: 213.6 100% 4.9%;
--primary: 214.12 100% 50%;
--primary-foreground: 0 0% 100%;
--card: 216 100% 98.04%;
--card-foreground: 213.6 100% 4.9%;
--popover: 0 0% 100%;
--popover-foreground: 213.6 100% 4.9%;
--secondary: 214.74 100% 92.55%;
--secondary-foreground: 216 100% 0.98%;
--muted: 213.6 100% 95.1%;
--muted-foreground: 0 0% 40%;
--accent: 213.6 100% 95.1%;
--accent-foreground: 214.12 100% 50%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--border: 0 0% 90.2%;
--input: 0 0% 90.2%;
--ring: 214.12 100% 50%;
--radius: 0.5rem;
}
}
::selection {
background-color: hsl(var(--primary));
color: hsl(var(--primary-foreground));
}
::-webkit-scrollbar {
width: 5px;
background-color: hsl(var(--background));
border-radius: 8px;
scrollbar-width: thin;
}
::-webkit-scrollbar-thumb {
color: hsl(var(--primary));
background-color: hsl(var(--primary));
border-radius: 8px;
}
::-webkit-scrollbar-track {
background-color: hsl(var(--background));
}
.dotPattern {
background-image: radial-gradient(rgb(35, 40, 68) 1px, transparent 1px);
background-size: 25px 25px;
}
.use-automation-zoom-in {
animation: automation-zoom-in 0.5s;
}
.card-mask {
background: radial-gradient(ellipse at center, rgba(0, 75, 224, 0.15), transparent);
}
.gradient {
background: conic-gradient(from 230.29deg at 51.63% 52.16%, rgb(36, 0, 255) 0deg, rgb(0, 135, 255) 67.5deg, rgb(108, 39, 157) 198.75deg, rgb(24, 38, 163) 251.25deg, rgb(54, 103, 196) 301.88deg, rgb(105, 30, 255) 360deg);
}
.lamp {
opacity: 1;
transform: translateY(-200px) rotate(180deg) scale(2) translateZ(0px);
}
@keyframes automation-zoom-in {
0% {
opacity: 0;
transform: scale(0.95);
}
100% {
opacity: 1;
transform: scale(1);
}
}
================================================
FILE: tailwind.config.ts
================================================
module.exports = {
darkMode: ['class'],
content: [
'./pages/**/*.{ts,tsx}',
'./components/**/*.{ts,tsx}',
'./app/**/*.{ts,tsx}',
'./src/**/*.{ts,tsx}',
'./node_modules/@tremor/**/*.{js,ts,jsx,tsx}', // Tremor module
],
theme: {
container: {
center: true,
padding: '2rem',
screens: {
'2xl': '1400px',
},
},
extend: {
colors: {
border: 'hsl(var(--border))',
input: 'hsl(var(--input))',
ring: 'hsl(var(--ring))',
background: 'hsl(var(--background))',
foreground: 'hsl(var(--foreground))',
primary: {
DEFAULT: 'hsl(var(--primary))',
foreground: 'hsl(var(--primary-foreground))',
},
secondary: {
DEFAULT: 'hsl(var(--secondary))',
foreground: 'hsl(var(--secondary-foreground))',
},
destructive: {
DEFAULT: 'hsl(var(--destructive))',
foreground: 'hsl(var(--destructive-foreground))',
},
muted: {
DEFAULT: 'hsl(var(--muted))',
foreground: 'hsl(var(--muted-foreground))',
},
accent: {
DEFAULT: 'hsl(var(--accent))',
foreground: 'hsl(var(--accent-foreground))',
},
popover: {
DEFAULT: 'hsl(var(--popover))',
foreground: 'hsl(var(--popover-foreground))',
},
card: {
DEFAULT: 'hsl(var(--card))',
foreground: 'hsl(var(--card-foreground))',
},
},
borderRadius: {
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
sm: 'calc(var(--radius) - 4px)',
},
keyframes: {
'accordion-down': {
from: { height: '0' },
to: { height: 'var(--radix-accordion-content-height)' },
},
'accordion-up': {
from: { height: 'var(--radix-accordion-content-height)' },
to: { height: '0' },
},
'automation-zoom-in': {
'0%': { transform: 'translateY(-30px) scale(0.2)' },
'100%': { transform: 'transform: translateY(0px) scale(1)' },
},
'flip': {
to: {
transform: "rotate(360deg)",
},
},
'rotate': {
to: {
transform: "rotate(90deg)",
},
},
'rotate-new': {
'0%': { transform: 'rotate(0deg) scale(10)' },
'100%': { transform: 'rotate(-360deg) scale(10)' },
},
'shimmer': {
from: {
backgroundPosition: "0 0",
},
to: {
backgroundPosition: "-200% 0",
},
},
"border-beam": {
"100%": {
"offset-distance": "100%",
},
},
"marquee": {
from: { transform: "translateX(0)" },
to: { transform: "translateX(calc(-100% - var(--gap)))" },
},
},
animation: {
'accordion-down': 'accordion-down 0.2s ease-out',
'accordion-up': 'accordion-up 0.2s ease-out',
'automation-zoom-in': 'automation-zoom-in 0.5s',
'flip': "flip 6s infinite steps(2, end)",
'rotate': "rotate 3s linear infinite both",
'rotate-new': 'rotate-new 20s linear infinite',
'shimmer': "shimmer 2s linear infinite",
"border-beam": "border-beam calc(var(--duration)*1s) infinite linear",
"marquee": "marquee var(--duration) linear infinite",
},
},
},
plugins: [require('tailwindcss-animate')],
};
================================================
FILE: tsconfig.json
================================================
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
gitextract_hcimz5hd/ ├── .eslintrc.json ├── .gitignore ├── .vscode/ │ └── settings.json ├── LICENSE ├── README.md ├── components.json ├── next.config.mjs ├── package.json ├── postcss.config.mjs ├── src/ │ ├── app/ │ │ ├── (auth)/ │ │ │ ├── layout.tsx │ │ │ ├── sign-in/ │ │ │ │ └── [[...sign-in]]/ │ │ │ │ └── page.tsx │ │ │ └── sign-up/ │ │ │ └── [[...sign-up]]/ │ │ │ └── page.tsx │ │ ├── (marketing)/ │ │ │ ├── layout.tsx │ │ │ └── page.tsx │ │ └── layout.tsx │ ├── components/ │ │ ├── global/ │ │ │ ├── container.tsx │ │ │ ├── icons.tsx │ │ │ └── wrapper.tsx │ │ ├── home/ │ │ │ └── navigation/ │ │ │ ├── footer.tsx │ │ │ └── navbar.tsx │ │ ├── index.ts │ │ ├── providers/ │ │ │ ├── providers.tsx │ │ │ └── theme-provider.tsx │ │ └── ui/ │ │ ├── border-beam.tsx │ │ ├── button.tsx │ │ ├── card.tsx │ │ ├── dialog.tsx │ │ ├── input.tsx │ │ ├── label.tsx │ │ ├── lamp.tsx │ │ ├── marquee.tsx │ │ ├── section-badge.tsx │ │ ├── select.tsx │ │ ├── sheet.tsx │ │ ├── sonner.tsx │ │ └── textarea.tsx │ ├── config/ │ │ └── index.ts │ ├── constants/ │ │ └── index.ts │ ├── lib/ │ │ └── utils.ts │ ├── middleware.ts │ └── styles/ │ └── globals.css ├── tailwind.config.ts └── tsconfig.json
SYMBOL INDEX (18 symbols across 17 files)
FILE: src/app/(auth)/layout.tsx
type Props (line 3) | interface Props {
FILE: src/app/(marketing)/layout.tsx
type Props (line 4) | interface Props {
FILE: src/app/layout.tsx
function RootLayout (line 13) | function RootLayout({
FILE: src/components/global/container.tsx
type Props (line 6) | interface Props {
FILE: src/components/global/icons.tsx
type IconType (line 3) | type IconType = {
FILE: src/components/global/wrapper.tsx
type Props (line 4) | interface Props {
FILE: src/components/providers/providers.tsx
type Props (line 7) | interface Props {
FILE: src/components/ui/border-beam.tsx
type BorderBeamProps (line 3) | interface BorderBeamProps {
FILE: src/components/ui/button.tsx
type ButtonProps (line 38) | interface ButtonProps
FILE: src/components/ui/input.tsx
type InputProps (line 5) | interface InputProps
FILE: src/components/ui/marquee.tsx
type MarqueeProps (line 3) | interface MarqueeProps {
function Marquee (line 13) | function Marquee({
FILE: src/components/ui/section-badge.tsx
type Props (line 3) | interface Props {
FILE: src/components/ui/sheet.tsx
type SheetContentProps (line 52) | interface SheetContentProps
FILE: src/components/ui/sonner.tsx
type ToasterProps (line 6) | type ToasterProps = React.ComponentProps<typeof Sonner>
FILE: src/components/ui/textarea.tsx
type TextareaProps (line 5) | interface TextareaProps
FILE: src/config/index.ts
constant SITE_CONFIG (line 3) | const SITE_CONFIG: Metadata = {
FILE: src/lib/utils.ts
function cn (line 4) | function cn(...inputs: ClassValue[]) {
Condensed preview — 43 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (148K chars).
[
{
"path": ".eslintrc.json",
"chars": 40,
"preview": "{\n \"extends\": \"next/core-web-vitals\"\n}\n"
},
{
"path": ".gitignore",
"chars": 396,
"preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pn"
},
{
"path": ".vscode/settings.json",
"chars": 87,
"preview": "{\n \"WillLuke.nextjs.addTypesOnSave\": true,\n \"WillLuke.nextjs.hasPrompted\": true\n}"
},
{
"path": "LICENSE",
"chars": 7048,
"preview": "Creative Commons Legal Code\n\nCC0 1.0 Universal\n\n CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE\n"
},
{
"path": "README.md",
"chars": 1919,
"preview": "<h1 align=\"start\">\n Astra - AI Powered Website Builder\n</h1>\n\n<img width=\"1280\" alt=\"Astra Thumbnail\" src=\"https://gith"
},
{
"path": "components.json",
"chars": 345,
"preview": "{\n \"$schema\": \"https://ui.shadcn.com/schema.json\",\n \"style\": \"default\",\n \"rsc\": true,\n \"tsx\": true,\n \"tailwind\": {\n"
},
{
"path": "next.config.mjs",
"chars": 217,
"preview": "/** @type {import('next').NextConfig} */\nconst nextConfig = {\n images: {\n domains: [\n 'utfs.io',\n 'img.cle"
},
{
"path": "package.json",
"chars": 2407,
"preview": "{\n \"name\": \"astra\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"scripts\": {\n \"dev\": \"next dev\",\n \"build\": \"next b"
},
{
"path": "postcss.config.mjs",
"chars": 135,
"preview": "/** @type {import('postcss-load-config').Config} */\nconst config = {\n plugins: {\n tailwindcss: {},\n },\n};\n\nexport d"
},
{
"path": "src/app/(auth)/layout.tsx",
"chars": 280,
"preview": "import React from 'react'\n\ninterface Props {\n children: React.ReactNode;\n}\n\nconst AuthLayout = ({ children }: Props) "
},
{
"path": "src/app/(auth)/sign-in/[[...sign-in]]/page.tsx",
"chars": 121,
"preview": "import { SignIn } from \"@clerk/nextjs\";\n\nconst SignInPage = () => {\n return <SignIn />;\n};\n\nexport default SignInPage"
},
{
"path": "src/app/(auth)/sign-up/[[...sign-up]]/page.tsx",
"chars": 122,
"preview": "import { SignUp } from \"@clerk/nextjs\";\n\nconst SignUpPage = () => {\n return <SignUp />;\n};\n\nexport default SignUpPage"
},
{
"path": "src/app/(marketing)/layout.tsx",
"chars": 375,
"preview": "import { Footer, Navbar } from \"@/components\";\nimport React from 'react'\n\ninterface Props {\n children: React.ReactNod"
},
{
"path": "src/app/(marketing)/page.tsx",
"chars": 21752,
"preview": "import { Container, Icons, Wrapper } from \"@/components\";\nimport { BorderBeam } from \"@/components/ui/border-beam\";\nimpo"
},
{
"path": "src/app/layout.tsx",
"chars": 917,
"preview": "import { Footer, Navbar } from \"@/components\";\nimport { SITE_CONFIG } from \"@/config\";\nimport { cn } from \"@/lib/utils\";"
},
{
"path": "src/components/global/container.tsx",
"chars": 687,
"preview": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { motion } from \"framer-motion\";\n\ninterface Props {\n classNam"
},
{
"path": "src/components/global/icons.tsx",
"chars": 49071,
"preview": "import { LucideProps } from \"lucide-react\";\n\ntype IconType = {\n [key: string]: (props: LucideProps) => JSX.Element;\n}"
},
{
"path": "src/components/global/wrapper.tsx",
"chars": 404,
"preview": "import React from 'react'\nimport { cn } from \"@/lib/utils\";\n\ninterface Props {\n className?: string;\n children: Rea"
},
{
"path": "src/components/home/navigation/footer.tsx",
"chars": 7652,
"preview": "import Icons from \"@/components/global/icons\"\nimport { Heart } from 'lucide-react'\nimport Link from 'next/link'\n\nconst F"
},
{
"path": "src/components/home/navigation/navbar.tsx",
"chars": 2446,
"preview": "import { Container, Icons } from \"@/components\";\nimport { buttonVariants } from \"@/components/ui/button\";\nimport { UserB"
},
{
"path": "src/components/index.ts",
"chars": 427,
"preview": "import Providers from \"./providers/providers\";\nimport ThemeProvider from \"./providers/theme-provider\";\n\nimport Navbar fr"
},
{
"path": "src/components/providers/providers.tsx",
"chars": 378,
"preview": "\"use client\";\n\nimport React from 'react';\nimport { dark } from \"@clerk/themes\";\nimport { ClerkProvider } from '@clerk/ne"
},
{
"path": "src/components/providers/theme-provider.tsx",
"chars": 356,
"preview": "\"use client\"\n\nimport * as React from \"react\"\nimport { ThemeProvider as NextThemesProvider } from \"next-themes\"\nimport { "
},
{
"path": "src/components/ui/border-beam.tsx",
"chars": 1664,
"preview": "import { cn } from \"@/lib/utils\";\n\ninterface BorderBeamProps {\n className?: string;\n size?: number;\n duration?:"
},
{
"path": "src/components/ui/button.tsx",
"chars": 1891,
"preview": "import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class"
},
{
"path": "src/components/ui/card.tsx",
"chars": 1877,
"preview": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Card = React.forwardRef<\n HTMLDivElement,\n Rea"
},
{
"path": "src/components/ui/dialog.tsx",
"chars": 3849,
"preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\"\nimport { X } from"
},
{
"path": "src/components/ui/input.tsx",
"chars": 824,
"preview": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport interface InputProps\n extends React.InputHTMLA"
},
{
"path": "src/components/ui/label.tsx",
"chars": 724,
"preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\nimport { cva, type "
},
{
"path": "src/components/ui/lamp.tsx",
"chars": 4124,
"preview": "\"use client\";\n\nimport React from \"react\";\nimport { motion } from \"framer-motion\";\nimport { cn } from \"@/lib/utils\";\n\nexp"
},
{
"path": "src/components/ui/marquee.tsx",
"chars": 1445,
"preview": "import { cn } from \"@/lib/utils\";\n\ninterface MarqueeProps {\n className?: string;\n reverse?: boolean;\n pauseOnHo"
},
{
"path": "src/components/ui/section-badge.tsx",
"chars": 698,
"preview": "import React from 'react'\n\ninterface Props {\n title: string;\n}\n\nconst SectionBadge = ({ title }: Props) => {\n retu"
},
{
"path": "src/components/ui/select.tsx",
"chars": 5625,
"preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as SelectPrimitive from \"@radix-ui/react-select\"\nimport { Check, C"
},
{
"path": "src/components/ui/sheet.tsx",
"chars": 4281,
"preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\"\nimport { cva, type"
},
{
"path": "src/components/ui/sonner.tsx",
"chars": 894,
"preview": "\"use client\"\n\nimport { useTheme } from \"next-themes\"\nimport { Toaster as Sonner } from \"sonner\"\n\ntype ToasterProps = Rea"
},
{
"path": "src/components/ui/textarea.tsx",
"chars": 772,
"preview": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport interface TextareaProps\n extends React.Textare"
},
{
"path": "src/config/index.ts",
"chars": 1476,
"preview": "import { Metadata } from \"next\";\n\nexport const SITE_CONFIG: Metadata = {\n title: {\n // write a default title f"
},
{
"path": "src/constants/index.ts",
"chars": 4591,
"preview": "import { Icons } from \"@/components\";\n\nexport const perks = [\n {\n icon: Icons.auth,\n title: \"Sign Up\",\n"
},
{
"path": "src/lib/utils.ts",
"chars": 166,
"preview": "import { type ClassValue, clsx } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: Cla"
},
{
"path": "src/middleware.ts",
"chars": 553,
"preview": "import { NextResponse } from \"next/server\";\nimport { clerkMiddleware, createRouteMatcher } from \"@clerk/nextjs/server\";\n"
},
{
"path": "src/styles/globals.css",
"chars": 2889,
"preview": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n :root {\n /* Name: custom color palette\n "
},
{
"path": "tailwind.config.ts",
"chars": 3522,
"preview": "module.exports = {\n darkMode: ['class'],\n content: [\n './pages/**/*.{ts,tsx}',\n './components/**/*.{ts,tsx}',\n "
},
{
"path": "tsconfig.json",
"chars": 578,
"preview": "{\n \"compilerOptions\": {\n \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n \"allowJs\": true,\n \"skipLibCheck\": true,\n "
}
]
About this extraction
This page contains the full source code of the Shreyas-29/astra GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 43 files (136.7 KB), approximately 46.7k tokens, and a symbol index with 18 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.