/* =====================================================================
   ZAPFLIX BRAND LOADER v2 — the "Z" pours out the rest of the word, letter by letter,
   and gathers it back in (X first). Shared by the player (first load, quality switch,
   buffering, repair) and Live TV. Pure CSS, no JS, no images. CLAUDE.md 5.52/5.54.

   Markup (aria-hidden; the status text next to it carries the meaning):
     <div class="zf-bl" aria-hidden="true"><span class="zf-bl-in">
       <span class="zf-bl-z">Z</span><span class="zf-bl-l">A</span><span class="zf-bl-l">P</span>
       <span class="zf-bl-l">F</span><span class="zf-bl-l">L</span><span class="zf-bl-l">I</span>
       <span class="zf-bl-l">X</span></span></div>

   Order: X leaves first and A last, and they return A first, so no letter ever crosses
   another. Each letter starts at the Z's centre (translateX(-offset), offsets measured for Inter 900
   at -0.02em letter-spacing), small, soft and transparent, then glides to its own place.
   The whole word slides by (50% - half a Z) of its own width so the mark stays centred.
   Size it with font-size on .zf-bl; .zf-bl-sm = small (over a picture).
   Generated by a small script: keep the per-letter keyframes in step with the offsets.
   ===================================================================== */

.zf-bl {
  --zf-bl-z: 0.674em;            /* width of the Inter 900 "Z" */
  --zf-bl-dur: 4.2s;
  position: relative;
  display: inline-flex;
  justify-content: center;
  font: 900 46px/1 Inter, "Segoe UI", system-ui, -apple-system, Arial, sans-serif;
  letter-spacing: -0.02em;
  direction: ltr;
  unicode-bidi: isolate;
  user-select: none;
  -webkit-user-select: none;
  pointer-events: none;
  filter: drop-shadow(0 0 14px rgba(229, 9, 20, 0.34)) drop-shadow(0 8px 22px rgba(0, 0, 0, 0.6));
}

.zf-bl-in {
  position: relative;
  display: inline-flex;
  align-items: center;
  animation: zfBlWord var(--zf-bl-dur) infinite;
  will-change: transform;
}

/* deep crimson metal: bright top edge, rich middle, dark foot, a light band for the sweep */
.zf-bl-z,
.zf-bl-l {
  position: relative;
  display: inline-block;
  background-image:
    linear-gradient(100deg, transparent 0%, transparent 40%, rgba(255, 232, 206, 0.9) 50%, transparent 60%, transparent 100%),
    linear-gradient(180deg, #ff8a8f 0%, #ff3b44 22%, #e50914 52%, #a3020c 82%, #6e0008 100%);
  background-size: 300% 100%, 100% 100%;
  background-position: 120% 0, 0 0;
  background-repeat: no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

.zf-bl-z {
  z-index: 2;
  transform-origin: 50% 58%;
  animation: zfBlZ var(--zf-bl-dur) infinite, zfBlShine var(--zf-bl-dur) infinite;
}

.zf-bl-l {
  z-index: 1;
  animation-duration: var(--zf-bl-dur), var(--zf-bl-dur);
  animation-iteration-count: infinite, infinite;
  will-change: transform, opacity, filter;
}

/* soft red halo that opens with the word and gathers back with it */
.zf-bl::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: 50%;
  top: 46%;
  width: 3.4em;
  height: 1.7em;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(229, 9, 20, 0.32), rgba(229, 9, 20, 0.07) 62%, transparent);
  transform: translate(-50%, -50%) scale(0.62);
  animation: zfBlHalo var(--zf-bl-dur) infinite;
}

/* ---- timeline ----
   0-10%   Z alone, a slow breath          10-46%  the word unrolls out of the Z as one piece, X a step ahead
   51-64%  the whole word, a light sweep   64-94%  it rolls back in, A first, X last
   The word slide follows X (the visible right edge), so the mark stays centred. */
@keyframes zfBlWord {
  0%, 10% { transform: translateX(calc(50% - var(--zf-bl-z) / 2)); animation-timing-function: cubic-bezier(0.2, 1.05, 0.32, 1); }
  40%, 69% { transform: translateX(0); animation-timing-function: cubic-bezier(0.62, 0, 0.36, 1); }
  94%, 100% { transform: translateX(calc(50% - var(--zf-bl-z) / 2)); }
}
@keyframes zfBlZ {
  0% { transform: scale(1); filter: brightness(1); animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
  7% { transform: scale(1.06); filter: brightness(1.18); animation-timing-function: cubic-bezier(0.3, 0, 0.25, 1); }
  16% { transform: scale(0.985); filter: brightness(1); }
  26%, 84% { transform: scale(1); animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
  93% { transform: scale(1.07); filter: brightness(1.25); animation-timing-function: cubic-bezier(0.3, 0, 0.3, 1); }
  100% { transform: scale(1); filter: brightness(1); }
}
@keyframes zfBlShine {
  0%, 49% { background-position: 120% 0, 0 0; }
  63%, 100% { background-position: -20% 0, 0 0; }
}
@keyframes zfBlHalo {
  0% { transform: translate(-50%, -50%) scale(0.62); opacity: 0.75; }
  7% { transform: translate(-50%, -50%) scale(0.78); opacity: 1; }
  48%, 64% { transform: translate(-50%, -50%) scale(1.5, 1); opacity: 0.85; }
  93% { transform: translate(-50%, -50%) scale(0.72); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(0.62); opacity: 0.75; }
}

@keyframes zfBlL1 {
  0%, 15.5% { transform: translateX(-0.72em) scale(0.82); opacity: 0; filter: blur(2px); animation-timing-function: cubic-bezier(0.2, 1.05, 0.32, 1); }
  24.5% { opacity: 1; filter: blur(1.2px); }
  45.5%, 64% { transform: translateX(0) scale(1); opacity: 1; filter: blur(0); animation-timing-function: cubic-bezier(0.62, 0, 0.36, 1); }
  81% { opacity: 1; filter: blur(0.6px); }
  89%, 100% { transform: translateX(-0.72em) scale(0.82); opacity: 0; filter: blur(2px); }
}
.zf-bl-l:nth-child(2) { animation-name: zfBlL1, zfBlShine; animation-delay: 0s, 0.07s; }
@keyframes zfBlL2 {
  0%, 14.4% { transform: translateX(-1.43em) scale(0.82); opacity: 0; filter: blur(2px); animation-timing-function: cubic-bezier(0.2, 1.05, 0.32, 1); }
  23.4% { opacity: 1; filter: blur(1.2px); }
  44.4%, 65% { transform: translateX(0) scale(1); opacity: 1; filter: blur(0); animation-timing-function: cubic-bezier(0.62, 0, 0.36, 1); }
  82% { opacity: 1; filter: blur(0.6px); }
  90%, 100% { transform: translateX(-1.43em) scale(0.82); opacity: 0; filter: blur(2px); }
}
.zf-bl-l:nth-child(3) { animation-name: zfBlL2, zfBlShine; animation-delay: 0s, 0.14s; }
@keyframes zfBlL3 {
  0%, 13.3% { transform: translateX(-2.03em) scale(0.82); opacity: 0; filter: blur(2px); animation-timing-function: cubic-bezier(0.2, 1.05, 0.32, 1); }
  22.3% { opacity: 1; filter: blur(1.2px); }
  43.3%, 66% { transform: translateX(0) scale(1); opacity: 1; filter: blur(0); animation-timing-function: cubic-bezier(0.62, 0, 0.36, 1); }
  83% { opacity: 1; filter: blur(0.6px); }
  91%, 100% { transform: translateX(-2.03em) scale(0.82); opacity: 0; filter: blur(2px); }
}
.zf-bl-l:nth-child(4) { animation-name: zfBlL3, zfBlShine; animation-delay: 0s, 0.21s; }
@keyframes zfBlL4 {
  0%, 12.2% { transform: translateX(-2.59em) scale(0.82); opacity: 0; filter: blur(2px); animation-timing-function: cubic-bezier(0.2, 1.05, 0.32, 1); }
  21.2% { opacity: 1; filter: blur(1.2px); }
  42.2%, 67% { transform: translateX(0) scale(1); opacity: 1; filter: blur(0); animation-timing-function: cubic-bezier(0.62, 0, 0.36, 1); }
  84% { opacity: 1; filter: blur(0.6px); }
  92%, 100% { transform: translateX(-2.59em) scale(0.82); opacity: 0; filter: blur(2px); }
}
.zf-bl-l:nth-child(5) { animation-name: zfBlL4, zfBlShine; animation-delay: 0s, 0.28s; }
@keyframes zfBlL5 {
  0%, 11.1% { transform: translateX(-2.99em) scale(0.82); opacity: 0; filter: blur(2px); animation-timing-function: cubic-bezier(0.2, 1.05, 0.32, 1); }
  20.1% { opacity: 1; filter: blur(1.2px); }
  41.1%, 68% { transform: translateX(0) scale(1); opacity: 1; filter: blur(0); animation-timing-function: cubic-bezier(0.62, 0, 0.36, 1); }
  85% { opacity: 1; filter: blur(0.6px); }
  93%, 100% { transform: translateX(-2.99em) scale(0.82); opacity: 0; filter: blur(2px); }
}
.zf-bl-l:nth-child(6) { animation-name: zfBlL5, zfBlShine; animation-delay: 0s, 0.35s; }
@keyframes zfBlL6 {
  0%, 10% { transform: translateX(-3.51em) scale(0.82); opacity: 0; filter: blur(2px); animation-timing-function: cubic-bezier(0.2, 1.05, 0.32, 1); }
  19% { opacity: 1; filter: blur(1.2px); }
  40%, 69% { transform: translateX(0) scale(1); opacity: 1; filter: blur(0); animation-timing-function: cubic-bezier(0.62, 0, 0.36, 1); }
  86% { opacity: 1; filter: blur(0.6px); }
  94%, 100% { transform: translateX(-3.51em) scale(0.82); opacity: 0; filter: blur(2px); }
}
.zf-bl-l:nth-child(7) { animation-name: zfBlL6, zfBlShine; animation-delay: 0s, 0.42s; }

/* small, over a picture (buffering, Live TV) */
.zf-bl.zf-bl-sm { font-size: 32px; }

/* no motion: the full word, breathing gently */
@media (prefers-reduced-motion: reduce) {
  .zf-bl-in, .zf-bl-z, .zf-bl-l { animation: none !important; transform: none !important; opacity: 1 !important; filter: none !important; }
  .zf-bl { animation: zfBlBreathe 2.4s ease-in-out infinite; }
  .zf-bl::before { animation: none; transform: translate(-50%, -50%) scale(1.5, 1); opacity: 0.8; }
}
@keyframes zfBlBreathe { 50% { opacity: 0.6; } }
