├── app ├── favicon.ico ├── page.tsx ├── layout.tsx └── globals.css ├── postcss.config.mjs ├── public ├── vercel.svg ├── window.svg ├── file.svg ├── globe.svg └── next.svg ├── lib └── utils.ts ├── next.config.ts ├── components ├── theme-provider.tsx ├── call-to-action.tsx ├── mode-toggle.tsx ├── ui │ ├── progressive-blur.tsx │ ├── button.tsx │ ├── card.tsx │ ├── infinite-slider.tsx │ └── dropdown-menu.tsx ├── logo.tsx ├── content-1.tsx ├── features-1.tsx ├── hero8-header.tsx ├── footer.tsx └── hero-section.tsx ├── eslint.config.mjs ├── components.json ├── .gitignore ├── tsconfig.json ├── package.json └── README.md /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheOrcDev/orcish-landing-page/HEAD/app/favicon.ico -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | const config = { 2 | plugins: ["@tailwindcss/postcss"], 3 | }; 4 | 5 | export default config; 6 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from "next"; 2 | 3 | const nextConfig: NextConfig = { 4 | /* config options here */ 5 | images: { 6 | remotePatterns: [ 7 | { 8 | hostname: "res.cloudinary.com", 9 | protocol: "https", 10 | }, 11 | ], 12 | }, 13 | }; 14 | 15 | export default nextConfig; 16 | -------------------------------------------------------------------------------- /components/theme-provider.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import * as React from "react"; 4 | import { ThemeProvider as NextThemesProvider } from "next-themes"; 5 | 6 | export function ThemeProvider({ 7 | children, 8 | ...props 9 | }: React.ComponentProps) { 10 | return {children}; 11 | } 12 | -------------------------------------------------------------------------------- /public/window.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { dirname } from "path"; 2 | import { fileURLToPath } from "url"; 3 | import { FlatCompat } from "@eslint/eslintrc"; 4 | 5 | const __filename = fileURLToPath(import.meta.url); 6 | const __dirname = dirname(__filename); 7 | 8 | const compat = new FlatCompat({ 9 | baseDirectory: __dirname, 10 | }); 11 | 12 | const eslintConfig = [ 13 | ...compat.extends("next/core-web-vitals", "next/typescript"), 14 | ]; 15 | 16 | export default eslintConfig; 17 | -------------------------------------------------------------------------------- /app/page.tsx: -------------------------------------------------------------------------------- 1 | import HeroSection from "@/components/hero-section"; 2 | import Features from "@/components/features-1"; 3 | import ContentSection from "@/components/content-1"; 4 | import CallToAction from "@/components/call-to-action"; 5 | import FooterSection from "@/components/footer"; 6 | 7 | export default function Home() { 8 | return ( 9 | <> 10 | 11 | 12 | 13 | 14 | 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "", 8 | "css": "app/globals.css", 9 | "baseColor": "stone", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # env files (can opt-in for committing if needed) 34 | .env* 35 | 36 | # vercel 37 | .vercel 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | next-env.d.ts 42 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./*"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /public/globe.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/call-to-action.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from "@/components/ui/button"; 2 | import Link from "next/link"; 3 | 4 | export default function CallToAction() { 5 | return ( 6 |
7 |
8 |
9 |

10 | Start Building 11 |

12 |

Libero sapiente aliquam quibusdam aspernatur.

13 | 14 |
15 | 20 | 21 | 26 |
27 |
28 |
29 |
30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "orcish-landing-page", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev --turbopack", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@radix-ui/react-dropdown-menu": "^2.1.15", 13 | "@radix-ui/react-slot": "^1.2.3", 14 | "class-variance-authority": "^0.7.1", 15 | "clsx": "^2.1.1", 16 | "lucide-react": "^0.525.0", 17 | "motion": "^12.23.6", 18 | "next": "15.4.1", 19 | "next-themes": "^0.4.6", 20 | "react": "^19.1.0", 21 | "react-dom": "^19.1.0", 22 | "react-use-measure": "^2.1.7", 23 | "tailwind-merge": "^3.3.1", 24 | "tw-animate-css": "^1.3.5" 25 | }, 26 | "devDependencies": { 27 | "@eslint/eslintrc": "^3.3.1", 28 | "@tailwindcss/postcss": "^4.1.11", 29 | "@types/node": "^24.0.14", 30 | "@types/react": "^19.1.8", 31 | "@types/react-dom": "^19.1.6", 32 | "eslint": "^9.31.0", 33 | "eslint-config-next": "15.4.1", 34 | "tailwindcss": "^4.1.11", 35 | "typescript": "^5.8.3" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Geist, Geist_Mono } from "next/font/google"; 3 | import "./globals.css"; 4 | import { ThemeProvider } from "@/components/theme-provider"; 5 | 6 | const geistSans = Geist({ 7 | variable: "--font-geist-sans", 8 | subsets: ["latin"], 9 | }); 10 | 11 | const geistMono = Geist_Mono({ 12 | variable: "--font-geist-mono", 13 | subsets: ["latin"], 14 | }); 15 | 16 | export const metadata: Metadata = { 17 | title: "Create Next App", 18 | description: "Generated by create next app", 19 | }; 20 | 21 | export default function RootLayout({ 22 | children, 23 | }: Readonly<{ 24 | children: React.ReactNode; 25 | }>) { 26 | return ( 27 | 28 | 31 | 37 | {children} 38 | 39 | 40 | 41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/mode-toggle.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import * as React from "react"; 4 | import { Moon, Sun } from "lucide-react"; 5 | import { useTheme } from "next-themes"; 6 | 7 | import { Button } from "@/components/ui/button"; 8 | import { 9 | DropdownMenu, 10 | DropdownMenuContent, 11 | DropdownMenuItem, 12 | DropdownMenuTrigger, 13 | } from "@/components/ui/dropdown-menu"; 14 | 15 | export function ModeToggle() { 16 | const { setTheme } = useTheme(); 17 | 18 | return ( 19 | 20 | 21 | 26 | 27 | 28 | setTheme("light")}> 29 | Light 30 | 31 | setTheme("dark")}> 32 | Dark 33 | 34 | setTheme("system")}> 35 | System 36 | 37 | 38 | 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | # or 12 | pnpm dev 13 | # or 14 | bun dev 15 | ``` 16 | 17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 18 | 19 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. 20 | 21 | This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. 22 | 23 | ## Learn More 24 | 25 | To learn more about Next.js, take a look at the following resources: 26 | 27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 29 | 30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! 31 | 32 | ## Deploy on Vercel 33 | 34 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 35 | 36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. 37 | -------------------------------------------------------------------------------- /components/ui/progressive-blur.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import { cn } from "@/lib/utils"; 3 | import { HTMLMotionProps, motion } from "motion/react"; 4 | 5 | export const GRADIENT_ANGLES = { 6 | top: 0, 7 | right: 90, 8 | bottom: 180, 9 | left: 270, 10 | }; 11 | 12 | export type ProgressiveBlurProps = { 13 | direction?: keyof typeof GRADIENT_ANGLES; 14 | blurLayers?: number; 15 | className?: string; 16 | blurIntensity?: number; 17 | } & HTMLMotionProps<"div">; 18 | 19 | export function ProgressiveBlur({ 20 | direction = "bottom", 21 | blurLayers = 8, 22 | className, 23 | blurIntensity = 0.25, 24 | ...props 25 | }: ProgressiveBlurProps) { 26 | const layers = Math.max(blurLayers, 2); 27 | const segmentSize = 1 / (blurLayers + 1); 28 | 29 | return ( 30 |
31 | {Array.from({ length: layers }).map((_, index) => { 32 | const angle = GRADIENT_ANGLES[direction]; 33 | const gradientStops = [ 34 | index * segmentSize, 35 | (index + 1) * segmentSize, 36 | (index + 2) * segmentSize, 37 | (index + 3) * segmentSize, 38 | ].map( 39 | (pos, posIndex) => 40 | `rgba(255, 255, 255, ${posIndex === 1 || posIndex === 2 ? 1 : 0}) ${ 41 | pos * 100 42 | }%` 43 | ); 44 | 45 | const gradient = `linear-gradient(${angle}deg, ${gradientStops.join( 46 | ", " 47 | )})`; 48 | 49 | return ( 50 | 60 | ); 61 | })} 62 |
63 | ); 64 | } 65 | -------------------------------------------------------------------------------- /components/ui/button.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { Slot } from "@radix-ui/react-slot" 3 | import { cva, type VariantProps } from "class-variance-authority" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const buttonVariants = cva( 8 | "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", 9 | { 10 | variants: { 11 | variant: { 12 | default: 13 | "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90", 14 | destructive: 15 | "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", 16 | outline: 17 | "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", 18 | secondary: 19 | "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80", 20 | ghost: 21 | "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", 22 | link: "text-primary underline-offset-4 hover:underline", 23 | }, 24 | size: { 25 | default: "h-9 px-4 py-2 has-[>svg]:px-3", 26 | sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", 27 | lg: "h-10 rounded-md px-6 has-[>svg]:px-4", 28 | icon: "size-9", 29 | }, 30 | }, 31 | defaultVariants: { 32 | variant: "default", 33 | size: "default", 34 | }, 35 | } 36 | ) 37 | 38 | function Button({ 39 | className, 40 | variant, 41 | size, 42 | asChild = false, 43 | ...props 44 | }: React.ComponentProps<"button"> & 45 | VariantProps & { 46 | asChild?: boolean 47 | }) { 48 | const Comp = asChild ? Slot : "button" 49 | 50 | return ( 51 | 56 | ) 57 | } 58 | 59 | export { Button, buttonVariants } 60 | -------------------------------------------------------------------------------- /components/ui/card.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | function Card({ className, ...props }: React.ComponentProps<"div">) { 6 | return ( 7 |
15 | ) 16 | } 17 | 18 | function CardHeader({ className, ...props }: React.ComponentProps<"div">) { 19 | return ( 20 |
28 | ) 29 | } 30 | 31 | function CardTitle({ className, ...props }: React.ComponentProps<"div">) { 32 | return ( 33 |
38 | ) 39 | } 40 | 41 | function CardDescription({ className, ...props }: React.ComponentProps<"div">) { 42 | return ( 43 |
48 | ) 49 | } 50 | 51 | function CardAction({ className, ...props }: React.ComponentProps<"div">) { 52 | return ( 53 |
61 | ) 62 | } 63 | 64 | function CardContent({ className, ...props }: React.ComponentProps<"div">) { 65 | return ( 66 |
71 | ) 72 | } 73 | 74 | function CardFooter({ className, ...props }: React.ComponentProps<"div">) { 75 | return ( 76 |
81 | ) 82 | } 83 | 84 | export { 85 | Card, 86 | CardHeader, 87 | CardFooter, 88 | CardTitle, 89 | CardAction, 90 | CardDescription, 91 | CardContent, 92 | } 93 | -------------------------------------------------------------------------------- /components/logo.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils' 2 | import { motion } from 'motion/react' 3 | 4 | export const Logo = ({ className }: { className?: string }) => { 5 | return ( 6 | 11 | 15 | 16 | ) 17 | } 18 | 19 | export const LogoStroke = ({ className }: { className?: string }) => { 20 | return ( 21 | 26 | 32 | 33 | ) 34 | } 35 | -------------------------------------------------------------------------------- /components/content-1.tsx: -------------------------------------------------------------------------------- 1 | import Image from "next/image"; 2 | 3 | export default function ContentSection() { 4 | return ( 5 |
6 |
7 |

8 | The Lyra ecosystem brings together our models. 9 |

10 |
11 |
12 |
13 | payments illustration dark 20 | payments illustration light 27 |
28 |
29 | 30 |
31 |

32 | Gemini is evolving to be more than just the models.{" "} 33 | 34 | It supports an entire ecosystem 35 | {" "} 36 | — from products innovate. 37 |

38 |

39 | It supports an entire ecosystem — from products to the APIs and 40 | platforms helping developers and businesses innovate 41 |

42 | 43 |
44 |
45 |

46 | Using TailsUI has been like unlocking a secret design 47 | superpower. It's the perfect fusion of simplicity and 48 | versatility, enabling us to create UIs that are as stunning as 49 | they are user-friendly. 50 |

51 | 52 |
53 | John Doe, CEO 54 | Nvidia Logo 61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | ); 69 | } 70 | -------------------------------------------------------------------------------- /components/ui/infinite-slider.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { cn } from '@/lib/utils'; 3 | import { useMotionValue, animate, motion } from 'motion/react'; 4 | import { useState, useEffect } from 'react'; 5 | import useMeasure from 'react-use-measure'; 6 | 7 | export type InfiniteSliderProps = { 8 | children: React.ReactNode; 9 | gap?: number; 10 | speed?: number; 11 | speedOnHover?: number; 12 | direction?: 'horizontal' | 'vertical'; 13 | reverse?: boolean; 14 | className?: string; 15 | }; 16 | 17 | export function InfiniteSlider({ 18 | children, 19 | gap = 16, 20 | speed = 100, 21 | speedOnHover, 22 | direction = 'horizontal', 23 | reverse = false, 24 | className, 25 | }: InfiniteSliderProps) { 26 | const [currentSpeed, setCurrentSpeed] = useState(speed); 27 | const [ref, { width, height }] = useMeasure(); 28 | const translation = useMotionValue(0); 29 | const [isTransitioning, setIsTransitioning] = useState(false); 30 | const [key, setKey] = useState(0); 31 | 32 | useEffect(() => { 33 | let controls; 34 | const size = direction === 'horizontal' ? width : height; 35 | const contentSize = size + gap; 36 | const from = reverse ? -contentSize / 2 : 0; 37 | const to = reverse ? 0 : -contentSize / 2; 38 | 39 | const distanceToTravel = Math.abs(to - from); 40 | const duration = distanceToTravel / currentSpeed; 41 | 42 | if (isTransitioning) { 43 | const remainingDistance = Math.abs(translation.get() - to); 44 | const transitionDuration = remainingDistance / currentSpeed; 45 | 46 | controls = animate(translation, [translation.get(), to], { 47 | ease: 'linear', 48 | duration: transitionDuration, 49 | onComplete: () => { 50 | setIsTransitioning(false); 51 | setKey((prevKey) => prevKey + 1); 52 | }, 53 | }); 54 | } else { 55 | controls = animate(translation, [from, to], { 56 | ease: 'linear', 57 | duration: duration, 58 | repeat: Infinity, 59 | repeatType: 'loop', 60 | repeatDelay: 0, 61 | onRepeat: () => { 62 | translation.set(from); 63 | }, 64 | }); 65 | } 66 | 67 | return controls?.stop; 68 | }, [ 69 | key, 70 | translation, 71 | currentSpeed, 72 | width, 73 | height, 74 | gap, 75 | isTransitioning, 76 | direction, 77 | reverse, 78 | ]); 79 | 80 | const hoverProps = speedOnHover 81 | ? { 82 | onHoverStart: () => { 83 | setIsTransitioning(true); 84 | setCurrentSpeed(speedOnHover); 85 | }, 86 | onHoverEnd: () => { 87 | setIsTransitioning(true); 88 | setCurrentSpeed(speed); 89 | }, 90 | } 91 | : {}; 92 | 93 | return ( 94 |
95 | 107 | {children} 108 | {children} 109 | 110 |
111 | ); 112 | } 113 | -------------------------------------------------------------------------------- /components/features-1.tsx: -------------------------------------------------------------------------------- 1 | import { Card, CardContent, CardHeader } from "@/components/ui/card"; 2 | import { Settings2, Sparkles, Zap } from "lucide-react"; 3 | import { ReactNode } from "react"; 4 | 5 | export default function Features() { 6 | return ( 7 |
8 |
9 |
10 |

11 | Built to cover your needs 12 |

13 |

14 | Libero sapiente aliquam quibusdam aspernatur, praesentium iusto 15 | repellendus. 16 |

17 |
18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |

Customizable

26 |
27 | 28 | 29 |

30 | Extensive customization options, allowing you to tailor every 31 | aspect to meet your specific needs. 32 |

33 |
34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |

You have full control

43 |
44 | 45 | 46 |

47 | From design elements to functionality, you have complete control 48 | to create a unique and personalized experience. 49 |

50 |
51 |
52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |

Powered By AI

60 |
61 | 62 | 63 |

64 | Elements to functionality, you have complete control to create a 65 | unique experience. 66 |

67 |
68 |
69 |
70 |
71 |
72 | ); 73 | } 74 | 75 | const CardDecorator = ({ children }: { children: ReactNode }) => ( 76 |
77 |
81 |
85 |
86 | {children} 87 |
88 |
89 | ); 90 | -------------------------------------------------------------------------------- /components/hero8-header.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import Link from "next/link"; 3 | import { Logo } from "./logo"; 4 | import { Menu, X } from "lucide-react"; 5 | import { Button } from "@/components/ui/button"; 6 | import React from "react"; 7 | import { ModeToggle } from "./mode-toggle"; 8 | 9 | const menuItems = [ 10 | { name: "Features", href: "#link" }, 11 | { name: "Solution", href: "#link" }, 12 | { name: "Pricing", href: "#link" }, 13 | { name: "About", href: "#link" }, 14 | ]; 15 | 16 | export const HeroHeader = () => { 17 | const [menuState, setMenuState] = React.useState(false); 18 | return ( 19 |
20 | 92 |
93 | ); 94 | }; 95 | -------------------------------------------------------------------------------- /app/globals.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | @import "tw-animate-css"; 3 | 4 | @custom-variant dark (&:is(.dark *)); 5 | 6 | @theme inline { 7 | --color-background: var(--background); 8 | --color-foreground: var(--foreground); 9 | --font-sans: var(--font-geist-sans); 10 | --font-mono: var(--font-geist-mono); 11 | --color-sidebar-ring: var(--sidebar-ring); 12 | --color-sidebar-border: var(--sidebar-border); 13 | --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); 14 | --color-sidebar-accent: var(--sidebar-accent); 15 | --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); 16 | --color-sidebar-primary: var(--sidebar-primary); 17 | --color-sidebar-foreground: var(--sidebar-foreground); 18 | --color-sidebar: var(--sidebar); 19 | --color-chart-5: var(--chart-5); 20 | --color-chart-4: var(--chart-4); 21 | --color-chart-3: var(--chart-3); 22 | --color-chart-2: var(--chart-2); 23 | --color-chart-1: var(--chart-1); 24 | --color-ring: var(--ring); 25 | --color-input: var(--input); 26 | --color-border: var(--border); 27 | --color-destructive: var(--destructive); 28 | --color-accent-foreground: var(--accent-foreground); 29 | --color-accent: var(--accent); 30 | --color-muted-foreground: var(--muted-foreground); 31 | --color-muted: var(--muted); 32 | --color-secondary-foreground: var(--secondary-foreground); 33 | --color-secondary: var(--secondary); 34 | --color-primary-foreground: var(--primary-foreground); 35 | --color-primary: var(--primary); 36 | --color-popover-foreground: var(--popover-foreground); 37 | --color-popover: var(--popover); 38 | --color-card-foreground: var(--card-foreground); 39 | --color-card: var(--card); 40 | --radius-sm: calc(var(--radius) - 4px); 41 | --radius-md: calc(var(--radius) - 2px); 42 | --radius-lg: var(--radius); 43 | --radius-xl: calc(var(--radius) + 4px); 44 | } 45 | 46 | :root { 47 | --radius: 0.625rem; 48 | --background: oklch(1 0 0); 49 | --foreground: oklch(0.147 0.004 49.25); 50 | --card: oklch(1 0 0); 51 | --card-foreground: oklch(0.147 0.004 49.25); 52 | --popover: oklch(1 0 0); 53 | --popover-foreground: oklch(0.147 0.004 49.25); 54 | --primary: oklch(0.216 0.006 56.043); 55 | --primary-foreground: oklch(0.985 0.001 106.423); 56 | --secondary: oklch(0.97 0.001 106.424); 57 | --secondary-foreground: oklch(0.216 0.006 56.043); 58 | --muted: oklch(0.97 0.001 106.424); 59 | --muted-foreground: oklch(0.553 0.013 58.071); 60 | --accent: oklch(0.97 0.001 106.424); 61 | --accent-foreground: oklch(0.216 0.006 56.043); 62 | --destructive: oklch(0.577 0.245 27.325); 63 | --border: oklch(0.923 0.003 48.717); 64 | --input: oklch(0.923 0.003 48.717); 65 | --ring: oklch(0.709 0.01 56.259); 66 | --chart-1: oklch(0.646 0.222 41.116); 67 | --chart-2: oklch(0.6 0.118 184.704); 68 | --chart-3: oklch(0.398 0.07 227.392); 69 | --chart-4: oklch(0.828 0.189 84.429); 70 | --chart-5: oklch(0.769 0.188 70.08); 71 | --sidebar: oklch(0.985 0.001 106.423); 72 | --sidebar-foreground: oklch(0.147 0.004 49.25); 73 | --sidebar-primary: oklch(0.216 0.006 56.043); 74 | --sidebar-primary-foreground: oklch(0.985 0.001 106.423); 75 | --sidebar-accent: oklch(0.97 0.001 106.424); 76 | --sidebar-accent-foreground: oklch(0.216 0.006 56.043); 77 | --sidebar-border: oklch(0.923 0.003 48.717); 78 | --sidebar-ring: oklch(0.709 0.01 56.259); 79 | } 80 | 81 | .dark { 82 | --background: oklch(0.147 0.004 49.25); 83 | --foreground: oklch(0.985 0.001 106.423); 84 | --card: oklch(0.216 0.006 56.043); 85 | --card-foreground: oklch(0.985 0.001 106.423); 86 | --popover: oklch(0.216 0.006 56.043); 87 | --popover-foreground: oklch(0.985 0.001 106.423); 88 | --primary: oklch(0.923 0.003 48.717); 89 | --primary-foreground: oklch(0.216 0.006 56.043); 90 | --secondary: oklch(0.268 0.007 34.298); 91 | --secondary-foreground: oklch(0.985 0.001 106.423); 92 | --muted: oklch(0.268 0.007 34.298); 93 | --muted-foreground: oklch(0.709 0.01 56.259); 94 | --accent: oklch(0.268 0.007 34.298); 95 | --accent-foreground: oklch(0.985 0.001 106.423); 96 | --destructive: oklch(0.704 0.191 22.216); 97 | --border: oklch(1 0 0 / 10%); 98 | --input: oklch(1 0 0 / 15%); 99 | --ring: oklch(0.553 0.013 58.071); 100 | --chart-1: oklch(0.488 0.243 264.376); 101 | --chart-2: oklch(0.696 0.17 162.48); 102 | --chart-3: oklch(0.769 0.188 70.08); 103 | --chart-4: oklch(0.627 0.265 303.9); 104 | --chart-5: oklch(0.645 0.246 16.439); 105 | --sidebar: oklch(0.216 0.006 56.043); 106 | --sidebar-foreground: oklch(0.985 0.001 106.423); 107 | --sidebar-primary: oklch(0.488 0.243 264.376); 108 | --sidebar-primary-foreground: oklch(0.985 0.001 106.423); 109 | --sidebar-accent: oklch(0.268 0.007 34.298); 110 | --sidebar-accent-foreground: oklch(0.985 0.001 106.423); 111 | --sidebar-border: oklch(1 0 0 / 10%); 112 | --sidebar-ring: oklch(0.553 0.013 58.071); 113 | } 114 | 115 | @layer base { 116 | * { 117 | @apply border-border outline-ring/50; 118 | } 119 | body { 120 | @apply bg-background text-foreground; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /components/footer.tsx: -------------------------------------------------------------------------------- 1 | import { Logo } from "@/components/logo"; 2 | import Link from "next/link"; 3 | 4 | const links = [ 5 | { 6 | title: "Features", 7 | href: "#", 8 | }, 9 | { 10 | title: "Solution", 11 | href: "#", 12 | }, 13 | { 14 | title: "Customers", 15 | href: "#", 16 | }, 17 | { 18 | title: "Pricing", 19 | href: "#", 20 | }, 21 | { 22 | title: "Help", 23 | href: "#", 24 | }, 25 | { 26 | title: "About", 27 | href: "#", 28 | }, 29 | ]; 30 | 31 | export default function FooterSection() { 32 | return ( 33 |
34 |
35 | 36 | 37 | 38 | 39 |
40 | {links.map((link, index) => ( 41 | 46 | {link.title} 47 | 48 | ))} 49 |
50 |
51 | 58 | 65 | 69 | 70 | 71 | 78 | 85 | 89 | 90 | 91 | 98 | 105 | 109 | 110 | 111 | 118 | 125 | 134 | 135 | 136 | 143 | 150 | 154 | 155 | 156 | 163 | 170 | 174 | 175 | 176 |
177 | 178 | {" "} 179 | © {new Date().getFullYear()} Tailus UI, All rights reserved 180 | 181 |
182 |
183 | ); 184 | } 185 | -------------------------------------------------------------------------------- /components/hero-section.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Link from "next/link"; 3 | import { Button } from "@/components/ui/button"; 4 | import Image from "next/image"; 5 | import { HeroHeader } from "@/components/hero8-header"; 6 | import { InfiniteSlider } from "@/components/ui/infinite-slider"; 7 | import { ProgressiveBlur } from "@/components/ui/progressive-blur"; 8 | 9 | export default function HeroSection() { 10 | return ( 11 | <> 12 | 13 |
14 |
15 |
16 |
17 |
18 |

19 | Ship 10x Faster with NS 20 |

21 |

22 | Highly customizable components for building modern websites 23 | and applications that look and feel the way you mean it. 24 |

25 | 26 |
27 | 32 | 43 |
44 |
45 | Abstract Object 52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |

Powering the best teams

60 |
61 |
62 | 63 |
64 | Nvidia Logo 71 |
72 | 73 |
74 | Column Logo 81 |
82 |
83 | GitHub Logo 90 |
91 |
92 | Nike Logo 99 |
100 |
101 | Lemon Squeezy Logo 108 |
109 |
110 | Laravel Logo 117 |
118 |
119 | Lilly Logo 126 |
127 | 128 |
129 | OpenAI Logo 136 |
137 |
138 | 139 |
140 |
141 | 146 | 151 |
152 |
153 |
154 |
155 |
156 | 157 | ); 158 | } 159 | -------------------------------------------------------------------------------- /components/ui/dropdown-menu.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" 5 | import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | function DropdownMenu({ 10 | ...props 11 | }: React.ComponentProps) { 12 | return 13 | } 14 | 15 | function DropdownMenuPortal({ 16 | ...props 17 | }: React.ComponentProps) { 18 | return ( 19 | 20 | ) 21 | } 22 | 23 | function DropdownMenuTrigger({ 24 | ...props 25 | }: React.ComponentProps) { 26 | return ( 27 | 31 | ) 32 | } 33 | 34 | function DropdownMenuContent({ 35 | className, 36 | sideOffset = 4, 37 | ...props 38 | }: React.ComponentProps) { 39 | return ( 40 | 41 | 50 | 51 | ) 52 | } 53 | 54 | function DropdownMenuGroup({ 55 | ...props 56 | }: React.ComponentProps) { 57 | return ( 58 | 59 | ) 60 | } 61 | 62 | function DropdownMenuItem({ 63 | className, 64 | inset, 65 | variant = "default", 66 | ...props 67 | }: React.ComponentProps & { 68 | inset?: boolean 69 | variant?: "default" | "destructive" 70 | }) { 71 | return ( 72 | 82 | ) 83 | } 84 | 85 | function DropdownMenuCheckboxItem({ 86 | className, 87 | children, 88 | checked, 89 | ...props 90 | }: React.ComponentProps) { 91 | return ( 92 | 101 | 102 | 103 | 104 | 105 | 106 | {children} 107 | 108 | ) 109 | } 110 | 111 | function DropdownMenuRadioGroup({ 112 | ...props 113 | }: React.ComponentProps) { 114 | return ( 115 | 119 | ) 120 | } 121 | 122 | function DropdownMenuRadioItem({ 123 | className, 124 | children, 125 | ...props 126 | }: React.ComponentProps) { 127 | return ( 128 | 136 | 137 | 138 | 139 | 140 | 141 | {children} 142 | 143 | ) 144 | } 145 | 146 | function DropdownMenuLabel({ 147 | className, 148 | inset, 149 | ...props 150 | }: React.ComponentProps & { 151 | inset?: boolean 152 | }) { 153 | return ( 154 | 163 | ) 164 | } 165 | 166 | function DropdownMenuSeparator({ 167 | className, 168 | ...props 169 | }: React.ComponentProps) { 170 | return ( 171 | 176 | ) 177 | } 178 | 179 | function DropdownMenuShortcut({ 180 | className, 181 | ...props 182 | }: React.ComponentProps<"span">) { 183 | return ( 184 | 192 | ) 193 | } 194 | 195 | function DropdownMenuSub({ 196 | ...props 197 | }: React.ComponentProps) { 198 | return 199 | } 200 | 201 | function DropdownMenuSubTrigger({ 202 | className, 203 | inset, 204 | children, 205 | ...props 206 | }: React.ComponentProps & { 207 | inset?: boolean 208 | }) { 209 | return ( 210 | 219 | {children} 220 | 221 | 222 | ) 223 | } 224 | 225 | function DropdownMenuSubContent({ 226 | className, 227 | ...props 228 | }: React.ComponentProps) { 229 | return ( 230 | 238 | ) 239 | } 240 | 241 | export { 242 | DropdownMenu, 243 | DropdownMenuPortal, 244 | DropdownMenuTrigger, 245 | DropdownMenuContent, 246 | DropdownMenuGroup, 247 | DropdownMenuLabel, 248 | DropdownMenuItem, 249 | DropdownMenuCheckboxItem, 250 | DropdownMenuRadioGroup, 251 | DropdownMenuRadioItem, 252 | DropdownMenuSeparator, 253 | DropdownMenuShortcut, 254 | DropdownMenuSub, 255 | DropdownMenuSubTrigger, 256 | DropdownMenuSubContent, 257 | } 258 | --------------------------------------------------------------------------------