/* kentel — snake loader.
 *
 * A venom-green snake coils along its path, then the brand caption fades
 * in beneath it. Shown on every fresh captive page load, and once per
 * session on the dashboards.
 *
 * Uses stroke-dash animation rather than a GIF or sprite: it is a few KB,
 * scales on any screen, and keeps the CSP free of external image sources.
 */
#kentel-loader {
  position: fixed;
  inset: 0;
  z-index: 2000;
  background: var(--void);
  background-image:
    radial-gradient(60% 50% at 50% 30%, rgba(159, 255, 59, 0.07), transparent 70%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  transition: opacity .45s ease, visibility .45s ease;
}
#kentel-loader.is-done {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.snake-wrap { width: 190px; height: 140px; }
.snake-svg { width: 100%; height: 100%; overflow: visible; }

/* The body: a long dash chasing itself along the coil. */
.snake-body {
  fill: none;
  stroke: var(--venom);
  stroke-width: 7;
  stroke-linecap: round;
  stroke-dasharray: 58 320;
  stroke-dashoffset: 380;
  filter: drop-shadow(0 0 7px rgba(159, 255, 59, .55));
  animation: snake-slither 3.0s cubic-bezier(.55, .1, .45, .9) infinite;
}
/* A dimmer trailing segment gives the body some depth. */
.snake-trail {
  fill: none;
  stroke: var(--venom-deep);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-dasharray: 34 344;
  stroke-dashoffset: 398;
  opacity: .5;
  animation: snake-slither 3.0s cubic-bezier(.55, .1, .45, .9) infinite;
}
@keyframes snake-slither {
  0%   { stroke-dashoffset: 380; }
  100% { stroke-dashoffset: 0; }
}

.snake-head {
  fill: var(--venom);
  filter: drop-shadow(0 0 8px rgba(159, 255, 59, .8));
  animation: snake-head-travel 2.6s cubic-bezier(.55, .1, .45, .9) infinite;
  offset-rotate: auto;
}
@keyframes snake-head-travel {
  0%   { opacity: 0; }
  8%   { opacity: 1; }
  92%  { opacity: 1; }
  100% { opacity: 0; }
}

/* Forked tongue flicking out of the head. */
.snake-tongue {
  stroke: var(--danger);
  stroke-width: 2;
  stroke-linecap: round;
  transform-origin: center;
  animation: tongue-flick 1.1s ease-in-out infinite;
}
@keyframes tongue-flick {
  0%, 70%, 100% { opacity: 0; transform: scaleX(.4); }
  80%, 90%      { opacity: 1; transform: scaleX(1); }
}

.snake-eye { fill: var(--void); }

.loader-caption {
  margin-top: 26px;
  text-align: center;
  opacity: 0;
  animation: caption-in .7s ease forwards;
  animation-delay: .5s;
  padding: 0 20px;
}
.loader-caption .credit {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 15px;
  letter-spacing: -.01em;
  color: var(--text);
}
.loader-caption .tagline {
  margin-top: 5px;
  font-size: 13px;
  color: var(--venom);
}
@keyframes caption-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

.loader-bar {
  width: 150px;
  height: 3px;
  margin-top: 24px;
  border-radius: 3px;
  background: var(--line);
  overflow: hidden;
}
.loader-bar > span {
  display: block;
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--venom-deep), var(--venom));
  animation: loader-fill 3.1s cubic-bezier(.4, 0, .2, 1) forwards;
}
@keyframes loader-fill { to { width: 100%; } }

/* Page content starts hidden only while the loader is on screen, so that
   a JS failure cannot leave a permanently blank page — see loader.js. */
.kentel-veiled { opacity: 0; }
.kentel-revealed { animation: veil-lift .45s ease forwards; }
@keyframes veil-lift {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .snake-body, .snake-trail, .snake-head, .snake-tongue, .loader-bar > span {
    animation: none;
  }
  .snake-body { stroke-dashoffset: 0; }
  .snake-trail { stroke-dashoffset: 0; }
  .loader-caption { opacity: 1; animation: none; }
  .loader-bar > span { width: 100%; }
}
