/* --------------------------------------------------------------------------
   media-placeholder: stand-in for a photo that has not been supplied yet.
   Drop the real file into assets/images/ with the name shown on the label,
   then swap this <div> for an <img> (or a background-image) pointing to it —
   every place that uses this component says which filename it expects.
   -------------------------------------------------------------------------- */
/*
   media-frame: wraps a real <img> and its gradient fallback together. The
   <img> starts hidden; the inline `onload="this.classList.add('is-loaded')"`
   on each <img> only fires once the browser confirms the file actually
   downloaded, so a missing file silently keeps showing the gradient behind
   it instead of a broken-image icon. Nothing else needs to change: drop the
   file into assets/images/ with the name on the label and it takes over.

   z-index: -2 on the frame mirrors the card's own ::after tint gradient
   (z-index: -1), so stacking is always photo/gradient -> tint -> text.
*/
.media-frame { position: absolute; z-index: -2; inset: 0; overflow: hidden; }
.media-placeholder { position: absolute; inset: 0; background:
    repeating-linear-gradient(135deg, rgba(255, 255, 255, .05) 0 2px, transparent 2px 14px),
    linear-gradient(155deg, var(--placeholder-a, #123a56), var(--placeholder-b, #061019)); }
.media-placeholder__label { position: absolute; top: 10px; right: 10px; padding: 4px 9px; color: #cfe3f2; background: rgba(2, 6, 12, .72); border: 1px dashed rgba(207, 227, 242, .5); border-radius: 4px; font-family: var(--font-display); font-size: 9px; font-weight: 600; letter-spacing: .03em; text-transform: none; white-space: nowrap; }
/* Hidden until "is-loaded" lands; then it covers the gradient completely. */
.media-frame__photo { position: absolute; z-index: 1; inset: 0; display: none; width: 100%; height: 100%; object-fit: cover; }
.media-frame__photo.is-loaded { display: block; }

/* --------------------------------------------------------------------------
   icon-frame: the same real-photo-or-fallback swap, sized for the small
   round icon badges (experience cards and the info strip). The circle size,
   border and background stay defined by the parent (.experience-card__icon
   or .info-icon); this only handles the swap itself.
   -------------------------------------------------------------------------- */
.icon-frame__img { display: none; position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
.icon-frame__img.is-loaded { display: block; }
.icon-frame__img.is-loaded ~ .icon-frame__fallback { display: none; }
