@use 'ui-design-system/src/styles/semantic/index' as *; .ui-skeleton-loader { display: block; width: 100%; overflow: hidden; position: relative; background: $semantic-color-surface-variant; // Core structure &::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient( 90deg, transparent, rgba(255, 255, 255, 0.2), transparent ); animation: shimmer 2s ease-in-out infinite; transform: translateX(-100%); } // Size variants &--xs { height: 0.5rem; border-radius: 0.125rem; } &--sm { height: 0.75rem; border-radius: 0.25rem; } &--md { height: 1rem; border-radius: 0.375rem; } &--lg { height: 1.25rem; border-radius: 0.5rem; } &--xl { height: 1.5rem; border-radius: 0.5rem; } // Shape variants &--text { height: 1.25rem; border-radius: 0.25rem; } &--heading { height: 1.75rem; border-radius: 0.25rem; } &--avatar { border-radius: 50%; aspect-ratio: 1; &.ui-skeleton-loader--xs { width: 1rem; } &.ui-skeleton-loader--sm { width: 1.5rem; } &.ui-skeleton-loader--md { width: 2rem; } &.ui-skeleton-loader--lg { width: 2.5rem; } &.ui-skeleton-loader--xl { width: 3rem; } } &--card { height: 200px; border-radius: 0.5rem; } &--button { height: 2.5rem; width: 120px; border-radius: 0.375rem; } &--image { aspect-ratio: 16/9; border-radius: 0.375rem; } &--circle { border-radius: 50%; aspect-ratio: 1; } &--rounded { border-radius: 0.375rem; } &--square { border-radius: 0; } // Animation variants &--pulse { &::after { display: none; } animation: pulse 1.5s ease-in-out infinite alternate; } &--wave { &::after { background: linear-gradient( 90deg, transparent 0%, rgba(255, 255, 255, 0.4) 50%, transparent 100% ); animation: wave 2s ease-in-out infinite; } } &--shimmer { // Default shimmer animation (already applied) } // Width variants &--w-25 { width: 25%; } &--w-50 { width: 50%; } &--w-75 { width: 75%; } &--w-full { width: 100%; } // State variants &--loading { opacity: 1; } &--loaded { opacity: 0; transition: opacity 0.3s ease; } // Dark mode support :host-context(.dark-theme) & { background: #374151; &::after { background: linear-gradient( 90deg, transparent, rgba(255, 255, 255, 0.1), transparent ); } } // High contrast mode @media (prefers-contrast: high) { background: #6b7280; &::after { background: linear-gradient( 90deg, transparent, rgba(255, 255, 255, 0.6), transparent ); } } // Reduced motion @media (prefers-reduced-motion: reduce) { &::after { animation: none; } &.ui-skeleton-loader--pulse { animation: none; } } } // Skeleton group for multiple skeleton items .ui-skeleton-group { display: flex; flex-direction: column; gap: 0.75rem; // Horizontal group &--horizontal { flex-direction: row; align-items: center; } // Grid group &--grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; } // Avatar with text group &--avatar-text { flex-direction: row; align-items: flex-start; gap: 0.75rem; .ui-skeleton-loader--avatar { flex-shrink: 0; } .ui-skeleton-content { flex: 1; display: flex; flex-direction: column; gap: 0.5rem; } } // Card group &--card { .ui-skeleton-loader { &:first-child { height: 180px; border-radius: 0.5rem 0.5rem 0 0; } &:not(:first-child) { margin: 0.75rem; height: 1rem; &:last-child { width: 60%; } } } } // Table group &--table { .ui-skeleton-loader { height: 1.25rem; &:first-child { width: 30%; } &:nth-child(2) { width: 50%; } &:last-child { width: 20%; } } } } // Animations @keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } @keyframes pulse { 0% { opacity: 1; } 100% { opacity: 0.6; } } @keyframes wave { 0% { transform: translateX(-100%) scale(0.8); opacity: 0; } 50% { opacity: 1; } 100% { transform: translateX(100%) scale(1.2); opacity: 0; } }