Files
JulesFILIOT e9e66cbfa3 fix(web): set lambda-prize tech-stack to get support gap
Add a bottomSpacingClassName prop to TechStackSection and use it to render
a 100px gap at >=1024px and 12px below.
2026-06-19 12:48:43 +02:00

185 lines
5.8 KiB
TypeScript

import type { TechStackOverviewSection } from '@repo/content/schemas'
import ContentWidth from '@/components/layout/content-width'
import { TechStackDiagram } from '@/components/sections/shared/tech-stack-diagram'
import { Button, ButtonArrowIcon, type ButtonVariant } from '@/components/ui'
import { EXTERNAL_URLS, ROUTES } from '@/constants/routes'
function formatEyebrow(eyebrow: string) {
return eyebrow.replaceAll('. ', '.\n')
}
function splitTechStackTitle(title: string): [string, string] {
const parts = title.split(' Technology Stack')
return [parts[0], 'Technology Stack']
}
const TECH_STACK_BODY =
'Private-by-default infrastructure for people who need secure coordination and do not trust existing platforms to provide it.'
type Props = {
data: TechStackOverviewSection
/**
* Where the networking row links to. Page-level concern (the section
* fixture covers the four pillars; the networking row is a shared link
* across pages).
*/
networkingHref: string
/** Where the foundation row links to. */
foundationHref: string
/** Keep the compact layout through tablet widths on pages that need it. */
desktopAt1367?: boolean
/** Hide the hairline above the section on pages that don't want it. */
borderTop?: boolean
/** Override the top margin when the section is attached to the previous band. */
flushTop?: boolean
/** Override the content blocks' bottom padding (the gap to the next section). */
bottomSpacingClassName?: string
ctas?: readonly {
label: string
href: string
variant?: ButtonVariant
}[]
}
export default function TechStackSection({
data,
networkingHref,
foundationHref,
desktopAt1367 = false,
borderTop = true,
flushTop = false,
bottomSpacingClassName,
ctas,
}: Props) {
const compactContentClass = desktopAt1367
? 'min-[1367px]:hidden'
: 'md:hidden'
const desktopContentClass = desktopAt1367 ? 'min-[1367px]:flex' : 'md:flex'
const compactBottomClass = bottomSpacingClassName ?? 'pb-25'
const desktopBottomClass = bottomSpacingClassName ?? 'pb-[34px]'
const sectionCtas: NonNullable<Props['ctas']> = ctas ?? [
{
label: 'Start Building',
href: ROUTES.getStarted,
},
{
label: data.cta?.label ?? 'View the docs',
href: data.cta?.href ?? EXTERNAL_URLS.docs,
variant: 'secondary',
},
]
const renderCtas = () =>
sectionCtas.map((cta) => (
<Button
key={`${cta.href}-${cta.label}`}
href={cta.href}
variant={cta.variant}
icon={<ButtonArrowIcon />}
className="cursor-pointer transition-opacity hover:opacity-70"
>
{cta.label}
</Button>
))
return (
<section
id="tech-stack"
className={`relative overflow-hidden bg-brand-off-white ${
flushTop ? '' : 'lg:mt-[224px]'
} ${
borderTop ? 'border-t border-brand-dark-green/10' : ''
}`}
>
<ContentWidth
className={`relative min-h-full flex-col pt-3 ${compactBottomClass} ${compactContentClass}`}
>
<div className="flex items-start justify-between">
<p className="text-mono-s w-[226px] text-brand-dark-green">
Disclaimer: This diagram oversimplifies the stack.
</p>
<div className="flex flex-col items-end gap-1.5">{renderCtas()}</div>
</div>
<div className="mt-[70px] flex flex-col items-center gap-10">
{data.eyebrow ? (
<p className="text-mono-s w-[120px] whitespace-pre-line text-center text-brand-dark-green">
{formatEyebrow(data.eyebrow)}
</p>
) : null}
{data.title ? (
<h2 className="text-h2 w-full text-center text-brand-dark-green">
{(() => {
const [first, second] = splitTechStackTitle(data.title)
return (
<>
{first}
<br />
{second}
</>
)
})()}
</h2>
) : null}
<p className="text-mono-s w-[178px] text-center text-brand-dark-green">
{TECH_STACK_BODY}
</p>
<div className="mt-[60px] w-full">
<TechStackDiagram
data={data}
networkingHref={networkingHref}
foundationHref={foundationHref}
desktopAt1367={desktopAt1367}
/>
</div>
</div>
</ContentWidth>
<ContentWidth
className={`relative hidden min-h-full flex-col pt-[11px] ${desktopBottomClass} ${desktopContentClass}`}
>
<div className="flex items-start justify-between">
<p className="text-mono-s w-[226px] text-brand-dark-green">
Disclaimer: Abstract representation of the stack.
</p>
<div className="flex items-center gap-1.5">{renderCtas()}</div>
</div>
<div className="mt-[73px] flex flex-col items-center gap-[73px]">
{data.eyebrow ? (
<div className="flex w-[464px] flex-col items-center">
<p className="text-mono-s w-[226px] self-end whitespace-pre-line text-left text-brand-dark-green">
{formatEyebrow(data.eyebrow)}
</p>
{data.title ? (
<h2 className="text-h2 mt-12 w-[464px] whitespace-pre-line text-center text-brand-dark-green">
{data.title}
</h2>
) : null}
<p className="text-mono-s mt-12 w-[226px] self-end text-left text-brand-dark-green">
{TECH_STACK_BODY}
</p>
</div>
) : null}
<div className="w-full">
<TechStackDiagram
data={data}
networkingHref={networkingHref}
foundationHref={foundationHref}
/>
</div>
</div>
</ContentWidth>
</section>
)
}