/**
 * A token-driven image frame with semantic loading and error states.
 * Supports <img-container>, [data-img-container], and .img-container hosts.
 */

:is(img-container, [data-img-container], .img-container) {
  --ic-aspect-ratio: attr(aspect-ratio type(*), auto);
  --ic-object-fit: attr(object-fit type(*), cover);
  --ic-object-position: attr(object-position type(*), center);
  --ic-radius: attr(radius type(*), 0);
  --ic-shadow: attr(shadow type(*), none);
  --ic-bg: attr(bg type(*), transparent);
  --ic-transition: attr(transition type(*), opacity 0.3s ease);
  --ic-loading-start: var(--surface-muted, #f0f0f0);
  --ic-loading-middle: var(--surface-overt, #e0e0e0);
  --ic-error-bg: var(--surface-error, #fee);
  --ic-error-border: var(--outline-error, #fcc);
  --ic-error-color: var(--text-error, #a22);

  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: var(--ic-aspect-ratio);
  border-radius: var(--ic-radius);
  box-shadow: var(--ic-shadow);
  background-color: var(--ic-bg);
  transition: var(--ic-transition);

  &::before,
  &::after {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
  }

  /* aria-busy is the primary loading-state contract. */
  &::before {
    content: '';
    background: linear-gradient(
      90deg,
      var(--ic-loading-start) 25%,
      var(--ic-loading-middle) 50%,
      var(--ic-loading-start) 75%
    );
    background-size: 200% 100%;
    opacity: 0;
    transition: opacity 0.2s ease;
  }

  &[aria-busy="true"]::before,
  &:has(img[data-loading])::before {
    opacity: 1;
    animation: img-container-loading 1.5s linear infinite;
  }

  &[data-error],
  &:has(img[data-error]) {
    background: var(--ic-error-bg);
    border: var(--border-width, 1px) dashed var(--ic-error-border);
  }

  &[data-error]::after,
  &:has(img[data-error])::after {
    content: attr(error-message, "Image failed to load");
    display: grid;
    place-items: center;
    padding: var(--space-md, 1rem);
    color: var(--ic-error-color);
    background: var(--ic-error-bg);
    font-size: var(--font-size-sm, 0.875rem);
    text-align: center;
  }

  & :is(img, picture, video) {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: var(--ic-object-fit);
    object-position: var(--ic-object-position);
    border-radius: inherit;
    transition: inherit;
  }

  & picture > img {
    width: 100%;
    height: 100%;
  }

  & img[data-loading] {
    opacity: 0;
  }

  & img:is([loaded], [data-loaded]) {
    opacity: 1;
  }

  & img[data-error] {
    visibility: hidden;
  }
}

@keyframes img-container-loading {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}

/* Viewport fallbacks for attribute-driven responsive aspect ratios. */
@media (max-width: 480px) {
  :is(img-container, [data-img-container], .img-container)[responsive] {
    --ic-aspect-ratio: attr(mobile-aspect-ratio type(*), var(--ic-aspect-ratio));
  }
}

@media (min-width: 768px) {
  :is(img-container, [data-img-container], .img-container)[responsive] {
    --ic-aspect-ratio: attr(desktop-aspect-ratio type(*), var(--ic-aspect-ratio));
  }
}

:is(img-container, [data-img-container], .img-container)[theme="card"] {
  --ic-radius: var(--radius-lg, 0.75rem);
  --ic-shadow: var(--shadow-md, none);
}

:is(img-container, [data-img-container], .img-container)[theme="hero"] {
  --ic-shadow: var(--shadow-lg, none);
}

:is(img-container, [data-img-container], .img-container)[theme="thumbnail"] {
  --ic-radius: var(--radius-md, 0.5rem);
  --ic-aspect-ratio: 1;
}

@media (prefers-reduced-motion: reduce) {
  :is(img-container, [data-img-container], .img-container),
  :is(img-container, [data-img-container], .img-container)::before {
    animation: none;
    transition: none;
  }
}
