diff --git a/src/app.css b/src/app.css index e9b0c7e..3369e8e 100644 --- a/src/app.css +++ b/src/app.css @@ -2147,73 +2147,136 @@ flex-direction: column; align-items: center; justify-content: center; - gap: 12px; - min-height: 140px; - padding: 20px; + gap: 10px; + min-height: 156px; + padding: 22px; + overflow: hidden; + background: + radial-gradient(circle at center 42%, rgba(151, 118, 255, 0.12), transparent 52%), + linear-gradient(180deg, rgba(15, 18, 31, 0.55), transparent); } - .file-history-loading-graph { width: 56px; height: 56px; overflow: visible; } - - .file-history-loading-graph .fhl-ring { - fill: none; - stroke: rgba(100, 108, 255, 0.22); - stroke-width: 3; - stroke-dasharray: 26 18; - transform-origin: 60px 60px; - animation: fhl-ring-spin 5s linear infinite; + .file-history-loading-mark { + position: relative; + display: grid; + place-items: center; + width: 86px; + height: 86px; + isolation: isolate; } - .file-history-loading-graph .fhl-trunk, - .file-history-loading-graph .fhl-branch { + .file-history-loading-halo { + position: absolute; + inset: 10px; + border: 1px solid rgba(151, 118, 255, 0.24); + border-radius: 18px; + transform: rotate(45deg); + animation: fhl-halo-breathe 2.4s ease-in-out infinite; + } + + .file-history-loading-traces { + position: absolute; + inset: -12px; + width: 110px; + height: 110px; + overflow: visible; + } + + .file-history-loading-traces .fhl-trace { fill: none; - stroke: url(#fhl-line); - stroke-width: 5; + stroke-width: 2.5; stroke-linecap: round; + stroke-dasharray: 92; + stroke-dashoffset: 92; + filter: drop-shadow(0 0 6px rgba(151, 118, 255, 0.5)); + animation: fhl-trace-draw 2.4s ease-in-out infinite; + } + .file-history-loading-traces .fhl-trace-main { + stroke: #9b70ff; + } + .file-history-loading-traces .fhl-trace-branch { + stroke: #ff6d26; + animation-delay: 0.28s; } - .file-history-loading-graph .fhl-branch { - stroke-dasharray: 90; - stroke-dashoffset: 90; - animation: fhl-branch-draw 2.4s ease-in-out infinite; + .file-history-loading-icon { + position: relative; + z-index: 1; + width: 64px; + height: 64px; + object-fit: contain; + filter: + drop-shadow(0 10px 14px rgba(0, 0, 0, 0.45)) + drop-shadow(0 0 12px rgba(151, 118, 255, 0.28)); + animation: fhl-icon-float 2.4s ease-in-out infinite; } - .file-history-loading-graph .fhl-node { - fill: var(--color-surface-alt); - stroke: url(#fhl-line); - stroke-width: 5; - animation: fhl-node-pulse 2.4s ease-in-out infinite; + .file-history-loading-sheen { + position: absolute; + z-index: 2; + width: 54px; + height: 82px; + border-radius: 50%; + background: linear-gradient(90deg, transparent 8%, rgba(255, 255, 255, 0.16), transparent 72%); + mix-blend-mode: screen; + transform: translateX(-48px) rotate(16deg); + animation: fhl-icon-sheen 2.8s ease-in-out infinite; } - .file-history-loading-graph .fhl-n1 { animation-delay: 0s; } - .file-history-loading-graph .fhl-n2 { animation-delay: 0.5s; } - .file-history-loading-graph .fhl-n3 { animation-delay: 1s; } - .file-history-loading-graph .fhl-n4 { animation-delay: 1.5s; } .file-history-loading-label { color: var(--color-ink-faint); font-size: 12.5px; - font-weight: 600; - letter-spacing: 0.01em; + font-weight: 800; } - @keyframes fhl-ring-spin { to { transform: rotate(360deg); } } - @keyframes fhl-branch-draw { - 0% { stroke-dashoffset: 90; opacity: 0.35; } - 45% { stroke-dashoffset: 0; opacity: 1; } - 100% { stroke-dashoffset: 0; opacity: 1; } + .file-history-loading-bar { + position: relative; + width: 118px; + height: 3px; + overflow: hidden; + border-radius: 999px; + background: rgba(151, 118, 255, 0.14); } - @keyframes fhl-node-pulse { - 0%, 100% { fill: var(--color-surface-alt); filter: none; } - 50% { - fill: var(--color-primary); - filter: drop-shadow(0 0 6px rgba(100, 108, 255, 0.8)); - } + .file-history-loading-bar span { + position: absolute; + inset: 0; + width: 46%; + border-radius: inherit; + background: linear-gradient(90deg, transparent, #9b70ff 42%, #ff6d26 74%, transparent); + box-shadow: 0 0 12px rgba(255, 109, 38, 0.26); + animation: fhl-bar-slide 1.35s ease-in-out infinite; + } + + @keyframes fhl-halo-breathe { + 0%, 100% { opacity: 0.35; transform: rotate(45deg) scale(0.94); } + 50% { opacity: 0.8; transform: rotate(45deg) scale(1.04); } + } + @keyframes fhl-icon-float { + 0%, 100% { transform: translateY(0) scale(1); } + 50% { transform: translateY(-3px) scale(1.02); } + } + @keyframes fhl-icon-sheen { + 0%, 18% { transform: translateX(-48px) rotate(16deg); opacity: 0; } + 44% { opacity: 0.8; } + 68%, 100% { transform: translateX(50px) rotate(16deg); opacity: 0; } + } + @keyframes fhl-trace-draw { + 0% { stroke-dashoffset: 92; opacity: 0; } + 36% { opacity: 1; } + 64%, 100% { stroke-dashoffset: 0; opacity: 0.72; } + } + @keyframes fhl-bar-slide { + 0% { transform: translateX(-120%); } + 100% { transform: translateX(320%); } } @media (prefers-reduced-motion: reduce) { - .file-history-loading-graph .fhl-ring, - .file-history-loading-graph .fhl-branch, - .file-history-loading-graph .fhl-node { animation: none; } - .file-history-loading-graph .fhl-branch { stroke-dashoffset: 0; } + .file-history-loading-halo, + .file-history-loading-traces .fhl-trace, + .file-history-loading-icon, + .file-history-loading-sheen, + .file-history-loading-bar span { animation: none; } + .file-history-loading-traces .fhl-trace { stroke-dashoffset: 0; opacity: 0.72; } } /* --- Git graph --- */ diff --git a/src/lib/components/FileHistoryPanel.svelte b/src/lib/components/FileHistoryPanel.svelte index a1cb468..ecb927e 100644 --- a/src/lib/components/FileHistoryPanel.svelte +++ b/src/lib/components/FileHistoryPanel.svelte @@ -1,5 +1,6 @@