"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: "https://docs.planoai.dev/get_started/quickstart", label: "start locally" }, { href: "https://docs.planoai.dev", label: "docs" }, { href: "/research", label: "research" }, { href: "/blog", label: "blog" }, { href: "/contact", label: "contact" }, ]; 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 ( ); }