From 64d45a7a009f9fede1602be78eda4eb7ccaa24b7 Mon Sep 17 00:00:00 2001 From: Musa Date: Fri, 12 Dec 2025 11:36:54 -0800 Subject: [PATCH] format(www) --- README-MONOREPO.md | 101 -------------- apps/www/next.config.ts | 2 +- apps/www/sanity.config.ts | 2 +- apps/www/src/app/api/og/[slug]/route.tsx | 131 +++++++++--------- apps/www/src/app/blog/[slug]/layout.tsx | 3 +- apps/www/src/app/blog/[slug]/not-found.tsx | 1 - apps/www/src/app/blog/[slug]/page.tsx | 1 - apps/www/src/app/blog/page.tsx | 1 - apps/www/src/app/research/page.tsx | 10 +- apps/www/src/app/studio/layout.tsx | 1 - apps/www/src/components/BlogCard.tsx | 1 - apps/www/src/components/BlogHeader.tsx | 1 - apps/www/src/components/BlogSectionHeader.tsx | 5 +- apps/www/src/components/ConditionalLayout.tsx | 7 +- apps/www/src/components/FeaturedBlogCard.tsx | 1 - apps/www/src/components/Hero.tsx | 5 +- .../www/src/components/IdeaToAgentSection.tsx | 4 +- apps/www/src/components/IntroSection.tsx | 17 ++- apps/www/src/components/LogoCloud.tsx | 12 +- apps/www/src/components/NetworkAnimation.tsx | 114 +++++++-------- apps/www/src/components/PortableText.tsx | 29 ++-- apps/www/src/components/UseCasesSection.tsx | 13 +- .../components/VerticalCarouselSection.tsx | 24 +++- .../research/ResearchBenchmarks.tsx | 4 +- .../src/components/research/ResearchCTA.tsx | 22 ++- .../research/ResearchCapabilities.tsx | 40 +++--- .../src/components/research/ResearchHero.tsx | 19 +-- 27 files changed, 257 insertions(+), 314 deletions(-) delete mode 100644 README-MONOREPO.md diff --git a/README-MONOREPO.md b/README-MONOREPO.md deleted file mode 100644 index 15745cf0..00000000 --- a/README-MONOREPO.md +++ /dev/null @@ -1,101 +0,0 @@ -# ArchGW Monorepo - -This is a Turborepo monorepo containing the Next.js applications and shared packages. - -## Structure - -``` -. -├── apps/ -│ ├── www/ # Marketing website -│ └── docs/ # Documentation site -├── packages/ -│ ├── ui/ # Shared UI components (Navbar, Footer, Logo, etc.) -│ ├── shared-styles/ # Shared CSS and Tailwind configuration -│ ├── tailwind-config/ # Tailwind configuration -│ └── tsconfig/ # Shared TypeScript configurations -└── turbo.json # Turborepo configuration -``` - -## Getting Started - -### Install Dependencies - -```bash -npm install -``` - -### Development - -Run all apps in development mode: - -```bash -npm run dev -``` - -Or run specific apps: - -```bash -# Marketing website (port 3000) -cd apps/www && npm run dev - -# Documentation (port 3001) -cd apps/docs && npm run dev -``` - -### Build - -Build all apps: - -```bash -npm run build -``` - -### Lint & Type Check - -```bash -npm run lint -npm run typecheck -``` - -## Shared Packages - -### @archgw/ui - -Shared React components including: -- `Navbar` - Navigation bar component -- `Footer` - Footer component -- `Logo` - Logo component -- UI components (Button, Dialog, etc.) - -### @archgw/shared-styles - -Shared CSS styles including: -- Tailwind CSS configuration -- Font definitions (IBM Plex Sans, JetBrains Mono) -- CSS variables for theming - -### @archgw/tailwind-config - -Shared Tailwind CSS configuration. - -### @archgw/tsconfig - -Shared TypeScript configurations: -- `base.json` - Base TypeScript config -- `nextjs.json` - Next.js specific config - -## Design System - -Both apps share the same design system: -- Same fonts (IBM Plex Sans, JetBrains Mono) -- Same color palette -- Same components (Navbar, Footer) -- Same Tailwind configuration - -## Notes - -- Fonts are stored in each app's `public/fonts/` directory -- Both apps use the same shared components and styles -- The monorepo uses npm workspaces and Turborepo for build orchestration - diff --git a/apps/www/next.config.ts b/apps/www/next.config.ts index d2f2d4e4..457635bc 100644 --- a/apps/www/next.config.ts +++ b/apps/www/next.config.ts @@ -19,7 +19,7 @@ const nextConfig: NextConfig = { "node_modules", "../../node_modules", ]; - + if (!isServer) { config.resolve.fallback = { ...config.resolve.fallback, diff --git a/apps/www/sanity.config.ts b/apps/www/sanity.config.ts index d6df61f6..4db703f5 100644 --- a/apps/www/sanity.config.ts +++ b/apps/www/sanity.config.ts @@ -16,4 +16,4 @@ export default defineConfig({ schema: { types: schemaTypes, }, -}); \ No newline at end of file +}); diff --git a/apps/www/src/app/api/og/[slug]/route.tsx b/apps/www/src/app/api/og/[slug]/route.tsx index eaf50e42..cefcbbb5 100644 --- a/apps/www/src/app/api/og/[slug]/route.tsx +++ b/apps/www/src/app/api/og/[slug]/route.tsx @@ -8,7 +8,9 @@ export const runtime = "edge"; function loadFont(fileName: string, baseUrl: string) { return fetch(new URL(`/fonts/${fileName}`, baseUrl)).then((res) => { if (!res.ok) { - throw new Error(`Failed to fetch font ${fileName}: ${res.status} ${res.statusText}`); + throw new Error( + `Failed to fetch font ${fileName}: ${res.status} ${res.statusText}`, + ); } return res.arrayBuffer(); }); @@ -63,16 +65,20 @@ export async function GET( // Load fonts with error handling let fontData; try { - const [ibmPlexSans, jetbrainsMonoRegular, jetbrainsMonoMedium, jetbrainsMonoBold] = - await Promise.all([ - loadFont("IBMPlexSans-VariableFont_wdth,wght.otf", fontBaseUrl), - loadFont("JetBrainsMono-Regular.otf", fontBaseUrl), - loadFont("JetBrainsMono-Medium.otf", fontBaseUrl), - loadFont("jetbrains-mono-bold.otf", fontBaseUrl), - ]).catch((error: Error) => { - console.error("Error loading fonts:", error); - throw new Error(`Failed to load fonts: ${error.message}`); - }); + const [ + ibmPlexSans, + jetbrainsMonoRegular, + jetbrainsMonoMedium, + jetbrainsMonoBold, + ] = await Promise.all([ + loadFont("IBMPlexSans-VariableFont_wdth,wght.otf", fontBaseUrl), + loadFont("JetBrainsMono-Regular.otf", fontBaseUrl), + loadFont("JetBrainsMono-Medium.otf", fontBaseUrl), + loadFont("jetbrains-mono-bold.otf", fontBaseUrl), + ]).catch((error: Error) => { + console.error("Error loading fonts:", error); + throw new Error(`Failed to load fonts: ${error.message}`); + }); fontData = { ibmPlexSans, @@ -81,7 +87,8 @@ export async function GET( jetbrainsMonoBold, }; } catch (error: unknown) { - const errorMessage = error instanceof Error ? error.message : "Unknown error"; + const errorMessage = + error instanceof Error ? error.message : "Unknown error"; console.error("Font loading error:", errorMessage); return new Response( JSON.stringify({ @@ -97,7 +104,9 @@ export async function GET( const post = await getBlogPost(slug); if (!post) { - return new Response(JSON.stringify({ error: "Post not found" }), { status: 404 }); + return new Response(JSON.stringify({ error: "Post not found" }), { + status: 404, + }); } // Get author image URL if available @@ -114,8 +123,7 @@ export async function GET( : request.nextUrl.origin); const logoUrl = `${baseUrl}/Logomark.png`; - return new ImageResponse( - ( + return new ImageResponse(
- - ), - { - width: 1200, - height: 630, - fonts: [ - { - name: "IBM Plex Sans Regular", - data: fontData.ibmPlexSans, - style: "normal", - weight: 400, - }, - { - name: "IBM Plex Sans Medium", - data: fontData.ibmPlexSans, - style: "normal", - weight: 500, - }, - { - name: "IBM Plex Sans Bold", - data: fontData.ibmPlexSans, - style: "normal", - weight: 700, - }, - { - name: "JetBrains Mono Regular", - data: fontData.jetbrainsMonoRegular, - style: "normal", - weight: 400, - }, - { - name: "JetBrains Mono Medium", - data: fontData.jetbrainsMonoMedium, - style: "normal", - weight: 500, - }, - { - name: "JetBrains Mono Bold", - data: fontData.jetbrainsMonoBold, - style: "normal", - weight: 600, - }, - ], - }, - ); + , + { + width: 1200, + height: 630, + fonts: [ + { + name: "IBM Plex Sans Regular", + data: fontData.ibmPlexSans, + style: "normal", + weight: 400, + }, + { + name: "IBM Plex Sans Medium", + data: fontData.ibmPlexSans, + style: "normal", + weight: 500, + }, + { + name: "IBM Plex Sans Bold", + data: fontData.ibmPlexSans, + style: "normal", + weight: 700, + }, + { + name: "JetBrains Mono Regular", + data: fontData.jetbrainsMonoRegular, + style: "normal", + weight: 400, + }, + { + name: "JetBrains Mono Medium", + data: fontData.jetbrainsMonoMedium, + style: "normal", + weight: 500, + }, + { + name: "JetBrains Mono Bold", + data: fontData.jetbrainsMonoBold, + style: "normal", + weight: 600, + }, + ], + }, + ); } catch (error: unknown) { - const errorMessage = error instanceof Error ? error.message : "Unknown error"; + const errorMessage = + error instanceof Error ? error.message : "Unknown error"; console.error("Error generating image response:", error); return new Response( JSON.stringify({ @@ -316,4 +324,3 @@ export async function GET( ); } } - diff --git a/apps/www/src/app/blog/[slug]/layout.tsx b/apps/www/src/app/blog/[slug]/layout.tsx index 1c26b94d..8d7b1ecf 100644 --- a/apps/www/src/app/blog/[slug]/layout.tsx +++ b/apps/www/src/app/blog/[slug]/layout.tsx @@ -49,7 +49,7 @@ export async function generateMetadata({ // Get baseUrl - use NEXT_PUBLIC_APP_URL if set, otherwise construct from VERCEL_URL // Restrict to allowed hosts: localhost:3000, archgw-tau.vercel.app, or plano.katanemo.com let baseUrl = "http://localhost:3000"; - + if (process.env.NEXT_PUBLIC_APP_URL) { const url = process.env.NEXT_PUBLIC_APP_URL; if ( @@ -118,4 +118,3 @@ interface LayoutProps { export default async function Layout({ children, params }: LayoutProps) { return <>{children}; } - diff --git a/apps/www/src/app/blog/[slug]/not-found.tsx b/apps/www/src/app/blog/[slug]/not-found.tsx index ec23b2df..e637736b 100644 --- a/apps/www/src/app/blog/[slug]/not-found.tsx +++ b/apps/www/src/app/blog/[slug]/not-found.tsx @@ -33,4 +33,3 @@ export default function NotFound() { ); } - diff --git a/apps/www/src/app/blog/[slug]/page.tsx b/apps/www/src/app/blog/[slug]/page.tsx index 4a64aca3..d2a53dc5 100644 --- a/apps/www/src/app/blog/[slug]/page.tsx +++ b/apps/www/src/app/blog/[slug]/page.tsx @@ -204,4 +204,3 @@ export default async function BlogPostPage({ ); } - diff --git a/apps/www/src/app/blog/page.tsx b/apps/www/src/app/blog/page.tsx index bdc27ec1..63d586bc 100644 --- a/apps/www/src/app/blog/page.tsx +++ b/apps/www/src/app/blog/page.tsx @@ -117,4 +117,3 @@ export default async function BlogPage() { ); } - diff --git a/apps/www/src/app/research/page.tsx b/apps/www/src/app/research/page.tsx index ced0a980..7e87afcc 100644 --- a/apps/www/src/app/research/page.tsx +++ b/apps/www/src/app/research/page.tsx @@ -1,7 +1,15 @@ "use client"; import React from "react"; -import { ResearchHero, ResearchGrid, ResearchTimeline, ResearchCTA, ResearchCapabilities, ResearchBenchmarks, ResearchFamily } from "@/components/research"; +import { + ResearchHero, + ResearchGrid, + ResearchTimeline, + ResearchCTA, + ResearchCapabilities, + ResearchBenchmarks, + ResearchFamily, +} from "@/components/research"; import { UnlockPotentialSection } from "@/components/UnlockPotentialSection"; export default function ResearchPage() { diff --git a/apps/www/src/app/studio/layout.tsx b/apps/www/src/app/studio/layout.tsx index 0ff56d7e..27f1e45f 100644 --- a/apps/www/src/app/studio/layout.tsx +++ b/apps/www/src/app/studio/layout.tsx @@ -9,4 +9,3 @@ export default function StudioLayout({ ); } - diff --git a/apps/www/src/components/BlogCard.tsx b/apps/www/src/components/BlogCard.tsx index 3bed832c..5ceb96f9 100644 --- a/apps/www/src/components/BlogCard.tsx +++ b/apps/www/src/components/BlogCard.tsx @@ -85,4 +85,3 @@ export function BlogCard({ post, index = 0 }: BlogCardProps) { ); } - diff --git a/apps/www/src/components/BlogHeader.tsx b/apps/www/src/components/BlogHeader.tsx index eebb0791..2fca21da 100644 --- a/apps/www/src/components/BlogHeader.tsx +++ b/apps/www/src/components/BlogHeader.tsx @@ -23,4 +23,3 @@ export function BlogHeader() { ); } - diff --git a/apps/www/src/components/BlogSectionHeader.tsx b/apps/www/src/components/BlogSectionHeader.tsx index 56499afe..039b51e8 100644 --- a/apps/www/src/components/BlogSectionHeader.tsx +++ b/apps/www/src/components/BlogSectionHeader.tsx @@ -3,10 +3,7 @@ export function BlogSectionHeader() { return (

- - The latest and greatest from our blog. - + The latest and greatest from our blog.

); } - diff --git a/apps/www/src/components/ConditionalLayout.tsx b/apps/www/src/components/ConditionalLayout.tsx index f5d3f144..04102953 100644 --- a/apps/www/src/components/ConditionalLayout.tsx +++ b/apps/www/src/components/ConditionalLayout.tsx @@ -3,11 +3,7 @@ import { usePathname } from "next/navigation"; import { Navbar, Footer } from "@katanemo/ui"; -export function ConditionalLayout({ - children, -}: { - children: React.ReactNode; -}) { +export function ConditionalLayout({ children }: { children: React.ReactNode }) { const pathname = usePathname(); const isStudio = pathname?.startsWith("/studio"); @@ -23,4 +19,3 @@ export function ConditionalLayout({ ); } - diff --git a/apps/www/src/components/FeaturedBlogCard.tsx b/apps/www/src/components/FeaturedBlogCard.tsx index ded1a1c9..5ddef92a 100644 --- a/apps/www/src/components/FeaturedBlogCard.tsx +++ b/apps/www/src/components/FeaturedBlogCard.tsx @@ -115,4 +115,3 @@ export function FeaturedBlogCard({ post }: FeaturedBlogCardProps) { ); } - diff --git a/apps/www/src/components/Hero.tsx b/apps/www/src/components/Hero.tsx index 3b968ab2..c6d7b3e0 100644 --- a/apps/www/src/components/Hero.tsx +++ b/apps/www/src/components/Hero.tsx @@ -44,9 +44,8 @@ export function Hero() { {/* Subheading with CTA Buttons */}

- Build agents faster, and deliver them reliably to production - - by offloading the critical plumbing work to Plano. - + Build agents faster, and deliver them reliably to production - by + offloading the critical plumbing work to Plano.

{/* CTA Buttons */} diff --git a/apps/www/src/components/IdeaToAgentSection.tsx b/apps/www/src/components/IdeaToAgentSection.tsx index 7dc44d08..82585ec1 100644 --- a/apps/www/src/components/IdeaToAgentSection.tsx +++ b/apps/www/src/components/IdeaToAgentSection.tsx @@ -150,7 +150,9 @@ export function IdeaToAgentSection() {
diff --git a/apps/www/src/components/IntroSection.tsx b/apps/www/src/components/IntroSection.tsx index 867528bf..821a1855 100644 --- a/apps/www/src/components/IntroSection.tsx +++ b/apps/www/src/components/IntroSection.tsx @@ -20,15 +20,18 @@ export function IntroSection() { {/* Body Text */}

- Plano is a models-native proxy and dataplane for agents that handles - critical plumbing work in AI - agent routing and orchestration, rich agentic - traces, guardrail hooks, and smart model routing APIs for LLMs. Use any - language, AI framework, and deliver agents to productions quickly with Plano. + Plano is a models-native proxy and dataplane for agents that + handles critical plumbing work in AI - agent routing and + orchestration, rich agentic traces, guardrail hooks, and smart + model routing APIs for LLMs. Use any language, AI framework, and + deliver agents to productions quickly with Plano.

- Developers can focus more on core product logic of agents. - Product teams can accelerate feedback loops for reinforcement learning. - Engineering teams can standardize policies and access controls across every agent and LLM for safer, more reliable scaling. + Developers can focus more on core product logic of agents. + Product teams can accelerate feedback loops for reinforcement + learning. Engineering teams can standardize policies and access + controls across every agent and LLM for safer, more reliable + scaling.

diff --git a/apps/www/src/components/LogoCloud.tsx b/apps/www/src/components/LogoCloud.tsx index 47b4f9b1..3df4c80f 100644 --- a/apps/www/src/components/LogoCloud.tsx +++ b/apps/www/src/components/LogoCloud.tsx @@ -34,17 +34,17 @@ export function LogoCloud() { const isTMobile = index === 1; // T-Mobile is before HP const isHP = index === 2; // HP is in center const isSanDisk = index === 3; // SanDisk is after HP - + // Custom spacing for logos around HP on large screens - let spacingClass = 'lg:mx-6 xl:mx-8'; // Default spacing + let spacingClass = "lg:mx-6 xl:mx-8"; // Default spacing if (isTMobile) { - spacingClass = 'lg:mr-3 xl:mr-4 lg:ml-6 xl:ml-8'; // Smaller gap to HP + spacingClass = "lg:mr-3 xl:mr-4 lg:ml-6 xl:ml-8"; // Smaller gap to HP } else if (isHP) { - spacingClass = 'lg:mx-3 xl:mx-4'; // Smaller gaps on both sides + spacingClass = "lg:mx-3 xl:mx-4"; // Smaller gaps on both sides } else if (isSanDisk) { - spacingClass = 'lg:ml-3 xl:ml-4 lg:mr-6 xl:mr-8'; // Smaller gap from HP + spacingClass = "lg:ml-3 xl:ml-4 lg:mr-6 xl:mr-8"; // Smaller gap from HP } - + return (
- + {/* Outer border */} - + {/* Inner background */} - - {/* Animated squares with wave effect */} - {squares.map((square, index) => { - // Use deterministic values based on index for SSR/client consistency - const { duration, peakOpacity, baseOpacity, midOpacity, baseBrightness, peakBrightness } = - getDeterministicValues(index); - - return ( - - ); - })} + + {/* Animated squares with wave effect */} + {squares.map((square, index) => { + // Use deterministic values based on index for SSR/client consistency + const { + duration, + peakOpacity, + baseOpacity, + midOpacity, + baseBrightness, + peakBrightness, + } = getDeterministicValues(index); + + return ( + + ); + })} diff --git a/apps/www/src/components/PortableText.tsx b/apps/www/src/components/PortableText.tsx index 381b40fd..f45d1500 100644 --- a/apps/www/src/components/PortableText.tsx +++ b/apps/www/src/components/PortableText.tsx @@ -11,22 +11,22 @@ const components = { types: { image: ({ value }: any) => { if (!value?.asset) return null; - + const imageUrl = urlFor(value); const asset = value.asset; - + // Get natural dimensions if available from metadata const dimensions = asset.metadata?.dimensions; const width = dimensions?.width || 1000; const height = dimensions?.height || 562; const aspectRatio = dimensions ? height / width : 0.5625; // Default to 16:9 if no dimensions - + return (
-
{value.alt && ( -

{value.alt}

+

+ {value.alt} +

)}
@@ -91,12 +93,8 @@ const components = { ), }, listItem: { - bullet: (props: any) => ( -
  • {props.children}
  • - ), - number: (props: any) => ( -
  • {props.children}
  • - ), + bullet: (props: any) =>
  • {props.children}
  • , + number: (props: any) =>
  • {props.children}
  • , }, marks: { strong: ({ children }: { children: React.ReactNode }) => ( @@ -109,7 +107,11 @@ const components = { {props.children} @@ -121,4 +123,3 @@ const components = { export function PortableText({ content }: PortableTextProps) { return ; } - diff --git a/apps/www/src/components/UseCasesSection.tsx b/apps/www/src/components/UseCasesSection.tsx index 2c8c7255..af845d23 100644 --- a/apps/www/src/components/UseCasesSection.tsx +++ b/apps/www/src/components/UseCasesSection.tsx @@ -115,7 +115,9 @@ export function UseCasesSection() { What's possible with Plano
    @@ -156,7 +158,9 @@ export function UseCasesSection() { {/* Start building button - Mobile only, appears last */}
    @@ -284,7 +288,10 @@ export function UseCasesSection() {
    diff --git a/apps/www/src/components/research/ResearchBenchmarks.tsx b/apps/www/src/components/research/ResearchBenchmarks.tsx index 39c675a4..01d6d54d 100644 --- a/apps/www/src/components/research/ResearchBenchmarks.tsx +++ b/apps/www/src/components/research/ResearchBenchmarks.tsx @@ -16,7 +16,9 @@ export function ResearchBenchmarks() { {/* Title */}

    - Production excellence, outperforming frontier LLMs + + Production excellence, outperforming frontier LLMs +

    diff --git a/apps/www/src/components/research/ResearchCTA.tsx b/apps/www/src/components/research/ResearchCTA.tsx index 9298107b..9f18f0bf 100644 --- a/apps/www/src/components/research/ResearchCTA.tsx +++ b/apps/www/src/components/research/ResearchCTA.tsx @@ -9,26 +9,34 @@ export function ResearchCTA() {
    {/* Main Heading */}

    - Meet Plano-Orchestrator. Our latest models. + + Meet Plano-Orchestrator. Our latest models. +

    {/* Description with CTA Buttons */}

    - Plano-Orchestrator is a family of state-of-the-art routing and orchestration models - that decides which agent(s) or LLM(s) should handle each request, and in what sequence. - Built for multi-agent orchestration systems, Plano-Orchestrator excels at analyzing - user intent and conversation context to make precise routing and orchestration decisions. + Plano-Orchestrator is a family of state-of-the-art routing and + orchestration models that decides which agent(s) or LLM(s) should + handle each request, and in what sequence. Built for multi-agent + orchestration systems, Plano-Orchestrator excels at analyzing user + intent and conversation context to make precise routing and + orchestration decisions.

    {/* CTA Buttons */}
    diff --git a/apps/www/src/components/research/ResearchCapabilities.tsx b/apps/www/src/components/research/ResearchCapabilities.tsx index eda864f5..cb2550d7 100644 --- a/apps/www/src/components/research/ResearchCapabilities.tsx +++ b/apps/www/src/components/research/ResearchCapabilities.tsx @@ -52,14 +52,16 @@ export function ResearchCapabilities() { {/* Title */}

    - Accurately route with confidence with no compromise + + Accurately route with confidence with no compromise +

    -

    - Designed for real-world deployments, it delivers strong performance across general - conversations, coding tasks, and long-context multi-turn conversations, while remaining - efficient enough for low-latency production environments. - +

    + Designed for real-world deployments, it delivers strong performance + across general conversations, coding tasks, and long-context + multi-turn conversations, while remaining efficient enough for + low-latency production environments.

    @@ -67,15 +69,18 @@ export function ResearchCapabilities() {
    {capabilitiesData.map((capability) => { // Map each capability to its icon - const iconMap: Record> = { + const iconMap: Record< + number, + React.ComponentType<{ className?: string }> + > = { 1: MessagesSquare, // Multi-turn Understanding 2: GitFork, // Multi-Intent Detection 3: Route, // Content-Dependency Routing 4: RefreshCw, // Conversational-Flow Handling }; - + const Icon = iconMap[capability.id]; - + return (
    {/* Icon Card */} @@ -84,9 +89,7 @@ export function ResearchCapabilities() { transition={{ duration: 0.2 }} className="bg-gradient-to-b from-[rgba(177,184,255,0.16)] to-[rgba(17,28,132,0.035)] border-2 border-[rgba(171,178,250,0.27)] rounded-md p-6 h-40 flex items-center justify-center mb-4" > - {Icon && ( - - )} + {Icon && } {/* Title */} @@ -107,15 +110,18 @@ export function ResearchCapabilities() {
    {capabilitiesData.map((capability) => { // Map each capability to its icon - const iconMap: Record> = { + const iconMap: Record< + number, + React.ComponentType<{ className?: string }> + > = { 1: MessagesSquare, // Multi-turn Understanding 2: GitFork, // Multi-Intent Detection 3: Route, // Content-Dependency Routing 4: RefreshCw, // Conversational-Flow Handling }; - + const Icon = iconMap[capability.id]; - + return ( - {Icon && ( - - )} + {Icon && } ); })} diff --git a/apps/www/src/components/research/ResearchHero.tsx b/apps/www/src/components/research/ResearchHero.tsx index e1cb561c..14a3f83c 100644 --- a/apps/www/src/components/research/ResearchHero.tsx +++ b/apps/www/src/components/research/ResearchHero.tsx @@ -24,9 +24,7 @@ export function ResearchHero() { — - - Plano Orchestrator models released - + Plano Orchestrator models released
    @@ -40,16 +38,19 @@ export function ResearchHero() { {/* Description */}

    - Our applied research focuses on how to deliver agents safely, efficiently, - and with improved real-world performance — critical for any AI application, - but work that sits outside of any agent's core product logic. + Our applied research focuses on how to deliver agents safely, + efficiently, and with improved real-world performance — critical for + any AI application, but work that sits outside of any agent's core + product logic.

    - +