RSSAmplifier

Karl Koch · Mar 6, 2026

On fake news…paper

0
Sign in to vote or save

Karl Koch · Karl Koch

The vinyl shelf was about flipping through a crate of records, using pure 2D transforms with a spring config. When I started on the writing section, I didn’t want a second crate; I wanted something that felt like picking a card off a table.

The card stack reuses the shelf’s spring deflection and velocity gating, then adds depth. CSS perspective and translateZ give it a Z axis that 2D transforms cannot reproduce.

Resting tilt

Before you hover anything, every card leans back 3 degrees:

const REST_TILT = 3;
let targetRotateX = REST_TILT;

With perspective: 500px on the container, the three-degree tilt puts the top edge of each card farther away than the bottom. The stack looks as if it lies on a tilted surface. The vinyl shelf stays flat at rest; this angle gives the cards depth before interaction.

Picking up a card

When you hover, the card doesn’t just slide upward. It comes toward you along the Z-axis and tilts forward to face you:

if (isHovered) {
  targetY = -18;
  targetRotateX = -6;
  targetTranslateZ = 40;
  targetScale = 1.02;
}

The translateZ: 40 does most of the work. With a 500px perspective, 40px of Z travel makes the card appear about 9% larger through foreshortening, so it needs little explicit scaling. The rotateX: -6 moves it from a three-degree backward lean to a six-degree forward lean. Together, those transforms make the card lift and face the viewer.

The neighbours do the inverse. They tilt further back and sink into negative Z:

targetRotateX = REST_TILT + 4 * Math.exp(-Math.abs(distance) * 0.3);
targetTranslateZ = -20 * Math.exp(-Math.abs(distance) * 0.4);

At translateZ: -20, the immediate neighbour appears about 4% smaller through the same perspective maths. Exponential decay concentrates the push around the focused card: it advances while its neighbours retreat, like lifting a postcard from a stack.

The editorial card

The other half of the differentiation is visual. The vinyl shelf is imagery; album art does the talking. For writing, the card needs to be typographic. I leaned into a newspaper clipping metaphor: serif font for the title and snippet, a double-rule <hr> as a header divider, monospace tag in uppercase, tabular-nums on the date.

<hr className="border-hairline m-0 border-t-[3px] border-double" />
<h3 className="font-serif text-[0.9rem]/[1.2] font-bold text-balance">
  {card.title}
</h3>

Each card is 180×250px, a portrait ratio like a broadsheet column and tall enough to show a title, date, tag, and a few lines of the snippet before it clips. The .text-balance on the title avoids orphaned words. The serif + monospace pairing makes each card feel like a small printed artefact rather than a UI element.

Dual springs

The vinyl shelf uses one spring for everything; the card stack uses two. SPRING_LIFT (stiffness 260, mass 0.9) gives the focused card a light response. SPRING_PUSH (stiffness 140, mass 1.2) gives the neighbours more weight. Their different responses reinforce which card has focus.

The finished stack

The finished stack combines resting tilt, Z-depth on hover, perspective foreshortening, newspaper card design, and the shelf mechanics underneath. prefers-reduced-motion gets a clean five-column grid. Mobile gets a horizontal scroll strip with snap points.

Read the original on karlkoch.me

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.