.tv-overlay {
  position: relative;
  width: 100%;
  /* PH04: optional per-group max width (set via CSS variable from Twig) */
  max-width: var(--tv-overlay-max-width, none);
  margin-left: auto;
  margin-right: auto;
  isolation: isolate;
}
.tv-overlay-stage {
  position: relative;
  width: 100%;
  overflow: hidden;
  aspect-ratio: 16 / 9;
}
.tv-overlay[data-ratio="16:9"] .tv-overlay-stage { aspect-ratio: 16 / 9; }
.tv-overlay[data-ratio="4:3"]  .tv-overlay-stage { aspect-ratio: 4 / 3; }
.tv-overlay[data-ratio="1:1"]  .tv-overlay-stage { aspect-ratio: 1 / 1; }
.tv-overlay[data-ratio="custom"] .tv-overlay-stage { aspect-ratio: auto; }

.tv-overlay-portal {
  /*
    PH05: Background "portal" layer.
    Background slides are children of this wrapper so we can clip them without
    affecting the overlay frame.
  */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;

  /*
    A1 (PH06):
    Portal mask sizing & positioning (CSS vars only).
    Defaults preserve existing behavior.
      --tv-mask-inset: uniform inset (e.g. 4px)
      --tv-mask-offset-x: horizontal nudge
      --tv-mask-offset-y: vertical nudge
  */
  padding: var(--tv-mask-inset, 0);
  transform: translate(
    var(--tv-mask-offset-x, 0),
    var(--tv-mask-offset-y, 0)
  );
  will-change: transform;

  /*
    Optional mask support.
    Twig sets: --tv-overlay-mask-url: url('...')
    If the variable is not set, `none` makes this a no-op (PH04 behavior).
  */
  -webkit-mask-image: var(--tv-overlay-mask-url, none);
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: center;
  -webkit-mask-size: 100% 100%;

  mask-image: var(--tv-overlay-mask-url, none);
  mask-repeat: no-repeat;
  mask-position: center;
  mask-size: 100% 100%;

  /*
    IMPORTANT (PH06):
    Force luminance-based masking.
    Without this, browsers default to alpha masking, which causes
    fully-opaque black/white masks to show everything.
    Luminance mode ensures:
      - white = visible
      - black = hidden
  */
  -webkit-mask-mode: luminance;
  mask-mode: luminance;
}

.tv-overlay-bg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;

  opacity: 0;
  visibility: hidden;

  transition: opacity 800ms ease, visibility 0s linear 800ms;

  will-change: opacity;
  backface-visibility: hidden;
  transform: translateZ(0);
}


/* PH04: per-group background fit controls */
.tv-overlay[data-bg-fit="contain"] .tv-overlay-bg { object-fit: contain; }
.tv-overlay[data-bg-fit="fill"] .tv-overlay-bg { object-fit: fill; }
.tv-overlay[data-bg-fit="none"] .tv-overlay-bg { object-fit: none; }
.tv-overlay[data-bg-fit="scale-down"] .tv-overlay-bg { object-fit: scale-down; }
.tv-overlay-bg.is-active {
  opacity: 1;
  visibility: visible;

  will-change: opacity;
  transition: opacity 800ms cubic-bezier(0.4, 0.0, 0.2, 1),
            visibility 0s linear 800ms;
}
.tv-overlay[data-transition="cut"] .tv-overlay-bg { transition: none; }

.tv-overlay-frame {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  /* PH04: default frame fit */
  object-fit: contain;
  pointer-events: none;
  z-index: 2;
}

/* PH04: per-group frame fit controls */
.tv-overlay[data-overlay-fit="cover"] .tv-overlay-frame { object-fit: cover; }
.tv-overlay[data-overlay-fit="fill"] .tv-overlay-frame { object-fit: fill; }
.tv-overlay[data-overlay-fit="none"] .tv-overlay-frame { object-fit: none; }
.tv-overlay[data-overlay-fit="scale-down"] .tv-overlay-frame { object-fit: scale-down; }

@media (prefers-reduced-motion: reduce) {
  .tv-overlay-bg { transition: none !important; }
}

