diff --git a/.gitignore b/.gitignore
index b203e285b76..b59b6739145 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,4 +59,9 @@ next-env.d.ts
!.superset/teardown.sh
# tsbuildinfo
-*.tsbuildinfo
\ No newline at end of file
+*.tsbuildinfo
+
+# Environment files (secrets)
+.envrc
+.env.local
+.env
diff --git a/apps/marketing/src/app/components/Header/Header.tsx b/apps/marketing/src/app/components/Header/Header.tsx
index f184b0743ee..eb2d4b97716 100644
--- a/apps/marketing/src/app/components/Header/Header.tsx
+++ b/apps/marketing/src/app/components/Header/Header.tsx
@@ -1,9 +1,26 @@
"use client";
import { motion } from "framer-motion";
-import Image from "next/image";
import { SocialLinks } from "../SocialLinks";
+function SupersetLogo() {
+ return (
+
+ );
+}
+
interface HeaderProps {
ctaButtons: React.ReactNode;
}
@@ -17,18 +34,12 @@ export function Header({ ctaButtons }: HeaderProps) {
{/* Logo */}
Run dozens of Claude Code, Codex, or any other cli agents you
diff --git a/apps/marketing/src/app/components/HeroSection/components/TypewriterText/TypewriterText.tsx b/apps/marketing/src/app/components/HeroSection/components/TypewriterText/TypewriterText.tsx
new file mode 100644
index 00000000000..107685c2c3d
--- /dev/null
+++ b/apps/marketing/src/app/components/HeroSection/components/TypewriterText/TypewriterText.tsx
@@ -0,0 +1,64 @@
+"use client";
+
+import { motion } from "framer-motion";
+import { useEffect, useState } from "react";
+
+interface TypewriterTextProps {
+ text: string;
+ className?: string;
+ style?: React.CSSProperties;
+ speed?: number;
+ delay?: number;
+ showCursor?: boolean;
+}
+
+export function TypewriterText({
+ text,
+ className,
+ style,
+ speed = 50,
+ delay = 500,
+ showCursor = true,
+}: TypewriterTextProps) {
+ const [displayedText, setDisplayedText] = useState("");
+ const [isTyping, setIsTyping] = useState(false);
+
+ useEffect(() => {
+ const startTimeout = setTimeout(() => {
+ setIsTyping(true);
+ }, delay);
+
+ return () => clearTimeout(startTimeout);
+ }, [delay]);
+
+ useEffect(() => {
+ if (!isTyping) return;
+
+ if (displayedText.length < text.length) {
+ const timeout = setTimeout(() => {
+ setDisplayedText(text.slice(0, displayedText.length + 1));
+ }, speed);
+
+ return () => clearTimeout(timeout);
+ }
+ }, [displayedText, isTyping, speed, text]);
+
+ return (
+
+ {displayedText}
+ {showCursor && (
+