2 Commits

Author SHA1 Message Date
26ae2f156a feat: add mobile app UI screenshots and enhance text components
- Added new app UI screenshots for cloud features (connector, billing, kubeconfig, reserve)
- Added new hero image (cloudhero3.webp) for cloud section
- Enhanced Texts component with new cyan color variant and default props support
- Updated Eyebrow component to use consistent styling with accent color and tracking
- Simplified CloudArchitecture component by removing redundant style props
- Completely rebuilt CloudFeatures component with
2025-10-31 04:04:44 +01:00
33c940c604 feat: update cloud page hero and home slider components
- Replaced CloudHero with new CloudHeroNew component on cloud page
- Added new cloud-related images (cloudhero.webp, cloudhero2.webp, k82.png) to public assets
- Enhanced HomeSlider section with Eyebrow component for "Ecosystem" label
- Updated HomeSlider heading text from "Discover the Mycelium Ecosystem" to "Discover the Mycelium Components"
2025-10-31 03:36:19 +01:00
21 changed files with 481 additions and 121 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 938 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
public/images/k82.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 KiB

View File

@@ -13,6 +13,7 @@ const colorVariants = {
secondary: 'text-gray-600', secondary: 'text-gray-600',
light: 'text-gray-50', light: 'text-gray-50',
accent: 'text-cyan-500', accent: 'text-cyan-500',
cyan: 'text-cyan-50',
white: 'text-white', white: 'text-white',
dark: 'text-gray-950', dark: 'text-gray-950',
tertiary: 'text-gray-700', tertiary: 'text-gray-700',
@@ -33,7 +34,8 @@ type PolymorphicProps<E extends React.ElementType, P> = P & {
const createTextComponent = <DefaultElement extends React.ElementType>( const createTextComponent = <DefaultElement extends React.ElementType>(
defaultElement: DefaultElement, defaultElement: DefaultElement,
defaultClassName: string defaultClassName: string,
defaultProps: Omit<TextOwnProps, 'className' | 'children'> = {}
) => { ) => {
type Props<E extends React.ElementType = DefaultElement> = PolymorphicProps< type Props<E extends React.ElementType = DefaultElement> = PolymorphicProps<
E, E,
@@ -41,9 +43,9 @@ const createTextComponent = <DefaultElement extends React.ElementType>(
> >
function Text<E extends React.ElementType = DefaultElement>({ function Text<E extends React.ElementType = DefaultElement>({
font = 'sans', font = defaultProps.font || 'sans',
as, as,
color = 'primary', color = defaultProps.color || 'primary',
className, className,
children, children,
...props ...props
@@ -104,7 +106,8 @@ export const H5 = createTextComponent(
) )
export const Eyebrow = createTextComponent( export const Eyebrow = createTextComponent(
'h2', 'h2',
'text-base/7 font-semibold tracking-wider uppercase' 'text-base/7 font-semibold tracking-[0.18em] uppercase',
{ color: 'accent' }
) )
export const SectionHeader = createTextComponent( export const SectionHeader = createTextComponent(
'p', 'p',

View File

@@ -42,7 +42,7 @@ export function CloudArchitecture() {
<section className="bg-white py-24 sm:py-32"> <section className="bg-white py-24 sm:py-32">
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow>
Technical Architecture Technical Architecture
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <SectionHeader as="h2" className="mt-6 text-gray-900">

View File

@@ -1,124 +1,432 @@
import { Container } from '../../components/Container' 'use client'
import { Eyebrow, SectionHeader, P, Small } from '../../components/Texts'
const featureSections = [ import { Fragment, useEffect, useId, useRef, useState } from 'react'
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
import clsx from 'clsx'
import {
type MotionProps,
type Variant,
AnimatePresence,
motion,
} from 'framer-motion'
import { useDebouncedCallback } from 'use-debounce'
import { AppScreen } from '../network/AppScreen'
import {
Eyebrow,
FeatureDescription,
FeatureTitle,
MobileFeatureTitle,
P,
SectionHeader,
} from '@/components/Texts'
import { CircleBackground } from '@/components/CircleBackground'
import { Container } from '@/components/Container'
import connectorImg from '@/images/connector.png'
import peersImg from '@/images/peers.png'
import settingImg from '@/images/setting.png'
import { PhoneFrame } from '@/components/PhoneFrame'
interface CustomAnimationProps {
isForwards: boolean
changeCount: number
}
const features = [
{ {
title: 'Mycelium Networking', name: 'Mycelium Connector',
description: description:
'Ultra-fast, decentralized networking inspired by nature to keep services reachable without exposing surfaces.', "Start (and stop) your Mycelium connector to gain access to sites, apps, and workloads available exclusively on the Mycelium Network. View statistics around peers and traffic.",
bullets: [ icon: DeviceUserIcon,
'End-to-end encrypted mesh connectivity between every node.', screen: InviteScreen,
'Direct node communication without centralized intermediaries.',
'Self-optimizing routes that heal around failures automatically.',
'Secure peer-to-peer communication across the entire grid.',
],
}, },
{ {
title: 'Zero-Image Technology', name: 'Mycelium Peers',
description: description:
'Metadata-first zero-images shrink artifacts up to 100x, reducing deployment time and bandwidth.', 'Search and discover active peers on the Mycelium Network, or add your own.',
bullets: [ icon: DeviceNotificationIcon,
'Deterministic deployments verified cryptographically.', screen: StocksScreen,
'Run containers, VMs, and Linux workloads with secure boot.',
'Smart contract orchestration manages every workload lifecycle.',
'Minimal artifact footprint accelerates delivery everywhere.',
],
}, },
{ {
title: 'Quantum-Safe Storage (QSS)', name: 'Network Setting',
description: description:
'Quantum-resistant encryption secures data beyond the application layer for complete ownership.', 'Find version and network information and trigger light or dark mode.',
bullets: [ icon: DeviceTouchIcon,
'Self-healing storage recovers instantly from corruption or failure.', screen: InvestScreen,
'Serve the same data via IPFS, S3, WebDAV, HTTP, and native FS.',
'Geo-aware placement enforces residency and redundancy policies.',
'Autonomous replication keeps data resilient across the globe.',
],
},
{
title: 'Multi-Master Clusters',
description:
'High-availability Kubernetes with automatic failover and leadership orchestration.',
bullets: [
'Multi-master topologies orchestrated with zero downtime.',
'Automatic failover keeps control planes healthy and responsive.',
'HA operations managed without manual intervention or scripts.',
'Upgrades roll out seamlessly with continuous verification.',
],
},
{
title: 'Effortless Load Balancing & Scaling',
description:
'Adaptive automation balances traffic and scales workloads based on demand.',
bullets: [
'Built-in autoscaling that responds to real-time usage.',
'Native load balancing distributes traffic globally.',
'High availability delivered without custom controllers.',
'Elastic scaling keeps costs aligned with workload demand.',
],
},
{
title: 'Simple Web Gateway Access',
description:
'Expose services to the public web with declarative Kubernetes resources.',
bullets: [
'One resource publishes services without complex ingress rules.',
'Domain and prefix-based routing built into the platform.',
'No need to manage dedicated ingress controllers.',
'Consistent configuration across every cluster and region.',
],
}, },
] ]
function DeviceUserIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
return (
<svg viewBox="0 0 32 32" aria-hidden="true" {...props}>
<circle cx={16} cy={16} r={16} fill="#A3A3A3" fillOpacity={0.2} />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M16 23a3 3 0 100-6 3 3 0 000 6zm-1 2a4 4 0 00-4 4v1a2 2 0 002 2h6a2 2 0 002-2v-1a4 4 0 00-4-4h-2z"
fill="#737373"
/>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M5 4a4 4 0 014-4h14a4 4 0 014 4v24a4.002 4.002 0 01-3.01 3.877c-.535.136-.99-.325-.99-.877s.474-.98.959-1.244A2 2 0 0025 28V4a2 2 0 00-2-2h-1.382a1 1 0 00-.894.553l-.448.894a1 1 0 01-.894.553h-6.764a1 1 0 01-.894-.553l-.448-.894A1 1 0 0010.382 2H9a2 2 0 00-2 2v24a2 2 0 001.041 1.756C8.525 30.02 9 30.448 9 31s-.455 1.013-.99.877A4.002 4.002 0 015 28V4z"
fill="#A3A3A3"
/>
</svg>
)
}
function DeviceNotificationIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
return (
<svg viewBox="0 0 32 32" aria-hidden="true" {...props}>
<circle cx={16} cy={16} r={16} fill="#A3A3A3" fillOpacity={0.2} />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M9 0a4 4 0 00-4 4v24a4 4 0 004 4h14a4 4 0 004-4V4a4 4 0 00-4-4H9zm0 2a2 2 0 00-2 2v24a2 2 0 002 2h14a2 2 0 002-2V4a2 2 0 00-2-2h-1.382a1 1 0 00-.894.553l-.448.894a1 1 0 01-.894.553h-6.764a1 1 0 01-.894-.553l-.448-.894A1 1 0 0010.382 2H9z"
fill="#A3A3A3"
/>
<path
d="M9 8a2 2 0 012-2h10a2 2 0 012 2v2a2 2 0 01-2 2H11a2 2 0 01-2-2V8z"
fill="#737373"
/>
</svg>
)
}
function DeviceTouchIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
let id = useId()
return (
<svg viewBox="0 0 32 32" fill="none" aria-hidden="true" {...props}>
<defs>
<linearGradient
id={`${id}-gradient`}
x1={14}
y1={14.5}
x2={7}
y2={17}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#737373" />
<stop offset={1} stopColor="#D4D4D4" stopOpacity={0} />
</linearGradient>
</defs>
<circle cx={16} cy={16} r={16} fill="#A3A3A3" fillOpacity={0.2} />
<path
fillRule="evenodd"
clipRule="evenodd"
d="M5 4a4 4 0 014-4h14a4 4 0 014 4v13h-2V4a2 2 0 00-2-2h-1.382a1 1 0 00-.894.553l-.448.894a1 1 0 01-.894.553h-6.764a1 1 0 01-.894-.553l-.448-.894A1 1 0 0010.382 2H9a2 2 0 00-2 2v24a2 2 0 002 2h4v2H9a4 4 0 01-4-4V4z"
fill="#A3A3A3"
/>
<path
d="M7 22c0-4.694 3.5-8 8-8"
stroke={`url(#${id}-gradient)`}
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M21 20l.217-5.513a1.431 1.431 0 00-2.85-.226L17.5 21.5l-1.51-1.51a2.107 2.107 0 00-2.98 0 .024.024 0 00-.005.024l3.083 9.25A4 4 0 0019.883 32H25a4 4 0 004-4v-5a3 3 0 00-3-3h-5z"
fill="#A3A3A3"
/>
</svg>
)
}
const maxZIndex = 2147483647
const bodyVariantBackwards: Variant = {
opacity: 0.4,
scale: 0.8,
zIndex: 0,
filter: 'blur(4px)',
transition: { duration: 0.4 },
}
const bodyAnimation: MotionProps = {
initial: 'initial',
animate: 'animate',
exit: 'exit',
variants: {
initial: (custom: CustomAnimationProps) => (
custom.isForwards
? {
y: '100%',
zIndex: maxZIndex - custom.changeCount,
transition: { duration: 0.4 },
}
: bodyVariantBackwards
),
animate: (custom: CustomAnimationProps) => ({
y: '0%',
opacity: 1,
scale: 1,
zIndex: maxZIndex / 2 - custom.changeCount,
filter: 'blur(0px)',
transition: { duration: 0.4 },
}),
exit: (custom: CustomAnimationProps) => (
custom.isForwards
? bodyVariantBackwards
: {
y: '100%',
zIndex: maxZIndex - custom.changeCount,
transition: { duration: 0.4 },
}
),
},
}
function InviteScreen() {
return (
<AppScreen className="w-full">
<img src={connectorImg} alt="Mycelium Connector" width="366" height="732" className="-mt-8" />
</AppScreen>
)
}
function StocksScreen() {
return (
<AppScreen className="w-full">
<img src={peersImg} alt="Mycelium Peers" width="366" height="732" className="-mt-8" />
</AppScreen>
)
}
function InvestScreen() {
return (
<AppScreen className="w-full">
<img src={settingImg} alt="Mycelium Settings" width="366" height="732" className="-mt-8" />
</AppScreen>
)
}
function usePrevious<T>(value: T) {
const ref = useRef<T>()
useEffect(() => {
ref.current = value
}, [value])
return ref.current
}
function FeaturesDesktop() {
let [changeCount, setChangeCount] = useState(0)
let [selectedIndex, setSelectedIndex] = useState(0)
let prevIndex = usePrevious(selectedIndex)
let isForwards = prevIndex === undefined ? true : selectedIndex > prevIndex
let onChange = useDebouncedCallback(
(selectedIndex: number) => {
setSelectedIndex(selectedIndex)
setChangeCount((changeCount) => changeCount + 1)
},
100,
{ leading: true },
)
return (
<TabGroup
className="grid grid-cols-12 items-center gap-8 lg:gap-16"
selectedIndex={selectedIndex}
onChange={onChange}
vertical
>
<TabList className="z-10 order-last col-span-6 space-y-6">
{features.map((feature, featureIndex) => (
<div
key={feature.name}
className={clsx(
'relative rounded-2xl outline-2 transition-all duration-300 ease-in-out hover:scale-105 hover:bg-gray-800/30',
selectedIndex === featureIndex
? 'outline-cyan-500'
: 'outline-transparent hover:outline-cyan-500',
)}
>
{featureIndex === selectedIndex && (
<motion.div
layoutId="activeBackground"
className="absolute inset-0 bg-gray-800"
initial={{ borderRadius: 16 }}
/>
)}
<div className="relative z-10 p-8">
<feature.icon className="h-8 w-8" />
<FeatureTitle as="h3" color="white" className="mt-6">
<Tab className="text-left data-selected:not-data-focus:outline-hidden">
<span className="absolute inset-0 rounded-2xl" />
{feature.name}
</Tab>
</FeatureTitle>
<FeatureDescription color="secondary" className="mt-2">
{feature.description}
</FeatureDescription>
</div>
</div>
))}
</TabList>
<div className="relative col-span-6">
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
<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}>
<AnimatePresence
initial={false}
custom={{ isForwards, changeCount }}
>
{features.map((feature, featureIndex) =>
selectedIndex === featureIndex ? (
<TabPanel
static
key={feature.name + changeCount}
className="col-start-1 row-start-1 flex focus:outline-offset-32 data-selected:not-data-focus:outline-hidden"
>
<motion.div {...bodyAnimation} custom={{ isForwards, changeCount }}>
<feature.screen />
</motion.div>
</TabPanel>
) : null,
)}
</AnimatePresence>
</TabPanels>
</PhoneFrame>
</div>
</TabGroup>
)
}
function FeaturesMobile() {
let [activeIndex, setActiveIndex] = useState(0)
let slideContainerRef = useRef<React.ElementRef<'div'>>(null)
let slideRefs = useRef<Array<React.ElementRef<'div'>>>([])
useEffect(() => {
let observer = new window.IntersectionObserver(
(entries) => {
for (let entry of entries) {
if (entry.isIntersecting && entry.target instanceof HTMLDivElement) {
setActiveIndex(slideRefs.current.indexOf(entry.target))
break
}
}
},
{
root: slideContainerRef.current,
threshold: 0.6,
},
)
for (let slide of slideRefs.current) {
if (slide) {
observer.observe(slide)
}
}
return () => {
observer.disconnect()
}
}, [slideContainerRef, slideRefs])
return (
<>
<div
ref={slideContainerRef}
className="-mb-4 flex snap-x snap-mandatory -space-x-4 overflow-x-auto overscroll-x-contain scroll-smooth pb-4 [scrollbar-width:none] sm:-space-x-6 [&::-webkit-scrollbar]:hidden"
>
{features.map((feature, featureIndex) => (
<div
key={featureIndex}
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
className={clsx(
'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
id={`primaryfeatures_mobile_circle_${featureIndex}`}
color="#13B5C8"
className={featureIndex % 2 === 1 ? 'rotate-180' : undefined}
/>
</div>
<PhoneFrame className="relative mx-auto w-full max-w-[366px]">
<feature.screen />
</PhoneFrame>
<div className="absolute inset-x-0 bottom-0 bg-gray-800/95 p-6 backdrop-blur-sm sm:p-10">
<feature.icon className="h-8 w-8" />
<MobileFeatureTitle color="white" className="mt-6">
{feature.name}
</MobileFeatureTitle>
<FeatureDescription color="secondary" className="mt-2">
{feature.description}
</FeatureDescription>
</div>
</div>
</div>
))}
</div>
<div className="mt-6 flex justify-center gap-3">
{features.map((_, featureIndex) => (
<button
type="button"
key={featureIndex}
className={clsx(
'relative h-0.5 w-4 rounded-full',
featureIndex === activeIndex ? 'bg-gray-300' : 'bg-gray-500',
)}
aria-label={`Go to slide ${featureIndex + 1}`}
onClick={() => {
slideRefs.current[featureIndex].scrollIntoView({
block: 'nearest',
inline: 'nearest',
})
}}
>
<span className="absolute -inset-x-1.5 -inset-y-3" />
</button>
))}
</div>
</>
)
}
export function CloudFeatures() { export function CloudFeatures() {
return ( return (
<section className="bg-gray-50 py-24 sm:py-32"> <section
id="howitworks"
aria-label="Features for investing all your money"
className="bg-gray-900 py-20 sm:py-32"
>
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-2xl lg:mx-0 lg:max-w-3xl">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow color="accent">How It Works</Eyebrow>
Core Features <SectionHeader color="white" className="mt-2">
</Eyebrow> How Mycelium Operates
<SectionHeader as="h2" className="mt-6 text-gray-900">
Infrastructure that verifies, heals, and scales itself.
</SectionHeader> </SectionHeader>
<P className="mt-6 text-gray-600"> <P color="light" className="mt-6">
From mesh networking to quantum-safe storage, every capability in Mycelium, like its natural namesake, thrives on decentralization,
Mycelium Cloud is designed for sovereign control and autonomous efficiency, and security, making it a truly powerful force in the world
operationsso your teams focus on shipping workloads instead of of decentralized networks.
wiring infrastructure.
</P> </P>
</div> </div>
<div className="mt-16 grid gap-8 md:grid-cols-2 xl:grid-cols-3"> </Container>
{featureSections.map((feature) => ( <div className="mt-16 md:hidden">
<div <FeaturesMobile />
key={feature.title} </div>
className="flex h-full flex-col rounded-3xl border border-slate-200 bg-white p-8 shadow-sm transition hover:-translate-y-1 hover:border-cyan-300 hover:shadow-lg" <Container className="hidden md:mt-20 md:block">
> <FeaturesDesktop />
<div>
<Small className="text-xs uppercase tracking-[0.3em] text-cyan-500">
Capability
</Small>
<h3 className="mt-4 text-xl font-semibold text-gray-900">
{feature.title}
</h3>
<p className="mt-4 text-sm leading-relaxed text-gray-600">
{feature.description}
</p>
</div>
<ul className="mt-6 space-y-3 text-sm text-gray-600">
{feature.bullets.map((bullet) => (
<li
key={bullet}
className="flex items-start gap-3 rounded-2xl border border-cyan-100 bg-cyan-50/60 p-3 leading-relaxed"
>
<span className="mt-1 inline-block size-2 rounded-full bg-cyan-500" />
<span>{bullet}</span>
</li>
))}
</ul>
</div>
))}
</div>
</Container> </Container>
</section> </section>
) )

View File

@@ -0,0 +1,44 @@
import { H3, H5, Eyebrow } from "../../components/Texts"
import { Button } from "../../components/Button"
export function CloudHeroNew() {
return (
<div
className="relative bg-cover lg:bg-contain bg-right bg-no-repeat"
style={{ backgroundImage: "url('/images/cloudhero3.webp')" }}
>
<div className="mx-auto max-w-7xl lg:px-8">
<div className="px-6 pt-12 pb-24 sm:pb-32 lg:col-span-5 lg:px-0 lg:pt-40 lg:pb-48 xl:col-span-5">
<div className="mx-auto max-w-2xl lg:mx-0">
<Eyebrow>
Mycelium Cloud
</Eyebrow>
<H3 className="mt-4">
Deploy sovereign Kubernetes clusters on decentralized infrastructure.
</H3>
<H5 className="mt-8 text-lg text-gray-600">
Mycelium Cloud turns the ThreeFold Grid into a programmable substrate for K3s.
</H5>
<H5 className="mt-4 text-lg text-gray-600">
Launch verifiable clusters with nature-inspired networking, quantum-safe storage, and zero-image delivery that keeps every workload deterministic.
</H5>
<div className="mt-10 flex items-center gap-x-6">
<Button
to="#"
variant="solid"
className=""
color="cyan"
>
Get started
</Button>
<Button to="#" variant="outline">
Explore Docs <span aria-hidden="true"> </span>
</Button>
</div>
</div>
</div>
</div>
</div>
)
}

View File

@@ -39,7 +39,7 @@ export function CloudOverview() {
</div> </div>
<Container className="relative"> <Container className="relative">
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-400"> <Eyebrow>
Platform Overview Platform Overview
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" color="light" className="mt-6 font-medium"> <SectionHeader as="h2" color="light" className="mt-6 font-medium">

View File

@@ -7,12 +7,14 @@ import { CloudGettingStarted } from './CloudGettingStarted'
import { CloudUseCases } from './CloudUseCases' import { CloudUseCases } from './CloudUseCases'
import { SecurityPillars } from './SecurityPillars' import { SecurityPillars } from './SecurityPillars'
import { CloudCTA } from './CloudCTA' import { CloudCTA } from './CloudCTA'
import { CloudHeroNew } from './CloudHeroNew'
export default function CloudPage() { export default function CloudPage() {
return ( return (
<> <>
<AnimatedSection> <AnimatedSection>
<CloudHero /> <CloudHeroNew />
</AnimatedSection> </AnimatedSection>
<AnimatedSection> <AnimatedSection>
<CloudOverview /> <CloudOverview />

View File

@@ -41,7 +41,7 @@ export function CloudUseCases() {
<section className="bg-white py-24 sm:py-32"> <section className="bg-white py-24 sm:py-32">
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow>
Use Cases Use Cases
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <SectionHeader as="h2" className="mt-6 text-gray-900">

View File

@@ -31,7 +31,7 @@ export function GpuArchitecture() {
<section id="gpu-architecture" className="bg-white py-24 sm:py-32"> <section id="gpu-architecture" className="bg-white py-24 sm:py-32">
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow>
Technical Architecture Technical Architecture
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <SectionHeader as="h2" className="mt-6 text-gray-900">

View File

@@ -37,7 +37,7 @@ export function GpuUseCases() {
<section className="bg-white py-24 sm:py-32"> <section className="bg-white py-24 sm:py-32">
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow>
Use Cases Use Cases
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <SectionHeader as="h2" className="mt-6 text-gray-900">

View File

@@ -1,7 +1,7 @@
"use client"; "use client";
import { Carousel, Card } from "@/components/ui/apple-cards-carousel"; import { Carousel, Card } from "@/components/ui/apple-cards-carousel";
import { H3, P } from "@/components/Texts"; import { H3, P , Eyebrow} from "@/components/Texts";
export function HomeSlider() { export function HomeSlider() {
const cards = data.map((card) => ( const cards = data.map((card) => (
@@ -11,8 +11,11 @@ export function HomeSlider() {
return ( return (
<div className="w-full h-full py-20 bg-[#0b0b0b]"> <div className="w-full h-full py-20 bg-[#0b0b0b]">
<div className="max-w-7xl mx-auto pl-4"> <div className="max-w-7xl mx-auto pl-4">
<Eyebrow className="text-left">
Ecosystem
</Eyebrow>
<H3 className="text-left text-white"> <H3 className="text-left text-white">
Discover the Mycelium Ecosystem Discover the Mycelium Components
</H3> </H3>
<div className="mt-4 max-w-3xl"> <div className="mt-4 max-w-3xl">
<P className="text-left text-neutral-400"> <P className="text-left text-neutral-400">

View File

@@ -53,7 +53,7 @@ export function StorageArchitecture() {
<section className="bg-gray-50 py-24 sm:py-32"> <section className="bg-gray-50 py-24 sm:py-32">
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow>
Technical Architecture Technical Architecture
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <SectionHeader as="h2" className="mt-6 text-gray-900">

View File

@@ -64,7 +64,7 @@ export function StorageFeatures() {
<section id="storage-features" className="bg-white py-24 sm:py-32"> <section id="storage-features" className="bg-white py-24 sm:py-32">
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow>
Core Features Core Features
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <SectionHeader as="h2" className="mt-6 text-gray-900">

View File

@@ -43,11 +43,11 @@ export function StorageOverview() {
{highlights.map((item) => ( {highlights.map((item) => (
<div <div
key={item.title} key={item.title}
className="group relative overflow-hidden rounded-3xl border border-white/10 bg-white/[0.04] p-8 backdrop-blur-sm transition hover:-translate-y-1 hover:border-cyan-300/50 hover:bg-white/[0.08]" className="group relative overflow-hidden rounded-3xl border border-white/10 bg-white/4 p-8 backdrop-blur-sm transition hover:-translate-y-1 hover:border-cyan-300/50 hover:bg-white/8"
> >
<div className="absolute inset-0 bg-gradient-to-br from-cyan-500/0 via-white/[0.05] to-cyan-300/20 opacity-0 transition group-hover:opacity-100" /> <div className="absolute inset-0 bg-linear-to-br from-cyan-500/0 via-white/5 to-cyan-300/20 opacity-0 transition group-hover:opacity-100" />
<div className="relative"> <div className="relative">
<Small className="text-xs uppercase tracking-[0.35em] text-cyan-200"> <Small className="text-xs uppercase tracking-[0.16em] text-cyan-200">
{item.label} {item.label}
</Small> </Small>
<h3 className="mt-4 text-lg font-semibold text-white"> <h3 className="mt-4 text-lg font-semibold text-white">

View File

@@ -84,7 +84,7 @@ export function StorageUseCases() {
<section className="bg-white py-24 sm:py-32"> <section className="bg-white py-24 sm:py-32">
<Container> <Container>
<div className="mx-auto max-w-3xl text-center"> <div className="mx-auto max-w-3xl text-center">
<Eyebrow className="tracking-[0.32em] uppercase text-cyan-500"> <Eyebrow>
Use Cases Use Cases
</Eyebrow> </Eyebrow>
<SectionHeader as="h2" className="mt-6 text-gray-900"> <SectionHeader as="h2" className="mt-6 text-gray-900">