Quote card layout lab

The same card parts, rearranged to give width back to the words, so a card can sit beside a screengrab on the Screens lens at one width everywhere. Every frame draws the same five invented quotes with the markup QuoteCard.tsx renders. Measurements are taken live in this browser.

Artefact — real classes, real pixelsCommentary — not the product

1 · Measure: every variant at 270, 320 and 380px

Variant270px320px380pxoverhead
(card − measure)
card width for
the list measure
measureΔw/lineheightmeasureΔw/lineheightmeasureΔw/lineheight

Measure is the width of the column the long quote's words flow in. Words per line averages every full line of all five quotes (last lines excluded). Height is the five cards' total, without gaps.

Control shippedShipped list card (Quotes lens)
Control · 270px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
Control · 320px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
Control · 380px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
Control S shippedShipped Screens card today (screens.css overrides, 13px words)
Control S · 270px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
Control S · 320px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
Control S · 380px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
A CSS onlyTimecode on a top row with the eye and star; words full width; left padding halved
A · 270px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
A · 320px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
A · 380px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
B CSS onlyA with the left padding kept at 1rem
B · 270px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
B · 320px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
B · 380px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
C CSS only (plus name truncation)Top row: timecode and participant badge left, eye and star right; tags under the words
C · 270px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
C · 320px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
C · 380px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
D1 CSS onlyTimecode runs in at the start of the first line; the first line alone leaves room for eye and star
D1 · 270px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
D1 · 320px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
D1 · 380px
[00:42]
“I'd just search for it.” p2Rowan
+
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[1:04:38]
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
delight+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
D2 DOM changeWords first, full width; timecode, tags, eye and star share the one row beneath
D2 · 270px
“I'd just search for it.” p2Rowan
[00:42]+
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
[03:17]frustration+
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
[12:05]saved filtersreturn visit+
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
[1:04:38]delight+
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
[27:51]confusionnavigation+
D2 · 320px
“I'd just search for it.” p2Rowan
[00:42]+
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
[03:17]frustration+
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
[12:05]saved filtersreturn visit+
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
[1:04:38]delight+
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
[27:51]confusionnavigation+
D2 · 380px
“I'd just search for it.” p2Rowan
[00:42]+
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
[03:17]frustration+
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
[12:05]saved filtersreturn visit+
“Honestly that's the first checkout this year that didn't make me feel like I'd done something wrong.” p1Tamsin
[1:04:38]delight+
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
[27:51]confusionnavigation+

What each variant buys and costs

VariantBuysCosts
ControlThe hanging timecode column lets the eye run down the timecodes of a list; the words start at one edge. Measured overhead 153px of every card width: the 1px keyline, 16px left padding, the timecode column (~56px plus an 8px gap) and the right reserve for the eye and star (4.5rem, 72px — .quote-group .quote-card). At 270px the words get 117px, under half the card. At 270px a long name runs past the card's right edge (blockquote .speaker is nowrap) — Control S too.
Control SScreens already trims: 12px timecode, 13px words, right reserve 2rem. The words drop to 13px (label size), which is chrome size, not the participant's voice. Overhead is still 103px because the timecode column and a 2rem right reserve remain.
AThe whole width minus 8px + 16px goes to the words. Same parts, same order of meaning (when, then what was said, who, tags). Pure CSS on the shipped DOM. One extra row per card for the top line: about 21px (five cards at 380px: 704px against D2's 598px). The timecodes no longer form a column you can scan in a list. 8px of gutter against the left keyline.
BIsolates the gutter: everything A gives except 8px.8px narrower than A; same extra row.
CA's measure, and the participant badge leaves the end of the quote, so the last line of words often ends sooner — about the same height as A. Reads like a message header: when, who, then what. A long name is truncated with an ellipsis (the code never is). Attribution moves from after the words to before them — a change in how a quote reads, not only where. Needs four small rules beyond the move.
D1No extra row: five cards at 380px are 620px against A's 704px. Every line after the first gets A's full width. The first line loses the timecode and the toggle space, so a short quote gains little. The timecode sits in the words' line at a different size and face; a run-in reads busier than a header.
D2No extra row, and the first line is full width too: the most words per card height. The timecode joins a row that already exists for "+". The only variant that changes the DOM. The star (a state mark, not only a control) moves to the bottom right, far from where the eye starts on a long quote. The timecode is read last.

Keyboard and accessibility, per variant

Reading order (DOM)Focus order vs what you seeHit targets
Controltimecode · words · participant · tags · + · eye · star Tab reaches the eye and star last, but they are drawn first-line right. Existing mismatch. Measured in the states frames: about 18×18 (star) and 19×19 (eye), centres about 22px apart — under the 24px of WCAG 2.5.8 in size and in spacing. Unchanged by A, B, C, D1.
A, BunchangedSame mismatch, now more visible: the eye and star share the timecode's row, and Tab goes timecode → participant → tags → + → back up to the eye. Fix in the DOM: render the hide and star toggles straight after the timecode. Same buttons. The top row has room to move the eye left by 2px (right: 2.15rem) and clear 24px spacing — free in A/B/C, impossible in the control where the words sit under them.
CunchangedVisual order is timecode, participant, eye, star, words, tags; DOM order is timecode, words, participant, tags, eye, star. The largest mismatch of all: worth a DOM change if C wins.As A.
D1unchangedAs the control: the toggles are drawn at the end of line 1 and reached last.As the control.
D2words · participant · timecode · tags · + · eye · starMatches: the toggles come after the tags in both.In flow, so spacing follows .badges's gap (0.35rem): centres measured 24px apart; the size is unchanged.

Screen readers hear the same content in every variant except D2, where the timecode comes after the words. The blockquote has no accessible name of its own, so the order of its children is the order a reader hears.

2 · States, light and dark

3 · Sandbox: drag the width

The long quote, the tagged quote and the long name, in every variant at the slider's width.

Control · 320px
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
Control S · 320px
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
A · 320px
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
B · 320px
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
C · 320px
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
D1 · 320px
[03:17]
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
frustration+
[12:05]
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
saved filtersreturn visit+
[27:51]
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
confusionnavigation+
D2 · 320px
“I scrolled right past the delivery options the first time because they looked like an advert, and by the time I found the cheaper one I'd already typed my card number in, so I just went with the fast one and paid extra.” p4Ines
[03:17]frustration+
“The filter remembered my size, which was nice, but then it hid the things I'd actually come back for.” p7Dev
[12:05]saved filtersreturn visit+
“Where's the button to go back? I thought that was it.” p12Maximiliana Oyelaran-Whitcombe
[27:51]confusionnavigation+

4 · Implementation and trade-offs

Implementing the winner in QuoteCard.tsx and the theme

Written for A (the owner's first idea, CSS only), with what changes for C or D2. Nothing here is implemented.

Trade-offs with editing, trimming, tag input and focus