<!-- source-hash: 8c0e5c74de8bbbd5020de8b54978e503 -->
Accessible loading placeholder component providing a base `UnifiedSkeleton` with specialized sub-components for consistent skeleton UI across the application.

## Key Components

### `UnifiedSkeleton` (base component)
Core skeleton element with dark theme styling (`#2A2A2A` base), pulse animation, and full accessibility support.

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `variant` | `'default' \| 'text' \| 'circular' \| 'rectangular'` | `'default'` | Shape/border-radius style |
| `width` | `string \| number` | — | Custom width override |
| `height` | `string \| number` | — | Custom height override |
| `animate` | `boolean` | `true` | Toggle pulse animation (respects `prefers-reduced-motion`) |
| `aria-label` | `string` | `"Loading content"` | Screen reader label |

### `TextSkeleton` namespace
| Export | Use Case |
|--------|----------|
| `TextSkeleton.Heading` | H1/H2 placeholders (`h-8` → `h-12`) |
| `TextSkeleton.Subheading` | H3/H4 placeholders (`h-6` → `h-8`) |
| `TextSkeleton.Body` | Paragraph text (`h-4` → `h-5`) |
| `TextSkeleton.Caption` | Metadata/captions (`h-3` → `h-4`) |

### `InteractiveSkeleton` namespace
| Export | Use Case |
|--------|----------|
| `InteractiveSkeleton.Button` | Fixed-width button placeholder |
| `InteractiveSkeleton.Input` | Full-width input field placeholder |
| `InteractiveSkeleton.Chip` | Pill-shaped filter chip placeholder |

### `MediaSkeleton` namespace
| Export | Use Case |
|--------|----------|
| `MediaSkeleton.Avatar` | Circular avatar (`sm/md/lg`) |
| `MediaSkeleton.CardImage` | `1200×630` aspect-ratio image (matches OG card, prevents layout shift) |
| `MediaSkeleton.Icon` | Square icon placeholder (`sm/md/lg`) |

## Usage Example

```typescript
import {
  UnifiedSkeleton,
  TextSkeleton,
  InteractiveSkeleton,
  MediaSkeleton,
} from "./unified-skeleton"

// Basic usage
<UnifiedSkeleton variant="rectangular" height={200} />

// Composing a card loading state
function TicketCardSkeleton() {
  return (
    <div className="flex gap-3 p-4">
      <MediaSkeleton.Avatar size="md" />
      <div className="flex-1 space-y-2">
        <TextSkeleton.Heading className="w-3/4" />
        <TextSkeleton.Body />
        <TextSkeleton.Caption className="w-1/2" />
      </div>
      <InteractiveSkeleton.Button />
    </div>
  )
}

// Disable animation (e.g. for snapshot tests)
<UnifiedSkeleton animate={false} aria-label="Loading ticket list" />
```