/* ============================================================
 * img-loader.css
 * Skeleton shimmer + spinner overlay for <img data-img-loader>
 * Works on light/dark themes via custom properties.
 * ============================================================ */

:root {
    --imgl-skeleton-1: #e2e8f0;
    --imgl-skeleton-2: #cbd5e0;
    --imgl-skeleton-3: #e2e8f0;
    --imgl-backdrop:   rgba(255, 255, 255, 0.35);
    --imgl-spinner:    #4a5568;
    --imgl-spinner-bg: rgba(0, 0, 0, 0.12);
    --imgl-error-bg:   #f1f5f9;
    --imgl-error-fg:   #94a3b8;
    --imgl-radius:     inherit;
}

@media (prefers-color-scheme: dark) {
    :root {
        --imgl-skeleton-1: #2d3748;
        --imgl-skeleton-2: #1a202c;
        --imgl-skeleton-3: #2d3748;
        --imgl-backdrop:   rgba(0, 0, 0, 0.35);
        --imgl-spinner:    #e2e8f0;
        --imgl-spinner-bg: rgba(255, 255, 255, 0.18);
        --imgl-error-bg:   #1e293b;
        --imgl-error-fg:   #64748b;
    }
}

/* ---------- Wrapper ----------
 * Default é inline-block pra não impactar layouts onde o wrapper substitui
 * uma <img> avulsa (logos, ícones). Temas que precisam do wrap preencher
 * um container fixo (cards de produto, thumbnails de carrinho) devem
 * sobrescrever para display:block + width/height:100% em CSS próprio.
 */
.img-loader-wrap {
    display: inline-block;
    position: relative;
    overflow: hidden;
    border-radius: var(--imgl-radius);
    line-height: 0;
}

/* The actual <img> stays invisible until loaded */
.img-loader-wrap > img[data-img-loader],
.img-loader-wrap > img {
    opacity: 0;
    transition: opacity .25s ease-in-out;
    display: block;
    max-width: 100%;
}

/* ---------- Overlay (skeleton + spinner) ---------- */
.img-loader-wrap::before,
.img-loader-wrap::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    transition: opacity .25s ease-in-out;
    z-index: 1;
}

/* Layer 1: shimmering skeleton */
.img-loader-wrap::before {
    background: linear-gradient(
        90deg,
        var(--imgl-skeleton-1) 0%,
        var(--imgl-skeleton-2) 50%,
        var(--imgl-skeleton-3) 100%
    );
    background-size: 200% 100%;
    animation: imgl-shimmer 1.4s linear infinite;
    border-radius: var(--imgl-radius);
}

/* Layer 2: centered spinner over a soft backdrop */
.img-loader-wrap::after {
    background-color: var(--imgl-backdrop);
    background-image:
        radial-gradient(
            circle at center,
            transparent 0,
            transparent 14px,
            var(--imgl-backdrop) 14px
        );
    /* spinner is drawn via a child? We use a nested span approach below */
}

/* Inject spinner via separate element added by JS-free fallback:
 * we use a CSS-only spinner by overriding ::after to be the spinner ring. */
.img-loader-wrap::after {
    background: var(--imgl-backdrop);
    /* The spinner ring: */
    -webkit-mask:
        radial-gradient(circle 14px at center, #000 98%, transparent 100%);
            mask:
        radial-gradient(circle 14px at center, #000 98%, transparent 100%);
}

/* Spinner ring element — sits in front of overlay */
.img-loader-wrap > .img-loader-spinner {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 28px;
    height: 28px;
    margin: -14px 0 0 -14px;
    border: 3px solid var(--imgl-spinner-bg);
    border-top-color: var(--imgl-spinner);
    border-radius: 50%;
    animation: imgl-border-spin .9s linear infinite;
    z-index: 2;
    pointer-events: none;
    transition: opacity .25s ease-in-out;
}

/* ---------- Loaded state ---------- */
.img-loader-wrap > img.img-loaded {
    opacity: 1;
}

.img-loader-wrap:has(> img.img-loaded)::before,
.img-loader-wrap:has(> img.img-loaded)::after,
.img-loader-wrap:has(> img.img-loaded) > .img-loader-spinner {
    opacity: 0;
    pointer-events: none;
}

/* Fallback for browsers without :has() — class set on wrapper by JS */
.img-loader-wrap.is-loaded::before,
.img-loader-wrap.is-loaded::after,
.img-loader-wrap.is-loaded > .img-loader-spinner {
    opacity: 0;
    pointer-events: none;
}

/* ---------- Error state ---------- */
.img-loader-wrap > img.img-error {
    opacity: 0;
}

.img-loader-wrap:has(> img.img-error)::before,
.img-loader-wrap.is-error::before {
    background: var(--imgl-error-bg);
    animation: none;
}

.img-loader-wrap:has(> img.img-error)::after,
.img-loader-wrap.is-error::after {
    background: var(--imgl-error-bg)
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='3' width='18' height='18' rx='2' ry='2'/><circle cx='8.5' cy='8.5' r='1.5'/><polyline points='21 15 16 10 5 21'/><line x1='3' y1='3' x2='21' y2='21'/></svg>")
        center / 40% no-repeat;
    -webkit-mask: none;
            mask: none;
    opacity: 1;
}

.img-loader-wrap:has(> img.img-error) > .img-loader-spinner,
.img-loader-wrap.is-error > .img-loader-spinner {
    display: none;
}

/* Unicode fallback when SVG is blocked */
.img-loader-wrap.is-error::after {
    content: "\1F5BC"; /* framed picture glyph */
    color: var(--imgl-error-fg);
    font-size: 1.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ---------- Animations ---------- */
@keyframes imgl-shimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

@keyframes imgl-border-spin {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .img-loader-wrap::before { animation: none; }
    .img-loader-wrap > .img-loader-spinner { animation-duration: 2.4s; }
}
