<script lang="ts">
  type Variant = 'line' | 'block' | 'circle' | 'pill';

  type Props = {
    variant?: Variant;
    width?: string;
    height?: string;
    radius?: string;
    class?: string;
  };

  let { variant = 'line', width, height, radius, class: className = '' }: Props = $props();

  const defaults: Record<Variant, { width: string; height: string; radius: string }> = {
    line: { width: '100%', height: '0.75rem', radius: '999px' },
    block: { width: '100%', height: '6rem', radius: '0.95rem' },
    circle: { width: '2.4rem', height: '2.4rem', radius: '999px' },
    pill: { width: '5rem', height: '1.4rem', radius: '999px' }
  };

  const resolvedWidth = $derived(width ?? defaults[variant].width);
  const resolvedHeight = $derived(height ?? defaults[variant].height);
  const resolvedRadius = $derived(radius ?? defaults[variant].radius);
</script>

<span
  aria-hidden="true"
  class={`skeleton ${className}`}
  style={`--sk-width:${resolvedWidth};--sk-height:${resolvedHeight};--sk-radius:${resolvedRadius};`}
></span>

<style>
  .skeleton {
    display: inline-block;
    width: var(--sk-width);
    height: var(--sk-height);
    border-radius: var(--sk-radius);
    background: linear-gradient(
        90deg,
        rgba(229, 236, 231, 0.55) 0%,
        rgba(244, 247, 245, 0.92) 45%,
        rgba(229, 236, 231, 0.55) 90%
      )
      0 0 / 220% 100%;
    animation: skeleton-shimmer 1.4s ease-in-out infinite;
    flex-shrink: 0;
    vertical-align: middle;
  }

  @keyframes skeleton-shimmer {
    0% { background-position: 220% 0; }
    100% { background-position: -120% 0; }
  }

  @media (prefers-reduced-motion: reduce) {
    .skeleton {
      animation: none;
      background: rgba(229, 236, 231, 0.7);
    }
  }
</style>
