/* Sharp preview texture at half the PNG's intrinsic 1098px size.
   Full-size background images already contain their own raster. */
.hero-picture,.komkon-background-picture,.about-chameleon-image{isolation:isolate}
/* Each frame waits for its own decoded preview AND the decoded texture. */
html[data-komkon-progressive] :is(.hero-picture,.komkon-background-picture,.about-chameleon-image,.location-photo-link):not(.komkon-preview-ready) img,
html[data-komkon-progressive] :is(.hero-picture,.komkon-background-picture,.about-chameleon-image,.location-photo-link):not(.komkon-preview-ready)::after{visibility:hidden}
.komkon-preview-without-pattern::after{display:none}
:is(.hero-picture,.komkon-background-picture,.about-chameleon-image,.location-photo-link)::after{
 content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
 background-image:var(--komkon-pattern-image);background-size:549px 549px;
 background-position:left top;background-repeat:repeat;opacity:1;
 transition:opacity .5s ease-out;
}
/* image-ready starts the same 500ms fade as the blurred preview. Wait for both
   Location layers; preview clones intentionally have no data-full-src. */
:is(.hero-picture,.komkon-background-picture,.about-chameleon-image,.location-photo-link):has(img[data-full-src]):not(:has(img[data-full-src]:not(.image-ready)))::after{opacity:0}
.location-photo-link:is(:hover,:focus-visible)::after{opacity:0}
/* The large portrait uses the same full-size tile; small portraits retain their scale. */
.speaker-detail-visual .portrait-pattern{background-size:auto;background-repeat:repeat;background-position:left top}
@media(prefers-reduced-motion:reduce){
 :is(.hero-picture,.komkon-background-picture,.about-chameleon-image,.location-photo-link)::after,.portrait-pattern{transition:none}
}
