business-ops
Business operations: strategy, technology, growth, competitive intelligence, support, finance, HR, legal, operations, sales, productivity, product management.
Standalone WebGL fragment shaders for card visual effects: holographic foil, shimmer, rarity glow.
$ npx -y skills add notque/vexjoy-agent --skill webgl-card-effects --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/webgl-card-effectsContext preview
The summary Claude sees to decide when to auto-load this skill.
Standalone WebGL fragment shaders for card visual effects: holographic foil, shimmer, rarity glow.
name: webgl-card-effects
promoted_to: distinctive-frontend-design
description: "Standalone WebGL fragment shaders for card visual effects: holographic foil, shimmer, rarity glow."
agent: typescript-frontend-engineer
user-invocable: false
command: /card-effects
allowed-tools:
- Read
- Write
- Bash
- Grep
- Glob
- Edit
routing:
triggers:
- card effects
- holographic
- foil effect
- card shimmer
- card glow
- shader card
- WebGL card
- rarity effects
- Balatro effect
- card visual effects
pairs_with:
- typescript-frontend-engineer
- ui-design-engineer
complexity: Medium
category: frontendThis skill adds GPU-accelerated visual effects to React card components using standalone WebGL2 fragment shaders — no Three.js, no R3F, no external library required. It targets deckbuilder games and card UIs where rarity tiers should feel visually distinct, not just differentiated by a CSS `box-shadow` value.
**Scope**: Holographic foil overlays, metallic shimmer bands, rarity-driven energy pulses, and interactive tilt-shine effects mounted directly on React card components. The canonical target is `FramedCard.tsx` in a React 19 / Vite / Tailwind project with a rarity system (starter → common → uncommon → rare → legendary).
**Not in scope**: 3D transformations, texture loading, post-processing pipelines, or any Three.js scene management. For those, use `threejs-builder`.
**Key constraint**: Browsers cap WebGL contexts at roughly 8–16 total per page. This skill uses a single shared WebGL2 context with blit-to-2D-canvas output per card, avoiding the per-card context problem entirely. See `references/shader-integration-react.md` for the full singleton pattern.
---
**Goal**: Understand which effects are needed and confirm the card component structure before writing any code.
**Step 1: Read the card component**
Read these files before writing anything:
Confirm:
**Step 2: Select effect tier per rarity**
| Rarity | WebGL? | Effect | |--------|--------|--------| | starter / common | No | CSS shimmer only — no WebGL overhead | | uncommon | Yes (subtle) | Metallic band shimmer, very low opacity | | rare | Yes (medium) | Moving shimmer + blue hue shift + edge pulse | | legendary | Yes (full) | Rainbow holographic foil, mouse-reactive tilt |
**Step 3: Confirm React version**
Check `package.json` for the React version. This skill assumes React 19 (ref as prop, no forwardRef). If the project uses React 18, canvas refs require `useRef` + standard ref passing.
**Gate**: Rarity values confirmed, CARD_SIZE_CONFIG read, effect tiers decided. Proceed only when this gate passes.
---
**Goal**: Write working GLSL shaders and the WebGL initialization harness.
Load `references/card-shader-patterns.md` now.
**Step 1: Create the shader strings module**
Create `src/components/cards/effects/cardShaders.ts`. This file holds:
Every shader must expose this exact uniform interface:
uniform float u_time; // seconds elapsed, JS wraps at 1000.0 uniform float u_rarity; // 0.0=starter/common, 0.25=uncommon, 0.5=rare, 1.0=legendary uniform float u_hover; // 0.0 to 1.0, lerped by JavaScript each frame uniform vec2 u_mouse; // normalized card-space [0,1] mouse position uniform vec2 u_resolution; // canvas pixel dimensions (width, height) uniform float u_upgraded; // 0.0 or 1.0 — upgraded cards get slightly more intense effect
**Step 2: Create the WebGL harness hook**
Create `src/components/cards/effects/useCardShader.ts`.
Load `references/shader-integration-react.md` for the full hook source. The hook must:
**Step 3: Shader construction for each tier**
Load `references/balatro-shader-breakdown.md` for the legendary holographic shader GLSL source.
For rare: use the shimmer band + hue shift layer from the breakdown, omit the rainbow foil layer.
For uncommon: use only the metallic band pass (single moving highlight), opacity 0.3 maximum.
**Gate**: Run `npx tsc --noEmit`. Zero TypeScript errors. Open browser console and verify `gl.getShaderInfoLog()` returns empty string for all shaders.
---
**Goal**: Mount the canvas overlay on `FramedCard.tsx` and wire rarity/hover state into the shader uniforms.
**Step 1: Derive render decision**
Inside `FramedCard`, after the existing `const shouldShine` line:
const shouldRenderShader = ['uncommon', 'rare', 'legendary'].includes(rarity) && size !== 'xs' && size !== 'sm';
**Step 2: Call the hook**
const shaderCanvasRef = useCardShader({
rarity,
isHovered,
isUpgraded,
enabled: shouldRenderShader,
});**Step 3: Add the canvas overlay to JSX**
Inside the `motion.div` return, immediately after the frame `<img>` elem
Essays and writing behind this toolkit live at vexjoy.com. VexJoy Agent connects plain-English requests to specialist agents, skills, and workflows. /do selects the knowledge and tools needed for your task.
Repo: notque/vexjoy-agent
Business operations: strategy, technology, growth, competitive intelligence, support, finance, HR, legal, operations, sales, productivity, product management.
Design workflows — UX copy, design systems, design critique, accessibility review, design handoff, user research synthesis. Use when writing UI copy, reviewing…
Marketing: SEO audits, campaign planning, content strategy, email sequences, competitive analysis, brand review, performance reporting.