# Shadow Card

> Composable marketing card for React and shadcn/ui with an extruded edge, bevel layers, vertical text, and a pixel gradient mesh.

Source: https://www.cult-ui.com/docs/components/shadow-card

## Example

```tsx title="shadow-card-demo.tsx"
"use client"

import {
  ShadowCard,
  ShadowCardBackdrop,
  ShadowCardBevel,
  ShadowCardFooter,
  ShadowCardGlow,
  ShadowCardPixelGradient,
  ShadowCardVerticalText,
} from "@/components/ui/shadow-card"

const CARD1_DOT_PATTERN = [
  1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1,
  1, 1, 1, 0,
]

function ShadowCardDemoCard1() {
  return (
    <ShadowCard className="h-[420px] w-[280px]">
      <ShadowCardBackdrop
        className="inset-0"
        style={{
          background: `
            radial-gradient(ellipse at 30% 20%, rgba(255, 100, 200, 0.8) 0%, transparent 50%),
            radial-gradient(ellipse at 70% 70%, rgba(255, 180, 150, 0.6) 0%, transparent 40%),
            linear-gradient(180deg, #e8ddd4 0%, #d4c8bc 50%, #e8ddd4 100%)
          `,
        }}
      />
      <ShadowCardGlow
        className="top-20 left-32 h-20 w-16 rounded-full blur-xl"
        style={{ background: "rgba(50, 50, 80, 0.4)" }}
      />
      <ShadowCardVerticalText className="top-1/4 right-6 font-medium text-[10px] text-neutral-700 tracking-wide">
        <span className="block">Where Design And Product Teams</span>
        <span className="mt-1 block">Build The Future Of Software</span>
      </ShadowCardVerticalText>
      <ShadowCardFooter>
        <div className="grid grid-cols-6 gap-[2px]">
          {CARD1_DOT_PATTERN.map((visible, i) => (
            <div
              className="h-1.5 w-1.5 rounded-full bg-neutral-800"
              key={i}
              style={{ opacity: visible === 1 ? 1 : 0.3 }}
            />
          ))}
        </div>
        <div className="flex flex-col text-[6px] text-neutral-600 leading-tight">
          <span>THE DESIGN</span>
          <span>ZEPXEN</span>
        </div>
        <div className="flex h-4 w-4 items-center justify-center border border-neutral-800">
          <svg
            aria-hidden="true"
            fill="none"
            focusable="false"
            height="10"
            viewBox="0 0 10 10"
            width="10"
          >
            <path
              d="M2 8L8 2M8 2H3M8 2V7"
              stroke="currentColor"
              strokeWidth="1"
            />
          </svg>
        </div>
      </ShadowCardFooter>
      <ShadowCardBevel />
    </ShadowCard>
  )
}

function ShadowCardDemoCard2() {
  return (
    <ShadowCard className="flex h-[420px] w-[280px] flex-col bg-white">
      <div className="h-[52%] min-h-0 shrink-0 overflow-hidden">
        <ShadowCardPixelGradient />
      </div>
      <div className="flex h-[48%] flex-col justify-between px-5 pt-6 pb-5">
        <h2 className="font-semibold text-[22px] text-neutral-900 leading-tight tracking-tight">
          Where Design And Product Teams Build The Future Of Software.
        </h2>
        <p className="text-neutral-500 text-xs leading-relaxed">
          Design Is About To Have Its
          <br />
          GitHub Moment.
        </p>
      </div>
      <ShadowCardBevel />
    </ShadowCard>
  )
}

function ShadowCardDemo() {
  return (
    <div className="flex min-h-full w-full items-center justify-center gap-6 bg-[#f7d9c4] p-8">
      <ShadowCardDemoCard1 />
      <ShadowCardDemoCard2 />
    </div>
  )
}

export { ShadowCardDemo }
export default ShadowCardDemo
```

Shadow Card is a composable React card component for shadcn/ui. Use it for feature highlights, pricing tiers, or marketing sections on landing pages.

## Installation

### CLI

```bash
npx shadcn@latest add @cult-ui/shadow-card
```

### Manual

**Copy and paste the following code into your project.**

```tsx title="shadow-card.tsx"
import type { ComponentProps } from "react"
import { Slot } from "@radix-ui/react-slot"

import { cn } from "@/lib/utils"

/**
 * 3D-style L-shaped extrusion. Renders at z-10; place after backdrops/glow/content
 * in DOM order so it paints on top, or rely on z-10 vs default z-0 layers.
 */
function ShadowCardBevel({
  className,
  barClassName,
  ...props
}: ComponentProps<"div"> & {
  /** Applied to both vertical and horizontal bars (e.g. thickness, color). */
  barClassName?: string
}) {
  return (
    <div
      aria-hidden
      className={cn("pointer-events-none absolute inset-0 z-10", className)}
      data-slot="shadow-card-bevel"
      {...props}
    >
      <div
        className={cn(
          "absolute top-0 right-0 bottom-0 w-2 bg-black",
          barClassName
        )}
      />
      <div
        className={cn(
          "absolute right-0 bottom-0 left-0 h-2 bg-black",
          barClassName
        )}
      />
    </div>
  )
}

type ShadowCardProps = ComponentProps<"div"> & {
  asChild?: boolean
}

function ShadowCard({ className, asChild, ...props }: ShadowCardProps) {
  const Comp = asChild ? Slot : "div"
  return (
    <Comp
      className={cn("relative overflow-hidden rounded-sm", className)}
      data-slot="shadow-card"
      {...props}
    />
  )
}

function ShadowCardBackdrop({ className, ...props }: ComponentProps<"div">) {
  return (
    <div
      className={cn("absolute", className)}
      data-slot="shadow-card-backdrop"
      {...props}
    />
  )
}

function ShadowCardGlow({ className, style, ...props }: ComponentProps<"div">) {
  return (
    <div
      className={cn("absolute", className)}
      data-slot="shadow-card-glow"
      style={style}
      {...props}
    />
  )
}

const DEFAULT_SHADOW_CARD_PIXEL_COLORS: string[][] = [
  [
    "#e8d0e0",
    "#dcc4d8",
    "#d4bcd4",
    "#ccb4d0",
    "#c8b0cc",
    "#c8aec8",
    "#ccb0c8",
    "#d0b4c8",
    "#d8bcc8",
    "#dcc0c8",
  ],
  [
    "#e4c8d8",
    "#d8bcd0",
    "#d0b0c8",
    "#c8a8c0",
    "#c4a0b8",
    "#c4a0b4",
    "#c8a4b4",
    "#d0acb4",
    "#d8b4b8",
    "#e0bcbc",
  ],
  [
    "#e0c0d0",
    "#d4b4c8",
    "#cca8bc",
    "#c49cb0",
    "#c094a8",
    "#c090a0",
    "#c49498",
    "#cc9c98",
    "#d8a8a0",
    "#e0b4a8",
  ],
  [
    "#deb8c8",
    "#d0a8bc",
    "#c89cac",
    "#c0909c",
    "#bc8890",
    "#bc8488",
    "#c08884",
    "#cc9080",
    "#dca088",
    "#e8b094",
  ],
  [
    "#dcb0c0",
    "#cca0b0",
    "#c4909c",
    "#bc848c",
    "#b87c80",
    "#b87874",
    "#c08070",
    "#d09070",
    "#e4a47c",
    "#f0b88c",
  ],
  [
    "#d8a8b8",
    "#c898a4",
    "#c08890",
    "#b87c80",
    "#b47470",
    "#b87064",
    "#c87c5c",
    "#dc9460",
    "#f0ac70",
    "#fcc484",
  ],
  [
    "#d4a0b0",
    "#c49098",
    "#bc8084",
    "#b47474",
    "#b06c64",
    "#b8685c",
    "#cc7850",
    "#e49454",
    "#f8b068",
    "#ffd080",
  ],
  [
    "#d498a8",
    "#c08890",
    "#b8787c",
    "#b06c6c",
    "#ac645c",
    "#b46050",
    "#d07448",
    "#e8944c",
    "#fcb860",
    "#ffe080",
  ],
  [
    "#d09098",
    "#bc8088",
    "#b47074",
    "#ac6464",
    "#a85c54",
    "#b45848",
    "#d47044",
    "#ec9448",
    "#ffc05c",
    "#ffec88",
  ],
  [
    "#cc8890",
    "#b87880",
    "#b0686c",
    "#a85c5c",
    "#a4544c",
    "#b05040",
    "#d86c40",
    "#f09444",
    "#ffc858",
    "#fff490",
  ],
]

type ShadowCardPixelGradientProps = ComponentProps<"div"> & {
  /** Row-major grid of CSS color strings; defaults to the built-in pastel mesh. */
  colors?: string[][]
}

function ShadowCardPixelGradient({
  className,
  colors = DEFAULT_SHADOW_CARD_PIXEL_COLORS,
  ...props
}: ShadowCardPixelGradientProps) {
  return (
    <div
      className={cn("flex h-full w-full flex-col", className)}
      data-slot="shadow-card-pixel-gradient"
      {...props}
    >
      {colors.map((row, i) => (
        <div className="flex flex-1" key={i}>
          {row.map((color, j) => (
            <div
              className="flex-1"
              key={j}
              style={{ backgroundColor: color }}
            />
          ))}
        </div>
      ))}
    </div>
  )
}

function ShadowCardVerticalText({
  className,
  style,
  ...props
}: ComponentProps<"div">) {
  return (
    <div
      className={cn("absolute", className)}
      data-slot="shadow-card-vertical-text"
      style={{
        writingMode: "vertical-rl",
        textOrientation: "mixed",
        transform: "rotate(180deg)",
        ...style,
      }}
      {...props}
    />
  )
}

function ShadowCardFooter({ className, ...props }: ComponentProps<"div">) {
  return (
    <div
      className={cn("absolute bottom-6 left-6 flex items-end gap-3", className)}
      data-slot="shadow-card-footer"
      {...props}
    />
  )
}

export type { ShadowCardPixelGradientProps, ShadowCardProps }
export {
  ShadowCard,
  ShadowCardBackdrop,
  ShadowCardBevel,
  ShadowCardFooter,
  ShadowCardGlow,
  ShadowCardPixelGradient,
  ShadowCardVerticalText,
}
```

**Install `@radix-ui/react-slot` if you use the root `asChild` prop.**

**Update the import paths to match your project setup.**

## Parts

| Part | Role |
|------|------|
| `ShadowCard` | Root container; supports `asChild` to merge props onto a child (e.g. `Link`). |
| `ShadowCardBevel` | L-shaped bars for the 3D edge; use `barClassName` for thickness or color. |
| `ShadowCardBackdrop` | Absolutely positioned layer for gradients or images (`className` sets geometry). |
| `ShadowCardGlow` | Optional blurred accent blob. |
| `ShadowCardPixelGradient` | Row/column color mesh; pass `colors` to customize the grid. |
| `ShadowCardVerticalText` | Vertical writing mode wrapper for edge copy. |
| `ShadowCardFooter` | Bottom-left absolute region for logos or metadata. |

Place `ShadowCardBevel` after other layers so its `z-10` stack paints on top.
