Files
GitLite/src/lib/components/RepoLoadingOverlay.svelte
T
Christoph 823a50ce85 style(repo-loading): refine overlay visuals and theming
Update the repository loading overlay and related UI styles to use
design tokens, improve contrast, and reduce visual bulk. Sizes,
spacing, radii, and icon dimensions were tuned to create a more
compact, consistent card. Backgrounds, grid textures, and shadows
were switched to CSS variables and color-mix; subtle backdrop-filter
and opacity tweaks improve legibility across themes.

- Replace hardcoded colors with theme variables and color-mix
- Reduce component dimensions and tighten spacing for a compact UI
- Add backdrop blur, adjust grid opacity, and simplify shadows
2026-08-29 22:52:14 +02:00

230 lines
6.4 KiB
Svelte

<script lang="ts">
import iconUrl from "../../../src-tauri/icons/icon.png";
export let label = "Opening repository";
export let repoName = "";
</script>
<div class="repo-loading" role="status" aria-live="polite">
<div class="repo-loading-grid" aria-hidden="true"></div>
<div class="repo-loading-card">
<div class="repo-loading-mark">
<span class="repo-loading-halo halo-one"></span>
<span class="repo-loading-halo halo-two"></span>
<svg class="repo-loading-traces" viewBox="0 0 220 220" aria-hidden="true">
<path class="trace trace-main" d="M28 154 C72 114, 88 108, 110 110 S156 116, 192 68" />
<path class="trace trace-branch" d="M62 74 C100 88, 126 124, 158 166" />
<path class="trace trace-cut" d="M46 180 L174 180" />
</svg>
<img src={iconUrl} alt="" class="repo-loading-icon" />
</div>
<div class="repo-loading-text">
<span class="repo-loading-label">{label}</span>
{#if repoName}
<span class="repo-loading-name" title={repoName}>{repoName}</span>
{/if}
</div>
<div class="repo-loading-bar"><span></span></div>
</div>
</div>
<style>
.repo-loading {
position: fixed;
top: calc(var(--app-titlebar-height, 42px) + 56px);
right: 0;
bottom: 0;
left: 0;
z-index: 400;
display: grid;
place-items: center;
overflow: hidden;
background:
radial-gradient(
circle at 50% 42%,
color-mix(in srgb, var(--color-accent) 13%, transparent),
transparent 38%
),
var(--app-dialog-backdrop);
backdrop-filter: blur(5px);
animation: overlay-in 180ms ease;
}
.repo-loading-grid {
position: absolute;
inset: 0;
opacity: 0.34;
background-image:
linear-gradient(color-mix(in srgb, var(--color-primary) 9%, transparent) 1px, transparent 1px),
linear-gradient(90deg, color-mix(in srgb, var(--color-accent) 8%, transparent) 1px, transparent 1px);
background-size: 42px 42px;
mask-image: radial-gradient(circle at center, black 0%, transparent 68%);
animation: grid-drift 10s linear infinite;
}
.repo-loading-card {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
gap: 14px;
width: min(360px, calc(100vw - 32px));
padding: 26px 30px 24px;
border: 1px solid var(--color-border-input);
border-radius: 14px;
background:
var(--app-panel-highlight),
var(--app-dialog-bg);
box-shadow: var(--app-dialog-shadow);
}
.repo-loading-mark {
position: relative;
width: 116px;
height: 116px;
display: grid;
place-items: center;
isolation: isolate;
}
.repo-loading-halo {
position: absolute;
inset: 8px;
border: 1px solid color-mix(in srgb, var(--color-primary) 34%, transparent);
border-radius: 24px;
transform: rotate(45deg);
}
.repo-loading-halo.halo-one {
animation: halo-breathe 2.4s ease-in-out infinite;
}
.repo-loading-halo.halo-two {
inset: 18px;
border-color: color-mix(in srgb, var(--color-accent) 38%, transparent);
animation: halo-breathe 2.4s ease-in-out infinite reverse;
}
.repo-loading-traces {
position: absolute;
inset: -14px;
width: 144px;
height: 144px;
overflow: visible;
z-index: 0;
}
.repo-loading-traces .trace {
fill: none;
stroke-width: 3;
stroke-linecap: round;
stroke-dasharray: 165;
stroke-dashoffset: 165;
filter: drop-shadow(0 0 7px color-mix(in srgb, var(--color-accent) 38%, transparent));
animation: trace-draw 2.6s ease-in-out infinite;
}
.repo-loading-traces .trace-main {
stroke: var(--color-primary);
}
.repo-loading-traces .trace-branch {
stroke: var(--color-accent);
animation-delay: 0.28s;
}
.repo-loading-traces .trace-cut {
stroke: color-mix(in srgb, var(--color-ink-muted) 52%, transparent);
stroke-dasharray: 128;
stroke-dashoffset: 128;
animation-delay: 0.55s;
}
.repo-loading-icon {
position: relative;
z-index: 1;
width: 82px;
height: 82px;
object-fit: contain;
filter:
drop-shadow(0 10px 16px color-mix(in srgb, var(--color-ink) 24%, transparent))
drop-shadow(0 0 14px color-mix(in srgb, var(--color-accent) 24%, transparent));
animation: icon-float 2.4s ease-in-out infinite;
}
.repo-loading-text {
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
text-align: center;
}
.repo-loading-label {
color: var(--color-ink);
font-size: 14px;
font-weight: 750;
}
.repo-loading-name {
max-width: 250px;
overflow: hidden;
color: var(--color-ink-faint);
font-family: var(--font-mono);
font-size: 12px;
text-overflow: ellipsis;
white-space: nowrap;
}
.repo-loading-bar {
position: relative;
width: min(230px, 100%);
height: 4px;
overflow: hidden;
border: 1px solid var(--color-border-subtle);
border-radius: 999px;
background: color-mix(in srgb, var(--color-primary) 12%, var(--color-surface-dim));
}
.repo-loading-bar span {
position: absolute;
inset: 0;
width: 46%;
border-radius: inherit;
background: linear-gradient(90deg, transparent, var(--color-primary) 40%, var(--color-accent) 74%, transparent);
box-shadow: 0 0 14px color-mix(in srgb, var(--color-accent) 32%, transparent);
animation: bar-slide 1.35s ease-in-out infinite;
}
@keyframes overlay-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes grid-drift { to { transform: translate3d(42px, 42px, 0); } }
@keyframes icon-float {
0%, 100% { transform: translateY(0) scale(1); }
50% { transform: translateY(-5px) scale(1.015); }
}
@keyframes halo-breathe {
0%, 100% { opacity: 0.35; transform: rotate(45deg) scale(0.95); }
50% { opacity: 0.8; transform: rotate(45deg) scale(1.04); }
}
@keyframes bar-slide {
0% { transform: translateX(-120%); }
100% { transform: translateX(320%); }
}
@keyframes trace-draw {
0% { stroke-dashoffset: 165; opacity: 0; }
36% { opacity: 1; }
64%, 100% { stroke-dashoffset: 0; opacity: 0.72; }
}
@media (prefers-reduced-motion: reduce) {
.repo-loading-grid,
.repo-loading-halo,
.repo-loading-traces .trace,
.repo-loading-icon,
.repo-loading-bar span { animation: none; }
.repo-loading-traces .trace { stroke-dashoffset: 0; opacity: 0.72; }
}
@media (max-width: 520px) {
.repo-loading-card {
width: calc(100vw - 20px);
padding: 22px 20px 20px;
}
}
</style>