refactor: redesign pods page with bento grid layout and improved benefits sections

- Increased CloudHeroNew vertical padding on large screens (lg:py-16 to lg:py-24)
- Reduced spacing between description paragraphs in CloudHeroNew (mt-4 to mt-2)
- Created PodsBento component with animated bento grid showcasing pod benefits
- Added animations for data control, connectivity, security, and resilience features
- Refactored PodsDesign from accordion layout to centered intro with 4-column grid
- Create
This commit is contained in:
2025-11-17 15:00:41 +01:00
parent 3ab559aa84
commit 2b7559ab47
12 changed files with 1799 additions and 80 deletions

View File

@@ -1,42 +1,39 @@
'use client'
import {
Disclosure,
DisclosureButton,
DisclosurePanel,
} from '@headlessui/react'
import { MinusIcon, PlusIcon } from '@heroicons/react/24/outline'
import { Eyebrow, H3, H4 } from "@/components/Texts"
import { Eyebrow, H3, P, Small } from "@/components/Texts"
const product = {
subtitle: "Federation",
subtitle: "BENEFITS",
name: "Runs on Your Own Infrastructure",
description: `
<p>
Each Pod lives on your own hardware or on trusted local nodes in the Mycelium Network.
There is no central cloud and no company in the middle. You are not uploading your life to the cloud. You are running it yourself.
There is no central cloud and no company in the middle. You are not uploading your life
to the cloud. You are running it yourself.
</p>
`,
details: [
{
label: "Data Control",
name: "Your Data Lives on Your Pods",
description:
"Full control of where your data is stored and how its shared.",
},
{
label: "Connectivity",
name: "Direct Pod-to-Pod Networking",
description:
"Direct connections between Pods for faster, private communication.",
},
{
label: "Security",
name: "No One Can Spy or Shut You Down",
description:
"Independence from corporate servers or cloud outages.",
},
{
label: "Resilience",
name: "Resilient Even if Nodes Disconnect",
description:
"Continuous availability even if one node disconnects.",
@@ -44,78 +41,66 @@ There is no central cloud and no company in the middle. You are not uploading yo
],
}
export function PodsDesign() {
return (
<div className="bg-white text-gray-900">
{/* TOP LINE */}
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-100" />
<section className="relative w-full bg-[#FDFDFD] overflow-hidden">
{/* ▸ Top Spacing Line */}
<div className="max-w-7xl bg-[#FDFDFD] mx-auto py-6 border border-t-0 border-b-0 border-gray-100"></div>
<div className="w-full border-t border-l border-r border-gray-100" />
<main className="mx-auto max-w-7xl px-6 lg:px-12 py-12 border border-t-0 border-b-0 border-gray-100">
<div className="mx-auto max-w-2xl lg:max-w-none">
{/* ▸ Intro Section */}
<div className="bg-[#FDFDFD] w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-100">
<div className="px-8 py-12 max-w-4xl mx-auto flex flex-col items-center justify-center min-h-[220px] text-center">
<Eyebrow className="uppercase tracking-[0.16em] text-cyan-600">
{product.subtitle}
</Eyebrow>
<div className="lg:grid lg:grid-cols-5 lg:items-start lg:gap-x-8">
<H3 className="mt-4 text-black">
{product.name}
</H3>
{/* IMAGE */}
<div className="lg:col-span-2 lg:mt-8 mt-2">
<img
alt="Mycelium Federation"
src="/images/pod1.png"
className="aspect-square w-full object-cover rounded-md"
/>
</div>
{/* PRODUCT INFO */}
<div className="mt-8 px-4 sm:px-0 lg:mt-0 lg:col-span-3">
<Eyebrow className="text-cyan-600">
{product.subtitle}
</Eyebrow>
<H4 className="text-gray-900">
{product.name}
</H4>
<div
className="mt-4 text-gray-700 text-xl"
dangerouslySetInnerHTML={{ __html: product.description }}
/>
{/* DETAILS ACCORDION */}
<section className="mt-6">
<div className="divide-y divide-gray-200 border-t border-cyan-600/60">
{product.details.map((detail) => (
<Disclosure key={detail.name} as="div">
<H3>
<DisclosureButton className="group flex w-full items-center justify-between py-6 text-left">
<span className="text-lg font-medium text-gray-900">
{detail.name}
</span>
<span className="ml-6 flex items-center">
<PlusIcon className="block h-6 w-6 text-gray-500 group-open:hidden" />
<MinusIcon className="hidden h-6 w-6 text-cyan-600 group-open:block" />
</span>
</DisclosureButton>
</H3>
<DisclosurePanel className="pb-6">
<p className="text-gray-600 text-base">
{detail.description}
</p>
</DisclosurePanel>
</Disclosure>
))}
</div>
</section>
</div>
</div>
<P
className="mt-4 text-gray-700 text-base leading-relaxed"
dangerouslySetInnerHTML={{ __html: product.description }}
/>
</div>
</main>
{/* BOTTOM LINE */}
<div className="w-full border-b border-gray-100" />
{/* ▸ 4-Column Highlights Grid */}
<div className="grid lg:grid-cols-4">
{product.details.map((item) => (
<div
key={item.name}
className="group relative overflow-hidden border border-gray-100 bg-white p-8 transition hover:border-cyan-400/40 hover:bg-white"
>
{/* Hover Glow */}
<div className="absolute inset-0 bg-linear-to-br from-cyan-200/0 via-cyan-100/20 to-cyan-300/20 opacity-0 transition group-hover:opacity-100" />
<div className="relative">
{item.label && (
<Small className="text-xs uppercase tracking-[0.16em] text-cyan-600">
{item.label}
</Small>
)}
<h3 className="mt-4 text-lg font-semibold leading-tight text-black">
{item.name}
</h3>
<p className="mt-4 text-sm leading-relaxed text-gray-600">
{item.description}
</p>
</div>
</div>
))}
</div>
</div>
{/* ▸ Bottom Spacing */}
<div className="w-full border-b border-gray-100 bg-[#FDFDFD]" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-100" />
</div>
)
</section>
);
}