Components
An animated, futuristic UI component featuring multiple rows of holographic-style cards that scroll infinitely in a continuous loop. Includes a dynamic starfield background and accessibility support for reduced motion.

import React from "react";
import {
DataReadout,
HoloButton,
ProgressBar,
DataViz,
GlowingOrb,
ScrollingRow,
Starfield,
} from "@/components/ui/scrolling-holographic-card-feed";
const settings = {
speed: 40,
bars: 5,
progress: 70,
rows: 3,
};
const styles = `
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@500;700&display=swap');
.holo-feed {
--cyan-bright: #22d3ee;
--cyan-glow: rgba(34, 211, 238, 0.7);
--cyan-dim: rgba(34, 211, 238, 0.25);
background: #050608;
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: center;
gap: 2rem;
}
.holo-feed .starfield {
position: absolute;
inset: 0;
background-image: radial-gradient(1px 1px at 20% 30%, rgba(255,255,255,0.5), transparent),
radial-gradient(1px 1px at 60% 70%, rgba(255,255,255,0.4), transparent),
radial-gradient(1px 1px at 80% 20%, rgba(255,255,255,0.3), transparent),
radial-gradient(1px 1px at 40% 80%, rgba(255,255,255,0.35), transparent),
radial-gradient(1px 1px at 90% 60%, rgba(255,255,255,0.3), transparent);
background-size: 300px 300px, 250px 250px, 200px 200px, 350px 350px, 280px 280px;
pointer-events: none;
}
.holo-feed .grid-container { overflow: hidden; }
.holo-feed .scrolling-grid {
display: flex;
gap: 1.5rem;
width: max-content;
animation-duration: var(--scroll-duration);
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.holo-feed .holo-card {
width: 260px;
height: 150px;
flex-shrink: 0;
border: 1px solid var(--cyan-dim);
border-radius: 12px;
background: rgba(34, 211, 238, 0.03);
box-shadow: 0 0 20px rgba(34, 211, 238, 0.08) inset;
}
.holo-feed .card-content {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 0.75rem;
padding: 1rem;
}
.holo-feed .card-preview-content {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.holo-feed .fake-link {
font-family: 'Orbitron', sans-serif;
font-size: 0.7rem;
letter-spacing: 0.15em;
text-transform: uppercase;
color: var(--cyan-bright);
text-decoration: none;
}
.holo-feed .holo-button {
font-family: 'Orbitron', sans-serif;
letter-spacing: 0.15em;
text-transform: uppercase;
font-size: 0.8rem;
color: var(--cyan-bright);
padding: 0.5rem 1rem;
border: 1px solid var(--cyan-glow);
border-radius: 6px;
background: transparent;
box-shadow: 0 0 10px var(--cyan-dim);
text-shadow: 0 0 6px var(--cyan-glow);
}
.holo-feed .progress-bar {
width: 160px;
height: 6px;
border-radius: 999px;
background: var(--cyan-dim);
overflow: hidden;
}
.holo-feed .progress-bar-inner {
height: 100%;
background: var(--cyan-bright);
box-shadow: 0 0 10px var(--cyan-glow);
}
.holo-feed .data-viz-bar {
width: 8px;
background: var(--cyan-bright);
box-shadow: 0 0 8px var(--cyan-glow);
animation: viz-pulse 1s ease-in-out infinite alternate;
}
.holo-feed .data-viz-bar:nth-child(1) { height: 100%; }
.holo-feed .data-viz-bar:nth-child(2) { height: 80%; }
.holo-feed .data-viz-bar:nth-child(3) { height: 90%; }
.holo-feed .data-viz-bar:nth-child(4) { height: 55%; opacity: 0.6; }
.holo-feed .data-viz-bar:nth-child(5) { height: 35%; opacity: 0.4; }
.holo-feed .glowing-orb {
width: 44px;
height: 44px;
border-radius: 50%;
background: radial-gradient(circle at 35% 35%, #fff, var(--orb-color));
box-shadow: 0 0 25px var(--orb-glow);
}
@keyframes scroll-left { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes scroll-right { from { transform: translateX(-50%); } to { transform: translateX(0); } }
@keyframes viz-pulse { from { transform: scaleY(0.85); } to { transform: scaleY(1); } }
`;
export default function Demo(props: Partial<typeof settings>) {
const s = { ...settings, ...props };
const cards = [
{ id: "r", component: DataReadout, props: { value: "89%" } },
{ id: "b", component: HoloButton, props: { text: "Engage" } },
{ id: "p", component: ProgressBar, props: { progress: s.progress } },
{ id: "v", component: DataViz, props: { bars: s.bars } },
{ id: "o", component: GlowingOrb, props: { color: "#FF8C00" } },
{ id: "n", component: DataReadout, props: { value: "404" } },
];
return (
<div className="holo-feed h-screen w-screen">
<style>{styles}</style>
<Starfield />
{Array.from({ length: s.rows }).map((_, i) => (
<ScrollingRow
key={i}
cards={cards}
duration={`${s.speed}s`}
direction={i % 2 === 0 ? "left" : "right"}
/>
))}
</div>
);
}