Sami Vuori Design system Back to site →

Story scroll

The heart of a case study: “slides” with a pinned visual and scrolling copy (Figma 104:816). Needs a full page, so see it live.

Live: Governance case study. Made for a 1496 × 848 laptop first.

How it behaves

Content rules

<StoryScroll steps={[
  { id: 'problem', label: 'Problem', title: 'No place for powerful governance', image: before,
    action: { href: 'https://figma.com/proto/…', label: 'View prototype' } },
  { title: 'What was at stake?', image: before },          // same image: same frame
  { quote: { text: '…', name: 'Intranet Operations Lead', role: 'Enterprise Software Company' } },
]}>
  <Fragment slot="step-0"><p>…</p></Fragment>
  <Fragment slot="step-1"><p>…</p></Fragment>
</StoryScroll>

Step

PropTypeDefaultDescription
label string — Eyebrow above the title, usually the chapter.
title string — H2. Leave out for a step that only continues a list.
subtitle string — H3 under the title.
id string — Anchor for a chapter start.
image { src; alt } — The visual (1040 × 740).
action { href; label } — Primary button floating on the visual, centred near the bottom (Figma 118:1253), e.g. "View prototype".
quote { text; name; role } — A customer quote as the visual (Story quote, below).
color string — Placeholder visual colour while there is no image.

Story quote

A customer quote as a step's visual (Figma 132:1466): text on the article band, not an image, so it's crisp and light. All sizes are Figma pixels of the 1040-wide visual times --story-px, so it scales with the visual.

Honestly, when I opened this, I was like: ‘Yes! This is so much easier.’
Intranet Operations Lead Enterprise Software Company

Tokens

Token Base≥ 1024 Note
--story-visual-ratio 1040 / 740
--story-visual-width 0pxmin(calc((100dvh - var(--chapter-nav-height) - var(--story-visual-top)) * 1040 / 740), calc(100% - var(--story-copy-min-width))) ≥ 1024: sized by the screen height
--story-stage-display noneflex mobile: visual inline per step
--story-inline-display blocknone
--story-steps-pt 0pxvar(--spacing-3xl) copy starts 64 below the chapter bar
--story-step-scroll-margin var(--chapter-scroll-margin)calc(var(--chapter-nav-height) + var(--story-steps-pt)) a chapter jump lands there too
--story-action-bottom var(--spacing-md)var(--spacing-xl) floating button on a visual
--story-steps-pb 0px40dvh the last step can reach mid-screen
--story-gap var(--spacing-lg) between all copy blocks (Figma)
--story-frame-gap var(--spacing-3xl)var(--spacing-edge) extra break before a new visual
--story-copy-max-width none34em
--story-inactive-opacity 10.25
--story-px calc(100cqw / 1040)
--story-quote-width 570
--story-quote-mark-width 142
--story-quote-mark-gap 20
--story-quote-mark-size 160
--story-quote-mark-line-height calc(129 / 160)
--story-quote-text-size 36
--story-quote-gap 48
--story-quote-attribution-size 22
--story-visual-top 0px visual fills the height under the chapter bar
--story-copy-min-width 360px