# Holo Foil Card

> Trading-card holographic tilt: one pointer drives 3D rotation, an iridescent foil sheen, twinkling glitter, depth parallax and a specular bloom, then settles elastically.

Canonical: https://gsapvault.com/effects/holo-foil-card
Live demo: https://gsapvault.com/demos/holo-foil-card/index.html

| Property | Value |
|----------|-------|
| Type | effect |
| Tier | paid |
| Price | £5 |
| Difficulty | advanced |
| Plugins | Core GSAP only |
| Techniques | 3d-transforms, pointer-effects, blend-mode, hover-effect, velocity-reactive, micro-interaction |
| Uses Lenis | No |

## Overview

A card that behaves like real holographic foil. Move a pointer across it and five things answer the same gesture at once: the card tilts in 3D, a prismatic sheen slides across its face and shifts hue with the angle, a glitter layer twinkles on its own clock, the art and the type separate into depth, and a specular highlight tracks the light.

Whip the pointer across it and the extreme state opens up: the sheen sweeps hard, the tilt overshoots past the pointer, and the glare blooms out to a blown highlight. Let go and it does not snap; it settles back to its resting pose with a single elastic overshoot.

The foil is CSS, not a filter: layered gradients under color-dodge, overlay and soft-light, positioned by custom properties that GSAP quickSetters write. Three recipes ship (rainbow prism, brushed chrome, cracked ice) and writing a fourth is one background rule.

## Features

- Five channels on one input: 3D tilt, angle-dependent iridescent sheen, independently twinkling glitter, art-versus-type depth parallax, and a specular glare that blooms only near grazing angles
- Real material layering rather than a hue-rotate: prismatic gradients under color-dodge, a specular under overlay, a laminate bevel under soft-light, and a screen-blend bloom that stays shut until it is earned
- Whip response with velocity lead, so a hard flick makes the tilt overshoot past the pointer and the highlight blow out, then recover
- Elastic settle back to a per-card resting pose, defined in CSS so the card looks identically lit with JS, without JS, and under reduced motion
- Three shipped foil recipes (rainbow prism, brushed chrome, cracked ice), each a different material; a new one is a single background rule on a data-foil value
- Touch drag as a first-class channel with pointer capture and pan-y, so a phone visitor tilts the card and can still scroll the page
- Device orientation as an optional enhancement, with the iOS permission prompt behind a button that only appears where it is needed, and a silent fallback when it is denied or unavailable
- Attach to any card-shaped element with data-foil-card; tilt range, gloss strength and hue swing are per-card data attributes
- Keyboard accessible: a focused card plays the full sweep and arrow keys steer the tilt, with a focus ring that mirrors the hover lift
- Runs on GSAP core with no plugins, no canvas and no WebGL; the ticker only turns over while a card is actually being touched or settling

## Use Cases

- Collectible, membership and loyalty cards where the card itself is the product
- Pricing and plan cards that want the premium tier to feel physically different from the others
- Ticket, pass and NFT-style reveals where a holographic finish signals rarity
- Music, film and game merch pages showing off a foil-stamped edition
- Portfolio and agency hero sections needing one tactile, clip-worthy object above the fold

## Vibe-Code Ready Setup

This effect includes `START-HERE-AI.md`, a product-specific copy-paste setup prompt for Cursor, Claude Code, ChatGPT, GitHub Copilot, Windsurf, and other coding assistants. It tells the assistant to inspect the existing stack, integrate the supplied files, preserve the design, scope selectors, retain accessibility and responsive behaviour, add framework-appropriate GSAP cleanup, and report what it tested.

[How AI-assisted setup works](https://gsapvault.com/vibe-coding)

## How It Works

The card's whole material is CSS custom properties. A stack of absolutely positioned layers inside the card carries the prismatic grating, the glitter field, the specular and the bloom, each with its own blend mode, and every one of them is positioned or scaled by a variable. GSAP quickSetters write those variables plus the rotation, so a frame costs a handful of property writes and no style recalculation of the layout.

Pointer position sets the target tilt, but pointer velocity is added on top as a lead angle: the card aims past where the pointer actually is, in proportion to how fast it is travelling. When the flick stops, the lead collapses and the follow tween pulls the card back through centre, which is the overshoot. Speed also sets an energy value that decays on its own clock; energy is what opens the bloom, so a slow drag to the same angle never blows the highlight out.

The grating slides several times faster than the card turns and its hue rotates with the angle, which is what stops the foil reading as a picture printed on the card. The glitter parallaxes faster still through a masked band that drifts on an independent loop, so it twinkles even while the card is held still.

Release runs an elastic.out tween back to the resting angle, which is read from the CSS --rest-x and --rest-y properties rather than assumed to be flat. That is why a card composed at a tilt returns to exactly the pose the stylesheet drew, and why the no-JS and reduced-motion renders are the same composed, lit object.

## Integration Preview

How this effect integrates into a page. The full documentation (examples, events, programmatic API, customization guide) ships with the download.

### Quick Start

**1. Add to your HTML `<head>`:**

```html
<link rel="stylesheet" href="path/to/style.css">
```

**2. Add before closing `</body>` tag:**

```html
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<script src="path/to/script.js"></script>
```

**3. Add the card structure to your `<body>`:**

```html
<article class="foil-card" data-foil-card data-foil="prism" tabindex="0" role="group"
         aria-label="Prism, rainbow foil card. Move a pointer across it to tilt it.">
  <div class="foil-card__inner" data-foil-inner>
    <div class="foil-card__art" data-foil-parallax="back">
      <!-- your artwork: an <img>, inline SVG, or nothing at all -->
    </div>
    <div class="foil-layer foil-layer--sheen" aria-hidden="true"></div>
    <div class="foil-layer foil-layer--sparkle" aria-hidden="true"></div>
    <div class="foil-card__face" data-foil-parallax="front">
      <!-- your card content: name, chips, whatever -->
    </div>
    <div class="foil-layer foil-layer--glare" aria-hidden="true"></div>
    <div class="foil-layer foil-layer--bloom" aria-hidden="true"></div>
    <div class="foil-card__frame" aria-hidden="true"></div>
  </div>
</article>
```

The script finds every `[data-foil-card]` and wires up pointer, touch, keyboard and (where available) device orientation. It writes nothing but custom properties and one rotation, so all the visual work stays in your stylesheet.

### Options

Per-card data attributes on the `[data-foil-card]` element.

| Attribute | Values | Default | Description |
|-----------|--------|---------|-------------|
| `data-foil-card` | marker | required | Makes the element a foil card |
| `data-foil` | any name you style | none | Selects a foil recipe. `prism`, `brush` and `ice` ship; a new one is a `[data-foil="yours"] .foil-layer--sheen` background rule |
| `data-foil-tilt` | degrees | `16` | Maximum tilt. A whip can lead past this by up to 60%. Above about 22 the card starts reading as a flap rather than a held object |
| `data-foil-gloss` | number | `1` | Multiplier on every light channel at once. `0.6` for a restrained card, `1.3` for a loud one |
| `data-foil-hue` | degrees | `130` | How far the spectrum rotates across the full tilt range. `0` gives a fixed-colour foil that still moves |

CSS custom properties you set (as opposed to the ones the script writes):

| Property | Default | Description |
|----------|---------|-------------|
| `--rest-x` | `0deg` | Resting X rotation. The card settles here, and renders here without JS |
| `--rest-y` | `0deg` | Resting Y rotation |
| `--w` | `280px` | Card width; height follows from `aspect-ratio` |
| `--art-base` | dark gradient | Background of the art plate behind your artwork |

Structural hooks the script looks for, all documented and all optional except the first:

| Hook | Description |
|------|-------------|
| `[data-foil-inner]` | The element that rotates. Required |
| `[data-foil-parallax="back"]` | Slides *with* the tilt: the layer that should feel behind the glass |
| `[data-foil-parallax="front"]` | Slides *against* it: the layer that should feel in front |
| `[data-foil-gyro-toggle]` | A button anywhere on the page, `hidden` by default. Revealed only on devices that gate orientation behind a permission prompt |

### Accessibility

- **Reduced motion**: with `prefers-reduced-motion: reduce` the script wires up nothing at all. The custom property defaults in the contract CSS are a fully lit card at its resting angle, so the reduced render is a composed object rather than a flat or blank one. Nothing is pre-hidden and nothing needs restoring.
- **Keyboard**: give each card `tabindex="0"`. Focus plays the same full sweep a tap does, and the arrow keys then steer the tilt directly. Blur runs the elastic settle, exactly like a pointer leaving.
- **Focus visible**: the `:focus-visible` rule pairs the accent ring with the same shadow lift the hover state uses, so keyboard and pointer users get the same affordance.
- **Labels**: the card is decorative furniture around real content, so give it `role="group"` and an `aria-label` describing the card, or drop both if the content inside already reads correctly on its own. Every foil layer is `aria-hidden`.
- **Touch**: `touch-action: pan-y` means a vertical swipe scrolls the page and a sideways drag tilts the card. A tap that never moves plays the sweep, so a coarse-pointer visitor always gets a response, and `pointercancel` releases safely.
- **Device orientation**: nothing is requested on load. On platforms that gate the sensor behind a permission prompt, a `[data-foil-gyro-toggle]` button is revealed and the prompt only happens if it is pressed; a refusal hides the button and changes nothing else, because touch drag was always the primary channel.

### Dependencies

**Required:**

- GSAP 3.12+ (core only, no plugins)

**Optional:**

- None. The effect has no scroll mechanic and does not use Lenis.

## What You Get

- `index.html`: working demo page
- `assets/script.js`: commented, readable source
- `assets/style.css`: effect styles
- `README.md`: full documentation with examples and framework integration notes
- `START-HERE-AI.md`: product-specific copy-paste prompt for AI-assisted setup
- `LICENSE.txt`: standard license terms
- Lifetime updates: re-download anytime from your library

## Get the Code

This is a premium effect. The standard license costs £5 one-time and covers unlimited personal and commercial projects with no attribution required. The only restrictions: no redistribution of the code itself and no competing effect libraries.

- [Buy Holo Foil Card](https://gsapvault.com/effects/holo-foil-card)
- [Effects & Templates Vault (£39 one-time, best value): every current and future effect and template](https://gsapvault.com/effects)

## Judge the Code Quality First

These related effects are free with complete source published, written to the same production standard (cleanup functions, reduced-motion support, framework-agnostic):

- [Hover Underline](https://gsapvault.com/effects/hover-underline.md): Three material link underlines—an exit-through line, marker sweep, and hand-drawn wave—with coordinated type and active-index responses.
- [3D Card Flip Gallery](https://gsapvault.com/effects/3d-card-flip.md): Tactile 3D cards with deep perspective, reactive edge-light, shadow inversion, hover/focus parity, and tap auto-close.

---

From [GSAP Vault](https://gsapvault.com): production-ready GSAP animation effects. Full catalog for agents: https://gsapvault.com/llms-full.txt
