mirror of
https://github.com/supabase/supabase.git
synced 2026-07-03 22:24:28 -04:00
56de26fe22
This PR migrates the whole monorepo to use Tailwind v4: - Removed `@tailwindcss/container-queries` plugin since it's included by default in v4, - Bump all instances of Tailwind to v4. Made minimal changes to the shared config to remove non-supported features (`alpha` mentions), - Migrate all apps to be compatible with v4 configs, - Fix the `typography.css` import in 3 apps, - Add missing rules which were included by default in v3, - Run `pnpm dlx @tailwindcss/upgrade` on all apps, which renames a lot of classes - Rename all misnamed classes according to https://tailwindcss.com/docs/upgrade-guide#renamed-utilities in all apps. --------- Co-authored-by: Jordi Enric <jordi.err@gmail.com>
206 lines
6.1 KiB
TypeScript
206 lines
6.1 KiB
TypeScript
'use client'
|
|
|
|
import { AnimatedCounter } from '../AnimatedCounter'
|
|
import { AnimatedGridBackground } from '../AnimatedGridBackground'
|
|
|
|
type HeroStat = {
|
|
headline: string
|
|
number: number
|
|
increment: number
|
|
intervalMs: number
|
|
}
|
|
|
|
const heroStats: HeroStat[] = [
|
|
{
|
|
headline: 'More databases created in 2025 than in all previous years combined',
|
|
number: 15_106_212,
|
|
increment: 1,
|
|
intervalMs: 1000,
|
|
},
|
|
{
|
|
headline: 'Projects created',
|
|
number: 11_808_815,
|
|
increment: 1,
|
|
intervalMs: 500,
|
|
},
|
|
{
|
|
headline: 'Realtime messages delivered',
|
|
number: 280_355_288_012,
|
|
increment: 1931,
|
|
intervalMs: 200,
|
|
},
|
|
]
|
|
|
|
type GridStat = {
|
|
headline: string
|
|
number: number
|
|
increment: number
|
|
suffix?: string
|
|
prefix?: string
|
|
}
|
|
|
|
const gridStats: GridStat[] = [
|
|
{
|
|
headline: 'Peak concurrent Realtime connections',
|
|
number: 193_942,
|
|
increment: 0,
|
|
},
|
|
{
|
|
headline: 'Edge Functions invoked',
|
|
number: 49_632_206_530,
|
|
increment: 1_709,
|
|
},
|
|
{
|
|
headline: 'Images transformed via Storage',
|
|
number: 64_454_990,
|
|
increment: 2,
|
|
},
|
|
{
|
|
headline: 'Petabytes stored',
|
|
number: 64.5,
|
|
increment: 0,
|
|
suffix: 'PB',
|
|
},
|
|
{
|
|
headline: 'Petabytes served',
|
|
number: 19.3,
|
|
increment: 0,
|
|
suffix: 'PB',
|
|
},
|
|
{
|
|
headline: 'One of the top 100 repos on Github',
|
|
number: 94_500,
|
|
increment: 0,
|
|
suffix: 'stars',
|
|
},
|
|
{
|
|
headline: 'paid to fund open source',
|
|
number: 662_357.71,
|
|
increment: 0,
|
|
prefix: '$',
|
|
suffix: 'USD',
|
|
},
|
|
{
|
|
headline: 'Commits to our repos by community members',
|
|
number: 1_421,
|
|
increment: 0,
|
|
},
|
|
]
|
|
|
|
export const Devs = () => {
|
|
return (
|
|
<>
|
|
<section className="relative max-w-240 h-[240px] md:h-[360px] mx-auto border-x border-b w-[95%] md:w-full">
|
|
{/* Grid background */}
|
|
<AnimatedGridBackground
|
|
cols={5}
|
|
rows={{ mobile: 2, desktop: 3 }}
|
|
tiles={[
|
|
{ cell: 0, type: 'dots' },
|
|
{ cell: 2, type: 'stripes' },
|
|
{ cell: 3, type: 'stripes' },
|
|
{ cell: 4, type: 'stripes' },
|
|
{ cell: 5, type: 'stripes' },
|
|
{ cell: 7, type: 'dots' },
|
|
]}
|
|
initialDelay={0.35}
|
|
/>
|
|
|
|
{/* Content */}
|
|
<div className="flex flex-col justify-end h-full px-4 py-0 relative">
|
|
<div className="flex justify-between items-center">
|
|
<h2 className="font-medium tracking-tighter text-6xl md:text-7xl lg:text-[5.6rem] translate-y-2 lg:translate-y-[10px]">
|
|
Devs <span className="text-brand">love</span> Supabase
|
|
</h2>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<div className="relative max-w-240 mx-auto border-x border-b px-4 lg:px-8 py-12 w-[95%] md:w-full">
|
|
<p className="text-lg text-foreground-light max-w-2xl">
|
|
In 2025, developers around the world shipped faster, scaled further, and built things we
|
|
never imagined. Here is what you accomplished on Supabase.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Hero stats */}
|
|
{heroStats.map((stat) => (
|
|
<div
|
|
key={stat.headline}
|
|
className="relative max-w-240 mx-auto border-x border-b p-8 bg-surface-75 w-[95%] md:w-full"
|
|
>
|
|
<div className="flex flex-col gap-2">
|
|
<p className="text-4xl md:text-5xl font-mono font-medium text-brand tracking-tighter">
|
|
<AnimatedCounter
|
|
value={stat.number}
|
|
increment={stat.increment}
|
|
intervalMs={stat.intervalMs}
|
|
/>
|
|
</p>
|
|
<p className="text-base text-foreground-light">{stat.headline}</p>
|
|
</div>
|
|
</div>
|
|
))}
|
|
|
|
{/* Stats grid */}
|
|
<div className="relative max-w-240 mx-auto border-x w-[95%] md:w-full">
|
|
<div className="grid grid-cols-2 lg:grid-cols-4">
|
|
{(() => {
|
|
const cols = 4
|
|
const remainder = gridStats.length % cols
|
|
const emptyCells = remainder === 0 ? 0 : cols - remainder
|
|
|
|
return (
|
|
<>
|
|
{gridStats.map((stat) => (
|
|
<div
|
|
key={stat.headline}
|
|
className="p-8 border-r border-b border-muted nth-[2n]:border-r-0 lg:nth-[2n]:border-r nth-[4n]:border-r-0"
|
|
>
|
|
<div className="flex flex-col gap-2">
|
|
<div className="flex flex-col">
|
|
<p
|
|
className={`text-2xl md:text-3xl font-mono font-medium tracking-tighter ${stat.increment > 0 ? 'text-brand' : 'text-foreground'}`}
|
|
>
|
|
{stat.suffix ? (
|
|
<>
|
|
{stat.prefix}
|
|
{new Intl.NumberFormat('en-US', {
|
|
notation: 'compact',
|
|
maximumFractionDigits: stat.number % 1 !== 0 ? 2 : 0,
|
|
minimumFractionDigits: stat.number % 1 !== 0 ? 1 : 0,
|
|
})
|
|
.format(stat.number)
|
|
.toLowerCase()}
|
|
<span className="text-lg ml-1.5 font-medium tracking-tight">
|
|
{stat.suffix}
|
|
</span>
|
|
</>
|
|
) : (
|
|
<AnimatedCounter
|
|
value={stat.number}
|
|
increment={stat.increment}
|
|
compact
|
|
/>
|
|
)}
|
|
</p>
|
|
</div>
|
|
<p className="text-sm text-foreground-lighter">{stat.headline}</p>
|
|
</div>
|
|
</div>
|
|
))}
|
|
{Array.from({ length: emptyCells }).map((_, i) => (
|
|
<div
|
|
key={`empty-${i}`}
|
|
className="px-6 py-8 border-r border-b border-muted last:border-r-0"
|
|
/>
|
|
))}
|
|
</>
|
|
)
|
|
})()}
|
|
</div>
|
|
</div>
|
|
</>
|
|
)
|
|
}
|