/* Minimal ambient motion: a handful of tiny dots, each with a soft glow,
   fading in and out on its own random schedule - like distant stars quietly
   lighting up. Confined to the body area only (JS narrows top/bottom to sit
   below the header and above the footer). Sits behind all real content
   (negative z-index on a fixed layer), never intercepts clicks, and is
   inert under prefers-reduced-motion. */

/* Not starfield-specific, but this is the one stylesheet every real page on
   the site already links, so it's the simplest place for a true global rule.
   Without it, Android Chrome paints its default blue tap-highlight as a
   sharp rectangle on tap - ignoring any border-radius the button/chip/card
   actually has - for the brief moment before the tap navigates or fires its
   handler. iOS Safari doesn't have this default, which is why it only shows
   up on Android. */
* {
  -webkit-tap-highlight-color: transparent;
}

.kd-starfield {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}

.kd-star {
  position: absolute;
  border-radius: 50%;
  background: #cdcdcd;
  box-shadow: 0 0 var(--kd-star-glow, 4px) 0 rgba(205, 205, 205, 0.55);
  opacity: 0;
  animation-name: kd-star-twinkle;
  animation-timing-function: cubic-bezier(0.45, 0, 0.55, 1);
  animation-iteration-count: infinite;
}

/* A minority of stars render crisp and bright instead of soft, for variety. */
.kd-star-sharp {
  background: #ffffff;
  box-shadow: 0 0 var(--kd-star-glow, 6px) 0 rgba(255, 255, 255, 0.9);
}

@keyframes kd-star-twinkle {
  0%, 100% { opacity: 0; }
  50% { opacity: var(--kd-star-opacity, 0.7); }
}

@media (prefers-reduced-motion: reduce) {
  .kd-star {
    animation: none;
    opacity: 0.25;
  }
}

/* ===== SHOOTING STARS (win celebration burst) =====
   Spawned into this same #kd-starfield layer by Starfield.js's
   window.KDShootingStars.burst() - see its own comment for when this fires.
   The element itself is the trailing streak (a thin gradient line, width =
   trail length - same 1px weight as a .kd-star dot, not a fat glowing bar);
   ::after is the head, sized and lit like a .kd-star-sharp dot, just
   fractionally brighter. transform-origin: left means rotating +
   translating along X moves the whole streak in a straight line at
   --kd-shoot-angle - any angle, not just a diagonal band (see
   Starfield.js's burst()).

   The head sits at the RIGHT edge (local x=100%), not the left - since
   translateX moves the element's origin (its left edge) forward, the right
   edge is always further along the direction of travel than the left edge,
   at every instant. Putting the head there (gradient fading from
   transparent-at-left/tail to bright-at-right/head) makes it genuinely
   lead the motion, trailing a fading streak behind it - a head at the LEFT
   edge (the previous bug) instead moves toward its own trail, since the
   trail's fading end sits further along the travel direction than the
   head does, reading as a flat line sliding along itself rather than a
   point cutting through space. */
.kd-shooting-star {
  position: absolute;
  left: 0;
  top: 0;
  height: 1px;
  border-radius: 999px;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.42));
  transform-origin: left center;
  opacity: 0;
  animation-name: kd-shooting-star-fly;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}

.kd-shooting-star::after {
  content: '';
  position: absolute;
  left: calc(100% - 0.6px);
  top: 50%;
  width: 1.2px;
  height: 1.2px;
  transform: translateY(-50%);
  background: #ffffff;
  border-radius: 50%;
  box-shadow: 0 0 4px 0 rgba(255, 255, 255, 0.7);
}

/* The head reaches its full travel distance by the 55% mark, then holds
   there while opacity keeps fading out through 100% - so the point visibly
   moves, then the streak it left behind lingers and dissolves in place,
   rather than the whole thing vanishing the instant it stops moving. Total
   duration (Starfield.js's flightMs) is ~3s, matching that lingering
   fade.

   A keyframe's own animation-timing-function shapes the segment FROM that
   stop onward, so setting it on the 0% and 55% stops (instead of leaving
   the base linear easing from the class rule) eases both the appear/fly
   segment and the fade-out segment, so the star eases in and dissolves out
   gradually instead of ramping at a constant rate. */
@keyframes kd-shooting-star-fly {
  0% { opacity: 0; transform: rotate(var(--kd-shoot-angle)) translateX(0); animation-timing-function: ease; }
  18% { opacity: 1; }
  55% { opacity: 1; transform: rotate(var(--kd-shoot-angle)) translateX(var(--kd-shoot-dist)); animation-timing-function: ease; }
  100% { opacity: 0; transform: rotate(var(--kd-shoot-angle)) translateX(var(--kd-shoot-dist)); }
}

@media (prefers-reduced-motion: reduce) {
  .kd-shooting-star { display: none; }
}

/* ===== BLOCKED-USER MODAL (Admin Panel Section 6 "Block this user") =====
   Built by HeaderC-D.js right after login, on any page - a blocked visitor
   can sign in and browse, but sees this every time until they're unblocked. */
.kd-blocked-overlay {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 600;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.8);
  padding: 20px;
}

.kd-blocked-overlay.is-open {
  display: flex;
}

.kd-blocked-box {
  border: 2px solid #5c2b2b;
  background: #0a0a0a;
  max-width: 420px;
  width: 100%;
  padding: 28px 24px;
  text-align: center;
}

.kd-blocked-title {
  color: #ff4d4d;
  font-weight: 800;
  font-size: 20px;
  margin: 0 0 14px;
}

.kd-blocked-line {
  color: #cdcdcd;
  font-size: 14px;
  line-height: 1.5;
  margin: 0 0 10px;
}

.kd-blocked-warn {
  color: #ff4d4d;
  font-size: 13px;
  line-height: 1.5;
  margin: 0 0 18px;
}

.kd-blocked-close {
  border: 2px solid #00ff92;
  background: transparent;
  color: #00ff92;
  font-weight: 800;
  font-size: 14px;
  padding: 8px 24px;
  cursor: pointer;
}
