/* ============================================================
   ExtraTV Smart Cards — cards.css  v2.0.0
   Single source of truth. No !important wars.
   ============================================================ */

/* ── Google Font (loaded in PHP via wp_enqueue_style) ── */

/* ─────────────────────────────────────────
   1. TOKENS
───────────────────────────────────────── */
:root {
  --bg:    #0b0f18;
  --font:  'Tajawal', Arial, sans-serif;
  --green: #7cf1b6;
  --yellow:#ffd76a;
}

/* ─────────────────────────────────────────
   2. RESET / BASE
───────────────────────────────────────── */
*, *::before, *::after {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

body {
  margin: 0;
  background:
    radial-gradient(circle at top, rgba(96, 38, 160, .18), transparent 34%),
    linear-gradient(180deg, #060a14 0%, #040814 100%);
  color: #fff;
  font-family: var(--font);
  padding: 28px 14px 56px;
}

/* ─────────────────────────────────────────
   3. PAGE LAYOUT
───────────────────────────────────────── */
.extratv-page {
  max-width: 1180px;
  margin: 0 auto;
  padding-bottom: 20px;
}

/* ─────────────────────────────────────────
   4. TYPOGRAPHY
───────────────────────────────────────── */
.hero-title,
.hero-sub,
.section-title,
.group-title,
.group-desc { text-align: center; }

.hero-title {
  font-size: 42px;
  line-height: 1.12;
  font-weight: 900;
  color: #ff23cf;
  margin: 0 0 12px;
}

.hero-sub {
  font-size: 22px;
  line-height: 1.5;
  font-weight: 800;
  max-width: 880px;
  margin: 0 auto 30px;
}

.section-title {
  font-size: 30px;
  line-height: 1.2;
  font-weight: 900;
  color: #ff23cf;
  margin: 0 0 22px;
}

/* ─────────────────────────────────────────
   5. SECTION DIVIDER
───────────────────────────────────────── */
.section-divider {
  margin: 18px auto 26px;
  max-width: 680px;
  display: flex;
  align-items: center;
  gap: 18px;
  justify-content: center;
}
.section-divider .line {
  height: 4px;
  flex: 1;
  border-radius: 999px;
  background: linear-gradient(90deg, #ff23cf, #ff23cf);
}
.section-divider .star {
  font-size: 34px;
  color: #ff23cf;
  line-height: 1;
}

/* ─────────────────────────────────────────
   6. CARDS WRAPPER
───────────────────────────────────────── */
.cards {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 52px;
  padding: 34px 22px;
}

/* ─────────────────────────────────────────
   7. GROUP BREAK
───────────────────────────────────────── */
.group-break {
  margin: 40px auto 50px;
  max-width: 900px;
  text-align: center;
}
.glow-line {
  height: 3px;
  width: 100%;
  margin: 18px 0;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, #ff23cf, transparent);
  filter: blur(2px);
}
.group-box {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 18px 22px;
  border-radius: 20px;
  background: linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.02));
  border: 1px solid rgba(255,255,255,.12);
  backdrop-filter: blur(6px);
  box-shadow: 0 10px 30px rgba(0,0,0,.25), 0 0 28px rgba(255,35,207,.08);
}
.group-icon { font-size: 26px; }
.group-title { font-size: 20px; font-weight: 900; color: #ff23cf; }
.group-desc  { font-size: 13px; font-weight: 700; color: #ddd; margin-top: 4px; }

/* ─────────────────────────────────────────
   8. PACKAGE THEME TOKENS
   (one block per package — no duplication)
───────────────────────────────────────── */
.card[data-key="premium-vip"] {
  --premium-vip-orange: #FF8A16;
  --premium-vip-gold: #C9962E;
  --premium-vip-deep-gold: #9F6B16;
  --premium-vip-border: #B8862F;
  --premium-vip-dark: #111722;
  --theme1: var(--premium-vip-gold); --theme2: var(--premium-vip-orange);
  --cta1: var(--premium-vip-orange); --cta2: var(--premium-vip-deep-gold);
  --glowA: rgba(201,150,46,.34);
  --glowB: rgba(255,138,22,.22);
  --glowC: rgba(159,107,22,.18);
}
.card[data-key="premium"] {
  --theme1: #ff4fd8; --theme2: #ff1f8f;
  --cta1: #ff2fb2;   --cta2: #b91dd4;
  --glowA: rgba(255,79,216,.26);
  --glowB: rgba(185,29,212,.20);
  --glowC: rgba(255,160,216,.16);
}
.card[data-key="basic"] {
  --theme1: #51b8ff; --theme2: #206bff;
  --cta1: #2a8dff;   --cta2: #1763d8;
  --glowA: rgba(81,184,255,.24);
  --glowB: rgba(32,107,255,.18);
  --glowC: rgba(158,230,255,.12);
}
.card[data-key="lite"] {
  --theme1: #d9d9e6; --theme2: #9fa6b8;
  --cta1: #9ba5b8;   --cta2: #7f8796;
  --glowA: rgba(220,220,235,.18);
  --glowB: rgba(159,166,184,.14);
  --glowC: rgba(255,255,255,.10);
}
.card[data-key="mix-plus"] {
  --theme1: #ff4fd8; --theme2: #9d4dff;
  --cta1: #d52dff;   --cta2: #7b29ff;
  --glowA: rgba(213,45,255,.24);
  --glowB: rgba(123,41,255,.18);
  --glowC: rgba(255,159,240,.14);
}
.card[data-key="vip-plus"] {
  --vip-plus-orange: #FF8A16;
  --vip-plus-copper: #C76A1A;
  --vip-plus-dark-copper: #8A4F12;
  --vip-plus-gold: #D9A441;
  --vip-plus-rose-accent: #C86A7E;
  --vip-plus-border: #C8953A;
  --vip-plus-dark: #111722;
  --theme1: var(--vip-plus-copper); --theme2: var(--vip-plus-orange);
  --cta1: var(--vip-plus-orange); --cta2: var(--vip-plus-copper);
  --glowA: rgba(199,106,26,.30);
  --glowB: rgba(255,138,22,.20);
  --glowC: rgba(200,106,126,.05);
}

/* ─────────────────────────────────────────
   9. CARD BASE
───────────────────────────────────────── */
.card {
  position: relative;
  /* Mobile default sizing */
  width: 92%;
  max-width: 420px;
  min-height: 620px;
  border-radius: 32px;
  overflow: visible;
  background: linear-gradient(180deg, rgba(11,16,28,.985), rgba(6,10,20,.985));
  border: 1px solid rgba(255,255,255,.08);
  box-shadow:
    0 30px 78px rgba(0,0,0,.56),
    0 0 0 1px color-mix(in srgb, var(--theme1, #fff) 18%, transparent),
    inset 0 1px 0 rgba(255,255,255,.06);
  isolation: isolate;
  /* Scroll reveal — starts hidden */
  opacity: 0;
  transform: translateY(60px) scale(0.95);
  transition:
    opacity .7s cubic-bezier(.2,.8,.2,1),
    transform .7s cubic-bezier(.2,.8,.2,1),
    box-shadow .35s ease;
}

/* Ambient glow border */
.card::before {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 36px;
  background:
    radial-gradient(circle at 50% 50%, var(--etv-visual-border-glow) 0 28%, transparent 68%),
    linear-gradient(120deg, #ff00cc, #ff7b29, #00eaff, #ff00cc);
  background-size: 220% 220%;
  z-index: -1;
  filter: blur(16px) saturate(1.12);
  opacity: .26;
  pointer-events: none;
}

/* Inner surface gloss */
.card::after {
  content: "";
  position: absolute;
  inset: 1px;
  border-radius: 31px;
  background:
    radial-gradient(circle at top, rgba(223,36,135,.12), transparent 42%),
    linear-gradient(180deg, rgba(255,255,255,.04), rgba(255,255,255,0)),
    linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,.12));
  pointer-events: none;
  z-index: 0;
  opacity: .88;
}

/* Scroll reveal: visible state */
.card.show {
  opacity: 1;
  transform: translateY(0) scale(1);
}

/* Hover lift */
.card:hover,
.card.touch-active {
  transform: translateY(-8px) scale(1.015);
  box-shadow:
    0 34px 76px rgba(0,0,0,.58),
    0 0 0 1px color-mix(in srgb, var(--theme1, #fff) 20%, rgba(255,255,255,.04)),
    0 0 44px var(--glowA),
    0 0 92px var(--glowB);
  filter: saturate(1.04);
}

/* Plan selection glow states */
.card.plan12-selected {
  box-shadow:
    0 40px 88px rgba(0,0,0,.62),
    0 0 0 1px color-mix(in srgb, var(--theme1, #fff) 24%, rgba(255,255,255,.05)),
    0 0 58px var(--glowA),
    0 0 112px var(--glowB),
    0 0 150px var(--glowC);
}
.card.plan12-selected::before { opacity: .88; filter: blur(18px) saturate(1.18); }
.card.plan6-selected {
  box-shadow:
    0 30px 68px rgba(0,0,0,.52),
    0 0 0 1px color-mix(in srgb, var(--theme1, #fff) 14%, rgba(255,255,255,.03)),
    0 0 36px var(--glowA);
}
.card.plan6-selected::before { opacity: .56; filter: blur(15px) saturate(1.08); }

/* Premium VIP hero accent */
.card[data-key="premium-vip"]::before {
  background: linear-gradient(120deg, #FF8A16, #C9962E, #9F6B16, #B8862F);
  opacity: .42;
  filter: blur(16px) saturate(1.18);
}
.card[data-key="premium-vip"]::after {
  background:
    radial-gradient(circle at top, rgba(201,150,46,.14), transparent 42%),
    linear-gradient(180deg, rgba(255,138,22,.045), rgba(255,255,255,0)),
    linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,.10));
}
.card[data-key="premium-vip"].show {
  box-shadow:
    0 40px 88px rgba(0,0,0,.62),
    0 0 0 1px rgba(184,134,47,.34),
    0 0 64px rgba(201,150,46,.26),
    0 0 120px rgba(159,107,22,.16);
}

/* VIP Plus hierarchy */
.card[data-key="vip-plus"] {
  transform: scale(1.04);
  z-index: 3;
  box-shadow:
    0 0 0 2px rgba(200,149,58,.45),
    0 0 28px rgba(199,106,26,.20),
    0 0 6px rgba(200,106,126,.05),
    0 18px 46px rgba(0,0,0,.34);
}
.card[data-key="vip-plus"]::before {
  background: linear-gradient(120deg, #FF8A16 0%, #D9A441 55%, #C76A1A 100%);
}
.card[data-key="vip-plus"]::after {
  background:
    radial-gradient(circle at top, rgba(199,106,26,.13), transparent 42%),
    linear-gradient(180deg, rgba(200,106,126,.015), rgba(255,255,255,0)),
    linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,.10));
}
.card[data-key="vip-plus"].show { transform: scale(1.04) translateY(0); }

/* Package dimming hierarchy */
.card[data-key="basic"] { filter: brightness(.97); }
.card[data-key="lite"]  { filter: brightness(.94) saturate(.9); }

/* ─────────────────────────────────────────
   10. MEDIA (image / video area)
───────────────────────────────────────── */
.media {
  position: absolute;
  inset: 0;
  background: #000;
  overflow: hidden;
  border-radius: inherit;
  --focus-mobile:  center top;
  --focus-tablet:  center center;
  --focus-desktop: center center;
}

.slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity .45s ease, transform .8s ease;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: var(--focus-mobile);
}
.slide.active { opacity: 1; transform: scale(1.01); }

@media (min-width: 481px) and (max-width: 1023px) {
  .slide { background-position: var(--focus-tablet); }
}
@media (min-width: 1024px) {
  .slide { background-position: var(--focus-desktop); }
}

.media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center center;
  display: block;
  background: #000;
}
@keyframes fadeInVideo {
  from { opacity: 0; transform: scale(1.04); }
  to   { opacity: 1; transform: scale(1); }
}
.media video.playing { animation: fadeInVideo .36s ease; }

.media-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(0,0,0,.08), rgba(0,0,0,.2) 28%, rgba(0,0,0,.9)),
    radial-gradient(circle at top, rgba(255,0,136,.16), transparent 42%);
}

/* Invisible tap zone over image area */
.media-hit {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 255px;
  background: transparent;
  border: none;
  cursor: pointer;
  z-index: 3;
}

/* ─────────────────────────────────────────
   11. PLAY HINT BUTTON
───────────────────────────────────────── */
.play-hint {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 10;
  width: 74px;
  height: 74px;
  border: none;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: rgba(8,12,22,.42);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255,255,255,.18);
  box-shadow:
    0 14px 34px rgba(0,0,0,.32),
    0 0 0 1px rgba(255,255,255,.05),
    0 0 24px rgba(255,120,220,.12);
  cursor: pointer;
  animation: none;
  transition: transform .25s ease, background .25s ease, box-shadow .25s ease;
}
.play-hint::after {
  content: "";
  width: 0;
  height: 0;
  border-top: 10px solid transparent;
  border-bottom: 10px solid transparent;
  border-left: 16px solid #fff;
  margin-inline-start: 4px;
}
.play-hint::before {
  content: "";
  position: absolute;
  inset: -10px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,.10);
  opacity: .55;
  animation: playRing 2.2s ease-out infinite;
  pointer-events: none;
}
.play-hint:hover {
  transform: translate(-50%,-50%) scale(1.08);
  background: rgba(8,12,22,.58);
}
.play-hint.no-video {
  display: none;
}
.play-hint.hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  animation: none;
}
.play-hint.hidden::before { animation: none; }
.play-hint.show-once { opacity:1 !important; visibility:visible !important; pointer-events:auto !important; animation: playPulse 1s ease-in-out 3 !important; }
.play-hint.show-once::before { animation: playRing 1s ease-out 3 !important; }

/* VIP gold play button */
.card[data-key="premium-vip"] .play-hint,
.card[data-key="vip-plus"] .play-hint {
  color: #C9962E;
  background: linear-gradient(135deg, rgba(17,23,34,.94), rgba(58,34,0,.86));
  border-color: rgba(201,150,46,.34);
  box-shadow:
    0 12px 32px rgba(0,0,0,.30),
    0 0 18px rgba(201,150,46,.24),
    0 0 42px rgba(255,138,22,.18);
  animation: none;
}

@keyframes playPulse {
  0%, 100% { transform: translate(-50%,-50%) scale(1); }
  50%       { transform: translate(-50%,-50%) scale(1.06); }
}
@keyframes playRing {
  0%   { transform: scale(.92); opacity: .55; }
  70%  { transform: scale(1.18); opacity: 0; }
  100% { transform: scale(1.18); opacity: 0; }
}
@keyframes playPulseVIP {
  0%, 100% { transform: translate(-50%,-50%) scale(1); }
  50%       { transform: translate(-50%,-50%) scale(1.09); }
}

/* Preview-running: hide play button, dim card content */
.card.preview-running .play-hint { opacity: 0 !important; visibility: hidden !important; pointer-events: none !important; animation: none !important; }
.card.preview-running .play-hint::before { animation: none; }
.card.preview-running .main { opacity: .22; transition: opacity .25s ease; }
.card.preview-running.controls-visible .main { opacity: 1; }

/* ─────────────────────────────────────────
   12. BADGE (top-left label)
───────────────────────────────────────── */
.badge-mini {
  position: absolute;
  top: 14px;
  left: 14px;
  z-index: 8;
  max-width: 172px;
  padding: 9px 16px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 900;
  text-align: center;
  color: #fff;
  background: linear-gradient(180deg, rgba(255,255,255,.14), rgba(255,255,255,.05));
  border: 1px solid rgba(255,255,255,.15);
  box-shadow: 0 10px 24px rgba(0,0,0,.22);
  backdrop-filter: blur(10px);
}
.card[data-key="premium-vip"] .badge-mini { background: linear-gradient(180deg, rgba(201,150,46,.20), rgba(255,255,255,.05)); border-color: rgba(184,134,47,.30); }
.card[data-key="vip-plus"]    .badge-mini { background: linear-gradient(180deg, rgba(199,106,26,.18), rgba(255,255,255,.05)); border-color: rgba(200,149,58,.28); }
.card[data-key="premium"]     .badge-mini,
.card[data-key="mix-plus"]    .badge-mini { background: linear-gradient(180deg, rgba(255,79,216,.18),  rgba(255,255,255,.05)); border-color: rgba(255,79,216,.24); }
.card[data-key="basic"]       .badge-mini { background: linear-gradient(180deg, rgba(81,184,255,.18),  rgba(255,255,255,.05)); border-color: rgba(81,184,255,.24); }
.card[data-key="lite"]        .badge-mini { background: linear-gradient(180deg, rgba(217,217,230,.14), rgba(255,255,255,.05)); border-color: rgba(217,217,230,.20); }

/* ─────────────────────────────────────────
   13. DEVICE INDICATOR (top-right)
───────────────────────────────────────── */
.device {
  position: absolute;
  top: 18px;
  right: 16px;
  z-index: 5;
  display: flex;
  gap: 8px;
  align-items: center;
  font-weight: 900;
  text-shadow: 0 2px 8px rgba(0,0,0,.24);
  pointer-events: none;
}
.device svg { width: 21px; height: 21px; }

/* ─────────────────────────────────────────
   14. MAIN CONTENT PANEL
───────────────────────────────────────── */
.main {
  position: relative;
  z-index: 2;
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: 20px 16px 34px;
}
.spacer { flex: 1; min-height: 150px; }
.center {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  margin-top: auto;
}

/* ─────────────────────────────────────────
   15. PRICE
───────────────────────────────────────── */
.price-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  margin-top: 24px;
}
.price {
  font-size: 70px;
  line-height: .92;
  font-weight: 900;
  color: color-mix(in srgb, var(--theme1, #ffc15a) 92%, white 8%);
  letter-spacing: 1.5px;
  direction: ltr;
  text-shadow: 0 0 12px rgba(255,190,90,.34), 0 8px 22px rgba(0,0,0,.22);
}
.card[data-key="premium-vip"] .price {
  text-shadow: 0 0 18px rgba(201,150,46,.46), 0 0 42px rgba(159,107,22,.24), 0 8px 22px rgba(0,0,0,.24);
}
/* Gold gradient price for multi-device plans */
.card[data-key="mix-plus"] .price,
.card[data-key="vip-plus"] .price {
  background: linear-gradient(90deg, #fff4c0 0%, #ffd36b 32%, #ffab3d 68%, #fff0b0 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: none;
  filter: drop-shadow(0 0 8px rgba(255,210,110,.22)) drop-shadow(0 0 22px rgba(255,150,60,.14));
}

.backup-pill {
  white-space: nowrap;
  padding: 10px 16px;
  font-size: 14px;
  font-weight: 800;
  border-radius: 18px;
  background: linear-gradient(180deg, rgba(255,255,255,.18), rgba(255,255,255,.05));
  border: 1px solid rgba(255,255,255,.20);
  backdrop-filter: blur(8px);
  box-shadow: 0 10px 25px rgba(0,0,0,.18);
  margin-bottom: 6px;
}
.card[data-key="premium-vip"] .backup-pill {
  background: linear-gradient(90deg, rgba(17,23,34,.92), rgba(159,107,22,.14));
  border-color: rgba(184,134,47,.30);
}
.card[data-key="mix-plus"] .backup-pill {
  background: linear-gradient(90deg, rgba(255,211,107,.18), rgba(255,143,58,.12));
  border-color: rgba(255,211,107,.26);
}
.card[data-key="vip-plus"] .backup-pill {
  background: linear-gradient(90deg, rgba(199,106,26,.18), rgba(255,138,22,.12), rgba(200,106,126,.015));
  border-color: rgba(200,149,58,.28);
}

/* ─────────────────────────────────────────
   16. PLAN SWITCHER (6 / 12 months)
───────────────────────────────────────── */
.grid {
  margin: 28px auto 0;
  max-width: 300px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  width: 100%;
}
.plan {
  min-height: 60px;
  border-radius: 22px;
  cursor: pointer;
  font: 900 16px var(--font);
  background: linear-gradient(180deg, rgba(255,255,255,.13), rgba(255,255,255,.08));
  border: 1px solid rgba(255,255,255,.14);
  color: rgba(255,255,255,.9);
  backdrop-filter: blur(8px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05), 0 10px 24px rgba(0,0,0,.12);
  transition: .3s;
}
.plan.active {
  background: linear-gradient(90deg, #ffb347, #ff7a18);
  color: #fff;
  border: none;
  box-shadow: 0 0 20px rgba(255,180,70,.6), 0 0 40px rgba(255,120,40,.4);
  transform: scale(1.05);
  animation: pulsePlan 2.5s infinite;
}
.plan.active::after { content: " \2714"; font-size: 14px; margin-inline-start: 4px; }

@keyframes pulsePlan {
  0%, 100% { box-shadow: 0 0 20px rgba(255,180,70,.6), 0 0 40px rgba(255,120,40,.4); }
  50%       { box-shadow: 0 0 30px rgba(255,200,100,.8), 0 0 60px rgba(255,140,60,.5); }
}

/* ─────────────────────────────────────────
   17. CTA LINKS
───────────────────────────────────────── */
.link {
  display: block;
  width: 100%;
  max-width: 300px;
  margin-inline: auto;
  text-decoration: none;
  text-align: center;
  border-radius: 18px;
  padding: 15px 12px;
  font: 900 16px var(--font);
  color: #fff;
}
.link.primary {
  margin-top: 18px;
  background: linear-gradient(180deg, var(--cta1, #df2487), var(--cta2, #b91dd4));
  box-shadow:
    0 18px 38px color-mix(in srgb, var(--cta1, #df2487) 28%, transparent),
    0 0 24px color-mix(in srgb, var(--cta2, #b91dd4) 14%, transparent);
  position: relative;
  overflow: hidden;
  animation: subscribePulse 2.8s ease-in-out infinite;
}
.link.primary::after {
  content: "";
  position: absolute;
  top: 0; left: -120%;
  width: 85%; height: 100%;
  background: linear-gradient(120deg, transparent, rgba(255,255,255,.22), transparent);
  transform: skewX(-18deg);
  animation: shine 3.4s infinite;
}
.card[data-key="premium-vip"] .link.primary {
  animation: subscribePulse 2.8s ease-in-out infinite, heroPulse 3.6s ease-in-out infinite;
}

.card[data-key="premium-vip"] .link.primary,
.card[data-key="premium-vip"] .sheet-accept {
  background: linear-gradient(135deg, #FF8A16 0%, #C9962E 60%, #9F6B16 100%);
  box-shadow: 0 18px 38px rgba(255,138,22,.22), 0 0 24px rgba(201,150,46,.18);
}
.card[data-key="premium-vip"] .more-link {
  background: linear-gradient(135deg, #FF8A16 0%, #C9962E 60%, #9F6B16 100%);
  box-shadow: 0 14px 28px rgba(201,150,46,.22);
}
.card[data-key="premium-vip"] .action {
  background: linear-gradient(180deg, rgba(17,23,34,.94), rgba(17,23,34,.78));
  border-color: rgba(184,134,47,.44);
  box-shadow: inset 0 1px 0 rgba(201,150,46,.10), 0 10px 22px rgba(0,0,0,.12);
}
.card[data-key="premium-vip"] .details-btn {
  background: linear-gradient(135deg, rgba(255,138,22,.20), rgba(201,150,46,.15), rgba(159,107,22,.10));
  border-color: rgba(184,134,47,.48);
}
.card[data-key="premium-vip"] .backup-btn {
  background: linear-gradient(180deg, rgba(17,23,34,.96), rgba(17,23,34,.82));
  border-color: rgba(184,134,47,.50);
}
.card[data-key="vip-plus"] .link.primary,
.card[data-key="vip-plus"] .sheet-accept {
  background: linear-gradient(135deg, #FF8A16 0%, #E6A23A 55%, #C76A1A 100%);
  box-shadow: 0 18px 38px rgba(255,138,22,.22), 0 0 24px rgba(199,106,26,.16), 0 0 6px rgba(200,106,126,.04);
}
.card[data-key="vip-plus"] .more-link {
  background: linear-gradient(135deg, #FF8A16 0%, #E6A23A 55%, #C76A1A 100%);
  box-shadow: 0 14px 28px rgba(199,106,26,.20), 0 0 6px rgba(200,106,126,.035);
}
.card[data-key="vip-plus"] .action {
  background: linear-gradient(180deg, rgba(17,23,34,.94), rgba(17,23,34,.78));
  border-color: rgba(200,149,58,.42);
  box-shadow: inset 0 1px 0 rgba(199,106,26,.10), 0 10px 22px rgba(0,0,0,.12);
}
.card[data-key="vip-plus"] .details-btn {
  background: linear-gradient(135deg, rgba(255,138,22,.20), rgba(199,106,26,.15), rgba(138,79,18,.08));
  border-color: rgba(200,149,58,.46);
}
.card[data-key="vip-plus"] .backup-btn {
  background: linear-gradient(180deg, rgba(17,23,34,.96), rgba(17,23,34,.82));
  border-color: rgba(200,149,58,.48);
}
.link.secondary {
  margin-top: 14px;
  color: #f5d7ff;
  border: 1px dashed rgba(240,171,252,.30);
  background: linear-gradient(180deg, rgba(217,70,239,.08), rgba(217,70,239,.03));
}

@keyframes subscribePulse {
  0%, 100% {
    box-shadow:
      0 18px 36px color-mix(in srgb, var(--cta1, #df2487) 24%, transparent),
      0 0 24px color-mix(in srgb, var(--cta2, #b91dd4) 14%, transparent);
  }
  50% {
    box-shadow:
      0 0 25px rgba(255,0,200,.30),
      0 0 60px rgba(255,100,200,.20),
      0 18px 40px color-mix(in srgb, var(--cta1, #df2487) 28%, transparent);
  }
}

@keyframes premiumVipSubscribePulse {
  0%, 100% {
    box-shadow:
      0 18px 36px rgba(255,138,22,.24),
      0 0 24px rgba(201,150,46,.16);
  }
  50% {
    box-shadow:
      0 0 25px rgba(201,150,46,.30),
      0 0 60px rgba(255,138,22,.18),
      0 18px 40px rgba(159,107,22,.22);
  }
}
@keyframes vipPlusSubscribePulse {
  0%, 100% {
    box-shadow:
      0 18px 36px rgba(255,138,22,.22),
      0 0 24px rgba(199,106,26,.15),
      0 0 6px rgba(200,106,126,.035);
  }
  50% {
    box-shadow:
      0 0 25px rgba(199,106,26,.28),
      0 0 60px rgba(255,138,22,.16),
      0 0 6px rgba(200,106,126,.045),
      0 18px 40px rgba(138,79,18,.20);
  }
}
.card[data-key="premium-vip"] .link.primary {
  animation: premiumVipSubscribePulse 2.8s ease-in-out infinite, heroPulse 3.6s ease-in-out infinite;
}
.card[data-key="vip-plus"] .link.primary {
  animation: vipPlusSubscribePulse 2.8s ease-in-out infinite;
}
@keyframes shine {
  0%   { left: -120%; }
  58%  { left: 140%; }
  100% { left: 140%; }
}
@keyframes heroPulse {
  0%, 100% { transform: translateY(0) scale(1); }
  50%       { transform: translateY(-2px) scale(1.015); }
}

/* ─────────────────────────────────────────
   18. ACTION BUTTONS (details / backup)
───────────────────────────────────────── */
.actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  max-width: 300px;
  width: 100%;
  margin: 22px auto 0;
}
.action {
  border: none;
  border-radius: 20px;
  padding: 12px 10px;
  cursor: pointer;
  font: 900 14px var(--font);
  color: #fff;
  background: linear-gradient(180deg, rgba(255,255,255,.11), rgba(255,255,255,.06));
  border: 1px solid color-mix(in srgb, var(--theme1, #fff) 16%, rgba(255,255,255,.08));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.04), 0 10px 22px rgba(0,0,0,.1);
  touch-action: manipulation;
}

/* Hidden micro text */
.micro { display: none; }

/* ─────────────────────────────────────────
   19. TOAST NOTIFICATION
───────────────────────────────────────── */
.toast {
  display: block;
  position: absolute;
  top: 58px;
  left: 16px;
  right: 16px;
  z-index: 9;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity .22s ease, transform .22s ease, visibility .22s ease;
  pointer-events: none;
}
.toast.show {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.toast-inner {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  align-items: center;
  padding: 12px 14px;
  border-radius: 18px;
  background: rgba(10,16,28,.96);
  border: 1px solid rgba(255,255,255,.10);
  box-shadow: 0 12px 30px rgba(0,0,0,.28);
  min-height: 58px;
}
.toast-title { font-size: 13px; font-weight: 900; line-height: 1.35; }
.toast-sub   { margin-top: 2px; font-size: 12px; font-weight: 800; line-height: 1.35; }
.toast-sub.ok   { color: var(--green); }
.toast-sub.warn { color: var(--yellow); }
.toast-icon {
  width: 36px; height: 36px;
  border-radius: 14px;
  display: grid;
  place-items: center;
  font-size: 18px;
  font-weight: 900;
}
.toast-icon.ok   { background: rgba(57,217,138,.14); color: var(--green); }
.toast-icon.warn { background: rgba(255,215,106,.12); color: var(--yellow); }

/* ─────────────────────────────────────────
   20. BOTTOM / SIDE SHEET
───────────────────────────────────────── */
.sheet {
  position: absolute;
  inset: 0;
  z-index: 20;
  background: rgba(4,5,10,.32);
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s ease, visibility .2s ease;
}
.sheet.open { opacity: 1; visibility: visible; }

.sheet-panel {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  min-height: 320px;
  max-height: 72%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: 26px 26px 0 0;
  background: linear-gradient(180deg, rgba(16,19,28,.98), rgba(8,10,16,.98));
  border-top: 1px solid rgba(255,255,255,.08);
  transform: translateY(104%);
  transition: transform .26s ease;
  z-index: 25;
}
.sheet.open .sheet-panel { transform: translateY(0); }

.handle {
  width: 58px; height: 5px;
  border-radius: 999px;
  background: rgba(255,255,255,.18);
  margin: 10px auto 6px;
}
.sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 16px 14px;
  border-bottom: 1px solid rgba(255,255,255,.08);
}
.sheet-title { font-size: 18px; font-weight: 900; }
.close-btn {
  width: 42px; height: 42px;
  border: none;
  border-radius: 16px;
  cursor: pointer;
  display: grid;
  place-items: center;
  font-size: 24px;
  color: #ff7c92;
  background: linear-gradient(180deg, rgba(255,95,122,.12), rgba(255,95,122,.05));
  border: 1px solid rgba(255,95,122,.28);
}

.tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  padding: 14px 16px 0;
}
.tab {
  border: none;
  border-radius: 18px;
  padding: 14px 12px;
  cursor: pointer;
  font: 900 15px var(--font);
  color: rgba(255,255,255,.84);
  background: linear-gradient(180deg, rgba(255,255,255,.07), rgba(255,255,255,.04));
  border: 1px solid rgba(255,255,255,.08);
}
.tab.active {
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--theme2, #df2487) 90%, black 10%),
    color-mix(in srgb, var(--theme1, #b91dd4) 82%, black 18%)
  );
  color: #fff;
  border-color: transparent;
}

.sheet-body {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding: 16px 16px 18px;
  font-size: 15px;
  line-height: 1.9;
  color: rgba(255,255,255,.9);
  font-weight: 500;
  -webkit-overflow-scrolling: touch;
}
.pane         { display: none; }
.pane.active  { display: block; }

.sec-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 900;
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--theme2, #df2487) 90%, black 10%),
    color-mix(in srgb, var(--theme1, #b91dd4) 82%, black 18%)
  );
  color: #fff;
}

.bullet,
.feature {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  border-radius: 18px;
  padding: 12px 14px;
  background: linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.03));
  border: 1px solid rgba(255,255,255,.06);
  margin-bottom: 10px;
}
.icon {
  width: 32px; height: 32px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  font-size: 16px;
  background: rgba(255,255,255,.08);
}

.activation {
  margin: 14px 0 16px;
  padding: 14px;
  border-radius: 18px;
  background: linear-gradient(180deg, rgba(255,193,7,.1), rgba(255,193,7,.04));
  border: 1px solid rgba(255,193,7,.18);
}
.activation-title { font-size: 13px; font-weight: 900; color: #ffd76a; margin-bottom: 6px; }
.activation-text  { font-size: 13px; line-height: 1.9; font-weight: 800; color: #fff4cf; }

.more-link {
  display: block;
  text-decoration: none;
  text-align: center;
  padding: 14px;
  border-radius: 20px;
  font-weight: 900;
  font-size: 14px;
  color: #fff;
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--theme2, #df2487) 90%, black 10%),
    color-mix(in srgb, var(--theme1, #b91dd4) 82%, black 18%)
  );
  box-shadow: 0 14px 28px rgba(223,36,135,.25);
  margin-top: 14px;
}

/* ─────────────────────────────────────────
   21. SHEET FOOTER BUTTONS
───────────────────────────────────────── */
.sheet-footer {
  position: sticky;
  bottom: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  padding: 14px 16px 16px;
  background: linear-gradient(to top, rgba(8,10,16,.99), rgba(8,10,16,.92), rgba(8,10,16,.05));
  border-top: 1px solid rgba(255,255,255,.06);
  z-index: 60;
}
.sheet-accept,
.sheet-dismiss {
  min-height: 52px;
  border: none;
  border-radius: 16px;
  font: 900 15px var(--font);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  z-index: 61;
}
.sheet-accept {
  color: #fff;
  background: linear-gradient(90deg, var(--cta1, #df2487), var(--cta2, #b91dd4));
  box-shadow: 0 12px 28px rgba(223,36,135,.22);
}
.sheet-dismiss {
  color: #fff;
  background: linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,.05));
  border: 1px solid rgba(255,255,255,.08);
}

/* Language-aware sheet labels */
.sheet-footer .label-en,
html[lang="en"] .sheet-footer .label-ar { display: none; }
html[lang="en"] .sheet-footer .label-en,
html[lang="ar"] .sheet-footer .label-ar,
html:not([lang="en"]) .sheet-footer .label-ar { display: inline; }

/* ─────────────────────────────────────────
   22. LANG SWITCHER
───────────────────────────────────────── */
.lang-switcher {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin: 0 0 18px;
}
.lang-btn {
  min-width: 110px;
  min-height: 42px;
  border: none;
  border-radius: 999px;
  cursor: pointer;
  font: 800 14px var(--font);
  color: #fff;
  background: linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,.05));
  border: 1px solid rgba(255,255,255,.10);
}
.lang-btn.active {
  background: linear-gradient(90deg, #ff2f9e, #b321ff);
  box-shadow: 0 10px 24px rgba(179,33,255,.18);
}

/* ─────────────────────────────────────────
   23. RESPONSIVE — SMALL PHONES  ≤480px
───────────────────────────────────────── */
@media (max-width: 480px) {
  body { padding: 18px 12px 40px; }
  .hero-title { font-size: 34px; }
  .hero-sub   { font-size: 18px; margin-bottom: 22px; }
  .section-title { font-size: 26px; }
  .cards      { gap: 40px; padding: 20px 10px; }
  .card       { max-width: 336px; min-height: 600px; border-radius: 24px; }
  .main       { padding: 18px 14px 30px; }
  .spacer     { min-height: 132px; }
  .media-hit  { height: 224px; }
  .play-hint  { width: 58px; height: 58px; }
  .play-hint::after {
    border-top-width: 9px;
    border-bottom-width: 9px;
    border-left-width: 14px;
  }
  .price      { font-size: 58px; }
  .grid, .actions, .link { max-width: 280px; }
  .plan       { min-height: 54px; }
  .action     { min-height: 46px; }
  .link.primary   { min-height: 50px; }
  .link.secondary { min-height: 46px; }
  .lang-switcher  { margin-bottom: 14px; }
  .lang-btn       { min-width: 96px; min-height: 38px; font-size: 13px; }
  .toast          { top: 56px; left: 12px; right: 12px; }
  .toast-inner    { padding: 11px 12px; }
  .sheet-footer   { gap: 10px; padding: 12px 14px 14px; }
  .sheet-accept, .sheet-dismiss { min-height: 48px; font-size: 14px; }
  .badge-mini     { max-width: 150px; }
}

/* ─────────────────────────────────────────
   24. RESPONSIVE — TABLET  481–1023px
───────────────────────────────────────── */
@media (min-width: 481px) and (max-width: 1023px) {
  .card     { width: 90%; max-width: 380px; min-height: 610px; }
  .media-hit { height: 232px; }
}

/* ─────────────────────────────────────────
   25. RESPONSIVE — DESKTOP  ≥1024px
   Full-image horizontal layout
───────────────────────────────────────── */
@media (min-width: 1024px) {
  .extratv-page { max-width: 1240px; }
  .cards        { gap: 30px; padding: 24px 16px; }

  .card {
    width: min(700px, 87%);
    max-width: 700px;
    min-height: 468px;
    border-radius: 32px;
    overflow: hidden;
  }
  .card::before { inset: -3px; border-radius: 34px; filter: blur(15px) saturate(1.08); opacity: .26; }
  .card::after  { border-radius: 29px; }

  /* Media fills full card */
  .media    { inset: 0; width: 100%; border-radius: inherit; }
  .media-hit { width: 56%; left: 0; right: auto; top: 0; height: 100%; z-index: 3; }

  /* Content panel on the right */
  .main {
    width: min(42%, 360px);
    margin-inline-start: auto;
    padding: 24px 22px 20px;
    justify-content: center;
    position: relative;
    z-index: 6;
    background:
      linear-gradient(180deg, rgba(8,12,22,.18), rgba(8,12,22,.10)),
      radial-gradient(circle at 15% 14%, rgba(255,192,70,.08), transparent 24%);
  }
  .spacer { display: none; }
  .center { margin-top: 0; align-items: stretch; text-align: right; }
  html[dir="ltr"] .center { text-align: left; }
  .price-wrap { align-items: flex-start; gap: 10px; margin-top: 8px; }
  .price      { font-size: 60px; line-height: .9; }
  .backup-pill { font-size: 13px; padding: 9px 15px; }
  .grid       { max-width: none; width: 100%; margin: 12px 0 0; gap: 10px; }
  .plan       { min-height: 48px; font-size: 14px; }
  .link, .actions { max-width: none; width: 100%; }
  .link.primary   { margin-top: 14px; min-height: 56px; font-size: 17px; }
  .link.secondary { margin-top: 10px; min-height: 48px; font-size: 15px; }
  .actions    { margin: 10px 0 0; gap: 10px; }
  .action     { min-height: 46px; font-size: 14px; }
  .device     { top: 16px; right: 16px; }
  .device svg { width: 24px; height: 24px; }
  .badge-mini { top: 14px; left: 14px; max-width: 170px; font-size: 11px; padding: 9px 14px; }

  /* Play hint centered on image side */
  .play-hint  { top: 50%; left: 28%; transform: translate(-50%,-50%); }
  .play-hint:hover { transform: translate(-50%,-50%) scale(1.08); }

  /* Side sheet (slides from right) */
  .sheet-panel {
    left: auto; right: 0;
    width: min(41%, 340px);
    max-height: 100%;
    min-height: 100%;
    border-radius: 0;
    border-top: none;
    border-inline-start: 1px solid rgba(255,255,255,.08);
    transform: translateX(104%);
  }
  .sheet.open .sheet-panel { transform: translateX(0); }
  .handle { display: none; }
  .sheet-head { padding-top: 18px; }

  .toast { top: 20px; left: 18px; right: auto; max-width: 340px; }
}

/* Intermediate desktop 1024–1199 */
@media (min-width: 1024px) and (max-width: 1199px) {
  .card { min-height: 430px; max-width: 640px; }
  .price { font-size: 52px; }
}


/* ─────────────────────────────────────────
   26. LOGO OVERLAY (dynamic via CSS vars)
───────────────────────────────────────── */
.card.has-logo .media::after {
  content: "";
  position: absolute;
  width: var(--logo-size, 80px);
  height: calc(var(--logo-size, 80px) * 0.5);
  background-image: var(--logo-url);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  z-index: 7;
  pointer-events: none;
  top:    var(--logo-top,    auto);
  bottom: var(--logo-bottom, auto);
  inset-inline-start: var(--logo-inset-inline-start, auto);
  inset-inline-end:   var(--logo-inset-inline-end,   auto);
  left:   var(--logo-left,   auto);
  transform: var(--logo-transform, none);
}
.card.logo-top-center .media::after,
.card.logo-bottom-center .media::after {
  transform: translateX(-50%);
}

/* ─────────────────────────────────────────
   27. SCROLL REVEAL (shown state)
───────────────────────────────────────── */
.card.show {
  opacity: 1 !important;
  transform: translateY(0) scale(1) !important;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * PACKAGE 3 — INTEGRATED FLOATING LOGO HEADER
 * ───────────────────────────────────────────────────────────────────────────
 * Real <img> rendered ABOVE the card inside .etv-card-wrap, using negative
 * margin overlap. No absolute positioning. Neutralizes the old pseudo-element
 * logo overlay so we never render the logo twice.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* Wrapper: stacks logo above card, preserves centered flex-item behavior of
   the .cards parent (which uses align-items:center). */
.etv-card-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
}

/* Logo container — centered, sits above the card, overlaps via negative margin */
.etv-card-logo {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  width: 100%;
  /* Negative bottom margin creates the "integrated" overlap onto the card's top edge */
  margin-bottom: -28px;
  position: relative;   /* stacking context; NOT absolute */
  z-index: 8;           /* above .card but below .sheet (which uses higher z) */
  pointer-events: none; /* the logo is decorative; clicks pass through to the card */
}

.etv-card-logo img {
  display: block;
  /* Respect saved logo_size as an upper bound; clamp responsively */
  max-width: min(var(--etv-logo-size, 160px), 180px);
  max-height: 120px;
  width: auto;
  height: auto;
  object-fit: contain;
  /* Subtle floating polish — no layout impact */
  filter: drop-shadow(0 6px 14px rgba(0,0,0,.35));
}

/* Mobile: smaller cap + tighter overlap so no horizontal overflow */
@media (max-width: 640px) {
  .etv-card-logo {
    margin-bottom: -20px;
  }
  .etv-card-logo img {
    max-width: min(var(--etv-logo-size, 120px), 120px);
    max-height: 90px;
  }
}

/* Tablet */
@media (min-width: 641px) and (max-width: 1023px) {
  .etv-card-logo img {
    max-width: min(var(--etv-logo-size, 150px), 160px);
  }
}

/* ───────────────────────────────────────────────────────────────────────────
 * NEUTRALIZE THE LEGACY PSEUDO-ELEMENT LOGO
 * The old implementation rendered the logo as .card.has-logo .media::after
 * using absolute positioning inside the card. We now render a real <img>
 * above the card, so the pseudo-element must be hidden to avoid duplicates.
 * We keep the .has-logo / .logo-* classes on the card (other styling may
 * reference them), but the ::after overlay is suppressed. */
.card.has-logo .media::after {
  content: none !important;
  background-image: none !important;
  display: none !important;
}

/* Keep the floating logo visually attached to the card during the card's
 * built-in reveal transform and hover lift. We mirror the card's transform
 * onto the wrapper's logo so the logo follows the card naturally. */
.etv-card-wrap {
  /* Let the logo move with the card; no transform on the wrap itself — the
   * card handles its own translate/scale. The logo is a sibling, so we give
   * it the SAME transition and hook the same states via :has() on the wrap. */
}
/* Use :has() where supported to mirror the card's hover/touch state onto the
 * logo. On browsers without :has(), the logo stays static during hover — no
 * broken layout, just slightly less polish. */
@supports selector(:has(*)) {
  .etv-card-wrap:has(.card:hover) .etv-card-logo,
  .etv-card-wrap:has(.card.touch-active) .etv-card-logo {
    transform: translateY(-8px) scale(1.015);
  }
  .etv-card-logo {
    transition: transform .35s ease;
  }
}

/* ── Phase 4.1 trial-status badge ── */
.trial-status {
  margin-top: 8px;
  width: 100%;
  display: flex;
  justify-content: center;
}
.trial-status-badge {
  width: 100%;
  max-width: 320px;
  box-sizing: border-box;
  padding: 8px 12px;
  border-radius: 16px;
  text-align: center;
  font-size: 12px;
  overflow: hidden;
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .10);
  color: inherit;
}
.trial-status-badge .line {
  display: block;
  white-space: normal;
  line-height: 1.35;
}
.trial-status-badge .line2 {
  opacity: 0.8;
  font-size: 11px;
}


/* ═══════════════════════════════════════════════════════════════════════════
 * PACKAGE 4 — FLOATING LOGO BADGE (Premium Gold Glass)
 * ───────────────────────────────────────────────────────────────────────────
 * Adds a floating gold-glass badge above each card and exposes two global
 * spacing controls (top space + space between cards). Every rule is scoped
 * on `.etv-card-wrap.has-floating-badge` — a class set by the renderer on
 * the wrap whenever the feature is enabled AND a logo URL was resolved.
 *
 * This means the feature does NOT depend on a `body` class (which some
 * themes drop or re-implement), and the wrap-scoping guarantees that when
 * the admin toggle is OFF the renderer simply doesn't add the class and
 * none of these rules apply — instant rollback, no data loss.
 *
 * CSS variables (set via wp_add_inline_style on :root from saved settings):
 *   --etv-bg-top              top padding of .cards container       (default 70px in admin)
 *   --etv-bg-gap              gap between cards                      (default 60px in admin)
 *   --etv-badge-offset-y      vertical offset of the badge           (default -45px)
 *   --etv-badge-w-d           desktop badge width                    (default 330px)
 *   --etv-badge-w-m           mobile badge width                     (default 240px)
 *   --etv-badge-glow-alpha    glow alpha (low/med/high → 0.18/0.32/0.48)
 *   --etv-badge-glow-blur     glow blur  (low/med/high → 14/22/32px)
 *
 * The wrapper layer (.etv-card-wrap) is reused — a new wrapper class would
 * have required renaming, which the spec forbids. We add the badge as a NEW
 * sibling layer inside that existing wrapper. Nothing inside .card changes.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* Hide the legacy floating logo when the new badge feature is on.
 * Two redundant paths so this works regardless of theme behavior:
 *   (a) wrap-scoped — primary path; always works because the class is set
 *       directly on the wrap by the renderer.
 *   (b) body-scoped — kept as a defense-in-depth fallback for any context
 *       where the wrap class might be missing (e.g. cached HTML).
 * The .etv-card-logo block is still emitted by PHP and its data, post meta,
 * and admin field are untouched — it is simply not painted. Toggling the
 * admin setting OFF removes both rules and the legacy logo reappears. */
.etv-card-wrap.has-floating-badge .etv-card-logo,
body.extratv-badge-on .etv-card-logo {
    display: none !important;
}

/* Layout: spacing controls apply when feature is on. Driven via :has() so
 * the rule fires on the .cards container as soon as any wrap inside it has
 * the has-floating-badge class. Browsers without :has() keep the existing
 * .cards padding/gap (52px/34px), which is acceptable graceful degradation
 * since the badge itself still appears above each card. */
@supports selector(:has(*)) {
    .cards:has(> .etv-card-wrap.has-floating-badge) {
        padding-top: var(--etv-bg-top, 70px);
        padding-bottom: var(--etv-bg-bottom, 20px);
        gap: var(--etv-bg-gap, 60px);
    }
    /* Mobile gap — overrides desktop gap on small viewports. Top/bottom
     * stay shared (admin can adjust via the desktop-only fields if needed). */
    @media (max-width: 640px) {
        .cards:has(> .etv-card-wrap.has-floating-badge) {
            gap: var(--etv-bg-gap-m, 40px);
        }
    }
}

/* The wrapper hosts an absolutely-positioned badge. position:relative is
 * additive — the existing wrapper is already a flex column centered, this
 * does not affect its layout.
 *
 * CRITICAL FIX phase: padding-top on the wrap is now ALWAYS 0. The badge
 * is absolutely positioned outside the wrap (negative top), and Top Gap
 * is folded into the badge's `top` calc instead of reserving wrap-level
 * layout space. This satisfies the Layout Spacing Independence rule —
 * card-to-card visual distance is now governed solely by .cards { gap }
 * (the between_space slider) and is unaffected by Top Gap / Overlap.
 *
 * For Inside placement, the badge sits over the card content area (inside
 * the wrap) and the .main element gets a padding-top instead so the badge
 * does not overlap the card's content. See the Inside placement rules
 * later in this file. */
.etv-card-wrap.has-floating-badge {
    position: relative;
    padding-top: 0;
}

/* The badge — absolutely positioned, centered, gold glass effect.
 * Uses backdrop-filter for the glass; `-webkit-backdrop-filter` covers Safari.
 * Clamped width so the badge can never exceed the card's horizontal area on
 * narrow screens (max-width:calc(100% - 24px) prevents horizontal scroll).
 *
 * Sizing rationale (v1.5): the badge is a FIXED-SIZE container — width, height
 * and horizontal padding are admin-controlled CSS variables, identical for
 * every card so badges line up uniformly regardless of logo aspect ratio or
 * text length. The image inside scales relative to the container (max-height
 * 70%) — the logo fits the badge, not the other way around.
 *
 * v1.6 visual upgrade: glow/border colors are now driven by theme variables
 * (--etv-theme-edge / -glow / -inner / -shadow) emitted by PHP based on the
 * "Badge Theme" admin selector. Defaults below match the v1.5 gold look so
 * sites that don't change the theme see the same colors with the new neon
 * structure layered on top. */
.etv-card-wrap.has-floating-badge > .extratv-floating-badge {
    position: absolute;
    /* Phase 1 + Phase Pro (v1.13): badge "top" is measured from the wrap's
     * outer top edge. Floating mode (default) lifts the badge above the card
     * by `overlap` and applies `offset_y` as a fine-tune nudge. Both values
     * are now per-tier (-d for desktop, -m for mobile via the @media block
     * below). The legacy single-value variables --etv-badge-overlap and
     * --etv-badge-offset-y are kept as fallbacks so any external code or
     * pre-Phase-Pro inline styles continue to work.
     *
     * Inside / hidden placement modes override this `top` value via the
     * .etv-badge-placement-* class rules (added later in this file). */
    top: calc(
        (-1 * var(--etv-badge-overlap-d, var(--etv-badge-overlap, 45px)))
        + var(--etv-badge-offset-y-d, var(--etv-badge-offset-y, 0px))
    );
    /* Phase Pro (v1.13): horizontal nudge of entire badge container.
     * Combined with the existing transform: translateX(-50%) below, the
     * badge stays centered around (50% + offset_x). The transform chain
     * is unchanged so v1.6 entrance animation + hover lift still work. */
    left: calc(50% + var(--etv-badge-offset-x-d, 0px));
    transform: translateX(-50%);
    z-index: 9; /* above .card (.etv-card-logo used z:8) but below .sheet */
    width: var(--etv-badge-w-d, 420px);
    height: var(--etv-badge-h-d, 90px);
    max-width: calc(100% - 24px);
    padding: 0 var(--etv-badge-px-d, 30px);
    border-radius: 18px;
    pointer-events: none; /* purely decorative; clicks pass through to the card */
    box-sizing: border-box;

    /* Glass surface — top-edge tint follows the active theme (subtle). */
    background:
        radial-gradient(120% 180% at 50% 0%, var(--etv-theme-tint, rgba(255, 209, 102, 0.10)) 0%, rgba(0, 0, 0, 0) 60%),
        linear-gradient(180deg, rgba(20, 20, 22, 0.55) 0%, rgba(10, 10, 12, 0.65) 100%);
    -webkit-backdrop-filter: blur(10px) saturate(140%);
    backdrop-filter: blur(10px) saturate(140%);

    /* Theme-driven neon edge + multi-layer cinematic glow.
     *   layer 1: 1px inset ring (inner edge light)
     *   layer 2: small inner softening
     *   layer 3: tight outer halo (sharper near border)
     *   layer 4: wide outer aura (cinematic depth)
     *   layer 5: cast shadow under badge for "floating" feel */
    border: 1px solid var(--etv-theme-edge, rgba(255, 199, 89, 0.85));
    box-shadow:
        inset 0 0 0 1px var(--etv-theme-inner, rgba(255, 220, 140, 0.35)),
        inset 0 1px 0 rgba(255, 255, 255, 0.18),
        0 0 calc(var(--etv-badge-glow-blur, 22px) * 0.6) var(--etv-theme-glow, rgba(255, 199, 89, 0.55)),
        0 0 calc(var(--etv-badge-glow-blur, 22px) * 1.6) var(--etv-theme-glow, rgba(255, 199, 89, 0.32)),
        0 12px 28px var(--etv-theme-shadow, rgba(0, 0, 0, 0.55));

    /* Smooth state transitions to mirror card hover */
    transition: transform .35s ease, box-shadow .35s ease;
    transform-origin: center bottom;

    display: flex;
    align-items: center;
    /* Center Align toggle — admin can set to flex-start to left-align the
     * logo inside the badge. Variable defaults to center. */
    justify-content: var(--etv-badge-justify, center);

    /* Subtle entrance animation. opacity + translateY only — no layout shift
     * (the badge is already absolute-positioned and out of flow). The keyframe
     * preserves translateX(-50%) so the static centering chain is intact. */
    animation: etv-badge-enter .55s cubic-bezier(.2, .8, .2, 1) both;
}

/* Top highlight — a thin glossy line just below the top border that catches
 * the theme edge color. Pure decoration; pointer-events disabled so the
 * underlying click-through behavior is preserved. */
.etv-card-wrap.has-floating-badge > .extratv-floating-badge::before {
    content: "";
    position: absolute;
    top: 1px; left: 10%; right: 10%;
    height: 1px;
    background: linear-gradient(90deg,
        transparent 0%,
        var(--etv-theme-edge, rgba(255, 199, 89, 0.85)) 50%,
        transparent 100%);
    opacity: .55;
    pointer-events: none;
    border-radius: 1px;
}

/* Soft inner edge light — a faint ambient bloom near the rounded corners.
 * Layered behind the content via z-index, never affects layout. */
.etv-card-wrap.has-floating-badge > .extratv-floating-badge::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    box-shadow: inset 0 0 18px var(--etv-theme-inner, rgba(255, 220, 140, 0.18));
    opacity: .8;
}

/* Optional soft pulse glow — gated on the .extratv-badge-pulse class added
 * to the wrap by PHP when the admin toggle is on. Animates only the box-shadow
 * intensity via the --etv-pulse-mul custom property; transform/layout never
 * touched, so this is GPU-cheap and causes zero reflow. */
@property --etv-pulse-mul {
    syntax: "<number>";
    inherits: true;
    initial-value: 1;
}
.etv-card-wrap.has-floating-badge.extratv-badge-pulse > .extratv-floating-badge {
    animation:
        etv-badge-enter .55s cubic-bezier(.2, .8, .2, 1) both,
        etv-badge-pulse 3.6s ease-in-out 0.6s infinite;
}

@keyframes etv-badge-enter {
    from {
        opacity: 0;
        transform: translateX(-50%) translateY(8px);
    }
    to {
        opacity: 1;
        transform: translateX(-50%) translateY(0);
    }
}

@keyframes etv-badge-pulse {
    0%, 100% {
        box-shadow:
            inset 0 0 0 1px var(--etv-theme-inner, rgba(255, 220, 140, 0.35)),
            inset 0 1px 0 rgba(255, 255, 255, 0.18),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 0.6) var(--etv-theme-glow, rgba(255, 199, 89, 0.55)),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 1.6) var(--etv-theme-glow, rgba(255, 199, 89, 0.32)),
            0 12px 28px var(--etv-theme-shadow, rgba(0, 0, 0, 0.55));
    }
    50% {
        box-shadow:
            inset 0 0 0 1px var(--etv-theme-inner, rgba(255, 220, 140, 0.55)),
            inset 0 1px 0 rgba(255, 255, 255, 0.22),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 0.9) var(--etv-theme-glow, rgba(255, 199, 89, 0.75)),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 2.2) var(--etv-theme-glow, rgba(255, 199, 89, 0.45)),
            0 12px 32px var(--etv-theme-shadow, rgba(0, 0, 0, 0.55));
    }
}

/* Reduced-motion users: disable both animations entirely. */
@media (prefers-reduced-motion: reduce) {
    .etv-card-wrap.has-floating-badge > .extratv-floating-badge,
    .etv-card-wrap.has-floating-badge.extratv-badge-pulse > .extratv-floating-badge {
        animation: none;
    }
}

/* The badge image — scales to fit the FIXED-SIZE container (premium wide
 * style). max-height:70% means the image always sits inside the badge with
 * uniform vertical breathing room regardless of badge height changes.
 *
 * Phase 1: an admin pixel override caps the image tighter than 70% if the
 * admin sets one. The PHP layer emits --etv-logo-max-h as 9999px when the
 * override is 0 (default), so min() resolves to 70%. When the admin sets a
 * non-zero override (e.g. 50px), min(70%, 50px) wins whichever is smaller.
 *
 * CRITICAL FIX phase: the cap is now per-tier. Desktop consumes
 * --etv-logo-max-h-d here; mobile consumes --etv-logo-max-h-m in the mobile
 * media query below. Each tier falls back to the legacy single-value
 * --etv-logo-max-h, then to 9999px (no cap = 70% rule wins). */
body.extratv-badge-on .extratv-floating-badge img,
.etv-card-wrap.has-floating-badge > .extratv-floating-badge img {
    display: block;
    width: auto;
    max-width: 100%;
    max-height: min(70%, var(--etv-logo-max-h-d, var(--etv-logo-max-h, 9999px)));
    object-fit: contain;
    /* margin auto preserves horizontal centering when the parent uses
     * justify-content:center; for left-align (flex-start) the auto margins
     * collapse and the image sits at the start edge naturally. */
    margin: 0 auto;
    /* Phase 2 (v1.12) + Phase Pro (v1.13): transform chain combines
     * horizontal offset, vertical lift, and uniform scale — all admin-
     * controlled with separate desktop/mobile values. Order: translateX,
     * translateY, scale. The legacy --etv-logo-scale variable is kept as
     * the final fallback for backward compat. */
    transform:
        translateX(var(--etv-logo-offset-x-d, 0px))
        translateY(var(--etv-logo-lift-d, 0px))
        scale(var(--etv-logo-scale-d, var(--etv-logo-scale, 1)));
    transform-origin: center center;
    /* Sit above the ::after inner-glow overlay (which has no z-index). */
    position: relative;
    z-index: 1;
}

/* Mobile tier — overrides width/height/padding to mobile-specific vars.
 * The badge stays a fixed size on mobile, just smaller. Glow is softened
 * via reduced shadow blur multipliers to keep mobile rendering clean and
 * avoid heavy compositor cost on lower-end devices. */
@media (max-width: 640px) {
    .etv-card-wrap.has-floating-badge > .extratv-floating-badge {
        width: var(--etv-badge-w-m, 300px);
        height: var(--etv-badge-h-m, 70px);
        padding: 0 var(--etv-badge-px-m, 16px);
        border-radius: 14px;
        /* Phase Pro (v1.13): re-bind top + left to mobile-specific vars. */
        top: calc(
            (-1 * var(--etv-badge-overlap-m, var(--etv-badge-overlap, 45px)))
            + var(--etv-badge-offset-y-m, var(--etv-badge-offset-y, 0px))
        );
        left: calc(50% + var(--etv-badge-offset-x-m, 0px));
        /* Glow blur multipliers scale with --etv-mobile-glow-mul (admin
         * "Mobile Glow Softness" 0..100% emitted as 0..1). At 60% (default)
         * the blurs match the previous hardcoded 0.4 / 1.0 ratios. */
        box-shadow:
            inset 0 0 0 1px var(--etv-theme-inner, rgba(255, 220, 140, 0.35)),
            inset 0 1px 0 rgba(255, 255, 255, 0.15),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 0.66 * var(--etv-mobile-glow-mul, 0.6)) var(--etv-theme-glow, rgba(255, 199, 89, 0.45)),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 1.66 * var(--etv-mobile-glow-mul, 0.6)) var(--etv-theme-glow, rgba(255, 199, 89, 0.22)),
            0 8px 18px var(--etv-theme-shadow, rgba(0, 0, 0, 0.45));
    }
    .etv-card-wrap.has-floating-badge > .extratv-floating-badge::after {
        box-shadow: inset 0 0 calc(20px * var(--etv-mobile-glow-mul, 0.6)) var(--etv-theme-inner, rgba(255, 220, 140, 0.14));
    }
    /* Phase 2 + Phase Pro (v1.13): re-bind the image transform chain on
     * mobile. translateX is the Logo Offset X (Phase Pro), translateY is
     * the Logo Lift Y (Phase 2), scale is Logo Scale (Phase 2).
     *
     * CRITICAL FIX phase: re-bind max-height to the mobile-specific
     * --etv-logo-max-h-m so the mobile cap is independent of desktop. */
    body.extratv-badge-on .extratv-floating-badge img,
    .etv-card-wrap.has-floating-badge > .extratv-floating-badge img {
        max-height: min(70%, var(--etv-logo-max-h-m, var(--etv-logo-max-h, 9999px)));
        transform:
            translateX(var(--etv-logo-offset-x-m, 0px))
            translateY(var(--etv-logo-lift-m, 0px))
            scale(var(--etv-logo-scale-m, var(--etv-logo-scale, 1)));
    }
}

/* Mirror the card's hover/touch lift onto the badge so the two move together.
 * The animation property is overridden to 'none' on hover so the static
 * transform here applies cleanly (without animations the entrance keyframes
 * would otherwise win on the transform chain). */
@supports selector(:has(*)) {
    .etv-card-wrap.has-floating-badge:has(.card:hover) > .extratv-floating-badge,
    .etv-card-wrap.has-floating-badge:has(.card.touch-active) > .extratv-floating-badge {
        animation: none;
        transform: translateX(-50%) translateY(-6px) scale(1.015);
    }
}


/* ═══════════════════════════════════════════════════════════════════════════
 * PACKAGE 5 — DISPLAY MODES + PER-PACKAGE COLORS + STRONG SPACING (v1.11)
 * ───────────────────────────────────────────────────────────────────────────
 * Layers four additive systems on top of v1.10:
 *
 *   1. Per-package color identity — each card key gets its own accent
 *      palette (edge/glow/inner/shadow/tint) that locally overrides the
 *      global theme set on :root. Selected via :has() so no HTML changes
 *      are needed on the wrap.
 *
 *   2. Display modes — wrap class controls the badge container shape:
 *        .etv-mode-wide      legacy fixed-size 420x90 (default for upgrades)
 *        .etv-mode-smart     auto-width, max 90% of card, balanced
 *        .etv-mode-slim      tight padding, lower height, compact
 *        .etv-mode-logo-only no container — just the logo floating
 *
 *   3. Spacing multiplier — multiplies the gap between cards by an admin
 *      preset (--etv-gap-multiplier: 1/1.5/2/3 = Soft/Medium/Strong/Extreme).
 *      Stacks on top of --etv-bg-gap. Top-space slider extended to 0-300.
 *
 *   4. Optional card accent — adds a subtle outer glow on the card itself
 *      driven by --etv-package-accent. Pure additive box-shadow, never
 *      touches card internals.
 *
 * All rules here are gated on .has-floating-badge so they only apply when
 * the badge feature is enabled. Disabling the feature reverts everything.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ─── Per-package palette via :has() on the wrap ─────────────────────────
 * The badge has data-card-key already; :has() selects the wrap based on
 * its descendant. We set the same 5 theme variables locally so they
 * override the global :root values via cascade. */
@supports selector(:has(*)) {
    /* Premium VIP — deep gold / amber */
    .etv-card-wrap.has-floating-badge:has(> .extratv-floating-badge[data-card-key="premium-vip"]) {
        --etv-theme-edge:   rgba(184, 134, 47, 0.85);
        --etv-theme-glow:   rgba(201, 150, 46, 0.52);
        --etv-theme-inner:  rgba(159, 107, 22, 0.32);
        --etv-theme-shadow: rgba(0, 0, 0, 0.55);
        --etv-theme-tint:   rgba(201, 150, 46, 0.10);
        --etv-package-accent: rgba(184, 134, 47, 0.45);
    }
    /* Premium — soft gold-green */
    .etv-card-wrap.has-floating-badge:has(> .extratv-floating-badge[data-card-key="premium"]) {
        --etv-theme-edge:   rgba(180, 215, 130, 0.80);
        --etv-theme-glow:   rgba(160, 200, 110, 0.50);
        --etv-theme-inner:  rgba(210, 235, 175, 0.35);
        --etv-theme-shadow: rgba(10, 24, 12, 0.55);
        --etv-theme-tint:   rgba(180, 215, 130, 0.10);
        --etv-package-accent: rgba(160, 200, 110, 0.40);
    }
    /* Basic — sky blue */
    .etv-card-wrap.has-floating-badge:has(> .extratv-floating-badge[data-card-key="basic"]) {
        --etv-theme-edge:   rgba(110, 200, 255, 0.85);
        --etv-theme-glow:   rgba(80, 180, 255, 0.50);
        --etv-theme-inner:  rgba(180, 225, 255, 0.35);
        --etv-theme-shadow: rgba(0, 14, 32, 0.55);
        --etv-theme-tint:   rgba(140, 210, 255, 0.10);
        --etv-package-accent: rgba(80, 180, 255, 0.42);
    }
    /* Lite — cool gray */
    .etv-card-wrap.has-floating-badge:has(> .extratv-floating-badge[data-card-key="lite"]) {
        --etv-theme-edge:   rgba(190, 200, 215, 0.75);
        --etv-theme-glow:   rgba(170, 185, 205, 0.42);
        --etv-theme-inner:  rgba(220, 230, 245, 0.30);
        --etv-theme-shadow: rgba(8, 12, 20, 0.55);
        --etv-theme-tint:   rgba(190, 200, 215, 0.08);
        --etv-package-accent: rgba(170, 185, 205, 0.30);
    }
    /* Mix Plus — purple/pink */
    .etv-card-wrap.has-floating-badge:has(> .extratv-floating-badge[data-card-key="mix-plus"]) {
        --etv-theme-edge:   rgba(200, 130, 240, 0.85);
        --etv-theme-glow:   rgba(190, 110, 230, 0.55);
        --etv-theme-inner:  rgba(225, 180, 245, 0.38);
        --etv-theme-shadow: rgba(20, 4, 32, 0.55);
        --etv-theme-tint:   rgba(200, 130, 240, 0.10);
        --etv-package-accent: rgba(200, 130, 240, 0.42);
    }
    /* VIP Plus — copper/orange with subtle rose-gold accent */
    .etv-card-wrap.has-floating-badge:has(> .extratv-floating-badge[data-card-key="vip-plus"]) {
        --etv-theme-edge:   rgba(200, 149, 58, 0.85);
        --etv-theme-glow:   rgba(199, 106, 26, 0.52);
        --etv-theme-inner:  rgba(138, 79, 18, 0.32);
        --etv-theme-shadow: rgba(28, 10, 0, 0.55);
        --etv-theme-tint:   rgba(255, 138, 22, 0.10);
        --etv-package-accent: rgba(200, 106, 126, 0.08);
    }
}

/* ─── Optional card accent ────────────────────────────────────────────────
 * Adds a soft outer glow on the card matching the package accent. Pure
 * additive — no card internals touched. The shadow is layered alongside
 * the existing .card box-shadow rather than replacing it. */
.etv-card-wrap.has-floating-badge .card {
    box-shadow:
        0 30px 78px rgba(0,0,0,.56),
        0 0 0 1px color-mix(in srgb, var(--theme1, #fff) 18%, transparent),
        inset 0 1px 0 rgba(255,255,255,.06),
        /* Package accent ring + soft glow — only paints when --etv-package-accent
         * is set (per-package overrides above). When unset, the var falls back
         * to fully-transparent so this layer is invisible. */
        0 0 0 1px var(--etv-package-accent, transparent),
        0 0 28px var(--etv-package-accent, transparent);
}

/* ─── Spacing multiplier ──────────────────────────────────────────────────
 * Multiplies the .cards gap by an admin-controlled factor (Soft 1 / Medium
 * 1.5 / Strong 2 / Extreme 3). Applied via :has() so it stacks with the
 * existing v1.7 gap rule. */
@supports selector(:has(*)) {
    .cards:has(> .etv-card-wrap.has-floating-badge) {
        gap: calc(var(--etv-bg-gap, 60px) * var(--etv-gap-multiplier, 1));
    }
    @media (max-width: 640px) {
        .cards:has(> .etv-card-wrap.has-floating-badge) {
            gap: calc(var(--etv-bg-gap-m, 40px) * var(--etv-gap-multiplier, 1));
        }
    }
}

/* ─── Display modes ───────────────────────────────────────────────────────
 *
 * SMART INTEGRATED (default for new installs)
 * Auto-width with max-width:90% of card. Slider value becomes the cap, not
 * the fixed width. Centered, balanced, doesn't force a large frame on small
 * logos.
 */
.etv-card-wrap.has-floating-badge.etv-mode-smart > .extratv-floating-badge {
    width: auto;
    min-width: 180px;
    max-width: min(var(--etv-badge-w-d, 420px), 90%);
}
@media (max-width: 640px) {
    .etv-card-wrap.has-floating-badge.etv-mode-smart > .extratv-floating-badge {
        min-width: 140px;
        max-width: min(var(--etv-badge-w-m, 300px), 90%);
    }
}

/*
 * SLIM
 * Tighter padding, reduced height. Width still auto-shrinks to content.
 */
.etv-card-wrap.has-floating-badge.etv-mode-slim > .extratv-floating-badge {
    width: auto;
    min-width: 160px;
    max-width: min(var(--etv-badge-w-d, 420px), 88%);
    height: calc(var(--etv-badge-h-d, 90px) - 18px);
    padding: 0 calc(var(--etv-badge-px-d, 30px) - 8px);
    border-radius: 14px;
}
@media (max-width: 640px) {
    .etv-card-wrap.has-floating-badge.etv-mode-slim > .extratv-floating-badge {
        min-width: 130px;
        max-width: min(var(--etv-badge-w-m, 300px), 88%);
        height: calc(var(--etv-badge-h-m, 70px) - 12px);
        padding: 0 calc(var(--etv-badge-px-m, 16px) - 4px);
        border-radius: 11px;
    }
}

/*
 * LOGO ONLY  (v1.14 visual refinement — cinematic floating header)
 * ─────────────────────────────────────────────────────────────────────────
 * Goal: a true premium standalone floating logo — no capsule, no oversized
 * empty container, but visually integrated with the card frame via a soft
 * theme-colored halo and a controlled border overlap.
 *
 * Design rules (do NOT inherit Wide/Smart/Slim sizing):
 *
 *   • The badge container becomes a sized box equal to the visible logo
 *     cap (64px desktop / 48px mobile by default). This means the floating
 *     math — which uses --etv-badge-h-d/-m to position the badge above the
 *     card — gets the *real* visible height, not the legacy 90/70px capsule
 *     height. Result: no phantom empty space above the logo.
 *
 *   • Capsule chrome is fully stripped (no background, border, hard shadow,
 *     backdrop-filter). The ::before/::after decorative layers are disabled.
 *
 *   • A soft radial halo is painted on the badge container itself, tinted
 *     with the active package theme color (--etv-theme-glow). This is the
 *     "blends into the card edge" effect — it is NOT a capsule, it is a
 *     diffuse cinematic glow that has no defined edge.
 *
 *   • The image carries a layered drop-shadow filter that uses the theme
 *     glow color (golden by default) plus a soft black anchoring shadow,
 *     replacing the previous muddy black-only shadow.
 *
 *   • Admin overrides (--etv-logo-max-h-d/-m) still cap the image as a
 *     hard upper bound so the slider keeps working.
 */

/* Logo-only mode redefines the badge "height" used by the floating-math
 * formula in PACKAGE 6 to the visible logo cap. The formula stays:
 *     badge_top = -(top_gap + badge_h - overlap) + offset_y
 * but badge_h now reflects what the user actually sees, so positioning
 * is tight and the logo sits naturally just above the card border. */
.etv-card-wrap.has-floating-badge.etv-mode-logo-only {
    --etv-logo-only-cap-d: 64px;
    --etv-logo-only-cap-m: 48px;
    --etv-badge-h-d: var(--etv-logo-only-cap-d);
    --etv-badge-h-m: var(--etv-logo-only-cap-m);
}

.etv-card-wrap.has-floating-badge.etv-mode-logo-only > .extratv-floating-badge {
    /* Container collapses to the logo footprint. Width auto-sizes to the
     * intrinsic image aspect ratio; height matches the cap so the floating
     * math has a correct number to work with. */
    width: auto;
    max-width: 90%;
    min-width: 0;
    height: var(--etv-logo-only-cap-d);
    padding: 0;
    border: 0;
    border-radius: 0;
    overflow: visible;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;

    /* Soft cinematic halo — radial, theme-tinted, no hard edge. This is what
     * gives the logo its "integrated with the card border" feel without
     * reintroducing a capsule. The halo extends past the image bounds via
     * the container's own overflow:visible AND the gradient's transparent
     * outer stop, so it fades into the card top edge naturally. */
    background:
        radial-gradient(
            120% 140% at 50% 70%,
            var(--etv-theme-glow, rgba(255, 199, 89, 0.28)) 0%,
            color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.28)) 35%, transparent) 35%,
            transparent 70%
        );
    box-shadow: none;
}

/* Disable the capsule decoration layers in logo-only. */
.etv-card-wrap.has-floating-badge.etv-mode-logo-only > .extratv-floating-badge::before,
.etv-card-wrap.has-floating-badge.etv-mode-logo-only > .extratv-floating-badge::after {
    display: none;
}

.etv-card-wrap.has-floating-badge.etv-mode-logo-only > .extratv-floating-badge img {
    /* Image is the hero. Height fills the container cap; admin's Logo Max
     * Height can pull it smaller but never larger than the cap. The 70%-of-
     * container rule from the base mode does not apply here. */
    height: 100%;
    width: auto;
    max-height: min(var(--etv-logo-only-cap-d), var(--etv-logo-max-h-d, var(--etv-logo-max-h, 9999px)));
    max-width: 100%;
    object-fit: contain;

    /* Two-layer cinematic drop-shadow: the first layer is the theme glow
     * (golden by default — "premium floating logo" feel), the second is a
     * tight black anchor so the logo reads against any backdrop. Replaces
     * the previous heavy black-only shadow. */
    filter:
        drop-shadow(0 0 10px var(--etv-theme-glow, rgba(255, 199, 89, 0.55)))
        drop-shadow(0 4px 10px rgba(0, 0, 0, 0.45));
}

@media (max-width: 640px) {
    .etv-card-wrap.has-floating-badge.etv-mode-logo-only > .extratv-floating-badge {
        height: var(--etv-logo-only-cap-m);
    }
    .etv-card-wrap.has-floating-badge.etv-mode-logo-only > .extratv-floating-badge img {
        max-height: min(var(--etv-logo-only-cap-m), var(--etv-logo-max-h-m, var(--etv-logo-max-h, 9999px)));
        /* Slightly tighter shadow on mobile so the logo doesn't bleed into
         * adjacent cards in a tight column layout. */
        filter:
            drop-shadow(0 0 8px var(--etv-theme-glow, rgba(255, 199, 89, 0.55)))
            drop-shadow(0 3px 8px rgba(0, 0, 0, 0.45));
    }
}

/*
 * WIDE BADGE (legacy)
 * No additional rules needed — this is the v1.5–v1.10 fixed-size behavior,
 * which is what the base .extratv-floating-badge selector already produces.
 * The .etv-mode-wide class is just a marker for the admin UI and PHP.
 */


/* ═══════════════════════════════════════════════════════════════════════════
 * PACKAGE 6 — BADGE PLACEMENT MODES (Phase Pro v1.13)
 * ───────────────────────────────────────────────────────────────────────────
 * Three placement modes via wrap class:
 *   .etv-badge-placement-floating  badge sits above the card (default — same
 *                                  behavior as pre-Phase-Pro). Uses overlap +
 *                                  offset_y. Top Gap reserves space.
 *   .etv-badge-placement-inside    badge sits inside the card content area at
 *                                  top: 18px + offset_y. Overlap + Top Gap
 *                                  do NOT apply. Useful when admins want the
 *                                  logo over the card image rather than
 *                                  floating above the card edge.
 *   .etv-badge-placement-hidden    badge is fully hidden via display:none.
 *
 * The wrap also keeps its existing classes (etv-mode-{smart|slim|logo-only|
 * wide}, package-key palette via :has(), etc.). Placement is orthogonal to
 * those — admins can pair Inside placement with Logo Only mode for a clean
 * "logo over the image" effect.
 *
 * The pre-Phase-Pro markup (no placement class) keeps working unchanged via
 * the base .extratv-floating-badge rules above, which already implement the
 * floating layout. Adding the floating class is a no-op visually; it exists
 * so the renderer can always emit one of the three classes deterministically.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* Floating (CRITICAL FIX phase): redefined math so Top Gap is the VISIBLE
 * empty space between the badge BOTTOM and the card TOP, while Overlap is
 * how far the badge dips INTO the card. Mutually exclusive zones — when
 * topGap > overlap, the result is a real air gap; when overlap > topGap,
 * the badge intrudes into the card by (overlap - topGap).
 *
 * Geometry (wrap-relative, wrap top edge = 0):
 *   wrap.padding-top  = 0                                    (no reserved space)
 *   card top          = 0
 *   badge bottom      = -(topGap - overlap) = overlap - topGap
 *   badge top         = badge bottom - badgeHeight
 *                     = -(topGap + badgeHeight - overlap)
 *   visible air gap   = topGap - overlap   (when positive)
 *   visible intrusion = overlap - topGap   (when positive)
 *
 * Verified against the v1.13 default (topGap=18, overlap=45, badgeH=90):
 *   badge top = -(18 + 90 - 45) = -63
 *   badge bottom = -63 + 90 = 27 (i.e. 27px below card top — same as before)
 *
 * Verified for true float (topGap=80, overlap=0, badgeH=90):
 *   badge top = -(80 + 90 - 0) = -170
 *   badge bottom = -80           (80px above card top — clear floating gap)
 *
 * The wrap no longer reserves any top padding in floating mode — it's not
 * needed because the badge is absolutely positioned above the wrap. This
 * also makes Top Gap and Overlap fully independent of the .cards-level
 * spacing controls (top_space / between_space / bottom_space): card-to-
 * card visual distance is governed solely by .cards { gap }, never by
 * the badge controls (Layout Spacing Independence requirement).
 */
.etv-card-wrap.has-floating-badge.etv-badge-placement-floating > .extratv-floating-badge {
    top: calc(
        -1 * (
            var(--etv-badge-top-gap-d, 18px)
            + var(--etv-badge-h-d, 90px)
            - var(--etv-badge-overlap-d, var(--etv-badge-overlap, 45px))
        )
        + var(--etv-badge-offset-y-d, var(--etv-badge-offset-y, 0px))
    );
    left: calc(50% + var(--etv-badge-offset-x-d, 0px));
}
@media (max-width: 640px) {
    .etv-card-wrap.has-floating-badge.etv-badge-placement-floating > .extratv-floating-badge {
        top: calc(
            -1 * (
                var(--etv-badge-top-gap-m, 14px)
                + var(--etv-badge-h-m, 70px)
                - var(--etv-badge-overlap-m, var(--etv-badge-overlap, 45px))
            )
            + var(--etv-badge-offset-y-m, var(--etv-badge-offset-y, 0px))
        );
        left: calc(50% + var(--etv-badge-offset-x-m, 0px));
    }
}

/* Inside: badge sits over the card content area at the top. The badge
 * itself remains absolutely positioned relative to the wrap; the badge top
 * is offset from the wrap's top edge (no Top Gap reserved space).
 *
 * CRITICAL FIX phase: previous attempts referenced `.etv-content`, which
 * does NOT exist in the actual card markup. The real DOM tree inside
 * `.card` is: `.media`, `.device`, `.main > .spacer + .center`, `.sheet`.
 * The fix is to push `.main` down with padding-top so the badge does not
 * overlap the price/CTA region. We do NOT modify the HTML structure or
 * rename any existing classes (per the strict rules). The selector is
 * scoped to `.etv-badge-placement-inside` so it only applies in Inside
 * mode and never affects Floating or Hidden modes.
 */
.etv-card-wrap.has-floating-badge.etv-badge-placement-inside > .extratv-floating-badge {
    top: calc(18px + var(--etv-badge-offset-y-d, var(--etv-badge-offset-y, 0px)));
    left: calc(50% + var(--etv-badge-offset-x-d, 0px));
}
.etv-card-wrap.has-floating-badge.etv-badge-placement-inside .card .main {
    padding-top: 80px;
}
@media (max-width: 768px) {
    .etv-card-wrap.has-floating-badge.etv-badge-placement-inside .card .main {
        padding-top: 60px;
    }
}
@media (max-width: 640px) {
    .etv-card-wrap.has-floating-badge.etv-badge-placement-inside > .extratv-floating-badge {
        top: calc(14px + var(--etv-badge-offset-y-m, var(--etv-badge-offset-y, 0px)));
        left: calc(50% + var(--etv-badge-offset-x-m, 0px));
    }
}

/* Hidden: badge fully hidden. Important to use !important since the pulse,
 * entrance animation and other modifier classes set display via cascading
 * rules that could otherwise revive it. */
.etv-card-wrap.has-floating-badge.etv-badge-placement-hidden > .extratv-floating-badge {
    display: none !important;
}


/* ═══════════════════════════════════════════════════════════════════════════
 * PACKAGE 7 — FINAL OPTICAL BLEND PASS (v1.15.1)
 * ───────────────────────────────────────────────────────────────────────────
 * STRICT VISUAL-ONLY REFINEMENT — additive, CSS-only, production-safe.
 *
 * Goal: dissolve the "floating dark rectangle" perception of the badge into
 * a cinematic integrated brand aura. Apple TV / Netflix Premium / DAZN feel,
 * NOT gaming-neon, NOT aggressive glow, NOT floating sticker.
 *
 * Strategy:
 *   1. Lower the dark glass background opacity so the container reads as
 *      atmosphere, not as a slab.
 *   2. Soften the 1px gold edge from 0.85α down to 0.30α and reduce the
 *      inset ring strength so the border dissolves into the surface.
 *   3. Redistribute box-shadow energy: less tight halo near the edge, more
 *      wide ambient aura. Glow now reads as originating from the content
 *      (logo / TV / Premium / VIP marks) rather than from the box border.
 *   4. mask-image radial fade on the badge container so the corner geometry
 *      melts into transparency — the rectangle becomes visually ambiguous.
 *   5. Slight compact: -8px desktop / -6px mobile on badge height, -4/-2px
 *      on padding. Tighter premium balance, no readability loss.
 *   6. Badge depth tuning: default overlap +6px so the badge embeds deeper
 *      into the card header, killing the floating-sticker feel.
 *   7. Top highlight & inner pseudo-glow opacity dropped so they read as
 *      atmosphere rather than container chrome.
 *   8. Pulse keyframe rebased on the new softer shadow values so the
 *      animation doesn't visually snap when it loops.
 *
 * All overrides are gated on .has-floating-badge so the legacy modes
 * (Inside, Hidden, Logo-Only) and disable paths are untouched. The
 * Logo-Only mode already has its own halo treatment and is intentionally
 * skipped here — refining a mode that has no capsule would be a no-op.
 *
 * Pre-Phase-Pro inline styles, --etv-badge-* admin vars, --etv-theme-*
 * package palettes, and per-tier desktop/mobile sizing all continue to
 * work — this layer only refines opacities, blurs, and one geometry tweak.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ─── 1+2+3+4+7. Container surface refinement (Wide / Smart / Slim) ──────
 * Logo-Only mode is excluded via :not() because it already strips capsule
 * chrome and applies its own radial halo (see PACKAGE 5 logo-only block).
 * The rule reasserts the same property set as the base v1.6 rule so the
 * cascade order is deterministic regardless of how the modifier classes
 * are ordered on the wrap. */
.etv-card-wrap.has-floating-badge:not(.etv-mode-logo-only) > .extratv-floating-badge {
    /* Softer glass surface — top tint kept (theme atmosphere), but the dark
     * base layer drops from 0.55/0.65 → 0.30/0.42 so the container reads as
     * atmosphere rather than a slab. Backdrop-filter unchanged. */
    background:
        radial-gradient(120% 180% at 50% 0%, var(--etv-theme-tint, rgba(255, 209, 102, 0.10)) 0%, rgba(0, 0, 0, 0) 60%),
        linear-gradient(180deg, rgba(20, 20, 22, 0.30) 0%, rgba(10, 10, 12, 0.42) 100%);

    /* Edge dissolve: a soft inverted radial mask so the corners fade into
     * transparency. The rectangle silhouette becomes visually ambiguous,
     * the center stays opaque enough to host the logo cleanly. */
    -webkit-mask-image:
        radial-gradient(140% 180% at 50% 50%,
            #000 0%,
            #000 55%,
            rgba(0, 0, 0, 0.85) 78%,
            rgba(0, 0, 0, 0.55) 92%,
            rgba(0, 0, 0, 0.35) 100%);
    mask-image:
        radial-gradient(140% 180% at 50% 50%,
            #000 0%,
            #000 55%,
            rgba(0, 0, 0, 0.85) 78%,
            rgba(0, 0, 0, 0.55) 92%,
            rgba(0, 0, 0, 0.35) 100%);

    /* Softer edge — the 1px hard ring drops from theme-edge (0.85α default)
     * to a much lower alpha via color-mix. Fallback uses a fixed 0.30α gold
     * for browsers without color-mix(). */
    border: 1px solid color-mix(in srgb, var(--etv-theme-edge, rgba(255, 199, 89, 0.85)) 35%, transparent);

    /* Redistributed cinematic glow — energy moved from the tight inner halo
     * to the wide ambient aura. Reads as content-originated atmosphere, not
     * border-originated neon. Cast shadow softened (lower y-offset, larger
     * blur) so the badge "sits in the scene" rather than hovering. */
    box-shadow:
        inset 0 0 0 1px color-mix(in srgb, var(--etv-theme-inner, rgba(255, 220, 140, 0.35)) 55%, transparent),
        inset 0 1px 0 rgba(255, 255, 255, 0.10),
        0 0 calc(var(--etv-badge-glow-blur, 22px) * 0.5) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 45%, transparent),
        0 0 calc(var(--etv-badge-glow-blur, 22px) * 2.4) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 32%, transparent),
        0 14px 36px color-mix(in srgb, var(--etv-theme-shadow, rgba(0, 0, 0, 0.55)) 70%, transparent);
}

/* Browsers without color-mix(): the legacy v1.15.0 shadow set above the
 * cascade still applies as fallback values via the base rule's !important-
 * free declarations. The :not() rule wins on specificity in modern browsers
 * but legacy Safari/old Chromium keep the previous look — graceful degrade. */

/* ─── 5+6. Compactness + badge depth (desktop) ───────────────────────────
 * Height -8px, padding -2px, default overlap +6px. The values fall back to
 * the existing admin-controlled vars when the admin has explicitly set
 * them (non-default), so user customisations are preserved. */
.etv-card-wrap.has-floating-badge:not(.etv-mode-logo-only) > .extratv-floating-badge {
    height: var(--etv-badge-h-d, 82px);
    padding: 0 var(--etv-badge-px-d, 28px);
}

/* Default overlap nudge: only applied when no admin override exists. The
 * float-position math in PACKAGE 6 already consumes --etv-badge-overlap-d
 * via var(... , fallback). Bumping the fallback from 45 → 51 pushes the
 * default position 6px deeper into the card without touching admin values. */
.etv-card-wrap.has-floating-badge.etv-badge-placement-floating > .extratv-floating-badge {
    top: calc(
        -1 * (
            var(--etv-badge-top-gap-d, 18px)
            + var(--etv-badge-h-d, 82px)
            - var(--etv-badge-overlap-d, var(--etv-badge-overlap, 51px))
        )
        + var(--etv-badge-offset-y-d, var(--etv-badge-offset-y, 0px))
    );
}

/* Decorative pseudo-elements — opacity tuned so they read as atmosphere
 * rather than container chrome. Top highlight: 0.55 → 0.32. Inner bloom:
 * 0.80 → 0.50. */
.etv-card-wrap.has-floating-badge:not(.etv-mode-logo-only) > .extratv-floating-badge::before {
    opacity: .32;
}
.etv-card-wrap.has-floating-badge:not(.etv-mode-logo-only) > .extratv-floating-badge::after {
    opacity: .50;
    box-shadow: inset 0 0 22px color-mix(in srgb, var(--etv-theme-inner, rgba(255, 220, 140, 0.18)) 60%, transparent);
}

/* ─── Pulse keyframe rebase ───────────────────────────────────────────────
 * The old PACKAGE 4 pulse animation drives box-shadow directly with the
 * legacy heavy values. With the softer base in place, the loop would
 * snap visually on every cycle. Re-define the same keyframe name with the
 * refined shadow palette so the pulse animates between the new base and a
 * gentle peak — no JS changes, the animation reference still resolves. */
@keyframes etv-badge-pulse {
    0%, 100% {
        box-shadow:
            inset 0 0 0 1px color-mix(in srgb, var(--etv-theme-inner, rgba(255, 220, 140, 0.35)) 55%, transparent),
            inset 0 1px 0 rgba(255, 255, 255, 0.10),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 0.5) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 45%, transparent),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 2.4) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 32%, transparent),
            0 14px 36px color-mix(in srgb, var(--etv-theme-shadow, rgba(0, 0, 0, 0.55)) 70%, transparent);
    }
    50% {
        box-shadow:
            inset 0 0 0 1px color-mix(in srgb, var(--etv-theme-inner, rgba(255, 220, 140, 0.35)) 70%, transparent),
            inset 0 1px 0 rgba(255, 255, 255, 0.14),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 0.8) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 60%, transparent),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 3.0) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 42%, transparent),
            0 16px 40px color-mix(in srgb, var(--etv-theme-shadow, rgba(0, 0, 0, 0.55)) 75%, transparent);
    }
}

/* ─── Mobile tier ────────────────────────────────────────────────────────
 * Same softening, smaller compact deltas (-6px height, -2px pad). Mobile
 * already has a softer shadow set via --etv-mobile-glow-mul, so this rule
 * only realigns it with the new base palette. */
@media (max-width: 640px) {
    .etv-card-wrap.has-floating-badge:not(.etv-mode-logo-only) > .extratv-floating-badge {
        height: var(--etv-badge-h-m, 64px);
        padding: 0 var(--etv-badge-px-m, 14px);
        background:
            radial-gradient(120% 180% at 50% 0%, var(--etv-theme-tint, rgba(255, 209, 102, 0.10)) 0%, rgba(0, 0, 0, 0) 60%),
            linear-gradient(180deg, rgba(20, 20, 22, 0.28) 0%, rgba(10, 10, 12, 0.40) 100%);
        border: 1px solid color-mix(in srgb, var(--etv-theme-edge, rgba(255, 199, 89, 0.85)) 32%, transparent);
        box-shadow:
            inset 0 0 0 1px color-mix(in srgb, var(--etv-theme-inner, rgba(255, 220, 140, 0.35)) 55%, transparent),
            inset 0 1px 0 rgba(255, 255, 255, 0.08),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 0.55 * var(--etv-mobile-glow-mul, 0.6)) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.45)) 40%, transparent),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 2.2 * var(--etv-mobile-glow-mul, 0.6)) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.45)) 26%, transparent),
            0 10px 24px color-mix(in srgb, var(--etv-theme-shadow, rgba(0, 0, 0, 0.45)) 65%, transparent);
    }

    /* Mobile placement: align fallback overlap with the desktop bump so the
     * badge embeds slightly deeper on phones too. Default 45 → 48 (smaller
     * delta on mobile to preserve compactness on tight column layouts). */
    .etv-card-wrap.has-floating-badge.etv-badge-placement-floating > .extratv-floating-badge {
        top: calc(
            -1 * (
                var(--etv-badge-top-gap-m, 14px)
                + var(--etv-badge-h-m, 64px)
                - var(--etv-badge-overlap-m, var(--etv-badge-overlap, 48px))
            )
            + var(--etv-badge-offset-y-m, var(--etv-badge-offset-y, 0px))
        );
    }
}

/* ─── Reduced-motion respect ──────────────────────────────────────────────
 * Already handled by the existing PACKAGE 4 rule that disables animations
 * under prefers-reduced-motion: reduce. The static state above is the new
 * resting palette, so reduced-motion users see the refined look without
 * any pulse — exactly as intended. No additional rule needed. */


/* ═══════════════════════════════════════════════════════════════════════════
 * PACKAGE 8 — FINAL MICRO OPTICAL TUNING (v1.15.2)
 * ───────────────────────────────────────────────────────────────────────────
 * STRICT CSS-ONLY, ADDITIVE micro-pass on top of PACKAGE 7. Cascade-only
 * overrides — every rule below targets the SAME selector chain that
 * PACKAGE 7 already owns, so the cascade resolves deterministically and
 * no earlier rule is deleted or replaced.
 *
 * Identified target class (verified against the renderer & cascade):
 *   .etv-card-wrap.has-floating-badge > .extratv-floating-badge
 * is the visible Logo Badge container. The :not(.etv-mode-logo-only) gate
 * is preserved so the standalone-logo mode (which has no capsule) is left
 * alone — refining a non-capsule mode would distort it.
 *
 * Refinement vector vs PACKAGE 7:
 *   • dark layer        0.30 / 0.42  →  0.20 / 0.30   (further dissolved)
 *   • edge alpha        35%          →  22%           (softer border)
 *   • inner ring        55%          →  35%           (softer inset)
 *   • mask falloff      55→100% gate →  45→100% gate  (deeper edge melt)
 *   • outer aura blur   *2.4         →  *3.0          (wider, softer)
 *   • outer aura alpha  32%          →  24%           (less mass, more air)
 *   • cast shadow       0 14 36      →  0 16 44       (sits deeper in scene)
 *
 * Plus two new "glow-from-content" devices:
 *   • a soft theme-tinted radial behind the logo, painted via the badge's
 *     existing background gradient stack (additive layer — does not
 *     replace the dark glass, sits BEHIND the logo at 50/55%).
 *   • a layered drop-shadow filter on the badge IMG so the cinematic glow
 *     reads as originating from the LOGO geometry itself, not from the
 *     rectangle border. Two stops: a wide soft theme aura + a tight black
 *     anchor for legibility on bright backdrops.
 *
 * Readability guards (per the "do not make logo weak" rule):
 *   • dark layer floor stays at 0.20α — never fully transparent
 *   • the logo drop-shadow's black anchor (0.40α) preserves contrast
 *   • inset 1px white highlight kept at 0.08α so the top edge still
 *     catches light and the badge silhouette remains perceptible
 *
 * Scope verification:
 *   • no PHP / Renderer / JS / DOM / shortcode / save / preview changes
 *   • no responsive logic touched (mobile mirrors desktop deltas only)
 *   • no card layout, button styling, logo sizing, logo positioning, or
 *     spacing-system changes — geometry inherited from PACKAGE 7
 *   • floating-math, placement modes, modes (smart/slim/wide), per-package
 *     palettes, pulse, entrance, hover-lift all unchanged
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ─── Desktop: surface, edge, glow, behind-logo radial ──────────────────── */
.etv-card-wrap.has-floating-badge:not(.etv-mode-logo-only) > .extratv-floating-badge {
    /* Background stack (top → bottom in paint order = bottom → top in code):
     *   layer A  theme tint cap (existing — atmosphere from card top)
     *   layer B  NEW soft theme-tinted radial behind logo (glow source)
     *   layer C  dark glass base (further reduced opacity)
     * Layer B is what makes the glow feel like it emanates from the logo
     * area instead of from the border. It is centered on the badge, fades
     * to transparent before reaching the edges, so it never reintroduces
     * a rectangular silhouette. */
    background:
        radial-gradient(120% 180% at 50% 0%,
            var(--etv-theme-tint, rgba(255, 209, 102, 0.10)) 0%,
            rgba(0, 0, 0, 0) 60%),
        radial-gradient(70% 120% at 50% 55%,
            color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 22%, transparent) 0%,
            color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 10%, transparent) 45%,
            transparent 75%),
        linear-gradient(180deg,
            rgba(20, 20, 22, 0.20) 0%,
            rgba(10, 10, 12, 0.30) 100%);

    /* Deeper edge dissolve — opaque core shrinks (55% → 45%) and corner
     * alphas drop further (0.85→0.80, 0.55→0.40, 0.35→0.20) so the
     * rectangle silhouette truly melts on dark backgrounds while the
     * center remains solid enough to host the logo. */
    -webkit-mask-image:
        radial-gradient(140% 180% at 50% 50%,
            #000 0%,
            #000 45%,
            rgba(0, 0, 0, 0.80) 72%,
            rgba(0, 0, 0, 0.40) 90%,
            rgba(0, 0, 0, 0.20) 100%);
    mask-image:
        radial-gradient(140% 180% at 50% 50%,
            #000 0%,
            #000 45%,
            rgba(0, 0, 0, 0.80) 72%,
            rgba(0, 0, 0, 0.40) 90%,
            rgba(0, 0, 0, 0.20) 100%);

    /* Softer border — alpha drops from 35% to 22% via color-mix. */
    border: 1px solid color-mix(in srgb, var(--etv-theme-edge, rgba(255, 199, 89, 0.85)) 22%, transparent);

    /* Glow re-balance:
     *   • inset ring  55% → 35%  (softer inner edge)
     *   • inset white 0.10 → 0.08 (top-edge highlight retained, dimmer)
     *   • tight halo  *0.5 / 45%  →  *0.4 / 35%  (reduced near-border energy)
     *   • wide aura   *2.4 / 32%  →  *3.0 / 24%  (wider, softer, more air)
     *   • cast shadow 0 14 36 / 70%  →  0 16 44 / 65%  (deeper, less heavy) */
    box-shadow:
        inset 0 0 0 1px color-mix(in srgb, var(--etv-theme-inner, rgba(255, 220, 140, 0.35)) 35%, transparent),
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        0 0 calc(var(--etv-badge-glow-blur, 22px) * 0.4) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 35%, transparent),
        0 0 calc(var(--etv-badge-glow-blur, 22px) * 3.0) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 24%, transparent),
        0 16px 44px color-mix(in srgb, var(--etv-theme-shadow, rgba(0, 0, 0, 0.55)) 65%, transparent);
}

/* Pseudo-element decoration — further dimmed so they don't read as chrome.
 * Top highlight 0.32 → 0.22, inner bloom 0.50 → 0.38. */
.etv-card-wrap.has-floating-badge:not(.etv-mode-logo-only) > .extratv-floating-badge::before {
    opacity: .22;
}
.etv-card-wrap.has-floating-badge:not(.etv-mode-logo-only) > .extratv-floating-badge::after {
    opacity: .38;
}

/* ─── Glow-originates-from-logo: drop-shadow on the badge IMG ───────────
 * Two-layer filter: a wide soft theme-colored aura (the "glow source")
 * plus a tight black anchor that protects logo legibility on light or
 * busy backdrops. This is what sells the "glow originates from the logo
 * itself" requirement — the visible aura now traces the logo's geometry,
 * not the rectangle's. The rule is gated on :not(.etv-mode-logo-only) so
 * the existing drop-shadow stack in logo-only mode is not double-applied. */
.etv-card-wrap.has-floating-badge:not(.etv-mode-logo-only) > .extratv-floating-badge img {
    filter:
        drop-shadow(0 0 14px color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 55%, transparent))
        drop-shadow(0 2px 6px rgba(0, 0, 0, 0.40));
}

/* ─── Pulse keyframe rebase (cascade override of PACKAGE 7's keyframe) ──
 * Same name, redefined with the v1.15.2 base+peak shadow palette so the
 * loop animates between the new resting state and a gentle peak — never
 * snapping back to the old heavier values mid-cycle. */
@keyframes etv-badge-pulse {
    0%, 100% {
        box-shadow:
            inset 0 0 0 1px color-mix(in srgb, var(--etv-theme-inner, rgba(255, 220, 140, 0.35)) 35%, transparent),
            inset 0 1px 0 rgba(255, 255, 255, 0.08),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 0.4) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 35%, transparent),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 3.0) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 24%, transparent),
            0 16px 44px color-mix(in srgb, var(--etv-theme-shadow, rgba(0, 0, 0, 0.55)) 65%, transparent);
    }
    50% {
        box-shadow:
            inset 0 0 0 1px color-mix(in srgb, var(--etv-theme-inner, rgba(255, 220, 140, 0.35)) 50%, transparent),
            inset 0 1px 0 rgba(255, 255, 255, 0.12),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 0.7) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 50%, transparent),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 3.6) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 32%, transparent),
            0 18px 48px color-mix(in srgb, var(--etv-theme-shadow, rgba(0, 0, 0, 0.55)) 70%, transparent);
    }
}

/* ─── Mobile (max-width:640px) — same vector, softer scale ─────────────── */
@media (max-width: 640px) {
    .etv-card-wrap.has-floating-badge:not(.etv-mode-logo-only) > .extratv-floating-badge {
        background:
            radial-gradient(120% 180% at 50% 0%,
                var(--etv-theme-tint, rgba(255, 209, 102, 0.10)) 0%,
                rgba(0, 0, 0, 0) 60%),
            radial-gradient(70% 120% at 50% 55%,
                color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.45)) 20%, transparent) 0%,
                color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.45)) 9%, transparent) 45%,
                transparent 75%),
            linear-gradient(180deg,
                rgba(20, 20, 22, 0.18) 0%,
                rgba(10, 10, 12, 0.28) 100%);

        border: 1px solid color-mix(in srgb, var(--etv-theme-edge, rgba(255, 199, 89, 0.85)) 20%, transparent);

        box-shadow:
            inset 0 0 0 1px color-mix(in srgb, var(--etv-theme-inner, rgba(255, 220, 140, 0.35)) 35%, transparent),
            inset 0 1px 0 rgba(255, 255, 255, 0.06),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 0.45 * var(--etv-mobile-glow-mul, 0.6)) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.45)) 30%, transparent),
            0 0 calc(var(--etv-badge-glow-blur, 22px) * 2.6 * var(--etv-mobile-glow-mul, 0.6)) color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.45)) 20%, transparent),
            0 12px 30px color-mix(in srgb, var(--etv-theme-shadow, rgba(0, 0, 0, 0.45)) 60%, transparent);
    }

    /* Mobile drop-shadow on the logo — slightly tighter so it doesn't
     * bleed into adjacent cards in tight column layouts. */
    .etv-card-wrap.has-floating-badge:not(.etv-mode-logo-only) > .extratv-floating-badge img {
        filter:
            drop-shadow(0 0 10px color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.45)) 50%, transparent))
            drop-shadow(0 2px 5px rgba(0, 0, 0, 0.40));
    }
}

/* ─── color-mix() fallback note ──────────────────────────────────────────
 * Browsers without color-mix() support (very old Safari/Chromium) keep the
 * PACKAGE 7 palette via lower-specificity rules. The visual delta in those
 * fallback contexts is minor — the badge stays softer than v1.15.0 base.
 * No graceful-degrade rule needed; the cascade handles it.
 * ═══════════════════════════════════════════════════════════════════════════ */


/* ═══════════════════════════════════════════════════════════════════════════
 * PACKAGE 9 — FINAL MICRO TRANSPARENCY REBALANCE (v1.15.3)
 * ───────────────────────────────────────────────────────────────────────────
 * CSS-ONLY, ADDITIVE micro-pass. Cascade override of ONLY the dark glass
 * base layer that PACKAGE 8 paints inside the badge background stack.
 *
 * What this pass touches:
 *   • dark linear-gradient base alpha   ~12% reduction:
 *       desktop  0.20 / 0.30  →  0.18 / 0.26
 *       mobile   0.18 / 0.28  →  0.16 / 0.24
 *
 * What this pass deliberately does NOT touch (kept exactly as PACKAGE 8):
 *   • glow system (box-shadow inner halo, outer aura, cast shadow)
 *   • blur radius (--etv-badge-glow-blur multipliers)
 *   • edge dissolve (mask-image radial gradient — same stops)
 *   • border softness (color-mix theme-edge alpha)
 *   • behind-logo radial atmosphere (theme-glow soft radial)
 *   • theme tint top atmosphere
 *   • drop-shadow filter on the badge IMG (logo-originated glow)
 *   • pseudo-element opacities (::before / ::after)
 *   • pulse keyframe (PACKAGE 8 rebase still wins)
 *   • placement modes, sizing, geometry, floating math
 *   • Logo-Only mode (excluded via :not())
 *
 * The override technique:
 *   Re-declare the SAME 3-layer background stack PACKAGE 8 sets, with the
 *   identical layer A (theme tint) and layer B (behind-logo radial)
 *   values, and ONLY layer C (the dark base) tweaked. This is necessary
 *   because the CSS `background` shorthand cannot independently override a
 *   single sub-layer — the entire stack must be re-declared as one unit.
 *   Every other layer is byte-identical to PACKAGE 8 so the cinematic
 *   direction is preserved exactly.
 *
 * Readability floor (per the brief):
 *   • dark base never goes below 0.16α — still provides a perceptible
 *     atmospheric support layer
 *   • the inset white highlight, theme-tint, behind-logo radial, soft
 *     border, cast shadow, and the logo's drop-shadow filter all remain
 *     unchanged → contrast on bright/mixed posters is preserved
 *   • visible-presence guards the brief's "badge still visually present"
 *     requirement
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ─── Desktop: rebalance dark base ONLY (everything else identical) ──── */
.etv-card-wrap.has-floating-badge:not(.etv-mode-logo-only) > .extratv-floating-badge {
    background:
        radial-gradient(120% 180% at 50% 0%,
            var(--etv-theme-tint, rgba(255, 209, 102, 0.10)) 0%,
            rgba(0, 0, 0, 0) 60%),
        radial-gradient(70% 120% at 50% 55%,
            color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 22%, transparent) 0%,
            color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.55)) 10%, transparent) 45%,
            transparent 75%),
        linear-gradient(180deg,
            rgba(20, 20, 22, 0.18) 0%,
            rgba(10, 10, 12, 0.26) 100%);
}

/* ─── Mobile: same rebalance, mobile palette preserved ───────────────── */
@media (max-width: 640px) {
    .etv-card-wrap.has-floating-badge:not(.etv-mode-logo-only) > .extratv-floating-badge {
        background:
            radial-gradient(120% 180% at 50% 0%,
                var(--etv-theme-tint, rgba(255, 209, 102, 0.10)) 0%,
                rgba(0, 0, 0, 0) 60%),
            radial-gradient(70% 120% at 50% 55%,
                color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.45)) 20%, transparent) 0%,
                color-mix(in srgb, var(--etv-theme-glow, rgba(255, 199, 89, 0.45)) 9%, transparent) 45%,
                transparent 75%),
            linear-gradient(180deg,
                rgba(20, 20, 22, 0.16) 0%,
                rgba(10, 10, 12, 0.24) 100%);
    }
}


/* ═══════════════════════════════════════════════════════════════════════════
 * PACKAGE 10 — FINAL MICRO ENVELOPE REFINEMENT (v1.15.4)
 * ───────────────────────────────────────────────────────────────────────────
 * CSS-ONLY, ADDITIVE micro-pass. Cascade override of ONLY the mask-image
 * radial gradient that PACKAGE 8 paints on the badge container. Nothing
 * else changes — every other value from PACKAGE 8 + 9 (glow, blur,
 * opacity, border, drop-shadow, theme tint, behind-logo radial, pulse,
 * pseudo-elements) is preserved byte-identical via the cascade.
 *
 * Diagnosis (from the visual comparison):
 *   The current mask ellipse `140% 180% at 50% 50%` extends past the badge
 *   horizontally further than necessary. Because the badge container is
 *   already a wide rectangle (~420×82 desktop), a 140% horizontal radius
 *   on the mask paints visible atmospheric ellipse mass to the left and
 *   right of the logo — the "horizontal band" perception. The 180%
 *   vertical radius similarly paints a slightly taller ellipse than the
 *   logo geometry needs.
 *
 *   The fix is purely geometric: shrink the radial ellipse on both axes
 *   so the visible atmospheric envelope hugs the logo more tightly. The
 *   falloff curve (stop alphas + stop positions) stays exactly as
 *   PACKAGE 8 set it, so softness and dissolve quality are preserved.
 *
 * Geometry deltas (mask-image radial-gradient only):
 *   desktop:  140% 180% at 50% 50%   →   110% 140% at 50% 50%
 *   mobile:   140% 180% at 50% 50%   →   115% 145% at 50% 50%   (slightly
 *             looser on mobile because the badge is shorter and more
 *             square-ish — going as tight as desktop would clip too close
 *             to the logo on small screens).
 *
 * What this pass deliberately does NOT touch (LOCKED per brief):
 *   • PHP / Renderer / JS / DOM / shortcode / save / preview
 *   • Responsive logic, card layout, buttons, logo sizing/position
 *   • Spacing system, floating math
 *   • Glow intensity (box-shadow halo + aura values from PACKAGE 8)
 *   • Blur strength (--etv-badge-glow-blur multipliers)
 *   • PACKAGE 9 opacity values (dark base 0.18/0.26 desktop, 0.16/0.24 mobile)
 *   • Border softness (color-mix theme-edge alpha at 22%)
 *   • Pseudo-element opacities, drop-shadow filter, pulse keyframe
 *   • Mask falloff alpha stops (0.80 / 0.40 / 0.20) and stop positions
 *     (0% / 45% / 72% / 90% / 100%) — only the ellipse SIZE changes,
 *     the curve shape is identical
 *   • Logo-Only mode (excluded via :not())
 *
 * Net visual effect:
 *   The atmospheric support layer becomes a tighter ellipse that hugs the
 *   logo geometry rather than spreading horizontally as a band. Softness,
 *   readability, glow, and cinematic direction are unaffected.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ─── Desktop: tighter mask ellipse ────────────────────────────────────── */
.etv-card-wrap.has-floating-badge:not(.etv-mode-logo-only) > .extratv-floating-badge {
    -webkit-mask-image:
        radial-gradient(110% 140% at 50% 50%,
            #000 0%,
            #000 45%,
            rgba(0, 0, 0, 0.80) 72%,
            rgba(0, 0, 0, 0.40) 90%,
            rgba(0, 0, 0, 0.20) 100%);
    mask-image:
        radial-gradient(110% 140% at 50% 50%,
            #000 0%,
            #000 45%,
            rgba(0, 0, 0, 0.80) 72%,
            rgba(0, 0, 0, 0.40) 90%,
            rgba(0, 0, 0, 0.20) 100%);
}

/* ─── Mobile: slightly looser tightening (115%/145%) ──────────────────── */
@media (max-width: 640px) {
    .etv-card-wrap.has-floating-badge:not(.etv-mode-logo-only) > .extratv-floating-badge {
        -webkit-mask-image:
            radial-gradient(115% 145% at 50% 50%,
                #000 0%,
                #000 45%,
                rgba(0, 0, 0, 0.80) 72%,
                rgba(0, 0, 0, 0.40) 90%,
                rgba(0, 0, 0, 0.20) 100%);
        mask-image:
            radial-gradient(115% 145% at 50% 50%,
                #000 0%,
                #000 45%,
                rgba(0, 0, 0, 0.80) 72%,
                rgba(0, 0, 0, 0.40) 90%,
                rgba(0, 0, 0, 0.20) 100%);
    }
}


/* ═══════════════════════════════════════════════════════════════════════════
 * PACKAGE 11 — LOGO ONLY TRUE ISOLATION (v1.16.0)
 * ───────────────────────────────────────────────────────────────────────────
 * NOT an optical tuning pass. NOT a glow / opacity / geometry adjustment.
 * This is a FUNCTIONAL ISOLATION fix for Logo Only Mode.
 *
 * Diagnosis:
 *   The PACKAGE 5 logo-only ruleset (added in v1.14) explicitly painted a
 *   radial-gradient background on the badge container as a "soft cinematic
 *   halo" feature. With container `width: auto; max-width: 90%` plus that
 *   radial gradient, the result reads to users as an atmospheric capsule
 *   support layer — exactly the "background layer / atmospheric rectangle /
 *   support band" the v1.16 spec requires Logo Only to NOT have.
 *
 *   Additionally, the PACKAGE 4 pulse box-shadow keyframe is not gated on
 *   :not(.etv-mode-logo-only). When pulse is enabled AND the mode is
 *   logo-only, the heavy capsule box-shadow re-enters via animation,
 *   undoing the `box-shadow: none` set by PACKAGE 5.
 *
 * Per the v1.16 brief, true Logo Only must show:
 *   ONLY a transparent logo + subtle per-card drop-shadow (the filter on
 *   the IMG, defined in PACKAGE 5 lines 1878-1881, already provides this).
 *
 *   Nothing else. No capsule background. No atmospheric radial. No
 *   container box-shadow at any time, including during pulse animation.
 *
 * Required isolations:
 *   1. Remove the radial-gradient halo background from the badge
 *      container in logo-only mode. The per-card glow already comes from
 *      the IMG's drop-shadow filter (which traces the actual logo
 *      geometry, not a rectangle). The container should paint nothing.
 *   2. Force box-shadow:none on the badge container in logo-only mode
 *      regardless of pulse state — pulse animation must not re-introduce
 *      the capsule shadow.
 *   3. Disable the entrance + pulse animations on the badge container in
 *      logo-only mode — both animations target box-shadow / transform on
 *      the container, neither of which is meaningful when the container
 *      has no visible chrome. The IMG's filter still renders normally,
 *      so per-card identity (gold / orange / purple / blue / neutral /
 *      green) is fully preserved.
 *
 * Scope:
 *   • PHP / Renderer / JS / DOM — untouched.
 *   • Other modes (Smart / Slim / Wide) — untouched. Their PACKAGE 5,
 *     7, 8, 9, 10 behavior is unchanged because every rule below is
 *     gated on .etv-mode-logo-only.
 *   • Per-card palette via :has() data-card-key — untouched.
 *   • The IMG's drop-shadow filter (PACKAGE 5 lines 1878-1881) —
 *     untouched. Per-card identity preserved.
 *   • Logo size / position — untouched.
 *   • Floating math — untouched (PACKAGE 5 already wires
 *     --etv-badge-h-d to the logo cap on the wrap, so placement math
 *     resolves to the correct logo height).
 *
 * This is a one-time functional isolation. No further passes needed.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ─── 1. Remove the container background entirely in logo-only ────────── */
.etv-card-wrap.has-floating-badge.etv-mode-logo-only > .extratv-floating-badge {
    background: none;
    /* Defensive: ensure nothing from earlier packages can paint the
     * container surface. PACKAGE 7-10 are already gated on
     * :not(.etv-mode-logo-only), but explicit nulls here protect against
     * any future addition that forgets the gate. */
    -webkit-mask-image: none;
    mask-image: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border: 0;
}

/* ─── 2. Force box-shadow off including during pulse animation ────────── */
.etv-card-wrap.has-floating-badge.etv-mode-logo-only > .extratv-floating-badge,
.etv-card-wrap.has-floating-badge.etv-mode-logo-only.extratv-badge-pulse > .extratv-floating-badge {
    box-shadow: none;
}

/* ─── 3. Disable container animations in logo-only ────────────────────── */
.etv-card-wrap.has-floating-badge.etv-mode-logo-only > .extratv-floating-badge,
.etv-card-wrap.has-floating-badge.etv-mode-logo-only.extratv-badge-pulse > .extratv-floating-badge {
    animation: none;
}

/* ─── Hover-lift safety: PACKAGE 4's :has() hover rule applies a small
 *     transform to the badge container on card hover. In logo-only that
 *     would shift the floating logo independently of the card, breaking
 *     the "logo is part of the card" feel. Reset to identity-translate
 *     so the entrance baseline (translateX(-50%)) is preserved.
 *     Gated on :supports(selector(:has(*))) implicitly because the
 *     PACKAGE 4 rule itself is gated that way; this rule simply wins
 *     on specificity when both apply. */
@supports selector(:has(*)) {
    .etv-card-wrap.has-floating-badge.etv-mode-logo-only:has(.card:hover) > .extratv-floating-badge,
    .etv-card-wrap.has-floating-badge.etv-mode-logo-only:has(.card.touch-active) > .extratv-floating-badge {
        animation: none;
        transform: translateX(-50%);
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * PACKAGE 11 — SURGICAL PERFORMANCE OPTIMIZATION (v1.16.2)
 * ───────────────────────────────────────────────────────────────────────────
 * Goal: reduce GPU paint cost, improve mobile rendering smoothness, fix
 * the VIP PLUS / MIX PLUS price-glyph top-clip, perfect the modal "×"
 * optical centering. ZERO visual change to the cinematic identity.
 *
 * Strategy:
 *   • Cards opt into the browser's content-visibility skip pass so cards
 *     well below the fold don't paint until scrolled near. Pure win for
 *     LCP / first paint on long pages with many cards. Keyed off the
 *     reveal-state .show class so the reveal animation never fights it.
 *   • Heavy infinite animations (shine/pulse/ring/heroPulse) are gated
 *     behind .show so off-screen cards never animate. Identical to the
 *     before-state (nothing was animating off-screen visually anyway,
 *     but the browser was still spending compositor cycles on them).
 *   • Mobile-only blur reduction on 5 surfaces. The visual is preserved
 *     because at mobile screen DPI, blur values 4-5px and 8-10px are
 *     visually indistinguishable on these dark, low-contrast surfaces,
 *     but the GPU paint cost is roughly halved on each.
 *   • prefers-reduced-motion: kill ALL infinite animations globally
 *     (already partly handled, now exhaustive).
 *   • (hover: none) / coarse pointer: no hover paint on touch devices.
 *
 * SCOPE GUARANTEES:
 *   • All rules below append to existing cascade — they OVERRIDE specific
 *     properties only, never replace whole rules. Removing this PACKAGE
 *     restores byte-identical pre-1.16.2 behavior.
 *   • No layout properties touched (no width/height/padding/margin on
 *     existing surfaces). No structural changes.
 *   • Per-package palettes, badge system, modes — all untouched.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ─── 1. Content visibility — defer paint of off-screen cards ──────────
 * .card uses opacity:0/translateY/scale for its reveal. We can give the
 * browser an intrinsic-size hint so it can skip layout/paint of cards
 * that are far below the viewport. The hint must be close to the actual
 * rendered size or the browser will mis-estimate scroll position.
 *
 * Mobile hint: ~600px tall card + 40px gap = ~640px.
 * Desktop hint: ~470px tall card + 30px gap = ~500px.
 *
 * Once a card has scrolled into view and received .show, the observer
 * has already locked it visible — at that point we drop content-visibility
 * to auto with no intrinsic size override so any internal text reflow
 * (lang switcher) is exact.
 *
 * Browsers without content-visibility ignore the property entirely.
 */
.card {
    /* v1.17.50.5 — White flash root fix:
       Do not use content-visibility:auto on cards. It can expose browser/theme
       placeholders during very fast scroll when media is still lazy/decoded. */
    content-visibility: visible;
    contain-intrinsic-size: auto;
}
@media (min-width: 1024px) {
    .card { contain-intrinsic-size: auto; }
}
.card.show {
    contain-intrinsic-size: auto;
}

/* ─── 2. Animation gating — only animate revealed cards ────────────────
 * Off-screen cards don't paint visibly (opacity:0) but the browser still
 * runs the keyframe loops, costing compositor time. Gate every infinite
 * animation on .show so cards that haven't entered the viewport yet are
 * literally idle. The visual end state is identical because off-screen
 * cards weren't visible anyway. */
.card:not(.show) .play-hint::before { animation: none; }
.card:not(.show) .plan.active       { animation: none; }
.card:not(.show) .link.primary      { animation: none; }
.card:not(.show) .link.primary::after { animation: none; }

/* ─── 3. Hover-only effects gated to true hover devices ────────────────
 * On touch devices, :hover fires after tap and triggers a full repaint
 * (including the lift transform + 4-layer box-shadow) for 300+ms before
 * being cleared. Gating .card:hover behind (hover: hover) eliminates
 * the cost on phones/tablets without removing it on desktop. The
 * .touch-active class (set by JS on touchstart) still produces the same
 * visual lift on tap, so behavior is unchanged. */
@media (hover: none) {
    .card:hover {
        /* Reset the hover paint on coarse-pointer devices. .touch-active
         * still applies the same effect via JS for tap feedback. */
        transform: translateY(0) scale(1);
        box-shadow:
            0 30px 78px rgba(0,0,0,.56),
            0 0 0 1px color-mix(in srgb, var(--theme1, #fff) 18%, transparent),
            inset 0 1px 0 rgba(255,255,255,.06);
        filter: none;
    }
    /* VIP plus keeps its scale */
    .card[data-key="vip-plus"]:hover { transform: scale(1.04); }
    .play-hint:hover {
        transform: translate(-50%, -50%);
        background: rgba(8,12,22,.42);
    }
}

/* ─── 4. Mobile blur reduction (≤640px) ────────────────────────────────
 * backdrop-filter is the single most expensive paint operation on mobile
 * GPUs. Each surface below currently uses 8-10px blur. At mobile screen
 * sizes these surfaces are tiny, sit on dark backgrounds, and the visual
 * difference between blur(8px) and blur(4px) is below perceptual threshold
 * — but the paint cost roughly halves with each px reduction.
 * The full desktop blur is preserved (rules untouched above 640px). */
@media (max-width: 640px) {
    .play-hint {
        -webkit-backdrop-filter: blur(4px);
        backdrop-filter: blur(4px);
    }
    .badge-mini {
        -webkit-backdrop-filter: blur(5px);
        backdrop-filter: blur(5px);
    }
    .backup-pill {
        -webkit-backdrop-filter: blur(4px);
        backdrop-filter: blur(4px);
    }
    .plan {
        -webkit-backdrop-filter: blur(4px);
        backdrop-filter: blur(4px);
    }
    .group-box {
        -webkit-backdrop-filter: blur(3px);
        backdrop-filter: blur(3px);
    }
    /* Card ambient glow — slightly tighter blur on mobile only.
     * Desktop unchanged (blur 16px). The opacity stays the same so the
     * visual halo is identical-looking; only the per-pixel blur cost drops. */
    .card::before {
        filter: blur(11px) saturate(1.12);
    }
}

/* ─── 4b. Mobile backdrop-filter disable (≤640px) — root-cause fix v1.17.51.13
 * INVESTIGATION RESULT: the mobile white/blank during fast scroll is a GPU
 * rasterization dropout, not a background/image/lazy-load issue. backdrop-filter
 * is the one effect whose cost is paid PER SCROLL FRAME — it must re-read and
 * re-blur the moving content behind it and cannot be cached while scrolling.
 * With many glass surfaces per card, the mobile rasterizer falls behind and the
 * compositor shows un-painted (white) tiles.
 *
 * Fix: on phones only (<=640px) and only inside .extratv-page, drop the live
 * backdrop blur on every card glass surface. Over the dark/cinematic card media
 * and the dark card body these chips already carry their own translucent fill,
 * so removing the live blur is below the perceptual threshold. Desktop (>640px)
 * is completely untouched. !important is used so this beats every per-style
 * backdrop-filter rule (including the one that itself uses !important) without
 * relying on selector-specificity ordering. Theme-coloured chips
 * (.badge-mini / .backup-pill / .device tier variants) keep their own
 * backgrounds, so per-tier colours are preserved. */
@media (max-width: 640px) {
    .extratv-page .group-box,
    .extratv-page .play-hint,
    .extratv-page .badge-mini,
    .extratv-page .backup-pill,
    .extratv-page .plan,
    .extratv-page .device,
    .extratv-page .extratv-floating-badge {
        -webkit-backdrop-filter: none !important;
        backdrop-filter: none !important;
    }
    /* Also cover the play-button style that declares backdrop-filter !important. */
    .extratv-page .card[data-play-button-style="mini-transparent"] .play-hint,
    .extratv-page .card[data-play-button-style="mini-transparent"] .play-hint.etv-play-visible:not(.hidden):not(.no-video) {
        -webkit-backdrop-filter: none !important;
        backdrop-filter: none !important;
    }
    /* Opacity compensation — default play button only. It is the one non-theme
     * glass surface sitting over the media that leaned on the blur; a small
     * alpha bump (.42 -> .52) keeps it reading as a solid chip. Style variants
     * (mini-transparent / small-glass) have higher specificity and keep their
     * own intentional backgrounds, so this does not affect them. */
    .extratv-page .play-hint {
        background: rgba(8,12,22,.52);
    }
}

/* ─── 5. Reduce ::after radial paint on small phones ───────────────────
 * The .card::after triple-gradient is layered behind .main on every card.
 * On tablets+ this is fine. On small phones, simplifying the layer to one
 * gradient halves the per-card paint cost. Visual difference on a 360px
 * screen is imperceptible. Top tint is preserved (theme identity stays). */
@media (max-width: 480px) {
    .card::after {
        background:
            radial-gradient(circle at top, rgba(223,36,135,.10), transparent 42%),
            linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,.10));
    }
}

/* ─── 6. Touch / scroll smoothness on mobile ───────────────────────────
 * touch-action: pan-y on the card prevents the browser from waiting on
 * pointer events to resolve before scrolling. Sheet body already uses
 * -webkit-overflow-scrolling: touch; we add scroll-behavior smoothing. */
@media (max-width: 640px) {
    .card,
    .extratv-card-wrap,
    .etv-card-wrap {
        touch-action: manipulation;
    }
    .sheet-body {
        overscroll-behavior: contain;
    }
}

/* ─── 7. prefers-reduced-motion — exhaustive animation kill ────────────
 * Users with motion sensitivity get a fully static card: no infinite
 * pulses, no shine sweep, no ring expansion, no entrance keyframes.
 * The .card.show transform/opacity transition is also collapsed to an
 * instantaneous state change so the card just appears. */
@media (prefers-reduced-motion: reduce) {
    .card,
    .card.show {
        transition: none !important;
    }
    .card,
    .card.show,
    .card[data-key="vip-plus"],
    .card[data-key="vip-plus"].show {
        animation: none !important;
    }
    .play-hint,
    .play-hint::before,
    .plan.active,
    .link.primary,
    .link.primary::after,
    .card[data-key="premium-vip"] .link.primary {
        animation: none !important;
    }
    .media video.playing { animation: none !important; }
}

/* ─── 8. PRICE CLIP FIX — VIP PLUS / MIX PLUS only ─────────────────────
 * Issue: on mobile, the top of digit ascenders ("9", "1", "7", "5") in
 * the gold-gradient prices for VIP PLUS and MIX PLUS gets clipped.
 *
 * Root cause: the gold gradient prices use background-clip:text + a 2-layer
 * drop-shadow filter. With line-height:.92 (mobile default) and the badge
 * top-overlap pulling content upward, the glyph ascenders + drop-shadow
 * halo render outside the .price box's logical line box. Any ancestor with
 * overflow:hidden (or even implicit clipping via the filter context) cuts
 * the top off.
 *
 * Surgical fix:
 *   (a) Add explicit overflow:visible on the .price element and the
 *       direct .price-wrap parent for these two tiers. Pure safety
 *       net — even if a future change adds overflow somewhere, the
 *       price stays uncut.
 *   (b) Lift line-height from .92/.9 to 1.02 ON THESE TIERS ONLY. This
 *       gives the ascender + drop-shadow halo room inside the line box.
 *       Other tiers keep the tight cinematic spacing exactly as-is.
 *   (c) Tiny padding-top: 2px on the .price element for these tiers
 *       absorbs any sub-pixel rounding offset where the badge sits.
 *
 * Visual result: the SAME font size, the SAME color/gradient, the SAME
 * cinematic feel — only the clipping is removed. No scale change.
 * Other tiers (premium-vip, premium, basic, lite) untouched.
 */
.card[data-key="mix-plus"] .price-wrap,
.card[data-key="vip-plus"] .price-wrap {
    overflow: visible;
}
.card[data-key="mix-plus"] .price,
.card[data-key="vip-plus"] .price {
    line-height: 1.02;
    padding-top: 2px;
    padding-bottom: 2px;
    overflow: visible;
}
/* On mobile, the issue is sharpest — keep the same fix but also make
 * sure the wrap above (.center) doesn't clip the drop-shadow halo. */
@media (max-width: 640px) {
    .card[data-key="mix-plus"] .center,
    .card[data-key="vip-plus"] .center {
        overflow: visible;
    }
    .card[data-key="mix-plus"] .price,
    .card[data-key="vip-plus"] .price {
        /* mobile font-size remains the global 58px from PACKAGE 23 — we
         * only ensure the line-box can hold the glyph + filter halo. */
        line-height: 1.04;
    }
}
/* Desktop side-panel layout: .price line-height was .9 — apply the same
 * line-height bump only to mix-plus / vip-plus so the side-by-side card
 * layout doesn't develop a different vertical rhythm. */
@media (min-width: 1024px) {
    .card[data-key="mix-plus"] .price,
    .card[data-key="vip-plus"] .price {
        line-height: 1.0;
    }
}

/* ─── 9. MODAL CLOSE "×" — TRUE OPTICAL CENTERING ──────────────────────
 * Issue: the U+00D7 multiplication sign has asymmetric vertical metrics
 * in most fonts — the glyph baseline sits ~12% below the visual center
 * of the box. With place-items:center grid alignment, the glyph appears
 * to sit slightly above-center.
 *
 * Surgical fix: switch to flex centering with explicit line-height:1
 * and a 1px optical baseline shift via padding-bottom. This places the
 * glyph's visual center at the box's mathematical center across all
 * sheets/cards/sizes consistently.
 *
 * The hit-area (42×42 / 14px radius / colors / borders) is unchanged. */
.close-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    /* The U+00D7 "×" glyph sits visually above its baseline center because
     * the multiplication sign's bounding box has more whitespace below the
     * glyph than above. Flex centers the LINE-BOX, not the glyph itself.
     * To shift the glyph visually downward into the box's true geometric
     * center, we add padding-top (which pushes the line-box down inside the
     * container). 3px is the empirically correct value for Tajawal at the
     * 26px font-size used here — the glyph baseline lands within ~1px of
     * geometric center of the 42px button on every tested rendering path. */
    padding: 3px 0 0 0;
    font-feature-settings: "kern" 0;
    font-family: 'Tajawal', Arial, sans-serif;
    /* Slight font-size bump so the glyph reads at the same optical weight
     * regardless of the user's installed font fallback. */
    font-size: 26px;
    font-weight: 700;
}
/* End of PACKAGE 11 — SURGICAL PERFORMANCE OPTIMIZATION */

/* ─── v1.17.9 — Smart Feature Text Fit — No Ellipsis ───────────────────
 * Feature lines must never be visually cut as "...".
 * Short text stays one line when it fits. Medium/long text wraps cleanly
 * to two lines if needed, especially on desktop side panels and mobile.
 * Details / Extra Stats HTML keep their normal <br> multi-line behavior. */
.feature {
  align-items: center;
  overflow: visible;
}

.feature .feature-text {
  min-width: 0;
  max-width: 100%;
  flex: 1 1 auto;
  display: block;
  white-space: normal !important;
  overflow: visible !important;
  text-overflow: clip !important;
  word-break: normal;
  overflow-wrap: anywhere;
  hyphens: auto;
  font-size: clamp(12.5px, 1.05vw, 15px);
  line-height: 1.35;
  font-weight: 800;
}

.feature .feature-text--short {
  white-space: nowrap !important;
  overflow-wrap: normal;
}

.feature .feature-text--medium {
  font-size: clamp(12px, 1vw, 14.5px);
  line-height: 1.32;
}

.feature .feature-text--long {
  font-size: clamp(11.5px, .95vw, 14px);
  line-height: 1.28;
}

@media (max-width: 480px) {
  .feature {
    gap: 7px;
    padding: 10px 10px;
    border-radius: 16px;
    align-items: center;
  }
  .feature .icon {
    width: 28px;
    height: 28px;
    min-width: 28px;
    border-radius: 10px;
    font-size: 14px;
  }
  .feature .feature-text {
    font-size: clamp(11px, 3.15vw, 13.25px);
    line-height: 1.25;
    letter-spacing: -0.02em;
  }
  .feature .feature-text--medium,
  .feature .feature-text--long {
    white-space: normal !important;
  }
}

@media (max-width: 360px) {
  .feature {
    gap: 6px;
    padding-left: 8px;
    padding-right: 8px;
  }
  .feature .icon {
    width: 26px;
    height: 26px;
    min-width: 26px;
    font-size: 13px;
  }
  .feature .feature-text {
    font-size: clamp(10.5px, 3vw, 12px);
    line-height: 1.22;
    letter-spacing: -0.035em;
  }
}


/* ─── v1.17.14 — Extra Stats Icon Alignment Polish ──────────────────────
 * Extra Stats are trusted HTML blocks appended after generated Features.
 * Generated Features keep their smart centered icon/text layout from v1.17.9.
 * Only Extra Stats blocks align the side icon to the top/first text line so
 * multi-line stats no longer look visually disconnected. */
.feature.extra-stats-feature {
  align-items: flex-start;
}

.feature.extra-stats-feature > .icon {
  align-self: flex-start;
  margin-top: 2px;
}

@media (max-width: 480px) {
  .feature.extra-stats-feature > .icon {
    margin-top: 1px;
  }
}


/* v1.17.15 — hide built-in language switcher; use site language/translation instead. */
.extratv-page .lang-switcher {
  display: none !important;
}

/* v1.17.19 — scoped details-anchor transition polish.
 * Applied only by cards.js when navigating to #details-{slug}. Uses opacity +
 * transform only, so it does not trigger layout shifts or affect other links. */
[id^="details-"] {
  scroll-margin-top: clamp(56px, 8vh, 96px);
}

@keyframes etvDetailsFocusIn {
  from {
    opacity: .82;
    transform: translate3d(0, 8px, 0);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

/* v1.17.51.12 — non-moving focus feedback (opacity only). This is the default
   for every device, so arriving at a details section never produces a
   transform-based jitter on touch/mobile. Desktop re-adds the subtle translate
   settle below. */
@keyframes etvDetailsFocusOpacity {
  from { opacity: .82; }
  to   { opacity: 1; }
}

.etv-details-focus[id^="details-"] {
  animation: etvDetailsFocusOpacity .32s ease both;
  will-change: opacity;
}

/* Desktop only (true hover + fine pointer) keeps the subtle translate settle. */
@media (hover: hover) and (pointer: fine) {
  .etv-details-focus[id^="details-"] {
    animation: etvDetailsFocusIn .32s cubic-bezier(.22, .61, .36, 1) both;
    will-change: opacity, transform;
  }
}

@media (prefers-reduced-motion: reduce) {
  .etv-details-focus[id^="details-"] {
    animation: none;
    will-change: auto;
  }
}

/* ExtraTV 1.17.46.1 — Mobile Safe Margins
   Minimal baseline patch on top of 1.17.46.
   Goal: reserve a small safe margin on phones without changing desktop,
   card content, prices, buttons, WooCommerce, WhatsApp, or overlay HTML. */
@media (max-width:480px){
  html,
  body{
    max-width:100%;
    overflow-x:hidden;
  }

  .extratv-page{
    max-width:100%;
    overflow-x:hidden;
    box-sizing:border-box;
  }

  .extratv-page .cards{
    padding-left:14px;
    padding-right:14px;
    box-sizing:border-box;
  }

  .extratv-page .etv-card-wrap,
  .extratv-page .card{
    width:100%;
    max-width:min(336px, calc(100vw - 36px));
    box-sizing:border-box;
    margin-left:auto;
    margin-right:auto;
  }
}

@media (max-width:360px){
  .extratv-page .cards{
    padding-left:12px;
    padding-right:12px;
  }

  .extratv-page .etv-card-wrap,
  .extratv-page .card{
    max-width:calc(100vw - 32px);
  }
}

/* ExtraTV 1.17.49.3 — True Cinematic Media Strength QA + Card Editor Top Badges
   Per-card visual controls from Card Editor:
   - General → Top Badges Visual
   - Media → Cinematic Image Preset
   Applies to all slides/images and video. No payment/checkout/link logic. */
.card{
  --etv-top-badge-bg: rgba(17,24,39,.34);
  --etv-top-badge-border: rgba(255,201,102,.28);
  --etv-top-badge-glow: rgba(255,170,52,.07);
  --etv-top-badge-blur: 10px;
  --etv-best-badge-x: 0px;
  --etv-best-badge-y: 0px;
  --etv-device-badge-x: 0px;
  --etv-device-badge-y: 0px;
  --etv-media-brightness: 100%;
  --etv-media-contrast: 100%;
  --etv-media-saturation: 100%;
  --etv-cinematic-overlay: rgba(0,0,0,0);
  --etv-cinematic-vignette: rgba(0,0,0,0);
  --etv-cinematic-warm: rgba(0,0,0,0);
  --etv-readability-gradient: rgba(0,0,0,0);
  --etv-visual-glow: rgba(0,0,0,0);
  --etv-visual-haze: rgba(255,255,255,0);
  --etv-visual-border-glow: rgba(0,0,0,0);
}

.card .slide{
  --etv-slide-brightness: var(--etv-media-brightness);
  --etv-slide-contrast: var(--etv-media-contrast);
  --etv-slide-saturation: var(--etv-media-saturation);
}
.card .slide{
  filter:
    brightness(var(--etv-slide-brightness))
    contrast(var(--etv-slide-contrast))
    saturate(var(--etv-slide-saturation));
}
.card .media video{
  filter:
    brightness(var(--etv-media-brightness))
    contrast(var(--etv-media-contrast))
    saturate(var(--etv-media-saturation));
}

.card .media::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:2;
  pointer-events:none;
  background:
    radial-gradient(circle at 72% 24%, var(--etv-visual-haze) 0 16%, transparent 44%),
    radial-gradient(circle at 26% 18%, var(--etv-visual-glow) 0 18%, transparent 48%),
    radial-gradient(circle at 68% 38%, var(--etv-cinematic-warm) 0 24%, transparent 50%),
    radial-gradient(circle at 50% 50%, transparent 0 54%, var(--etv-cinematic-vignette) 100%),
    linear-gradient(180deg, var(--etv-cinematic-overlay), rgba(0,0,0,0) 38%, var(--etv-readability-gradient) 78%, var(--etv-cinematic-vignette));
}

.card .badge-mini,
.card .device{
  background: linear-gradient(180deg, color-mix(in srgb, var(--etv-top-badge-bg) 92%, rgba(255,255,255,.10)), var(--etv-top-badge-bg));
  border: 1px solid var(--etv-top-badge-border);
  box-shadow:
    0 10px 24px rgba(0,0,0,.22),
    0 0 18px var(--etv-top-badge-glow),
    inset 0 1px 0 rgba(255,255,255,.10);
  backdrop-filter: blur(var(--etv-top-badge-blur)) saturate(1.12);
  -webkit-backdrop-filter: blur(var(--etv-top-badge-blur)) saturate(1.12);
}

.card .badge-mini{
  transform: translate(var(--etv-best-badge-x), var(--etv-best-badge-y));
}

.card .device{
  transform: translate(var(--etv-device-badge-x), var(--etv-device-badge-y));
  padding: 8px 13px;
  border-radius: 999px;
}

.card:hover .badge-mini,
.card.touch-active .badge-mini{
  transform: translate(var(--etv-best-badge-x), var(--etv-best-badge-y));
}

.card:hover .device,
.card.touch-active .device{
  transform: translate(var(--etv-device-badge-x), var(--etv-device-badge-y));
}

/* ExtraTV 1.17.49.5 — Play Button Controls
   Small transparent card-colored intro play button. Controlled from Card Editor → Media.
   Does not change video URL, media order, checkout, links, pricing, or slider logic. */
.card{
  --etv-play-small: 46px;
  --etv-play-medium: 58px;
  --etv-play-current-size: var(--etv-play-small);
  --etv-play-bg: color-mix(in srgb, var(--theme1, #ffc966) 24%, rgba(8,12,22,.42));
  --etv-play-border: color-mix(in srgb, var(--theme1, #ffc966) 36%, rgba(255,255,255,.16));
  --etv-play-glow: color-mix(in srgb, var(--theme1, #ffc966) 34%, transparent);
}

.card[data-play-button-visible="0"] .play-hint,
.card[data-play-button-style="hidden"] .play-hint{
  display:none !important;
  opacity:0 !important;
  visibility:hidden !important;
  pointer-events:none !important;
}

.card[data-play-button-size="small"]{
  --etv-play-current-size: var(--etv-play-small);
}
.card[data-play-button-size="medium"]{
  --etv-play-current-size: var(--etv-play-medium);
}

.card[data-play-button-style="small-glass"] .play-hint,
.card[data-play-button-style="circle-soft"] .play-hint,
.card[data-play-button-style="mini-transparent"] .play-hint{
  width: var(--etv-play-current-size);
  height: var(--etv-play-current-size);
  background:
    linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,.02)),
    var(--etv-play-bg);
  border: 1px solid var(--etv-play-border);
  box-shadow:
    0 10px 26px rgba(0,0,0,.26),
    0 0 20px var(--etv-play-glow),
    inset 0 1px 0 rgba(255,255,255,.12);
  backdrop-filter: blur(9px) saturate(1.12);
  -webkit-backdrop-filter: blur(9px) saturate(1.12);
}

.card[data-play-button-style="small-glass"] .play-hint{
  border-radius: 18px;
}

.card[data-play-button-style="circle-soft"] .play-hint{
  border-radius: 50%;
}

.card[data-play-button-style="mini-transparent"] .play-hint{
  width: calc(var(--etv-play-current-size) * .72) !important;
  height: calc(var(--etv-play-current-size) * .72) !important;
  border-radius: 50%;
  background:
    linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.015)),
    rgba(8,12,22,.18);
  border: 1px solid rgba(255,255,255,.34);
  box-shadow:
    0 8px 18px rgba(0,0,0,.20),
    0 0 0 1px rgba(255,255,255,.045),
    inset 0 1px 0 rgba(255,255,255,.12);
  backdrop-filter: blur(4px) saturate(1.04);
  -webkit-backdrop-filter: blur(4px) saturate(1.04);
}

.card[data-play-button-style="mini-transparent"] .play-hint::before{
  inset: -4px;
  opacity: .18;
  border-color: rgba(255,255,255,.20);
  animation: none;
}

.card[data-play-button-style="mini-transparent"] .play-hint::after{
  border-top-width: 5px !important;
  border-bottom-width: 5px !important;
  border-left-width: 8px !important;
  border-left-color: rgba(255,255,255,.88) !important;
  margin-inline-start: 2px !important;
}

.card[data-play-button-size="medium"][data-play-button-style="mini-transparent"] .play-hint::after{
  border-top-width: 6px !important;
  border-bottom-width: 6px !important;
  border-left-width: 10px !important;
}

.card[data-play-button-style="small-glass"] .play-hint::before,
.card[data-play-button-style="circle-soft"] .play-hint::before{
  inset: -6px;
  opacity: .34;
}

.card[data-play-button-style="small-glass"] .play-hint::after,
.card[data-play-button-style="circle-soft"] .play-hint::after,
.card[data-play-button-style="mini-transparent"] .play-hint::after{
  border-top-width: 7px;
  border-bottom-width: 7px;
  border-left-width: 11px;
  margin-inline-start: 3px;
}

.card[data-play-button-position="center"] .play-hint{
  top: 50%;
  left: 50%;
  right: auto;
  bottom: auto;
  transform: translate(-50%, -50%);
}

.card[data-play-button-position="lower-center"] .play-hint{
  top: 62%;
  left: 50%;
  right: auto;
  bottom: auto;
  transform: translate(-50%, -50%);
}

.card[data-play-button-position="bottom-right"] .play-hint{
  top: auto;
  left: auto;
  right: 22px;
  bottom: 142px;
  transform: none;
}

.card[data-play-button-position="center"] .play-hint:hover,
.card[data-play-button-position="lower-center"] .play-hint:hover{
  transform: translate(-50%, -50%) scale(1.06);
}

.card[data-play-button-position="bottom-right"] .play-hint:hover{
  transform: scale(1.06);
}

@media (max-width:480px){
  .card{
    --etv-play-small: 42px;
    --etv-play-medium: 52px;
  }
  .card[data-play-button-position="bottom-right"] .play-hint{
    right: 18px;
    bottom: 132px;
  }
}

/* ExtraTV 1.17.49.5.1 — Play Button Single Source Fix
   Fixes duplicate play triangles and makes saved size/visibility apply from first paint.
   The button icon is now CSS-only; any inner text is suppressed. */
.play-hint{
  font-size:0 !important;
  line-height:0 !important;
  color:transparent !important;
  overflow:hidden;
}

.play-hint::after{
  content:"" !important;
}

.play-hint.hidden,
.card[data-play-button-visible="0"] .play-hint,
.card[data-play-button-style="hidden"] .play-hint{
  opacity:0 !important;
  visibility:hidden !important;
  pointer-events:none !important;
  animation:none !important;
}

.play-hint.hidden::before,
.play-hint.hidden::after,
.card[data-play-button-visible="0"] .play-hint::before,
.card[data-play-button-visible="0"] .play-hint::after,
.card[data-play-button-style="hidden"] .play-hint::before,
.card[data-play-button-style="hidden"] .play-hint::after{
  animation:none !important;
}

.card[data-play-button-style="small-glass"] .play-hint,
.card[data-play-button-style="circle-soft"] .play-hint,
.card[data-play-button-style="mini-transparent"] .play-hint{
  width: var(--etv-play-current-size) !important;
  height: var(--etv-play-current-size) !important;
}

.card[data-play-button-style="small-glass"] .play-hint::after,
.card[data-play-button-style="circle-soft"] .play-hint::after,
.card[data-play-button-style="mini-transparent"] .play-hint::after{
  width:0 !important;
  height:0 !important;
  border-top:7px solid transparent !important;
  border-bottom:7px solid transparent !important;
  border-left:11px solid #fff !important;
  margin-inline-start:3px !important;
}

.card[data-play-button-size="small"] .play-hint::after{
  border-top-width:6px !important;
  border-bottom-width:6px !important;
  border-left-width:10px !important;
}

.card[data-play-button-size="medium"] .play-hint::after{
  border-top-width:8px !important;
  border-bottom-width:8px !important;
  border-left-width:13px !important;
}
/* ExtraTV 1.17.49.5.2 — Play Button Visibility Fix: server visibility follows admin setting; JS handles no-video. */

/* ExtraTV 1.17.49.5.3 — Play Button Clean Visibility Controller
   Show from first paint when admin enabled, then JS auto-hides. Hidden only
   when admin disabled/style hidden or JS adds .hidden after timeout/start. */
.card[data-play-button-visible="1"] .play-hint:not(.hidden):not(.no-video){
  opacity:1 !important;
  visibility:visible !important;
  pointer-events:auto !important;
  display:flex !important;
}

.card[data-play-button-visible="1"] .play-hint:not(.hidden):not(.no-video)::before,
.card[data-play-button-visible="1"] .play-hint:not(.hidden):not(.no-video)::after{
  opacity:1;
  visibility:visible;
}

.card[data-play-button-visible="1"][data-play-button-style="small-glass"] .play-hint:not(.hidden),
.card[data-play-button-visible="1"][data-play-button-style="circle-soft"] .play-hint:not(.hidden),
.card[data-play-button-visible="1"][data-play-button-style="mini-transparent"] .play-hint:not(.hidden){
  width: var(--etv-play-current-size) !important;
  height: var(--etv-play-current-size) !important;
}

/* ExtraTV 1.17.49.5.4 — Play Button Hard Reset
   Explicit .etv-play-visible class wins over legacy display:none rules.
   Hidden/disabled states still win when .hidden, no-video, or style hidden. */
.card .play-hint.etv-play-visible:not(.hidden):not(.no-video),
.play-hint.etv-play-visible:not(.hidden):not(.no-video){
  display:flex !important;
  opacity:1 !important;
  visibility:visible !important;
  pointer-events:auto !important;
  align-items:center !important;
  justify-content:center !important;
}

.card[data-play-button-style="hidden"] .play-hint,
.card[data-play-button-visible="0"] .play-hint,
.play-hint.hidden,
.play-hint.no-video{
  display:none !important;
  opacity:0 !important;
  visibility:hidden !important;
  pointer-events:none !important;
}

.card .play-hint.etv-play-visible:not(.hidden):not(.no-video)::after,
.play-hint.etv-play-visible:not(.hidden):not(.no-video)::after{
  content:"" !important;
  display:block !important;
  opacity:1 !important;
  visibility:visible !important;
}


/* ExtraTV 1.17.49.6.1 — Mini Transparent Play Button
   Small, highly transparent global-only style. No media/order/slider logic changed. */
.card[data-play-button-style="mini-transparent"] .play-hint,
.card[data-play-button-visible="1"][data-play-button-style="mini-transparent"] .play-hint:not(.hidden),
.card[data-play-button-style="mini-transparent"] .play-hint.etv-play-visible:not(.hidden):not(.no-video){
  width: calc(var(--etv-play-current-size) * .72) !important;
  height: calc(var(--etv-play-current-size) * .72) !important;
  border-radius: 50% !important;
  background:
    linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.015)),
    rgba(8,12,22,.18) !important;
  border: 1px solid rgba(255,255,255,.34) !important;
  box-shadow:
    0 8px 18px rgba(0,0,0,.20),
    0 0 0 1px rgba(255,255,255,.045),
    inset 0 1px 0 rgba(255,255,255,.12) !important;
  backdrop-filter: blur(4px) saturate(1.04) !important;
  -webkit-backdrop-filter: blur(4px) saturate(1.04) !important;
}

.card[data-play-button-style="mini-transparent"] .play-hint::before{
  inset: -4px !important;
  opacity: .18 !important;
  border-color: rgba(255,255,255,.20) !important;
  animation: none !important;
}

.card[data-play-button-style="mini-transparent"] .play-hint::after,
.card[data-play-button-style="mini-transparent"] .play-hint.etv-play-visible:not(.hidden):not(.no-video)::after{
  width: 0 !important;
  height: 0 !important;
  border-top: 5px solid transparent !important;
  border-bottom: 5px solid transparent !important;
  border-left: 8px solid rgba(255,255,255,.88) !important;
  margin-inline-start: 2px !important;
}

.card[data-play-button-size="medium"][data-play-button-style="mini-transparent"] .play-hint::after,
.card[data-play-button-size="medium"][data-play-button-style="mini-transparent"] .play-hint.etv-play-visible:not(.hidden):not(.no-video)::after{
  border-top-width: 6px !important;
  border-bottom-width: 6px !important;
  border-left-width: 10px !important;
}


/* ExtraTV 1.17.50.5 — Clean Scoped Media Flash Guard
   Replaces the old 1.17.49.7 guard. The old guard painted html/body/page/cards
   dark and created a wide black canvas around cards. This version is scoped to
   the media subtree only: no html/body/.extratv-page/.cards background rules. */

.extratv-page .etv-card-wrap,
.extratv-page .extratv-card-wrap{
  background:transparent;
  min-height:1px;
}

/* Keep real card canvas owned by the original design, not by the flash guard. */
.extratv-page .card{
  content-visibility:visible;
  contain-intrinsic-size:auto;
}

/* The only permitted fallback is inside media/slide while the image decodes. */
.extratv-page .media,
.extratv-page .media-slider,
.extratv-page .slide,
.extratv-page .slide img,
.extratv-page .media video{
  background-color:#050914;
}

.extratv-page .media{
  background:
    radial-gradient(circle at 50% 16%, rgba(96,38,160,.10), transparent 38%),
    linear-gradient(180deg, #08101f 0%, #030711 100%);
}

.extratv-page .media-slider{
  position:absolute;
  inset:0;
}

.extratv-page .slide{
  backface-visibility:hidden;
  transform:translateZ(0) scale(1.01);
}

.extratv-page .slide:not([style*="background-image"]){
  background-image:
    radial-gradient(circle at 50% 22%, rgba(255,255,255,.035), transparent 36%),
    linear-gradient(180deg, #0a1222 0%, #030711 100%);
}

.extratv-page .slide img{
  min-width:100%;
  min-height:100%;
}

/* WP Rocket / Used CSS / lazy-load safety: keep guarded MEDIA opaque inside
   the image area only. Never paint decorative/logo PNG canvases.
   1.17.51.2: avoid adding a dark rectangle behind the floating logo tab by
   scoping the guard to actual card media/slider images. */
.extratv-page img.etv-scroll-guard-media,
.extratv-page .media img.skip-lazy.no-lazyload,
.extratv-page .media-slider img.skip-lazy.no-lazyload,
.extratv-page .slide img.skip-lazy.no-lazyload{
  background-color:#050914;
}

@media (max-width:480px){
  .extratv-page .card{ min-height:600px; }
}

@media (min-width:481px) and (max-width:1023px){
  .extratv-page .card{ min-height:610px; }
}

@media (min-width:1024px){
  .extratv-page .card{ min-height:468px; }
}


/* v1.17.49.9.1 — Smart Display Visible Effect Fix
   Stronger visible presets + frontend debug attributes. Current Design remains
   untouched; only slides with an explicit smart preset are affected. */
.card .slide[data-image-theme-override="1"]::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:1;
  pointer-events:none;
  background:
    radial-gradient(circle at 72% 24%, var(--etv-slide-haze, rgba(255,255,255,0)) 0 16%, transparent 44%),
    radial-gradient(circle at 26% 18%, var(--etv-slide-glow, rgba(0,0,0,0)) 0 18%, transparent 48%),
    radial-gradient(circle at 68% 38%, var(--etv-slide-warm, rgba(0,0,0,0)) 0 24%, transparent 50%),
    radial-gradient(circle at 50% 50%, transparent 0 54%, var(--etv-slide-vignette, rgba(0,0,0,0)) 100%),
    linear-gradient(180deg, var(--etv-slide-overlay, rgba(0,0,0,0)), rgba(0,0,0,0) 38%, var(--etv-slide-readability, rgba(0,0,0,0)) 78%, var(--etv-slide-vignette, rgba(0,0,0,0)));
}
.card .slide[data-image-theme-override="1"] img{position:relative;z-index:0;}

.card .slide[data-smart-display][data-smart-applied="1"]{
  background-size:cover !important;
  /* v1.17.51.12 — removed permanent will-change:transform,background-position.
     The smart-display scale is a STATIC transform, so a persistent compositor
     promotion gave no visual benefit and only added a GPU layer per active
     slide across all cards — compositor pressure that contributes to
     fast-scroll checkerboarding (white gaps) and jank on mobile. The scale
     transform itself is unchanged, so visual output is identical. */
}
.card .slide[data-smart-display][data-smart-applied="1"] img{
  object-fit:cover !important;
}

/* Desktop/base rules: stronger than 1.17.49.9 so the admin can see the change. */
.card .slide.active[data-smart-display="auto-smart"]{transform:scale(1.08) !important;transform-origin:50% 46% !important;}
.card .slide[data-smart-display="auto-smart"],
.card .slide[data-smart-display="auto-smart"] img{background-position:center 46% !important;object-position:center 46% !important;}

.card .slide.active[data-smart-display="center-safe"]{transform:scale(1.10) !important;transform-origin:50% 50% !important;}
.card .slide[data-smart-display="center-safe"],
.card .slide[data-smart-display="center-safe"] img{background-position:center center !important;object-position:center center !important;}

.card .slide.active[data-smart-display="top-safe"]{transform:scale(1.14) !important;transform-origin:50% 8% !important;}
.card .slide[data-smart-display="top-safe"],
.card .slide[data-smart-display="top-safe"] img{background-position:center 8% !important;object-position:center 8% !important;}

.card .slide.active[data-smart-display="left-focus"]{transform:scale(1.14) !important;transform-origin:18% 50% !important;}
.card .slide[data-smart-display="left-focus"],
.card .slide[data-smart-display="left-focus"] img{background-position:18% center !important;object-position:18% center !important;}

.card .slide.active[data-smart-display="right-focus"]{transform:scale(1.14) !important;transform-origin:82% 50% !important;}
.card .slide[data-smart-display="right-focus"],
.card .slide[data-smart-display="right-focus"] img{background-position:82% center !important;object-position:82% center !important;}


/* v1.17.49.9.2 — One Image Safe-Fit Display System
   Uses the same exact image twice: a blurred cover fill behind a clear contain
   image. This avoids a second mobile image while reducing harsh mobile crops. */
.card .slide[data-smart-display="safe-fit-fill"]{
  background-image:none !important;
  background-color:#050914 !important;
  background-size:cover !important;
  background-position:center center !important;
  overflow:hidden;
}
.card .slide[data-smart-display="safe-fit-fill"]::before{
  content:"";
  position:absolute;
  inset:-28px;
  z-index:0;
  pointer-events:none;
  background-image:var(--etv-safe-fit-image);
  background-size:cover;
  background-position:center center;
  background-repeat:no-repeat;
  filter:blur(18px) brightness(.58) saturate(1.08);
  transform:scale(1.12);
  opacity:.92;
}
.card .slide[data-smart-display="safe-fit-fill"] img{
  position:relative !important;
  z-index:1 !important;
  object-fit:contain !important;
  object-position:center center !important;
  transform:none !important;
  filter:drop-shadow(0 16px 28px rgba(0,0,0,.36));
}
.card .slide.active[data-smart-display="safe-fit-fill"]{
  transform:scale(1) !important;
  transform-origin:50% 50% !important;
}
.card .slide[data-smart-display="safe-fit-fill"][data-image-theme-override="1"]::after{
  z-index:2;
}
.card .slide[data-smart-display="safe-fit-fill"][data-image-theme-override="1"] img{
  z-index:1 !important;
}
@media (max-width:480px){
  .card .slide[data-smart-display="safe-fit-fill"]::before{inset:-34px;filter:blur(20px) brightness(.52) saturate(1.06);transform:scale(1.16);}
}

.card .slide[data-smart-display="full-view"]{background-size:contain !important;background-position:center center !important;background-color:#000 !important;}
.card .slide[data-smart-display="full-view"] img{object-fit:contain !important;object-position:center center !important;}
.card .slide.active[data-smart-display="full-view"]{transform:scale(1) !important;transform-origin:50% 50% !important;}

/* Tablet: Auto Smart and Mobile Fix visibly protect the upper center. */
@media (min-width:481px) and (max-width:1023px){
  .card .slide.active[data-smart-display="auto-smart"]{transform:scale(1.14) !important;transform-origin:50% 24% !important;}
  .card .slide[data-smart-display="auto-smart"],
  .card .slide[data-smart-display="auto-smart"] img{background-position:center 24% !important;object-position:center 24% !important;}

  .card .slide.active[data-smart-display="mobile-fix"]{transform:scale(1.16) !important;transform-origin:50% 18% !important;}
  .card .slide[data-smart-display="mobile-fix"],
  .card .slide[data-smart-display="mobile-fix"] img{background-position:center 18% !important;object-position:center 18% !important;}
}

/* Desktop: Mobile Fix intentionally does not alter the desktop crop. */
@media (min-width:1024px){
  .card .slide[data-smart-display="mobile-fix"]{background-position:inherit !important;}
  .card .slide[data-smart-display="mobile-fix"] img{object-position:inherit !important;}
  .card .slide.active[data-smart-display="mobile-fix"]{transform:scale(1.01) !important;transform-origin:50% 50% !important;}
}

/* Mobile: stronger difference so the admin can quickly see that the preset works. */
@media (max-width:480px){
  .card .slide.active[data-smart-display="auto-smart"]{transform:scale(1.18) !important;transform-origin:50% 16% !important;}
  .card .slide[data-smart-display="auto-smart"],
  .card .slide[data-smart-display="auto-smart"] img{background-position:center 16% !important;object-position:center 16% !important;}

  .card .slide.active[data-smart-display="mobile-fix"]{transform:scale(1.20) !important;transform-origin:50% 12% !important;}
  .card .slide[data-smart-display="mobile-fix"],
  .card .slide[data-smart-display="mobile-fix"] img{background-position:center 12% !important;object-position:center 12% !important;}

  .card .slide.active[data-smart-display="top-safe"]{transform:scale(1.18) !important;transform-origin:50% 6% !important;}
  .card .slide[data-smart-display="top-safe"],
  .card .slide[data-smart-display="top-safe"] img{background-position:center 6% !important;object-position:center 6% !important;}

  .card .slide.active[data-smart-display="left-focus"]{transform:scale(1.18) !important;transform-origin:12% 50% !important;}
  .card .slide[data-smart-display="left-focus"],
  .card .slide[data-smart-display="left-focus"] img{background-position:12% center !important;object-position:12% center !important;}

  .card .slide.active[data-smart-display="right-focus"]{transform:scale(1.18) !important;transform-origin:88% 50% !important;}
  .card .slide[data-smart-display="right-focus"],
  .card .slide[data-smart-display="right-focus"] img{background-position:88% center !important;object-position:88% center !important;}
}

/* v1.17.49.9.3 — Hero Cover Focus + Device Fallback Images
   Priority: Smart Display beats legacy image position when selected. */
.card .slide[data-smart-display="hero-cover"],
.card .slide[data-smart-display="center-person"],
.card .slide[data-smart-display="people-right"],
.card .slide[data-smart-display="people-left"],
.card .slide[data-smart-display="face-top"],
.card .slide[data-smart-display="bottom-focus"]{
  background-size:cover !important;
}
.card .slide[data-smart-display="hero-cover"] img,
.card .slide[data-smart-display="center-person"] img,
.card .slide[data-smart-display="people-right"] img,
.card .slide[data-smart-display="people-left"] img,
.card .slide[data-smart-display="face-top"] img,
.card .slide[data-smart-display="bottom-focus"] img{
  object-fit:cover !important;
}
.card .slide[data-smart-display="hero-cover"]{background-position:center center !important;}
.card .slide[data-smart-display="hero-cover"] img{object-position:center center !important;}
.card .slide[data-smart-display="center-person"]{background-position:center center !important;}
.card .slide[data-smart-display="center-person"] img{object-position:center center !important;}
.card .slide[data-smart-display="people-right"]{background-position:82% center !important;}
.card .slide[data-smart-display="people-right"] img{object-position:82% center !important;}
.card .slide[data-smart-display="people-left"]{background-position:18% center !important;}
.card .slide[data-smart-display="people-left"] img{object-position:18% center !important;}
.card .slide[data-smart-display="face-top"]{background-position:center 10% !important;}
.card .slide[data-smart-display="face-top"] img{object-position:center 10% !important;}
.card .slide[data-smart-display="bottom-focus"]{background-position:center 86% !important;}
.card .slide[data-smart-display="bottom-focus"] img{object-position:center 86% !important;}

@media (max-width: 767px){
  .card .slide[data-smart-display="hero-cover"] img{transform:scale(1.04);}
  .card .slide[data-smart-display="center-person"]{background-position:center center !important;}
  .card .slide[data-smart-display="center-person"] img{object-position:center center !important;transform:scale(1.08);}
  .card .slide[data-smart-display="people-right"]{background-position:90% center !important;}
  .card .slide[data-smart-display="people-right"] img{object-position:90% center !important;transform:scale(1.08);}
  .card .slide[data-smart-display="people-left"]{background-position:10% center !important;}
  .card .slide[data-smart-display="people-left"] img{object-position:10% center !important;transform:scale(1.08);}
  .card .slide[data-smart-display="face-top"]{background-position:center 4% !important;}
  .card .slide[data-smart-display="face-top"] img{object-position:center 4% !important;transform:scale(1.08);}
  .card .slide[data-smart-display="bottom-focus"]{background-position:center 92% !important;}
  .card .slide[data-smart-display="bottom-focus"] img{object-position:center 92% !important;transform:scale(1.08);}
}

.card .slide[data-device-images="1"]{
  background-image:var(--etv-desktop-image, inherit) !important;
}
@media (max-width: 767px){
  .card .slide[data-device-images="1"]{
    background-image:var(--etv-mobile-image, var(--etv-desktop-image, inherit)) !important;
  }
}


/* v1.17.49.9.5 — Action Wide Balance + Focus Preset Cleanup
   Wider action preset added. Soft now preserves more action/background, while
   Action Hero stays the closer option for stronger people focus. */
.card .slide[data-smart-display="action-hero-balance"]{
  background-size:cover !important;
  background-position:64% center !important;
}
.card .slide[data-smart-display="action-hero-balance"] img{
  object-fit:cover !important;
  object-position:64% center !important;
}
.card .slide[data-smart-display="action-wide-balance"]{
  background-size:cover !important;
  background-position:58% center !important;
}
.card .slide[data-smart-display="action-wide-balance"] img{
  object-fit:cover !important;
  object-position:58% center !important;
}
.card .slide[data-smart-applied="1"][data-focus-strength="soft"] img{transform:scale(1.01) !important;}
.card .slide[data-smart-applied="1"][data-focus-strength="normal"] img{transform:scale(1.04) !important;}
.card .slide[data-smart-applied="1"][data-focus-strength="close"] img{transform:scale(1.08) !important;}
.card .slide[data-smart-display="hero-cover"][data-focus-strength="soft"] img{transform:scale(1.00) !important;}
.card .slide[data-smart-display="hero-cover"][data-focus-strength="normal"] img{transform:scale(1.03) !important;}
.card .slide[data-smart-display="hero-cover"][data-focus-strength="close"] img{transform:scale(1.07) !important;}
.card .slide[data-smart-display="people-right"][data-focus-strength="soft"]{background-position:74% center !important;}
.card .slide[data-smart-display="people-right"][data-focus-strength="soft"] img{object-position:74% center !important;transform:scale(1.02) !important;}
.card .slide[data-smart-display="people-right"][data-focus-strength="normal"]{background-position:82% center !important;}
.card .slide[data-smart-display="people-right"][data-focus-strength="normal"] img{object-position:82% center !important;transform:scale(1.05) !important;}
.card .slide[data-smart-display="people-right"][data-focus-strength="close"]{background-position:90% center !important;}
.card .slide[data-smart-display="people-right"][data-focus-strength="close"] img{object-position:90% center !important;transform:scale(1.09) !important;}
.card .slide[data-smart-display="people-left"][data-focus-strength="soft"]{background-position:26% center !important;}
.card .slide[data-smart-display="people-left"][data-focus-strength="soft"] img{object-position:26% center !important;transform:scale(1.02) !important;}
.card .slide[data-smart-display="people-left"][data-focus-strength="normal"]{background-position:18% center !important;}
.card .slide[data-smart-display="people-left"][data-focus-strength="normal"] img{object-position:18% center !important;transform:scale(1.05) !important;}
.card .slide[data-smart-display="people-left"][data-focus-strength="close"]{background-position:10% center !important;}
.card .slide[data-smart-display="people-left"][data-focus-strength="close"] img{object-position:10% center !important;transform:scale(1.09) !important;}
.card .slide[data-smart-display="action-wide-balance"][data-focus-strength="soft"]{background-position:52% center !important;}
.card .slide[data-smart-display="action-wide-balance"][data-focus-strength="soft"] img{object-position:52% center !important;transform:scale(0.95) !important;}
.card .slide[data-smart-display="action-wide-balance"][data-focus-strength="normal"]{background-position:58% center !important;}
.card .slide[data-smart-display="action-wide-balance"][data-focus-strength="normal"] img{object-position:58% center !important;transform:scale(1.02) !important;}
.card .slide[data-smart-display="action-wide-balance"][data-focus-strength="close"]{background-position:64% center !important;}
.card .slide[data-smart-display="action-wide-balance"][data-focus-strength="close"] img{object-position:64% center !important;transform:scale(1.05) !important;}
.card .slide[data-smart-display="action-hero-balance"][data-focus-strength="soft"]{background-position:59% center !important;}
.card .slide[data-smart-display="action-hero-balance"][data-focus-strength="soft"] img{object-position:59% center !important;transform:scale(0.97) !important;}
.card .slide[data-smart-display="action-hero-balance"][data-focus-strength="normal"]{background-position:66% center !important;}
.card .slide[data-smart-display="action-hero-balance"][data-focus-strength="normal"] img{object-position:66% center !important;transform:scale(1.04) !important;}
.card .slide[data-smart-display="action-hero-balance"][data-focus-strength="close"]{background-position:74% center !important;}
.card .slide[data-smart-display="action-hero-balance"][data-focus-strength="close"] img{object-position:74% center !important;transform:scale(1.08) !important;}
@media (max-width: 767px){
  .card .slide[data-smart-display="action-wide-balance"]{background-position:58% center !important;}
  .card .slide[data-smart-display="action-wide-balance"] img{object-position:58% center !important;}
  .card .slide[data-smart-display="action-wide-balance"][data-focus-strength="soft"]{background-position:50% center !important;}
  .card .slide[data-smart-display="action-wide-balance"][data-focus-strength="soft"] img{object-position:50% center !important;transform:scale(0.94) !important;}
  .card .slide[data-smart-display="action-wide-balance"][data-focus-strength="normal"]{background-position:56% center !important;}
  .card .slide[data-smart-display="action-wide-balance"][data-focus-strength="normal"] img{object-position:56% center !important;transform:scale(1.02) !important;}
  .card .slide[data-smart-display="action-wide-balance"][data-focus-strength="close"]{background-position:60% center !important;}
  .card .slide[data-smart-display="action-wide-balance"][data-focus-strength="close"] img{object-position:60% center !important;transform:scale(1.05) !important;}
  .card .slide[data-smart-display="action-hero-balance"]{background-position:64% center !important;}
  .card .slide[data-smart-display="action-hero-balance"] img{object-position:64% center !important;}
  .card .slide[data-smart-display="action-hero-balance"][data-focus-strength="soft"]{background-position:58% center !important;}
  .card .slide[data-smart-display="action-hero-balance"][data-focus-strength="soft"] img{object-position:58% center !important;transform:scale(0.96) !important;}
  .card .slide[data-smart-display="action-hero-balance"][data-focus-strength="normal"]{background-position:65% center !important;}
  .card .slide[data-smart-display="action-hero-balance"][data-focus-strength="normal"] img{object-position:65% center !important;transform:scale(1.04) !important;}
  .card .slide[data-smart-display="action-hero-balance"][data-focus-strength="close"]{background-position:72% center !important;}
  .card .slide[data-smart-display="action-hero-balance"][data-focus-strength="close"] img{object-position:72% center !important;transform:scale(1.08) !important;}
  .card .slide[data-smart-display="people-right"][data-focus-strength="soft"]{background-position:74% center !important;}
  .card .slide[data-smart-display="people-right"][data-focus-strength="soft"] img{object-position:74% center !important;transform:scale(1.02) !important;}
  .card .slide[data-smart-display="people-right"][data-focus-strength="normal"]{background-position:82% center !important;}
  .card .slide[data-smart-display="people-right"][data-focus-strength="normal"] img{object-position:82% center !important;transform:scale(1.05) !important;}
  .card .slide[data-smart-display="people-right"][data-focus-strength="close"]{background-position:90% center !important;}
  .card .slide[data-smart-display="people-right"][data-focus-strength="close"] img{object-position:90% center !important;transform:scale(1.09) !important;}
}


/* v1.17.49.9.6 — Left+Center / Right+Center Focus Presets
   These are balanced focus windows, not hard one-side crops.
   They keep the middle plus one side visible for wide action posters. */
.card .slide[data-smart-display="right-center"],
.card .slide[data-smart-display="left-center"]{
  background-size:cover !important;
}
.card .slide[data-smart-display="right-center"] img,
.card .slide[data-smart-display="left-center"] img{
  object-fit:cover !important;
}
.card .slide[data-smart-display="right-center"]{background-position:64% center !important;}
.card .slide[data-smart-display="right-center"] img{object-position:64% center !important;transform:scale(1.02) !important;}
.card .slide[data-smart-display="left-center"]{background-position:36% center !important;}
.card .slide[data-smart-display="left-center"] img{object-position:36% center !important;transform:scale(1.02) !important;}

.card .slide[data-smart-display="right-center"][data-focus-strength="soft"]{background-position:58% center !important;}
.card .slide[data-smart-display="right-center"][data-focus-strength="soft"] img{object-position:58% center !important;transform:scale(0.96) !important;}
.card .slide[data-smart-display="right-center"][data-focus-strength="normal"]{background-position:66% center !important;}
.card .slide[data-smart-display="right-center"][data-focus-strength="normal"] img{object-position:66% center !important;transform:scale(1.02) !important;}
.card .slide[data-smart-display="right-center"][data-focus-strength="close"]{background-position:72% center !important;}
.card .slide[data-smart-display="right-center"][data-focus-strength="close"] img{object-position:72% center !important;transform:scale(1.05) !important;}

.card .slide[data-smart-display="left-center"][data-focus-strength="soft"]{background-position:42% center !important;}
.card .slide[data-smart-display="left-center"][data-focus-strength="soft"] img{object-position:42% center !important;transform:scale(0.96) !important;}
.card .slide[data-smart-display="left-center"][data-focus-strength="normal"]{background-position:34% center !important;}
.card .slide[data-smart-display="left-center"][data-focus-strength="normal"] img{object-position:34% center !important;transform:scale(1.02) !important;}
.card .slide[data-smart-display="left-center"][data-focus-strength="close"]{background-position:28% center !important;}
.card .slide[data-smart-display="left-center"][data-focus-strength="close"] img{object-position:28% center !important;transform:scale(1.05) !important;}

@media (max-width: 767px){
  .card .slide[data-smart-display="right-center"][data-focus-strength="soft"]{background-position:56% center !important;}
  .card .slide[data-smart-display="right-center"][data-focus-strength="soft"] img{object-position:56% center !important;transform:scale(0.95) !important;}
  .card .slide[data-smart-display="right-center"][data-focus-strength="normal"]{background-position:64% center !important;}
  .card .slide[data-smart-display="right-center"][data-focus-strength="normal"] img{object-position:64% center !important;transform:scale(1.02) !important;}
  .card .slide[data-smart-display="right-center"][data-focus-strength="close"]{background-position:70% center !important;}
  .card .slide[data-smart-display="right-center"][data-focus-strength="close"] img{object-position:70% center !important;transform:scale(1.05) !important;}

  .card .slide[data-smart-display="left-center"][data-focus-strength="soft"]{background-position:44% center !important;}
  .card .slide[data-smart-display="left-center"][data-focus-strength="soft"] img{object-position:44% center !important;transform:scale(0.95) !important;}
  .card .slide[data-smart-display="left-center"][data-focus-strength="normal"]{background-position:36% center !important;}
  .card .slide[data-smart-display="left-center"][data-focus-strength="normal"] img{object-position:36% center !important;transform:scale(1.02) !important;}
  .card .slide[data-smart-display="left-center"][data-focus-strength="close"]{background-position:30% center !important;}
  .card .slide[data-smart-display="left-center"][data-focus-strength="close"] img{object-position:30% center !important;transform:scale(1.05) !important;}
}


/* v1.17.49.9.7 — Wider View / Zoom-Out Range
   UI cleanup: Soft is now Wider, Normal is Default.
   Wider reduces zoom slightly to show more of the same image. */

/* v1.17.51.16-mobile-lightweight-production
 * Production mobile paint/compositor safety. Scope is mobile <=640px and
 * .extratv-page only. Desktop and global page/body styling are untouched.
 */
@media (max-width: 640px) {
  .extratv-page .card,
  .extratv-page .card.show,
  .extratv-page .card:hover,
  .extratv-page .card.touch-active {
    opacity: 1 !important;
    transform: translateY(0) scale(1) !important;
    transition: none !important;
    transition-delay: 0s !important;
    animation: none !important;
    filter: none !important;
    box-shadow:
      0 18px 42px rgba(0,0,0,.38),
      0 0 0 1px color-mix(in srgb, var(--theme1, #fff) 14%, transparent) !important;
    will-change: auto !important;
  }

  .extratv-page .card[data-key="vip-plus"],
  .extratv-page .card[data-key="vip-plus"].show,
  .extratv-page .card[data-key="vip-plus"]:hover,
  .extratv-page .card[data-key="vip-plus"].touch-active {
    transform: scale(1.04) !important;
  }

  .extratv-page .card::before,
  .extratv-page .card::after {
    filter: none !important;
    animation: none !important;
    transition: none !important;
    transition-delay: 0s !important;
    will-change: auto !important;
  }

  .extratv-page .card::before {
    opacity: .28 !important;
  }

  .extratv-page .card[data-key="basic"],
  .extratv-page .card[data-key="lite"] {
    filter: none !important;
  }

  .extratv-page .group-box,
  .extratv-page .play-hint,
  .extratv-page .badge-mini,
  .extratv-page .backup-pill,
  .extratv-page .plan,
  .extratv-page .device {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }

  .extratv-page .play-hint::before,
  .extratv-page .play-hint.show-once,
  .extratv-page .play-hint.show-once::before,
  .extratv-page .plan.active,
  .extratv-page .link.primary,
  .extratv-page .link.primary::after,
  .extratv-page .card[data-key="premium-vip"] .link.primary,
  .extratv-page .card[data-key="vip-plus"] .link.primary {
    animation: none !important;
  }

  .extratv-page .plan.active {
    box-shadow: 0 0 16px rgba(255,180,70,.32) !important;
  }

  .extratv-page .link.primary,
  .extratv-page .sheet-accept {
    box-shadow: 0 12px 24px rgba(0,0,0,.18) !important;
  }
}

/* v1.17.51.16-mobile-lightweight-production
 * Keep the external logo/frame system visible on mobile, but remove expensive
 * paint/compositor effects from the layers that sit outside .card.
 */
@media (max-width: 640px) {
  .extratv-page .premium-vip-shell,
  .extratv-page .premium-vip-shell:hover,
  .extratv-page .premium-vip-shell:active,
  .extratv-page .premium-vip-shell:focus,
  .extratv-page .premium-vip-shell:focus-within,
  .extratv-page .premium-vip-shell.pv-touch {
    transform: none !important;
    filter: none !important;
    box-shadow: none !important;
    animation: none !important;
    transition: none !important;
    will-change: auto !important;
  }

  .extratv-page .premium-vip-top-tab,
  .extratv-page .premium-vip-frame-overlay,
  .extratv-page .extratv-floating-badge,
  .extratv-page .etv-card-logo {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
    filter: none !important;
    animation: none !important;
    transition: none !important;
    will-change: auto !important;
  }

  .extratv-page .premium-vip-frame-overlay {
    box-shadow:
      0 0 0 1px rgba(255,168,58,.10),
      0 0 10px var(--pv-frame-glow-soft),
      inset 0 0 8px rgba(255,158,44,.04) !important;
  }

  .extratv-page .premium-vip-top-tab {
    box-shadow:
      0 0 0 1px rgba(0,0,0,.40),
      0 0 8px var(--pv-tab-glow),
      inset 0 1px 0 rgba(255,255,255,.05) !important;
  }

  .extratv-page .extratv-floating-badge {
    box-shadow: 0 8px 18px rgba(0,0,0,.22) !important;
  }

  .extratv-page .etv-card-logo {
    box-shadow: none !important;
  }

  .extratv-page .premium-vip-frame-overlay,
  .extratv-page .premium-vip-shell:hover .premium-vip-frame-overlay,
  .extratv-page .premium-vip-shell:active .premium-vip-frame-overlay,
  .extratv-page .premium-vip-shell:focus .premium-vip-frame-overlay,
  .extratv-page .premium-vip-shell:focus-within .premium-vip-frame-overlay,
  .extratv-page .premium-vip-shell.pv-touch .premium-vip-frame-overlay {
    transform: none !important;
  }

  .extratv-page .premium-vip-top-tab,
  .extratv-page .premium-vip-shell:hover .premium-vip-top-tab,
  .extratv-page .premium-vip-shell:active .premium-vip-top-tab,
  .extratv-page .premium-vip-shell:focus .premium-vip-top-tab,
  .extratv-page .premium-vip-shell:focus-within .premium-vip-top-tab,
  .extratv-page .premium-vip-shell.pv-touch .premium-vip-top-tab {
    transform: translateX(-50%) !important;
  }

  .extratv-page .extratv-floating-badge,
  .extratv-page .etv-card-wrap.has-floating-badge:has(.card:hover) > .extratv-floating-badge,
  .extratv-page .etv-card-wrap.has-floating-badge:has(.card.touch-active) > .extratv-floating-badge,
  .extratv-page .etv-card-wrap.pv-hide-legacy-logo:has(.premium-vip-shell:hover) > .extratv-floating-badge,
  .extratv-page .etv-card-wrap.pv-hide-legacy-logo:has(.premium-vip-shell:active) > .extratv-floating-badge,
  .extratv-page .etv-card-wrap.pv-hide-legacy-logo:has(.premium-vip-shell:focus-within) > .extratv-floating-badge {
    transform: translateX(-50%) !important;
    animation: none !important;
  }

  .extratv-page .premium-vip-top-tab::before,
  .extratv-page .premium-vip-top-tab::after,
  .extratv-page .extratv-floating-badge::before,
  .extratv-page .extratv-floating-badge::after {
    filter: none !important;
    box-shadow: none !important;
    animation: none !important;
    transition: none !important;
    will-change: auto !important;
  }

  .extratv-page .premium-vip-top-tab img,
  .extratv-page .extratv-floating-badge img,
  .extratv-page .etv-card-logo img {
    -webkit-filter: none !important;
    filter: none !important;
    box-shadow: none !important;
    animation: none !important;
    transition: none !important;
    will-change: auto !important;
  }
}


/* ExtraTV 1.17.51.16-base-mobile-spacing-balance
   Mobile-only spacing balance from inside the cards plugin.
   Goal: raise the cards area slightly without sliding it under the banner,
   and keep a small safe gap after the last card before the package features. */
@media screen and (max-width:767px),screen and (hover:none) and (pointer:coarse){
  html body .extratv-page.etv-mobile-boundary-lock{padding-top:var(--etv-mobile-boundary-top,56px)!important;padding-bottom:16px!important;margin-top:0!important;margin-bottom:0!important;overflow:visible!important;}
  html body .extratv-page.etv-mobile-boundary-lock>.hero-title,
  html body .extratv-page.etv-mobile-boundary-lock>.hero-sub{height:0!important;min-height:0!important;margin:0!important;padding:0!important;overflow:hidden!important;}
  html body .extratv-page.etv-mobile-boundary-lock>.cards:first-of-type{padding-top:var(--etv-bg-top,70px)!important;}
  html body .extratv-page.etv-mobile-boundary-lock>.cards:last-of-type{padding-bottom:18px!important;margin-bottom:0!important;}
  html body .extratv-page.etv-mobile-boundary-lock>.cards:last-of-type>.etv-card-wrap:last-child{padding-bottom:0!important;margin-bottom:12px!important;}
}
@media screen and (min-width:768px){
  html body .extratv-page.etv-mobile-boundary-lock{padding-top:0!important;padding-bottom:20px!important;}
}

/* ═══════════════════════════════════════════════════════════════════════════
 * v1.17.51.17 — DESKTOP LIGHTWEIGHT (glow/shadow blur trim only)
 * Scope: real desktop with a mouse only — @media (hover: hover) and
 * (pointer: fine). Touch phones/tablets (hover:none / coarse pointer) NEVER
 * match this block, so mobile paint is provably untouched.
 *
 * What it does: gently tightens the LARGEST decorative glow/shadow blur radii
 * on the card hover, the 12-month selected state, and the premium-vip reveal
 * glow. Large blur radii are the single most expensive part of these paints to
 * rasterize, so a modest ~12-15% radius trim cuts real desktop paint cost while
 * the glow stays clearly present — the premium look is preserved.
 *
 * What it does NOT touch: no transform (the synchronized card→logo→badge hover
 * lift is left exactly as-is to avoid any per-tier desync), no colours, no
 * layout, no spacing, no animation, no media/slide/img/video. Additive override
 * only — removing this block restores byte-identical prior desktop glow. */
@media (hover: hover) and (pointer: fine) {
  /* Card hover glow — tighter radii, slightly lighter drop shadow. */
  .extratv-page .card:hover {
    box-shadow:
      0 28px 64px rgba(0,0,0,.58),
      0 0 0 1px color-mix(in srgb, var(--theme1, #fff) 20%, rgba(255,255,255,.04)),
      0 0 38px var(--glowA),
      0 0 78px var(--glowB);
  }

  /* 12-month selected glow — tighter outer radii. */
  .extratv-page .card.plan12-selected {
    box-shadow:
      0 34px 76px rgba(0,0,0,.62),
      0 0 0 1px color-mix(in srgb, var(--theme1, #fff) 24%, rgba(255,255,255,.05)),
      0 0 50px var(--glowA),
      0 0 96px var(--glowB),
      0 0 128px var(--glowC);
  }

  /* Premium VIP revealed glow — tighter outer radii. */
  .extratv-page .card[data-key="premium-vip"].show {
    box-shadow:
      0 36px 80px rgba(0,0,0,.62),
      0 0 0 1px rgba(184,134,47,.34),
      0 0 56px rgba(201,150,46,.26),
      0 0 104px rgba(159,107,22,.16);
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * Phase 4A-1 — MOBILE SAFE LITE REPAINT OPTIMIZATION (v1.17.51.19)
 * Scope: <=640px under .extratv-page only. Desktop is never matched.
 *
 * The prior mobile pass stripped the external card layers flat (filter:none on
 * the ambient halo, no card glow ring, no badge glow) to kill the fast-scroll
 * white flash. The flash, however, came from LIVE backdrop-filter (re-blurred
 * every scroll frame as it samples the moving backdrop) and from animated /
 * looping layers — NOT from static shadows. So this pass restores a GENTLE
 * premium glow using only STATIC, non-animated shadow/blur values, which the
 * compositor rasterizes once and caches into the card's own layer (composited,
 * not recomputed, during scroll). Everything that actually caused the flash
 * stays OFF: backdrop-filter:none, animation:none, transition:none,
 * transform re-enable: none, will-change: auto — all left exactly as the prior
 * pass set them. This is "reduce, don't remove": lighter than desktop, premium
 * on mobile, safe on scroll.
 *
 * Touches only the allowed external layers (.card, .card::before, frame overlay,
 * top tab, floating badge). No media/slide/img/video/poster/preview. No spacing.
 * No background. No logo-img halo (a container box-shadow would read as a black
 * box behind the transparent PNG — the proper shape halo lives on the <img>,
 * which is intentionally left untouched). Appended last, so it overrides the
 * prior flat values by source order; removing this block restores them. */
@media (max-width: 640px) {
  /* Card — keep the light drop shadow, add back a soft ambient glow ring. */
  .extratv-page .card,
  .extratv-page .card.show,
  .extratv-page .card:hover,
  .extratv-page .card.touch-active {
    box-shadow:
      0 16px 38px rgba(0,0,0,.36),
      0 0 0 1px color-mix(in srgb, var(--theme1, #fff) 14%, transparent),
      0 0 24px var(--glowA, rgba(255,255,255,.06)) !important;
  }

  /* Card ambient halo (::before) — gentle static blur instead of fully off.
   * Small radius = cheap one-time raster; no animation, no backdrop-filter. */
  .extratv-page .card::before {
    filter: blur(8px) saturate(1.08) !important;
    opacity: .34 !important;
  }

  /* Premium VIP frame — slightly richer but still soft frame glow. */
  .extratv-page .premium-vip-frame-overlay {
    box-shadow:
      0 0 0 1px rgba(255,168,58,.12),
      0 0 15px var(--pv-frame-glow-soft, rgba(255,158,44,.18)),
      inset 0 0 10px rgba(255,158,44,.05) !important;
  }

  /* Premium VIP top tab — gentle tab halo. */
  .extratv-page .premium-vip-top-tab {
    box-shadow:
      0 0 0 1px rgba(0,0,0,.40),
      0 0 12px var(--pv-tab-glow, rgba(255,158,44,.22)),
      inset 0 1px 0 rgba(255,255,255,.06) !important;
  }

  /* Floating badge — keep its light drop shadow, add a soft per-tier glow. */
  .extratv-page .extratv-floating-badge {
    box-shadow:
      0 8px 18px rgba(0,0,0,.22),
      0 0 16px var(--etv-theme-glow, rgba(255,255,255,.10)) !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * v1.17.51.20 — MOBILE CARD GAP / CARD STACK SURFACE FLASH FIX
 * Root cause (confirmed from the diagnostic video + code): .extratv-page and
 * .cards carry NO background, so the vertical gaps between cards (gap ~40px) and
 * the top padding region are transparent and expose the white Elementor/page
 * parent surface. During fast mobile scroll the composited card layers repaint a
 * beat late, so the white parent flashes through the gaps — worst above the
 * first card, where the exposed top space is largest.
 *
 * Fix: the plugin OWNS its own backdrop. Paint the cards-plugin wrapper
 * (.extratv-page — the element rendered with data-etv-mobile-boundary=
 * "cards-plugin-only") with the plugin's EXISTING design base token --bg
 * (#0b0f18). A lagging card now reveals the dark design surface instead of
 * white, and the gaps are dark in normal use too. This is:
 *   - NOT the media letterbox colour #050914 (that lives in the slide subtree),
 *   - NOT a global guard on html / body / Elementor / site-main / entry-content,
 *   - NOT a mask over content — it sits BEHIND the fully-opaque cards.
 * Scoped to mobile so desktop is untouched. No spacing change, no media touched,
 * no masking. Removing this block restores the prior transparent wrapper. */
@media (max-width: 640px) {
  .extratv-page {
    background-color: var(--bg, #0b0f18);
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * v1.17.51.21 — MOBILE UPWARD-SCROLL PAINT FIX (A/B result: Test C)
 *
 *  Test A (containment / paint-skip) — NOT the cause. Audit found no
 *    content-visibility:auto and no contain: rule anywhere in the stack; .card
 *    is already forced content-visibility:visible. The prescribed Test A
 *    override would be a no-op, so it was deliberately NOT added.
 *
 *  Test C (card-stack surface) — the cause and the fix. After v1.17.51.20 a
 *    stable dark surface existed only at the outermost .extratv-page. The
 *    intermediate stack levels were still see-through: .etv-card-wrap is
 *    explicitly background:transparent and .cards has no background. During a
 *    fast UPWARD fling the compositor re-rasterises the stack a beat late, and
 *    with only one far-back surface the transparent gaps/wraps briefly expose
 *    white — worse with larger spacing (more transparent area) and worse upward
 *    (the browser pre-paints the scroll direction, so up-scroll lags most).
 *
 * Fix: give EVERY level of the card stack its own opaque dark surface using the
 * plugin's existing --bg token (#0b0f18) — defence in depth. Whichever layer
 * lags during the fling, the surface immediately behind it is already dark, so
 * no white can show through. Visually identical to today (the gaps already read
 * #0b0f18 via the v1.17.51.20 .extratv-page surface); this simply moves an
 * opaque copy of that surface onto the closer stack levels so the fling can't
 * out-run it. Plugin-scoped (.extratv-page subtree only), mobile-only, CSS-only.
 * NOT the media letterbox #050914, NOT a global html/body/Elementor surface,
 * NOT a mask (sits behind the opaque cards), no scroll JS, no spacing change. */
@media (max-width: 640px) {
  .extratv-page .cards {
    background-color: var(--bg, #0b0f18);
  }
  .extratv-page .etv-card-wrap,
  .extratv-page .extratv-card-wrap {
    background-color: var(--bg, #0b0f18);
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * v1.17.51.22 — MOBILE ROOT / PAGE SURFACE (Phase 2)
 *
 * Context: v1.17.51.20 + .21 painted every level of the plugin's OWN stack
 * (.extratv-page, .cards, .etv-card-wrap) dark, yet the white fast-upward-fling
 * flash persisted. Logically, a dark container cannot emit white — so the white
 * is coming from a surface ABOVE the card stack: the root scroller / page /
 * theme wrappers, whose default canvas is white and which "checkerboard" during
 * a fast mobile fling (the browser pre-paints the scroll direction, so upward
 * lags most). Test B (transform / layer-promotion de-promotion) was inspected
 * and is NOT the cause for the same reason: every plugin layer is already
 * opaque dark, so a lagging card layer reveals dark, never white.
 *
 * Fix: darken the page scroller surface behind the card stack, scoped to
 * ExtraTV Cards pages only via the `extratv-cards-page` body class (added by a
 * body_class filter in extratv-cards.php, gated by the shared cards-page
 * detection). Mobile only. Uses the plugin's own --bg token (#0b0f18), NOT the
 * media letterbox #050914. This is NOT a site-wide background: it applies only
 * when <body> carries `extratv-cards-page`. No spacing change, no media touched,
 * no scroll JS. Removing the body class (or this block) fully reverts it. */
@media (max-width: 640px) {
  body.extratv-cards-page,
  body.extratv-cards-page #page,
  body.extratv-cards-page .site,
  body.extratv-cards-page .site-main,
  body.extratv-cards-page .page-content,
  body.extratv-cards-page .entry-content {
    background-color: var(--bg, #0b0f18);
  }
}

/* ─────────────────────────────────────────
   v1.17.53.3 — Top tag / micro badge: single-line guarantee
   ─────────────────────────────────────────
   The two top card tags must always render on ONE line for any Arabic or
   English text (current or future/dynamic), on mobile and desktop:
     • .badge-mini  — top marketing tag (e.g. الأكثر مبيعاً / الأكثر طلباً / عرض خاص)
     • .device      — top device tag, icon + .device-text (e.g. جهاز واحد / جهازين / استخدام مزدوج)
   Earlier rules cap .badge-mini width (max-width 150–172px) without nowrap, so
   longer tags wrapped onto two lines. This scoped override stops the wrap and
   lets each pill size to its content; the .device icon and text stay on the
   same horizontal row.

   Targets the real tag component selectors (not hardcoded words) and is scoped
   to .extratv-page .card only — NO global / body / html / Elementor-wrapper CSS.
   Does not touch price, buttons, currency selector, logo tab, frame/glow, media,
   the backup micro pill, or the badge position. */
.extratv-page .card .badge-mini {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  white-space: nowrap;
  max-width: none;
  width: max-content;
}
.extratv-page .card .badge-mini > * {
  flex-shrink: 0;
}
.extratv-page .card .device {
  flex-wrap: nowrap;
  white-space: nowrap;
}
.extratv-page .card .device > * {
  flex-shrink: 0;
}
.extratv-page .card .device .device-text {
  white-space: nowrap;
}

/* ─────────────────────────────────────────
   v1.17.54.2 — Smart Image Studio frontend correctness: "Full Image" (full-view)
   ─────────────────────────────────────────
   "Full Image" must show the WHOLE image (object-fit:contain), but the generic
   smart-applied rules above were overriding it because they are more specific:
     .card .slide[data-smart-display][data-smart-applied="1"] img{object-fit:cover}   (0,4,1)
     .card .slide[data-smart-applied="1"][data-focus-strength="x"] img{transform:scale}(0,4,1)
   vs full-view's .card .slide[data-smart-display="full-view"] img{...contain}        (0,3,1)
   The rules below add [data-smart-applied="1"] to match that 0,4,1 specificity and,
   being later in the file, win deterministically. This is image-rendering ONLY and
   is scoped strictly to data-smart-display="full-view" — it does not change layout,
   spacing, buttons, the logo/frame, currency, WhatsApp, Play Button, More Details,
   or any other mode/behavior. */
.card .slide[data-smart-display="full-view"][data-smart-applied="1"]{background-size:contain !important;background-position:center center !important;background-color:#000 !important;}
.card .slide[data-smart-display="full-view"][data-smart-applied="1"] img{object-fit:contain !important;object-position:center center !important;transform:none !important;}

/* ─────────────────────────────────────────
   v1.17.54.4 — Smart Image Studio: "Desktop Sales Hero" (sales-hero)
   ─────────────────────────────────────────
   A NEW, opt-in focus value (no existing card uses it, so old cards are
   unaffected). It gives the wide Desktop card a stronger, more premium hero
   crop: bigger subject (more zoom than Hero Cover), slight right/up bias to keep
   the subject off the left-side buttons and protect the head, full cover (no
   gaps). Mobile uses a head-safe, lower-zoom variant.

   Selectors include [data-focus-strength] + [data-smart-applied="1"] to reach
   (0,5,1)/(0,4,1) specificity and, being later in the file, win over the generic
   .card .slide[data-smart-applied="1"][data-focus-strength] img scale rules.
   Image-rendering ONLY; scoped strictly to data-smart-display="sales-hero";
   no layout, spacing, button, currency, or logic change. */
.card .slide[data-smart-display="sales-hero"][data-smart-applied="1"]{background-size:cover !important;background-position:52% 42% !important;}
.card .slide[data-smart-display="sales-hero"][data-smart-applied="1"] img{object-fit:cover !important;object-position:52% 42% !important;}
.card .slide[data-smart-display="sales-hero"][data-focus-strength="soft"][data-smart-applied="1"] img{object-position:52% 44% !important;transform:scale(1.06) !important;}
.card .slide[data-smart-display="sales-hero"][data-focus-strength="normal"][data-smart-applied="1"] img{object-position:52% 42% !important;transform:scale(1.12) !important;}
.card .slide[data-smart-display="sales-hero"][data-focus-strength="close"][data-smart-applied="1"] img{object-position:54% 40% !important;transform:scale(1.18) !important;}
@media (max-width:480px){
  .card .slide[data-smart-display="sales-hero"][data-focus-strength="soft"][data-smart-applied="1"] img{object-position:center 16% !important;transform:scale(1.05) !important;}
  .card .slide[data-smart-display="sales-hero"][data-focus-strength="normal"][data-smart-applied="1"] img{object-position:center 14% !important;transform:scale(1.08) !important;}
  .card .slide[data-smart-display="sales-hero"][data-focus-strength="close"][data-smart-applied="1"] img{object-position:center 12% !important;transform:scale(1.12) !important;}
}

/* ─────────────────────────────────────────
   v1.17.54.5 — Smart Image Studio: Desktop Portrait Hero / Poster Fill /
   Smart Background Fill (opt-in composite for portrait images on wide Desktop)
   ─────────────────────────────────────────
   Modeled on the proven safe-fit-fill technique. NEW opt-in values only
   (poster-fill / poster-right / poster-left / poster-top / poster-dark); no
   existing card uses them, so old cards are unaffected. Desktop = a blurred,
   darkened, enlarged background-fill layer (::before, from --etv-poster-image set
   by cards.js) that removes empty gaps, plus the SAME image as a sharp, contained
   foreground (no stretch, no distortion). Mobile = the portrait stays natural
   (the fill layer is hidden and the image uses a head-safe cover). Image-rendering
   ONLY; scoped strictly to data-smart-display="poster-*"; no layout/button/
   currency/logic change. Lightweight: one CSS var + a pseudo-element, no JS
   analysis, no extra network request. */
.card .slide[data-smart-display="poster-fill"],
.card .slide[data-smart-display="poster-right"],
.card .slide[data-smart-display="poster-left"],
.card .slide[data-smart-display="poster-top"],
.card .slide[data-smart-display="poster-dark"]{
  background-image:none !important;
  background-color:#050914 !important;
  overflow:hidden;
}
.card .slide[data-smart-display="poster-fill"]::before,
.card .slide[data-smart-display="poster-right"]::before,
.card .slide[data-smart-display="poster-left"]::before,
.card .slide[data-smart-display="poster-top"]::before,
.card .slide[data-smart-display="poster-dark"]::before{
  content:"";
  position:absolute;
  inset:-30px;
  z-index:0;
  pointer-events:none;
  background-image:var(--etv-poster-image);
  background-size:cover;
  background-position:center center;
  background-repeat:no-repeat;
  filter:blur(22px) brightness(.55) saturate(1.08);
  transform:scale(1.14);
  opacity:.96;
}
.card .slide[data-smart-display="poster-dark"]::before{
  filter:blur(24px) brightness(.4) saturate(1.05);
}
.card .slide[data-smart-display="poster-fill"][data-smart-applied="1"] img,
.card .slide[data-smart-display="poster-right"][data-smart-applied="1"] img,
.card .slide[data-smart-display="poster-left"][data-smart-applied="1"] img,
.card .slide[data-smart-display="poster-top"][data-smart-applied="1"] img,
.card .slide[data-smart-display="poster-dark"][data-smart-applied="1"] img{
  position:relative !important;
  z-index:1 !important;
  object-fit:contain !important;
  object-position:center center !important;
  transform:none !important;
  background:transparent !important;
  background-color:transparent !important;
  filter:drop-shadow(0 16px 30px rgba(0,0,0,.40));
}
.card .slide[data-smart-display="poster-right"][data-smart-applied="1"] img{object-position:right center !important;}
.card .slide[data-smart-display="poster-left"][data-smart-applied="1"] img{object-position:left center !important;}
.card .slide[data-smart-display="poster-top"][data-smart-applied="1"] img{object-position:center top !important;}
.card .slide.active[data-smart-display="poster-fill"],
.card .slide.active[data-smart-display="poster-right"],
.card .slide.active[data-smart-display="poster-left"],
.card .slide.active[data-smart-display="poster-top"],
.card .slide.active[data-smart-display="poster-dark"]{
  transform:scale(1) !important;
  transform-origin:50% 50% !important;
}
.card .slide[data-smart-display="poster-fill"][data-image-theme-override="1"]::after,
.card .slide[data-smart-display="poster-right"][data-image-theme-override="1"]::after,
.card .slide[data-smart-display="poster-left"][data-image-theme-override="1"]::after,
.card .slide[data-smart-display="poster-top"][data-image-theme-override="1"]::after,
.card .slide[data-smart-display="poster-dark"][data-image-theme-override="1"]::after{z-index:2;}
@media (max-width:767px){
  .card .slide[data-smart-display="poster-fill"]::before,
  .card .slide[data-smart-display="poster-right"]::before,
  .card .slide[data-smart-display="poster-left"]::before,
  .card .slide[data-smart-display="poster-top"]::before,
  .card .slide[data-smart-display="poster-dark"]::before{display:none !important;}
  .card .slide[data-smart-display="poster-fill"][data-smart-applied="1"] img,
  .card .slide[data-smart-display="poster-right"][data-smart-applied="1"] img,
  .card .slide[data-smart-display="poster-left"][data-smart-applied="1"] img,
  .card .slide[data-smart-display="poster-top"][data-smart-applied="1"] img,
  .card .slide[data-smart-display="poster-dark"][data-smart-applied="1"] img{
    position:absolute !important;
    inset:0 !important;
    object-fit:cover !important;
    object-position:center 12% !important;
    transform:none !important;
    filter:none !important;
  }
}


/* ─────────────────────────────────────────
   v1.17.55.16 — Phase 2: smart Desktop left-stack + price hierarchy
   ─────────────────────────────────────────
   Purpose: use the available lower desktop space instead of compressing the
   badge/offer/price at the top. Scoped only to the real frontend card body;
   no Details panel, Mobile, Currency logic, WooCommerce, checkout, media, or
   action-visibility logic is touched.
*/
@media (min-width: 1024px) {
  .extratv-page .card[data-key] > .main {
    justify-content: flex-start;
    padding-top: clamp(56px, 5.6vw, 72px);
    padding-bottom: 20px;
  }

  .extratv-page .card[data-key] > .main > .center {
    height: 100%;
    min-height: 0;
    display: grid;
    grid-template-rows:
      minmax(132px, auto)  /* Backup/Offer pill + smart price */
      minmax(50px, auto)   /* 12 / 6 */
      minmax(56px, auto)   /* Subscribe */
      minmax(48px, auto)   /* Try Now reserved */
      minmax(46px, auto);  /* Lower actions reserved */
    row-gap: 10px;
    align-content: start;
    align-items: stretch;
    width: 100%;
    text-align: start;
  }

  .extratv-page .card[data-key] > .main > .center > .price-wrap {
    grid-row: 1;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    gap: 12px;
    min-height: 132px;
    margin: 0;
    max-width: 100%;
    direction: ltr; /* flex-start must mean the visual LEFT edge in RTL pages */
    overflow: visible;
  }

  .extratv-page .card[data-key] > .main > .center > .price-wrap > .backup-pill {
    order: 1;
    align-self: flex-start;
    width: max-content;
    max-width: min(100%, 260px);
    margin: 0;
    direction: rtl;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .extratv-page .card[data-key] > .main > .center > .price-wrap > .price {
    order: 2;
    display: inline-flex;
    align-items: baseline;
    justify-content: flex-start;
    gap: .16em;
    max-width: 100%;
    min-width: 0;
    margin: 0;
    padding: 0;
    white-space: nowrap;
    overflow: visible;
    direction: ltr;
    unicode-bidi: isolate;
    font-size: clamp(46px, 4.7vw, 64px);
    line-height: .9;
    letter-spacing: .01em;
  }

  .extratv-page .card[data-key] .price .etv-price-number {
    font-size: 1em;
    font-weight: 950;
    line-height: .9;
  }

  .extratv-page .card[data-key] .price .etv-price-currency {
    font-size: .66em;
    font-weight: 850;
    line-height: 1;
    letter-spacing: .045em;
    opacity: .92;
    transform: translateY(-.04em);
  }


  /* v1.17.55.17 — Phase 2.1: never let the currency suffix collapse.
     The price line is measured/shrunk as one unit; the number and currency
     code are non-shrinking glyph groups so values like 338 SAR / 450 SAR
     cannot lose the SAR label. */
  .extratv-page .card[data-key] > .main > .center > .price-wrap > .price.etvcs-cv,
  .extratv-page .card[data-key] > .main > .center > .price-wrap > .price {
    width: max-content;
    max-width: none;
    min-width: 0;
    flex-wrap: nowrap;
  }

  .extratv-page .card[data-key] .price .etv-price-number,
  .extratv-page .card[data-key] .price .etv-price-currency {
    display: inline-block;
    flex: 0 0 auto;
    min-width: max-content;
    max-width: none;
    overflow: visible;
    white-space: nowrap;
  }

  .extratv-page .card[data-key] > .main > .center > .grid {
    grid-row: 2;
    margin: 0;
    align-self: stretch;
  }
  .extratv-page .card[data-key] > .main > .center > .link.primary {
    grid-row: 3;
    margin-top: 0;
    align-self: stretch;
  }
  .extratv-page .card[data-key] > .main > .center > .link.secondary {
    grid-row: 4;
    margin-top: 0;
    align-self: stretch;
  }
  .extratv-page .card[data-key] > .main > .center > .actions {
    grid-row: 5;
    margin-top: 0;
    align-self: stretch;
  }
}

@media (min-width: 1024px) and (max-width: 1199px) {
  .extratv-page .card[data-key] > .main {
    padding-top: clamp(50px, 5.2vw, 62px);
    padding-bottom: 18px;
  }
  .extratv-page .card[data-key] > .main > .center {
    grid-template-rows:
      minmax(116px, auto)
      minmax(46px, auto)
      minmax(52px, auto)
      minmax(46px, auto)
      minmax(44px, auto);
    row-gap: 8px;
  }
  .extratv-page .card[data-key] > .main > .center > .price-wrap {
    min-height: 116px;
    gap: 10px;
  }
  .extratv-page .card[data-key] > .main > .center > .price-wrap > .price {
    font-size: clamp(40px, 4.7vw, 54px);
  }
  .extratv-page .card[data-key] > .main > .center > .price-wrap > .backup-pill {
    max-width: min(100%, 230px);
  }
}


/* ─────────────────────────────────────────────────────────────
   v1.17.55.18 — Phase 2.2: VIP PLUS / Mix PLUS price-code visibility
   ─────────────────────────────────────────────────────────────
   Problem: on VIP PLUS / Mix PLUS, the converted Desktop price could show
   only the numeric part (e.g. "437") while the currency code (ILS/SAR/etc.)
   became visually invisible. This was a rendering issue caused by the tier's
   transparent gradient price styling, not a currency conversion issue.

   Scope: Desktop frontend price text only for vip-plus and mix-plus. Does not
   touch Currency button positioning, currency logic, rates, rounding,
   WooCommerce, checkout, Details panel, Mobile, or action buttons.
*/
@media (min-width: 1024px) {
  .extratv-page .card[data-key="vip-plus"] .price,
  .extratv-page .card[data-key="mix-plus"] .price {
    overflow: visible !important;
    white-space: nowrap !important;
    flex-wrap: nowrap !important;
    align-items: baseline !important;
  }

  .extratv-page .card[data-key="vip-plus"] .price .etv-price-number,
  .extratv-page .card[data-key="mix-plus"] .price .etv-price-number {
    display: inline-block !important;
    flex: 0 0 auto !important;
    min-width: max-content !important;
    max-width: none !important;
    white-space: nowrap !important;
    overflow: visible !important;
    background: linear-gradient(90deg, #fff4c0 0%, #ffd36b 32%, #ffab3d 68%, #fff0b0 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent !important;
    -webkit-text-fill-color: transparent;
  }

  .extratv-page .card[data-key="vip-plus"] .price .etv-price-currency,
  .extratv-page .card[data-key="mix-plus"] .price .etv-price-currency {
    display: inline-block !important;
    flex: 0 0 auto !important;
    min-width: max-content !important;
    max-width: none !important;
    white-space: nowrap !important;
    overflow: visible !important;
    font-size: .60em !important;
    font-weight: 850 !important;
    letter-spacing: .035em !important;
    line-height: 1 !important;
    opacity: .96 !important;
    color: #ffd36b !important;
    -webkit-text-fill-color: #ffd36b !important;
    background: none !important;
    -webkit-background-clip: initial !important;
    background-clip: initial !important;
    text-shadow: 0 0 10px rgba(255, 195, 80, .24);
  }
}

/* ─────────────────────────────────────────────────────────────
   v1.17.55.19 — Phase 2.3: final Desktop stack spacing polish
   ─────────────────────────────────────────────────────────────
   Continues the approved Phase 2 baseline after the VIP PLUS / Mix PLUS
   price-code visibility fix. This is a scoped Desktop-only balance pass for
   the real card left stack. It uses the available lower space more evenly and
   keeps reserved rows so later visibility modes do not make remaining controls
   jump upward.

   Scope: frontend card body on Desktop only. Does not touch Phase 1 Currency
   button behavior, currency logic/rates/rounding, WooCommerce/checkout,
   Details panel, Mobile, media/video, or saved texts.
*/
@media (min-width: 1200px) {
  .extratv-page .card[data-key] > .main {
    padding-top: clamp(66px, 5.9vw, 84px) !important;
    padding-bottom: 24px !important;
  }

  .extratv-page .card[data-key] > .main > .center {
    grid-template-rows:
      minmax(150px, 150px)  /* offer pill + full smart price */
      minmax(52px, 52px)    /* 12 / 6 selector */
      minmax(58px, 58px)    /* Subscribe */
      minmax(50px, 50px)    /* Try Now reserved */
      minmax(48px, 48px) !important; /* Backup + Details reserved */
    row-gap: 11px !important;
    align-content: start !important;
  }

  .extratv-page .card[data-key] > .main > .center > .price-wrap {
    min-height: 150px !important;
    gap: 14px !important;
  }
}

@media (min-width: 1024px) and (max-width: 1199px) {
  .extratv-page .card[data-key] > .main {
    padding-top: clamp(58px, 5.8vw, 66px) !important;
    padding-bottom: 18px !important;
  }

  .extratv-page .card[data-key] > .main > .center {
    grid-template-rows:
      minmax(136px, 136px)
      minmax(48px, 48px)
      minmax(54px, 54px)
      minmax(46px, 46px)
      minmax(46px, 46px) !important;
    row-gap: 8px !important;
    align-content: start !important;
  }

  .extratv-page .card[data-key] > .main > .center > .price-wrap {
    min-height: 136px !important;
    gap: 11px !important;
  }
}

@media (min-width: 1024px) {
  /* Keep the meta/offer and price as a predictable left stack. */
  .extratv-page .card[data-key] > .main > .center > .price-wrap > .backup-pill {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    min-height: 34px !important;
    line-height: 1.15 !important;
    flex: 0 0 auto !important;
  }

  .extratv-page .card[data-key] > .main > .center > .price-wrap > .price {
    flex: 0 0 auto !important;
    min-height: 58px !important;
    align-items: baseline !important;
    max-width: none !important;
    overflow: visible !important;
  }

  /* Keep the bottom controls in their reserved rows. This does not change
     visibility logic; it only prevents future hide/show modes from pulling
     the whole stack upward. */
  .extratv-page .card[data-key] > .main > .center > .grid,
  .extratv-page .card[data-key] > .main > .center > .link.primary,
  .extratv-page .card[data-key] > .main > .center > .link.secondary,
  .extratv-page .card[data-key] > .main > .center > .actions {
    align-self: stretch !important;
    min-width: 0 !important;
  }
}

/* ─────────────────────────────────────────────────────────────
   v1.17.55.20 — Phase 2.4: micro price vertical polish
   ─────────────────────────────────────────────────────────────
   Purpose: lower the smart price line very slightly by increasing the
   breathing space between the Backup/Offer pill and the price. This is a
   Desktop-only visual polish for the approved Phase 2 stack. It does not
   change price size, currency rendering, Phase 1 currency button behavior,
   mobile layout, Details panel, WooCommerce, checkout, or 6/12 logic.
*/
@media (min-width: 1200px) {
  .extratv-page .card[data-key] > .main > .center > .price-wrap {
    gap: 20px !important; /* was 14px: move price down by +6px */
  }
}

@media (min-width: 1024px) and (max-width: 1199px) {
  .extratv-page .card[data-key] > .main > .center > .price-wrap {
    gap: 17px !important; /* was 11px: move price down by +6px */
  }
}



/* ─────────────────────────────────────────────────────────────
   v1.17.55.22 — Phase 3.1: Desktop action layout mode 1
   ─────────────────────────────────────────────────────────────
   Mode: Backup hidden + Try replaces Backup.
   Scope: Desktop frontend main card actions only. Current/Default remains
   untouched. Mobile, Details panel, Phase 1 currency button, Phase 2 stack,
   WooCommerce/checkout, 6/12 logic, media/video, and saved texts are untouched.
*/
@media (min-width: 1024px) {
  .extratv-page .card[data-desktop-actions-layout="hide_backup_try_replaces_backup"] > .main > .center {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) !important;
    column-gap: 10px !important;
    direction: ltr; /* keep Try visually left and Details visually right, even on RTL pages */
  }

  .extratv-page .card[data-desktop-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .price-wrap,
  .extratv-page .card[data-desktop-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .grid,
  .extratv-page .card[data-desktop-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .link.primary {
    grid-column: 1 / -1 !important;
  }

  .extratv-page .card[data-desktop-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .link.secondary {
    grid-row: 5 !important;
    grid-column: 1 !important;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100% !important;
    max-width: none !important;
    min-height: 48px !important;
    margin: 0 !important;
    direction: rtl;
  }

  .extratv-page .card[data-desktop-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .actions {
    grid-row: 5 !important;
    grid-column: 2 !important;
    display: grid !important;
    grid-template-columns: 1fr !important;
    width: 100% !important;
    max-width: none !important;
    min-height: 48px !important;
    margin: 0 !important;
    gap: 0 !important;
    direction: rtl;
  }

  .extratv-page .card[data-desktop-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .actions > .backup-btn {
    display: none !important;
  }

  .extratv-page .card[data-desktop-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .actions > .details-btn {
    width: 100% !important;
    min-height: 48px !important;
  }
}

/* ─────────────────────────────────────────────────────────────
   v1.17.55.25 — Phase 5: Mobile action layout mode 1
   ─────────────────────────────────────────────────────────────
   Mode: Backup hidden + Try replaces Backup on Mobile only.
   Result: Subscribe Now, then Details + Try Now in the lower row. The lower
   Backup action button is only visually hidden; saved Backup data and the
   Backup panel are untouched. Desktop, Phase 1 Currency Position, Phase 2
   price/stack, Phase 3.1 desktop action layout, Phase 4 layering, currency
   logic, WooCommerce/checkout, 6/12 switching, media/video, and saved texts
   are untouched.
*/
@media screen and (max-width: 767px), screen and (hover: none) and (pointer: coarse) {
  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"] > .main > .center {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 10px;
    align-items: stretch;
    width: 100%;
    direction: ltr; /* keep Try in the old Backup slot (left) and Details on the right on RTL pages */
  }

  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .price-wrap,
  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .grid,
  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .link.primary {
    grid-column: 1 / -1;
  }

  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .link.secondary {
    grid-column: 1;
    grid-row: 4;
    width: 100%;
    max-width: none;
    min-height: 46px;
    margin: 10px 0 0;
    align-self: stretch;
    display: flex;
    align-items: center;
    justify-content: center;
    direction: rtl;
  }

  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .actions {
    grid-column: 2;
    grid-row: 4;
    width: 100%;
    max-width: none;
    min-height: 46px;
    margin: 10px 0 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: 0;
    align-self: stretch;
    direction: rtl;
  }

  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .actions > .backup-btn {
    display: none !important;
  }

  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .actions > .details-btn {
    width: 100%;
    min-height: 46px;
  }
}

/* v1.17.55.28 — Phase 6.1 Mobile Device Media Binding Polish
   Scope: device-specific MOBILE images only. Prevents Mobile Image 2/3 from
   inheriting old visual haze/blur/filter settings that make the real uploaded
   mobile image look faded, while leaving desktop media, card layout, video,
   currency, checkout, and approved action phases untouched. */
@media (max-width: 767px) {
  .extratv-page .card .slide[data-device-images="1"][data-mobile-url] {
    --etv-slide-brightness: 100% !important;
    --etv-slide-contrast: 100% !important;
    --etv-slide-saturation: 100% !important;
    filter: none !important;
  }

  .extratv-page .card .slide[data-device-images="1"][data-mobile-url][data-image-theme-override="1"]::after {
    display: none !important;
    content: none !important;
  }

  .extratv-page .card .slide[data-device-images="1"][data-mobile-url] img {
    filter: none !important;
  }

  .extratv-page .card .slide[data-device-images="1"][data-mobile-url] .etv-device-picture,
  .extratv-page .card .slide[data-device-images="1"][data-mobile-url] .etv-device-picture img {
    display: block !important;
    width: 100% !important;
    height: 100% !important;
  }
}


/* ─────────────────────────────────────────────────────────────
   v1.17.55.30 — Phase 7.1: Subscribe button visible-lower hotfix
   ─────────────────────────────────────────────────────────────
   Scope: frontend visual spacing only.
   Desktop: center the price above the 6/12 duration button group and move
   Subscribe Now visibly lower without changing its width or column.
   Mobile: move Subscribe Now slightly lower without changing width/order.
   Does not touch Currency logic/dropdown behavior, WooCommerce/checkout,
   6/12 switching, Details/Backup panels, media, saved texts, or admin settings.
*/
@media (min-width: 1024px) {
  .extratv-page .card[data-key] > .main > .center > .price-wrap > .price {
    align-self: center !important;
  }

  .extratv-page .card[data-key] > .main > .center > .link.primary {
    transform: translateY(clamp(26px, 2.15vw, 34px)) !important;
    will-change: transform;
  }
}

@media screen and (max-width: 767px), screen and (hover: none) and (pointer: coarse) {
  .extratv-page .card[data-key] > .main > .center > .link.primary {
    margin-top: 30px !important;
    transform: translateY(8px) !important;
    will-change: transform;
  }
}

/* ─────────────────────────────────────────────────────────────
   v1.17.55.31 — Phase 7.2: flow-safe Subscribe spacing hotfix
   ─────────────────────────────────────────────────────────────
   Fixes v1.17.55.30 where the visible Subscribe movement used transform and
   could overlap the Try Now row on some cards. This reserves real grid/flow
   space instead: Subscribe moves down, but lower buttons move safely with it.
   Scope: frontend visual spacing only. No admin/settings/data/currency/media.
*/
@media (min-width: 1200px) {
  .extratv-page .card[data-key] > .main > .center {
    grid-template-rows:
      minmax(150px, 150px)
      minmax(52px, 52px)
      minmax(78px, 78px)
      minmax(50px, 50px)
      minmax(48px, 48px) !important;
    row-gap: 9px !important;
  }
}

@media (min-width: 1024px) and (max-width: 1199px) {
  .extratv-page .card[data-key] > .main > .center {
    grid-template-rows:
      minmax(136px, 136px)
      minmax(48px, 48px)
      minmax(70px, 70px)
      minmax(46px, 46px)
      minmax(46px, 46px) !important;
    row-gap: 7px !important;
  }
}

@media (min-width: 1024px) {
  .extratv-page .card[data-key] > .main > .center > .price-wrap > .price {
    align-self: center !important;
  }

  .extratv-page .card[data-key] > .main > .center > .link.primary {
    transform: none !important;
    margin-top: 0 !important;
    align-self: end !important;
    will-change: auto !important;
  }
}

@media screen and (max-width: 767px), screen and (hover: none) and (pointer: coarse) {
  .extratv-page .card[data-key] > .main > .center > .link.primary {
    transform: none !important;
    margin-top: 34px !important;
    will-change: auto !important;
  }
}

/* ─────────────────────────────────────────────────────────────
   v1.17.55.32 — Phase 7.3: bottom action row flow spacing hotfix
   ─────────────────────────────────────────────────────────────
   Goal: lower the lower action controls (Try Now / Details / Backup) slightly
   on Desktop and Mobile using real layout spacing, not transform. This keeps
   the row professional and prevents hidden/moved Try states from pulling the
   remaining lower buttons upward.

   Scope: frontend spacing only. Does not touch Subscribe position, price,
   Currency button/dropdown, Details/Backup panels, media/video, WooCommerce,
   checkout, saved texts, or admin settings.
*/
@media (min-width: 1024px) {
  .extratv-page .card[data-key] > .main > .center > .link.secondary,
  .extratv-page .card[data-key] > .main > .center > .actions {
    margin-top: clamp(12px, 1.05vw, 16px) !important;
  }

  .extratv-page .card[data-desktop-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .link.secondary,
  .extratv-page .card[data-desktop-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .actions {
    margin-top: clamp(12px, 1.05vw, 16px) !important;
  }
}

@media screen and (max-width: 767px), screen and (hover: none) and (pointer: coarse) {
  .extratv-page .card[data-key] > .main > .center > .link.secondary,
  .extratv-page .card[data-key] > .main > .center > .actions {
    margin-top: 18px !important;
  }

  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .link.secondary,
  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"] > .main > .center > .actions {
    margin-top: 18px !important;
  }
}


/* ─────────────────────────────────────────────────────────────
   v1.17.55.33 — Phase 7.4: conditional Subscribe balance
   ─────────────────────────────────────────────────────────────
   Goal: Subscribe Now is lowered only when needed — when Try Now is hidden
   or moved into the lower row, or when the new per-device admin control is
   set to Lower slightly. This supersedes the v1.17.55.32 bottom-row lowering
   so Details / Try / Backup do not get pushed down globally.

   Scope: frontend spacing only. No currency logic/dropdown, price values,
   6/12 switching, Details/Backup panel logic, media/video, WooCommerce,
   checkout, links, or saved label text changed.
*/
@media (min-width: 1200px) {
  .extratv-page .card[data-desktop-subscribe-balance="current"] > .main > .center {
    grid-template-rows:
      minmax(132px, auto)
      minmax(50px, auto)
      minmax(56px, auto)
      minmax(48px, auto)
      minmax(46px, auto) !important;
    row-gap: 10px !important;
  }

  .extratv-page .card[data-desktop-subscribe-balance="lower"] > .main > .center {
    grid-template-rows:
      minmax(150px, 150px)
      minmax(52px, 52px)
      minmax(78px, 78px)
      minmax(50px, 50px)
      minmax(48px, 48px) !important;
    row-gap: 9px !important;
  }
}

@media (min-width: 1024px) and (max-width: 1199px) {
  .extratv-page .card[data-desktop-subscribe-balance="current"] > .main > .center {
    grid-template-rows:
      minmax(116px, auto)
      minmax(46px, auto)
      minmax(52px, auto)
      minmax(46px, auto)
      minmax(44px, auto) !important;
    row-gap: 8px !important;
  }

  .extratv-page .card[data-desktop-subscribe-balance="lower"] > .main > .center {
    grid-template-rows:
      minmax(136px, 136px)
      minmax(48px, 48px)
      minmax(70px, 70px)
      minmax(46px, 46px)
      minmax(46px, 46px) !important;
    row-gap: 7px !important;
  }
}

@media (min-width: 1024px) {
  .extratv-page .card[data-desktop-subscribe-balance] > .main > .center > .price-wrap > .price {
    align-self: center !important;
  }

  .extratv-page .card[data-desktop-subscribe-balance="current"] > .main > .center > .link.primary {
    transform: none !important;
    margin-top: 0 !important;
    align-self: stretch !important;
    will-change: auto !important;
  }

  .extratv-page .card[data-desktop-subscribe-balance="lower"] > .main > .center > .link.primary {
    transform: none !important;
    margin-top: 0 !important;
    align-self: end !important;
    will-change: auto !important;
  }

  .extratv-page .card[data-desktop-subscribe-balance] > .main > .center > .link.secondary,
  .extratv-page .card[data-desktop-subscribe-balance] > .main > .center > .actions {
    margin-top: 0 !important;
  }
}

@media screen and (max-width: 767px), screen and (hover: none) and (pointer: coarse) {
  .extratv-page .card[data-mobile-subscribe-balance="current"] > .main > .center > .link.primary {
    transform: none !important;
    margin-top: 18px !important;
    will-change: auto !important;
  }

  .extratv-page .card[data-mobile-subscribe-balance="lower"] > .main > .center > .link.primary {
    transform: none !important;
    margin-top: 34px !important;
    will-change: auto !important;
  }

  .extratv-page .card[data-mobile-subscribe-balance] > .main > .center > .link.secondary {
    margin-top: 14px !important;
  }

  .extratv-page .card[data-mobile-subscribe-balance] > .main > .center > .actions {
    margin: 22px auto 0 !important;
  }

  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"][data-mobile-subscribe-balance] > .main > .center > .link.secondary,
  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"][data-mobile-subscribe-balance] > .main > .center > .actions {
    margin: 10px 0 0 !important;
  }
}


/* ─────────────────────────────────────────────────────────────
   v1.17.55.34 — Phase 7.5: visible per-device Subscribe balance fix
   ─────────────────────────────────────────────────────────────
   Goal: make the new Subscribe Button Balance control visibly effective.
   Desktop Lower: Subscribe Now drops more, still inside the left column,
   same width, away from the currency button/dropdown.
   Mobile Lower/Auto: Subscribe Now keeps a stable lower position when Try Now
   is hidden or moved into the lower Backup row, so controls do not jump upward.
   Scope: frontend spacing only. No currency logic/dropdown, checkout, media,
   price values, 6/12 switching, Details/Backup panels, links, or saved texts.
*/
@media (min-width: 1200px) {
  .extratv-page .card[data-desktop-subscribe-balance="lower"] > .main > .center {
    grid-template-rows:
      minmax(150px, 150px)
      minmax(52px, 52px)
      minmax(96px, 96px)
      minmax(50px, 50px)
      minmax(48px, 48px) !important;
    row-gap: 6px !important;
  }
}

@media (min-width: 1024px) and (max-width: 1199px) {
  .extratv-page .card[data-desktop-subscribe-balance="lower"] > .main > .center {
    grid-template-rows:
      minmax(136px, 136px)
      minmax(48px, 48px)
      minmax(84px, 84px)
      minmax(46px, 46px)
      minmax(46px, 46px) !important;
    row-gap: 5px !important;
  }
}

@media (min-width: 1024px) {
  .extratv-page .card[data-desktop-subscribe-balance="lower"] > .main > .center > .link.primary {
    align-self: end !important;
    justify-self: stretch !important;
    width: 100% !important;
    max-width: none !important;
    transform: none !important;
    margin-top: 0 !important;
  }

  .extratv-page .card[data-desktop-subscribe-balance="lower"] > .main > .center > .link.secondary,
  .extratv-page .card[data-desktop-subscribe-balance="lower"] > .main > .center > .actions {
    margin-top: 0 !important;
  }
}

@media screen and (max-width: 767px), screen and (hover: none) and (pointer: coarse) {
  .extratv-page .card[data-mobile-subscribe-balance="current"] > .main > .center > .link.primary {
    margin-top: 30px !important;
    transform: none !important;
    will-change: auto !important;
  }

  .extratv-page .card[data-mobile-subscribe-balance="lower"] > .main > .center > .link.primary {
    margin-top: 52px !important;
    transform: none !important;
    will-change: auto !important;
  }

  .extratv-page .card[data-mobile-subscribe-balance] > .main > .center > .link.secondary,
  .extratv-page .card[data-mobile-subscribe-balance] > .main > .center > .actions,
  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"][data-mobile-subscribe-balance] > .main > .center > .link.secondary,
  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"][data-mobile-subscribe-balance] > .main > .center > .actions {
    margin-top: 18px !important;
  }
}


/* ─────────────────────────────────────────────────────────────
   v1.17.55.35 — Phase 7.6: mobile Subscribe breathing fix
   ─────────────────────────────────────────────────────────────
   Goal: make Mobile Subscribe Button Balance = Lower slightly breathe more.
   Mobile-only override. Desktop, currency/dropdown, price, 6/12, lower action
   layout, media/video, Details/Backup panels, checkout, and links untouched.
*/
@media screen and (max-width: 767px), screen and (hover: none) and (pointer: coarse) {
  .extratv-page .card[data-mobile-subscribe-balance="lower"] > .main > .center > .link.primary {
    margin-top: 68px !important;
    transform: none !important;
    will-change: auto !important;
  }
}


/* ─────────────────────────────────────────────────────────────
   v1.17.55.36 — Phase 7.7: final mobile/desktop breathing balance
   ─────────────────────────────────────────────────────────────
   Direction approved after visual review:
   Desktop: only a small Subscribe Now drop when Subscribe Button Balance
   resolves to lower.
   Mobile: reduce the over-large Subscribe drop from 1.17.55.35, then give
   the lower action row (Trial / Details / Backup) a little extra breathing
   space. This matches Option B: do not push Subscribe too far; lower the
   lower controls slightly.

   Scope: frontend spacing only. No Currency button/dropdown logic, price,
   6/12 switching, checkout, media/video, Details/Backup panels, links, or
   saved text changed.
*/
@media (min-width: 1200px) {
  .extratv-page .card[data-desktop-subscribe-balance="lower"] > .main > .center {
    grid-template-rows:
      minmax(150px, 150px)
      minmax(52px, 52px)
      minmax(104px, 104px)
      minmax(50px, 50px)
      minmax(48px, 48px) !important;
    row-gap: 5px !important;
  }
}

@media (min-width: 1024px) and (max-width: 1199px) {
  .extratv-page .card[data-desktop-subscribe-balance="lower"] > .main > .center {
    grid-template-rows:
      minmax(136px, 136px)
      minmax(48px, 48px)
      minmax(92px, 92px)
      minmax(46px, 46px)
      minmax(46px, 46px) !important;
    row-gap: 4px !important;
  }
}

@media (min-width: 1024px) {
  .extratv-page .card[data-desktop-subscribe-balance="lower"] > .main > .center > .link.primary {
    align-self: end !important;
    margin-top: 0 !important;
    transform: none !important;
    will-change: auto !important;
  }
}

@media screen and (max-width: 767px), screen and (hover: none) and (pointer: coarse) {
  .extratv-page .card[data-mobile-subscribe-balance="lower"] > .main > .center > .link.primary {
    margin-top: 46px !important;
    transform: none !important;
    will-change: auto !important;
  }

  .extratv-page .card[data-mobile-subscribe-balance="lower"] > .main > .center > .link.secondary,
  .extratv-page .card[data-mobile-subscribe-balance="lower"] > .main > .center > .actions,
  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"][data-mobile-subscribe-balance="lower"] > .main > .center > .link.secondary,
  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"][data-mobile-subscribe-balance="lower"] > .main > .center > .actions {
    margin-top: 30px !important;
  }
}

/* ─────────────────────────────────────────────────────────────
   v1.17.55.37 — Phase 7.8: mobile Subscribe mid-balance fix
   ─────────────────────────────────────────────────────────────
   Goal: mobile-only correction after live review. Raise Subscribe Now from
   the over-lowered 1.17.55.36 position so it sits visually between the
   6/12 row and the lower Trial/Details row. Keep lower actions breathing.

   Scope: Mobile frontend spacing only. Desktop, Currency button/dropdown,
   price, 6/12 switching, media/video, Details/Backup panels, checkout,
   links, saved texts, and admin controls untouched.
*/
@media screen and (max-width: 767px), screen and (hover: none) and (pointer: coarse) {
  .extratv-page .card[data-mobile-subscribe-balance="lower"] > .main > .center > .link.primary {
    margin-top: 30px !important;
    transform: none !important;
    will-change: auto !important;
  }

  .extratv-page .card[data-mobile-subscribe-balance="lower"] > .main > .center > .link.secondary,
  .extratv-page .card[data-mobile-subscribe-balance="lower"] > .main > .center > .actions,
  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"][data-mobile-subscribe-balance="lower"] > .main > .center > .link.secondary,
  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"][data-mobile-subscribe-balance="lower"] > .main > .center > .actions {
    margin-top: 32px !important;
  }
}


/* ─────────────────────────────────────────────────────────────
   v1.17.55.38 — Final Mobile Micro Spacing Polish
   ─────────────────────────────────────────────────────────────
   Mobile-only final micro adjustment after visual review. Keep the current
   approved structure, but add a tiny amount of breathing room: Subscribe Now
   drops only slightly, and the lower Trial/Details row drops slightly more.

   Scope: Mobile frontend spacing only. Desktop, Currency button/dropdown,
   price, 6/12 switching, Backup pill, media/video, Details/Backup panels,
   checkout, links, saved texts, and admin controls untouched.
*/
@media screen and (max-width: 767px), screen and (hover: none) and (pointer: coarse) {
  .extratv-page .card[data-mobile-subscribe-balance="lower"] > .main > .center > .link.primary {
    margin-top: 36px !important;
    transform: none !important;
    will-change: auto !important;
  }

  .extratv-page .card[data-mobile-subscribe-balance="lower"] > .main > .center > .link.secondary,
  .extratv-page .card[data-mobile-subscribe-balance="lower"] > .main > .center > .actions,
  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"][data-mobile-subscribe-balance="lower"] > .main > .center > .link.secondary,
  .extratv-page .card[data-mobile-actions-layout="hide_backup_try_replaces_backup"][data-mobile-subscribe-balance="lower"] > .main > .center > .actions {
    margin-top: 40px !important;
  }
}

/* ─────────────────────────────────────────────────────────────
   v1.17.55.41/42 — Full Video Mode: clean video-slide-only rebuild
   ─────────────────────────────────────────────────────────────
   Scope: only the active video slide when the saved Video Display Mode is
   Full Video. Image slides, card layout, pricing/buttons, Currency Switcher,
   Details/Backup panels, and approved mobile spacing are intentionally not
   targeted by this block.
*/
.extratv-page .card .slide.video.etv-video-mode-full,
.extratv-page .card .slide.video[data-video-display-mode="full_video"] {
  overflow: hidden;
  background:
    radial-gradient(circle at 50% 18%, rgba(139,92,246,.24), transparent 44%),
    linear-gradient(180deg, #070b16 0%, #030611 100%);
}

.extratv-page .card .slide.video.etv-video-mode-full .etv-video-backdrop,
.extratv-page .card .slide.video[data-video-display-mode="full_video"] .etv-video-backdrop {
  position: absolute;
  inset: -26px;
  z-index: 0;
  display: block;
  pointer-events: none;
  background-image:
    var(--etv-video-backdrop-image, linear-gradient(180deg, #0a1020 0%, #030611 100%)),
    radial-gradient(circle at 50% 16%, rgba(255,255,255,.12), transparent 42%),
    linear-gradient(180deg, #0a1020 0%, #030611 100%);
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
  filter: blur(22px) brightness(.52) saturate(1.2);
  transform: scale(1.08);
  transform-origin: center center;
}

.extratv-page .card .slide.video.etv-video-mode-full .etv-video-backdrop::after,
.extratv-page .card .slide.video[data-video-display-mode="full_video"] .etv-video-backdrop::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(circle at 50% 45%, rgba(255,255,255,.08), transparent 40%),
    linear-gradient(180deg, rgba(0,0,0,.20), rgba(0,0,0,.58));
}

.extratv-page .card .slide.video.etv-video-mode-full .etv-video-layer,
.extratv-page .card .slide.video[data-video-display-mode="full_video"] .etv-video-layer {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.extratv-page .card .slide.video.etv-video-mode-full video,
.extratv-page .card .slide.video[data-video-display-mode="full_video"] video {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: cover;
  object-position: center center;
  background: transparent !important;
  border: 0;
  box-shadow: none;
}

/* ─────────────────────────────────────────────────────────────
   v1.17.55.45 — Mobile Full Video Framing Application Fix
   ─────────────────────────────────────────────────────────────
   Mobile-only, Full-Video-only, video-slide-only. Smart/Safe modes now use
   true negative zoom: object-fit stays cover, then the foreground video is
   scaled down slightly. The blurred backdrop fills the exposed edges, so the
   user sees a visible framing difference without touching controls or images.
*/
@media (max-width: 767px) {
  .extratv-page .card .slide.video.etv-video-mode-full[data-mobile-video-framing="smart_zoom_out"] .etv-video-layer,
  .extratv-page .card .slide.video[data-video-display-mode="full_video"][data-mobile-video-framing="smart_zoom_out"] .etv-video-layer,
  .extratv-page .card .slide.video.etv-video-mode-full[data-mobile-video-framing="safe_zoom_out"] .etv-video-layer,
  .extratv-page .card .slide.video[data-video-display-mode="full_video"][data-mobile-video-framing="safe_zoom_out"] .etv-video-layer {
    overflow: hidden;
  }

  .extratv-page .card .slide.video.etv-video-mode-full[data-mobile-video-framing="smart_zoom_out"] video,
  .extratv-page .card .slide.video[data-video-display-mode="full_video"][data-mobile-video-framing="smart_zoom_out"] video,
  .extratv-page .card .slide.video.etv-video-mode-full[data-mobile-video-framing="safe_zoom_out"] video,
  .extratv-page .card .slide.video[data-video-display-mode="full_video"][data-mobile-video-framing="safe_zoom_out"] video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center center;
    transform: scale(var(--etv-mobile-video-framing-scale, .94));
    transform-origin: center center;
    background: transparent !important;
    will-change: transform;
  }

  .extratv-page .card .slide.video.etv-video-mode-full[data-mobile-video-framing="smart_zoom_out"] .etv-video-backdrop,
  .extratv-page .card .slide.video[data-video-display-mode="full_video"][data-mobile-video-framing="smart_zoom_out"] .etv-video-backdrop,
  .extratv-page .card .slide.video.etv-video-mode-full[data-mobile-video-framing="safe_zoom_out"] .etv-video-backdrop,
  .extratv-page .card .slide.video[data-video-display-mode="full_video"][data-mobile-video-framing="safe_zoom_out"] .etv-video-backdrop {
    opacity: 1;
    filter: blur(26px) brightness(.44) saturate(1.24);
    transform: scale(1.16);
  }
}



/* ─────────────────────────────────────────────────────────────
   v1.17.55.48 — Full Video Final Visual Pass
   ─────────────────────────────────────────────────────────────
   Scoped to Full Video only. Cinematic Cover, image slides, media ordering,
   Natural Mode, currency, buttons, prices, Details/Backup panels and layouts
   remain untouched. The goal is a full-card video presentation with no small
   contained strip, while keeping controls readable and not dimmed.
*/
.extratv-page .card[data-video-display-mode="full_video"] .slide.video.etv-video-mode-full,
.extratv-page .card[data-video-display-mode="full_video"] .slide.video[data-video-display-mode="full_video"] {
  transform: none !important;
  will-change: opacity;
}

.extratv-page .card[data-video-display-mode="full_video"] .slide.video.etv-video-mode-full .etv-video-layer,
.extratv-page .card[data-video-display-mode="full_video"] .slide.video[data-video-display-mode="full_video"] .etv-video-layer {
  inset: 0;
  width: 100%;
  height: 100%;
}

.extratv-page .card[data-video-display-mode="full_video"] .slide.video.etv-video-mode-full video,
.extratv-page .card[data-video-display-mode="full_video"] .slide.video[data-video-display-mode="full_video"] video {
  display: block;
  min-width: 100%;
  min-height: 100%;
  object-fit: cover;
  object-position: center center;
  transform-origin: center center;
}

/* Full Video must not dim the price/buttons after the controls auto-hide timer.
   This fixes the video-only regression without changing Cinematic Cover. */
.extratv-page .card[data-video-display-mode="full_video"].preview-running .main {
  opacity: 1 !important;
}
.extratv-page .card[data-video-display-mode="full_video"].preview-running .badge-mini,
.extratv-page .card[data-video-display-mode="full_video"].preview-running .device {
  opacity: 1 !important;
}

.extratv-page .card[data-video-display-mode="full_video"][data-media-look="natural"] .slide.video.etv-video-mode-full .etv-video-backdrop::after,
.extratv-page .card[data-video-display-mode="full_video"][data-media-look="natural"] .slide.video[data-video-display-mode="full_video"] .etv-video-backdrop::after {
  background:
    radial-gradient(circle at 50% 45%, rgba(255,255,255,.035), transparent 42%),
    linear-gradient(180deg, rgba(0,0,0,.08), rgba(0,0,0,.24));
}

@media (max-width: 767px) {
  .extratv-page .card[data-video-display-mode="full_video"] .slide.video.etv-video-mode-full video,
  .extratv-page .card[data-video-display-mode="full_video"] .slide.video[data-video-display-mode="full_video"] video {
    object-position: center center;
  }
}

/* ExtraTV 1.17.55.46 — Media Natural Mode + Overlay Control
   Scoped to a single card via data-media-look="natural". This does not delete
   or reset saved cinematic/global/per-slot settings; it only bypasses their
   visible media effects while this mode is selected. */
.card[data-media-look="natural"]{
  --etv-media-brightness: 100% !important;
  --etv-media-contrast: 100% !important;
  --etv-media-saturation: 100% !important;
  --etv-cinematic-overlay: rgba(0,0,0,0) !important;
  --etv-cinematic-vignette: rgba(0,0,0,0) !important;
  --etv-cinematic-warm: rgba(0,0,0,0) !important;
  --etv-readability-gradient: rgba(0,0,0,0) !important;
  --etv-visual-glow: rgba(0,0,0,0) !important;
  --etv-visual-haze: rgba(255,255,255,0) !important;
  --etv-visual-border-glow: rgba(0,0,0,0) !important;
}
.card[data-media-look="natural"] .slide{
  --etv-slide-brightness: 100% !important;
  --etv-slide-contrast: 100% !important;
  --etv-slide-saturation: 100% !important;
  --etv-slide-overlay: rgba(0,0,0,0) !important;
  --etv-slide-vignette: rgba(0,0,0,0) !important;
  --etv-slide-warm: rgba(0,0,0,0) !important;
  --etv-slide-readability: rgba(0,0,0,0) !important;
  --etv-slide-glow: rgba(0,0,0,0) !important;
  --etv-slide-haze: rgba(255,255,255,0) !important;
  filter: brightness(100%) contrast(100%) saturate(100%) !important;
}
.card[data-media-look="natural"] .media video{
  filter: brightness(100%) contrast(100%) saturate(100%) !important;
}
.card[data-media-look="natural"] .media-overlay,
.card[data-media-look="natural"] .etv-media-tint{
  display: none !important;
  opacity: 0 !important;
  background: transparent !important;
}
.card[data-media-look="natural"] .media::after{
  content: none !important;
  display: none !important;
  background: none !important;
}

/* ExtraTV 1.17.55.50 — Stable Production Release.
   No new CSS behavior is introduced here; this comment promotes the approved
   1.17.55.49 release candidate to the stable production package. */


/* ─────────────────────────────────────────────────────────────
   v1.17.56.18 — Backup Button Visual Consistency Fix
   Scope: bottom Backup action button visual style only.
   Keeps behavior, layout, pricing, currency, media, Add-ons, and panels unchanged.
   ───────────────────────────────────────────────────────────── */
.extratv-page .card[data-key="premium-vip"] .actions > .backup-btn {
  background: linear-gradient(135deg, rgba(255,138,22,.20), rgba(201,150,46,.15), rgba(159,107,22,.10)) !important;
  border-color: rgba(184,134,47,.48) !important;
  box-shadow: inset 0 1px 0 rgba(201,150,46,.10), 0 10px 22px rgba(0,0,0,.12) !important;
}
.extratv-page .card[data-key="vip-plus"] .actions > .backup-btn {
  background: linear-gradient(135deg, rgba(255,138,22,.20), rgba(199,106,26,.15), rgba(138,79,18,.08)) !important;
  border-color: rgba(200,149,58,.46) !important;
  box-shadow: inset 0 1px 0 rgba(199,106,26,.10), 0 10px 22px rgba(0,0,0,.12) !important;
}
