/* IMTB-Loader — die Wortmarke als Ladeanzeige.
 *
 * Quelle: `imtb-loader-integration.html` (Marketing, 01.09.2026). Die
 * Keyframes und Zeiten sind unveraendert uebernommen; ein 4-Sekunden-Lauf,
 * alle Bewegung ueber `transform`, damit der Browser sie auf der Grafikkarte
 * rechnet und kein Layout neu setzt.
 *
 * Die Farben stehen hier als Literale und nicht als `var(--imtb-akzent-rot)`,
 * obwohl `imtb-tokens.css` sie kennt: Diese Datei laedt nur `start.html` und
 * `ueber.html`, das Dashboard nicht. Ein Loader, der ohne seine Tokendatei
 * unsichtbar wird, ist schlimmer als eine doppelt gepflegte Farbe. Die Werte
 * sind dieselben — Nachtblau #3C4058, Akzentrot #E4523B.
 *
 * Drei Auspraegungen:
 *   .imtb-ldr              Wortmarke, Breite ueber `width` am Wrapper
 *   .imtb-ldr--ring        nur die Ringe, quadratisch, in `em` — fuer Knoepfe,
 *                          Abzeichen und Tabellenzeilen
 *   .imtb-ladeschicht      ganzseitige Schicht beim Seitenwechsel
 */

.imtb-ldr {
  --imtb-rings: #E4523B;
  --imtb-typo: #3C4058;
  --imtb-shine: rgba(228, 82, 59, .45);
  width: 220px;
}
.imtb-ldr svg { width: 100%; display: block; overflow: visible; }
.imtb-ldr .ldr-typo { fill: var(--imtb-typo); }
.imtb-ldr .ldr-shine {
  fill: var(--imtb-shine);
  transform: translateX(-340px) skewX(-22deg);
  animation: imtbShine 4s infinite;
}
.imtb-ldr .ldr-rings {
  fill: var(--imtb-rings);
  transform-origin: 318.715px 109.625px;
  animation: imtbSwing 4s infinite;
}
.imtb-ldr .ldr-breath {
  transform-origin: 318.715px 109.625px;
  animation: imtbBreath 4s infinite;
}
.imtb-ldr .ldr-suffix { animation: imtbSuffix 4s infinite; }
.imtb-ldr .ldr-suffix text {
  fill: var(--imtb-rings);
  font: 600 30px "DM Sans", Aptos, "Segoe UI", system-ui, sans-serif;
  letter-spacing: 5px;
}

@keyframes imtbSwing {
  0%     { transform: rotate(0deg);   animation-timing-function: cubic-bezier(.37,0,.63,1); }
  6.25%  { transform: rotate(-10deg); animation-timing-function: cubic-bezier(.65,0,.35,1); }
  27.5%  { transform: rotate(187deg); animation-timing-function: cubic-bezier(.34,1.56,.64,1); }
  35%    { transform: rotate(180deg); }
  50%    { transform: rotate(180deg); animation-timing-function: cubic-bezier(.37,0,.63,1); }
  56.25% { transform: rotate(170deg); animation-timing-function: cubic-bezier(.65,0,.35,1); }
  77.5%  { transform: rotate(367deg); animation-timing-function: cubic-bezier(.34,1.56,.64,1); }
  85%    { transform: rotate(360deg); }
  100%   { transform: rotate(360deg); }
}
@keyframes imtbShine {
  0%, 6.25%   { transform: translateX(-340px) skewX(-22deg); animation-timing-function: cubic-bezier(.45,0,.55,1); }
  28.75%      { transform: translateX(980px) skewX(-22deg); }
  29%, 56.25% { transform: translateX(-340px) skewX(-22deg); animation-timing-function: cubic-bezier(.45,0,.55,1); }
  78.75%      { transform: translateX(980px) skewX(-22deg); }
  79%, 100%   { transform: translateX(-340px) skewX(-22deg); }
}
@keyframes imtbBreath {
  0%, 2.5%      { transform: scale(1); }
  18.75%        { transform: scale(1.018); }
  38.75%, 52.5% { transform: scale(1); }
  68.75%        { transform: scale(1.018); }
  88.75%, 100%  { transform: scale(1); }
}
@keyframes imtbSuffix {
  0%, 12%   { transform: translateY(0); }
  20%       { transform: translateY(-5px); }
  28%, 62%  { transform: translateY(0); }
  70%       { transform: translateY(-5px); }
  78%, 100% { transform: translateY(0); }
}

/* ── Ring-Variante ───────────────────────────────────────────────────────
 * Ersetzt den alten `.spinner`. Groesse in `em`, damit sie der Schriftgroesse
 * der Umgebung folgt; `currentColor` als Vorgabe, damit die Ringe im roten
 * Abzeichen rot und im grauen grau sind — der alte Spinner tat dasselbe.
 * Der Akzent laesst sich mit `--imtb-rings` je Stelle erzwingen. */
.imtb-ldr--ring {
  width: 1.15em;
  display: inline-block;
  vertical-align: -0.22em;
  margin-right: 5px;
  --imtb-rings: currentColor;
}
.imtb-ldr--ring svg { overflow: visible; }
/* `hidden` muss stärker sein als das `display` oben. Ohne diese Zeile
 * gewinnt die Klasse gegen die UA-Regel `[hidden] { display: none }`, und
 * `spinner.hidden = true` im Vorschaufenster täte nichts sichtbar — der
 * frühere `.spinner` hatte denselben blinden Fleck. */
.imtb-ldr[hidden] { display: none; }

/* ── Anzeige fuer htmx ───────────────────────────────────────────────────
 * htmx tauscht ein Stueck der Seite, nicht die Seite. Ein Ring mit
 * `htmx-indicator` bleibt unsichtbar und wird nur eingeblendet, solange die
 * Anfrage laeuft — htmx setzt dafuer `htmx-request`, am ausloesenden Element
 * oder am Ziel aus `hx-indicator`. Beide Faelle deckt die zweite Regel ab.
 *
 * `visibility` statt `display`, damit der Ring seinen Platz behaelt: Ein
 * Knopf, der beim Klick um die Ringbreite waechst, verschiebt die Zeile. */
.imtb-ldr.htmx-indicator {
  opacity: 0; visibility: hidden; transition: opacity .15s ease;
}
.htmx-request .imtb-ldr.htmx-indicator,
.imtb-ldr.htmx-indicator.htmx-request {
  opacity: 1; visibility: visible;
}

/* ── Ganzseitige Ladeschicht ─────────────────────────────────────────────
 * Sie liegt ueber allem, ist aber nur sichtbar, wenn `data-sichtbar` gesetzt
 * ist. Das Einblenden ist verzoegert (`transition-delay`), damit ein schneller
 * Seitenwechsel nicht kurz aufblitzt — sichtbar wird sie erst, wenn das Laden
 * wirklich dauert. Das Ausblenden hat keine Verzoegerung. */
.imtb-ladeschicht {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 22px;
  background: rgba(255, 255, 255, .92);
  backdrop-filter: blur(2px);
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s ease, visibility 0s linear .2s;
}
.imtb-ladeschicht[data-sichtbar] {
  opacity: 1;
  visibility: visible;
  transition: opacity .25s ease .18s, visibility 0s linear .18s;
}
.imtb-ladeschicht .imtb-ldr { width: min(260px, 55vw); }
.imtb-ladeschicht-text {
  font: 500 0.82rem/1.4 "DM Sans", -apple-system, "Segoe UI", sans-serif;
  letter-spacing: .04em;
  color: #82849F;
}
/* Auf dunklem Grund — die Anmeldeseite. */
.imtb-ladeschicht--dunkel { background: rgba(60, 64, 88, .93); }
.imtb-ladeschicht--dunkel .imtb-ldr { --imtb-typo: #F4F3F0; }
.imtb-ladeschicht--dunkel .imtb-ladeschicht-text { color: rgba(244, 243, 240, .7); }

/* Wer Bewegung reduziert haben will, bekommt sie langsamer statt gar nicht:
 * Eine Ladeanzeige, die stillsteht, ist keine — sie sieht aus wie ein Bild
 * und laesst offen, ob ueberhaupt noch etwas passiert. Dieselbe Abwaegung
 * stand schon beim alten `.spinner` in base.html. */
@media (prefers-reduced-motion: reduce) {
  .imtb-ldr .ldr-rings,
  .imtb-ldr .ldr-breath,
  .imtb-ldr .ldr-suffix { animation-duration: 12s; }
  .imtb-ldr .ldr-shine { animation: none; }
  .imtb-ladeschicht,
  .imtb-ladeschicht[data-sichtbar] { transition-duration: 0s; }
}
