# Holo Card

> Collectible trading card with a real holographic foil and glitter that sparkles as it tilts toward the light.

A trading card rendered through a WebGL2 shader: the print sits on a metal foil with one of eight holo patterns, and a glittering border catches the light. Move the pointer over the card to tilt it and steer the light; when nobody is hovering it drifts on its own. Give it a `back-image` and a click, Enter or Space flips it over.

<demo-holo-card>



</demo-holo-card>

## Installation

```bash
npx shadcn-vue@latest add "https://nxui.geoql.in/r/holo-card.json"
```

## Usage

```vue
<script setup lang="ts">
  import HoloCard from '~/components/ui/holo-card/HoloCard.vue';
</script>

<template>
  <HoloCard
    image="/cards/pikachu.webp"
    back-image="/cards/back.webp"
    alt="Pikachu trading card"
    preset="bursts"
    foil-color="#e2e6ec"
    :intensity="0.85"
    :edge-sparkle="0.8"
    :frame="4"
    :tilt-max="14"
    :width="320"
  />
</template>
```

The image is uploaded as a WebGL texture, so it must be same-origin or served with CORS headers. The card height follows the image's aspect ratio.

## Props

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

<tbody>
  <tr>
    <td>
      <code>
        image
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Front of the card. Same-origin or CORS-enabled URL.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        back-image
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Back of the card. When set, a click or Enter flips the card over.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        alt
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Accessible description of the card.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        preset
      </code>
    </td>
    
    <td>
      <code>
        'bursts' | 'stars' | 'shards' | 'cosmos' | 'rainbow' | 'swirl' | 'glitter' | 'gold'
      </code>
    </td>
    
    <td>
      <code>
        'bursts'
      </code>
    </td>
    
    <td>
      The holo pattern. Bursts are rings of foil dashes, shards are cracked ice, swirl is one big round rainbow, gold is etched.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        foil-color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        '#e2e6ec'
      </code>
    </td>
    
    <td>
      Colour of the metal under the print, silver by default.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intensity
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.85
      </code>
    </td>
    
    <td>
      How strongly the foil shows through the print, from 0 for plain card to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        scale
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Size of the holo pattern. Higher values pack in more, smaller elements.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        edge-sparkle
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.8
      </code>
    </td>
    
    <td>
      Brightness of the glitter on the silver border as it catches the light.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        frame
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        4
      </code>
    </td>
    
    <td>
      Width of the sparkling border as a percentage of the card width. Match it to your card art.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        glare
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Strength of the glossy highlight under the light.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tilt-max
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        14
      </code>
    </td>
    
    <td>
      Largest tilt in degrees as the pointer moves.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        hover-scale
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1.04
      </code>
    </td>
    
    <td>
      How much the card lifts while hovered.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        radius
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        14
      </code>
    </td>
    
    <td>
      Corner radius in px.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        width
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        320
      </code>
    </td>
    
    <td>
      Card width in px, capped at the parent. The height follows the image.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        idle
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Drifts the light and tilt slowly when nobody is hovering, so the foil keeps shimmering.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        shadow
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Soft shadow under the card that follows the tilt.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes for the root element.
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- Without a back image the card is `role="img"` named by `alt`.
- With a back image it is a focusable `role="button"` with `aria-pressed` for the flipped state. Enter and Space flip it, and focus shows a visible ring.
- With `prefers-reduced-motion: reduce` the card stays flat: no tilt, no idle drift, and the flip jumps instead of turning.
- The render loop sleeps when the card is still or offscreen.
- Ported from [React Bits](https://reactbits.dev/components/holo-card) by David Haz.
