diff --git a/static/index.html b/static/index.html index 731c801..9072be7 100644 --- a/static/index.html +++ b/static/index.html @@ -534,6 +534,42 @@ .empty-state { text-align: center; padding: 28px 16px; color: var(--text2); font-size: 13px; } .empty-state .es-icon { font-size: 36px; margin-bottom: 8px; opacity: 0.5; } .loading-row { text-align: center; padding: 20px; color: var(--text2); } + + /* ── Skeleton cards (dashboard loading) ── */ + .skeleton-card { + background: var(--card); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 18px; + margin-bottom: 14px; + min-height: 80px; + } + .skeleton-card.skeleton-stat { padding: 18px; text-align: center; min-height: 100px; } + .skeleton-card .skeleton-bar { + height: 14px; background: var(--card2); border-radius: 8px; margin-bottom: 8px; + animation: skeleton-pulse 1.4s ease-in-out infinite; + } + .skeleton-card .skeleton-bar:last-child { margin-bottom: 0; } + .skeleton-card .skeleton-bar.w60 { width: 60%; } + .skeleton-card .skeleton-bar.w40 { width: 40%; } + .skeleton-card .skeleton-bar.w80 { width: 80%; } + .skeleton-card .skeleton-circle { + width: 48px; height: 48px; border-radius: 50%; background: var(--card2); + margin: 0 auto 10px; animation: skeleton-pulse 1.4s ease-in-out infinite; + } + @keyframes skeleton-pulse { + 0%, 100% { opacity: 0.3; } + 50% { opacity: 0.7; } + } + @keyframes pulse-border { + 0%, 100% { border-color: var(--accent); } + 50% { border-color: var(--accent2); } + } + td.saving { + opacity: 0.6; + box-shadow: inset 0 0 0 1px var(--accent); + animation: pulse-border 1s infinite; + } .flex-row { display: flex; gap: 8px; align-items: center; } .gap-sm { gap: 6px; } .mt-8 { margin-top: 8px; } @@ -767,36 +803,39 @@