fix(web): update mobile text and structure in use cases section; refine descriptions in technology stack pages

This commit is contained in:
jinhojang6
2026-06-19 16:23:12 +09:00
parent 798572d320
commit 435d264a1a
9 changed files with 74 additions and 96 deletions
@@ -11,8 +11,8 @@ import { HOME_USE_CASE_CARDS } from '@/lib/homepage-section-data'
export default async function UseCasesSection({ locale }: { locale: string }) {
const t = await getTranslations({ locale, namespace: 'home.useCases' })
const renderLambdaPrizeText = () =>
t.rich('lambda', {
const renderLambdaPrizeText = (key: 'lambda' | 'lambdaMobile' = 'lambda') =>
t.rich(key, {
lambdaPrize: (chunks: ReactNode) => (
<Link
href={ROUTES.lambdaPrize}
@@ -40,11 +40,14 @@ export default async function UseCasesSection({ locale }: { locale: string }) {
className="object-cover"
/>
</div>
<p className="font-mono-body min-w-0 text-left text-[10px] leading-[1.3] whitespace-pre-wrap lg:hidden">
{t('headline')}
{'\n\n'}
{renderLambdaPrizeText()}
</p>
<div className="flex min-w-0 flex-col gap-[17px] text-left lg:hidden">
<p className="text-body-sans whitespace-pre-line">
{t('headlineMobile')}
</p>
<p className="text-mono-s whitespace-pre-line">
{renderLambdaPrizeText('lambdaMobile')}
</p>
</div>
<p className="text-mono-s hidden w-full lg:block">{t('eyebrow')}</p>
<SectionHeadingReveal className="text-h3-serif hidden w-full whitespace-normal lg:block desktop:whitespace-pre-line">
{t('headline')}
@@ -82,95 +82,68 @@ function StatusCard({
export default function TechOverviewHero({ data }: Props) {
return (
<section className="relative mb-13 h-[760px] overflow-hidden bg-brand-off-white px-3 pt-10 pb-0 md:mb-25 md:h-119.25 md:pt-8 md:pb-0 xl:h-98.75">
<ContentWidth className="relative h-[500px] md:h-[600px] xl:h-[403px]">
<section className="relative mb-13 bg-brand-off-white px-3 pt-10 pb-13 md:mb-25 md:pt-8 md:pb-20">
<ContentWidth className="relative flex flex-col gap-10 md:gap-[70px]">
{/* Status card — desktop, anchored top-left over the spine */}
<div className="absolute top-0 left-0 hidden h-[99px] w-[393px] md:block">
{data.status ? <StatusCard status={data.status} compact /> : null}
</div>
<div className="hidden md:block">
<p className="text-mono-s absolute top-0 left-[calc(50%+6px)] w-[calc(50%-18px)] max-w-[226px] whitespace-pre-line text-brand-dark-green xl:w-[226px] xl:max-w-none">
{data.eyebrow}
</p>
<div className="absolute top-67 left-[calc(50%+6px)] flex max-w-[calc(50%-18px)] flex-col items-start gap-6 xl:max-w-none">
<p className="text-mono-s w-full max-w-[226px] text-brand-dark-green xl:w-[226px] xl:max-w-none">
{data.body}
</p>
{data.ctas && data.ctas.length > 0 ? (
<div className="flex flex-col items-start gap-2.5 xl:flex-row">
{data.ctas.map((cta) => (
<Button
key={cta.label}
{...resolveBasecampInstallCtaLinkProps(cta)}
variant={cta.variant ?? 'secondary'}
icon={getButtonIcon(cta.iconOverride)}
className="cursor-pointer"
>
{cta.label}
</Button>
))}
</div>
) : null}
<div className="mt-4 hidden h-px w-[calc(100vw-24px)] -translate-x-[calc(50vw-6px)] bg-brand-dark-green/10 lg:block xl:hidden" />
{/* Header image — mobile, anchored top-left over the spine */}
<div className="absolute top-2.5 left-0 h-[75px] w-[107px] overflow-hidden md:hidden">
<div className="absolute top-[-29px] left-[-48px] h-[208px] w-[166px]">
<Image
src={
data.background?.src ??
'/images/technology-stack/header-top.jpg'
}
alt={data.background?.alt ?? ''}
fill
sizes="166px"
className="object-cover"
/>
<div className="absolute inset-0 bg-black/30" />
</div>
</div>
<div className="md:hidden">
<div className="absolute top-2.5 left-0 h-[75px] w-[107px] overflow-hidden">
<div className="absolute top-[-29px] left-[-48px] h-[208px] w-[166px]">
<Image
src={
data.background?.src ??
'/images/technology-stack/header-top.jpg'
}
alt={data.background?.alt ?? ''}
fill
sizes="166px"
className="object-cover"
/>
<div className="absolute inset-0 bg-black/30" />
</div>
</div>
<p className="text-mono-s absolute top-2.5 left-[calc(50%+6px)] w-[calc(50%-18px)] max-w-[178px] whitespace-pre-line text-brand-dark-green">
{data.eyebrow}
</p>
</div>
{/* Eyebrow — right column */}
<p className="text-mono-s ml-[calc(50%+6px)] w-[calc(50%-18px)] max-w-[178px] whitespace-pre-line text-brand-dark-green md:max-w-[226px] xl:w-[226px] xl:max-w-none">
{data.eyebrow}
</p>
<Reveal className="absolute top-[126px] left-1/2 w-[464px] max-w-none -translate-x-1/2 md:top-[115px] xl:left-[476px] xl:translate-x-0">
<h1 className="text-h2 text-center text-brand-dark-green">
{data.headline === 'The Logos Technology Stack' ? (
<>
<span className="block">The Logos</span>
<span className="block">Technology Stack</span>
</>
) : (
data.headline
)}
{/* Headline */}
<Reveal className="w-full md:w-[464px] md:self-center xl:ml-[464px] xl:self-start">
<h1 className="text-h2 text-center whitespace-pre-line text-brand-dark-green">
{data.headline}
</h1>
</Reveal>
<div className="absolute top-[259px] left-0 w-full md:hidden">
<div className="ml-[calc(50%+6px)] flex w-[calc(50%-18px)] max-w-[178px] flex-col items-start gap-6">
<p className="text-mono-s text-brand-dark-green">{data.body}</p>
{data.ctas && data.ctas.length > 0 ? (
<div className="flex flex-col items-start gap-2.5">
{data.ctas.map((cta) => (
<Button
key={cta.label}
{...resolveBasecampInstallCtaLinkProps(cta)}
variant={cta.variant ?? 'secondary'}
icon={getButtonIcon(cta.iconOverride)}
className="cursor-pointer"
>
{cta.label}
</Button>
))}
</div>
) : null}
</div>
<div className="mt-10 h-px w-full bg-brand-dark-green/10" />
{/* Body + CTAs — right column */}
<div className="ml-[calc(50%+6px)] flex w-[calc(50%-18px)] max-w-[178px] flex-col items-start gap-6 md:max-w-[226px] xl:w-[226px] xl:max-w-none">
<p className="text-mono-s text-brand-dark-green">{data.body}</p>
{data.ctas && data.ctas.length > 0 ? (
<div className="flex flex-col items-start gap-2.5 xl:flex-row">
{data.ctas.map((cta) => (
<Button
key={cta.label}
{...resolveBasecampInstallCtaLinkProps(cta)}
variant={cta.variant ?? 'secondary'}
icon={getButtonIcon(cta.iconOverride)}
className="cursor-pointer"
>
{cta.label}
</Button>
))}
</div>
) : null}
<div className="mt-4 hidden h-px w-[calc(100vw-24px)] -translate-x-[calc(50vw-6px)] bg-brand-dark-green/10 lg:block xl:hidden" />
</div>
{/* Divider + status — mobile only */}
<div className="md:hidden">
<div className="h-px w-full bg-brand-dark-green/10" />
{data.status ? (
<div>
<div className="mt-6">
<StatusCard status={data.status} />
</div>
) : null}
+4 -2
View File
@@ -155,7 +155,9 @@
"useCases": {
"eyebrow": "Use Cases",
"headline": "Privacy is the condition that makes free association possible.\nLogos is the technology stack that makes it the default.",
"headlineMobile": "Privacy is the\ncondition that makes\nfree association possible.\n\nLogos is the\ntechnology stack that\nmakes it the default.",
"lambda": "Explore the applications Logos is funding through the <lambdaPrize>Lambda Prize</lambdaPrize>.",
"lambdaMobile": "Explore the applications\nLogos is funding through\nthe <lambdaPrize>Lambda Prize</lambdaPrize>.",
"secure": {
"title": "Secure, private communications.",
"body": "Resilient, private messaging for coordination in hostile environments."
@@ -174,7 +176,7 @@
}
},
"builderPortal": {
"title": "Basecamp.\nThe local launcher\nfor the Logos stack",
"title": "Basecamp.\nThe local launcher\nfor the Logos stack.",
"description": "Basecamp is a ready-to-run Logos distribution that you deploy on your own hardware, under your control. From the moment its installed, youre standing on your own ground, not connecting to someone elses infrastructure.\n\nThe Logos runtime runs locally, core modules are loaded, and essential applications — wallet, messenger, file sharing, blockchain explorer — are ready to use from day one.",
"feature1": "Explore programmes and resources to help you build your cyberstate.",
"feature2": "The Node Programme is for anyone who wants to join our movement to revitalise civil society using decentralised technologies.",
@@ -252,7 +254,7 @@
},
"scaffold": {
"title": "Start with the Scaffold Boilerplate",
"body": "A Rust CLI for bootstrapping LSSA program_deployment projects in standalone mode."
"body": "A Rust CLI for bootstrapping LEZ (Logos Execution Zone) program_deployment projects in standalone mode."
},
"sampleApps": {
"title": "Sample Apps",
+1 -1
View File
@@ -106,7 +106,7 @@
},
{
"title": "Start with the Scaffold Boilerplate",
"description": "A Rust CLI for bootstrapping LSSA program_deployment projects in standalone mode.",
"description": "A Rust CLI for bootstrapping LEZ (Logos Execution Zone) program_deployment projects in standalone mode.",
"ctas": [
{
"label": "Learn more",
@@ -90,7 +90,7 @@
"cards": [
{
"title": "Cryptarchia:\nPrivate Proof-of-Stake",
"description": "Most proof-of-stake systems reveal who proposed each block, creating a target for censorship, bribery, and coercion. Logos solves this with Cryptarchia, a private proof-of-stake mechanism in which block proposers are selected through a private lottery and anonymised through Blend, a mixnet-based protocol.\n\nValidators take part in consensus without revealing their identity during block proposal — a privacy guarantee most blockchains cannot offer.",
"description": "Many proof-of-stake systems reveal who proposed each block, creating a target for censorship, bribery, and coercion. Logos solves this with Cryptarchia, a private proof-of-stake mechanism in which block proposers are selected through a private lottery and anonymised through Blend, a mixnet-based protocol that makes it hard to link a proposal to its proposer through network analysis.\n\nValidators take part in consensus without revealing their identity during block proposal — a level of proposer privacy that few proof-of-stake networks provide.",
"image": {
"src": "/images/blockchain/overview/mantle.webp",
"alt": "",
@@ -157,7 +157,7 @@
"width": 1280,
"height": 720
},
"cta": { "label": "Build", "href": "/builders-hub" }
"cta": { "label": "Build", "href": "/get-started" }
},
{
"title": "Install Basecamp",
@@ -146,7 +146,7 @@
"width": 1280,
"height": 720
},
"cta": { "label": "Build", "href": "/builders-hub" }
"cta": { "label": "Build", "href": "/get-started" }
},
{
"title": "Install Basecamp",
@@ -152,7 +152,7 @@
"width": 1280,
"height": 720
},
"cta": { "label": "Build", "href": "/builders-hub" }
"cta": { "label": "Build", "href": "/get-started" }
},
{
"title": "Install Basecamp",
@@ -164,7 +164,7 @@
"width": 1280,
"height": 720
},
"cta": { "label": "Build", "href": "/builders-hub" }
"cta": { "label": "Build", "href": "/get-started" }
},
{
"title": "Install Basecamp",
+4 -4
View File
@@ -19,9 +19,9 @@
{
"componentType": "hero",
"key": "techStack.hero",
"eyebrow": "A unified ecosystem.\nPrivate-by-default.\nBuilt for real life.",
"headline": "The Logos Stack",
"body": "Private-by-default infrastructure for decentralised applications, private communication, and secure storage.",
"eyebrow": "Open by design, open in spirit. Build \ntruly decentralized applications with \nthe modular Logos Technology Stack.",
"headline": "The Logos \nTechnology Stack",
"body": "The Logos technology stack is a unified ecosystem of distinct modules. The whole stack is modular, allowing developers to assemble their own desired stack from their selection of modules.",
"background": {
"src": "/images/technology-stack/header-status.jpg",
"alt": "",
@@ -143,7 +143,7 @@
"accent": "grey",
"imagePosition": "left",
"title": "Logos Basecamp",
"description": "Basecamp is the launcher and unified surface of the Logos stack. It is an executable that wraps the Logos runtime, initialises the Logos Core environment, and discovers and loads plugins from installed modules. It is the primary, unified interface for users to interact with applications built on Logos.",
"description": "Basecamp is the launcher and unified surface of the Logos stack. It is an executable that wraps the Logos runtime, initialises the Logos Core environment, and discovers and loads plugins from installed modules.",
"image": {
"src": "/images/home/figma-refresh/basecamp.webp",
"alt": "",