# Case Study Flip Stack

> An editorial, scroll-driven case study stack where each full-width card folds upward to reveal the next story beneath it.

An editorial case study sequence. Scroll down: the stack pins in place and each card folds up and away, while the card below lifts from its resting offset to take its place.

<demo-case-study-flip-stack>



</demo-case-study-flip-stack>

## Installation

```bash
npx shadcn-vue@latest add "https://nxui.geoql.in/r/case-study-flip-stack.json"
```

## Usage

```vue
<script setup lang="ts">
  import CaseStudyFlipStack from '~/components/ui/case-study-flip-stack/CaseStudyFlipStack.vue';
  import type { CaseStudyFlipItem } from '~/components/ui/case-study-flip-stack/types';

  const items: CaseStudyFlipItem[] = [
    {
      eyebrow: 'Fintech',
      title: 'Boosted conversion by 42% with a product-led redesign',
      description: 'We rebuilt onboarding around the moments that matter.',
      image: '/work/fintech.jpg',
      imageAlt: 'Portrait from the fintech campaign',
      background: '#a94808',
      foreground: '#fff7ed',
    },
    {
      eyebrow: 'Hospitality',
      title: 'A slower digital experience for a faster-growing retreat',
      description:
        'A cinematic booking journey with a stronger sense of place.',
      image: '/work/retreat.jpg',
      imageAlt: 'A mountain retreat at dusk',
      background: '#067b8f',
      foreground: '#ecfeff',
    },
  ];
</script>

<template>
  <CaseStudyFlipStack :items="items" />
</template>
```

The stack tracks the nearest scrollable ancestor, or the window when there is none. Section heights follow that scroller's height, so it works full-page and inside a scrolling panel.

## Props

<table>
<thead>
  <tr>
    <th>
      Prop
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        items
      </code>
    </td>
    
    <td>
      <code>
        CaseStudyFlipItem[]
      </code>
    </td>
    
    <td>
      4 sample case studies
    </td>
    
    <td>
      Case studies with copy, image, alt text, and card colors
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        hint
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'Scroll Down'
      </code>
    </td>
    
    <td>
      The animated opening instruction between the arrows
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        heading
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'Design That Delivers.'
      </code>
    </td>
    
    <td>
      The large introduction heading shown before the card stack
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        end-label
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'The End'
      </code>
    </td>
    
    <td>
      The closing message revealed after the final card stacks
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Additional classes for the root container
    </td>
  </tr>
</tbody>
</table>

### `CaseStudyFlipItem`

<table>
<thead>
  <tr>
    <th>
      Field
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Optional label; defaults to the zero-padded index
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        eyebrow
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Small uppercase category
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        title
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Card heading
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        description
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Body copy
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        image
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Image URL
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        imageAlt
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Image alt text
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        background
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Card background color
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        foreground
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Optional text color (default <code>
        white
      </code>
      
      )
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- Every card is an `<article>` with a heading and real image alt text, so the content reads in order without the animation.
- The bobbing arrows are `aria-hidden`.
- With `prefers-reduced-motion: reduce`, cards fade out in place instead of folding, the scroll spring is skipped, and the arrows stop moving.

## Credits

- Ported from [componentry.fun](https://componentry.dev/docs/components/case-study-flip-stack) by Harsh Jadhav.
