/* ── FOOTER ── */
/* Spaltenstruktur exakt wie .body → Button steht axial unter dem Bild */
/* Der Zwischenraum ist so gewaehlt, dass der Knopf oben zum Bild denselben
   Abstand hat wie unten zum Fensterrand. Unten stehen fest 46 px — aus
   dem Seitenrand (28), der Hoehe des Knopfblocks (54) und dessen
   Verschiebung nach oben (18), abzueglich Zaehler und Knopf (22 + 32).
   Oben ergibt sich der Abstand aus diesem Polster minus derselben 18 plus
   den 22 ueber dem Knopf, also 42 - 18 + 22 = 46. Der Knopf bleibt dabei
   stehen: was der Fuss oben zulegt, gibt das Bild ab.               */
footer {
  display: grid;
  grid-template-columns: var(--sw) 1fr var(--sw);
  align-items: center;
  padding: calc(var(--pad) + 14px) 0 0;
}
.f-status {
  opacity: 0;
  font-size: var(--t-status-groesse);
  font-weight: var(--t-status-gewicht);
  letter-spacing: var(--t-status-sperrung);
  padding-left: var(--t-status-sperrung); /* mittig gesetzt: die Sperrung ausgleichen */
  text-transform: uppercase;
  color: var(--mid);
  transition: opacity 0.3s;
  pointer-events: none;
  white-space: nowrap;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 16px;
  text-align: center;
  z-index: 50;
}
/* Über dem Hauptbild (#out-img, z-index 6): sonst lägen die Sterne über
   dem Knopf dahinter (V3). */
.gen-wrap {
  position: relative;
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-self: center;
  grid-column: 2;
  gap: 0;
  transform: translateY(-18px);
}
.gen-progress {
  width: 100%;
  height: 1px;
  background: transparent;
  overflow: hidden;
  opacity: 0;
}
.gen-progress.on {
  opacity: 1;
}
.gen-progress-fill {
  height: 100%;
  width: 0;
  background: var(--black);
}
@keyframes _progSteady {
  from {
    width: 0;
  }
  to {
    width: 88%;
  }
}
.gen-progress.on .gen-progress-fill {
  animation: _progSteady 180s linear forwards;
}
.gen-btn {
  font-family: var(--serif);
  font-size: 18px;
  font-weight: 400;
  font-style: italic;
  letter-spacing: 0.04em;
  color: var(--white);
  background: var(--black);
  border: none;
  cursor: pointer;
  padding: 0 26px;
  height: 32px;
  display: flex;
  align-items: center;
  white-space: nowrap;
  transition: opacity 0.15s;
  position: relative;
  overflow: hidden;
}
/* Unter der Hand graut der Knopf auf — nur der FREIE, per filter und am
   Rahmen der Wendekarte (V3, 25.09.2026): die Deckung gehört dem Ein- und
   Ausblenden des ganzen Knopfes, und der gesperrte Knopf lässt den Zeiger
   durch — die Karte behält ihn, so graut er im selben Bild auf, in dem er
   schwarz wird. Nicht grau wird er, wenn er schon angenommen ist oder geht
   (pointer-events: none) und während eines Auftrags (gesperrt). */
.gen-flip:hover > .gen-btn:not(:disabled):not([style*='pointer-events: none']) {
  filter: opacity(0.75);
}
/* Der Generieren-Knopf bleibt im Loeschmodus unberuehrt — das Loeschen
   sitzt jetzt vollstaendig im Knopf am rechten Ende der Bildleiste.
   Zwischen Schwarz und Schraffur wechselt er in EINEM Bild (Prototyp V3,
   Zeilen 3115–3121): ein Farbuebergang liesse unter den Linien eine
   halbdurchsichtige graue Flaeche aufblitzen. Weich bleibt nur das Ein-
   und Ausblenden des ganzen Knopfes. */
.gen-btn {
  transition: opacity 0.15s;
}
/* Der Uebergang vom schwarzen Abonnieren- in den ausgegrauten Generieren-
   Knopf. Die Grundregel blendet in 0,15 s — das waere ein Umschalten.
   Die Klasse gilt nur fuer diesen einen Wechsel und faellt danach wieder
   weg. Der Weg zurueck aus der letzten Zappel-Auslenkung laeuft mit,
   sonst spraenge der Knopf in dem Moment an seinen Platz.           */
.gen-btn.weich-aus {
  transition:
    opacity 0.9s ease,
    transform 0.55s ease !important;
}
/* Gesperrt: Schraffur statt halber Deckung (components/hatch.css) */
/* Ein ausgeschalteter Knopf gibt in Chrome keine Mausereignisse mehr her —
   auch kein Doppelklick kaeme an. Waehrend eines Auftrags ist er genau
   das: ausgeschaltet. Er laesst die Ereignisse darum durch, und die
   Wendekarte unter ihm faengt sie auf.                              */
.gen-btn:disabled {
  pointer-events: none;
}
.gen-btn canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* ── DIE WENDEKARTE UM DEN GENERIEREN-KNOPF ─────────────────────
   Solange gerechnet wird, ist der Knopf schwarz und zappelt. Ein Doppel-
   klick dreht ihn um die waagerechte Achse — dieselbe Bewegung wie bei
   einem Bild in der Historie — und bringt ihn dabei zur Ruhe: was man
   abbrechen will, soll stillhalten. Auf der Rueckseite steht nur das
   weisse Kreuz auf dem Rot, das in dieser App immer das Wegnehmen
   bedeutet.
   Die Perspektive steht in der Transformation selbst und nicht am
   Elternelement: .gen-wrap wuerde sonst zum Bezugsrahmen fuer alles,
   was darin absolut sitzt.                                         */
.gen-flip {
  position: relative;
  transform-style: preserve-3d;
  transition: transform 0.5s cubic-bezier(0.4, 0, 0.3, 1);
}
.gen-flip.gedreht {
  transform: perspective(680px) rotateX(180deg);
}
.gen-flip #gen-btn {
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.gen-rueck {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #e8391c;
  color: #fff;
  transform: rotateX(180deg) translateZ(1px);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  /* Das Rot faengt nichts ab: was hier ankommt, gehoert der Karte und
     wendet sie zurueck. Nur das Kreuz in der Mitte hoert selbst zu.  */
  pointer-events: none;
}
/* Beide Seiten liegen sonst genau aufeinander, und welche der Browser
   dann vorn zeichnet, ist nicht gesagt — die Zahl des Zaehlers stand
   deshalb ueber dem Kreuz. Zwei Mittel dagegen: jede Seite steht einen
   Pixel vor ihrer eigenen Ebene (translateZ), und auf halber Drehung
   wird die abgewandte Seite ausdruecklich unsichtbar. Der Verzug von
   0,25 s ist die halbe Wendezeit — dort steht die Karte auf der Kante
   und man sieht den Wechsel nicht.                                  */
.gen-flip #gen-btn {
  transform: translateZ(1px);
  transition: visibility 0s 0.25s;
}
.gen-flip.gedreht #gen-btn {
  visibility: hidden;
}
.gen-rueck {
  visibility: hidden;
  transition: visibility 0s 0.25s;
}
.gen-flip.gedreht .gen-rueck {
  visibility: visible;
}
/* Das Kreuz selbst: nur so gross wie sein Feld, damit ringsum Rot bleibt,
   auf das man doppelklicken kann. Beim Ueberfahren wird der Strich
   deutlich dicker — mehr Rueckmeldung braucht es nicht.             */
.gen-x {
  width: 34px;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  color: inherit;
  cursor: pointer;
  pointer-events: none;
}
.gen-flip.gedreht .gen-x {
  pointer-events: auto;
}
.gen-x svg {
  display: block;
}
.gen-x svg path {
  stroke-width: 1.5;
  transition: stroke-width 0.13s;
}
.gen-x:hover svg path {
  stroke-width: 2.9;
}
/* Vom Klick an blinkt das Kreuz, und es hoert erst auf, wenn der Auftrag
   wirklich abgelegt ist — bei ComfyUI wie in der App.               */
@keyframes gen-x-blink {
  50% {
    opacity: 0.14;
  }
}
.gen-x.blinkt svg {
  animation: gen-x-blink 0.62s step-end infinite;
  opacity: 1;
}

/* ── Login-Feuerwerk ── */
@keyframes _fw {
  0% {
    transform: translate(-50%, -50%) translate(0, 0) scale(1);
    opacity: 1;
  }
  100% {
    transform: translate(-50%, -50%) translate(var(--fx), var(--fy)) scale(0);
    opacity: 0;
  }
}
/* Cursor-Blinken im Login-Button */
@keyframes _cursor-blink {
  50% {
    opacity: 0;
  }
}

/* ── Button-Animationen (CSS) ── */
@keyframes _btn-shake {
  0%,
  100% {
    transform: translate(0, 0) rotate(0deg);
  }
  10% {
    transform: translate(-6px, -1px) rotate(-1deg);
  }
  20% {
    transform: translate(6px, 1px) rotate(1deg);
  }
  30% {
    transform: translate(-6px, 1px) rotate(-1deg);
  }
  40% {
    transform: translate(6px, -1px) rotate(1deg);
  }
  50% {
    transform: translate(-4px, 0) rotate(-0.5deg);
  }
  60% {
    transform: translate(4px, 0) rotate(0.5deg);
  }
  70% {
    transform: translate(-3px, -1px) rotate(-0.5deg);
  }
  80% {
    transform: translate(3px, 1px) rotate(0.5deg);
  }
  90% {
    transform: translate(-1px, 0) rotate(0);
  }
}
@keyframes _btn-bounce {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-5px);
  }
}
@keyframes _btn-wave {
  0%,
  100% {
    transform: skewX(0);
  }
  25% {
    transform: skewX(-4deg);
  }
  75% {
    transform: skewX(4deg);
  }
}
@keyframes _btn-breathe {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.05);
  }
}
@keyframes _btn-wobble {
  0%,
  100% {
    transform: translate(0, 0) rotate(0);
  }
  30% {
    transform: translate(-3px, 0) rotate(-1.5deg);
  }
  70% {
    transform: translate(3px, 0) rotate(1.5deg);
  }
}
@keyframes _btn-stir {
  0%,
  100% {
    transform: rotate(0);
  }
  25% {
    transform: rotate(-6deg);
  }
  75% {
    transform: rotate(6deg);
  }
}
@keyframes _btn-pulse {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.5);
  }
  50% {
    box-shadow: 0 0 0 8px rgba(255, 255, 255, 0);
  }
}

.gen-btn.anim-shake {
  animation: _btn-shake 0.28s ease-in-out infinite;
}
.gen-btn.anim-bounce {
  animation: _btn-bounce 0.55s ease-in-out infinite;
}
.gen-btn.anim-wave {
  animation: _btn-wave 0.7s ease-in-out infinite;
}
.gen-btn.anim-breathe {
  animation: _btn-breathe 1.6s ease-in-out infinite;
}
.gen-btn.anim-wobble {
  animation: _btn-wobble 0.45s ease-in-out infinite;
}
.gen-btn.anim-stir {
  animation: _btn-stir 0.6s ease-in-out infinite;
}
.gen-btn.anim-pulse {
  animation: _btn-pulse 1.2s ease-in-out infinite;
}
.f-right {
  display: none;
}
.copy-btn {
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mid);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  transition: color 0.15s;
}
.copy-btn:hover {
  color: var(--black);
}

/* ── EDGE HINTS ── */
.edge-hint {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
  z-index: 150;
  display: flex;
  align-items: center;
  gap: 10px;
  pointer-events: none;
  font-family: var(--serif);
  font-size: 21px;
  font-weight: 400;
  font-style: italic;
  letter-spacing: 0.04em;
  color: var(--black);
  /* Feste Zeilenhoehe: CJK-Schriften bringen von sich aus eine groessere
     mit, und dann waechst der Kasten und der Text verschiebt sich gegen
     das Dreieck. Mit 1 bleibt das Verhaeltnis in jeder Sprache gleich. */
  line-height: 1;
  transition: opacity 0.2s;
}
/* Das Dreieck war ein Schriftzeichen (U+25B6 bzw. U+25C0). EB Garamond
   hat es nicht, also sucht der Browser eine Ersatzschrift — und WELCHE,
   haengt am lang-Attribut. Zwischen Japanisch, Chinesisch und Koreanisch
   sind das drei verschiedene Schriften mit drei verschiedenen Groessen
   fuer dasselbe Zeichen, in CJK-Schriften oft geviertbreit. Daher das
   Springen. Als Form gezeichnet ist das Dreieck in jeder Sprache gleich
   gross und haengt an gar keiner Schrift mehr.
   Das Mass kommt vom Zeichen: bei 32 px druckte es eine Flaeche von
   23 x 25 px — die gezeichnete Form war mit 15 x 18 px deutlich kleiner
   geraten. Jetzt steht sie darueber, 26 x 28 px, und behaelt dabei das
   Verhaeltnis des Zeichens (etwas hoeher als breit).                 */
.edge-hint .eh-arrow {
  width: 26px;
  height: 28px;
  background: currentColor;
  flex: 0 0 auto;
  line-height: 1;
  font-style: normal;
}
.edge-hint-left .eh-arrow {
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}
.edge-hint-right .eh-arrow {
  clip-path: polygon(100% 0, 0 50%, 100% 100%);
}
.edge-hint-left {
  left: 4px;
}
/* Rechts: tiefer, an Mitte des Noise-Bildes ausgerichtet (per JS gesetzt) */
.edge-hint-right {
  right: 4px;
}

.btn-count {
  position: relative;
  z-index: 2;
  pointer-events: none;
}
