:root{--loading-dots:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Ccircle%20cx%3D%2212.00%22%20cy%3D%223.50%22%20r%3D%221.5%22%20opacity%3D%221.000%22%2F%3E%3Ccircle%20cx%3D%2216.25%22%20cy%3D%224.64%22%20r%3D%221.5%22%20opacity%3D%220.925%22%2F%3E%3Ccircle%20cx%3D%2219.36%22%20cy%3D%227.75%22%20r%3D%221.5%22%20opacity%3D%220.850%22%2F%3E%3Ccircle%20cx%3D%2220.50%22%20cy%3D%2212.00%22%20r%3D%221.5%22%20opacity%3D%220.775%22%2F%3E%3Ccircle%20cx%3D%2219.36%22%20cy%3D%2216.25%22%20r%3D%221.5%22%20opacity%3D%220.700%22%2F%3E%3Ccircle%20cx%3D%2216.25%22%20cy%3D%2219.36%22%20r%3D%221.5%22%20opacity%3D%220.625%22%2F%3E%3Ccircle%20cx%3D%2212.00%22%20cy%3D%2220.50%22%20r%3D%221.5%22%20opacity%3D%220.550%22%2F%3E%3Ccircle%20cx%3D%227.75%22%20cy%3D%2219.36%22%20r%3D%221.5%22%20opacity%3D%220.475%22%2F%3E%3Ccircle%20cx%3D%224.64%22%20cy%3D%2216.25%22%20r%3D%221.5%22%20opacity%3D%220.400%22%2F%3E%3Ccircle%20cx%3D%223.50%22%20cy%3D%2212.00%22%20r%3D%221.5%22%20opacity%3D%220.325%22%2F%3E%3Ccircle%20cx%3D%224.64%22%20cy%3D%227.75%22%20r%3D%221.5%22%20opacity%3D%220.250%22%2F%3E%3Ccircle%20cx%3D%227.75%22%20cy%3D%224.64%22%20r%3D%221.5%22%20opacity%3D%220.175%22%2F%3E%3C%2Fsvg%3E")}
.loading-card {width:min(380px,calc(100vw - 40px));padding:22px 24px;border:1px solid var(--color-line);border-radius:22px;background:var(--color-paper);color:var(--color-ink);box-shadow:0 12px 40px var(--color-shadow);display:grid;gap:14px;text-align:left}
.loading-card>strong {font-size:18px;letter-spacing:-.35px;line-height:1.3}
.loading-spinner {display:inline-block;width:24px;height:24px;border:2px solid var(--color-line);border-top-color:var(--color-accent);border-radius:50%;animation:spin .85s linear infinite;flex:none}
.loading-card[data-phase=ready] .loading-spinner,.loading-card[data-phase=error] .loading-spinner {display:none}
.loading-meter {height:5px;border-radius:5px;overflow:hidden;background:var(--color-accent-soft)}
.loading-meter i {display:block;height:100%;width:var(--load-progress,0%);background:var(--color-accent);border-radius:inherit;transition:width .18s ease-out}
.loading-meter.is-indeterminate i {width:32%;animation:loading-slide 1.3s ease-in-out infinite}
.loading-detail {display:flex;align-items:center;gap:12px;font-size:12px;line-height:1.5;color:var(--color-muted);min-height:36px}
.loading-detail span {flex:1}.loading-detail b {font-size:14px;color:var(--color-accent);font-variant-numeric:tabular-nums}
.catalog-transition-status.loading-card {left:50%;bottom:max(28px,env(safe-area-inset-bottom));transform:translateX(-50%);white-space:normal}
#loading .loading-card {box-shadow:none}
#tvStatus[aria-busy=true] {display:flex;align-items:center;gap:8px}
#tvStatus[aria-busy=true]::before,button.is-loading::after {content:'';display:inline-block;flex:none;width:13px;height:13px;border:2px solid var(--color-line);border-top-color:var(--color-accent);border-radius:50%;animation:spin .85s linear infinite}
#documentLoading {position:absolute;inset:0;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:14px;color:var(--color-muted);font-size:13px;pointer-events:none}
#documentLoading button {pointer-events:auto;color:var(--color-accent)}
#documentLoading[data-state=error] .loading-spinner {display:none}
@keyframes loading-slide {from{transform:translateX(-110%)}to{transform:translateX(420%)}}
@media(prefers-reduced-motion:reduce){.loading-spinner,.loading-meter.is-indeterminate i,#tvStatus[aria-busy=true]::before,button.is-loading::after{animation:none}.loading-meter i{transition:none}}

/* Self-contained dots: visible before any JS, even when asset requests fail. */
.loading-spinner,#tvStatus[aria-busy=true]::before,button.is-loading::after{border:0;border-radius:0;background:var(--color-accent);mask:var(--loading-dots) center/contain no-repeat;-webkit-mask:var(--loading-dots) center/contain no-repeat;animation:loading-spin 1.2s linear infinite}
@keyframes loading-spin{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){.loading-spinner,#tvStatus[aria-busy=true]::before,button.is-loading::after{animation:none}}
