/* Image placeholder box (.ph). The dashed frame and label only show while <html data-placeholder-labels="true">
   (SHOW_PLACEHOLDER_LABELS), so production never displays "image goes here" text. */
.ph{position:relative;overflow:hidden;background:linear-gradient(135deg,var(--ph-a) 0%,var(--ph-b) 55%,var(--ph-c) 100%)}
.ph.empty img,.ph.empty video{display:none}
:root[data-placeholder-labels="true"] .ph.empty::after{content:attr(data-label) "\A" attr(data-size);white-space:pre;position:absolute;inset:0;display:grid;place-items:center;font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:rgba(255,255,255,.92);font-weight:600;text-align:center;padding:8px;line-height:1.8;z-index:1}
:root[data-placeholder-labels="true"] .ph.empty::before{content:"";position:absolute;inset:10px;border:1px dashed rgba(255,255,255,.45);pointer-events:none}

/* Image sequences (rotator): all images are stacked, only .on is visible. One random slide is picked per page
   load (ImageRotator); no transition, so that pick never fades in visibly while the page is open. */
.ph.rotator img{position:absolute;inset:0;opacity:0}
.ph.rotator img.on{opacity:1}
