SectionsSimpleApril 21, 2026

Editorial Intro

A centered editorial text block with uppercase label, large serif heading with italic emphasis, and a description with inline bold. Configurable background color. Reusable as a section divider or philosophy statement.

View Full Demo →

Our Philosophy

Skincare rooted in ingredients people have trusted for generations.

SheaBinta began with a simple belief: skincare should be simple. Every jar starts with unrefined shea butter and nourishing oils, thoughtfully crafted to deliver lasting hydration and support healthy, balanced skin.

demo.jsx
import EditorialIntro from "./index.jsx";
import { editorialIntro } from "../demo-data.js";

export default function EditorialIntroDemo() {
  return (
    <>
      <EditorialIntro {...editorialIntro} />

      <EditorialIntro
        label="The Mission"
        heading="Clean beauty, honestly made."
        headingEmphasis="honestly made."
        description="No fillers, no artificial fragrances — just pure ingredients your skin will love. We believe **good skincare** shouldn't need a chemistry degree to understand."
        background="#fff"
      />

      <EditorialIntro
        label="Our Promise"
        heading="Made for every skin. Tested by real people."
        headingEmphasis="every skin."
        description="From dry to sensitive, our formulas are designed to work across all skin types. Every batch is **small-batch tested** before it leaves our studio."
        background="#e8e0d8"
      />

      <EditorialIntro
        label="The Craft"
        heading="Whipped by hand, never mass-produced."
        headingEmphasis="by hand,"
        description="Each jar is made in small batches using traditional techniques passed down through generations of West African women."
        background="#1a1a1a"
        dark
      />
    </>
  );
}
index.jsx
"use client";

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

function RichText({ text }) {
  const parts = text.split(/(\*\*[^*]+\*\*)/g);
  return parts.map((part, i) => {
    if (part.startsWith("**") && part.endsWith("**")) {
      return <strong key={i}>{part.slice(2, -2)}</strong>;
    }
    return part;
  });
}

export default function EditorialIntro({
  label,
  heading,
  headingEmphasis,
  description,
  background = "#f1ebe7",
  dark = false,
}) {
  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} ${dark ? styles.dark : ""}`} style={{ background }}>
      {label && <p className={styles.label}>{label}</p>}
      {heading && <h2 className={styles.heading}>{renderHeading()}</h2>}
      {description && (
        <p className={styles.description}>
          <RichText text={description} />
        </p>
      )}
    </section>
  );
}
styles.module.css
.section {
  width: 100%;
  padding: 8rem 2rem;
  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, 4rem);
  font-weight: 400;
  line-height: 1.15;
  color: #1a1a1a;
  max-width: 20ch;
  margin-bottom: 1.5rem;
}

.heading em {
  font-style: italic;
}

/* ---- Description ---- */
.description {
  font-size: clamp(14px, 1.1vw, 16px);
  line-height: 1.65;
  color: #666;
  max-width: 55ch;
}

.description strong {
  color: #1a1a1a;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}

/* ---- Dark mode ---- */
.dark .label {
  color: rgba(255, 255, 255, 0.45);
}

.dark .heading {
  color: #fff;
}

.dark .description {
  color: rgba(255, 255, 255, 0.55);
}

.dark .description strong {
  color: #fff;
}

/* ---- Mobile ---- */
@media (max-width: 768px) {
  .section {
    padding: 5rem 1.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.