Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/groovy/llms.txt

Use this file to discover all available pages before exploring further.

RecordCrate presents blog posts as physical vinyl records stored in a wooden crate — a nod to every record shop in 1970s Greenwich Village. Five records sit in a stacked 3D arrangement inside an amber-800 crate with a wood-texture background. Clicking any record fans it upward out of the crate, exposing the colourful label area on its face. The label displays the post’s date, title, excerpt, and a Read Track button. Clicking an open record (or any other record) collapses it back into the crate.

Configuration

RecordCrate accepts no props. Blog post data is sourced from the hard-coded array d inside the component file. Each entry has the following shape:
{
  title:   string,  // Blog post title, shown on the label
  date:    string,  // Publication date string, e.g. "June 1973"
  excerpt: string,  // One- or two-sentence summary of the post
  color:   string,  // Hex color for the record label background
}
To update, add, or remove posts, edit the d array in RecordCrate.js.

Animation Model

Each record is a motion.div. The selected state variable (a useState(null) holding the index of the open record) tracks which record (if any) is currently fanned out. The animation for each record at index r is:
StateyrotateXscale
Selected-250px01.1
Hovered (below selected)-(r × 15) − 20px301
Default (collapsed)-(r × 15)px151
Records start from initial: { y: -(r × 15), rotateX: 20 }. The transition uses Framer Motion’s default spring for a physical, bouncy pop. Only one record can be expanded at a time; clicking a different record collapses the current selection and fans out the new one in a single state update.
The 3D crate effect is achieved with CSS perspective on the crate container and individual rotateX transforms on each record to simulate depth. The crate itself uses bg-amber-800 with a bg-[url('/textures/wood.png')] overlay — ensure public/textures/wood.png exists in your project, or replace the class with a solid amber gradient if the texture asset is not available.

Expanded Label Area

When a record is fanned out, the lower half of the record face reveals the label section:
  • Date — displayed in a small monospace font at the top of the label
  • Title — large, bold text matching the record’s color accent
  • Excerpt — paragraph-weight body copy
  • Read Track button — a pill-shaped link styled with the record’s color as background; wired to navigate to the full blog post

Usage

import RecordCrate from './components/RecordCrate';

function BlogSection() {
  return (
    <section className="py-24 flex flex-col items-center gap-12">
      <h2 className="text-5xl font-bold text-amber-900">From The Crate</h2>
      <RecordCrate />
    </section>
  );
}
Keep excerpt text under 120 characters so it reads cleanly within the label’s constrained width without truncation. If a title is longer than ~30 characters, consider using text-ellipsis on the label heading to prevent overflow at small viewport widths.

Build docs developers (and LLMs) love