forked from sashaastiadi/www_mycelium_net
Compare commits
7 Commits
f6841df98f
...
4eb8a8aba7
| Author | SHA1 | Date | |
|---|---|---|---|
| 4eb8a8aba7 | |||
| 90499e2b77 | |||
| 812eb5f455 | |||
| 471f53162f | |||
| e7b053bd76 | |||
| d197ca74ad | |||
| 0ca6a563b1 |
@@ -6,7 +6,7 @@ import { PrimaryFeatures } from '@/components/PrimaryFeatures'
|
||||
import { UseCases } from '@/components/UseCases'
|
||||
import { SecondaryFeatures } from '@/components/SecondaryFeatures'
|
||||
import { Benefits } from '@/components/Benefits'
|
||||
import { About } from '@/components/About'
|
||||
import { AboutNew } from '@/components/AboutNew'
|
||||
import { Features } from '@/components/Features'
|
||||
|
||||
export default function Home() {
|
||||
@@ -16,7 +16,7 @@ export default function Home() {
|
||||
<Hero />
|
||||
</AnimatedSection>
|
||||
<AnimatedSection>
|
||||
<About />
|
||||
<AboutNew />
|
||||
</AnimatedSection>
|
||||
<AnimatedSection>
|
||||
<Features />
|
||||
|
||||
@@ -8,39 +8,41 @@ export function About() {
|
||||
return (
|
||||
<section
|
||||
id="about"
|
||||
className="relative overflow-hidden bg-gray-900 py-20 lg:py-32 lg:top-0 top-0"
|
||||
className="relative bg-gray-900 py-20 lg:py-32"
|
||||
>
|
||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
|
||||
<CircleBackground color="#06b6d4" className="animate-spin-slower" />
|
||||
<div className="relative -mt-[100vh]">
|
||||
<Container>
|
||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
|
||||
<CircleBackground id="aboutcircle" color="#06b6d4" className="animate-spin-slower" />
|
||||
</div>
|
||||
<Container>
|
||||
<div className="mx-auto max-w-3xl text-center">
|
||||
<Eyebrow color="accent">Our Mission</Eyebrow>
|
||||
<SectionHeader color="white" className="mt-2">
|
||||
Discover Mycelium
|
||||
</SectionHeader>
|
||||
<P color="light" className="mt-6">
|
||||
Mycelium is an unbreakable network, always finding the shortest path and
|
||||
providing 100% secure, peer-to-peer communication. But this is just
|
||||
the beginning.
|
||||
</P>
|
||||
<P color="light" className="mt-6">
|
||||
Our mission is to create a sustainable digital ecosystem where
|
||||
communication is seamless, data is secure, and scalability knows no
|
||||
bounds.
|
||||
</P>
|
||||
<div className="mt-8 flex justify-center">
|
||||
<Button
|
||||
href="https://threefold.info/mycelium_network/docs/"
|
||||
target="_blank"
|
||||
variant="outline"
|
||||
color="white"
|
||||
>
|
||||
Learn More
|
||||
</Button>
|
||||
<div className="mx-auto max-w-3xl text-center">
|
||||
<Eyebrow color="accent">Our Mission</Eyebrow>
|
||||
<SectionHeader color="white" className="mt-2">
|
||||
Discover Mycelium
|
||||
</SectionHeader>
|
||||
<P color="light" className="mt-6">
|
||||
Mycelium is an unbreakable network, always finding the shortest path and
|
||||
providing 100% secure, peer-to-peer communication. But this is just
|
||||
the beginning.
|
||||
</P>
|
||||
<P color="light" className="mt-6">
|
||||
Our mission is to create a sustainable digital ecosystem where
|
||||
communication is seamless, data is secure, and scalability knows no
|
||||
bounds.
|
||||
</P>
|
||||
<div className="mt-8 flex justify-center">
|
||||
<Button
|
||||
href="https://threefold.info/mycelium_network/docs/"
|
||||
target="_blank"
|
||||
variant="outline"
|
||||
color="white"
|
||||
>
|
||||
Learn More
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
</Container>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
37
src/components/AboutNew.tsx
Normal file
37
src/components/AboutNew.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { AppStoreLink } from '@/components/AppStoreLink'
|
||||
import { P, SectionHeader } from '@/components/Texts'
|
||||
import { WindowsLink } from '@/components/WindowsLink'
|
||||
import { AndroidLink } from './AndroidLink'
|
||||
import { LinuxLink } from '@/components/LinuxLink'
|
||||
import { CircleBackground } from '@/components/CircleBackground'
|
||||
import { Container } from '@/components/Container'
|
||||
|
||||
export function AboutNew() {
|
||||
return (
|
||||
<section
|
||||
id="get-free-shares-today"
|
||||
className="relative overflow-hidden bg-gray-900 py-20 sm:py-28"
|
||||
>
|
||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
|
||||
<CircleBackground id="aboutcircle" color="#06b6d4" className="animate-spin-slower" />
|
||||
</div>
|
||||
<Container>
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<SectionHeader as="h2" color="white">
|
||||
Discover Mycelium
|
||||
</SectionHeader>
|
||||
<P color="light" className="mt-6">
|
||||
Mycelium is an unbreakable network, always finding the shortest path and
|
||||
providing 100% secure, peer-to-peer communication. But this is just
|
||||
the beginning.
|
||||
</P>
|
||||
<P color="light" className="mt-6">
|
||||
Our mission is to create a sustainable digital ecosystem where
|
||||
communication is seamless, data is secure, and scalability knows no
|
||||
bounds.
|
||||
</P>
|
||||
</div>
|
||||
</Container>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -13,7 +13,7 @@ export function CallToAction() {
|
||||
className="relative overflow-hidden bg-gray-900 py-20 sm:py-28"
|
||||
>
|
||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
|
||||
<CircleBackground color="#06b6d4" className="animate-spin-slower" />
|
||||
<CircleBackground id="cta_circle" color="#06b6d4" className="animate-spin-slower" />
|
||||
</div>
|
||||
<Container>
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import * as React from 'react';
|
||||
import { motion, useReducedMotion } from 'framer-motion';
|
||||
import clsx from 'clsx';
|
||||
|
||||
type Props = {
|
||||
className?: string; // e.g. "w-full h-80"
|
||||
@@ -135,7 +136,12 @@ export default function ContentDistribution({ className, bg = '#ffffff' }: Props
|
||||
const prefersReduced = useReducedMotion();
|
||||
|
||||
return (
|
||||
<div className={className} aria-hidden="true" role="img" style={{ background: bg }}>
|
||||
<div
|
||||
className={clsx('relative overflow-hidden', className)}
|
||||
aria-hidden="true"
|
||||
role="img"
|
||||
style={{ background: bg }}
|
||||
>
|
||||
<svg viewBox={`0 0 ${W} ${H}`} width="100%" height="100%">
|
||||
{/* subtle radial background + rings */}
|
||||
<defs>
|
||||
|
||||
@@ -5,114 +5,92 @@ import ProxyDetection from '@/components/ProxyDetection'
|
||||
import ProxyForwarding from '@/components/ProxyForwarding'
|
||||
import ContentDistribution from '@/components/ContentDistribution'
|
||||
|
||||
const eyebrow = 'Core Components'
|
||||
const sectionHeader = 'Network Capabilities'
|
||||
const description1 = 'Built for resilience and autonomy, the Mycelium Network dynamically connects nodes through intelligent routing, proxy discovery, and decentralized delivery.'
|
||||
const description2 = 'Each component — from message passing to content distribution — works in harmony to create a fully self-healing, self-optimizing data mesh.'
|
||||
|
||||
const cards = [
|
||||
{
|
||||
eyebrow: 'Routing',
|
||||
title: 'Automatic pathfinding',
|
||||
description: 'The Mycelium Network automatically discovers the shortest and fastest routes between nodes, ensuring optimal data flow and network efficiency without manual configuration.',
|
||||
component: <Pathfinding />,
|
||||
className: 'lg:col-span-3',
|
||||
roundedClassName: 'max-lg:rounded-t-4xl lg:rounded-tl-4xl',
|
||||
roundedInnerClassName: 'max-lg:rounded-t-[calc(2rem+1px)] lg:rounded-tl-[calc(2rem+1px)]'
|
||||
},
|
||||
{
|
||||
eyebrow: 'Communication',
|
||||
title: 'Distributed message bus',
|
||||
description: 'Acts as a global message layer that lets nodes exchange information seamlessly. Enables resilient, asynchronous communication across the entire decentralized mesh.',
|
||||
component: <MessageBus />,
|
||||
className: 'lg:col-span-3',
|
||||
roundedClassName: 'lg:rounded-tr-4xl',
|
||||
roundedInnerClassName: 'lg:rounded-tr-[calc(2rem+1px)]'
|
||||
},
|
||||
{
|
||||
eyebrow: 'Discovery',
|
||||
title: 'Automatic proxy detection',
|
||||
description: 'The system continuously scans for open SOCKS5 proxies within the network, making it effortless to find available connection points without manual setup.',
|
||||
component: <ProxyDetection className="h-80" />,
|
||||
className: 'lg:col-span-2',
|
||||
roundedClassName: 'lg:rounded-bl-4xl',
|
||||
roundedInnerClassName: 'lg:rounded-bl-[calc(2rem+1px)]'
|
||||
},
|
||||
{
|
||||
eyebrow: 'Connectivity',
|
||||
title: 'Seamless proxy forwarding',
|
||||
description: 'Local SOCKS5 connections can be forwarded through nearby nodes or remote proxies. When browsers use the local proxy, traffic moves securely through the mesh—like a built-in VPN.',
|
||||
component: <ProxyForwarding className="h-80" />,
|
||||
className: 'lg:col-span-2',
|
||||
roundedClassName: '',
|
||||
roundedInnerClassName: ''
|
||||
},
|
||||
{
|
||||
eyebrow: 'Delivery',
|
||||
title: 'Decentralized content distribution',
|
||||
description: 'Mycelium can serve data from distributed 0-DBs, creating a CDN-like layer that delivers content faster and more reliably—without relying on centralized servers.',
|
||||
component: <ContentDistribution className="h-80" />,
|
||||
className: 'lg:col-span-2',
|
||||
roundedClassName: 'max-lg:rounded-b-4xl lg:rounded-br-4xl',
|
||||
roundedInnerClassName: 'max-lg:rounded-b-[calc(2rem+1px)] lg:rounded-br-[calc(2rem+1px)]'
|
||||
}
|
||||
]
|
||||
|
||||
export function Features() {
|
||||
return (
|
||||
<section id="features" className=" py-24">
|
||||
<section id="features" className="py-24">
|
||||
<div className="mx-auto max-w-2xl px-6 lg:max-w-7xl lg:px-8">
|
||||
<Eyebrow color="accent">Core Components</Eyebrow>
|
||||
<Eyebrow color="accent">{eyebrow}</Eyebrow>
|
||||
<SectionHeader color="dark" className="mt-2 max-w-2xl text-pretty">
|
||||
Network Capabilities
|
||||
{sectionHeader}
|
||||
</SectionHeader>
|
||||
<P color="secondary" className="mt-4 max-w-4xl">
|
||||
Built for resilience and autonomy, the Mycelium Network dynamically
|
||||
connects nodes through intelligent routing, proxy discovery, and
|
||||
decentralized delivery.
|
||||
<P color="secondary" className="mt-4 max-w-4xl text-black">
|
||||
{description1}
|
||||
</P>
|
||||
<P color="secondary" className="mt-2 max-w-4xl">
|
||||
Each component — from message passing to content distribution — works in
|
||||
harmony to create a fully self-healing, self-optimizing data mesh.
|
||||
</P>
|
||||
{description2}
|
||||
</P>
|
||||
<div className="mt-10 grid grid-cols-1 gap-x-4 gap-y-8 sm:mt-16 lg:grid-cols-6 lg:grid-rows-2">
|
||||
<div className="group relative lg:col-span-3 transition-all duration-300 ease-in-out hover:scale-105">
|
||||
<div className="absolute inset-0 rounded-lg bg-white max-lg:rounded-t-4xl lg:rounded-tl-4xl" />
|
||||
<div className="flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] max-lg:rounded-t-[calc(2rem+1px)] lg:rounded-tl-[calc(2rem+1px)]">
|
||||
<Pathfinding />
|
||||
<div className="p-10 pt-4">
|
||||
<CardEyebrow color="accent">Routing</CardEyebrow>
|
||||
<CardTitle color="dark" className="mt-2">
|
||||
Automatic pathfinding
|
||||
</CardTitle>
|
||||
<CardDescription color="secondary" className="mt-2 max-w-lg">
|
||||
The Mycelium Network automatically discovers the shortest and
|
||||
fastest routes between nodes, ensuring optimal data flow and
|
||||
network efficiency without manual configuration.
|
||||
</CardDescription>
|
||||
{cards.map((card, index) => (
|
||||
<div key={index} className={`group relative ${card.className} transition-all duration-300 ease-in-out hover:scale-105`}>
|
||||
<div className={`absolute inset-0 rounded-lg bg-transparent ${card.roundedClassName}`} />
|
||||
<div className={`flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] ${card.roundedInnerClassName}`}>
|
||||
{card.component}
|
||||
<div className="p-10 pt-4">
|
||||
<CardEyebrow color="accent">{card.eyebrow}</CardEyebrow>
|
||||
<CardTitle color="dark" className="mt-2">
|
||||
{card.title}
|
||||
</CardTitle>
|
||||
<CardDescription color="secondary" className="mt-2 max-w-lg">
|
||||
{card.description}
|
||||
</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`pointer-events-none absolute inset-0 rounded-lg shadow-sm outline outline-black/5 group-hover:outline-cyan-500 group-hover:shadow-lg group-hover:shadow-cyan-500/20 ${card.roundedClassName}`} />
|
||||
</div>
|
||||
<div className="pointer-events-none absolute inset-0 rounded-lg shadow-sm outline outline-black/5 max-lg:rounded-t-4xl lg:rounded-tl-4xl group-hover:outline-cyan-500 group-hover:shadow-lg group-hover:shadow-cyan-500/20" />
|
||||
</div>
|
||||
<div className="group relative lg:col-span-3 transition-all duration-300 ease-in-out hover:scale-105">
|
||||
<div className="absolute inset-0 rounded-lg bg-white lg:rounded-tr-4xl" />
|
||||
<div className="flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] lg:rounded-tr-[calc(2rem+1px)]">
|
||||
<MessageBus />
|
||||
<div className="p-10 pt-4">
|
||||
<CardEyebrow color="accent">Communication</CardEyebrow>
|
||||
<CardTitle color="dark" className="mt-2">
|
||||
Distributed message bus
|
||||
</CardTitle>
|
||||
<CardDescription color="secondary" className="mt-2 max-w-lg">
|
||||
Acts as a global message layer that lets nodes exchange
|
||||
information seamlessly. Enables resilient, asynchronous
|
||||
communication across the entire decentralized mesh.
|
||||
</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pointer-events-none absolute inset-0 rounded-lg shadow-sm outline outline-black/5 lg:rounded-tr-4xl group-hover:outline-cyan-500 group-hover:shadow-lg group-hover:shadow-cyan-500/20" />
|
||||
</div>
|
||||
<div className="group relative lg:col-span-2 transition-all duration-300 ease-in-out hover:scale-105">
|
||||
<div className="absolute inset-0 rounded-lg bg-white lg:rounded-bl-4xl" />
|
||||
<div className="flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] lg:rounded-bl-[calc(2rem+1px)]">
|
||||
<ProxyDetection className="h-80" />
|
||||
<div className="p-10 pt-4">
|
||||
<CardEyebrow color="accent">Discovery</CardEyebrow>
|
||||
<CardTitle color="dark" className="mt-2">
|
||||
Automatic proxy detection
|
||||
</CardTitle>
|
||||
<CardDescription color="secondary" className="mt-2 max-w-lg">
|
||||
The system continuously scans for open SOCKS5 proxies within the
|
||||
network, making it effortless to find available connection points
|
||||
without manual setup.
|
||||
</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pointer-events-none absolute inset-0 rounded-lg shadow-sm outline outline-black/5 lg:rounded-bl-4xl group-hover:outline-cyan-500 group-hover:shadow-lg group-hover:shadow-cyan-500/20" />
|
||||
</div>
|
||||
<div className="group relative lg:col-span-2 transition-all duration-300 ease-in-out hover:scale-105">
|
||||
<div className="absolute inset-0 rounded-lg bg-white" />
|
||||
<div className="flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)]">
|
||||
<ProxyForwarding className="h-80" />
|
||||
<div className="p-10 pt-4">
|
||||
<CardEyebrow color="accent">Connectivity</CardEyebrow>
|
||||
<CardTitle color="dark" className="mt-2">
|
||||
Seamless proxy forwarding
|
||||
</CardTitle>
|
||||
<CardDescription color="secondary" className="mt-2 max-w-lg">
|
||||
Local SOCKS5 connections can be forwarded through nearby nodes or
|
||||
remote proxies. When browsers use the local proxy, traffic moves
|
||||
securely through the mesh—like a built-in VPN.
|
||||
</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pointer-events-none absolute inset-0 rounded-lg shadow-sm outline outline-black/5 group-hover:outline-cyan-500 group-hover:shadow-lg group-hover:shadow-cyan-500/20" />
|
||||
</div>
|
||||
<div className="group relative lg:col-span-2 transition-all duration-300 ease-in-out hover:scale-105">
|
||||
<div className="absolute inset-0 rounded-lg bg-white max-lg:rounded-b-4xl lg:rounded-br-4xl" />
|
||||
<div className="flex h-full flex-col overflow-hidden rounded-[calc(var(--radius-lg)+1px)] max-lg:rounded-b-[calc(2rem+1px)] lg:rounded-br-[calc(2rem+1px)]">
|
||||
<ContentDistribution className="h-80" />
|
||||
<div className="p-10 pt-4">
|
||||
<CardEyebrow color="accent">Delivery</CardEyebrow>
|
||||
<CardTitle color="dark" className="mt-2">
|
||||
Decentralized content distribution
|
||||
</CardTitle>
|
||||
<CardDescription color="secondary" className="mt-2 max-w-lg">
|
||||
Mycelium can serve data from distributed 0-DBs, creating a
|
||||
CDN-like layer that delivers content faster and more
|
||||
reliably—without relying on centralized servers.
|
||||
</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pointer-events-none absolute inset-0 rounded-lg shadow-sm outline outline-black/5 max-lg:rounded-b-4xl lg:rounded-br-4xl group-hover:outline-cyan-500 group-hover:shadow-lg group-hover:shadow-cyan-500/20" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import * as React from 'react';
|
||||
import { motion, useReducedMotion } from 'framer-motion';
|
||||
import clsx from 'clsx';
|
||||
|
||||
type Props = {
|
||||
className?: string; // e.g. "w-full h-72"
|
||||
@@ -72,7 +73,12 @@ export default function MessageBus({ className, bg = '#ffffff' }: Props) {
|
||||
const H = 460;
|
||||
|
||||
return (
|
||||
<div className={className} aria-hidden="true" role="img" style={{ background: bg }}>
|
||||
<div
|
||||
className={clsx('relative overflow-hidden', className)}
|
||||
aria-hidden="true"
|
||||
role="img"
|
||||
style={{ background: bg }}
|
||||
>
|
||||
<svg viewBox={`0 0 ${W} ${H}`} width="100%" height="100%">
|
||||
|
||||
{/* subtle grid */}
|
||||
|
||||
@@ -292,9 +292,9 @@ function FeaturesDesktop() {
|
||||
</div>
|
||||
))}
|
||||
</TabList>
|
||||
<div className="col-span-6">
|
||||
<div className="relative col-span-6">
|
||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
|
||||
<CircleBackground color="#13B5C8" className="animate-spin-slower" />
|
||||
<CircleBackground id="primaryfeatures_desktop_circle" color="#13B5C8" className="animate-spin-slower" />
|
||||
</div>
|
||||
<PhoneFrame className="z-10 mx-auto w-full max-w-[366px]">
|
||||
<TabPanels as={Fragment}>
|
||||
@@ -368,16 +368,17 @@ function FeaturesMobile() {
|
||||
ref={(ref) => ref && (slideRefs.current[featureIndex] = ref)}
|
||||
className="w-full flex-none snap-center px-4 sm:px-6 transition-all duration-300 ease-in-out hover:scale-105"
|
||||
>
|
||||
<div
|
||||
<div
|
||||
className={clsx(
|
||||
'transform overflow-hidden rounded-2xl bg-gray-800 px-5 py-6 outline-2 transition-colors',
|
||||
'relative transform overflow-hidden rounded-2xl bg-gray-800 px-5 py-6 outline-2 transition-colors',
|
||||
activeIndex === featureIndex
|
||||
? 'outline-transparent' // Remove outline for active mobile slide
|
||||
: 'outline-transparent hover:outline-cyan-500',
|
||||
)}
|
||||
>
|
||||
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
|
||||
<CircleBackground
|
||||
<CircleBackground
|
||||
id={`primaryfeatures_mobile_circle_${featureIndex}`}
|
||||
color="#13B5C8"
|
||||
className={featureIndex % 2 === 1 ? 'rotate-180' : undefined}
|
||||
/>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import * as React from 'react';
|
||||
import { motion, useReducedMotion } from 'framer-motion';
|
||||
import clsx from 'clsx';
|
||||
|
||||
type Props = {
|
||||
className?: string; // e.g. "w-full h-64"
|
||||
@@ -160,8 +161,8 @@ export default function ProxyDetection({ className, bg = '#ffffff' }: Props) {
|
||||
const delays = [0.8, 0.6, 0.4, 0.2, 0.0];
|
||||
|
||||
return (
|
||||
<div
|
||||
className={className}
|
||||
<div
|
||||
className={clsx('relative overflow-hidden', className)}
|
||||
aria-hidden="true"
|
||||
role="img"
|
||||
style={{ background: bg }}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import * as React from 'react';
|
||||
import { motion, useReducedMotion } from 'framer-motion';
|
||||
import clsx from 'clsx';
|
||||
|
||||
type Props = {
|
||||
className?: string; // e.g. "w-full h-72"
|
||||
@@ -124,7 +125,12 @@ export default function ProxyForwarding({ className, bg = '#ffffff' }: Props) {
|
||||
const DEST = { x: 860, y: 210 };
|
||||
|
||||
return (
|
||||
<div className={className} aria-hidden="true" role="img" style={{ background: bg }}>
|
||||
<div
|
||||
className={clsx('relative overflow-hidden', className)}
|
||||
aria-hidden="true"
|
||||
role="img"
|
||||
style={{ background: bg }}
|
||||
>
|
||||
<svg viewBox={`0 0 ${W} ${H}`} width="100%" height="100%">
|
||||
{/* subtle grid bg */}
|
||||
<defs>
|
||||
|
||||
@@ -44,15 +44,14 @@ const createTextComponent = <DefaultElement extends React.ElementType>(
|
||||
return (
|
||||
<Tag
|
||||
className={cn(defaultClassName, colorVariants[color], className)}
|
||||
{...(props as object)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Tag>
|
||||
)
|
||||
}
|
||||
|
||||
;(Text as any).displayName = `Text(${
|
||||
typeof defaultElement === 'string' ? defaultElement : 'Component'
|
||||
;(Text as any).displayName = `Text(${typeof defaultElement === 'string' ? defaultElement : 'Component'
|
||||
})`
|
||||
return Text
|
||||
}
|
||||
@@ -60,47 +59,89 @@ const createTextComponent = <DefaultElement extends React.ElementType>(
|
||||
// Exports based on your tailwind.css and the example
|
||||
export const H1 = createTextComponent(
|
||||
'h1',
|
||||
'text-5xl lg:text-8xl font-medium tracking-tight'
|
||||
'text-5xl lg:text-8xl font-medium leading-tight tracking-tight'
|
||||
)
|
||||
export const H2 = createTextComponent(
|
||||
'h2',
|
||||
'text-4xl lg:text-6xl font-medium leading-tight tracking-tight'
|
||||
)
|
||||
export const H3 = createTextComponent(
|
||||
'h3',
|
||||
'text-3xl lg:text-5xl font-medium leading-tight tracking-tight'
|
||||
)
|
||||
export const H4 = createTextComponent(
|
||||
'h4',
|
||||
'text-2xl lg:text-4xl font-medium leading-snug tracking-tight'
|
||||
)
|
||||
export const H2 = createTextComponent('h2', 'text-4xl lg:text-6xl font-medium')
|
||||
export const H3 = createTextComponent('h3', 'text-3xl lg:text-5xl font-medium')
|
||||
export const H4 = createTextComponent('h4', 'text-2xl lg:text-4xl font-medium')
|
||||
export const P = createTextComponent(
|
||||
'p',
|
||||
'text-base lg:text-lg leading-relaxed'
|
||||
)
|
||||
export const Small = createTextComponent('small', 'text-sm font-medium')
|
||||
export const Subtle = createTextComponent('p', 'text-sm text-gray-500')
|
||||
export const H5 = createTextComponent('h5', 'text-xl lg:text-2xl font-semibold')
|
||||
export const Eyebrow = createTextComponent('h2', 'text-base/7 font-semibold')
|
||||
export const Small = createTextComponent(
|
||||
'small',
|
||||
'text-sm font-medium leading-normal tracking-normal'
|
||||
)
|
||||
export const Subtle = createTextComponent(
|
||||
'p',
|
||||
'text-sm leading-normal tracking-normal text-gray-500'
|
||||
)
|
||||
export const H5 = createTextComponent(
|
||||
'h5',
|
||||
'text-xl lg:text-2xl font-semibold leading-snug tracking-tight'
|
||||
)
|
||||
export const Eyebrow = createTextComponent(
|
||||
'h2',
|
||||
'text-base/7 font-semibold tracking-wide'
|
||||
)
|
||||
export const SectionHeader = createTextComponent(
|
||||
'p',
|
||||
'text-3xl lg:text-4xl font-medium tracking-tight'
|
||||
'text-3xl lg:text-4xl font-medium leading-tight tracking-tight'
|
||||
)
|
||||
export const CardEyebrow = createTextComponent(
|
||||
'h3',
|
||||
'text-sm/4 font-semibold tracking-wide'
|
||||
)
|
||||
export const CardEyebrow = createTextComponent('h3', 'text-sm/4 font-semibold')
|
||||
export const CardTitle = createTextComponent(
|
||||
'p',
|
||||
'text-lg font-medium tracking-tight'
|
||||
'text-lg font-medium leading-snug tracking-tight'
|
||||
)
|
||||
export const CardDescription = createTextComponent(
|
||||
'p',
|
||||
'text-sm/6 leading-normal tracking-normal'
|
||||
)
|
||||
export const FeatureTitle = createTextComponent(
|
||||
'h3',
|
||||
'text-lg font-semibold leading-snug tracking-tight'
|
||||
)
|
||||
export const FeatureDescription = createTextComponent(
|
||||
'p',
|
||||
'text-sm leading-normal tracking-normal'
|
||||
)
|
||||
export const CardDescription = createTextComponent('p', 'text-sm/6')
|
||||
export const FeatureTitle = createTextComponent('h3', 'text-lg font-semibold')
|
||||
export const FeatureDescription = createTextComponent('p', 'text-sm')
|
||||
export const MobileFeatureTitle = createTextComponent(
|
||||
'h3',
|
||||
'text-sm font-semibold sm:text-lg'
|
||||
'text-sm font-semibold sm:text-lg leading-snug tracking-tight'
|
||||
)
|
||||
export const SecondaryFeatureTitle = createTextComponent(
|
||||
'h3',
|
||||
'font-semibold'
|
||||
'text-base font-semibold leading-snug tracking-tight'
|
||||
)
|
||||
export const Question = createTextComponent(
|
||||
'h3',
|
||||
'text-lg/6 font-semibold tracking-tight'
|
||||
)
|
||||
export const Answer = createTextComponent(
|
||||
'p',
|
||||
'mt-4 text-sm leading-normal tracking-normal'
|
||||
)
|
||||
export const Question = createTextComponent('h3', 'text-lg/6 font-semibold')
|
||||
export const Answer = createTextComponent('p', 'mt-4 text-sm')
|
||||
export const PageHeader = createTextComponent(
|
||||
'h2',
|
||||
'text-5xl lg:text-6xl font-medium tracking-tight'
|
||||
'text-5xl lg:text-6xl font-medium leading-tight tracking-tight'
|
||||
)
|
||||
export const DownloadCardTitle = createTextComponent(
|
||||
'dt',
|
||||
'text-base/7 font-semibold'
|
||||
'text-base/7 font-semibold tracking-wide'
|
||||
)
|
||||
export const DownloadCardDescription = createTextComponent(
|
||||
'dd',
|
||||
'text-base/7 leading-normal tracking-normal'
|
||||
)
|
||||
export const DownloadCardDescription = createTextComponent('dd', 'text-base/7')
|
||||
|
||||
Reference in New Issue
Block a user