/*
 * The branded loading screen (owner request, 4 Oct 2026). Loaded by index.html before any
 * JavaScript, so the same black screen with the show logo appears at once and stays while the
 * app fetches the campaign data (App.tsx Status uses the same classes). A separate file because
 * the page's Content-Security-Policy allows only same-origin stylesheets (no inline styles).
 */
/* The page appears under the loading screen and brings a scrollbar with it; on desktop that
   narrowed the window by ~15 px and the screen jumped. The scrollbar track is always shown
   (dark while the loader shows), so the width never changes. (scrollbar-gutter on the root
   element is not applied reliably.) Phones use overlay scrollbars and are not affected. */
html {
  overflow-y: scroll;
}

html:has(.page-loader) {
  background: #000000;
  scrollbar-color: #2a2a2a #000000;
}

.page-loader {
  position: fixed;
  /* top/right/bottom/left as well as inset: old Safari (iOS 12-14.4) has no inset. */
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 28px;
  padding: 24px;
  background: #000000;
  color: #ffffff;
  text-align: center;
}

.page-loader-logo {
  will-change: transform, opacity;
  width: min(62vw, 320px);
  height: auto;
  animation: page-loader-pulse 1.6s ease-in-out infinite;
  /* Set by the app on its own loader elements, so they continue the first one's animation. */
  animation-delay: var(--page-loader-delay, 0s);
}

.page-loader-logo.is-static {
  animation: none;
}

/* An indeterminate progress bar in the campaign magenta. */
.page-loader-bar {
  position: relative;
  width: min(46vw, 200px);
  height: 3px;
  overflow: hidden;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.15);
}

.page-loader-bar::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 40%;
  transform: translateX(-100%);
  will-change: transform;
  height: 100%;
  border-radius: 3px;
  background: #e20074;
  animation: page-loader-slide 1.2s ease-in-out infinite;
  animation-delay: var(--page-loader-delay, 0s);
}

.page-loader-msg {
  max-width: 22rem;
  margin: 0;
  font:
    600 17px/1.4 TeleNeo,
    system-ui,
    -apple-system,
    'Segoe UI',
    Arial,
    sans-serif;
}

.page-loader-retry {
  min-height: 48px;
  padding: 0 28px;
  border: 2px solid #ffffff;
  border-radius: 999px;
  background: transparent;
  color: #ffffff;
  font:
    700 16px TeleNeo,
    system-ui,
    -apple-system,
    'Segoe UI',
    Arial,
    sans-serif;
  cursor: pointer;
}

.page-loader-retry:focus-visible {
  outline: 3px solid #e20074;
  outline-offset: 3px;
}

/* Old browsers (public/compat.js): the campaign name and a message. No gap and no WebP here,
   because those browsers support neither. */
.page-loader-old .page-loader-title {
  margin: 0 0 18px;
  color: #e20074;
  font:
    800 30px/1.15 TeleNeo,
    system-ui,
    -apple-system,
    'Segoe UI',
    Arial,
    sans-serif;
}

/* Read by screen readers, not shown. */
.page-loader-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

@keyframes page-loader-pulse {
  0%,
  100% {
    opacity: 0.55;
    transform: scale(0.97);
  }
  50% {
    opacity: 1;
    transform: scale(1);
  }
}

/* From just left of the bar to just past its right end (the stripe is 40% of the bar). */
@keyframes page-loader-slide {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(250%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .page-loader-logo,
  .page-loader-bar::after {
    animation: none;
  }
  .page-loader-logo {
    opacity: 1;
  }
  .page-loader-bar::after {
    transform: translateX(75%);
  }
}

/* Over the ready page (App.tsx PageLoader cover): on top, then faded out. The fade duration comes
   from the owner's settings and is set by the app. */
.page-loader.is-cover {
  z-index: 1000;
  transition-property: opacity;
  transition-timing-function: ease;
}

.page-loader.is-cover.is-fading {
  opacity: 0;
  pointer-events: none;
}
