AnimationsSimpleApril 8, 2026

Divider Width Expand

Horizontal line expands from 0% to 100% width when a section is opened. Used as a visual separator animation for accordion-style toggles.

View Full Demo →
demo.jsx
import DividerWidthExpand from "./index.jsx";
import { dividerWidthExpand } from "@/content/animations/demo-data.js";
import styles from "./demo.module.css";

export default function DividerWidthExpandDemo() {
  return (
    <div className={styles.demo}>
      <div className={styles.inner}>
        <div className={styles.left}>
          <p className={styles.label}>What we do</p>
          <h2 className={styles.heading}>Services</h2>
        </div>
        <div className={styles.right}>
          <DividerWidthExpand {...dividerWidthExpand} />
        </div>
      </div>
    </div>
  );
}
index.jsx
"use client";

import { useState } from "react";
import styles from "./styles.module.css";

export default function DividerWidthExpand({ sections = [] }) {
  const [openIndex, setOpenIndex] = useState(null);

  return (
    <div className={styles.list}>
      {sections.map((section, i) => {
        const isOpen = openIndex === i;
        return (
          <div key={section.title} className={styles.item}>
            <button
              className={styles.trigger}
              onClick={() => setOpenIndex(isOpen ? null : i)}
              aria-expanded={isOpen}
            >
              <span>{section.title}</span>
              <span className={styles.indicator}>{isOpen ? "−" : "+"}</span>
            </button>
            <div className={`${styles.divider} ${isOpen ? styles.expanded : ""}`} />
            {isOpen && (
              <p className={styles.content}>{section.content}</p>
            )}
          </div>
        );
      })}
    </div>
  );
}
demo.module.css
.demo {
  min-height: 100vh;
  background: #f8f8f6;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 5rem 3rem;
}

.inner {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 5rem;
  width: 100%;
  max-width: 1000px;
  align-items: start;
}

.left {
  padding-top: 2rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  position: sticky;
  top: 5rem;
}

.label {
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #9b9b9b;
}

.heading {
  font-size: clamp(2.5rem, 5vw, 4.5rem);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 0.95;
  color: #1a1a1a;
}

.right {
  width: 100%;
}

/* Let the component fill full width in demo */
.right :global(.list) {
  max-width: 100%;
  padding: 0;
  margin: 0;
}

@media (max-width: 767px) {
  .inner {
    grid-template-columns: 1fr;
    gap: 2rem;
  }

  .left {
    position: static;
  }
}
styles.module.css
.list {
  max-width: 600px;
  margin: 0 auto;
  padding: 2rem;
}

.item {
  border-top: 1px solid #e5e5e5;
}

.item:last-child {
  border-bottom: 1px solid #e5e5e5;
}

.trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 1.25rem 0;
  font-size: 1rem;
  font-weight: 500;
  font-family: inherit;
  letter-spacing: -0.01em;
  color: #1a1a1a;
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
}

.indicator {
  font-size: 1.25rem;
  font-weight: 300;
  color: #9b9b9b;
}

.divider {
  height: 1px;
  background: #1a1a1a;
  width: 0%;
  transition: width 400ms cubic-bezier(0.16, 1, 0.3, 1);
}

.divider.expanded {
  width: 100%;
}

.content {
  padding: 0.75rem 0 1.5rem;
  font-size: 0.9375rem;
  color: #6b6b6b;
  line-height: 1.65;
}

Apr 27, 2026

ANIMATIONS

Cursor Hover Label

A custom cursor label that follows the mouse and fades in when hovering trigger elements. Uses GSAP quickTo for smooth tracking. Trigger elements use data-cursor-label attributes to set label text. Inspired by portfolio/agency sites like Studio PIC.

Apr 27, 2026

ANIMATIONS

Section Transition 01

GSAP ScrollTrigger-based section transition system. Sibling sections opt into parallax, pin, or reveal modes via data attributes. Supports y offset, overlay opacity, and overlay color per section. Mobile strategy simplifies motion on smaller screens.

Apr 27, 2026

ANIMATIONS

Text Reveal 01

GSAP SplitText-based text reveal system. Text elements opt in with data-reveal-01 and split into lines, words, or characters. Supports load-time reveals, scroll-triggered reveals, scrubbed scroll reveals, and manual split-only mode for custom timelines. Per-element overrides for duration, stagger, delay, ease, and replay behavior.