diff --git a/components/RotatingHeadline.tsx b/components/RotatingHeadline.tsx
new file mode 100644
index 0000000..ff3c66b
--- /dev/null
+++ b/components/RotatingHeadline.tsx
@@ -0,0 +1,39 @@
+"use client";
+
+import { useEffect, useState } from "react";
+
+type RotatingHeadlineProps = {
+ items: string[];
+ subtext: string;
+ intervalSeconds?: number;
+};
+
+export default function RotatingHeadline({
+ items,
+ subtext,
+ intervalSeconds = 3,
+}: RotatingHeadlineProps) {
+ const [activeIndex, setActiveIndex] = useState(0);
+
+ useEffect(() => {
+ if (items.length <= 1) return;
+
+ const id = setInterval(() => {
+ setActiveIndex((i) => (i + 1) % items.length);
+ }, intervalSeconds * 1000);
+
+ return () => clearInterval(id);
+ }, [items.length, intervalSeconds]);
+
+ return (
+
+ {/* rotating row — key forces remount so a CSS transition can fire */}
+
+ {items[activeIndex]}
+
+
+ {/* static row */}
+
{subtext}
+
+ );
+}
diff --git a/components/Testimonials.tsx b/components/Testimonials.tsx
new file mode 100644
index 0000000..b482207
--- /dev/null
+++ b/components/Testimonials.tsx
@@ -0,0 +1,56 @@
+"use client";
+
+import { useState } from "react";
+
+type Testimonial = {
+ name: string;
+ title: string;
+ avatar?: string;
+ quote: string;
+};
+
+type TestimonialsProps = {
+ items: Testimonial[];
+};
+
+export default function Testimonials({ items }: TestimonialsProps) {
+ const [activeIndex, setActiveIndex] = useState(0);
+ const active = items[activeIndex];
+
+ if (!active) return null;
+
+ return (
+
+ {/* header: avatar + name + title */}
+
+ {/* TODO: avatar */}
+
+
{active.name}
+
{active.title}
+
+
+
+ {/* quote */}
+ {active.quote}
+
+ {/* controls: pagination dots + play/pause */}
+
+
+ );
+}