LayoutSimpleApril 8, 2026

Infinite Ticker

An infinitely scrolling horizontal text ticker that loops seamlessly. Items are duplicated and a CSS animation shifts the track by exactly 50%, creating a gapless loop without JavaScript.

View Full Demo →
Brand IdentityWeb DesignMotionShopifyArt DirectionNo-5 StudioBrand IdentityWeb DesignMotionShopifyArt DirectionNo-5 Studio
index.jsx
import styles from "./styles.module.css";

export default function InfiniteTicker({ items = [], speed = 30 }) {
  // Duplicate items to ensure seamless loop
  const doubled = [...items, ...items];

  return (
    <div className={styles.wrapper}>
      <div
        className={styles.track}
        style={{ "--ticker-duration": `${speed}s` }}
      >
        {doubled.map((item, i) => (
          <span key={i} className={styles.item}>
            <span className={styles.text}>{item}</span>
            <span className={styles.dot} aria-hidden="true">·</span>
          </span>
        ))}
      </div>
    </div>
  );
}
styles.module.css
.wrapper {
  overflow: hidden;
  border-top: 1px solid #e5e5e5;
  border-bottom: 1px solid #e5e5e5;
  padding: 0.875rem 0;
  background: #fafafa;
}

.track {
  display: flex;
  width: max-content;
  animation: ticker var(--ticker-duration, 30s) linear infinite;
}

.item {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  white-space: nowrap;
}

.text {
  font-size: 0.9375rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: #1a1a1a;
  padding: 0 0.5rem;
}

.dot {
  color: #9b9b9b;
  padding: 0 0.25rem;
}

@keyframes ticker {
  from {
    transform: translateX(0);
  }
  to {
    /* Move exactly half (one set of items) for seamless loop */
    transform: translateX(-50%);
  }
}

Apr 10, 2026

LAYOUT

Card Slider

A draggable horizontal card slider built with GSAP Draggable and InertiaPlugin. Supports snap-to-slide, momentum scrolling, mousewheel, keyboard navigation, and prev/next buttons. Responsive slide width via CSS container queries.

Apr 9, 2026

LAYOUT

Layout Grid Flip

A card grid that animates between large (3-col) and small (5-col) layouts using GSAP Flip. Cards reflow with a smooth positional tween and the container height animates in sync. Subtitle text fades out in small view. Respects prefers-reduced-motion.