SectionsSimpleApril 22, 2026

Process Steps

A centered editorial heading with a 3-column numbered process grid below. Each step has a large serif number, title, and description. Configurable background color.

View Full Demo →

The Process

A jar of SHEABINTA passes through three pairs of hands before it reaches yours.

01

Sourced

Unrefined shea produced by women-led cooperatives in West Africa using traditional cold-press methods.

02

Whipped

Blended by hand with coconut oil, arrowroot, vitamin E, and essential oils in small, numbered batches.

03

Packed

Filled into 200ml glass jars. Labelled, dated, and shipped within seven days of being whipped.

demo.jsx
import ProcessSteps from "./index.jsx";
import { processSteps } from "../demo-data.js";

export default function ProcessStepsDemo() {
  return <ProcessSteps {...processSteps} />;
}
index.jsx
"use client";

import styles from "./styles.module.css";

export default function ProcessSteps({
  label,
  heading,
  headingEmphasis,
  steps = [],
  background = "#f1ebe7",
}) {
  const renderHeading = () => {
    if (!headingEmphasis || !heading) return heading;
    const parts = heading.split(headingEmphasis);
    if (parts.length < 2) return heading;
    return (
      <>
        {parts[0]}<em>{headingEmphasis}</em>{parts[1]}
      </>
    );
  };

  return (
    <section className={styles.section} style={{ background }}>
      {label && <p className={styles.label}>{label}</p>}
      {heading && <h2 className={styles.heading}>{renderHeading()}</h2>}

      <div className={styles.grid}>
        {steps.map((step, i) => (
          <div key={i} className={styles.step}>
            <span className={styles.number}>{step.number || String(i + 1).padStart(2, "0")}</span>
            <h3 className={styles.title}>{step.title}</h3>
            <p className={styles.description}>{step.description}</p>
          </div>
        ))}
      </div>
    </section>
  );
}
styles.module.css
.section {
  width: 100%;
  padding: 6rem 2rem 7rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

/* ---- Label ---- */
.label {
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: #777;
  margin-bottom: 1.5rem;
}

/* ---- Heading ---- */
.heading {
  font-family: Georgia, "Times New Roman", serif;
  font-size: clamp(2rem, 4.5vw, 3.75rem);
  font-weight: 400;
  line-height: 1.15;
  color: #1a1a1a;
  max-width: 22ch;
  margin-bottom: 4rem;
}

.heading em {
  font-style: italic;
}

/* ---- Grid ---- */
.grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 3rem;
  width: 100%;
  max-width: 1200px;
  text-align: left;
}

/* ---- Step ---- */
.number {
  font-family: Georgia, "Times New Roman", serif;
  font-size: clamp(2.5rem, 4vw, 3.5rem);
  font-weight: 400;
  color: #a8875b;
  line-height: 1;
  display: block;
  margin-bottom: 0.75rem;
}

.title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: clamp(1.1rem, 1.5vw, 1.35rem);
  font-weight: 400;
  color: #1a1a1a;
  margin-bottom: 0.5rem;
}

.description {
  font-size: clamp(14px, 1.1vw, 16px);
  line-height: 1.6;
  color: #666;
  max-width: 40ch;
}

/* ---- Desktop ---- */
@media (min-width: 768px) {
  .grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 2rem;
  }
}

/* ---- Mobile ---- */
@media (max-width: 767px) {
  .section {
    padding: 4rem 1.5rem 5rem;
  }
}

May 11, 2026

SECTIONS

Dual Push Cards

Two-up CTA card section with scroll-driven parallax on each card's background image. Cards scale down and drift vertically as you scroll past. Glassmorphic blur buttons at bottom-left. Stacks on mobile, side-by-side grid on desktop.

May 4, 2026

SECTIONS

Portfolio Grid

A responsive portfolio showcase section with a header tagline, blinking cursor counters, a 2-up/4-col project card grid with hover-zoom images and data-label metadata, plus a full-width CTA button. Scroll-triggered fade and move-up animations via GSAP.

May 1, 2026

SECTIONS

Logo Wall Cycle

A responsive logo grid that cycles through brand logos with smooth GSAP-powered swap animations. Shows 8 logos on desktop and 6 on tablet, shuffling hidden logos into view on a timed loop. Pauses when out of viewport or tab is hidden.