/* Keep each image's space while the observer requests and decodes its source. */
.image-frame { position: relative; display: block; overflow: hidden; background: var(--soft); }
.image-frame > .lazy-image,
.image-frame .image-nojs { display: block; width: 100%; height: 100%; margin: 0; border: 0; border-radius: inherit; object-fit: cover; }
.image-frame > .lazy-image { opacity: 0; transition: opacity .18s ease; }
.image-frame[data-image-state="loaded"] > .lazy-image { opacity: 1; }
.image-status { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; padding: 4px; pointer-events: none; color: var(--muted); font-size: 12px; line-height: 1.4; text-align: center; }
.image-spinner { display: block; width: 24px; height: 24px; max-width: 55%; aspect-ratio: 1; border: 2px solid var(--line); border-top-color: var(--accent); border-radius: 50%; }
.image-frame[data-image-state="loading"] .image-spinner { animation: image-spin .8s linear infinite; }
.image-error-graphic { display: none; width: 44px; height: 44px; max-width: 65%; max-height: 50%; background: url('../images/image-error.svg') center / contain no-repeat; }
.image-error-label { display: none; }
.image-frame[data-image-state="error"] .image-spinner { display: none; }
.image-frame[data-image-state="error"] .image-error-graphic,
.image-frame[data-image-state="error"] .image-error-label { display: block; }
.image-frame[data-image-state="loaded"] .image-status { display: none; }
.cover.image-frame { aspect-ratio: .8; }
.detail > .cover.image-frame { aspect-ratio: .76; }
.result .cover.image-frame { height: auto; aspect-ratio: .85; }
.focus-slide > .image-frame { width: 100%; height: 100%; border-radius: 0; }
.reader-pages .reader-image { box-sizing: content-box; width: 100%; aspect-ratio: var(--image-ratio); border-bottom: 0; }
.reader-pages .reader-image > .lazy-image,
.reader-pages .reader-image .image-nojs { width: 100%; height: 100%; border: 0; object-fit: contain; }
.reader-image .image-spinner { width: 32px; height: 32px; border-width: 3px; }
.reader-image .image-error-graphic { width: 60px; height: 60px; }
.home-ranking .image-status,
.update-cover .image-status { gap: 2px; font-size: 9px; }
.home-ranking .image-spinner,
.update-cover .image-spinner { width: 18px; height: 18px; }
.home-ranking .image-error-graphic,
.update-cover .image-error-graphic { width: 24px; height: 24px; }
@keyframes image-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .image-frame > .lazy-image { transition: none; }
  .image-frame[data-image-state] .image-spinner { animation: none; }
}
