diff --git a/apps/www/src/components/Footer.tsx b/apps/www/src/components/Footer.tsx
deleted file mode 100644
index 7477f3cb..00000000
--- a/apps/www/src/components/Footer.tsx
+++ /dev/null
@@ -1,100 +0,0 @@
-import React from "react";
-import Link from "next/link";
-import Image from "next/image";
-
-const footerLinks = {
- company: [
- { label: "Product", href: "/product" },
- { label: "Use Cases", href: "/use-cases" },
- { label: "Blog", href: "/blog" },
- { label: "Plano LLMs", href: "/llms" },
- ],
- developerResources: [{ label: "Documentation", href: "/docs" }],
-};
-
-export function Footer() {
- return (
-
- );
-}
diff --git a/apps/www/src/components/Hero.tsx b/apps/www/src/components/Hero.tsx
index ba2d79e2..e91a6d29 100644
--- a/apps/www/src/components/Hero.tsx
+++ b/apps/www/src/components/Hero.tsx
@@ -1,5 +1,5 @@
import React from "react";
-import { Button } from "./ui/button";
+import { Button } from "@katanemo/ui";
import Link from "next/link";
import { NetworkAnimation } from "./NetworkAnimation";
diff --git a/apps/www/src/components/IdeaToAgentSection.tsx b/apps/www/src/components/IdeaToAgentSection.tsx
index 0693e328..b02afc13 100644
--- a/apps/www/src/components/IdeaToAgentSection.tsx
+++ b/apps/www/src/components/IdeaToAgentSection.tsx
@@ -2,7 +2,7 @@
import React, { useState, useEffect } from "react";
import { motion, AnimatePresence } from "framer-motion";
-import { Button } from "./ui/button";
+import { Button } from "@katanemo/ui";
const carouselData = [
{
diff --git a/apps/www/src/components/Logo.tsx b/apps/www/src/components/Logo.tsx
deleted file mode 100644
index b99f8890..00000000
--- a/apps/www/src/components/Logo.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from "react";
-import Image from "next/image";
-
-export function Logo() {
- return (
-
- {/* LogoMarkSquare SVG */}
-
-
- );
-}
diff --git a/apps/www/src/components/Navbar.tsx b/apps/www/src/components/Navbar.tsx
deleted file mode 100644
index d998d6cd..00000000
--- a/apps/www/src/components/Navbar.tsx
+++ /dev/null
@@ -1,290 +0,0 @@
-"use client";
-
-import React, { useState, useEffect } from "react";
-import Link from "next/link";
-import { Logo } from "./Logo";
-import { Button } from "./ui/button";
-import { cn } from "../lib/utils";
-import { motion, AnimatePresence } from "framer-motion";
-import { X, Menu } from "lucide-react";
-
-const navItems = [
- { href: "/start", label: "start locally" },
- { href: "/docs", label: "docs" },
- { href: "/model-research", label: "models research" },
- { href: "/blog", label: "blog" },
- { href: "/why", label: "why plano?" },
-];
-
-export function Navbar() {
- const [isMenuOpen, setIsMenuOpen] = useState(false);
- const [isDarkBackground, setIsDarkBackground] = useState(false);
-
- // Detect background color behind dropdown menu
- useEffect(() => {
- if (!isMenuOpen) {
- setIsDarkBackground(false);
- return;
- }
-
- const detectBackground = () => {
- // Small delay to ensure DOM is ready
- setTimeout(() => {
- const nav = document.querySelector("nav");
- if (!nav) return;
-
- const navRect = nav.getBoundingClientRect();
- const dropdownBottom = navRect.bottom;
- const checkY = dropdownBottom + 20; // Just below the dropdown
-
- // First, try to find section elements directly
- const main = document.querySelector("main");
- if (main) {
- const sections = main.querySelectorAll("section");
- let foundDarkSection = false;
-
- sections.forEach((section) => {
- const rect = section.getBoundingClientRect();
- // Check if this section is visible below the navbar
- if (rect.top <= checkY && rect.bottom > checkY) {
- // Check for dark background classes
- const classList = Array.from(section.classList);
- const hasDarkBg = classList.some(
- (cls) =>
- cls.includes("bg-[#1a1a1a]") ||
- cls.includes("bg-black") ||
- cls.includes("bg-gray-900") ||
- cls.includes("bg-neutral-900") ||
- cls.includes("dark"),
- );
-
- if (hasDarkBg) {
- foundDarkSection = true;
- setIsDarkBackground(true);
- return;
- }
-
- // Also check computed background
- const computed = window.getComputedStyle(section);
- const bg = computed.backgroundColor;
- if (bg && bg !== "rgba(0, 0, 0, 0)" && bg !== "transparent") {
- const rgbMatch = bg.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
- if (rgbMatch) {
- const r = parseInt(rgbMatch[1]);
- const g = parseInt(rgbMatch[2]);
- const b = parseInt(rgbMatch[3]);
- const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
- setIsDarkBackground(luminance < 0.5);
- foundDarkSection = true;
- return;
- }
- }
- }
- });
-
- if (foundDarkSection) return;
- }
-
- // Fallback: Check element at point
- const centerX = window.innerWidth / 2;
- const elementBelow = document.elementFromPoint(centerX, checkY);
-
- if (elementBelow) {
- let current: HTMLElement | null = elementBelow as HTMLElement;
- let backgroundColor = "";
-
- // Walk up the DOM tree
- let levels = 0;
- while (
- current &&
- !backgroundColor &&
- current !== document.body &&
- levels < 15
- ) {
- const computed = window.getComputedStyle(current);
- const bg = computed.backgroundColor;
-
- if (bg && bg !== "rgba(0, 0, 0, 0)" && bg !== "transparent") {
- const rgbaMatch = bg.match(
- /rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/,
- );
- if (rgbaMatch) {
- const alpha = rgbaMatch[4] ? parseFloat(rgbaMatch[4]) : 1;
- if (alpha > 0.1) {
- backgroundColor = bg;
- break;
- }
- } else {
- backgroundColor = bg;
- break;
- }
- }
-
- current = current.parentElement;
- levels++;
- }
-
- if (!backgroundColor) {
- const bodyBg = window.getComputedStyle(
- document.body,
- ).backgroundColor;
- backgroundColor = bodyBg;
- }
-
- if (backgroundColor) {
- const rgbMatch = backgroundColor.match(
- /rgba?\((\d+),\s*(\d+),\s*(\d+)/,
- );
- if (rgbMatch) {
- const r = parseInt(rgbMatch[1]);
- const g = parseInt(rgbMatch[2]);
- const b = parseInt(rgbMatch[3]);
- const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
- setIsDarkBackground(luminance < 0.5);
- } else {
- const darkColors = [
- "black",
- "#000",
- "#000000",
- "rgb(0,0,0)",
- "rgba(0,0,0",
- "#1a1a1a",
- ];
- const isDark = darkColors.some((color) =>
- backgroundColor.toLowerCase().includes(color.toLowerCase()),
- );
- setIsDarkBackground(isDark);
- }
- }
- }
- }, 100);
- };
-
- // Detect on open and on scroll
- detectBackground();
- const scrollHandler = () => detectBackground();
- const resizeHandler = () => detectBackground();
-
- window.addEventListener("scroll", scrollHandler, { passive: true });
- window.addEventListener("resize", resizeHandler);
-
- return () => {
- window.removeEventListener("scroll", scrollHandler);
- window.removeEventListener("resize", resizeHandler);
- };
- }, [isMenuOpen]);
-
- // Close menu when route changes
- const handleLinkClick = () => {
- setIsMenuOpen(false);
- };
-
- return (
-
- );
-}
diff --git a/apps/www/src/components/UnlockPotentialSection.tsx b/apps/www/src/components/UnlockPotentialSection.tsx
index e22b2c7d..adf90c37 100644
--- a/apps/www/src/components/UnlockPotentialSection.tsx
+++ b/apps/www/src/components/UnlockPotentialSection.tsx
@@ -1,5 +1,5 @@
import React from "react";
-import { Button } from "./ui/button";
+import { Button } from "@katanemo/ui";
interface UnlockPotentialSectionProps {
variant?: "transparent" | "black";
diff --git a/apps/www/src/components/UseCasesSection.tsx b/apps/www/src/components/UseCasesSection.tsx
index c0f967f8..d613d417 100644
--- a/apps/www/src/components/UseCasesSection.tsx
+++ b/apps/www/src/components/UseCasesSection.tsx
@@ -10,15 +10,15 @@ import {
Server,
XIcon,
} from "lucide-react";
-import { Button } from "./ui/button";
import {
+ Button,
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
DialogClose,
-} from "./ui/dialog";
+} from "@katanemo/ui";
import { motion, AnimatePresence } from "framer-motion";
interface UseCase {
diff --git a/apps/www/src/components/VerticalCarouselSection.tsx b/apps/www/src/components/VerticalCarouselSection.tsx
index 47f2ec2f..14fb5e74 100644
--- a/apps/www/src/components/VerticalCarouselSection.tsx
+++ b/apps/www/src/components/VerticalCarouselSection.tsx
@@ -3,7 +3,7 @@
import React, { useState } from "react";
import Image from "next/image";
import { motion, AnimatePresence } from "framer-motion";
-import { Button } from "./ui/button";
+import { Button } from "@katanemo/ui";
const verticalCarouselData = [
{
diff --git a/apps/www/src/components/ui/button.tsx b/apps/www/src/components/ui/button.tsx
deleted file mode 100644
index 95803d5b..00000000
--- a/apps/www/src/components/ui/button.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-import * as React from "react";
-import { Slot } from "@radix-ui/react-slot";
-import { cva, type VariantProps } from "class-variance-authority";
-
-import { cn } from "../../lib/utils";
-
-const buttonVariants = cva(
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-[7px] font-mono font-medium tracking-[-0.989px] transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
- {
- variants: {
- variant: {
- default:
- "bg-[#7780d9] border-[#4141b2] border-[1.562px] border-solid text-white hover:bg-[#7780d9]/90 text-base leading-[1.102]",
- primary:
- "bg-[#7780d9] border-[#4141b2] border-[1.562px] border-solid text-white hover:bg-[#7780d9]/90 text-base leading-[1.102]",
- destructive:
- "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
- outline:
- "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
- secondary:
- "bg-[#edefff] border-[#d1d1d1] border-[1.562px] border-solid text-[#494949] hover:bg-[#edefff]/90 text-base leading-[1.102]",
- secondaryDark:
- "bg-neutral-600 border-[#d1d1d1]/20 border-[1.562px] border-solid text-white hover:bg-[#1a1a1a]/90 text-base leading-[1.102]",
- ghost:
- "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
- link: "text-primary underline-offset-4 hover:underline",
- },
- size: {
- default: "h-10 px-5 py-2 has-[>svg]:px-3",
- sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
- lg: "h-10 rounded-[7px] px-5 has-[>svg]:px-4",
- icon: "size-9",
- "icon-sm": "size-8",
- "icon-lg": "size-10",
- },
- },
- defaultVariants: {
- variant: "default",
- size: "default",
- },
- },
-);
-
-function Button({
- className,
- variant,
- size,
- asChild = false,
- ...props
-}: React.ComponentProps<"button"> &
- VariantProps & {
- asChild?: boolean;
- }) {
- const Comp = asChild ? Slot : "button";
-
- return (
-
- );
-}
-
-export { Button, buttonVariants };
diff --git a/apps/www/src/components/ui/dialog.tsx b/apps/www/src/components/ui/dialog.tsx
deleted file mode 100644
index b9ce5dc3..00000000
--- a/apps/www/src/components/ui/dialog.tsx
+++ /dev/null
@@ -1,143 +0,0 @@
-"use client";
-
-import * as React from "react";
-import * as DialogPrimitive from "@radix-ui/react-dialog";
-import { XIcon } from "lucide-react";
-
-import { cn } from "../../lib/utils";
-
-function Dialog({
- ...props
-}: React.ComponentProps) {
- return ;
-}
-
-function DialogTrigger({
- ...props
-}: React.ComponentProps) {
- return ;
-}
-
-function DialogPortal({
- ...props
-}: React.ComponentProps) {
- return ;
-}
-
-function DialogClose({
- ...props
-}: React.ComponentProps) {
- return ;
-}
-
-function DialogOverlay({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function DialogContent({
- className,
- children,
- showCloseButton = true,
- ...props
-}: React.ComponentProps & {
- showCloseButton?: boolean;
-}) {
- return (
-
-
-
- {children}
- {showCloseButton && (
-
-
- Close
-
- )}
-
-
- );
-}
-
-function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- );
-}
-
-function DialogTitle({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function DialogDescription({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-export {
- Dialog,
- DialogClose,
- DialogContent,
- DialogDescription,
- DialogFooter,
- DialogHeader,
- DialogOverlay,
- DialogPortal,
- DialogTitle,
- DialogTrigger,
-};