diff --git a/apps/marketing/package.json b/apps/marketing/package.json index 53b3d0c1f2c..ea372936126 100644 --- a/apps/marketing/package.json +++ b/apps/marketing/package.json @@ -19,7 +19,7 @@ "@superset/ui": "workspace:*", "@t3-oss/env-nextjs": "^0.13.8", "framer-motion": "^12.23.26", - "geist": "^1.5.1", + "geist": "^1.7.0", "gray-matter": "^4.0.3", "import-in-the-middle": "2.0.1", "lucide-react": "^0.563.0", diff --git a/apps/marketing/src/app/components/HeroSection/HeroSection.tsx b/apps/marketing/src/app/components/HeroSection/HeroSection.tsx index 12b9e88a6af..400efd756cd 100644 --- a/apps/marketing/src/app/components/HeroSection/HeroSection.tsx +++ b/apps/marketing/src/app/components/HeroSection/HeroSection.tsx @@ -13,13 +13,13 @@ export function HeroSection() { return (
+
Orchestrate a team of Claude Code, Codex, or any other coding agents
diff --git a/apps/marketing/src/app/components/HeroSection/components/TypewriterText/TypewriterText.tsx b/apps/marketing/src/app/components/HeroSection/components/TypewriterText/TypewriterText.tsx index 2dcf41aaa0a..e925789b219 100644 --- a/apps/marketing/src/app/components/HeroSection/components/TypewriterText/TypewriterText.tsx +++ b/apps/marketing/src/app/components/HeroSection/components/TypewriterText/TypewriterText.tsx @@ -3,10 +3,17 @@ import { motion } from "framer-motion"; import { useEffect, useState } from "react"; -interface TypewriterTextProps { +interface TextSegment { text: string; className?: string; style?: React.CSSProperties; +} + +interface TypewriterTextProps { + text?: string; + segments?: TextSegment[]; + className?: string; + style?: React.CSSProperties; speed?: number; delay?: number; showCursor?: boolean; @@ -14,12 +21,16 @@ interface TypewriterTextProps { export function TypewriterText({ text, + segments, className, style, speed = 50, delay = 500, showCursor = true, }: TypewriterTextProps) { + const fullText = segments + ? segments.map((s) => s.text).join("") + : (text ?? ""); const [displayedText, setDisplayedText] = useState(""); const [isTyping, setIsTyping] = useState(false); @@ -34,20 +45,47 @@ export function TypewriterText({ useEffect(() => { if (!isTyping) return; - if (displayedText.length < text.length) { + if (displayedText.length < fullText.length) { const timeout = setTimeout(() => { - setDisplayedText(text.slice(0, displayedText.length + 1)); + setDisplayedText(fullText.slice(0, displayedText.length + 1)); }, speed); return () => clearTimeout(timeout); } - }, [displayedText, isTyping, speed, text]); + }, [displayedText, isTyping, speed, fullText]); + + const isTypingComplete = isTyping && displayedText.length === fullText.length; + + const renderText = () => { + if (!segments) return displayedText; + + let charIndex = 0; + return segments.map((segment) => { + const segStart = charIndex; + charIndex += segment.text.length; + + if (segStart >= displayedText.length) return null; + + const visibleText = segment.text.slice( + 0, + Math.min(segment.text.length, displayedText.length - segStart), + ); - const isTypingComplete = isTyping && displayedText.length === text.length; + return ( + + {visibleText} + + ); + }); + }; return ( - {displayedText} + {renderText()} {showCursor && (