tenext redesign
This commit is contained in:
50
components/sections/services/DeliveryPrinciplesSection.tsx
Normal file
50
components/sections/services/DeliveryPrinciplesSection.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import { PageContainer } from "@/components/shared/PageContainer";
|
||||
import { SectionContainer } from "@/components/shared/SectionContainer";
|
||||
import { SectionHeading } from "@/components/shared/SectionHeading";
|
||||
import { deliveryPrinciples } from "@/data/site-content";
|
||||
|
||||
/**
|
||||
* DeliveryPrinciplesSection — masonry grid of the commitments that keep
|
||||
* delivery predictable.
|
||||
*
|
||||
* Shared by: Home and Services.
|
||||
*
|
||||
* This slot held stock client testimonials in the original build. Tenext
|
||||
* does not publish named client quotes, so it presents how the company
|
||||
* works instead. If real, attributable testimonials become available,
|
||||
* this section is the place to reinstate them.
|
||||
*/
|
||||
export function DeliveryPrinciplesSection() {
|
||||
return (
|
||||
<SectionContainer paddingY="lg" className="bg-tenext-surface-muted">
|
||||
<PageContainer>
|
||||
<div className="mb-12 max-w-[650px]">
|
||||
<SectionHeading
|
||||
tag="how we work"
|
||||
title="The principles that keep delivery predictable"
|
||||
titleClassName="text-tenext-dark"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="columns-1 gap-6 sm:columns-2 lg:columns-4">
|
||||
{deliveryPrinciples.map((principle) => (
|
||||
<div
|
||||
key={principle.id}
|
||||
className="mb-6 break-inside-avoid rounded-[20px] bg-white p-8"
|
||||
>
|
||||
<h5
|
||||
className="mb-4 text-[18px] font-bold text-tenext-dark"
|
||||
style={{ fontFamily: "var(--font-dm-sans)" }}
|
||||
>
|
||||
{principle.title}
|
||||
</h5>
|
||||
<p className="text-[15px] leading-[1.7] text-tenext-text-muted">
|
||||
{principle.description}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</PageContainer>
|
||||
</SectionContainer>
|
||||
);
|
||||
}
|
||||
83
components/sections/services/EngagementModelsSection.tsx
Normal file
83
components/sections/services/EngagementModelsSection.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import { PageContainer } from "@/components/shared/PageContainer";
|
||||
import { SectionContainer } from "@/components/shared/SectionContainer";
|
||||
import { SectionHeading } from "@/components/shared/SectionHeading";
|
||||
import { engagementModels } from "@/data/site-content";
|
||||
|
||||
/**
|
||||
* EngagementModelsSection — the three ways enterprises work with Tenext.
|
||||
*
|
||||
* This slot held the template's SaaS pricing tiers. Tenext quotes
|
||||
* commercial terms per engagement, so no prices are published; each card
|
||||
* routes to the contact form instead.
|
||||
*/
|
||||
export function EngagementModelsSection() {
|
||||
return (
|
||||
<SectionContainer paddingY="lg">
|
||||
<PageContainer>
|
||||
<div className="mb-16 flex flex-col items-center justify-center text-center">
|
||||
<SectionHeading
|
||||
tag="engagement models"
|
||||
title="Ways to work with us"
|
||||
titleClassName="text-white max-w-[500px] text-center"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 gap-6 md:grid-cols-3">
|
||||
{engagementModels.map((model) => (
|
||||
<div
|
||||
key={model.name}
|
||||
className="relative flex flex-col overflow-hidden rounded-[25px] border border-tenext-card-border bg-tenext-dark p-10 transition-colors hover:border-tenext-teal"
|
||||
>
|
||||
<h3
|
||||
className="mb-4 text-[24px] font-bold text-white"
|
||||
style={{ fontFamily: "var(--font-dm-sans)" }}
|
||||
>
|
||||
{model.name}
|
||||
</h3>
|
||||
<p className="mb-8 text-[15px] leading-[1.7] text-tenext-text-muted">
|
||||
{model.summary}
|
||||
</p>
|
||||
|
||||
<ul className="mb-10 flex flex-col gap-4">
|
||||
{model.includes.map((item) => (
|
||||
<li
|
||||
key={item}
|
||||
className="flex items-start gap-3 text-[15px] text-white"
|
||||
>
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
className="mt-[3px] shrink-0 text-tenext-teal"
|
||||
aria-hidden
|
||||
>
|
||||
<path
|
||||
d="M20 6L9 17l-5-5"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<div className="mt-auto">
|
||||
<a
|
||||
href="/contacts"
|
||||
className="flex w-full items-center justify-center rounded-[12px] border border-tenext-card-border py-4 text-[16px] font-bold text-white transition-all hover:border-tenext-teal hover:text-tenext-teal"
|
||||
style={{ fontFamily: "var(--font-sora)" }}
|
||||
>
|
||||
Talk to an expert
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</PageContainer>
|
||||
</SectionContainer>
|
||||
);
|
||||
}
|
||||
55
components/sections/services/ServiceCardsGrid.tsx
Normal file
55
components/sections/services/ServiceCardsGrid.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import { PageContainer } from "@/components/shared/PageContainer";
|
||||
import { SectionContainer } from "@/components/shared/SectionContainer";
|
||||
import { ArrowIcon } from "@/components/shared/icons/ArrowIcon";
|
||||
import { services } from "@/data/site-content";
|
||||
|
||||
export function ServiceCardsGrid() {
|
||||
return (
|
||||
<SectionContainer paddingY="lg">
|
||||
<PageContainer>
|
||||
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
|
||||
{services.map((svc) => (
|
||||
<div
|
||||
key={svc.id}
|
||||
id={svc.id}
|
||||
className="group relative flex h-full min-h-[340px] scroll-mt-[120px] flex-col justify-between overflow-hidden rounded-[25px] border border-tenext-card-border bg-tenext-card-dark p-10 transition-all hover:bg-tenext-card-purple"
|
||||
>
|
||||
<div className="mb-6 h-[60px] w-[60px] rounded-full bg-tenext-card-purple2 p-4">
|
||||
<Image
|
||||
src="/images/tenext/3x.png"
|
||||
alt=""
|
||||
width={60}
|
||||
height={60}
|
||||
className="h-full w-full object-contain"
|
||||
onError={(e) => {
|
||||
(e.target as HTMLImageElement).src =
|
||||
"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23fff'><path d='M12 2L2 22h20L12 2z'/></svg>";
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4
|
||||
className="mb-4 text-[22px] font-bold text-white transition-colors group-hover:text-tenext-teal"
|
||||
style={{ fontFamily: "var(--font-dm-sans)" }}
|
||||
>
|
||||
{svc.title}
|
||||
</h4>
|
||||
<p className="text-[16px] text-tenext-text-muted">
|
||||
{svc.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="absolute bottom-0 right-0 flex h-[60px] w-[60px] items-center justify-center rounded-tl-[25px] bg-white text-tenext-dark transition-all duration-300 group-hover:bg-tenext-teal group-hover:text-white">
|
||||
<ArrowIcon className="h-4 w-4" />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</PageContainer>
|
||||
</SectionContainer>
|
||||
);
|
||||
}
|
||||
53
components/sections/services/ServiceFeaturesSection.tsx
Normal file
53
components/sections/services/ServiceFeaturesSection.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import { PageContainer } from "@/components/shared/PageContainer";
|
||||
import { SectionContainer } from "@/components/shared/SectionContainer";
|
||||
import { SectionHeading } from "@/components/shared/SectionHeading";
|
||||
import { IconBox } from "@/components/shared/IconBox";
|
||||
import { differentiators } from "@/data/site-content";
|
||||
|
||||
export function ServiceFeaturesSection() {
|
||||
const DefaultIcon = () => (
|
||||
<div className="flex h-full w-full items-center justify-center rounded-[18px] bg-tenext-card-purple">
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
className="text-white"
|
||||
>
|
||||
<path
|
||||
d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<SectionContainer paddingY="lg">
|
||||
<PageContainer>
|
||||
<div className="mb-16">
|
||||
<SectionHeading
|
||||
tag="why tenext"
|
||||
title="What enterprises get from working with us"
|
||||
titleClassName="text-white max-w-[700px]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 gap-x-12 gap-y-12 md:grid-cols-2 lg:grid-cols-3">
|
||||
{differentiators.map((item, i) => (
|
||||
<IconBox
|
||||
key={item.id}
|
||||
icon={<DefaultIcon />}
|
||||
title={item.title}
|
||||
description={item.description}
|
||||
hasBorder={i < 3} // The original has a border for the first row
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</PageContainer>
|
||||
</SectionContainer>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user