Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/observatory/llms.txt
Use this file to discover all available pages before exploring further.
PolaroidTestimonials displays colleague testimonials as a row of polaroid-style photo cards. Each card is slightly rotated and offset to give the impression of a scatter of printed photographs. Hovering a card flattens its tilt and scales it up using Framer Motion’s whileHover prop, bringing it visually to the front.
Visual appearance
Cards are arranged in aflex-wrap row with gap-8 md:gap-16 padding, centered on the page. Each card is 288px (w-72) wide, with a light #e2e8f0 background (the characteristic off-white of a physical polaroid), p-4 on the sides and top, and pb-12 for the bottom caption area, mimicking the wider white border at the base.
A small “tape” element is absolutely positioned at the top center — a w-24 (96px) × h-6 (24px) translucent white strip rotated slightly, simulating a piece of tape holding the polaroid to a surface.
Photo placeholder
The upper portion of each card is a square (aspect-square) image area with a border border-slate-300 and an overflow: hidden. The photo is replaced by a CSS gradient using the imageHue value:
1px dots, 20px spacing) at 30% opacity sits on top of the gradient, followed by a blurred white shine strip at the bottom half of the image, skewed at -12° to simulate a natural light reflection.
Caption area
The quote text is rendered infont-sans text-slate-800 text-sm italic with " and " wrappers. The author name and role are positioned absolute bottom-4 right-4 in a right-aligned block:
- Author:
font-display font-bold text-slate-900 text-sm - Role:
font-mono text-[10px] text-slate-500
Animations
| Effect | Implementation |
|---|---|
| Card entrance | m.div initial: { opacity: 0, y: 50, rotate: 0 } → animate: { opacity: 1, y: card.y, rotate: card.rotation, x: card.x }, spring type, staggered by index × 0.2s |
| Hover lift | m.div whileHover: { scale: 1.05, rotate: 0, zIndex: 50 } |
rotate: 0 so cards animate in straight before settling to their final tilt. The whileHover override snaps rotation back to zero and scales to 105%, creating a tactile “picking up a polaroid” feeling.
Where it’s used
PolaroidTestimonials is the primary content component on the /testimonials route:
Data shape
The testimonials array is defined incomponents/aurora/PolaroidTestimonials.js.
Unique identifier for the testimonial. Used as the React key.
Full name or abbreviated name of the person giving the testimonial. Displayed in bold display font in the card caption.
Job title and company string (e.g.,
'Lead Architect @ Nova Systems'). Displayed in small monospace below the author name.The testimonial quote body. Displayed in italic serif within
" double quotation marks. Keep to 1–3 sentences to fit within the card without overflow.CSS rotation in degrees applied to the card at rest. Negative values tilt left; positive values tilt right. Typical range:
-5 to 5. On hover, rotation is overridden to 0.Framer Motion
x offset in pixels applied to the card in the animate state. Use small values (-20 to 20) for a subtle horizontal displacement from the flex grid position.Framer Motion
y offset in pixels applied to the card. Use small values (0 to 50) to stagger card heights slightly, creating a scattered feel.CSS hue value (
0–360) used to generate the photo placeholder gradient. The gradient spans from hsl(imageHue, 30%, 15%) to hsl(imageHue + 40, 60%, 30%). Choose values that complement each other — teal (~190), purple (~260), and blue (~220) are used in the default set.How to customize
Layout tips
- Alternate rotation signs (positive/negative) across cards to create a natural scattered feel.
- Keep
rotationvalues within±6°— steeper angles look unnatural and can clip the caption text. - Vary
yoffsets to stagger vertical positions. Avoid largeyvalues that push cards out of the flex row container. - Choose
imageHuevalues at least 30° apart to give each card a distinct color identity. - 3–5 cards work best — the
flex-wraplayout handles any number, but more than 5 may require scrolling on mobile.