-
+const GradientBackground = ({children, className = ''}) => (
+
+)
+
+const PatternBackground = ({pattern, className = ''}) => (
+
+)
+
+const FeatureCard = ({title, description, icon, pattern}) => (
+
+
+
+
+
+
+
{title}
+
{description}
+
+
+)
+
+const TechnologyCard = ({title, description, logo, link}) => (
+
+
+
+
+
+
{description}
+
+ Learn more
+
+
+
+)
+
+const RuntimeCard = ({title, description, logo, link, logoClassName = ''}) => (
+
+
+
+
+
-
- The next generation of building APIs
+ {title}
+
+
+
+ {description}
+
+ Learn more
+
+
+
+
+)
+
+const patterns = {
+ dots: `
`,
+ lines: `
`,
+ squares: `
`,
+ circles: `
`,
+ zigzag: `
`,
+ waves: `
`,
+ triangles: `
`,
+ hexagons: `
`
+}
+
+export function Landing() {
+ const {resolvedTheme} = useTheme()
+ const [animationData, setAnimationData] = useState(null)
+
+ useEffect(() => {
+ fetch(
+ 'https://lottie.host/c32b1c68-74ef-4a25-91b2-11f792317480/we8GALnU48.json'
+ )
+ .then(response => response.json())
+ .then(data => setAnimationData(data))
+ .catch(error => console.error('Error loading Lottie animation:', error))
+ }, [])
+
+ return (
+
+ {/* Hero */}
+
+
+ The Next Generation of
+
+ Building APIs
-
-
- A code-first framework for GraphQL API development, where your
- schema reflects your functionality.
+
+ Used by innovative teams worldwide, Pylon enables you to create
+
+ {' '}
+ high-quality GraphQL APIs{' '}
+
+ without defining any schema.
+
+
+
+ Get started
+
+
+
+ {/*
+ Get started
+ */}
+
+
+
+
+
+
+ npm create
+ pylon@latest
+
+
+
+
+
+
+
+ {/* Features */}
+
+
+
+
+ What's in Pylon?
+
+
+ Everything you need to build production-ready GraphQL APIs.
+
+
+
+
}
+ pattern={patterns.dots}
+ />
+
}
+ pattern={patterns.lines}
+ />
+
}
+ pattern={patterns.squares}
+ />
+
}
+ pattern={patterns.circles}
+ />
+
}
+ pattern={patterns.zigzag}
+ />
+
}
+ pattern={patterns.waves}
+ />
+
}
+ pattern={patterns.triangles}
+ />
+
}
+ pattern={patterns.hexagons}
+ />
+
+
+
+ Pylon 2.3
+
+
+
+ Full Support for TypeScript Interfaces and Unions in Pylon
+
+
+
+
+
+
+
+
+
+ {/* Foundation / Powered By */}
+
+
+
+ Built on a Foundation of Fast, Production-Grade Tooling
+
+
+ {/* Powered By Box with Lottie Animation */}
+
+
+ Powered By
+
+ {animationData && (
+
+ )}
+
+
+ {/* Technology Cards */}
+
+
+
+
+
+
+ {/* Supported Runtimes */}
+
+
+ Supported Runtimes
+
+
+
+
+
+
+
+
+ Pylon is designed to be runtime-agnostic, allowing you to deploy
+ your GraphQL API to various environments. Choose the runtime
+ that best fits your project's needs and infrastructure
+ requirements.
+
+
+
-
-
-
-
- Explore documentation
-
-
-
-
-
-
+
+
+ {/* Improved CTA */}
+
+
+
+
+
+ Start Building Powerful APIs Today
+
+
+ Join hundreds of developers who are revolutionizing API
+ development with Pylon.
+
+
+
+
+
+
+
+ Documentation
+
+
+
+
+ Explore our comprehensive documentation to get started with
+ Pylon and learn about all its features.
+
+
+ View Documentation
+
+
+
+
+
+
+ Open Source
+
+
+
+
+ Pylon is open source. Contribute, report issues, or star our
+ GitHub repository to support the project.
+
+
+
+ View on GitHub
+
+
+
+
+
+
+
+
+ "Pylon is the foundation of our greater vision to make backend
+ development easier and faster. It's revolutionizing how we build
+ and scale APIs."
+
+
+
+
+
Nico Schett
+
CEO, Cronit
+
+
+
+
+
+
)
}
diff --git a/docs/components/ui/card.tsx b/docs/components/ui/card.tsx
index 7820300..2e90a32 100644
--- a/docs/components/ui/card.tsx
+++ b/docs/components/ui/card.tsx
@@ -4,8 +4,8 @@ import {cn} from '@/lib/utils'
const Card = React.forwardRef<
HTMLDivElement,
- React.HTMLAttributes
->(({className, ...props}, ref) => (
+ React.HTMLAttributes & {showGradient?: boolean}
+>(({className, showGradient = true, ...props}, ref) => (
-
+ {showGradient && (
+
+ )}
{props.children}
))
diff --git a/docs/components/ui/glowing-stars-card.tsx b/docs/components/ui/glowing-stars-card.tsx
new file mode 100644
index 0000000..b792be1
--- /dev/null
+++ b/docs/components/ui/glowing-stars-card.tsx
@@ -0,0 +1,169 @@
+'use client'
+
+import React, {useEffect, useRef, useState} from 'react'
+import {AnimatePresence, motion} from 'framer-motion'
+import {cn} from '@/lib/utils'
+import {useTheme} from 'nextra-theme-docs'
+
+export const GlowingStarsCard = ({
+ className,
+ children,
+ hoverEfect = true
+}: {
+ className?: string
+ children?: React.ReactNode
+ hoverEfect?: boolean
+}) => {
+ const [mouseEnter, setMouseEnter] = useState(false)
+
+ return (
+ {
+ if (!hoverEfect) return
+ setMouseEnter(true)
+ }}
+ onMouseLeave={() => {
+ if (!hoverEfect) return
+ setMouseEnter(false)
+ }}
+ className={cn(
+ 'p-6 max-w-md h-full w-full rounded-xl border border-[#eaeaea] dark:border-gray-800',
+ className
+ )}>
+
+
+
+
{children}
+
+ )
+}
+
+export const GlowingStarsDescription = ({
+ className,
+ children
+}: {
+ className?: string
+ children?: React.ReactNode
+}) => {
+ return (
+
+ {children}
+
+ )
+}
+
+export const GlowingStarsTitle = ({
+ className,
+ children
+}: {
+ className?: string
+ children?: React.ReactNode
+}) => {
+ return (
+
+ {children}
+
+ )
+}
+
+export const Illustration = ({mouseEnter}: {mouseEnter: boolean}) => {
+ const stars = 108
+ const columns = 18
+
+ const [glowingStars, setGlowingStars] = useState([])
+
+ const highlightedStars = useRef([])
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ highlightedStars.current = Array.from({length: 5}, () =>
+ Math.floor(Math.random() * stars)
+ )
+ setGlowingStars([...highlightedStars.current])
+ }, 3000)
+
+ return () => clearInterval(interval)
+ }, [])
+
+ return (
+
+ {[...Array(stars)].map((_, starIdx) => {
+ const isGlowing = glowingStars.includes(starIdx)
+ const delay = (starIdx % 10) * 0.1
+ const staticDelay = starIdx * 0.01
+ return (
+
+
+ {mouseEnter &&
}
+
+ {isGlowing && }
+
+
+ )
+ })}
+
+ )
+}
+
+const Star = ({isGlowing, delay}: {isGlowing: boolean; delay: number}) => {
+ const {resolvedTheme} = useTheme()
+ const isDarkTheme = resolvedTheme === 'dark'
+ return (
+
+ )
+}
+
+const Glow = ({delay}: {delay: number}) => {
+ return (
+
+ )
+}
diff --git a/docs/components/ui/hover-border-gradient.tsx b/docs/components/ui/hover-border-gradient.tsx
new file mode 100644
index 0000000..8f885d5
--- /dev/null
+++ b/docs/components/ui/hover-border-gradient.tsx
@@ -0,0 +1,118 @@
+'use client'
+import React, {useState, useEffect} from 'react'
+import {motion} from 'framer-motion'
+import {useTheme} from 'nextra-theme-docs'
+
+import {cn} from '@/lib/utils'
+
+type Direction = 'TOP' | 'LEFT' | 'BOTTOM' | 'RIGHT'
+
+export function HoverBorderGradient({
+ children,
+ containerClassName,
+ className,
+ as: Tag = 'button',
+ duration = 1,
+ clockwise = true,
+ ...props
+}: React.PropsWithChildren<
+ {
+ as?: React.ElementType
+ containerClassName?: string
+ className?: string
+ duration?: number
+ clockwise?: boolean
+ } & React.HTMLAttributes
+>) {
+ const [hovered, setHovered] = useState(false)
+ const [direction, setDirection] = useState('TOP')
+
+ const {resolvedTheme} = useTheme()
+
+ // Usually, we wouldnt need this, but the useTheme hook from nextra-theme-docs seem to have (a) bug(s)
+ const theme =
+ resolvedTheme && resolvedTheme === 'system'
+ ? 'dark'
+ : resolvedTheme ?? 'dark'
+
+ const rotateDirection = (currentDirection: Direction): Direction => {
+ const directions: Direction[] = ['TOP', 'LEFT', 'BOTTOM', 'RIGHT']
+ const currentIndex = directions.indexOf(currentDirection)
+ const nextIndex = clockwise
+ ? (currentIndex - 1 + directions.length) % directions.length
+ : (currentIndex + 1) % directions.length
+ return directions[nextIndex]
+ }
+
+ const movingMap: Record<'dark' | 'light', Record> = {
+ dark: {
+ TOP: 'radial-gradient(20.7% 50% at 50% 0%, #3275F8 0%, rgba(255, 255, 255, 0) 100%)',
+ LEFT: 'radial-gradient(16.6% 43.1% at 0% 50%, #3275F8 0%, rgba(255, 255, 255, 0) 100%)',
+ BOTTOM:
+ 'radial-gradient(20.7% 50% at 50% 100%, #3275F8 0%, rgba(255, 255, 255, 0) 100%)',
+ RIGHT:
+ 'radial-gradient(16.2% 41.199999999999996% at 100% 50%, #3275F8 0%, rgba(255, 255, 255, 0) 100%)'
+ },
+ light: {
+ TOP: 'radial-gradient(20.7% 50% at 50% 0%, #3275F8 0%, rgba(255, 255, 255, 1) 100%)',
+ LEFT: 'radial-gradient(16.6% 43.1% at 0% 50%, #3275F8 0%, rgba(255, 255, 255, 1) 100%)',
+ BOTTOM:
+ 'radial-gradient(20.7% 50% at 50% 100%, #3275F8 0%, rgba(255, 255, 255, 1) 100%)',
+ RIGHT:
+ 'radial-gradient(16.2% 41.199999999999996% at 100% 50%, #3275F8 0%, rgba(255, 255, 255, 1) 100%)'
+ }
+ }
+
+ const highlight =
+ theme === 'dark'
+ ? 'radial-gradient(75% 181.15942028985506% at 50% 50%, #3275F8 0%, rgba(255, 255, 255, 0) 100%)'
+ : 'radial-gradient(75% 181.15942028985506% at 50% 50%, #3275F8 0%, rgba(255, 255, 255, 1) 100%)'
+
+ useEffect(() => {
+ if (!hovered) {
+ const interval = setInterval(() => {
+ setDirection(prevState => rotateDirection(prevState))
+ }, duration * 1000)
+ return () => clearInterval(interval)
+ }
+ }, [hovered])
+ return (
+ ) => {
+ setHovered(true)
+ }}
+ onMouseLeave={() => setHovered(false)}
+ className={cn(
+ 'relative flex rounded-full border content-center bg-border dark:hover:bg-white/10 transition duration-500 dark:bg-white/20 items-center flex-col flex-nowrap gap-10 h-min justify-center overflow-visible p-px decoration-clone w-fit',
+ containerClassName
+ )}
+ {...props}>
+
+ {children}
+
+
+
+
+ )
+}
diff --git a/docs/next.config.js b/docs/next.config.js
index bdb7cb3..b172428 100644
--- a/docs/next.config.js
+++ b/docs/next.config.js
@@ -1,9 +1,17 @@
const withNextra = require('nextra')({
theme: 'nextra-theme-docs',
- themeConfig: './theme.config.tsx'
+ themeConfig: './theme.config.tsx',
+ cleanDistDir: true
})
module.exports = withNextra({
+ images: {
+ domains: [
+ 'raw.githubusercontent.com',
+ 'avatars.githubusercontent.com',
+ 'upload.wikimedia.org'
+ ]
+ },
async redirects() {
return [
{
diff --git a/docs/package.json b/docs/package.json
index c61d538..b86eda0 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -25,6 +25,8 @@
"@vercel/analytics": "^1.3.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
+ "framer-motion": "^11.11.11",
+ "lottie-react": "^2.4.0",
"lucide-react": "^0.440.0",
"next": "^13.0.6",
"nextra": "latest",
diff --git a/docs/pages/_meta.json b/docs/pages/_meta.json
index 1013037..d73da76 100644
--- a/docs/pages/_meta.json
+++ b/docs/pages/_meta.json
@@ -5,7 +5,7 @@
"display": "hidden",
"theme": {
"timestamp": false,
- "layout": "full"
+ "layout": "raw"
}
},
"docs": {
diff --git a/docs/theme.config.tsx b/docs/theme.config.tsx
index 0e0587e..e075139 100644
--- a/docs/theme.config.tsx
+++ b/docs/theme.config.tsx
@@ -23,13 +23,23 @@ const config: DocsThemeConfig = {
docsRepositoryBase: 'https://github.com/getcronit/pylon/tree/main/docs',
footer: {
text: (
-
- {new Date().getFullYear()} ©{' '}
-
- cronit
-
- . Imprint
-
+
)
},
nextThemes: {