diff --git a/package.json b/package.json
index 55aa2a8a25..c6233d6e40 100644
--- a/package.json
+++ b/package.json
@@ -203,6 +203,7 @@
"packages/twenty-utils",
"packages/twenty-zapier",
"packages/twenty-website",
+ "packages/twenty-website-new",
"packages/twenty-docs",
"packages/twenty-e2e-testing",
"packages/twenty-shared",
diff --git a/packages/twenty-website-new/.gitignore b/packages/twenty-website-new/.gitignore
new file mode 100644
index 0000000000..301c67f0cd
--- /dev/null
+++ b/packages/twenty-website-new/.gitignore
@@ -0,0 +1,39 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+.yarn/install-state.gz
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env*.local
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
+
+# DB
+*.sqlite
\ No newline at end of file
diff --git a/packages/twenty-website-new/.oxlintrc.json b/packages/twenty-website-new/.oxlintrc.json
new file mode 100644
index 0000000000..3402a729a8
--- /dev/null
+++ b/packages/twenty-website-new/.oxlintrc.json
@@ -0,0 +1,48 @@
+{
+ "$schema": "./node_modules/oxlint/configuration_schema.json",
+ "plugins": ["react", "typescript", "import", "unicorn"],
+ "categories": {
+ "correctness": "off"
+ },
+ "ignorePatterns": ["node_modules"],
+ "rules": {
+ "func-style": ["error", "declaration", { "allowArrowFunctions": true }],
+ "no-console": "off",
+ "no-control-regex": "off",
+ "no-debugger": "error",
+ "no-duplicate-imports": "error",
+ "no-undef": "off",
+ "no-unused-vars": "off",
+ "no-redeclare": "off",
+ "import/no-duplicates": "error",
+ "typescript/no-redeclare": "error",
+ "typescript/ban-ts-comment": "error",
+ "typescript/consistent-type-imports": ["error", {
+ "prefer": "type-imports",
+ "fixStyle": "inline-type-imports"
+ }],
+ "typescript/explicit-function-return-type": "off",
+ "typescript/explicit-module-boundary-types": "off",
+ "typescript/no-empty-object-type": ["error", {
+ "allowInterfaces": "with-single-extends"
+ }],
+ "typescript/no-empty-function": "off",
+ "typescript/no-explicit-any": "off",
+ "typescript/no-unused-vars": ["warn", {
+ "vars": "all",
+ "varsIgnorePattern": "^_",
+ "args": "after-used",
+ "argsIgnorePattern": "^_"
+ }],
+ "react/no-unescaped-entities": "off",
+ "react/prop-types": "off",
+ "react/jsx-key": "off",
+ "react/display-name": "off",
+ "react/jsx-uses-react": "off",
+ "react/react-in-jsx-scope": "off",
+ "react/jsx-no-useless-fragment": "off",
+ "react/jsx-props-no-spreading": ["error", { "explicitSpread": "ignore" }],
+ "react-hooks/rules-of-hooks": "error",
+ "react-hooks/exhaustive-deps": "warn"
+ }
+}
diff --git a/packages/twenty-website-new/README.md b/packages/twenty-website-new/README.md
new file mode 100644
index 0000000000..663a198e11
--- /dev/null
+++ b/packages/twenty-website-new/README.md
@@ -0,0 +1,4 @@
+# Twenty-Website
+
+This is used for the marketing website (twenty.com).
+This is not related in any way to the main app, which you can find in twenty-front and twenty-server.
diff --git a/packages/twenty-website-new/next.config.ts b/packages/twenty-website-new/next.config.ts
new file mode 100644
index 0000000000..14aee202e8
--- /dev/null
+++ b/packages/twenty-website-new/next.config.ts
@@ -0,0 +1,5 @@
+import withLinaria, { type LinariaConfig } from 'next-with-linaria';
+
+const nextConfig: LinariaConfig = { reactCompiler: true };
+
+module.exports = withLinaria(nextConfig);
diff --git a/packages/twenty-website-new/package.json b/packages/twenty-website-new/package.json
new file mode 100644
index 0000000000..c4ad1d9804
--- /dev/null
+++ b/packages/twenty-website-new/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "twenty-website-new",
+ "private": true,
+ "scripts": {
+ "nx": "NX_DEFAULT_PROJECT=twenty-website-new node ../../node_modules/nx/bin/nx.js",
+ "dev": "npx next dev",
+ "build": "npx next build",
+ "start": "npx next start"
+ },
+ "dependencies": {
+ "@base-ui/react": "^1.3.0",
+ "@base-ui/utils": "^0.2.6",
+ "@linaria/core": "^7.0.0",
+ "@linaria/react": "^7.0.1",
+ "@wyw-in-js/babel-preset": "^0.8.1",
+ "next": "16.1.7",
+ "next-with-linaria": "^1.3.0",
+ "react": "19.2.3",
+ "react-dom": "19.2.3"
+ },
+ "devDependencies": {
+ "@types/node": "^20",
+ "@types/react": "^19",
+ "@types/react-dom": "^19",
+ "babel-plugin-react-compiler": "1.0.0"
+ }
+}
diff --git a/packages/twenty-website-new/project.json b/packages/twenty-website-new/project.json
new file mode 100644
index 0000000000..7af8727de3
--- /dev/null
+++ b/packages/twenty-website-new/project.json
@@ -0,0 +1,48 @@
+{
+ "name": "twenty-website-new",
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
+ "sourceRoot": "packages/twenty-website-new/src",
+ "projectType": "application",
+ "tags": ["scope:website"],
+ "targets": {
+ "build": {
+ "executor": "nx:run-commands",
+ "cache": true,
+ "inputs": ["production", "^production"],
+ "outputs": ["{projectRoot}/.next"],
+ "options": {
+ "cwd": "{projectRoot}",
+ "command": "npx next build"
+ },
+ "dependsOn": ["^build"]
+ },
+ "dev": {
+ "executor": "nx:run-commands",
+ "cache": false,
+ "options": {
+ "cwd": "{projectRoot}",
+ "command": "npx next dev"
+ }
+ },
+ "start": {
+ "executor": "nx:run-commands",
+ "cache": false,
+ "dependsOn": ["build"],
+ "options": {
+ "cwd": "{projectRoot}",
+ "command": "npx next start"
+ }
+ },
+ "lint": {},
+ "lint:diff-with-main": {},
+ "typecheck": {},
+ "fmt": {
+ "options": {
+ "files": "."
+ },
+ "configurations": {
+ "fix": {}
+ }
+ }
+ }
+}
diff --git a/packages/twenty-website-new/public/images/home/hero/background.png b/packages/twenty-website-new/public/images/home/hero/background.png
new file mode 100644
index 0000000000..2d5203cdee
Binary files /dev/null and b/packages/twenty-website-new/public/images/home/hero/background.png differ
diff --git a/packages/twenty-website-new/public/images/home/hero/foreground.png b/packages/twenty-website-new/public/images/home/hero/foreground.png
new file mode 100644
index 0000000000..3b9d55d84a
Binary files /dev/null and b/packages/twenty-website-new/public/images/home/hero/foreground.png differ
diff --git a/packages/twenty-website-new/public/images/home/problem/problem-visual.svg b/packages/twenty-website-new/public/images/home/problem/problem-visual.svg
new file mode 100644
index 0000000000..608ba5ce1a
--- /dev/null
+++ b/packages/twenty-website-new/public/images/home/problem/problem-visual.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/twenty-website-new/public/images/home/three-cards-feature/familiar-interface.png b/packages/twenty-website-new/public/images/home/three-cards-feature/familiar-interface.png
new file mode 100644
index 0000000000..00fb1b0231
Binary files /dev/null and b/packages/twenty-website-new/public/images/home/three-cards-feature/familiar-interface.png differ
diff --git a/packages/twenty-website-new/public/images/home/three-cards-feature/fast-path.png b/packages/twenty-website-new/public/images/home/three-cards-feature/fast-path.png
new file mode 100644
index 0000000000..00fb1b0231
Binary files /dev/null and b/packages/twenty-website-new/public/images/home/three-cards-feature/fast-path.png differ
diff --git a/packages/twenty-website-new/public/images/home/three-cards-feature/live-data.png b/packages/twenty-website-new/public/images/home/three-cards-feature/live-data.png
new file mode 100644
index 0000000000..00fb1b0231
Binary files /dev/null and b/packages/twenty-website-new/public/images/home/three-cards-feature/live-data.png differ
diff --git a/packages/twenty-website-new/public/images/why-twenty/hero/background.png b/packages/twenty-website-new/public/images/why-twenty/hero/background.png
new file mode 100644
index 0000000000..b0a7e6a575
Binary files /dev/null and b/packages/twenty-website-new/public/images/why-twenty/hero/background.png differ
diff --git a/packages/twenty-website-new/src/app/(home)/constants/hero.ts b/packages/twenty-website-new/src/app/(home)/constants/hero.ts
new file mode 100644
index 0000000000..95ed63264a
--- /dev/null
+++ b/packages/twenty-website-new/src/app/(home)/constants/hero.ts
@@ -0,0 +1,12 @@
+import { HeroDataType } from '@/sections/Hero/types';
+
+export const HERO_DATA: HeroDataType = {
+ heading: [
+ { text: 'Build', fontFamily: 'sans' },
+ { text: ' your Enterprise CRM ', fontFamily: 'serif' },
+ { text: 'at AI Speed', fontFamily: 'sans' },
+ ],
+ body: {
+ text: 'Twenty gives technical teams the building blocks for a custom CRM that meets complex business needs and quickly adapts as the business evolves.',
+ },
+};
diff --git a/packages/twenty-website-new/src/app/(home)/constants/problem.ts b/packages/twenty-website-new/src/app/(home)/constants/problem.ts
new file mode 100644
index 0000000000..77d1d7d01b
--- /dev/null
+++ b/packages/twenty-website-new/src/app/(home)/constants/problem.ts
@@ -0,0 +1,23 @@
+import { ProblemDataType } from '@/sections/Problem/types';
+
+export const PROBLEM_DATA: ProblemDataType = {
+ eyebrow: { heading: { text: 'The Problem:', fontFamily: 'sans' } },
+ heading: [
+ { text: 'A custom CRM gives your org an edge, ', fontFamily: 'serif' },
+ { text: 'but building one comes with tradeoffs', fontFamily: 'sans' },
+ ],
+ points: [
+ {
+ heading: { text: 'The Giant Monolith', fontFamily: 'sans' },
+ body: {
+ text: 'Proprietary languages, slow deployment cycles, and "black box" logic.',
+ },
+ },
+ {
+ heading: { text: 'The In-house Burden', fontFamily: 'sans' },
+ body: {
+ text: "It's fragile. V1 ships quickly, but maintaining and making changes is a long term burden.",
+ },
+ },
+ ],
+};
diff --git a/packages/twenty-website-new/src/app/(home)/constants/three-cards-feature.ts b/packages/twenty-website-new/src/app/(home)/constants/three-cards-feature.ts
new file mode 100644
index 0000000000..7ce6586fd4
--- /dev/null
+++ b/packages/twenty-website-new/src/app/(home)/constants/three-cards-feature.ts
@@ -0,0 +1,34 @@
+import { ThreeCardsFeatureCardsDataType } from '@/sections/ThreeCards/types';
+
+export const THREE_CARDS_FEATURE_DATA: ThreeCardsFeatureCardsDataType = {
+ eyebrow: {
+ heading: {
+ text: 'Skip the clunky UX that always comes with custom.',
+ fontFamily: 'sans',
+ },
+ },
+ heading: [
+ { text: 'Make your GTM team happy with ', fontFamily: 'serif' },
+ { text: "a CRM they'll love", fontFamily: 'sans' },
+ ],
+ featureCards: [
+ {
+ heading: { text: 'Familiar, modern interface', fontFamily: 'sans' },
+ body: {
+ text: "Twenty makes it simple. It's clean, intuitive, and built to feel like Notion.",
+ },
+ },
+ {
+ heading: { text: 'Fast path to action', fontFamily: 'sans' },
+ body: {
+ text: 'Smart patterns, shortcuts, and layouts make everyday tasks faster and easier to execute.',
+ },
+ },
+ {
+ heading: { text: 'Live data and AI Built', fontFamily: 'sans' },
+ body: {
+ text: 'Everything updates in real time, with AI chat always ready to help you move faster.',
+ },
+ },
+ ],
+};
diff --git a/packages/twenty-website-new/src/app/(home)/constants/three-cards-illustration.ts b/packages/twenty-website-new/src/app/(home)/constants/three-cards-illustration.ts
new file mode 100644
index 0000000000..8de854a9ed
--- /dev/null
+++ b/packages/twenty-website-new/src/app/(home)/constants/three-cards-illustration.ts
@@ -0,0 +1,49 @@
+import { ThreeCardsIllustrationDataType } from '@/sections/ThreeCards/types';
+
+export const THREE_CARDS_ILLUSTRATION_DATA: ThreeCardsIllustrationDataType = {
+ eyebrow: {
+ heading: { text: 'Stop settling for trade-offs.', fontFamily: 'sans' },
+ },
+ heading: [
+ { text: 'Assemble, iterate and adapt a robust CRM,', fontFamily: 'serif' },
+ { text: " that's quick to flex", fontFamily: 'sans' },
+ ],
+ body: {
+ text: 'Compose your CRM and interal apps with a single exesibility toolkit.',
+ },
+ illustrationCards: [
+ {
+ heading: { text: 'Production grade quality', fontFamily: 'sans' },
+ body: {
+ text: "What stood out with Twenty wasn't just flexibility it was the quality. The system feels stable, polished, and ready for real teams with real stakes.",
+ },
+ benefits: undefined,
+ attribution: {
+ role: { text: 'Head of Engineering' },
+ company: { text: 'Mid-Market Fintech' },
+ },
+ },
+ {
+ heading: { text: 'AI for rapid iterations', fontFamily: 'sans' },
+ body: {
+ text: 'Twenty removes friction from iteration and lets us adapt our CRM as the business changes.',
+ },
+ benefits: undefined,
+ attribution: {
+ role: { text: 'Head of Engineering' },
+ company: { text: 'Mid-Market Fintech' },
+ },
+ },
+ {
+ heading: { text: 'Control without drag', fontFamily: 'sans' },
+ body: {
+ text: "It's a modern, open-source alternative to Salesforce/Hubspot that lets you manage your customer relationships in a secure + privacy-first way.",
+ },
+ benefits: undefined,
+ attribution: {
+ role: { text: 'Head of Engineering' },
+ company: { text: 'Mid-Market Fintech' },
+ },
+ },
+ ],
+};
diff --git a/packages/twenty-website-new/src/app/(home)/constants/trusted-by.ts b/packages/twenty-website-new/src/app/(home)/constants/trusted-by.ts
new file mode 100644
index 0000000000..bec3823871
--- /dev/null
+++ b/packages/twenty-website-new/src/app/(home)/constants/trusted-by.ts
@@ -0,0 +1,7 @@
+import { TrustedByDataType } from '@/sections/TrustedBy/types';
+
+export const TRUSTED_BY_DATA: TrustedByDataType = {
+ separator: { text: 'trusted by' },
+ clientCountLabel: { text: '+ 10 000 other clients' },
+ logos: [{ icon: 'flexport' }, { icon: 'zapier' }],
+};
diff --git a/packages/twenty-website-new/src/app/(home)/page.tsx b/packages/twenty-website-new/src/app/(home)/page.tsx
new file mode 100644
index 0000000000..e598332292
--- /dev/null
+++ b/packages/twenty-website-new/src/app/(home)/page.tsx
@@ -0,0 +1,88 @@
+import { HERO_DATA } from '@/app/(home)/constants/hero';
+import { PROBLEM_DATA } from '@/app/(home)/constants/problem';
+import { THREE_CARDS_FEATURE_DATA } from '@/app/(home)/constants/three-cards-feature';
+import { THREE_CARDS_ILLUSTRATION_DATA } from '@/app/(home)/constants/three-cards-illustration';
+import { TRUSTED_BY_DATA } from '@/app/(home)/constants/trusted-by';
+import { Body, Eyebrow, Heading, LinkButton } from '@/design-system/components';
+import { Pages } from '@/enums/pages';
+import { Hero } from '@/sections/Hero/components';
+import { Problem } from '@/sections/Problem/components';
+import { ThreeCards } from '@/sections/ThreeCards/components';
+import { TrustedBy } from '@/sections/TrustedBy/components';
+import { theme } from '@/theme';
+
+export default function HomePage() {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/packages/twenty-website-new/src/app/favicon.ico b/packages/twenty-website-new/src/app/favicon.ico
new file mode 100644
index 0000000000..d611985bfd
Binary files /dev/null and b/packages/twenty-website-new/src/app/favicon.ico differ
diff --git a/packages/twenty-website-new/src/app/layout.tsx b/packages/twenty-website-new/src/app/layout.tsx
new file mode 100644
index 0000000000..2ef8d8527b
--- /dev/null
+++ b/packages/twenty-website-new/src/app/layout.tsx
@@ -0,0 +1,89 @@
+import { Footer } from '@/sections/Footer/components';
+import { Menu } from '@/sections/Menu/components';
+import { theme } from '@/theme';
+import { cssVariables } from '@/theme/css-variables';
+import { css } from '@linaria/core';
+import { styled } from '@linaria/react';
+import type { Metadata } from 'next';
+import { Aleo, Azeret_Mono, Host_Grotesk } from 'next/font/google';
+
+const hostGrotesk = Host_Grotesk({
+ subsets: ['latin'],
+ weight: ['300', '400', '500', '600'],
+ variable: '--font-sans',
+ display: 'swap',
+});
+
+const aleo = Aleo({
+ subsets: ['latin'],
+ weight: ['300'],
+ variable: '--font-serif',
+ display: 'swap',
+});
+
+const azeretMono = Azeret_Mono({
+ subsets: ['latin'],
+ weight: ['300', '500'],
+ variable: '--font-mono',
+ display: 'swap',
+});
+
+css`
+ :global(*),
+ :global(*::before),
+ :global(*::after) {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ }
+
+ :global(html) {
+ background-color: ${theme.colors.primary.background[100]};
+ }
+
+ :global(body) {
+ color: ${theme.colors.primary.text[100]};
+ display: flex;
+ font-family: ${theme.font.family.sans};
+ flex-direction: column;
+ min-height: 100vh;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ }
+`;
+
+const StyledMain = styled.main`
+ flex-grow: 1;
+`;
+
+export const metadata: Metadata = {
+ title: 'Twenty — Open Source CRM',
+ description: 'Modular, scalable open source CRM for modern teams.',
+};
+
+export default function RootLayout({
+ children,
+}: Readonly<{ children: React.ReactNode }>) {
+ return (
+
+
+
+
+
+
+
+
+ {children}
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/app/partner/constants/hero.ts b/packages/twenty-website-new/src/app/partner/constants/hero.ts
new file mode 100644
index 0000000000..7983f82b32
--- /dev/null
+++ b/packages/twenty-website-new/src/app/partner/constants/hero.ts
@@ -0,0 +1,11 @@
+import { HeroDataType } from '@/sections/Hero/types';
+
+export const HERO_DATA: HeroDataType = {
+ heading: [
+ { text: 'Become a ', fontFamily: 'serif' },
+ { text: 'Twenty Partner', fontFamily: 'sans' },
+ ],
+ body: {
+ text: "We're building the #1 open-source CRM, but we can't do it alone. Join our partner ecosystem and grow with us.",
+ },
+};
diff --git a/packages/twenty-website-new/src/app/partner/constants/three-cards-illustration.ts b/packages/twenty-website-new/src/app/partner/constants/three-cards-illustration.ts
new file mode 100644
index 0000000000..857319c75b
--- /dev/null
+++ b/packages/twenty-website-new/src/app/partner/constants/three-cards-illustration.ts
@@ -0,0 +1,53 @@
+import { ThreeCardsIllustrationDataType } from '@/sections/ThreeCards/types';
+
+export const THREE_CARDS_ILLUSTRATION_DATA: ThreeCardsIllustrationDataType = {
+ eyebrow: {
+ heading: {
+ text: 'Which partner program is right for you?',
+ fontFamily: 'sans',
+ },
+ },
+ heading: [
+ { text: 'Find the program that fits your business ', fontFamily: 'serif' },
+ { text: 'and unlock new opportunities with Twenty', fontFamily: 'sans' },
+ ],
+ body: { text: '' },
+ illustrationCards: [
+ {
+ heading: { text: 'Technology Partners', fontFamily: 'sans' },
+ body: {
+ text: 'Build integrations that connect Twenty with the tools your customers already use. Help us expand the Twenty ecosystem.',
+ },
+ benefits: [
+ { text: 'Co-marketing opportunities' },
+ { text: 'Listing on Twenty integrations page' },
+ { text: 'Soon: earn revenue' },
+ ],
+ attribution: undefined,
+ },
+ {
+ heading: { text: 'Content & Community Partners', fontFamily: 'sans' },
+ body: {
+ text: "Share Twenty with your audience and help shape the future of open-source CRM. We're looking for creators, educators, and community builders who want to showcase great software.",
+ },
+ benefits: [
+ { text: 'Revenue share for referred customers' },
+ { text: 'Exclusive content collaboration opportunities' },
+ { text: 'Marketing assets & brand resources' },
+ ],
+ attribution: undefined,
+ },
+ {
+ heading: { text: 'Solutions Partners', fontFamily: 'sans' },
+ body: {
+ text: 'Help customers implement, customize, and succeed with Twenty. Combine sales and services to grow your business.',
+ },
+ benefits: [
+ { text: 'Resale discounts & revenue share' },
+ { text: 'Marketplace listing' },
+ { text: 'Dedicated partner support' },
+ ],
+ attribution: undefined,
+ },
+ ],
+};
diff --git a/packages/twenty-website-new/src/app/partner/page.tsx b/packages/twenty-website-new/src/app/partner/page.tsx
new file mode 100644
index 0000000000..1fe36e8668
--- /dev/null
+++ b/packages/twenty-website-new/src/app/partner/page.tsx
@@ -0,0 +1,68 @@
+import { TRUSTED_BY_DATA } from '@/app/(home)/constants/trusted-by';
+import { HERO_DATA } from '@/app/partner/constants/hero';
+import { THREE_CARDS_ILLUSTRATION_DATA } from '@/app/partner/constants/three-cards-illustration';
+import { Body, Eyebrow, Heading, LinkButton } from '@/design-system/components';
+import { Pages } from '@/enums/pages';
+import { Hero } from '@/sections/Hero/components';
+import { ThreeCards } from '@/sections/ThreeCards/components';
+import { TrustedBy } from '@/sections/TrustedBy/components';
+import { theme } from '@/theme';
+
+export default function PartnerPage() {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/packages/twenty-website-new/src/app/pricing/constants/hero.ts b/packages/twenty-website-new/src/app/pricing/constants/hero.ts
new file mode 100644
index 0000000000..7a8abeb9f3
--- /dev/null
+++ b/packages/twenty-website-new/src/app/pricing/constants/hero.ts
@@ -0,0 +1,11 @@
+import { HeroDataType } from '@/sections/Hero/types';
+
+export const HERO_DATA: HeroDataType = {
+ heading: [
+ { text: 'A pricing that scales ', fontFamily: 'serif' },
+ { text: 'with your need', fontFamily: 'sans' },
+ ],
+ body: {
+ text: "We're building the #1 open-source CRM, but we can't do it alone. Join our partner ecosystem and grow with us.",
+ },
+};
diff --git a/packages/twenty-website-new/src/app/pricing/page.tsx b/packages/twenty-website-new/src/app/pricing/page.tsx
new file mode 100644
index 0000000000..3c119728de
--- /dev/null
+++ b/packages/twenty-website-new/src/app/pricing/page.tsx
@@ -0,0 +1,15 @@
+import { HERO_DATA } from '@/app/pricing/constants/hero';
+import { Pages } from '@/enums/pages';
+import { Hero } from '@/sections/Hero/components';
+import { theme } from '@/theme';
+
+export default function PricingPage() {
+ return (
+ <>
+
+
+
+
+ >
+ );
+}
diff --git a/packages/twenty-website-new/src/app/product/constants/hero.ts b/packages/twenty-website-new/src/app/product/constants/hero.ts
new file mode 100644
index 0000000000..9e0eeec7c7
--- /dev/null
+++ b/packages/twenty-website-new/src/app/product/constants/hero.ts
@@ -0,0 +1,11 @@
+import { HeroDataType } from '@/sections/Hero/types';
+
+export const HERO_DATA: HeroDataType = {
+ heading: [
+ { text: 'The CRM that moves ', fontFamily: 'serif' },
+ { text: 'as fast as you do', fontFamily: 'sans' },
+ ],
+ body: {
+ text: 'Modern interface. AI assistance. All the features you need, ready from day one.',
+ },
+};
diff --git a/packages/twenty-website-new/src/app/product/constants/three-cards.ts b/packages/twenty-website-new/src/app/product/constants/three-cards.ts
new file mode 100644
index 0000000000..57902ca01c
--- /dev/null
+++ b/packages/twenty-website-new/src/app/product/constants/three-cards.ts
@@ -0,0 +1,38 @@
+import { ThreeCardsIllustrationDataType } from '@/sections/ThreeCards/types';
+
+export const THREE_CARDS_ILLUSTRATION_DATA: ThreeCardsIllustrationDataType = {
+ eyebrow: {
+ heading: { text: 'Stop settling for trade-offs.', fontFamily: 'sans' },
+ },
+ heading: [
+ { text: 'A modern CRM with ', fontFamily: 'serif' },
+ { text: 'an intuitive interface', fontFamily: 'sans' },
+ ],
+ body: { text: '' },
+ illustrationCards: [
+ {
+ heading: { text: 'Built for speed', fontFamily: 'sans' },
+ body: {
+ text: 'Fly through your workspace with shortcuts and short load times.',
+ },
+ benefits: undefined,
+ attribution: undefined,
+ },
+ {
+ heading: { text: 'Real-time data', fontFamily: 'sans' },
+ body: {
+ text: 'See updates as they happen. Work with your team and agents seamlessly.',
+ },
+ benefits: undefined,
+ attribution: undefined,
+ },
+ {
+ heading: { text: 'Stay in Flow', fontFamily: 'sans' },
+ body: {
+ text: 'AI chat, settings, and records in a side panels for fast, single-screen access.',
+ },
+ benefits: undefined,
+ attribution: undefined,
+ },
+ ],
+};
diff --git a/packages/twenty-website-new/src/app/product/page.tsx b/packages/twenty-website-new/src/app/product/page.tsx
new file mode 100644
index 0000000000..681c9be58c
--- /dev/null
+++ b/packages/twenty-website-new/src/app/product/page.tsx
@@ -0,0 +1,60 @@
+import { TRUSTED_BY_DATA } from '@/app/(home)/constants/trusted-by';
+import { HERO_DATA } from '@/app/product/constants/hero';
+import { THREE_CARDS_ILLUSTRATION_DATA } from '@/app/product/constants/three-cards';
+import { Body, Eyebrow, Heading, LinkButton } from '@/design-system/components';
+import { Pages } from '@/enums/pages';
+import { Hero } from '@/sections/Hero/components';
+import { ThreeCards } from '@/sections/ThreeCards/components';
+import { TrustedBy } from '@/sections/TrustedBy/components';
+import { theme } from '@/theme';
+
+export default function ProductPage() {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/packages/twenty-website-new/src/app/why-twenty/constants/hero.ts b/packages/twenty-website-new/src/app/why-twenty/constants/hero.ts
new file mode 100644
index 0000000000..7db806d429
--- /dev/null
+++ b/packages/twenty-website-new/src/app/why-twenty/constants/hero.ts
@@ -0,0 +1,11 @@
+import { HeroDataType } from '@/sections/Hero/types';
+
+export const HERO_DATA: HeroDataType = {
+ heading: [
+ { text: 'The future of CRM is built, ', fontFamily: 'serif' },
+ { text: 'not bought.', fontFamily: 'sans' },
+ ],
+ body: {
+ text: 'Most packaged software makes companies more similar. CRM is no exception. AI is turning software into a commodity. That does not make your go-to-market a commodity. It makes it the battleground.',
+ },
+};
diff --git a/packages/twenty-website-new/src/app/why-twenty/page.tsx b/packages/twenty-website-new/src/app/why-twenty/page.tsx
new file mode 100644
index 0000000000..69a3b2550d
--- /dev/null
+++ b/packages/twenty-website-new/src/app/why-twenty/page.tsx
@@ -0,0 +1,14 @@
+import { HERO_DATA } from '@/app/why-twenty/constants/hero';
+import { Pages } from '@/enums/pages';
+import { Hero } from '@/sections/Hero/components';
+import { theme } from '@/theme';
+
+export default function WhyTwentyPage() {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/design-system/components/Body/Body.tsx b/packages/twenty-website-new/src/design-system/components/Body/Body.tsx
new file mode 100644
index 0000000000..d7183afa31
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Body/Body.tsx
@@ -0,0 +1,99 @@
+import { theme } from '@/theme';
+import { css } from '@linaria/core';
+import { BodyType } from './types/Body';
+
+const bodyClassName = css`
+ margin: 0;
+
+ &[data-family='sans'] {
+ font-family: ${theme.font.family.sans};
+ }
+
+ &[data-family='serif'] {
+ font-family: ${theme.font.family.serif};
+ }
+
+ &[data-family='mono'] {
+ font-family: ${theme.font.family.mono};
+ }
+
+ &[data-weight='light'] {
+ font-weight: ${theme.font.weight.light};
+ }
+
+ &[data-weight='regular'] {
+ font-weight: ${theme.font.weight.regular};
+ }
+
+ &[data-weight='medium'] {
+ font-weight: ${theme.font.weight.medium};
+ }
+
+ &[data-size='md'] {
+ font-size: ${theme.font.size(4)};
+ line-height: ${theme.lineHeight(5.5)};
+ }
+
+ &[data-size='sm'] {
+ font-size: ${theme.font.size(4)};
+ line-height: ${theme.lineHeight(5.5)};
+ }
+
+ &[data-size='xs'] {
+ font-size: ${theme.font.size(3)};
+ line-height: ${theme.lineHeight(3.5)};
+ }
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ &[data-size='md'] {
+ font-size: ${theme.font.size(4.5)};
+ line-height: ${theme.lineHeight(6)};
+ }
+
+ &[data-size='sm'] {
+ font-size: ${theme.font.size(4)};
+ line-height: ${theme.lineHeight(5.5)};
+ }
+
+ &[data-size='xs'] {
+ font-size: ${theme.font.size(3)};
+ line-height: ${theme.lineHeight(3.5)};
+ }
+ }
+`;
+
+export type BodyAs = 'p' | 'span' | 'div';
+export type BodyFamily = 'sans' | 'serif' | 'mono';
+export type BodyWeight = 'light' | 'regular' | 'medium';
+export type BodySize = 'md' | 'sm' | 'xs';
+
+export type BodyProps = {
+ as?: BodyAs;
+ body: BodyType;
+ family?: BodyFamily;
+ weight?: BodyWeight;
+ size?: BodySize;
+ className?: string;
+};
+
+export function Body({
+ as: Tag = 'p',
+ body,
+ family = 'sans',
+ weight = 'regular',
+ size = 'md',
+ className,
+}: BodyProps) {
+ const rootClassName = [bodyClassName, className].filter(Boolean).join(' ');
+
+ return (
+
+ {body.text}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/design-system/components/Body/types/Body.ts b/packages/twenty-website-new/src/design-system/components/Body/types/Body.ts
new file mode 100644
index 0000000000..183f9de787
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Body/types/Body.ts
@@ -0,0 +1,3 @@
+export type BodyType = {
+ text: string;
+}
diff --git a/packages/twenty-website-new/src/design-system/components/Button/BaseButton.tsx b/packages/twenty-website-new/src/design-system/components/Button/BaseButton.tsx
new file mode 100644
index 0000000000..d21b1627a7
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Button/BaseButton.tsx
@@ -0,0 +1,84 @@
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import { ButtonShape } from './ButtonShape';
+
+export const buttonBaseStyles = `
+ align-items: center;
+ background: transparent;
+ border: none;
+ border-radius: ${theme.radius(2)};
+ cursor: pointer;
+ display: inline-flex;
+ font-family: ${theme.font.family.mono};
+ font-size: ${theme.font.size(3)};
+ font-weight: ${theme.font.weight.medium};
+ height: ${theme.spacing(10)};
+ justify-content: center;
+ letter-spacing: 0;
+ padding: 0 ${theme.spacing(5)};
+ position: relative;
+ text-decoration: none;
+ text-transform: uppercase;
+
+ &:focus-visible {
+ outline: 1px solid ${theme.colors.highlight[100]};
+ outline-offset: 1px;
+ }
+`;
+
+const Label = styled.span`
+ position: relative;
+ z-index: 1;
+
+ &[data-color='primary'] {
+ color: ${theme.colors.primary.text[100]};
+ }
+
+ &[data-color='secondary'] {
+ color: ${theme.colors.secondary.text[100]};
+ }
+`;
+
+export type BaseButtonProps = {
+ color: 'primary' | 'secondary';
+ label: string;
+ variant: 'contained' | 'outlined';
+};
+
+export function BaseButton({ color, label, variant }: BaseButtonProps) {
+ let fillColor: string;
+ let strokeColor: string;
+ let labelColor: 'primary' | 'secondary';
+
+ switch (`${variant}.${color}`) {
+ case 'contained.primary':
+ fillColor = theme.colors.primary.background[100];
+ strokeColor = 'none';
+ labelColor = 'primary';
+ break;
+ case 'contained.secondary':
+ fillColor = theme.colors.secondary.background[100];
+ strokeColor = 'none';
+ labelColor = 'secondary';
+ break;
+ case 'outlined.primary':
+ fillColor = 'none';
+ strokeColor = theme.colors.primary.background[100];
+ labelColor = 'secondary';
+ break;
+ case 'outlined.secondary':
+ fillColor = 'none';
+ strokeColor = theme.colors.secondary.background[100];
+ labelColor = 'primary';
+ break;
+ default:
+ throw new Error(`Unhandled button appearance: ${variant} ${color}`);
+ }
+
+ return (
+ <>
+
+
+ >
+ );
+}
diff --git a/packages/twenty-website-new/src/design-system/components/Button/ButtonShape.tsx b/packages/twenty-website-new/src/design-system/components/Button/ButtonShape.tsx
new file mode 100644
index 0000000000..1c5617f3c6
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Button/ButtonShape.tsx
@@ -0,0 +1,74 @@
+import { styled } from "@linaria/react";
+
+interface ButtonShapeProps {
+ fillColor: string;
+ strokeColor: string;
+}
+
+const LEFT_FILL = "M4 0 A4 4 0 0 0 0 4 V36 A4 4 0 0 0 4 40 Z";
+const LEFT_OUTLINE = "M4 0.5 A3.5 3.5 0 0 0 0.5 4 V36 A3.5 3.5 0 0 0 4 39.5";
+
+const RIGHT_FILL = "M0 0 h11 a4 4 0 0 1 4 4 v20.523 a6 6 0 0 1 -1.544 4.019 l-8.548 9.477 A6 6 0 0 1 0.453 40 H0 Z";
+const RIGHT_OUTLINE = "M0 0.5 h11 a3.5 3.5 0 0 1 3.5 3.5 v20.523 a5.5 5.5 0 0 1 -1.416 3.684 l-8.547 9.477 a5.5 5.5 0 0 1 -4.084 1.816 H0";
+
+const ShapeContainer = styled.div`
+ display: flex;
+ height: 40px;
+ inset: 0;
+ pointer-events: none;
+ position: absolute;
+ width: 100%;
+ z-index: 0;
+`;
+
+const LeftCap = styled.svg`
+ display: block;
+ flex-shrink: 0;
+`;
+
+const MiddleSegment = styled.svg`
+ display: block;
+ flex-grow: 1;
+ margin: 0 -1px;
+ min-width: 0;
+`;
+
+const RightCap = styled.svg`
+ display: block;
+ flex-shrink: 0;
+`;
+
+export function ButtonShape({ fillColor, strokeColor }: ButtonShapeProps) {
+ const isOutline = fillColor === "none";
+
+ return (
+
+
+ {isOutline ? (
+
+ ) : (
+
+ )}
+
+
+
+ {isOutline ? (
+ <>
+
+
+ >
+ ) : (
+
+ )}
+
+
+
+ {isOutline ? (
+
+ ) : (
+
+ )}
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/design-system/components/Button/LinkButton.tsx b/packages/twenty-website-new/src/design-system/components/Button/LinkButton.tsx
new file mode 100644
index 0000000000..9abccf4320
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Button/LinkButton.tsx
@@ -0,0 +1,49 @@
+import type { LinkButtonType } from '@/design-system/components/Button/types/LinkButtonType';
+import { styled } from '@linaria/react';
+import Link from 'next/link';
+import {
+ BaseButton,
+ type BaseButtonProps,
+ buttonBaseStyles,
+} from './BaseButton';
+
+const StyledButtonAnchor = styled.a`
+ ${buttonBaseStyles}
+`;
+
+const StyledButtonLink = styled(Link)`
+ ${buttonBaseStyles}
+`;
+
+export type LinkButtonPresentation = 'anchor' | 'link';
+
+export type LinkButtonProps = Omit &
+ LinkButtonType & { type: LinkButtonPresentation };
+
+export function LinkButton({
+ color,
+ href,
+ label,
+ type,
+ variant,
+}: LinkButtonProps) {
+ const inner = ;
+
+ if (type === 'anchor') {
+ return (
+
+ {inner}
+
+ );
+ }
+
+ return (
+
+ {inner}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/design-system/components/Button/SubmitButton.tsx b/packages/twenty-website-new/src/design-system/components/Button/SubmitButton.tsx
new file mode 100644
index 0000000000..94bc6cda0b
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Button/SubmitButton.tsx
@@ -0,0 +1,27 @@
+import { styled } from '@linaria/react';
+import {
+ BaseButton,
+ type BaseButtonProps,
+ buttonBaseStyles,
+} from './BaseButton';
+import type { SubmitButtonType } from './types/SubmitButtonType';
+
+const StyledSubmitButton = styled.button`
+ ${buttonBaseStyles}
+`;
+
+export type SubmitButtonProps = Omit &
+ SubmitButtonType & { onClick?: () => void };
+
+export function SubmitButton({
+ color,
+ label,
+ onClick,
+ variant,
+}: SubmitButtonProps) {
+ return (
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/design-system/components/Button/types/LinkButtonType.ts b/packages/twenty-website-new/src/design-system/components/Button/types/LinkButtonType.ts
new file mode 100644
index 0000000000..e2d671cf60
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Button/types/LinkButtonType.ts
@@ -0,0 +1 @@
+export type LinkButtonType = { href: string; label: string };
diff --git a/packages/twenty-website-new/src/design-system/components/Button/types/SubmitButtonType.ts b/packages/twenty-website-new/src/design-system/components/Button/types/SubmitButtonType.ts
new file mode 100644
index 0000000000..4e98c8ecc2
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Button/types/SubmitButtonType.ts
@@ -0,0 +1 @@
+export type SubmitButtonType = { label: string };
diff --git a/packages/twenty-website-new/src/design-system/components/Container/Container.tsx b/packages/twenty-website-new/src/design-system/components/Container/Container.tsx
new file mode 100644
index 0000000000..28b17fcbf9
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Container/Container.tsx
@@ -0,0 +1,15 @@
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import type { ReactNode } from 'react';
+
+const ContainerRoot = styled.div`
+ margin: 0 auto;
+ max-width: ${theme.breakpoints.maxContent}px;
+ width: 100%;
+`;
+
+export type ContainerProps = { children: ReactNode; className?: string };
+
+export function Container({ children, className }: ContainerProps) {
+ return {children};
+}
diff --git a/packages/twenty-website-new/src/design-system/components/Eyebrow/Eyebrow.tsx b/packages/twenty-website-new/src/design-system/components/Eyebrow/Eyebrow.tsx
new file mode 100644
index 0000000000..172d995d91
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Eyebrow/Eyebrow.tsx
@@ -0,0 +1,53 @@
+import { Heading } from '@/design-system/components/Heading/Heading';
+import { HeadingType } from '@/design-system/components/Heading/types/Heading';
+import { RectangleFillIcon } from '@/icons';
+import { theme } from '@/theme';
+import { css } from '@linaria/core';
+import { styled } from '@linaria/react';
+
+const EyebrowRow = styled.div`
+ align-items: start;
+ display: grid;
+ gap: ${theme.spacing(2)};
+ grid-template-columns: auto 1fr;
+ text-align: start;
+`;
+
+const IconWrapper = styled.div`
+ display: flex;
+ align-items: center;
+ height: ${theme.lineHeight(6)};
+`;
+
+const eyebrowColorPrimary = css`
+ color: ${theme.colors.primary.text[60]};
+`;
+
+const eyebrowColorSecondary = css`
+ color: ${theme.colors.secondary.text[60]};
+`;
+
+type EyebrowProps = {
+ heading: HeadingType;
+ colorScheme: 'primary' | 'secondary';
+};
+
+export function Eyebrow({ heading, colorScheme }: EyebrowProps) {
+ const colorClassName =
+ colorScheme === 'primary' ? eyebrowColorPrimary : eyebrowColorSecondary;
+
+ return (
+
+
+
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/design-system/components/Eyebrow/types/Eyebrow.ts b/packages/twenty-website-new/src/design-system/components/Eyebrow/types/Eyebrow.ts
new file mode 100644
index 0000000000..b13030e201
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Eyebrow/types/Eyebrow.ts
@@ -0,0 +1,3 @@
+import { HeadingType } from '@/design-system/components/Heading/types/Heading';
+
+export type EyebrowType = { heading: HeadingType };
diff --git a/packages/twenty-website-new/src/design-system/components/Heading/Heading.tsx b/packages/twenty-website-new/src/design-system/components/Heading/Heading.tsx
new file mode 100644
index 0000000000..8e8a97bf46
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Heading/Heading.tsx
@@ -0,0 +1,130 @@
+import { theme } from '@/theme';
+import { css } from '@linaria/core';
+import { styled } from '@linaria/react';
+import { HeadingType } from './types/Heading';
+
+const headingRootClassName = css`
+ margin: 0;
+
+ &[data-weight='light'] {
+ font-weight: ${theme.font.weight.light};
+ }
+
+ &[data-weight='regular'] {
+ font-weight: ${theme.font.weight.regular};
+ }
+
+ &[data-weight='medium'] {
+ font-weight: ${theme.font.weight.medium};
+ }
+
+ &[data-size='xl'] {
+ font-size: ${theme.font.size(15)};
+ line-height: ${theme.lineHeight(16.5)};
+ }
+
+ &[data-size='lg'] {
+ font-size: ${theme.font.size(10)};
+ line-height: ${theme.lineHeight(11.5)};
+ }
+
+ &[data-size='md'] {
+ font-size: ${theme.font.size(10)};
+ line-height: ${theme.lineHeight(11.5)};
+ }
+
+ &[data-size='sm'] {
+ font-size: ${theme.font.size(8)};
+ line-height: ${theme.lineHeight(10)};
+ }
+
+ &[data-size='xs'] {
+ font-size: ${theme.font.size(4.5)};
+ line-height: ${theme.lineHeight(6)};
+ }
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ &[data-size='xl'] {
+ font-size: ${theme.font.size(20)};
+ line-height: ${theme.lineHeight(21.5)};
+ }
+
+ &[data-size='lg'] {
+ font-size: ${theme.font.size(15)};
+ line-height: ${theme.lineHeight(16.5)};
+ }
+
+ &[data-size='md'] {
+ font-size: ${theme.font.size(12)};
+ line-height: ${theme.lineHeight(14)};
+ }
+
+ &[data-size='sm'] {
+ font-size: ${theme.font.size(8)};
+ line-height: ${theme.lineHeight(10)};
+ }
+
+ &[data-size='xs'] {
+ font-size: ${theme.font.size(5.5)};
+ line-height: ${theme.lineHeight(7)};
+ }
+ }
+`;
+
+const StyledSpan = styled.span`
+ &[data-family='sans'] {
+ font-family: ${theme.font.family.sans};
+ letter-spacing: -0.02em;
+ }
+
+ &[data-family='serif'] {
+ font-family: ${theme.font.family.serif};
+ letter-spacing: 0;
+ }
+
+ &[data-family='mono'] {
+ font-family: ${theme.font.family.mono};
+ letter-spacing: -0.02em;
+ }
+`;
+
+export type HeadingAs = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
+export type HeadingFamily = 'sans' | 'serif' | 'mono';
+export type HeadingWeight = 'light' | 'regular' | 'medium';
+export type HeadingSize = 'xl' | 'lg' | 'md' | 'sm' | 'xs';
+
+export type HeadingProps = {
+ as?: HeadingAs;
+ segments: HeadingType | HeadingType[];
+ weight?: HeadingWeight;
+ size?: HeadingSize;
+ className?: string;
+};
+
+export function Heading({
+ as: Tag = 'h1',
+ segments,
+ weight = 'regular',
+ size = 'md',
+ className,
+}: HeadingProps) {
+ const rootClassName = [headingRootClassName, className]
+ .filter(Boolean)
+ .join(' ');
+
+ return (
+
+ {Array.isArray(segments) ? (
+ segments.map((segment, index) => (
+
+ {segment.text}
+
+ ))
+ ) : (
+
+ {segments.text}
+
+ )}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/design-system/components/Heading/types/Heading.ts b/packages/twenty-website-new/src/design-system/components/Heading/types/Heading.ts
new file mode 100644
index 0000000000..ff36e8b77f
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Heading/types/Heading.ts
@@ -0,0 +1,4 @@
+export type HeadingType = {
+ fontFamily: 'sans' | 'serif' | 'mono';
+ text: string;
+}
\ No newline at end of file
diff --git a/packages/twenty-website-new/src/design-system/components/IconButton/IconButton.tsx b/packages/twenty-website-new/src/design-system/components/IconButton/IconButton.tsx
new file mode 100644
index 0000000000..8d63e38869
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/IconButton/IconButton.tsx
@@ -0,0 +1,68 @@
+import type { ComponentType } from "react";
+import { theme } from "@/theme";
+import { styled } from "@linaria/react";
+
+type IconComponent =
+ | ComponentType<{ size: number; fillColor: string }>
+ | ComponentType<{ size: number; strokeColor: string }>;
+
+interface IconButtonProps {
+ icon: IconComponent;
+ ariaLabel: string;
+ borderColor: string;
+ iconFillColor: string;
+ iconSize: number;
+ iconStrokeColor: string;
+ size: number;
+ onClick?: (e: React.MouseEvent) => void;
+ ariaExpanded?: boolean;
+}
+
+const StyledButton = styled.button<{ size: number; borderColor: string }>`
+ align-items: center;
+ background: transparent;
+ border: 1px solid ${(p) => p.borderColor};
+ border-radius: ${theme.radius(2)};
+ cursor: pointer;
+ display: inline-flex;
+ height: ${(p) => p.size}px;
+ justify-content: center;
+ margin: 0;
+ padding: 0;
+ width: ${(p) => p.size}px;
+
+ &:focus-visible {
+ outline: 1px solid ${theme.colors.highlight[100]};
+ outline-offset: 1px;
+ }
+`;
+
+export function IconButton({
+ icon: Icon,
+ ariaLabel,
+ borderColor,
+ iconFillColor,
+ iconSize,
+ iconStrokeColor,
+ size,
+ onClick,
+ ariaExpanded,
+}: IconButtonProps) {
+ return (
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/design-system/components/Illustration/types/Illustration.ts b/packages/twenty-website-new/src/design-system/components/Illustration/types/Illustration.ts
new file mode 100644
index 0000000000..58ca3171a3
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Illustration/types/Illustration.ts
@@ -0,0 +1,4 @@
+export type IllustrationType = {
+ src: string;
+ title: string;
+};
diff --git a/packages/twenty-website-new/src/design-system/components/Image/Image.tsx b/packages/twenty-website-new/src/design-system/components/Image/Image.tsx
new file mode 100644
index 0000000000..732836e86a
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Image/Image.tsx
@@ -0,0 +1,26 @@
+import NextImage from 'next/image';
+import { styled } from '@linaria/react';
+import type { ImageType } from './types/Image';
+
+const ImageRoot = styled.div`
+ aspect-ratio: 16 / 9;
+ overflow: hidden;
+ position: relative;
+ width: 100%;
+`;
+
+export type ImageComponentProps = ImageType & { className?: string };
+
+export function Image({ alt, className, src }: ImageComponentProps) {
+ return (
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/design-system/components/Image/types/Image.ts b/packages/twenty-website-new/src/design-system/components/Image/types/Image.ts
new file mode 100644
index 0000000000..5403c61dbc
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/Image/types/Image.ts
@@ -0,0 +1,4 @@
+export type ImageType = {
+ alt: string;
+ src: string;
+};
diff --git a/packages/twenty-website-new/src/design-system/components/index.ts b/packages/twenty-website-new/src/design-system/components/index.ts
new file mode 100644
index 0000000000..7a843ec2b3
--- /dev/null
+++ b/packages/twenty-website-new/src/design-system/components/index.ts
@@ -0,0 +1,8 @@
+export { Body } from './Body/Body';
+export { LinkButton } from './Button/LinkButton';
+export { SubmitButton } from './Button/SubmitButton';
+export { Container } from './Container/Container';
+export { Eyebrow } from './Eyebrow/Eyebrow';
+export { Heading } from './Heading/Heading';
+export { IconButton } from './IconButton/IconButton';
+export { Image } from './Image/Image';
diff --git a/packages/twenty-website-new/src/enums/pages.ts b/packages/twenty-website-new/src/enums/pages.ts
new file mode 100644
index 0000000000..ba005c862e
--- /dev/null
+++ b/packages/twenty-website-new/src/enums/pages.ts
@@ -0,0 +1,7 @@
+export enum Pages {
+ Home = "home",
+ Partner = "partner",
+ Pricing = "pricing",
+ Product = "product",
+ WhyTwenty = "whyTwenty",
+ }
\ No newline at end of file
diff --git a/packages/twenty-website-new/src/icons/clients/Flexport.tsx b/packages/twenty-website-new/src/icons/clients/Flexport.tsx
new file mode 100644
index 0000000000..c122350b58
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/clients/Flexport.tsx
@@ -0,0 +1,29 @@
+const FLEXPORT_VIEWBOX_WIDTH = 115;
+const FLEXPORT_VIEWBOX_HEIGHT = 27;
+
+const FLEXPORT_PATH_1 =
+ "M13.462 16.78V.047h5.457v16.034c0 1.13.24 1.394 1.394 1.394h.457l.649 4.423a39 39 0 0 1-3.125.169c-2.981.024-4.832-1.034-4.832-5.289M55.241 6.562l4.23-.336.41 1.274c.84-.793 2.331-1.587 5.528-1.587 5.505 0 6.78 3.87 6.78 8.198 0 4.35-1.395 8.173-7.116 8.173-2.524 0-3.726-.577-4.4-1.202v5.505h-5.456zm11.418 7.765c0-1.851-.336-3.462-2.692-3.462-2.524 0-3.27 1.299-3.27 3.462s.554 3.365 3.27 3.365c2.308-.024 2.692-1.538 2.692-3.365m24.977-7.764 4.23-.337.553 1.659c.698-.938 2.597-1.731 4.856-1.827v5.24c-3.63.024-4.183 1.106-4.183 3.27v7.452h-5.456zm11.154-.505h2.812l.89-3.197 4.206-.914v4.11h3.438v5.241h-3.438v4.568c0 1.081.169 1.634 1.875 1.634h1.563v4.543c-.817.049-1.731.073-2.765.073-4.591 0-6.105-1.467-6.105-5.433v-5.36h-2.476zM0 6.25h2.98v-.312C2.98 1.97 4.472 0 9.592 0c1.347 0 1.587.024 2.26.072v4.423h-1.514c-1.563 0-1.9.385-1.9 1.394v.361h3.414v4.616H8.414V22.02H2.98V10.866H0zm33.294 11.058c-.914.529-1.37.649-3.173.649-2.14 0-2.957-.77-3.222-2.043H37.38c.192-5.553-.264-10.048-7.26-10.048s-8.485 3.87-8.485 8.149c0 4.399 1.466 8.293 8.485 8.293 2.765 0 4.496-.505 6.347-1.707zm-3.318-6.947c2.236 0 2.404 1.057 2.5 2.356h-5.6c.192-1.515.913-2.356 3.1-2.356";
+const FLEXPORT_PATH_2 =
+ "m48.198 22.043-2.669-3.822-2.668 3.822h-6.106l5.721-8.149-5.192-7.332h6.154l2.115 2.981 2.116-2.98h6.226l-5.289 7.307 5.722 8.173zm25.12-7.956c0-5.24 2.404-8.197 8.558-8.197 6.178 0 8.534 2.98 8.534 8.197 0 5.24-2.38 8.22-8.534 8.22-6.154.025-8.558-2.98-8.558-8.22m11.61.168c0-1.971-.504-3.414-3.052-3.414-2.572 0-3.053 1.443-3.053 3.414 0 1.947.505 3.414 3.053 3.414 2.572 0 3.053-1.443 3.053-3.414";
+
+interface FlexportIconProps {
+ size: number;
+ fillColor: string;
+}
+
+export function FlexportIcon({ size, fillColor }: FlexportIconProps) {
+ const height = size * (FLEXPORT_VIEWBOX_HEIGHT / FLEXPORT_VIEWBOX_WIDTH);
+
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/clients/Zapier.tsx b/packages/twenty-website-new/src/icons/clients/Zapier.tsx
new file mode 100644
index 0000000000..49511c64ea
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/clients/Zapier.tsx
@@ -0,0 +1,26 @@
+const ZAPIER_VIEWBOX_WIDTH = 112;
+const ZAPIER_VIEWBOX_HEIGHT = 31;
+
+const ZAPIER_PATH =
+ "m26.105 20.644-.016-.05 9.885-9.05v-4.36H20.115v4.36h9.473l.015.043-9.788 9.057v4.36h16.318v-4.36zM45.87 6.77q-2.744 0-4.473.827a5.87 5.87 0 0 0-2.595 2.274 8.3 8.3 0 0 0-1.089 3.29l4.812.676q.261-1.538 1.044-2.18a3.2 3.2 0 0 1 2.068-.64q1.466 0 2.126.784c.436.522.658 1.245.658 2.198v.475h-4.627q-3.532 0-5.076 1.567t-1.54 4.136q0 2.631 1.54 3.916t3.875 1.277q2.895 0 4.454-1.992a7.4 7.4 0 0 0 1.288-2.744h.174l.664 4.36h4.36V13.952q0-3.423-1.804-5.303t-5.86-1.88m1.525 13.61c-.692.577-1.598.865-2.726.865q-1.395 0-1.938-.489a1.6 1.6 0 0 1-.545-1.24 1.63 1.63 0 0 1 .451-1.203 1.68 1.68 0 0 1 1.24-.452h4.552v.3a2.78 2.78 0 0 1-1.034 2.22M79.899 7.184h-5.151v17.823h5.15zm30.415 0q-2.183 0-3.441 1.541-.903 1.108-1.373 3.271h-.152l-.674-4.812h-4.399v17.82h5.152v-9.138q0-1.728.809-2.65t2.987-.922h1.955v-5.11zm-15.152.583q-1.804-1.074-4.55-1.07-4.324 0-6.768 2.461-2.445 2.463-2.444 6.789a10.8 10.8 0 0 0 1.11 5.037 8 8 0 0 0 3.16 3.329q2.046 1.182 4.869 1.185 2.44 0 4.078-.752a6.56 6.56 0 0 0 2.595-2.05 8.9 8.9 0 0 0 1.41-2.914l-4.438-1.242a4.1 4.1 0 0 1-1.045 1.806q-.752.753-2.52.753-2.1 0-3.133-1.204c-.499-.58-.812-1.408-.95-2.48H98.69q.076-.753.076-1.262v-1.11a9.9 9.9 0 0 0-.9-4.323 6.77 6.77 0 0 0-2.704-2.953m-4.7 3.177q3.135 0 3.554 3.084h-7.389a4.24 4.24 0 0 1 .828-1.883q1.016-1.203 3.008-1.2M77.38.002a2.9 2.9 0 0 0-2.108.81 2.8 2.8 0 0 0-.828 2.088 2.83 2.83 0 0 0 2.935 2.932 2.8 2.8 0 0 0 2.089-.828 2.87 2.87 0 0 0 .807-2.104A2.77 2.77 0 0 0 77.382.004zM66.737 6.696q-2.633 0-4.23 1.653-1.183 1.225-1.736 3.655h-.165l-.673-4.812h-4.4v22.935h5.151v-9.446h.189c.157.63.377 1.242.657 1.827a5.2 5.2 0 0 0 2.05 2.293 6 6 0 0 0 3.044.734q3.236 0 4.927-2.52 1.692-2.52 1.692-7.032 0-4.357-1.636-6.822-1.638-2.465-4.87-2.465m.522 12.914q-.9 1.306-2.82 1.306a3.32 3.32 0 0 1-2.762-1.261q-1-1.256-.998-3.44v-.338q0-2.217.998-3.395t2.762-1.164q1.953 0 2.838 1.24t.885 3.46q.006 2.295-.898 3.592zm-49.436 1.034H0v4.366h17.823z";
+
+interface ZapierIconProps {
+ size: number;
+ fillColor: string;
+}
+
+export function ZapierIcon({ size, fillColor }: ZapierIconProps) {
+ const height = size * (ZAPIER_VIEWBOX_HEIGHT / ZAPIER_VIEWBOX_WIDTH);
+
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/clients/index.ts b/packages/twenty-website-new/src/icons/clients/index.ts
new file mode 100644
index 0000000000..59c58fb04c
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/clients/index.ts
@@ -0,0 +1,13 @@
+import type { ComponentType } from "react";
+import { FlexportIcon } from "./Flexport";
+import { ZapierIcon } from "./Zapier";
+
+export { FlexportIcon } from "./Flexport";
+export { ZapierIcon } from "./Zapier";
+
+export type ClientIconProps = { size: number; fillColor: string };
+
+export const CLIENT_ICONS: Record> = {
+ flexport: FlexportIcon,
+ zapier: ZapierIcon,
+};
diff --git a/packages/twenty-website-new/src/icons/functional/ArrowLeft.tsx b/packages/twenty-website-new/src/icons/functional/ArrowLeft.tsx
new file mode 100644
index 0000000000..9f30d45cf0
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/functional/ArrowLeft.tsx
@@ -0,0 +1,29 @@
+const ARROW_LEFT_PATH =
+ "M.5 5.75H14m-13.5 0L5.75 11M.5 5.75 5.75.5";
+
+interface ArrowLeftIconProps {
+ size: number;
+ strokeColor: string;
+ fillColor?: string;
+}
+
+export function ArrowLeftIcon({ size, strokeColor }: ArrowLeftIconProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/functional/ArrowRight.tsx b/packages/twenty-website-new/src/icons/functional/ArrowRight.tsx
new file mode 100644
index 0000000000..d19ec6d851
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/functional/ArrowRight.tsx
@@ -0,0 +1,29 @@
+const ARROW_RIGHT_PATH =
+ "M14 5.75H.5m13.5 0L8.75.5M14 5.75 8.75 11";
+
+interface ArrowRightIconProps {
+ size: number;
+ strokeColor: string;
+ fillColor?: string;
+}
+
+export function ArrowRightIcon({ size, strokeColor }: ArrowRightIconProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/functional/ArrowRightUp.tsx b/packages/twenty-website-new/src/icons/functional/ArrowRightUp.tsx
new file mode 100644
index 0000000000..b46354651b
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/functional/ArrowRightUp.tsx
@@ -0,0 +1,30 @@
+const ARROW_RIGHT_UP_PATH =
+ "M6.069.5.5 6.068M6.069.5H1.738m4.33 0v4.331";
+
+interface ArrowRightUpIconProps {
+ size: number;
+ strokeColor: string;
+}
+
+export function ArrowRightUpIcon({
+ size,
+ strokeColor,
+}: ArrowRightUpIconProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/functional/Close.tsx b/packages/twenty-website-new/src/icons/functional/Close.tsx
new file mode 100644
index 0000000000..4e4b2300a4
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/functional/Close.tsx
@@ -0,0 +1,26 @@
+const CLOSE_PATH = "m.5.5 9.546 9.546m-9.546 0L10.046.5";
+
+interface CloseIconProps {
+ size: number;
+ strokeColor: string;
+}
+
+export function CloseIcon({ size, strokeColor }: CloseIconProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/functional/Menu.tsx b/packages/twenty-website-new/src/icons/functional/Menu.tsx
new file mode 100644
index 0000000000..b0c37c966e
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/functional/Menu.tsx
@@ -0,0 +1,26 @@
+const MENU_PATH = "M.5.5H14M.5 5.75H14M.5 11H14";
+
+interface MenuIconProps {
+ size: number;
+ strokeColor: string;
+}
+
+export function MenuIcon({ size, strokeColor }: MenuIconProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/functional/Minus.tsx b/packages/twenty-website-new/src/icons/functional/Minus.tsx
new file mode 100644
index 0000000000..d1d5095e02
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/functional/Minus.tsx
@@ -0,0 +1,26 @@
+const MINUS_PATH = "M.5 7.25H14.5";
+
+interface MinusIconProps {
+ size: number;
+ strokeColor: string;
+}
+
+export function MinusIcon({ size, strokeColor }: MinusIconProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/functional/Plus.tsx b/packages/twenty-website-new/src/icons/functional/Plus.tsx
new file mode 100644
index 0000000000..74be5f0ceb
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/functional/Plus.tsx
@@ -0,0 +1,26 @@
+const PLUS_PATH = "M.5 7.25H14M7.25 14V.5";
+
+interface PlusIconProps {
+ size: number;
+ strokeColor: string;
+}
+
+export function PlusIcon({ size, strokeColor }: PlusIconProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/functional/RectangleFill.tsx b/packages/twenty-website-new/src/icons/functional/RectangleFill.tsx
new file mode 100644
index 0000000000..5b27d805f2
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/functional/RectangleFill.tsx
@@ -0,0 +1,18 @@
+interface RectangleFillIconProps {
+ size: number;
+ fillColor: string;
+}
+
+export function RectangleFillIcon({ size, fillColor }: RectangleFillIconProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/functional/RectangleOutline.tsx b/packages/twenty-website-new/src/icons/functional/RectangleOutline.tsx
new file mode 100644
index 0000000000..288ebe0bc4
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/functional/RectangleOutline.tsx
@@ -0,0 +1,29 @@
+interface RectangleOutlineIconProps {
+ size: number;
+ strokeColor: string;
+}
+
+export function RectangleOutlineIcon({
+ size,
+ strokeColor,
+}: RectangleOutlineIconProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/index.ts b/packages/twenty-website-new/src/icons/index.ts
new file mode 100644
index 0000000000..0b42ff0411
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/index.ts
@@ -0,0 +1,15 @@
+export { CLIENT_ICONS, FlexportIcon, ZapierIcon } from "./clients";
+export { ArrowLeftIcon } from "./functional/ArrowLeft";
+export { ArrowRightIcon } from "./functional/ArrowRight";
+export { ArrowRightUpIcon } from "./functional/ArrowRightUp";
+export { CloseIcon } from "./functional/Close";
+export { MenuIcon } from "./functional/Menu";
+export { MinusIcon } from "./functional/Minus";
+export { PlusIcon } from "./functional/Plus";
+export { RectangleFillIcon } from "./functional/RectangleFill";
+export { RectangleOutlineIcon } from "./functional/RectangleOutline";
+export { Logo } from "./logo/Logo";
+export { DiscordIcon } from "./social/Discord";
+export { GitHubIcon } from "./social/GitHub";
+export { LinkedInIcon } from "./social/LinkedIn";
+export { XIcon } from "./social/X";
diff --git a/packages/twenty-website-new/src/icons/informative/Users.tsx b/packages/twenty-website-new/src/icons/informative/Users.tsx
new file mode 100644
index 0000000000..b9ea2ed901
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/informative/Users.tsx
@@ -0,0 +1,29 @@
+const USERS_PATH =
+ "M5.499 9a7.52 7.52 0 0 1 4.492 1.502c.939.694 1.176 1.744.895 2.646h2.523c.28-.014.42-.06.48-.091a1 1 0 0 0-.11-.354 2.8 2.8 0 0 0-.709-.885 2 2 0 0 0-.396-.261.5.5 0 0 0-.175-.057v-2c.72 0 1.382.392 1.85.78.495.412.948.965 1.232 1.554.266.552.487 1.363.113 2.123-.405.824-1.277 1.145-2.2 1.19l-.024.001H8.427v-.153q-.06.004-.121.005H2.692a2.7 2.7 0 0 1-2.49-1.605c-.41-.952-.22-2.135.805-2.893A7.52 7.52 0 0 1 5.499 9m0 2c-1.213 0-2.347.404-3.303 1.11-.136.101-.175.19-.188.245a.4.4 0 0 0 .03.247c.09.205.32.398.654.398h5.614a.7.7 0 0 0 .654-.398.4.4 0 0 0 .03-.248c-.013-.054-.052-.143-.188-.244-.956-.706-2.09-1.11-3.303-1.11m.373-11a3.873 3.873 0 1 1 0 7.747 3.873 3.873 0 0 1 0-7.747m5.387.742a3.132 3.132 0 1 1-.648 6.195V4.799a1.133 1.133 0 0 0 1.78-.926 1.132 1.132 0 0 0-1.78-.928V.81q.315-.067.648-.068M5.872 2a1.873 1.873 0 1 0 0 3.746 1.873 1.873 0 0 0 0-3.746";
+
+interface UsersIconProps {
+ size: number;
+ fillColor: string;
+}
+
+export function UsersIcon({
+ size,
+ fillColor,
+}: UsersIconProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/logo/Logo.tsx b/packages/twenty-website-new/src/icons/logo/Logo.tsx
new file mode 100644
index 0000000000..736d781354
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/logo/Logo.tsx
@@ -0,0 +1,27 @@
+const LOGO_PATH =
+ "M6.822 14.174c0-2.435 1.996-4.411 4.456-4.411h8.574c.125 0 .241.075.293.19a.31.31 0 0 1-.056.344l-1.88 2.023c-.326.35-.787.552-1.27.552H11.3c-.738 0-1.338.594-1.338 1.325v3.336a.78.78 0 0 1-.783.777H7.61a.78.78 0 0 1-.783-.777v-3.36zM33.5 25.553c0 2.434-1.996 4.411-4.456 4.411h-3.642c-2.46 0-4.454-1.977-4.454-4.411v-6.315c0-.43.16-.842.456-1.16l2.124-2.285a.33.33 0 0 1 .355-.081.32.32 0 0 1 .205.295v9.527c0 .73.598 1.322 1.337 1.322h3.6a1.33 1.33 0 0 0 1.337-1.322V14.197c0-.73-.599-1.325-1.337-1.325H24.84c-.481 0-.938.201-1.265.547L11.088 26.856h7.503a.78.78 0 0 1 .784.778v1.552a.78.78 0 0 1-.784.778H8.481a1.655 1.655 0 0 1-1.662-1.644v-.824c0-.412.156-.809.44-1.114l13.999-15.06a4.9 4.9 0 0 1 3.594-1.56h4.189c2.46 0 4.454 1.977 4.454 4.412v11.379z";
+
+interface LogoProps {
+ size: number;
+ fillColor: string;
+ backgroundColor: string;
+}
+
+export function Logo({
+ size,
+ fillColor,
+ backgroundColor,
+}: LogoProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/social/Discord.tsx b/packages/twenty-website-new/src/icons/social/Discord.tsx
new file mode 100644
index 0000000000..73080bc656
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/social/Discord.tsx
@@ -0,0 +1,21 @@
+const DISCORD_PATH =
+ "M10.518.785A10.3 10.3 0 0 0 7.99.001a.04.04 0 0 0-.04.019c-.11.194-.23.448-.315.647a9.5 9.5 0 0 0-2.84 0 7 7 0 0 0-.32-.647.04.04 0 0 0-.041-.02c-.888.153-1.737.421-2.53.785A.04.04 0 0 0 1.888.8C.277 3.206-.165 5.553.05 7.871a.04.04 0 0 0 .017.03A10.3 10.3 0 0 0 3.17 9.469a.04.04 0 0 0 .044-.014q.36-.49.634-1.033a.04.04 0 0 0-.021-.055 7 7 0 0 1-.97-.462.04.04 0 0 1-.003-.066q.098-.073.192-.15a.04.04 0 0 1 .04-.006c2.034.928 4.235.928 6.245 0a.04.04 0 0 1 .04.005q.095.078.193.151a.04.04 0 0 1-.003.066q-.463.27-.97.462a.04.04 0 0 0-.02.055q.28.543.633 1.032a.04.04 0 0 0 .044.015A10.3 10.3 0 0 0 12.355 7.9a.04.04 0 0 0 .016-.03c.26-2.68-.433-5.007-1.837-7.071a.03.03 0 0 0-.016-.015M4.152 6.46c-.612 0-1.117-.562-1.117-1.252s.495-1.253 1.117-1.253c.627 0 1.126.567 1.117 1.253 0 .69-.495 1.252-1.117 1.252m4.129 0c-.613 0-1.117-.562-1.117-1.252s.495-1.253 1.117-1.253c.627 0 1.126.567 1.116 1.253 0 .69-.49 1.252-1.116 1.252";
+
+interface DiscordIconProps {
+ size: number;
+ fillColor: string;
+}
+
+export function DiscordIcon({ size, fillColor }: DiscordIconProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/social/GitHub.tsx b/packages/twenty-website-new/src/icons/social/GitHub.tsx
new file mode 100644
index 0000000000..d50d61c4d5
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/social/GitHub.tsx
@@ -0,0 +1,21 @@
+const GITHUB_PATH =
+ "M6.979 0C3.12 0 0 3.143 0 7.031a7.025 7.025 0 0 0 4.772 6.67c.347.07.474-.151.474-.337 0-.163-.012-.722-.012-1.304-1.941.419-2.345-.838-2.345-.838-.312-.815-.775-1.025-.775-1.025-.635-.43.047-.43.047-.43.705.046 1.074.721 1.074.721.624 1.071 1.63.769 2.034.582.058-.454.243-.768.439-.943-1.548-.163-3.177-.768-3.177-3.469 0-.768.277-1.396.716-1.885-.069-.175-.312-.897.069-1.863 0 0 .59-.186 1.918.722a6.7 6.7 0 0 1 1.745-.233c.589 0 1.19.082 1.745.233 1.329-.908 1.918-.722 1.918-.722.381.966.139 1.688.069 1.863.451.489.717 1.117.717 1.885 0 2.701-1.629 3.295-3.189 3.469.254.222.473.641.473 1.304 0 .943-.011 1.7-.011 1.932 0 .187.127.408.474.338a7.025 7.025 0 0 0 4.772-6.67C13.958 3.143 10.827 0 6.979 0";
+
+interface GitHubIconProps {
+ size: number;
+ fillColor: string;
+}
+
+export function GitHubIcon({ size, fillColor }: GitHubIconProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/social/LinkedIn.tsx b/packages/twenty-website-new/src/icons/social/LinkedIn.tsx
new file mode 100644
index 0000000000..8e775e8716
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/social/LinkedIn.tsx
@@ -0,0 +1,21 @@
+const LINKEDIN_PATH =
+ "M.386 2.375A1.35 1.35 0 0 1 0 1.394c0-.39.129-.732.386-.997Q.772.001 1.38 0c.406 0 .725.133.982.397q.386.397.386.997c0 .399-.13.716-.386.98q-.386.398-.982.398c-.397 0-.738-.133-.995-.397m2.146 1.517V12H.216V3.892zm7.712.801Q11 5.602 11 7.19v4.667H8.8V7.519q0-.802-.375-1.245t-1.01-.444q-.633 0-1.009.444T6.031 7.52v4.338H3.818V3.869h2.213v1.06q.336-.53.906-.838t1.28-.307q1.27 0 2.026.908";
+
+interface LinkedInIconProps {
+ size: number;
+ fillColor: string;
+}
+
+export function LinkedInIcon({ size, fillColor }: LinkedInIconProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/icons/social/X.tsx b/packages/twenty-website-new/src/icons/social/X.tsx
new file mode 100644
index 0000000000..f0eac68307
--- /dev/null
+++ b/packages/twenty-website-new/src/icons/social/X.tsx
@@ -0,0 +1,21 @@
+const X_PATH =
+ "m.03 0 4.83 6.46L0 11.713h1.094L5.35 7.115l3.439 4.598h3.723L7.41 4.89 11.935 0H10.84L6.921 4.235 3.754 0zm1.61.806h1.71l7.553 10.101h-1.71z";
+
+interface XIconProps {
+ size: number;
+ fillColor: string;
+}
+
+export function XIcon({ size, fillColor }: XIconProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Footer/FooterShape.tsx b/packages/twenty-website-new/src/sections/Footer/FooterShape.tsx
new file mode 100644
index 0000000000..af2f31e0f4
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Footer/FooterShape.tsx
@@ -0,0 +1,46 @@
+const FOOTER_SHAPE_PATH =
+ "M0 4a4 4 0 0 1 4-4h344.32c4.197 0 8.369.66 12.361 1.958l49.5 16.084A40 40 0 0 0 422.542 20h517.7c4.293 0 8.559-.691 12.633-2.047l47.785-15.906A40 40 0 0 1 1013.29 0H1356a4 4 0 0 1 4 4v16H0z";
+
+interface FooterShapeProps {
+ fillColor: string;
+}
+
+export function FooterShape({ fillColor }: FooterShapeProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Footer/components/Bottom/Bottom.tsx b/packages/twenty-website-new/src/sections/Footer/components/Bottom/Bottom.tsx
new file mode 100644
index 0000000000..8f9a4ca65e
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Footer/components/Bottom/Bottom.tsx
@@ -0,0 +1,49 @@
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import type { ReactNode } from 'react';
+
+const BottomGrid = styled.div`
+ display: grid;
+ font-size: ${theme.font.size(3)};
+ gap: ${theme.spacing(6)};
+ grid-template-columns: 1fr 1fr;
+ grid-template-rows: auto auto;
+`;
+
+const Copyright = styled.div`
+ color: ${theme.colors.primary.text[100]};
+ font-family: ${theme.font.family.mono};
+ grid-column: 1;
+ grid-row: 2;
+ justify-self: start;
+ text-transform: uppercase;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ grid-row: 1;
+ }
+`;
+
+const Credit = styled.div`
+ color: ${theme.colors.primary.text[100]};
+ font-family: ${theme.font.family.mono};
+ grid-column: 2;
+ grid-row: 2;
+ justify-self: end;
+ text-transform: uppercase;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ grid-column: 1 / -1;
+ }
+`;
+
+type BottomProps = { children?: ReactNode };
+
+export function Bottom({ children }: BottomProps) {
+ return (
+
+ © 2026 – Twenty
+ {children}
+ Design by Ardent.
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Footer/components/Logo/Logo.tsx b/packages/twenty-website-new/src/sections/Footer/components/Logo/Logo.tsx
new file mode 100644
index 0000000000..a0f1252ff2
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Footer/components/Logo/Logo.tsx
@@ -0,0 +1,12 @@
+import { Logo as LogoIcon } from '@/icons';
+import { theme } from '@/theme';
+
+export function Logo() {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Footer/components/Nav/Nav.tsx b/packages/twenty-website-new/src/sections/Footer/components/Nav/Nav.tsx
new file mode 100644
index 0000000000..6a21b727be
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Footer/components/Nav/Nav.tsx
@@ -0,0 +1,198 @@
+import { LinkButton } from '@/design-system/components';
+import { PlusIcon, RectangleFillIcon } from '@/icons';
+import { FOOTER_NAV_GROUPS } from '@/sections/Footer/constants/footer-nav-groups';
+import { theme } from '@/theme';
+import { NavigationMenu } from '@base-ui/react/navigation-menu';
+import { styled } from '@linaria/react';
+import Link from 'next/link';
+import React from 'react';
+
+const FooterNav = styled.nav`
+ margin-top: ${theme.spacing(10)};
+ margin-bottom: ${theme.spacing(10)};
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ display: grid;
+ grid-template-columns: 1fr auto 1fr auto 1fr auto 1fr;
+ }
+`;
+
+const NavDivider = styled.div`
+ align-items: center;
+ display: flex;
+ gap: ${theme.spacing(1.5)};
+ width: 100%;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ flex-direction: column;
+ height: 100%;
+ width: auto;
+ margin-left: ${theme.spacing(7)};
+ margin-right: ${theme.spacing(7)};
+ }
+`;
+
+const NavDividerLine = styled.div`
+ background-color: #1c1c1c1a;
+ flex: 1 1 0%;
+ height: 1px;
+ min-height: 1px;
+ min-width: 0;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ height: auto;
+ min-height: 0;
+ min-width: 1px;
+ width: 1px;
+ }
+`;
+
+const NavGroup = styled.section`
+ margin-top: ${theme.spacing(4)};
+ margin-bottom: ${theme.spacing(4)};
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ margin-top: 0;
+ margin-bottom: ${theme.spacing(7)};
+ }
+`;
+
+const NavGroupTitle = styled.h4`
+ font-size: ${theme.font.size(4)};
+ font-weight: ${theme.font.weight.medium};
+ margin-bottom: ${theme.spacing(2)};
+ line-height: 1.35;
+`;
+
+const NavMenuList = styled(NavigationMenu.List)`
+ display: flex;
+ flex-direction: column;
+ gap: ${theme.spacing(2)};
+ list-style: none;
+ margin: 0;
+ padding: 0;
+`;
+
+const NavLinkHoverIcon = styled.span`
+ display: inline-flex;
+ flex-shrink: 0;
+ min-width: 0;
+ opacity: 0;
+ overflow: hidden;
+ transition:
+ width 0.3s ease-out,
+ opacity 0.3s ease-out;
+ width: 0;
+`;
+
+const NavLink = styled(NavigationMenu.Link)`
+ align-items: center;
+ color: ${theme.colors.primary.text[100]};
+ display: flex;
+ font-size: ${theme.font.size(4)};
+ gap: 0;
+ text-decoration: none;
+ transition: gap 0.3s ease-out;
+
+ &:focus-visible {
+ outline: 1px solid ${theme.colors.highlight[100]};
+ outline-offset: 1px;
+ }
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ &:hover {
+ gap: ${theme.spacing(2)};
+ }
+
+ &:hover ${NavLinkHoverIcon} {
+ opacity: 1;
+ width: 14px;
+ }
+ }
+`;
+
+const Actions = styled.div`
+ align-items: flex-start;
+ display: flex;
+ flex-direction: column;
+ gap: ${theme.spacing(2)};
+ margin-top: ${theme.spacing(8)};
+
+ & > * {
+ width: 126px;
+ }
+`;
+
+export function Nav() {
+ return (
+ }>
+ {FOOTER_NAV_GROUPS.map((group, index) => (
+
+ {index > 0 && (
+
+
+
+
+
+ )}
+
+ {group.title}
+
+ {group.links.map((link) => (
+
+
+ ) : (
+
+ )
+ }
+ >
+
+
+
+ {link.label}
+
+
+ ))}
+
+ {group.showActions && (
+
+
+
+
+ )}
+
+
+ ))}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Footer/components/Root/Root.tsx b/packages/twenty-website-new/src/sections/Footer/components/Root/Root.tsx
new file mode 100644
index 0000000000..a3beadcb71
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Footer/components/Root/Root.tsx
@@ -0,0 +1,68 @@
+import { Container } from '@/design-system/components';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import type { ReactNode } from 'react';
+import { FooterShape } from '../../FooterShape';
+
+const FooterRoot = styled.footer`
+ background-color: ${theme.colors.secondary.background[100]};
+ width: 100%;
+`;
+
+const FooterContainer = styled(Container)`
+ display: flex;
+ flex-direction: column;
+ height: 1280px;
+ position: relative;
+ padding-bottom: ${theme.spacing(4)};
+ padding-left: ${theme.spacing(4)};
+ padding-right: ${theme.spacing(4)};
+
+ @media (min-width: ${theme.breakpoints.lg}px) {
+ padding-bottom: ${theme.spacing(10)};
+ padding-left: ${theme.spacing(10)};
+ padding-right: ${theme.spacing(10)};
+ }
+`;
+
+const FooterBackground = styled.div`
+ position: absolute;
+ z-index: 0;
+`;
+
+const FooterContent = styled.div`
+ margin-top: auto;
+ padding-bottom: ${theme.spacing(12)};
+ padding-top: ${theme.spacing(12)};
+ padding-left: ${theme.spacing(4)};
+ padding-right: ${theme.spacing(4)};
+ position: relative;
+ z-index: 1;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ padding-left: ${theme.spacing(20)};
+ padding-right: ${theme.spacing(20)};
+ padding-top: ${theme.spacing(20)};
+ }
+
+ @media (min-width: ${theme.breakpoints.lg}px) {
+ padding-left: ${theme.spacing(30)};
+ padding-right: ${theme.spacing(30)};
+ }
+`;
+
+type RootProps = { children: ReactNode };
+
+export function Root({ children }: RootProps) {
+ return (
+
+
+
+
+
+ {children}
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Footer/components/Social/Social.tsx b/packages/twenty-website-new/src/sections/Footer/components/Social/Social.tsx
new file mode 100644
index 0000000000..558620aff7
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Footer/components/Social/Social.tsx
@@ -0,0 +1,74 @@
+import { ArrowRightUpIcon } from '@/icons';
+import { SOCIAL_LINKS } from '@/sections/Footer/constants/social-links';
+import { theme } from '@/theme';
+import { Separator } from '@base-ui/react/separator';
+import { styled } from '@linaria/react';
+import React from 'react';
+
+const SocialContainer = styled.nav`
+ align-items: center;
+ display: flex;
+ gap: ${theme.spacing(6)};
+ grid-column: 1 / -1;
+ grid-row: 1;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ grid-column: 2;
+ justify-self: end;
+ }
+`;
+
+const SocialDivider = styled(Separator)`
+ background-color: ${theme.colors.primary.border[40]};
+ border: none;
+ height: 10px;
+ width: 1px;
+`;
+
+const SocialItem = styled.a`
+ align-items: center;
+ color: ${theme.colors.primary.text[100]};
+ display: flex;
+ font-size: ${theme.font.size(3)};
+ font-weight: ${theme.font.weight.medium};
+ gap: ${theme.spacing(3)};
+ line-height: 14px;
+ text-decoration: none;
+
+ &:focus-visible {
+ outline: 1px solid ${theme.colors.highlight[100]};
+ outline-offset: 1px;
+ }
+`;
+
+export function Social() {
+ return (
+
+ {SOCIAL_LINKS.filter((item) => item.showInDrawer).map((item, index) => (
+
+ {index > 0 && }
+
+
+ {item.label}
+ {item.label != null && (
+
+ )}
+
+
+ ))}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Footer/components/index.ts b/packages/twenty-website-new/src/sections/Footer/components/index.ts
new file mode 100644
index 0000000000..d329377e0d
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Footer/components/index.ts
@@ -0,0 +1,7 @@
+import { Bottom } from './Bottom/Bottom';
+import { Logo } from './Logo/Logo';
+import { Nav } from './Nav/Nav';
+import { Root } from './Root/Root';
+import { Social } from './Social/Social';
+
+export const Footer = { Root, Logo, Nav, Social, Bottom };
diff --git a/packages/twenty-website-new/src/sections/Footer/constants/footer-nav-groups.ts b/packages/twenty-website-new/src/sections/Footer/constants/footer-nav-groups.ts
new file mode 100644
index 0000000000..bedffb4990
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Footer/constants/footer-nav-groups.ts
@@ -0,0 +1,47 @@
+export const FOOTER_NAV_GROUPS = [
+ {
+ id: "footer-sitemap",
+ title: "Sitemap",
+ showActions: false,
+ links: [
+ { label: "Home", href: "/", external: false },
+ { label: "Product", href: "/product", external: false },
+ { label: "Pricing", href: "/pricing", external: false },
+ { label: "Partners", href: "/partner", external: false },
+ { label: "Why Twenty", href: "/why-twenty", external: false },
+ ],
+ },
+ {
+ id: "footer-help",
+ title: "Help",
+ showActions: false,
+ links: [
+ { label: "Developers", href: "#", external: false },
+ { label: "FAQ", href: "#", external: false },
+ { label: "Support", href: "#", external: false },
+ { label: "Release Notes", href: "#", external: false },
+ ],
+ },
+ {
+ id: "footer-legal",
+ title: "Legal",
+ showActions: false,
+ links: [
+ { label: "Cookie Policy", href: "#", external: false },
+ { label: "Privacy Policy", href: "#", external: false },
+ { label: "Terms and Conditions", href: "#", external: false },
+ ],
+ },
+ {
+ id: "footer-connect",
+ title: "Connect",
+ showActions: true,
+ links: [
+ {
+ label: "LinkedIn",
+ href: "https://www.linkedin.com/company/twenty",
+ external: true,
+ },
+ ],
+ },
+];
diff --git a/packages/twenty-website-new/src/sections/Footer/constants/nav-items.ts b/packages/twenty-website-new/src/sections/Footer/constants/nav-items.ts
new file mode 100644
index 0000000000..99b8a94aad
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Footer/constants/nav-items.ts
@@ -0,0 +1,6 @@
+export const NAV_ITEMS = [
+ { label: 'Product', href: '/product' },
+ { label: 'Pricing', href: '/pricing' },
+ { label: 'Partners', href: '/partner' },
+ { label: 'Why Twenty', href: '/why-twenty' },
+];
diff --git a/packages/twenty-website-new/src/sections/Footer/constants/social-links.ts b/packages/twenty-website-new/src/sections/Footer/constants/social-links.ts
new file mode 100644
index 0000000000..beaf0ca099
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Footer/constants/social-links.ts
@@ -0,0 +1,37 @@
+import { DiscordIcon, GitHubIcon, LinkedInIcon, XIcon } from "@/icons"
+
+export const SOCIAL_LINKS = [
+ {
+ href: "https://github.com/twentyhq/twenty",
+ icon: GitHubIcon,
+ label: "39.8K",
+ ariaLabel: "GitHub (opens in new tab)",
+ showInDesktop: true,
+ showInDrawer: true,
+ },
+ {
+ href: "https://discord.gg/cx5n4Jzs57",
+ icon: DiscordIcon,
+ label: "5.6K",
+ ariaLabel: "Discord (opens in new tab)",
+ className: "discord-link",
+ showInDesktop: true,
+ showInDrawer: true,
+ },
+ {
+ href: "https://www.linkedin.com/company/twenty",
+ icon: LinkedInIcon,
+ label: undefined,
+ ariaLabel: "LinkedIn (opens in new tab)",
+ showInDesktop: false,
+ showInDrawer: true,
+ },
+ {
+ href: "https://x.com/twentycrm",
+ icon: XIcon,
+ label: undefined,
+ ariaLabel: "X (opens in new tab)",
+ showInDesktop: false,
+ showInDrawer: true,
+ },
+]
diff --git a/packages/twenty-website-new/src/sections/Hero/components/Body/Body.tsx b/packages/twenty-website-new/src/sections/Hero/components/Body/Body.tsx
new file mode 100644
index 0000000000..df7e8cc92b
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Hero/components/Body/Body.tsx
@@ -0,0 +1,46 @@
+import {
+ Body as BaseBody,
+ type BodyProps,
+} from '@/design-system/components/Body/Body';
+import { Pages } from '@/enums/pages';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+
+const BodyContainer = styled.div`
+ color: ${theme.colors.primary.text[60]};
+ margin-top: calc(${theme.spacing(2)} - ${theme.spacing(6)});
+ width: 360px;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ &[data-page=${Pages.Home}] {
+ width: 591px;
+ }
+
+ &[data-page=${Pages.Partner}] {
+ width: 500px;
+ }
+
+ &[data-page=${Pages.Pricing}] {
+ width: 500px;
+ }
+
+ &[data-page=${Pages.Product}] {
+ width: 591px;
+ }
+
+ &[data-page=${Pages.WhyTwenty}] {
+ width: 443px;
+ color: ${theme.colors.secondary.text[100]};
+ }
+ }
+`;
+
+export type HeroBodyProps = BodyProps & { page: Pages };
+
+export function Body({ page, ...bodyProps }: HeroBodyProps) {
+ return (
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Hero/components/Cta/Cta.tsx b/packages/twenty-website-new/src/sections/Hero/components/Cta/Cta.tsx
new file mode 100644
index 0000000000..d20d98b91a
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Hero/components/Cta/Cta.tsx
@@ -0,0 +1,16 @@
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import { ReactNode } from 'react';
+
+const CTAsContainer = styled.div`
+ display: flex;
+ flex-wrap: wrap;
+ gap: ${theme.spacing(4)};
+ justify-content: center;
+`;
+
+export type HeroCtaProps = { children: ReactNode };
+
+export function Cta({ children }: HeroCtaProps) {
+ return {children};
+}
diff --git a/packages/twenty-website-new/src/sections/Hero/components/Heading/Heading.tsx b/packages/twenty-website-new/src/sections/Hero/components/Heading/Heading.tsx
new file mode 100644
index 0000000000..0f3d230580
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Hero/components/Heading/Heading.tsx
@@ -0,0 +1,35 @@
+import {
+ Heading as BaseHeading,
+ type HeadingProps,
+} from '@/design-system/components/Heading/Heading';
+import { Pages } from '@/enums/pages';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+
+const HeadingContainer = styled.div`
+ width: 360px;
+ word-wrap: break-word;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ width: 672px;
+
+ &[data-page=${Pages.WhyTwenty}] {
+ color: ${theme.colors.secondary.text[100]};
+ }
+ }
+`;
+
+export type HeroHeadingProps = HeadingProps & { page: Pages };
+
+export function Heading({
+ page,
+ size = 'lg',
+ weight = 'light',
+ ...props
+}: HeroHeadingProps) {
+ return (
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Hero/components/HomeVisual/HomeVisual.tsx b/packages/twenty-website-new/src/sections/Hero/components/HomeVisual/HomeVisual.tsx
new file mode 100644
index 0000000000..68c41fedcf
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Hero/components/HomeVisual/HomeVisual.tsx
@@ -0,0 +1,55 @@
+import { Image } from '@/design-system/components';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+
+const StyledHomeVisual = styled.div`
+ display: grid;
+ grid-template-columns: 1fr;
+ grid-template-rows: 1fr;
+ margin-top: ${theme.spacing(5)};
+ position: relative;
+ right: calc(${theme.spacing(2)} - ${theme.spacing(6)});
+ width: 100%;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ height: 500px;
+ margin-top: ${theme.spacing(17.5)};
+ overflow: hidden;
+ right: 0;
+ }
+`;
+
+const StyledBackgroundImage = styled(Image)`
+ grid-area: 1 / 1;
+ justify-self: end;
+ width: 98%;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ width: 850px;
+ }
+`;
+
+const StyledForegroundImage = styled(Image)`
+ grid-area: 1 / 1;
+ justify-self: end;
+ margin-right: ${theme.spacing(6.5)};
+ margin-top: ${theme.spacing(20)};
+ width: 98%;
+ z-index: 1;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ justify-self: center;
+ margin-right: ${theme.spacing(40)};
+ margin-top: ${theme.spacing(17.5)};
+ width: 800px;
+ }
+`;
+
+export function HomeVisual() {
+ return (
+
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Hero/components/Illustration/Illustration.tsx b/packages/twenty-website-new/src/sections/Hero/components/Illustration/Illustration.tsx
new file mode 100644
index 0000000000..11eb01c4ea
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Hero/components/Illustration/Illustration.tsx
@@ -0,0 +1,37 @@
+import { IllustrationType } from '@/design-system/components/Illustration/types/Illustration';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+
+const StyledIllustrationContainer = styled.div`
+ margin-top: ${theme.spacing(6)};
+ width: 100%;
+`;
+
+type IllustrationProps = IllustrationType & {
+ backgroundColor: string;
+};
+
+export function Illustration({
+ src,
+ title,
+ backgroundColor,
+}: IllustrationProps) {
+ return (
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Hero/components/Root/Root.tsx b/packages/twenty-website-new/src/sections/Hero/components/Root/Root.tsx
new file mode 100644
index 0000000000..b661e3f555
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Hero/components/Root/Root.tsx
@@ -0,0 +1,35 @@
+import { Container } from '@/design-system/components';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import type { ReactNode } from 'react';
+
+const StyledSection = styled.section`
+ width: 100%;
+`;
+
+const StyledContainer = styled(Container)`
+ display: grid;
+ grid-template-columns: 1fr;
+ justify-items: center;
+ text-align: center;
+ padding-top: ${theme.spacing(7.5)};
+ padding-left: ${theme.spacing(4)};
+ padding-right: ${theme.spacing(4)};
+ row-gap: ${theme.spacing(6)};
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ padding-top: ${theme.spacing(12)};
+ padding-left: ${theme.spacing(10)};
+ padding-right: ${theme.spacing(10)};
+ }
+`;
+
+type RootProps = { backgroundColor: string; children: ReactNode };
+
+export function Root({ backgroundColor, children }: RootProps) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Hero/components/WhyTwentyVisual/WhyTwentyVisual.tsx b/packages/twenty-website-new/src/sections/Hero/components/WhyTwentyVisual/WhyTwentyVisual.tsx
new file mode 100644
index 0000000000..325f018b54
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Hero/components/WhyTwentyVisual/WhyTwentyVisual.tsx
@@ -0,0 +1,42 @@
+import { Image } from '@/design-system/components';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+
+const VisualContainer = styled.div`
+ border-radius: ${theme.radius(1)};
+ height: 462px;
+ overflow: hidden;
+ position: relative;
+ width: 100%;
+`;
+
+const StyledBackground = styled(Image)`
+ aspect-ratio: auto;
+ height: 100%;
+`;
+
+const StyledIframe = styled.iframe`
+ border: none;
+ height: 200%;
+ mix-blend-mode: lighten;
+ position: absolute;
+ top: 50%;
+ left: 51.5%;
+ transform: translate(-50%, -50%);
+ width: 200%;
+`;
+
+export function WhyTwentyVisual() {
+ return (
+
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Hero/components/index.ts b/packages/twenty-website-new/src/sections/Hero/components/index.ts
new file mode 100644
index 0000000000..d6794a31f3
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Hero/components/index.ts
@@ -0,0 +1,17 @@
+import { Body } from './Body/Body';
+import { Cta } from './Cta/Cta';
+import { Heading } from './Heading/Heading';
+import { HomeVisual } from './HomeVisual/HomeVisual';
+import { Illustration } from './Illustration/Illustration';
+import { Root } from './Root/Root';
+import { WhyTwentyVisual } from './WhyTwentyVisual/WhyTwentyVisual';
+
+export const Hero = {
+ Root,
+ Heading,
+ Body,
+ Cta,
+ Illustration,
+ HomeVisual,
+ WhyTwentyVisual,
+};
diff --git a/packages/twenty-website-new/src/sections/Hero/types/HeroData.ts b/packages/twenty-website-new/src/sections/Hero/types/HeroData.ts
new file mode 100644
index 0000000000..d4064ddeeb
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Hero/types/HeroData.ts
@@ -0,0 +1,7 @@
+import { BodyType } from '@/design-system/components/Body/types/Body';
+import { HeadingType } from '@/design-system/components/Heading/types/Heading';
+
+export type HeroDataType = {
+ heading: HeadingType[];
+ body: BodyType;
+};
diff --git a/packages/twenty-website-new/src/sections/Hero/types/index.ts b/packages/twenty-website-new/src/sections/Hero/types/index.ts
new file mode 100644
index 0000000000..4109d51101
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Hero/types/index.ts
@@ -0,0 +1 @@
+export type { HeroDataType } from './HeroData';
diff --git a/packages/twenty-website-new/src/sections/Menu/components/Cta/Cta.tsx b/packages/twenty-website-new/src/sections/Menu/components/Cta/Cta.tsx
new file mode 100644
index 0000000000..d909d74628
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Menu/components/Cta/Cta.tsx
@@ -0,0 +1,34 @@
+import { LinkButton } from '@/design-system/components';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+
+const CtaContainer = styled.div`
+ display: none;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ align-items: center;
+ display: flex;
+ gap: ${theme.spacing(2)};
+ }
+`;
+
+export function Cta() {
+ return (
+
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Menu/components/Drawer/Drawer.tsx b/packages/twenty-website-new/src/sections/Menu/components/Drawer/Drawer.tsx
new file mode 100644
index 0000000000..9ec80247b2
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Menu/components/Drawer/Drawer.tsx
@@ -0,0 +1,166 @@
+import { LinkButton } from '@/design-system/components';
+import { ArrowRightUpIcon } from '@/icons';
+import { NAV_ITEMS } from '@/sections/Menu/constants/nav-items';
+import { SOCIAL_LINKS } from '@/sections/Menu/constants/social-links';
+import { theme } from '@/theme';
+import { Drawer } from '@base-ui/react/drawer';
+import { Separator } from '@base-ui/react/separator';
+import { styled } from '@linaria/react';
+import Link from 'next/link';
+import React from 'react';
+
+const DrawerPopup = styled(Drawer.Popup)`
+ background: ${theme.colors.primary.background[100]};
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ left: 0;
+ overflow-y: auto;
+ padding-bottom: ${theme.spacing(4)};
+ padding-left: ${theme.spacing(4)};
+ padding-right: ${theme.spacing(4)};
+ padding-top: ${theme.spacing(35)};
+ position: fixed;
+ top: 0;
+ width: 100vw;
+ z-index: 90;
+`;
+
+const NavigationContainer = styled.nav`
+ align-items: stretch;
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+ gap: ${theme.spacing(8)};
+ justify-content: center;
+ width: 100%;
+`;
+
+const NavItem = styled(Link)`
+ border-radius: ${theme.radius(2)};
+ color: ${theme.colors.primary.text[100]};
+ display: block;
+ font-family: ${theme.font.family.mono};
+ font-size: ${theme.font.size(8)};
+ font-weight: ${theme.font.weight.light};
+ letter-spacing: 0;
+ line-height: 38px;
+ text-decoration: none;
+ text-transform: uppercase;
+ width: 100%;
+
+ &:focus-visible {
+ outline: 1px solid ${theme.colors.highlight[100]};
+ outline-offset: 1px;
+ }
+`;
+
+const HorizontalSeparator = styled(Separator)`
+ background: repeating-linear-gradient(
+ 90deg,
+ ${theme.colors.primary.border[60]} 0,
+ ${theme.colors.primary.border[60]} 1px,
+ transparent 2px,
+ transparent 4px
+ );
+ border: none;
+ height: 1px;
+ width: 100%;
+`;
+
+const CtaContainer = styled.div`
+ margin-bottom: ${theme.spacing(10)};
+`;
+
+const SocialContainer = styled.div`
+ align-items: center;
+ display: flex;
+ gap: ${theme.spacing(6)};
+`;
+
+const SocialItem = styled.a`
+ align-items: center;
+ border-radius: ${theme.radius(1)};
+ color: ${theme.colors.primary.text[100]};
+ display: flex;
+ font-size: ${theme.font.size(3)};
+ font-weight: ${theme.font.weight.medium};
+ gap: ${theme.spacing(3)};
+ line-height: 14px;
+ text-decoration: none;
+
+ &:focus-visible {
+ outline: 1px solid ${theme.colors.highlight[100]};
+ outline-offset: 1px;
+ }
+`;
+
+const Divider = styled(Separator)`
+ border-left: 1px solid ${theme.colors.primary.border[40]};
+ height: 10px;
+ width: 0px;
+`;
+
+export function MenuDrawer() {
+ return (
+
+
+
+ {NAV_ITEMS.map((item, index) => (
+
+ }
+ >
+ {item.label}
+
+ {index < NAV_ITEMS.length - 1 && (
+
+ )}
+
+ ))}
+
+
+
+
+
+
+
+ {SOCIAL_LINKS.filter((item) => item.showInDrawer).map(
+ (item, index) => (
+
+ {index > 0 && }
+
+
+ {item.label}
+ {item.label && (
+
+ )}
+
+
+ ),
+ )}
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Menu/components/Logo/Logo.tsx b/packages/twenty-website-new/src/sections/Menu/components/Logo/Logo.tsx
new file mode 100644
index 0000000000..396844fa9a
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Menu/components/Logo/Logo.tsx
@@ -0,0 +1,37 @@
+import { Logo as LogoIcon } from '@/icons';
+import { theme } from '@/theme';
+import { Drawer } from '@base-ui/react/drawer';
+import { styled } from '@linaria/react';
+import Link from 'next/link';
+
+const LogoContainer = styled.div`
+ align-items: center;
+ display: flex;
+`;
+
+const LogoLink = styled(Link)`
+ display: flex;
+ text-decoration: none;
+
+ &:focus-visible {
+ outline: 1px solid ${theme.colors.highlight[100]};
+ outline-offset: 1px;
+ }
+`;
+
+export function Logo() {
+ return (
+
+ }
+ >
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Menu/components/Nav/Nav.tsx b/packages/twenty-website-new/src/sections/Menu/components/Nav/Nav.tsx
new file mode 100644
index 0000000000..12b866f525
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Menu/components/Nav/Nav.tsx
@@ -0,0 +1,62 @@
+import { NAV_ITEMS } from '@/sections/Menu/constants/nav-items';
+import { theme } from '@/theme';
+import { NavigationMenu } from '@base-ui/react/navigation-menu';
+import { Separator } from '@base-ui/react/separator';
+import { styled } from '@linaria/react';
+import Link from 'next/link';
+import React from 'react';
+
+const NavList = styled(NavigationMenu.List)`
+ display: none;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ align-items: center;
+ display: flex;
+ gap: ${theme.spacing(8)};
+ }
+`;
+
+const NavLink = styled(NavigationMenu.Link)`
+ color: ${theme.colors.primary.text[100]};
+ font-family: ${theme.font.family.mono};
+ font-size: ${theme.font.size(3)};
+ font-weight: ${theme.font.weight.medium};
+ letter-spacing: 0;
+ text-decoration: none;
+ text-transform: uppercase;
+
+ &:focus-visible {
+ outline: 1px solid ${theme.colors.highlight[100]};
+ outline-offset: 1px;
+ }
+`;
+
+const Divider = styled(Separator)`
+ border-left: 1px solid ${theme.colors.primary.border[40]};
+ height: 10px;
+ width: 0px;
+`;
+
+export function Nav() {
+ return (
+ }>
+
+ {NAV_ITEMS.map((item, index) => (
+
+
+ }>
+ {item.label}
+
+
+ {index < NAV_ITEMS.length - 1 && (
+
+ )}
+
+ ))}
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Menu/components/Root/Root.tsx b/packages/twenty-website-new/src/sections/Menu/components/Root/Root.tsx
new file mode 100644
index 0000000000..e378540192
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Menu/components/Root/Root.tsx
@@ -0,0 +1,87 @@
+'use client';
+
+import { Container, IconButton, LinkButton } from '@/design-system/components';
+import { CloseIcon, MenuIcon } from '@/icons';
+import { theme } from '@/theme';
+import { Drawer } from '@base-ui/react/drawer';
+import { styled } from '@linaria/react';
+import type { ReactNode } from 'react';
+import { useState } from 'react';
+import { CloseDrawerWhenNavigationExpandsEffect } from '../../effect-components/CloseDrawerWhenNavigationExpandsEffect';
+import { MenuDrawer } from '../Drawer/Drawer';
+
+const StyledMenuContainer = styled(Container)`
+ margin-top: ${theme.spacing(4)};
+ position: relative;
+ z-index: 100;
+`;
+
+const StyledNav = styled.nav`
+ align-items: center;
+ background-color: ${theme.colors.primary.background[100]};
+ border-radius: ${theme.radius(2)};
+ display: flex;
+ height: 48px;
+ justify-content: space-between;
+ padding-left: ${theme.spacing(4)};
+ padding-right: ${theme.spacing(4)};
+ width: 100%;
+
+ @media (min-width: ${theme.breakpoints.lg}px) {
+ padding-left: ${theme.spacing(10)};
+ padding-right: ${theme.spacing(10)};
+ }
+`;
+
+const MobileRightContainer = styled.div`
+ align-items: center;
+ display: flex;
+ gap: ${theme.spacing(1)};
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ display: none;
+ }
+`;
+
+type RootProps = { children: ReactNode };
+
+export function Root({ children }: RootProps) {
+ const [isDrawerOpen, setIsDrawerOpen] = useState(false);
+
+ return (
+
+ setIsDrawerOpen(false)}
+ />
+
+
+ {children}
+
+
+ setIsDrawerOpen((prev) => !prev)}
+ />
+
+
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Menu/components/Social/Social.tsx b/packages/twenty-website-new/src/sections/Menu/components/Social/Social.tsx
new file mode 100644
index 0000000000..aaead7fab3
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Menu/components/Social/Social.tsx
@@ -0,0 +1,88 @@
+import { ArrowRightUpIcon } from '@/icons';
+import { SOCIAL_LINKS } from '@/sections/Menu/constants/social-links';
+import { theme } from '@/theme';
+import { Separator } from '@base-ui/react/separator';
+import { styled } from '@linaria/react';
+
+const SocialContainer = styled.nav`
+ display: none;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ align-items: center;
+ display: flex;
+ gap: ${theme.spacing(5)};
+ }
+`;
+
+const SocialLinkItem = styled.div`
+ display: none;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ align-items: center;
+ display: flex;
+ gap: ${theme.spacing(5)};
+
+ &.discord-link {
+ display: none;
+ }
+ }
+
+ @media (min-width: ${theme.breakpoints.lg}px) {
+ &.discord-link {
+ display: flex;
+ }
+ }
+`;
+
+const SocialLink = styled.a`
+ align-items: center;
+ border-radius: ${theme.radius(1)};
+ color: ${theme.colors.primary.text[100]};
+ display: flex;
+ font-size: ${theme.font.size(3)};
+ font-weight: ${theme.font.weight.medium};
+ gap: ${theme.spacing(2)};
+ letter-spacing: 0;
+ text-decoration: none;
+
+ &:focus-visible {
+ outline: 1px solid ${theme.colors.highlight[100]};
+ outline-offset: 1px;
+ }
+`;
+
+const Divider = styled(Separator)`
+ border-left: 1px solid ${theme.colors.primary.border[40]};
+ height: 10px;
+ width: 0px;
+`;
+
+export function Social() {
+ return (
+
+ {SOCIAL_LINKS.filter((item) => item.showInDesktop).map((item, index) => (
+
+ {index > 0 && }
+
+
+ {item.label}
+
+
+
+ ))}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Menu/components/index.ts b/packages/twenty-website-new/src/sections/Menu/components/index.ts
new file mode 100644
index 0000000000..61dc1da0af
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Menu/components/index.ts
@@ -0,0 +1,7 @@
+import { Cta } from './Cta/Cta';
+import { Logo } from './Logo/Logo';
+import { Nav } from './Nav/Nav';
+import { Root } from './Root/Root';
+import { Social } from './Social/Social';
+
+export const Menu = { Root, Logo, Nav, Social, Cta };
diff --git a/packages/twenty-website-new/src/sections/Menu/constants/nav-items.ts b/packages/twenty-website-new/src/sections/Menu/constants/nav-items.ts
new file mode 100644
index 0000000000..99b8a94aad
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Menu/constants/nav-items.ts
@@ -0,0 +1,6 @@
+export const NAV_ITEMS = [
+ { label: 'Product', href: '/product' },
+ { label: 'Pricing', href: '/pricing' },
+ { label: 'Partners', href: '/partner' },
+ { label: 'Why Twenty', href: '/why-twenty' },
+];
diff --git a/packages/twenty-website-new/src/sections/Menu/constants/social-links.ts b/packages/twenty-website-new/src/sections/Menu/constants/social-links.ts
new file mode 100644
index 0000000000..beaf0ca099
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Menu/constants/social-links.ts
@@ -0,0 +1,37 @@
+import { DiscordIcon, GitHubIcon, LinkedInIcon, XIcon } from "@/icons"
+
+export const SOCIAL_LINKS = [
+ {
+ href: "https://github.com/twentyhq/twenty",
+ icon: GitHubIcon,
+ label: "39.8K",
+ ariaLabel: "GitHub (opens in new tab)",
+ showInDesktop: true,
+ showInDrawer: true,
+ },
+ {
+ href: "https://discord.gg/cx5n4Jzs57",
+ icon: DiscordIcon,
+ label: "5.6K",
+ ariaLabel: "Discord (opens in new tab)",
+ className: "discord-link",
+ showInDesktop: true,
+ showInDrawer: true,
+ },
+ {
+ href: "https://www.linkedin.com/company/twenty",
+ icon: LinkedInIcon,
+ label: undefined,
+ ariaLabel: "LinkedIn (opens in new tab)",
+ showInDesktop: false,
+ showInDrawer: true,
+ },
+ {
+ href: "https://x.com/twentycrm",
+ icon: XIcon,
+ label: undefined,
+ ariaLabel: "X (opens in new tab)",
+ showInDesktop: false,
+ showInDrawer: true,
+ },
+]
diff --git a/packages/twenty-website-new/src/sections/Menu/effect-components/CloseDrawerWhenNavigationExpandsEffect.tsx b/packages/twenty-website-new/src/sections/Menu/effect-components/CloseDrawerWhenNavigationExpandsEffect.tsx
new file mode 100644
index 0000000000..a3fc92c70b
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Menu/effect-components/CloseDrawerWhenNavigationExpandsEffect.tsx
@@ -0,0 +1,31 @@
+"use client";
+
+import { useEffect } from "react";
+import { theme } from "@/theme";
+
+interface CloseDrawerWhenNavigationExpandsEffectProps {
+ onClose: () => void;
+}
+
+/**
+ * Subscribes to viewport changes and calls onClose whenever the layout
+ * crosses into the desktop breakpoint, so the drawer closes when the full
+ * navigation is shown.
+ */
+export function CloseDrawerWhenNavigationExpandsEffect({
+ onClose,
+}: CloseDrawerWhenNavigationExpandsEffectProps) {
+ useEffect(() => {
+ const mediaQuery = window.matchMedia(`(min-width: ${theme.breakpoints.md}px)`);
+
+ const handleChange = () => {
+ if (mediaQuery.matches) onClose();
+ };
+
+ mediaQuery.addEventListener("change", handleChange);
+
+ return () => mediaQuery.removeEventListener("change", handleChange);
+ }, [onClose]);
+
+ return null;
+}
diff --git a/packages/twenty-website-new/src/sections/Problem/components/Content/Content.tsx b/packages/twenty-website-new/src/sections/Problem/components/Content/Content.tsx
new file mode 100644
index 0000000000..d3af83bf9e
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Problem/components/Content/Content.tsx
@@ -0,0 +1,25 @@
+import { theme } from "@/theme";
+import { styled } from "@linaria/react";
+import type { ReactNode } from "react";
+
+const StyledContent = styled.div`
+ display: grid;
+ grid-template-columns: 1fr;
+ row-gap: ${theme.spacing(10)};
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ padding-bottom: ${theme.spacing(15)};
+ padding-left: ${theme.spacing(15)};
+ padding-right: ${theme.spacing(15)};
+ padding-top: ${theme.spacing(15)};
+ row-gap: ${theme.spacing(20)};
+ }
+`;
+
+type ContentProps = {
+ children: ReactNode;
+};
+
+export function Content({ children }: ContentProps) {
+ return {children};
+}
diff --git a/packages/twenty-website-new/src/sections/Problem/components/Heading/Heading.tsx b/packages/twenty-website-new/src/sections/Problem/components/Heading/Heading.tsx
new file mode 100644
index 0000000000..3abadc02a2
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Problem/components/Heading/Heading.tsx
@@ -0,0 +1,31 @@
+import {
+ Heading as BaseHeading,
+ type HeadingProps,
+} from "@/design-system/components/Heading/Heading";
+import { theme } from "@/theme";
+import { css } from "@linaria/core";
+
+const problemHeadingClassName = css`
+ margin-top: calc(${theme.spacing(2)} - ${theme.spacing(10)});
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ margin-top: calc(${theme.spacing(2)} - ${theme.spacing(16)});
+ }
+`;
+
+export function Heading({
+ as = "h2",
+ size = "md",
+ weight = "light",
+ ...props
+}: HeadingProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Problem/components/Points/Points.tsx b/packages/twenty-website-new/src/sections/Problem/components/Points/Points.tsx
new file mode 100644
index 0000000000..5d17463fc2
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Problem/components/Points/Points.tsx
@@ -0,0 +1,51 @@
+import { Body } from '@/design-system/components/Body/Body';
+import { Heading } from '@/design-system/components/Heading/Heading';
+import { ProblemPointType } from '@/sections/Problem/types';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import React from 'react';
+
+const StyledPoints = styled.div`
+ display: grid;
+ grid-template-columns: 1fr;
+ row-gap: ${theme.spacing(6)};
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ max-width: 454px;
+ }
+`;
+
+const StyledDivider = styled.div`
+ height: 0;
+ border-top: 0.75px dashed ${theme.colors.primary.border[80]};
+ width: 100%;
+ opacity: 50%;
+`;
+
+const StyledPoint = styled.div`
+ display: grid;
+ grid-template-columns: 1fr;
+ row-gap: ${theme.spacing(2)};
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ width: 380px;
+ }
+`;
+
+export type PointsProps = { points: ProblemPointType[] };
+
+export function Points({ points }: PointsProps) {
+ return (
+
+ {points.map((point, index) => (
+
+
+
+
+
+
+
+ ))}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Problem/components/Root/Root.tsx b/packages/twenty-website-new/src/sections/Problem/components/Root/Root.tsx
new file mode 100644
index 0000000000..5c2761dbc4
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Problem/components/Root/Root.tsx
@@ -0,0 +1,38 @@
+import { Container } from '@/design-system/components';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import type { ReactNode } from 'react';
+
+const StyledSection = styled.section`
+ width: 100%;
+`;
+
+const StyledContainer = styled(Container)`
+ display: grid;
+ grid-template-columns: 1fr;
+ row-gap: ${theme.spacing(12)};
+ padding-bottom: ${theme.spacing(12)};
+ padding-left: ${theme.spacing(4)};
+ padding-right: ${theme.spacing(4)};
+ padding-top: ${theme.spacing(12)};
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ column-gap: ${theme.spacing(4)};
+ grid-template-columns: 1fr 1fr;
+ padding-left: ${theme.spacing(10)};
+ padding-right: ${theme.spacing(10)};
+ padding-top: ${theme.spacing(10)};
+ padding-bottom: ${theme.spacing(10)};
+ row-gap: ${theme.spacing(20)};
+ }
+`;
+
+type RootProps = { children: ReactNode };
+
+export function Root({ children }: RootProps) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Problem/components/Visual/Visual.tsx b/packages/twenty-website-new/src/sections/Problem/components/Visual/Visual.tsx
new file mode 100644
index 0000000000..7b2eb49ff7
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Problem/components/Visual/Visual.tsx
@@ -0,0 +1,55 @@
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+
+const DESKTOP_PATH =
+ 'M672 395.498V701a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h664a4 4 0 0 1 4 4v65.155c0 2.363-.837 4.65-2.361 6.454l-23.603 27.936a10 10 0 0 0-2.362 6.453v242.614c0 2.245.756 4.424 2.145 6.188l24.036 30.51a10 10 0 0 1 2.145 6.188';
+
+const MOBILE_PATH =
+ 'M360 214.218v165.689a2.093 2.093 0 0 1-2.093 2.093H2.093A2.093 2.093 0 0 1 0 379.907V2.093C0 .937.937 0 2.093 0h355.814C359.063 0 360 .937 360 2.093v35.463a5.23 5.23 0 0 1-1.217 3.355l-12.741 15.252a5.23 5.23 0 0 0-1.216 3.354v131.624a5.23 5.23 0 0 0 1.104 3.215l12.966 16.646a5.24 5.24 0 0 1 1.104 3.216';
+
+const desktopMask = `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 672 705' preserveAspectRatio='none'%3E%3Cpath d='${encodeURIComponent(DESKTOP_PATH)}' fill='black'/%3E%3C/svg%3E")`;
+
+const mobileMask = `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 360 382' preserveAspectRatio='none'%3E%3Cpath d='${encodeURIComponent(MOBILE_PATH)}' fill='black'/%3E%3C/svg%3E")`;
+
+const StyledVisual = styled.div`
+ min-height: 382px;
+ width: 100%;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ min-height: 0;
+ }
+`;
+
+const StyledMasked = styled.div`
+ background-color: ${theme.colors.secondary.background[100]};
+ height: 100%;
+ mask-image: ${mobileMask};
+ mask-repeat: no-repeat;
+ mask-size: 100% 100%;
+ width: 100%;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ mask-image: ${desktopMask};
+ }
+`;
+
+const StyledImage = styled.img`
+ display: block;
+ height: 100%;
+ object-fit: cover;
+ width: 100%;
+`;
+
+export function Visual() {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/Problem/components/index.ts b/packages/twenty-website-new/src/sections/Problem/components/index.ts
new file mode 100644
index 0000000000..b70481f2a4
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Problem/components/index.ts
@@ -0,0 +1,13 @@
+import { Content } from "./Content/Content";
+import { Heading } from "./Heading/Heading";
+import { Points } from "./Points/Points";
+import { Root } from "./Root/Root";
+import { Visual } from "./Visual/Visual";
+
+export const Problem = {
+ Root,
+ Visual,
+ Content,
+ Heading,
+ Points,
+};
diff --git a/packages/twenty-website-new/src/sections/Problem/types/ProblemData.ts b/packages/twenty-website-new/src/sections/Problem/types/ProblemData.ts
new file mode 100644
index 0000000000..28406dbcbf
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Problem/types/ProblemData.ts
@@ -0,0 +1,9 @@
+import { EyebrowType } from '@/design-system/components/Eyebrow/types/Eyebrow';
+import { HeadingType } from '@/design-system/components/Heading/types/Heading';
+import { ProblemPointType } from './ProblemPoint';
+
+export type ProblemDataType = {
+ eyebrow: EyebrowType;
+ heading: HeadingType[];
+ points: ProblemPointType[];
+};
diff --git a/packages/twenty-website-new/src/sections/Problem/types/ProblemPoint.ts b/packages/twenty-website-new/src/sections/Problem/types/ProblemPoint.ts
new file mode 100644
index 0000000000..c173af314a
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Problem/types/ProblemPoint.ts
@@ -0,0 +1,4 @@
+import { BodyType } from '@/design-system/components/Body/types/Body';
+import { HeadingType } from '@/design-system/components/Heading/types/Heading';
+
+export type ProblemPointType = { heading: HeadingType; body: BodyType };
diff --git a/packages/twenty-website-new/src/sections/Problem/types/index.ts b/packages/twenty-website-new/src/sections/Problem/types/index.ts
new file mode 100644
index 0000000000..5d303bc14f
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/Problem/types/index.ts
@@ -0,0 +1,2 @@
+export type { ProblemPointType } from "./ProblemPoint";
+export type { ProblemDataType } from './ProblemData'
\ No newline at end of file
diff --git a/packages/twenty-website-new/src/sections/ThreeCards/components/FeatureCard/FeatureCard.tsx b/packages/twenty-website-new/src/sections/ThreeCards/components/FeatureCard/FeatureCard.tsx
new file mode 100644
index 0000000000..140db834ea
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/ThreeCards/components/FeatureCard/FeatureCard.tsx
@@ -0,0 +1,87 @@
+import { Body, Heading } from '@/design-system/components';
+import { RectangleFillIcon } from '@/icons';
+import { ThreeCardsFeatureCardType } from '@/sections/ThreeCards/types';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import Image from 'next/image';
+
+const FeatureCardContainer = styled.div`
+ display: grid;
+ grid-template-columns: 1fr;
+ grid-template-rows: auto auto;
+ background-color: ${theme.colors.primary.background[100]};
+ border: 1px solid ${theme.colors.primary.border[20]};
+ border-radius: ${theme.radius(2)};
+ overflow: hidden;
+ min-width: 0;
+ height: 100%;
+`;
+
+const CardImage = styled.div`
+ width: 100%;
+ height: 508px;
+ background-color: ${theme.colors.primary.border[10]};
+ position: relative;
+ overflow: hidden;
+`;
+
+const CardContent = styled.div`
+ display: grid;
+ grid-template-columns: 1fr;
+ row-gap: ${theme.spacing(4)};
+ padding: ${theme.spacing(4)};
+`;
+
+const CardTitleRow = styled.div`
+ display: grid;
+ grid-template-columns: auto minmax(0, 1fr);
+ align-items: center;
+ column-gap: ${theme.spacing(2)};
+`;
+
+const CardIcon = styled.div`
+ display: grid;
+ place-items: center;
+ width: 22px;
+ height: 22px;
+`;
+
+const HeadingWrap = styled.div`
+ min-width: 0;
+`;
+
+type FeatureCardProps = { featureCard: ThreeCardsFeatureCardType };
+
+export function FeatureCard({ featureCard }: FeatureCardProps) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/ThreeCards/components/FeatureCards/FeatureCards.tsx b/packages/twenty-website-new/src/sections/ThreeCards/components/FeatureCards/FeatureCards.tsx
new file mode 100644
index 0000000000..e72a9e4330
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/ThreeCards/components/FeatureCards/FeatureCards.tsx
@@ -0,0 +1,28 @@
+import { ThreeCardsFeatureCardType } from '@/sections/ThreeCards/types';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import { FeatureCard } from '../FeatureCard/FeatureCard';
+
+const FeatureCardsGrid = styled.div`
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: ${theme.spacing(4)};
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ grid-auto-flow: column;
+ grid-auto-columns: 1fr;
+ grid-template-columns: none;
+ }
+`;
+
+type FeatureCardsProps = { featureCards: ThreeCardsFeatureCardType[] };
+
+export function FeatureCards({ featureCards }: FeatureCardsProps) {
+ return (
+
+ {featureCards.map((featureCard, index) => (
+
+ ))}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/ThreeCards/components/IllustrationCard/CardShape.tsx b/packages/twenty-website-new/src/sections/ThreeCards/components/IllustrationCard/CardShape.tsx
new file mode 100644
index 0000000000..7d09ae132a
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/ThreeCards/components/IllustrationCard/CardShape.tsx
@@ -0,0 +1,46 @@
+const THREE_CARDS_CARD_SHAPE_FILL_PATH =
+ "M0 490V4a4 4 0 0 1 4-4h288.23c.932 0 1.856.163 2.731.48l60.814 22.09c.875.318 1.8.48 2.731.48H439a4 4 0 0 1 4 4V490a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4";
+
+const THREE_CARDS_CARD_SHAPE_STROKE_PATH =
+ "M4 .5h288.23c.874 0 1.74.152 2.561.45l60.813 22.09c.931.338 1.912.51 2.902.51H439a3.5 3.5 0 0 1 3.5 3.5V490a3.5 3.5 0 0 1-3.5 3.5H4A3.5 3.5 0 0 1 .5 490V4A3.5 3.5 0 0 1 4 .5Z";
+
+interface ThreeCardsCardShapeProps {
+ fillColor: string;
+ strokeColor: string;
+}
+
+export function ThreeCardsCardShape({
+ fillColor,
+ strokeColor,
+}: ThreeCardsCardShapeProps) {
+ return (
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/ThreeCards/components/IllustrationCard/IllustrationCard.tsx b/packages/twenty-website-new/src/sections/ThreeCards/components/IllustrationCard/IllustrationCard.tsx
new file mode 100644
index 0000000000..6ec5c2a0ba
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/ThreeCards/components/IllustrationCard/IllustrationCard.tsx
@@ -0,0 +1,127 @@
+import { Body, Heading, IconButton } from '@/design-system/components';
+import { ArrowRightIcon } from '@/icons';
+import { ThreeCardsIllustrationCardType } from '@/sections/ThreeCards/types';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import { ThreeCardsCardShape } from './CardShape';
+
+const IllustrationCardContainer = styled.div`
+ position: relative;
+ display: grid;
+ grid-template-columns: 1fr;
+ grid-template-rows: auto auto auto auto 1fr auto;
+ gap: ${theme.spacing(4)};
+ padding: ${theme.spacing(4)};
+ background-color: ${theme.colors.primary.background[100]};
+ border-radius: ${theme.radius(2)};
+ isolation: isolate;
+ min-width: 0;
+ min-height: 0;
+ height: 100%;
+`;
+
+const CardRule = styled.div`
+ height: 0;
+ border-top: 1px dotted ${theme.colors.primary.border[20]};
+ width: 100%;
+`;
+
+const CardEmbed = styled.iframe`
+ width: 100%;
+ height: 240px;
+ border: none;
+ display: block;
+ overflow: hidden;
+ background-color: ${theme.colors.primary.background[100]};
+ border-radius: ${theme.radius(2)};
+`;
+
+const CardFooter = styled.footer`
+ display: grid;
+ grid-template-columns: auto auto auto 1fr;
+ align-items: start;
+ column-gap: ${theme.spacing(2)};
+`;
+
+const AttributionPipe = styled.span`
+ display: block;
+ width: 0;
+ height: 21px;
+ border-left: 1px solid ${theme.colors.primary.border[20]};
+`;
+
+const FooterTrailingAction = styled.div`
+ justify-self: end;
+`;
+
+const CardBodyCell = styled.div`
+ align-self: start;
+ min-height: 0;
+ min-width: 0;
+`;
+
+type IllustrationCardProps = {
+ illustrationCard: ThreeCardsIllustrationCardType;
+ variant?: 'shaped' | 'simple';
+};
+
+export function IllustrationCard({
+ illustrationCard,
+ variant = 'shaped',
+}: IllustrationCardProps) {
+ return (
+
+ {variant === 'shaped' && (
+
+ )}
+
+
+
+
+
+
+
+
+ {illustrationCard.attribution && (
+
+
+
+
+
+
+
+
+ )}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/ThreeCards/components/IllustrationCards/IllustrationCards.tsx b/packages/twenty-website-new/src/sections/ThreeCards/components/IllustrationCards/IllustrationCards.tsx
new file mode 100644
index 0000000000..571b1bde3c
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/ThreeCards/components/IllustrationCards/IllustrationCards.tsx
@@ -0,0 +1,38 @@
+import { ThreeCardsIllustrationCardType } from '@/sections/ThreeCards/types';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import { IllustrationCard } from '../IllustrationCard/IllustrationCard';
+
+const IllustrationCardsGrid = styled.div`
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: ${theme.spacing(4)};
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ grid-auto-flow: column;
+ grid-auto-columns: 1fr;
+ grid-template-columns: none;
+ }
+`;
+
+type IllustrationCardsProps = {
+ illustrationCards: ThreeCardsIllustrationCardType[];
+ variant?: 'shaped' | 'simple';
+};
+
+export function IllustrationCards({
+ illustrationCards,
+ variant = 'shaped',
+}: IllustrationCardsProps) {
+ return (
+
+ {illustrationCards.map((illustrationCard, index) => (
+
+ ))}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/ThreeCards/components/Intro/Intro.tsx b/packages/twenty-website-new/src/sections/ThreeCards/components/Intro/Intro.tsx
new file mode 100644
index 0000000000..d3107f559b
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/ThreeCards/components/Intro/Intro.tsx
@@ -0,0 +1,44 @@
+import { Pages } from '@/enums/pages';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import type { ReactNode } from 'react';
+
+const StyledIntro = styled.div`
+ display: grid;
+ grid-template-columns: 1fr;
+ row-gap: ${theme.spacing(6)};
+ text-align: start;
+
+ &[data-align='center'] {
+ margin-left: auto;
+ margin-right: auto;
+ justify-items: center;
+ text-align: center;
+ }
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ max-width: 921px;
+
+ &[data-align='center'][data-page=${Pages.Home}] {
+ max-width: 900px;
+ }
+
+ &[data-page=${Pages.Product}] {
+ max-width: 600px;
+ }
+ }
+`;
+
+type IntroProps = {
+ align: 'left' | 'center';
+ page: Pages;
+ children: ReactNode;
+};
+
+export function Intro({ align, page, children }: IntroProps) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/ThreeCards/components/Root/Root.tsx b/packages/twenty-website-new/src/sections/ThreeCards/components/Root/Root.tsx
new file mode 100644
index 0000000000..c2aa571325
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/ThreeCards/components/Root/Root.tsx
@@ -0,0 +1,36 @@
+import { Container } from '@/design-system/components';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import type { ReactNode } from 'react';
+
+const StyledSection = styled.section`
+ width: 100%;
+`;
+
+const StyledContainer = styled(Container)`
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: ${theme.spacing(6)};
+ padding-bottom: ${theme.spacing(22)};
+ padding-left: ${theme.spacing(4)};
+ padding-right: ${theme.spacing(4)};
+ padding-top: ${theme.spacing(12)};
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ gap: ${theme.spacing(20)};
+ padding-left: ${theme.spacing(10)};
+ padding-right: ${theme.spacing(10)};
+ padding-top: ${theme.spacing(20)};
+ padding-bottom: ${theme.spacing(20)};
+ }
+`;
+
+type RootProps = { backgroundColor: string; children: ReactNode };
+
+export function Root({ backgroundColor, children }: RootProps) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/ThreeCards/components/index.ts b/packages/twenty-website-new/src/sections/ThreeCards/components/index.ts
new file mode 100644
index 0000000000..fa7a71bb65
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/ThreeCards/components/index.ts
@@ -0,0 +1,15 @@
+import { Root } from "./Root/Root";
+import { IllustrationCards } from "./IllustrationCards/IllustrationCards";
+import { IllustrationCard } from "./IllustrationCard/IllustrationCard";
+import { FeatureCards } from "./FeatureCards/FeatureCards";
+import { FeatureCard } from "./FeatureCard/FeatureCard";
+import { Intro } from "./Intro/Intro";
+
+export const ThreeCards = {
+ Root,
+ Intro,
+ IllustrationCards,
+ IllustrationCard,
+ FeatureCards,
+ FeatureCard,
+};
diff --git a/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsBase.ts b/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsBase.ts
new file mode 100644
index 0000000000..2c4836dbe3
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsBase.ts
@@ -0,0 +1,7 @@
+import { EyebrowType } from '@/design-system/components/Eyebrow/types/Eyebrow';
+import { HeadingType } from '@/design-system/components/Heading/types/Heading';
+
+export type ThreeCardsBaseDataType = {
+ eyebrow: EyebrowType;
+ heading: HeadingType[];
+};
diff --git a/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsFeatureCard.ts b/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsFeatureCard.ts
new file mode 100644
index 0000000000..09988fefa2
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsFeatureCard.ts
@@ -0,0 +1,7 @@
+import { BodyType } from '@/design-system/components/Body/types/Body';
+import { HeadingType } from '@/design-system/components/Heading/types/Heading';
+
+export type ThreeCardsFeatureCardType = {
+ heading: HeadingType;
+ body: BodyType;
+};
diff --git a/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsFeatureData.ts b/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsFeatureData.ts
new file mode 100644
index 0000000000..e4549be53a
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsFeatureData.ts
@@ -0,0 +1,6 @@
+import { ThreeCardsBaseDataType } from './ThreeCardsBase';
+import { ThreeCardsFeatureCardType } from './ThreeCardsFeatureCard';
+
+export type ThreeCardsFeatureCardsDataType = ThreeCardsBaseDataType & {
+ featureCards: ThreeCardsFeatureCardType[];
+};
diff --git a/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsIllustrationCard.ts b/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsIllustrationCard.ts
new file mode 100644
index 0000000000..e3e4e8e429
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsIllustrationCard.ts
@@ -0,0 +1,10 @@
+import { BodyType } from '@/design-system/components/Body/types/Body';
+import { HeadingType } from '@/design-system/components/Heading/types/Heading';
+import { ThreeCardsIllustrationCardAttributionType } from './ThreeCardsIllustrationCardAttribution';
+
+export type ThreeCardsIllustrationCardType = {
+ heading: HeadingType;
+ body: BodyType;
+ benefits?: BodyType[];
+ attribution?: ThreeCardsIllustrationCardAttributionType;
+};
diff --git a/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsIllustrationCardAttribution.ts b/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsIllustrationCardAttribution.ts
new file mode 100644
index 0000000000..21accd106b
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsIllustrationCardAttribution.ts
@@ -0,0 +1,6 @@
+import { BodyType } from '@/design-system/components/Body/types/Body';
+
+export type ThreeCardsIllustrationCardAttributionType = {
+ role: BodyType;
+ company: BodyType;
+};
diff --git a/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsIllustrationData.ts b/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsIllustrationData.ts
new file mode 100644
index 0000000000..3fdeedf12b
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/ThreeCards/types/ThreeCardsIllustrationData.ts
@@ -0,0 +1,8 @@
+import { BodyType } from '@/design-system/components/Body/types/Body';
+import { ThreeCardsBaseDataType } from './ThreeCardsBase';
+import { ThreeCardsIllustrationCardType } from './ThreeCardsIllustrationCard';
+
+export type ThreeCardsIllustrationDataType = ThreeCardsBaseDataType & {
+ body: BodyType;
+ illustrationCards: ThreeCardsIllustrationCardType[];
+};
diff --git a/packages/twenty-website-new/src/sections/ThreeCards/types/index.ts b/packages/twenty-website-new/src/sections/ThreeCards/types/index.ts
new file mode 100644
index 0000000000..f519875060
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/ThreeCards/types/index.ts
@@ -0,0 +1,6 @@
+export type { ThreeCardsBaseDataType } from "./ThreeCardsBase";
+export type { ThreeCardsIllustrationCardAttributionType } from "./ThreeCardsIllustrationCardAttribution";
+export type { ThreeCardsIllustrationCardType } from "./ThreeCardsIllustrationCard";
+export type { ThreeCardsIllustrationDataType } from "./ThreeCardsIllustrationData";
+export type { ThreeCardsFeatureCardType } from "./ThreeCardsFeatureCard";
+export type { ThreeCardsFeatureCardsDataType } from "./ThreeCardsFeatureData";
diff --git a/packages/twenty-website-new/src/sections/TrustedBy/components/ClientCount/ClientCount.tsx b/packages/twenty-website-new/src/sections/TrustedBy/components/ClientCount/ClientCount.tsx
new file mode 100644
index 0000000000..a5e99c15a2
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/TrustedBy/components/ClientCount/ClientCount.tsx
@@ -0,0 +1,68 @@
+import { UsersIcon } from "@/icons/informative/Users";
+import { theme } from "@/theme";
+import { styled } from "@linaria/react";
+import { ClientCountShape } from "./ClientCountShape";
+
+const StyledBlock = styled.div`
+ display: flex;
+ align-items: center;
+ gap: ${theme.spacing(2)};
+ padding-top: ${theme.spacing(1)};
+ padding-right: ${theme.spacing(3.75)};
+ padding-bottom: ${theme.spacing(1)};
+ padding-left: ${theme.spacing(1)};
+ border-radius: ${theme.radius(2)};
+ position: relative;
+ overflow: clip;
+ flex-shrink: 0;
+`;
+
+const ShapeWrapper = styled.div`
+ position: absolute;
+ top: 50%;
+ right: 0;
+ transform: translateY(-50%);
+ height: 48px;
+ width: 234px;
+ z-index: 0;
+`;
+
+const IconWrapper = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ height: 40px;
+ background-color: ${theme.colors.primary.text[5]};
+ border-radius: ${theme.radius(1)};
+ position: relative;
+ overflow: clip;
+`;
+
+const StyledText = styled.p`
+ font-weight: ${theme.font.weight.medium};
+ font-size: ${theme.font.size(4)};
+ line-height: ${theme.lineHeight(5.5)};
+ color: ${theme.colors.primary.text[100]};
+ white-space: nowrap;
+ position: relative;
+ z-index: 1;
+`;
+
+type ClientCountProps = {
+ label: string;
+};
+
+export function ClientCount({ label }: ClientCountProps) {
+ return (
+
+
+
+
+
+
+
+ {label}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/TrustedBy/components/ClientCount/ClientCountShape.tsx b/packages/twenty-website-new/src/sections/TrustedBy/components/ClientCount/ClientCountShape.tsx
new file mode 100644
index 0000000000..c92def6c53
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/TrustedBy/components/ClientCount/ClientCountShape.tsx
@@ -0,0 +1,98 @@
+import { styled } from "@linaria/react";
+
+interface ClientCountShapeProps {
+ strokeColor: string;
+}
+
+const LEFT_OUTLINE = "M4 0.5 A3.5 3.5 0 0 0 0.5 4 V44 A3.5 3.5 0 0 0 4 47.5";
+
+const RIGHT_OUTLINE =
+ "M0 0.5 h11 a3.5 3.5 0 0 1 3.5 3.5 v28.523 a5.5 5.5 0 0 1 -1.416 3.684 l-8.547 9.477 a5.5 5.5 0 0 1 -4.084 1.816 H0";
+
+const ShapeContainer = styled.div`
+ display: flex;
+ height: 48px;
+ inset: 0;
+ pointer-events: none;
+ position: absolute;
+ width: 100%;
+ z-index: 0;
+`;
+
+const LeftCap = styled.svg`
+ display: block;
+ flex-shrink: 0;
+`;
+
+const MiddleSegment = styled.svg`
+ display: block;
+ flex-grow: 1;
+ margin: 0 -1px;
+ min-width: 0;
+`;
+
+const RightCap = styled.svg`
+ display: block;
+ flex-shrink: 0;
+`;
+
+export function ClientCountShape({ strokeColor }: ClientCountShapeProps) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/TrustedBy/components/Logo/Logo.tsx b/packages/twenty-website-new/src/sections/TrustedBy/components/Logo/Logo.tsx
new file mode 100644
index 0000000000..cfd4b4b70d
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/TrustedBy/components/Logo/Logo.tsx
@@ -0,0 +1,21 @@
+import { styled } from "@linaria/react";
+import type { ReactNode } from "react";
+
+const StyledLogo = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 140px;
+ height: inherit;
+ position: relative;
+ overflow: clip;
+ flex-shrink: 0;
+`;
+
+type LogoProps = {
+ children: ReactNode;
+}
+
+export function Logo({ children }: LogoProps) {
+ return {children};
+}
diff --git a/packages/twenty-website-new/src/sections/TrustedBy/components/Logos/Logos.tsx b/packages/twenty-website-new/src/sections/TrustedBy/components/Logos/Logos.tsx
new file mode 100644
index 0000000000..f6784c807d
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/TrustedBy/components/Logos/Logos.tsx
@@ -0,0 +1,54 @@
+import { CLIENT_ICONS } from '@/icons';
+import {
+ TrustedByClientCountLabelType,
+ TrustedByLogosType,
+} from '@/sections/TrustedBy/types';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import React from 'react';
+import { ClientCount } from '../ClientCount/ClientCount';
+import { Logo } from '../Logo/Logo';
+
+const StyledLogos = styled.div`
+ align-items: center;
+ display: flex;
+ flex-direction: column;
+ row-gap: ${theme.spacing(4)};
+ justify-content: center;
+ position: relative;
+ width: 100%;
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ flex-direction: row;
+ column-gap: ${theme.spacing(14)};
+ height: 48px;
+ }
+`;
+
+type LogosProps = {
+ clientCountLabel: TrustedByClientCountLabelType;
+ logos: TrustedByLogosType[];
+};
+
+export function Logos({ clientCountLabel, logos }: LogosProps) {
+ return (
+
+ {logos.map((logo, index) => {
+ const IconComponent = CLIENT_ICONS[logo.icon];
+ if (!IconComponent) return null;
+
+ return (
+
+ {index === 1 && }
+
+
+
+
+ );
+ })}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/TrustedBy/components/Root/Root.tsx b/packages/twenty-website-new/src/sections/TrustedBy/components/Root/Root.tsx
new file mode 100644
index 0000000000..6f9283343c
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/TrustedBy/components/Root/Root.tsx
@@ -0,0 +1,37 @@
+import { Container } from '@/design-system/components';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+import type { ReactNode } from 'react';
+
+const StyledSection = styled.section`
+ width: 100%;
+`;
+
+const StyledContainer = styled(Container)`
+ display: flex;
+ flex-direction: column;
+ gap: ${theme.spacing(6)};
+ padding-bottom: ${theme.spacing(12)};
+ padding-left: ${theme.spacing(4)};
+ padding-right: ${theme.spacing(4)};
+ padding-top: ${theme.spacing(12)};
+
+ @media (min-width: ${theme.breakpoints.md}px) {
+ padding-bottom: ${theme.spacing(16)};
+ padding-left: ${theme.spacing(10)};
+ padding-right: ${theme.spacing(10)};
+ padding-top: ${theme.spacing(16)};
+ }
+`;
+
+interface RootProps {
+ children: ReactNode;
+}
+
+export function Root({ children }: RootProps) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/TrustedBy/components/Separator/Separator.tsx b/packages/twenty-website-new/src/sections/TrustedBy/components/Separator/Separator.tsx
new file mode 100644
index 0000000000..d1c0a6ff1f
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/TrustedBy/components/Separator/Separator.tsx
@@ -0,0 +1,56 @@
+import { PlusIcon } from '@/icons';
+import { TrustedBySeparatorType } from '@/sections/TrustedBy/types';
+import { theme } from '@/theme';
+import { styled } from '@linaria/react';
+
+const StyledSeparatorRow = styled.div`
+ display: flex;
+ width: 100%;
+ align-items: center;
+ gap: ${theme.spacing(1.5)};
+`;
+
+const SeparatorIcon = styled.span`
+ display: flex;
+ align-items: center;
+ width: 12px;
+ height: 12px;
+ flex-shrink: 0;
+`;
+
+const SeparatorLine = styled.div`
+ flex-grow: 1;
+ flex-shrink: 0;
+ flex-basis: 0;
+ height: 1px;
+ background-color: ${theme.colors.primary.border[10]};
+`;
+
+const SeparatorText = styled.p`
+ color: ${theme.colors.primary.text[60]};
+ font-size: ${theme.font.size(3)};
+ font-family: ${theme.font.family.mono};
+ font-weight: ${theme.font.weight.medium};
+ text-transform: uppercase;
+ white-space: nowrap;
+ letter-spacing: 0;
+ line-height: ${theme.font.size(4)};
+`;
+
+type SeparatorProps = { separator: TrustedBySeparatorType };
+
+export function Separator({ separator }: SeparatorProps) {
+ return (
+
+
+
+
+
+ {separator.text}
+
+
+
+
+
+ );
+}
diff --git a/packages/twenty-website-new/src/sections/TrustedBy/components/index.ts b/packages/twenty-website-new/src/sections/TrustedBy/components/index.ts
new file mode 100644
index 0000000000..d6e2223dbb
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/TrustedBy/components/index.ts
@@ -0,0 +1,13 @@
+import { Root } from "./Root/Root";
+import { Separator } from "./Separator/Separator";
+import { Logos } from "./Logos/Logos";
+import { Logo } from "./Logo/Logo";
+import { ClientCount } from "./ClientCount/ClientCount";
+
+export const TrustedBy = {
+ Root,
+ Separator,
+ Logos,
+ Logo,
+ ClientCount,
+};
diff --git a/packages/twenty-website-new/src/sections/TrustedBy/types/TrustedByClientCountLabel.ts b/packages/twenty-website-new/src/sections/TrustedBy/types/TrustedByClientCountLabel.ts
new file mode 100644
index 0000000000..c99d17ac80
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/TrustedBy/types/TrustedByClientCountLabel.ts
@@ -0,0 +1,3 @@
+export type TrustedByClientCountLabelType = {
+ text: string;
+}
\ No newline at end of file
diff --git a/packages/twenty-website-new/src/sections/TrustedBy/types/TrustedByData.ts b/packages/twenty-website-new/src/sections/TrustedBy/types/TrustedByData.ts
new file mode 100644
index 0000000000..224baf100c
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/TrustedBy/types/TrustedByData.ts
@@ -0,0 +1,9 @@
+import { TrustedByClientCountLabelType } from "./TrustedByClientCountLabel";
+import { TrustedBySeparatorType } from "./TrustedBySeparator"
+import { TrustedByLogosType } from "./TrustedByLogos";
+
+export type TrustedByDataType = {
+ separator: TrustedBySeparatorType;
+ clientCountLabel: TrustedByClientCountLabelType;
+ logos: TrustedByLogosType[];
+}
\ No newline at end of file
diff --git a/packages/twenty-website-new/src/sections/TrustedBy/types/TrustedByLogos.ts b/packages/twenty-website-new/src/sections/TrustedBy/types/TrustedByLogos.ts
new file mode 100644
index 0000000000..d8d018bbcb
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/TrustedBy/types/TrustedByLogos.ts
@@ -0,0 +1,3 @@
+export type TrustedByLogosType = {
+ icon: string;
+}
\ No newline at end of file
diff --git a/packages/twenty-website-new/src/sections/TrustedBy/types/TrustedBySeparator.ts b/packages/twenty-website-new/src/sections/TrustedBy/types/TrustedBySeparator.ts
new file mode 100644
index 0000000000..846682406d
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/TrustedBy/types/TrustedBySeparator.ts
@@ -0,0 +1,3 @@
+export type TrustedBySeparatorType = {
+ text: string;
+}
\ No newline at end of file
diff --git a/packages/twenty-website-new/src/sections/TrustedBy/types/index.ts b/packages/twenty-website-new/src/sections/TrustedBy/types/index.ts
new file mode 100644
index 0000000000..8e872ea9fb
--- /dev/null
+++ b/packages/twenty-website-new/src/sections/TrustedBy/types/index.ts
@@ -0,0 +1,4 @@
+export type { TrustedByClientCountLabelType } from './TrustedByClientCountLabel'
+export type { TrustedByDataType } from './TrustedByData'
+export type { TrustedBySeparatorType } from './TrustedBySeparator'
+export type { TrustedByLogosType } from './TrustedByLogos'
\ No newline at end of file
diff --git a/packages/twenty-website-new/src/theme/breakpoints.ts b/packages/twenty-website-new/src/theme/breakpoints.ts
new file mode 100644
index 0000000000..eed2a2e5c8
--- /dev/null
+++ b/packages/twenty-website-new/src/theme/breakpoints.ts
@@ -0,0 +1 @@
+export const breakpoints = { md: 921, lg: 1281, maxContent: 1440 };
diff --git a/packages/twenty-website-new/src/theme/colors.ts b/packages/twenty-website-new/src/theme/colors.ts
new file mode 100644
index 0000000000..93353ee935
--- /dev/null
+++ b/packages/twenty-website-new/src/theme/colors.ts
@@ -0,0 +1,47 @@
+export const colors = {
+ primary: {
+ background: { 100: 'var(--color-white-100)' },
+ text: {
+ 100: 'var(--color-black-100)',
+ 80: 'var(--color-black-80)',
+ 60: 'var(--color-black-60)',
+ 40: 'var(--color-black-40)',
+ 20: 'var(--color-black-20)',
+ 10: 'var(--color-black-10)',
+ 5: 'var(--color-black-5)',
+ },
+ border: {
+ 100: 'var(--color-black-100)',
+ 80: 'var(--color-black-80)',
+ 60: 'var(--color-black-60)',
+ 40: 'var(--color-black-40)',
+ 20: 'var(--color-black-20)',
+ 10: 'var(--color-black-10)',
+ 5: 'var(--color-black-5)',
+ },
+ },
+ secondary: {
+ background: {
+ 100: 'var(--color-black-100)',
+ 80: 'var(--color-black-80)',
+ 5: 'var(--color-black-5)',
+ },
+ text: {
+ 100: 'var(--color-white-100)',
+ 80: 'var(--color-white-80)',
+ 60: 'var(--color-white-60)',
+ 40: 'var(--color-white-40)',
+ 20: 'var(--color-white-20)',
+ 10: 'var(--color-white-10)',
+ },
+ border: {
+ 100: 'var(--color-white-100)',
+ 80: 'var(--color-white-80)',
+ 60: 'var(--color-white-60)',
+ 40: 'var(--color-white-40)',
+ 20: 'var(--color-white-20)',
+ 10: 'var(--color-white-10)',
+ },
+ },
+ highlight: { 100: 'var(--color-blue-100)', 70: 'var(--color-blue-70)' },
+};
diff --git a/packages/twenty-website-new/src/theme/css-variables.ts b/packages/twenty-website-new/src/theme/css-variables.ts
new file mode 100644
index 0000000000..bd8e67b1d8
--- /dev/null
+++ b/packages/twenty-website-new/src/theme/css-variables.ts
@@ -0,0 +1,29 @@
+import { css } from "@linaria/core";
+
+export const cssVariables = css`
+ :global(:root) {
+ --color-white-100: #FFFFFF;
+ --color-white-80: #FFFFFFCC;
+ --color-white-60: #FFFFFF99;
+ --color-white-40: #FFFFFF66;
+ --color-white-20: #FFFFFF33;
+ --color-white-10: #FFFFFF1A;
+
+ --color-black-100: #1C1C1C;
+ --color-black-80: #1C1C1CCC;
+ --color-black-60: #1C1C1C99;
+ --color-black-40: #1C1C1C66;
+ --color-black-20: #1C1C1C33;
+ --color-black-10: #1C1C1C1A;
+ --color-black-5: #1C1C1C0D;
+
+ --color-blue-100: #4A38F5;
+ --color-blue-70: #8174F8;
+
+ --radius-base: 2px;
+ --spacing-base: 4px;
+
+ --font-base: 0.25rem;
+ --line-height-base: 0.25rem;
+ }
+`;
diff --git a/packages/twenty-website-new/src/theme/font.ts b/packages/twenty-website-new/src/theme/font.ts
new file mode 100644
index 0000000000..67f39a8c4c
--- /dev/null
+++ b/packages/twenty-website-new/src/theme/font.ts
@@ -0,0 +1,9 @@
+export const font = {
+ family: {
+ sans: 'var(--font-sans), sans-serif',
+ serif: 'var(--font-serif), serif',
+ mono: 'var(--font-mono), monospace',
+ },
+ weight: { light: '300', regular: '400', medium: '500' },
+ size: (multiplier: number) => `calc(var(--font-base) * ${multiplier})`,
+};
diff --git a/packages/twenty-website-new/src/theme/index.ts b/packages/twenty-website-new/src/theme/index.ts
new file mode 100644
index 0000000000..7df3a01ccd
--- /dev/null
+++ b/packages/twenty-website-new/src/theme/index.ts
@@ -0,0 +1,10 @@
+import { breakpoints } from './breakpoints';
+import { colors } from './colors';
+import { font } from './font';
+import { lineHeight } from './line-height';
+import { radius } from './radius';
+import { spacing } from './spacing';
+
+export const theme = { colors, font, spacing, radius, lineHeight, breakpoints };
+
+export type Theme = typeof theme;
diff --git a/packages/twenty-website-new/src/theme/line-height.ts b/packages/twenty-website-new/src/theme/line-height.ts
new file mode 100644
index 0000000000..5dd917cfc0
--- /dev/null
+++ b/packages/twenty-website-new/src/theme/line-height.ts
@@ -0,0 +1,3 @@
+export function lineHeight(multiplier: number): string {
+ return `calc(var(--line-height-base) * ${multiplier})`;
+}
\ No newline at end of file
diff --git a/packages/twenty-website-new/src/theme/radius.ts b/packages/twenty-website-new/src/theme/radius.ts
new file mode 100644
index 0000000000..8bce10f56c
--- /dev/null
+++ b/packages/twenty-website-new/src/theme/radius.ts
@@ -0,0 +1,3 @@
+export function radius(multiplier: number): string {
+ return `calc(var(--radius-base) * ${multiplier})`;
+}
diff --git a/packages/twenty-website-new/src/theme/spacing.ts b/packages/twenty-website-new/src/theme/spacing.ts
new file mode 100644
index 0000000000..c472077cad
--- /dev/null
+++ b/packages/twenty-website-new/src/theme/spacing.ts
@@ -0,0 +1,3 @@
+export function spacing(multiplier: number): string {
+ return `calc(var(--spacing-base) * ${multiplier})`
+}
diff --git a/packages/twenty-website-new/tsconfig.json b/packages/twenty-website-new/tsconfig.json
new file mode 100644
index 0000000000..d3955b31cc
--- /dev/null
+++ b/packages/twenty-website-new/tsconfig.json
@@ -0,0 +1,41 @@
+{
+ "compilerOptions": {
+ "target": "es2020",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ],
+ "paths": {
+ "@/*": [
+ "./src/*"
+ ]
+ }
+ },
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts",
+ ".next/dev/types/**/*.ts"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}
diff --git a/yarn.lock b/yarn.lock
index a4af8d3cca..17c928ef89 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3504,6 +3504,16 @@ __metadata:
languageName: node
linkType: hard
+"@babel/types@npm:^7.26.0":
+ version: 7.29.0
+ resolution: "@babel/types@npm:7.29.0"
+ dependencies:
+ "@babel/helper-string-parser": "npm:^7.27.1"
+ "@babel/helper-validator-identifier": "npm:^7.28.5"
+ checksum: 10c0/23cc3466e83bcbfab8b9bd0edaafdb5d4efdb88b82b3be6728bbade5ba2f0996f84f63b1c5f7a8c0d67efded28300898a5f930b171bb40b311bca2029c4e9b4f
+ languageName: node
+ linkType: hard
+
"@babel/types@npm:^7.28.4, @babel/types@npm:^7.28.5":
version: 7.28.5
resolution: "@babel/types@npm:7.28.5"
@@ -3514,6 +3524,46 @@ __metadata:
languageName: node
linkType: hard
+"@base-ui/react@npm:^1.3.0":
+ version: 1.3.0
+ resolution: "@base-ui/react@npm:1.3.0"
+ dependencies:
+ "@babel/runtime": "npm:^7.28.6"
+ "@base-ui/utils": "npm:0.2.6"
+ "@floating-ui/react-dom": "npm:^2.1.8"
+ "@floating-ui/utils": "npm:^0.2.11"
+ tabbable: "npm:^6.4.0"
+ use-sync-external-store: "npm:^1.6.0"
+ peerDependencies:
+ "@types/react": ^17 || ^18 || ^19
+ react: ^17 || ^18 || ^19
+ react-dom: ^17 || ^18 || ^19
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 10c0/36c9d2d77a82b41cb3783be39340aa0713bbe102fb18213f8f3e2c4f1295beb8359dd97067248bea34925f4a40eab281ddc42f05009179db1d5a7a99e4bfecdc
+ languageName: node
+ linkType: hard
+
+"@base-ui/utils@npm:0.2.6, @base-ui/utils@npm:^0.2.6":
+ version: 0.2.6
+ resolution: "@base-ui/utils@npm:0.2.6"
+ dependencies:
+ "@babel/runtime": "npm:^7.28.6"
+ "@floating-ui/utils": "npm:^0.2.11"
+ reselect: "npm:^5.1.1"
+ use-sync-external-store: "npm:^1.6.0"
+ peerDependencies:
+ "@types/react": ^17 || ^18 || ^19
+ react: ^17 || ^18 || ^19
+ react-dom: ^17 || ^18 || ^19
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 10c0/5611442ac37066774277cd3360d16ebc3f599dc7b8efdfdfbf5b66b6d2eb6e87a18c0f9922b061818850e781d9bbc70aa5fc4ffb1dfd7fb234eefc401e070090
+ languageName: node
+ linkType: hard
+
"@bcoe/v8-coverage@npm:^0.2.3":
version: 0.2.3
resolution: "@bcoe/v8-coverage@npm:0.2.3"
@@ -10770,6 +10820,15 @@ __metadata:
languageName: node
linkType: hard
+"@linaria/core@npm:^7.0.0":
+ version: 7.0.0
+ resolution: "@linaria/core@npm:7.0.0"
+ dependencies:
+ "@wyw-in-js/processor-utils": "npm:^1.0.4"
+ checksum: 10c0/10d760409dc07e5f023eb1cf7207a93ab9be187e82b2117d3bff592598ecef01cc74598c767ca93c2912a1527ff73033c2719b4a9992705c26c58759296741d4
+ languageName: node
+ linkType: hard
+
"@linaria/react@npm:^6.2.1":
version: 6.2.1
resolution: "@linaria/react@npm:6.2.1"
@@ -10788,6 +10847,24 @@ __metadata:
languageName: node
linkType: hard
+"@linaria/react@npm:^7.0.1":
+ version: 7.0.1
+ resolution: "@linaria/react@npm:7.0.1"
+ dependencies:
+ "@emotion/is-prop-valid": "npm:^1.2.0"
+ "@linaria/core": "npm:^7.0.0"
+ "@wyw-in-js/processor-utils": "npm:^1.0.4"
+ "@wyw-in-js/shared": "npm:^1.0.4"
+ minimatch: "npm:^9.0.3"
+ react-html-attributes: "npm:^1.4.6"
+ resolve: "npm:^1.22.8"
+ ts-invariant: "npm:^0.10.3"
+ peerDependencies:
+ react: ">=16"
+ checksum: 10c0/6771d9229de38fe39a01d2d4b331094ad7b9bb9ad00ba4b8469709702e1540eeb090a028abf904528d5399f57f16540d052071916111451a8827792ad6625cb9
+ languageName: node
+ linkType: hard
+
"@lingui/babel-plugin-extract-messages@npm:^5.1.2":
version: 5.1.2
resolution: "@lingui/babel-plugin-extract-messages@npm:5.1.2"
@@ -12845,6 +12922,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/env@npm:16.1.7":
+ version: 16.1.7
+ resolution: "@next/env@npm:16.1.7"
+ checksum: 10c0/89a9e657b29d01be04394cd8a4c917cfdd76aec76ea9a0f7670896efe7668e665713adcf72632958b0c19ce66cf7e1f39961cfd9ba69d10c5a3e08ee20d2370a
+ languageName: node
+ linkType: hard
+
"@next/swc-darwin-arm64@npm:14.2.33":
version: 14.2.33
resolution: "@next/swc-darwin-arm64@npm:14.2.33"
@@ -12859,6 +12943,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-darwin-arm64@npm:16.1.7":
+ version: 16.1.7
+ resolution: "@next/swc-darwin-arm64@npm:16.1.7"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@next/swc-darwin-x64@npm:14.2.33":
version: 14.2.33
resolution: "@next/swc-darwin-x64@npm:14.2.33"
@@ -12873,6 +12964,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-darwin-x64@npm:16.1.7":
+ version: 16.1.7
+ resolution: "@next/swc-darwin-x64@npm:16.1.7"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
"@next/swc-linux-arm64-gnu@npm:14.2.33":
version: 14.2.33
resolution: "@next/swc-linux-arm64-gnu@npm:14.2.33"
@@ -12887,6 +12985,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-linux-arm64-gnu@npm:16.1.7":
+ version: 16.1.7
+ resolution: "@next/swc-linux-arm64-gnu@npm:16.1.7"
+ conditions: os=linux & cpu=arm64 & libc=glibc
+ languageName: node
+ linkType: hard
+
"@next/swc-linux-arm64-musl@npm:14.2.33":
version: 14.2.33
resolution: "@next/swc-linux-arm64-musl@npm:14.2.33"
@@ -12901,6 +13006,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-linux-arm64-musl@npm:16.1.7":
+ version: 16.1.7
+ resolution: "@next/swc-linux-arm64-musl@npm:16.1.7"
+ conditions: os=linux & cpu=arm64 & libc=musl
+ languageName: node
+ linkType: hard
+
"@next/swc-linux-x64-gnu@npm:14.2.33":
version: 14.2.33
resolution: "@next/swc-linux-x64-gnu@npm:14.2.33"
@@ -12915,6 +13027,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-linux-x64-gnu@npm:16.1.7":
+ version: 16.1.7
+ resolution: "@next/swc-linux-x64-gnu@npm:16.1.7"
+ conditions: os=linux & cpu=x64 & libc=glibc
+ languageName: node
+ linkType: hard
+
"@next/swc-linux-x64-musl@npm:14.2.33":
version: 14.2.33
resolution: "@next/swc-linux-x64-musl@npm:14.2.33"
@@ -12929,6 +13048,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-linux-x64-musl@npm:16.1.7":
+ version: 16.1.7
+ resolution: "@next/swc-linux-x64-musl@npm:16.1.7"
+ conditions: os=linux & cpu=x64 & libc=musl
+ languageName: node
+ linkType: hard
+
"@next/swc-win32-arm64-msvc@npm:14.2.33":
version: 14.2.33
resolution: "@next/swc-win32-arm64-msvc@npm:14.2.33"
@@ -12943,6 +13069,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-win32-arm64-msvc@npm:16.1.7":
+ version: 16.1.7
+ resolution: "@next/swc-win32-arm64-msvc@npm:16.1.7"
+ conditions: os=win32 & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@next/swc-win32-ia32-msvc@npm:14.2.33":
version: 14.2.33
resolution: "@next/swc-win32-ia32-msvc@npm:14.2.33"
@@ -12964,6 +13097,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-win32-x64-msvc@npm:16.1.7":
+ version: 16.1.7
+ resolution: "@next/swc-win32-x64-msvc@npm:16.1.7"
+ conditions: os=win32 & cpu=x64
+ languageName: node
+ linkType: hard
+
"@nivo/annotations@npm:0.99.0":
version: 0.99.0
resolution: "@nivo/annotations@npm:0.99.0"
@@ -25204,6 +25344,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/node@npm:^20":
+ version: 20.19.37
+ resolution: "@types/node@npm:20.19.37"
+ dependencies:
+ undici-types: "npm:~6.21.0"
+ checksum: 10c0/8420353aee776ae5c1e9720058949909a0e908fa2af85501e9db2645bb9f9acd7d767890f8aaee34d375e6f8b5f550a9a169e908d2d8cf7d5daf63dce64092a0
+ languageName: node
+ linkType: hard
+
"@types/node@npm:^20.0.0":
version: 20.19.19
resolution: "@types/node@npm:20.19.19"
@@ -27389,6 +27538,16 @@ __metadata:
languageName: node
linkType: hard
+"@wyw-in-js/babel-preset@npm:^0.8.1":
+ version: 0.8.1
+ resolution: "@wyw-in-js/babel-preset@npm:0.8.1"
+ dependencies:
+ "@babel/core": "npm:^7.23.5"
+ "@wyw-in-js/transform": "npm:0.8.1"
+ checksum: 10c0/69adedcf3c49cf4f3c181feae6fb8df26c5168a4e5abf4c47b36c2d01da2a77fde6bab46d4b8111e59d28046fdf04c2c8d5dccdeff677033351be2408ffcb2a3
+ languageName: node
+ linkType: hard
+
"@wyw-in-js/babel-preset@npm:^1.0.6":
version: 1.0.6
resolution: "@wyw-in-js/babel-preset@npm:1.0.6"
@@ -27409,7 +27568,17 @@ __metadata:
languageName: node
linkType: hard
-"@wyw-in-js/processor-utils@npm:1.0.4":
+"@wyw-in-js/processor-utils@npm:0.8.1":
+ version: 0.8.1
+ resolution: "@wyw-in-js/processor-utils@npm:0.8.1"
+ dependencies:
+ "@babel/generator": "npm:^7.23.5"
+ "@wyw-in-js/shared": "npm:0.8.1"
+ checksum: 10c0/40e89fbc6a714f121b54b0201f5ad49409cda1ea522237c4554e50bb378a10f051275f631ce8db534f840173d842835e8db87c332b796f5764983bd89006907b
+ languageName: node
+ linkType: hard
+
+"@wyw-in-js/processor-utils@npm:1.0.4, @wyw-in-js/processor-utils@npm:^1.0.4":
version: 1.0.4
resolution: "@wyw-in-js/processor-utils@npm:1.0.4"
dependencies:
@@ -27472,7 +27641,18 @@ __metadata:
languageName: node
linkType: hard
-"@wyw-in-js/shared@npm:1.0.4":
+"@wyw-in-js/shared@npm:0.8.1":
+ version: 0.8.1
+ resolution: "@wyw-in-js/shared@npm:0.8.1"
+ dependencies:
+ debug: "npm:^4.3.4"
+ find-up: "npm:^5.0.0"
+ minimatch: "npm:^9.0.3"
+ checksum: 10c0/3539fc6179517a0ee33984c68dbc155d824aedd789f321825fd3bb4c67414459c45553690185c968695d4e23628b87bd79031ed935072e4da4f499dea62949e4
+ languageName: node
+ linkType: hard
+
+"@wyw-in-js/shared@npm:1.0.4, @wyw-in-js/shared@npm:^1.0.4":
version: 1.0.4
resolution: "@wyw-in-js/shared@npm:1.0.4"
dependencies:
@@ -27506,6 +27686,29 @@ __metadata:
languageName: node
linkType: hard
+"@wyw-in-js/transform@npm:0.8.1":
+ version: 0.8.1
+ resolution: "@wyw-in-js/transform@npm:0.8.1"
+ dependencies:
+ "@babel/core": "npm:^7.23.5"
+ "@babel/generator": "npm:^7.23.5"
+ "@babel/helper-module-imports": "npm:^7.22.15"
+ "@babel/plugin-transform-modules-commonjs": "npm:^7.23.3"
+ "@babel/template": "npm:^7.22.15"
+ "@babel/traverse": "npm:^7.23.5"
+ "@babel/types": "npm:^7.23.5"
+ "@wyw-in-js/processor-utils": "npm:0.8.1"
+ "@wyw-in-js/shared": "npm:0.8.1"
+ babel-merge: "npm:^3.0.0"
+ cosmiconfig: "npm:^8.0.0"
+ happy-dom: "npm:^20.0.10"
+ source-map: "npm:^0.7.4"
+ stylis: "npm:^4.3.0"
+ ts-invariant: "npm:^0.10.3"
+ checksum: 10c0/8d35bbaeb57164e7002f072e182a0495cc8380d689e7f43c038d19c9fe2d2b78f2b4fe22bde9137c227eccc80e74516f80fb492be93de14065a1c3eea801b95d
+ languageName: node
+ linkType: hard
+
"@wyw-in-js/transform@npm:1.0.6":
version: 1.0.6
resolution: "@wyw-in-js/transform@npm:1.0.6"
@@ -30429,6 +30632,15 @@ __metadata:
languageName: node
linkType: hard
+"babel-plugin-react-compiler@npm:1.0.0":
+ version: 1.0.0
+ resolution: "babel-plugin-react-compiler@npm:1.0.0"
+ dependencies:
+ "@babel/types": "npm:^7.26.0"
+ checksum: 10c0/9406267ada8d7dbdfe8906b40ecadb816a5f4cee2922bee23f7729293b369624ee135b5a9b0f263851c263c9787522ac5d97016c9a2b82d1668300e42b18aff8
+ languageName: node
+ linkType: hard
+
"babel-plugin-syntax-trailing-function-commas@npm:^7.0.0-beta.0":
version: 7.0.0-beta.0
resolution: "babel-plugin-syntax-trailing-function-commas@npm:7.0.0-beta.0"
@@ -30730,6 +30942,15 @@ __metadata:
languageName: node
linkType: hard
+"baseline-browser-mapping@npm:^2.9.19":
+ version: 2.10.11
+ resolution: "baseline-browser-mapping@npm:2.10.11"
+ bin:
+ baseline-browser-mapping: dist/cli.cjs
+ checksum: 10c0/6ae44b653c26de8ea7b75a109c0771c95c9676c32a11aff25f7c10b2ddeb864d2c387243a0ec083dffe3b76a7aacf2d777fa7e5a6df16e3a2624c1573e116285
+ languageName: node
+ linkType: hard
+
"basic-auth@npm:^2.0.1":
version: 2.0.1
resolution: "basic-auth@npm:2.0.1"
@@ -40004,6 +40225,20 @@ __metadata:
languageName: node
linkType: hard
+"happy-dom@npm:^20.0.10":
+ version: 20.8.9
+ resolution: "happy-dom@npm:20.8.9"
+ dependencies:
+ "@types/node": "npm:>=20.0.0"
+ "@types/whatwg-mimetype": "npm:^3.0.2"
+ "@types/ws": "npm:^8.18.1"
+ entities: "npm:^7.0.1"
+ whatwg-mimetype: "npm:^3.0.0"
+ ws: "npm:^8.18.3"
+ checksum: 10c0/12fe9b85891b1289935b2a4f726e2839e7c92e3f55401bd20cb5500763dd994364645acaab20a754fd90d5e1b2ffdf734b39a32ea02704c3e3ee0c4d30cf958e
+ languageName: node
+ linkType: hard
+
"happy-dom@npm:^20.1.0":
version: 20.8.3
resolution: "happy-dom@npm:20.8.3"
@@ -48613,6 +48848,66 @@ __metadata:
languageName: node
linkType: hard
+"next@npm:16.1.7":
+ version: 16.1.7
+ resolution: "next@npm:16.1.7"
+ dependencies:
+ "@next/env": "npm:16.1.7"
+ "@next/swc-darwin-arm64": "npm:16.1.7"
+ "@next/swc-darwin-x64": "npm:16.1.7"
+ "@next/swc-linux-arm64-gnu": "npm:16.1.7"
+ "@next/swc-linux-arm64-musl": "npm:16.1.7"
+ "@next/swc-linux-x64-gnu": "npm:16.1.7"
+ "@next/swc-linux-x64-musl": "npm:16.1.7"
+ "@next/swc-win32-arm64-msvc": "npm:16.1.7"
+ "@next/swc-win32-x64-msvc": "npm:16.1.7"
+ "@swc/helpers": "npm:0.5.15"
+ baseline-browser-mapping: "npm:^2.9.19"
+ caniuse-lite: "npm:^1.0.30001579"
+ postcss: "npm:8.4.31"
+ sharp: "npm:^0.34.4"
+ styled-jsx: "npm:5.1.6"
+ peerDependencies:
+ "@opentelemetry/api": ^1.1.0
+ "@playwright/test": ^1.51.1
+ babel-plugin-react-compiler: "*"
+ react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ sass: ^1.3.0
+ dependenciesMeta:
+ "@next/swc-darwin-arm64":
+ optional: true
+ "@next/swc-darwin-x64":
+ optional: true
+ "@next/swc-linux-arm64-gnu":
+ optional: true
+ "@next/swc-linux-arm64-musl":
+ optional: true
+ "@next/swc-linux-x64-gnu":
+ optional: true
+ "@next/swc-linux-x64-musl":
+ optional: true
+ "@next/swc-win32-arm64-msvc":
+ optional: true
+ "@next/swc-win32-x64-msvc":
+ optional: true
+ sharp:
+ optional: true
+ peerDependenciesMeta:
+ "@opentelemetry/api":
+ optional: true
+ "@playwright/test":
+ optional: true
+ babel-plugin-react-compiler:
+ optional: true
+ sass:
+ optional: true
+ bin:
+ next: dist/bin/next
+ checksum: 10c0/f6cebb3ce57d267cd92fb364b56710004c883baafea9cfed36434c0cd51db74299d59094ab782674d9813f10ce2891b633bc6d94e7e38aa9af7a1870194818d0
+ languageName: node
+ linkType: hard
+
"next@npm:^14, next@npm:^14.2.25":
version: 14.2.35
resolution: "next@npm:14.2.35"
@@ -52966,7 +53261,7 @@ __metadata:
languageName: node
linkType: hard
-"react-dom@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0":
+"react-dom@npm:19.2.3, react-dom@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0":
version: 19.2.3
resolution: "react-dom@npm:19.2.3"
dependencies:
@@ -53589,7 +53884,7 @@ __metadata:
languageName: node
linkType: hard
-"react@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0":
+"react@npm:19.2.3, react@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0":
version: 19.2.3
resolution: "react@npm:19.2.3"
checksum: 10c0/094220b3ba3a76c1b668f972ace1dd15509b157aead1b40391d1c8e657e720c201d9719537375eff08f5e0514748c0319063392a6f000e31303aafc4471f1436
@@ -54567,6 +54862,13 @@ __metadata:
languageName: node
linkType: hard
+"reselect@npm:^5.1.1":
+ version: 5.1.1
+ resolution: "reselect@npm:5.1.1"
+ checksum: 10c0/219c30da122980f61853db3aebd173524a2accd4b3baec770e3d51941426c87648a125ca08d8c57daa6b8b086f2fdd2703cb035dd6231db98cdbe1176a71f489
+ languageName: node
+ linkType: hard
+
"resize-observer-polyfill@npm:^1.5.1":
version: 1.5.1
resolution: "resize-observer-polyfill@npm:1.5.1"
@@ -57999,6 +58301,13 @@ __metadata:
languageName: node
linkType: hard
+"tabbable@npm:^6.4.0":
+ version: 6.4.0
+ resolution: "tabbable@npm:6.4.0"
+ checksum: 10c0/d931427f4a96b801fd8801ba296a702119e06f70ad262fed8abc5271225c9f1ca51b89fdec4fb2f22e1d35acb3d2881db0a17cedc758272e9ecb540d00299d76
+ languageName: node
+ linkType: hard
+
"tailwind-merge@npm:^2.5.5":
version: 2.6.0
resolution: "tailwind-merge@npm:2.6.0"
@@ -59720,6 +60029,26 @@ __metadata:
languageName: unknown
linkType: soft
+"twenty-website-new@workspace:packages/twenty-website-new":
+ version: 0.0.0-use.local
+ resolution: "twenty-website-new@workspace:packages/twenty-website-new"
+ dependencies:
+ "@base-ui/react": "npm:^1.3.0"
+ "@base-ui/utils": "npm:^0.2.6"
+ "@linaria/core": "npm:^7.0.0"
+ "@linaria/react": "npm:^7.0.1"
+ "@types/node": "npm:^20"
+ "@types/react": "npm:^19"
+ "@types/react-dom": "npm:^19"
+ "@wyw-in-js/babel-preset": "npm:^0.8.1"
+ babel-plugin-react-compiler: "npm:1.0.0"
+ next: "npm:16.1.7"
+ next-with-linaria: "npm:^1.3.0"
+ react: "npm:19.2.3"
+ react-dom: "npm:19.2.3"
+ languageName: unknown
+ linkType: soft
+
"twenty-website@workspace:packages/twenty-website":
version: 0.0.0-use.local
resolution: "twenty-website@workspace:packages/twenty-website"
@@ -61245,7 +61574,7 @@ __metadata:
languageName: node
linkType: hard
-"use-sync-external-store@npm:1.6.0, use-sync-external-store@npm:^1.5.0":
+"use-sync-external-store@npm:1.6.0, use-sync-external-store@npm:^1.5.0, use-sync-external-store@npm:^1.6.0":
version: 1.6.0
resolution: "use-sync-external-store@npm:1.6.0"
peerDependencies: