/* ============================================================
   HELM nautical loaders — dependency-free CSS + inline SVG
   ------------------------------------------------------------
   Served by the kit at _content/HELM.UiKit/css/helm-loaders.css.
   Link it once in the host (alongside helm-tokens.css), then use
   the <HelmLoader /> component (or drop the raw markup).

   Theme & size with CSS variables on the .helm-loader:
     --hl-size   : rendered box size (default 64px)
     --hl-line   : primary line colour
     --hl-muted  : secondary line colour
     --hl-accent : brand green accent (override per instance if needed)
     --hl-speed  : animation speed multiplier (1 = default)
   Add class .is-dark for the light-on-dark palette.
   Everything scales from --hl-size (used as font-size; all
   internal metrics are in em), so one variable resizes a loader.
   ============================================================ */

.helm-loader {
  --hl-size: 64px;
  --hl-line: #23246b;
  --hl-muted: #a8abca;
  --hl-accent: #4dba7b;
  --hl-speed: 1;

  position: relative;
  display: inline-block;
  width: 1em;
  height: 1em;
  font-size: var(--hl-size,64px);
  line-height: 0;
  vertical-align: middle;
}
.helm-loader.is-dark {
  --hl-line: #ffffff;
  --hl-muted: #9aa0c6;
}

/* SVG sizing. Colours are set inline on each SVG element as
   fill/stroke: var(--hl-line | --hl-muted | --hl-accent)
   with a hardcoded fallback, so they render even with no stylesheet
   and survive CSS-Modules / scoped / shadow-DOM class mangling. */
.helm-loader svg { display: block; width: 100%; }
.helm-loader svg.hl-fill { position: absolute; inset: 0; height: 100%; }

/* Optional brand tile behind any loader (splash screens) */
.helm-loader.has-tile {
  background: linear-gradient(#3a3b76, #1f2065);
  border-radius: 0.22em;
  overflow: hidden;
}

/* ---- HELM · ship's wheel (hand-steering) ------------------ */
.helm-loader--wheel .hl-spin {
  position: absolute; inset: 0;
  animation: hl-steer calc(7s / var(--hl-speed,1)) ease-in-out infinite;
}
.helm-loader--wheel .hl-hub {
  position: absolute; left: 43.5%; top: 43.5%;
  width: 13%; height: 13%; border-radius: 50%;
  background: var(--hl-accent,#4dba7b);
  box-shadow: 0 0 0.14em 0.03em rgba(77,186,123,.5);
  animation: hl-hub calc(2.2s / var(--hl-speed,1)) ease-in-out infinite;
}

/* ---- Compass · settling needle ---------------------------- */
.helm-loader--compass .hl-needle {
  position: absolute; inset: 0;
  animation: hl-compass calc(3.6s / var(--hl-speed,1)) cubic-bezier(.5,0,.2,1) infinite;
}

/* ---- Setting sail · boat + water -------------------------- */
.helm-loader--sail { overflow: hidden; }
.helm-loader--sail .hl-boat {
  position: absolute; top: 16%; left: 50%; width: 56%; margin-left: -28%;
  animation: hl-bob calc(3s / var(--hl-speed,1)) ease-in-out infinite;
}

/* ---- Chart · plotting the course -------------------------- */
.helm-loader--chart .hl-star {
  position: absolute; top: 18%; right: 14%; width: 20%;
  animation: hl-twinkle calc(2.4s / var(--hl-speed,1)) ease-in-out infinite;
}
.helm-loader--chart .hl-travel {
  position: absolute; top: 29%; left: 32%;
  width: 7.2%; height: 7.2%; border-radius: 50%;
  background: var(--hl-accent,#4dba7b);
  box-shadow: 0 0 0.13em 0.03em rgba(77,186,123,.5);
  animation: hl-travel calc(2.8s / var(--hl-speed,1)) cubic-bezier(.45,0,.55,1) infinite;
}

/* ---- Atlas · orbiting locator ----------------------------- */
.helm-loader--atlas .hl-orbit {
  position: absolute; left: 50%; top: 50%;
  width: 7.2%; height: 7.2%; margin: -3.6% 0 0 -3.6%; border-radius: 50%;
  background: var(--hl-accent,#4dba7b);
  box-shadow: 0 0 0.13em 0.03em rgba(77,186,123,.5);
  animation:
    hl-orbit calc(4s / var(--hl-speed,1)) linear infinite,
    hl-fade  calc(4s / var(--hl-speed,1)) ease-in-out infinite;
}

/* ---- Wake · ship-wake signal ------------------------------ */
.helm-loader--wake { overflow: hidden; }
.helm-loader--wake .hl-shield {
  position: absolute; top: 16%; left: 50%; width: 19%; margin-left: -9.5%;
  animation: hl-shield calc(2.1s / var(--hl-speed,1)) ease-in-out infinite;
}
.helm-loader--wake .hl-chev {
  position: absolute; top: 42%; left: 50%; width: 26%; margin-left: -13%;
  animation: hl-emit calc(2.1s / var(--hl-speed,1)) ease-out infinite;
}
.helm-loader--wake .hl-chev--2 { animation-delay: calc(0.7s / var(--hl-speed,1)); }
.helm-loader--wake .hl-chev--3 { animation-delay: calc(1.4s / var(--hl-speed,1)); }

/* ---- Wave · flowing tide ---------------------------------- */
.helm-loader--wave { overflow: hidden; }

/* Shared scrolling wave layers (sail water + wave hero) */
.helm-loader .hl-w1,
.helm-loader .hl-w2,
.helm-loader .hl-w3 { position: absolute; left: 0; width: 200%; height: 14%; }
.helm-loader .hl-w1 svg,
.helm-loader .hl-w2 svg,
.helm-loader .hl-w3 svg { height: 100%; }
.helm-loader .hl-w1 { animation: hl-wave calc(3.4s / var(--hl-speed,1)) linear infinite; }
.helm-loader .hl-w2 { animation: hl-wave calc(2.6s / var(--hl-speed,1)) linear infinite reverse; }
.helm-loader .hl-w3 { animation: hl-wave calc(4.2s / var(--hl-speed,1)) linear infinite; }

.helm-loader--sail .hl-w1 { bottom: 20%; }
.helm-loader--sail .hl-w2 { bottom: 10.5%; }
.helm-loader--sail .hl-w3 { bottom: 1%; }

.helm-loader--wave .hl-w1 { top: 39%; }
.helm-loader--wave .hl-w2 { top: 49%; }
.helm-loader--wave .hl-w3 { top: 59%; }

/* ---- Range · radar sweep ---------------------------------- */
.helm-loader--range .hl-sweep-clip {
  position: absolute; top: 19%; left: 19%; width: 62%; height: 62%;
  border-radius: 50%; overflow: hidden;
}
.helm-loader--range .hl-sweep {
  display: block; width: 100%; height: 100%;
  background: conic-gradient(
    from 0deg,
    rgba(77,186,123,.5),
    rgba(77,186,123,0) 70deg,
    transparent 360deg);
  animation: hl-sweep calc(2.8s / var(--hl-speed,1)) linear infinite;
}
.helm-loader--range .hl-blip {
  position: absolute; top: 30%; left: 62%;
  width: 6.7%; height: 6.7%; border-radius: 50%;
  background: var(--hl-accent,#4dba7b);
  box-shadow: 0 0 0.13em 0.03em rgba(77,186,123,.6);
  animation: hl-blip calc(2.8s / var(--hl-speed,1)) ease-in-out infinite;
}

/* ---- Sonar · sounding the depths -------------------------- */
.helm-loader--sonar { overflow: hidden; }
.helm-loader--sonar .hl-scene {
  position: absolute; inset: 0;
  animation: hl-sonar-bob calc(3s / var(--hl-speed,1)) ease-in-out infinite;
}
.helm-loader--sonar .hl-ping {
  position: absolute; inset: 0;
  transform-origin: 50% 28.5%;
  animation: hl-sonar-ping calc(3s / var(--hl-speed,1)) ease-out infinite;
}
.helm-loader--sonar .hl-ping--2 { animation-delay: calc(1s / var(--hl-speed,1)); }
.helm-loader--sonar .hl-ping--3 { animation-delay: calc(2s / var(--hl-speed,1)); }
.helm-loader--sonar .hl-target {
  position: absolute; top: 70%; left: 50%;
  width: 7.7%; height: 7.7%; margin-left: -3.85%; border-radius: 50%;
  background: var(--hl-accent,#4dba7b);
  box-shadow: 0 0 0.13em 0.03em rgba(77,186,123,.55);
  animation: hl-sonar-blip calc(3s / var(--hl-speed,1)) ease-in-out infinite;
}

/* ============================ keyframes ===================== */
@keyframes hl-sonar-ping { 0% { transform: scale(.2); opacity: 0; } 18% { opacity: 1; } 72% { opacity: .8; } 100% { transform: scale(1.18); opacity: 0; } }
@keyframes hl-sonar-blip { 0%,52% { transform: scale(.72); opacity: .3; } 68% { transform: scale(1.32); opacity: 1; } 100% { transform: scale(.72); opacity: .3; } }
@keyframes hl-sonar-bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-1.7%); } }
@keyframes hl-steer {
  0%   { transform: rotate(0deg); }
  12%  { transform: rotate(116deg); }
  24%  { transform: rotate(72deg); }
  37%  { transform: rotate(196deg); }
  50%  { transform: rotate(150deg); }
  63%  { transform: rotate(44deg); }
  76%  { transform: rotate(98deg); }
  88%  { transform: rotate(16deg); }
  100% { transform: rotate(0deg); }
}
@keyframes hl-hub { 0%,100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.16); opacity: .82; } }
@keyframes hl-compass {
  0% { transform: rotate(0deg); } 12% { transform: rotate(190deg); } 22% { transform: rotate(168deg); }
  30% { transform: rotate(180deg); } 60% { transform: rotate(180deg); } 72% { transform: rotate(415deg); }
  82% { transform: rotate(355deg); } 90%,100% { transform: rotate(360deg); }
}
@keyframes hl-wave { to { transform: translateX(-50%); } }
@keyframes hl-bob { 0%,100% { transform: translateY(0) rotate(-2deg); } 50% { transform: translateY(-0.04em) rotate(2deg); } }
@keyframes hl-twinkle { 0%,100% { transform: scale(.82); opacity: .55; } 50% { transform: scale(1.1); opacity: 1; } }
@keyframes hl-travel {
  0% { transform: translate(0,0); opacity: 0; } 12% { opacity: 1; }
  86% { opacity: 1; } 100% { transform: translate(0.39em, 0.43em); opacity: 0; }
}
@keyframes hl-orbit {
  0%    { transform: translate(0.28em, 0); }
  12.5% { transform: translate(0.198em, 0.064em); }
  25%   { transform: translate(0, 0.09em); }
  37.5% { transform: translate(-0.198em, 0.064em); }
  50%   { transform: translate(-0.28em, 0); }
  62.5% { transform: translate(-0.198em, -0.064em); }
  75%   { transform: translate(0, -0.09em); }
  87.5% { transform: translate(0.198em, -0.064em); }
  100%  { transform: translate(0.28em, 0); }
}
@keyframes hl-fade { 0%,50% { opacity: 1; } 70%,82% { opacity: .2; } 100% { opacity: 1; } }
@keyframes hl-emit {
  0%   { transform: translateY(-0.01em) scaleX(.28); opacity: 0; }
  24%  { opacity: .95; }
  100% { transform: translateY(0.29em) scaleX(1.9); opacity: 0; }
}
@keyframes hl-shield { 0%,100% { transform: scale(1); } 50% { transform: scale(1.16); } }
@keyframes hl-sweep { to { transform: rotate(360deg); } }
@keyframes hl-blip { 0%,100% { transform: scale(.78); opacity: .3; } 50% { transform: scale(1.18); opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .helm-loader * { animation-duration: 0.001s !important; animation-iteration-count: 1 !important; }
}
