/* Login/Editor-Konsole fuer das Bearbeiten direkt auf der echten Seite (kein separates
   bearbeiten.html mehr - "Die App oeffnet dieselbe Webseite in einem Bearbeiten-Modus").
   Bewusst neutral (schwarz/weiss/grau), unabhaengig von Kundenfarben, wie auth.css.

   Design (siehe DESIGN.md, "Die schwebende Konsole"): EIN schwebendes Element an EINER
   Stelle (unten mittig, wie .es-leiste), das zwischen zwei Zustaenden umschaltet - Login-
   Formular ODER Bearbeiten-Leiste - statt zwei getrennter Kaesten an zwei Stellen.

   .cms-console       = transparenter Positionierungs-Rahmen (immer an derselben Stelle)
   .cms-console-login = die dunkle, gross abgerundete Box fuer das Anmelde-Formular
   .cms-console-app   = die Pillenform fuer die Bearbeiten-Leiste (editor-shell.js baut
                         seine Knoepfe per options.container direkt HIER hinein) */

/* Die Konsole ist eine feste, unsichtbare SCHICHT ueber der ganzen Seite - sie bewegt sich nie.
   Ihre beiden Kinder sitzen fest an ihrem eigenen Platz (Karte = Bildschirmmitte, Leiste = unten).

   Warum das der Kern ist: frueher war die Konsole selbst der Kasten, und sie sass MAL unten
   (Leiste) und MAL mittig (Login). Dieser Ankerwechsel passiert genau dann, wenn auth.js die
   Zustaende umlegt - also WAEHREND die Konsole noch sichtbar ist (sie faded ja aus). Egal ob man
   den Wechsel animierte (dann flog sie) oder hart springen liess (dann zuckte sie): man sah ihn
   immer. Ein Element, das nie umzieht, kann man auch nicht umziehen sehen. Damit ist die ganze
   Fehlerklasse weg, unabhaengig davon, in welcher Reihenfolge auth.js seine Zustaende setzt.

   pointer-events:none, damit die unsichtbare Schicht keine Klicks auf der Kundenseite abfaengt -
   nur ihre Kinder nehmen Klicks an (siehe unten). Der gedimmte Hintergrund liegt als eigenes
   Geschwister darunter und bleibt anklickbar (Klick daneben schliesst). */
.cms-console {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 2147483000; /* wie .es-leiste - moeglichst weit oben, ueber allem auf der Seite */
  font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* Weicher Auftritt statt hartem hidden-Sprung (siehe Design-Kritik: "poppt auf" wirkte
     unfertig). transition-behavior:allow-discrete + @starting-style animieren display/
     [hidden] selbst mit - auf Browsern ohne Unterstuetzung (aeltere Safari/Firefox) faellt
     es unauffaellig auf den alten Sofort-Sprung zurueck, keine Funktionseinbusse.

     Die Konsole selbst bewegt sich nie - sie faded nur. Die Bewegung liegt allein bei den Kindern
     (die Karte taucht auf, siehe .cms-console-login; die Leiste steigt, siehe .cms-console-app). */
  opacity: 1;
  transition: opacity 0.25s cubic-bezier(0.25, 1, 0.5, 1),
              display 0.2s allow-discrete;

  /* Beide Kinder liegen im SELBEN Grid-Feld (grid-area unten), damit sie beim Anmelden/Abmelden
     UEBERLAPPEN statt sich im Fluss zu stapeln - jedes sitzt aber an seinem EIGENEN Platz in
     diesem Feld (place-self unten), nicht an einem gemeinsamen Ankerpunkt. */
  display: grid;
}
.cms-console-login,
.cms-console-app {
  grid-area: 1 / 1;
  pointer-events: auto; /* die Schicht drumherum ist durchlaessig, die Bedienelemente nicht */
}
/* BEIDE unten mittig, DERSELBE Platz (23.07.2026 ueberarbeitet - vorher stand die Karte in der
   Bildschirmmitte, per Vollbild-Abdunklung). Das widersprach dem eigenen Produktprinzip
   ("bleibt klein und im Hintergrund, bis man es aktiv nutzt", PRODUCT.md) im einzigen Moment,
   der es am woertlichsten haette einloesen muessen: ein bildschirmfuellendes Modal ist das
   dominanteste Element der ganzen Seite, ausgerechnet als Login. Jetzt ist die Karte dasselbe
   kleine Instrument wie die Leiste, nur im Anmelden-Zustand - keiner weiss etwas vom anderen,
   es gibt keinen gemeinsamen Anker, der wechseln koennte, aber beide teilen denselben Platz. */
.cms-console-login,
.cms-console-app { place-self: end center; margin-bottom: 1.25rem; }
.cms-console[hidden] {
  display: none;
  opacity: 0;
  /* Auch hier ease-IN, und das ist der entscheidende Punkt: Die Deckkraft der Konsole
     MULTIPLIZIERT sich auf die ihrer Kinder. Bliebe sie auf ease-out (vorne steil), waere der
     Balken schon fast unsichtbar, bevor sein eigenes Zusammenziehen anfaengt - der Fix an der
     Leiste liefe ins Leere. Alle drei Ebenen (Konsole, Karte, Leiste) muessen beim Abgang
     dieselbe Kurve fahren, sonst frisst die aeusserste die inneren. */
  transition: opacity 0.22s ease-in,
              display 0.24s allow-discrete;
}
@starting-style {
  .cms-console:not([hidden]) { opacity: 0; }
}

/* (Hier stand ein ganzer Block, der die Konsole je nach Zustand umpositionierte - erst abhaengig
   von der Login-Box, dann von der Leiste. Beides war eine Behandlung des Symptoms: solange EIN
   Element mal unten und mal mittig sitzt, sieht man den Wechsel. Ersatzlos entfallen, seit jedes
   Kind seinen eigenen festen Platz hat (place-self oben). Der Umzug findet nicht mehr statt,
   also muss er auch nicht mehr kaschiert werden.) */

/* UNSICHTBARE Klickflaeche. Liegt als GESCHWISTER der Konsole im HTML, deckt den ganzen
   Bildschirm ab, damit "irgendwo daneben klicken" die Login-Box schliesst - aber sie dimmt die
   Seite NICHT mehr (23.07.2026 entfernt). Ein abgedunkelter Hintergrund ist die Sprache eines
   Modals, das die Seite blockiert; dieses Werkzeug soll "klein und im Hintergrund" bleiben
   (PRODUCT.md) und nie wie ein Overlay wirken, das sich über das Produkt legt. Der eigentliche
   Ausstieg ist jetzt der Schliessen-Knopf in der Titelzeile (.cms-console-close, auth.js) -
   die Klickflaeche bleibt nur als bequeme Zusatzgeste. */
.cms-backdrop {
  position: fixed;
  inset: 0;
  z-index: 2147482999; /* knapp unter der Konsole */
  background: transparent;
  /* Faded mit, statt hart umzuschalten: das display:none/block ohne Uebergang war ein harter
     Schnitt - die halbe "billige" Anmutung des Auftritts. Gleiche allow-discrete-Technik wie
     ueberall hier, damit display mitanimiert. */
  display: none;
  opacity: 0;
  transition: opacity 0.2s ease, display 0.2s allow-discrete;
}
body:has(.cms-console:not([hidden]) .cms-console-login:not([hidden])) .cms-backdrop {
  display: block;
  opacity: 1;
}
@starting-style {
  body:has(.cms-console:not([hidden]) .cms-console-login:not([hidden])) .cms-backdrop { opacity: 0; }
}

.cms-console-login {
  background: #141414; /* EINE Konsolen-Flaeche - identisch mit .cms-console-app (Leiste) */
  /* KEIN Rahmen (23.07.2026 entfernt) - .cms-console-app hat nie einen getragen, obwohl beide
     laut DESIGN.md "EINE Konsolen-Flaeche" sind. #2b2b2b auf #141414 ist genau der Grauton, den
     das System an anderer Stelle bewusst ablehnt (siehe .cms-console .ga-input, "Rahmen, der auf
     #111 kaum zu treffen ist, ohne entweder unsichtbar oder zu hell zu wirken") - hier stand er
     trotzdem, ein Rest aus der Zeit der grossen Karte. Der Schatten allein traegt die Kante. */
  color: #fff;
  /* DIESELBE Schatten-Tiefe wie .cms-console-app (DESIGN.md, "The Single Elevation Rule": genau
     eine Erhebung im ganzen System) - vorher trug die Karte einen groesseren, weicheren Halo
     (24/70/0.55) als eigene Begruendung fuer "frei in der Bildschirmmitte schwebend". Seit sie
     im selben Eck wie die Leiste steht (siehe .cms-console-login,.cms-console-app oben), ist das
     ein zweiter Schatten-Grad ohne eigenen Grund - genau der Fehler, den die Regel ausschliesst. */
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
  border-radius: 16px; /* crisper als die fruehen 24px - Instrument/Konsole statt weiches SaaS-Kaertchen */
  /* Kein Karten-Innenabstand mehr (23.07.2026) - die Zeile (.ga-bar) traegt ihr eigenes Padding,
     exakt wie .cms-console-app. Diese Huelle ist nur noch der gemeinsame Rahmen (Farbe, Radius,
     Schatten, Breite), der Inhalt bestimmt selbst, wie viele Zeilen er braucht. */
  padding: 0;
  /* min() statt max-width+width:calc(100%-...): .cms-console (der Elternrahmen) hat selbst
     KEINE feste Breite (bestimmt seine Groesse vom Inhalt) - ein Prozentwert hier waere ein
     Zirkelbezug gegen ein undefiniertes Eltern-Mass, den Browser unterschiedlich aufloesen.
     100vw ist dagegen immer eindeutig (echte Fensterbreite), unabhaengig vom Elternelement -
     jede max-width-Erhoehung vorher aenderte deshalb sichtbar nichts. */
  width: min(400px, calc(100vw - 2rem));
  box-sizing: border-box;

  /* Erscheint/verschwindet AN ORT UND STELLE: Deckkraft 0<->1 plus ein sehr kleiner
     Massstabssprung, Ursprung Mitte, KEIN Versatz. Seit Karte und Leiste denselben Platz teilen
     (siehe oben), gibt es nichts mehr, dem die Karte beim Verschwinden "entgegendriften" muesste -
     der eigentliche Zustandswechsel (Karte -> Leiste beim Anmelden) ist ohnehin der native
     View-Transition-Morph weiter unten, nicht diese Regel hier. Die reist nur noch fuer
     Faelle ohne Morph (Oeffnen/Schliessen per Klick, Browser ohne View-Transitions-Support).

     0.2s liegt im Rahmen fuer Produkt-UI (150-250ms), ease-out-quart, kein Bounce. */
  opacity: 1;
  transform: scale(1);
  transform-origin: center;
  transition: opacity 0.2s cubic-bezier(0.25, 1, 0.5, 1),
              transform 0.2s cubic-bezier(0.25, 1, 0.5, 1),
              display 0.2s allow-discrete;
}
/* Abgang = gespiegelter Auftritt: verschwindet AN ORT UND STELLE, genau so wie sie erschienen ist.
   Frueher stand hier zusaetzlich ein translateY(10px) - ein Drift nach unten, als Andeutung der
   Uebergabe an die Leiste. Der stammt aus der Zeit VOR dem echten Morph. Jetzt macht den Uebergang
   der Browser (view-transition, siehe unten), und dieser Drift feuerte nur noch dort, wo er nie
   gemeint war: beim Schliessen per × und beim Abmelden. Da sah es aus, als rutsche die Konsole
   nach unten aus dem Bild - statt einfach zu verschwinden. */
.cms-console-login[hidden] {
  display: none;
  opacity: 0;
  transform: scale(0.94);
  /* Abgang mit eigenen Kurven, wie bei der Leiste (siehe dort die ausfuehrliche Begruendung):
     Deckkraft mit ease-IN, damit man die Karte noch SIEHT, waehrend sie kleiner wird. Lief die
     Deckkraft mit ease-out, war sie weg, bevor sich die Form bewegt hatte - das las sich als
     Aufloesen/Aufblaehen statt als Zusammenziehen. */
  transition: opacity 0.2s ease-in,
              transform 0.24s cubic-bezier(0.25, 1, 0.5, 1),
              display 0.24s allow-discrete;
}
@starting-style { .cms-console-login:not([hidden]) { opacity: 0; transform: scale(0.97); } }

/* ===== Der echte Uebergang: Karte -> Leiste (View Transitions API) =====
   Beim Anmelden ist es DIESELBE Konsole, die ihren Zustand wechselt. Genau das zeigt der
   Uebergang: die Karte sinkt ab und WIRD zur Leiste, statt dass eine Sache verschwindet und eine
   andere auftaucht. Das ist uebertragener Zustand ("das ist dasselbe Ding geblieben"), keine
   Dekoration - deshalb ist die Bewegung hier erlaubt, wo sie es beim Ankerwechsel nicht war.

   Umgesetzt mit dem nativen Primitiv, nicht handgeschrieben: beide Kaesten tragen DENSELBEN
   view-transition-name, aber immer nur das gerade SICHTBARE (:not([hidden])). Der Browser sieht
   denselben Namen vorher und nachher an verschiedenen Stellen und morpht Position und Groesse
   selbst ineinander. Kein Ausmessen, kein Timer, kein Gummi.

   Der :not([hidden])-Teil ist nicht Kosmetik, sondern Pflicht: waeren beide gleichzeitig
   benannt (der ausblendende Kasten haengt wegen allow-discrete noch kurz im Baum), waere der
   Name doppelt vergeben und der Browser bricht den Uebergang ab. */
.cms-console-login:not([hidden]),
.cms-console-app:not([hidden]) { view-transition-name: cms-konsole; }

/* Waehrend des Uebergangs malt der Browser seine Schnappschuesse, nicht die echten Elemente.
   Deren eigene Ein-/Ausblend-Transitions (oben) wuerden nur dagegenlaufen und den alten Kasten
   doppelt zeigen - hier also stumm schalten. */
:root:active-view-transition .cms-console-login,
:root:active-view-transition .cms-console-app { transition: none; }

/* Der KASTEN schrumpft: von der Karte auf die Leistenhoehe, an ORT UND STELLE (beide stehen im
   selben Eck, siehe .cms-console-login,.cms-console-app oben) - kein Weg mehr quer ueber den
   Bildschirm, seit die Karte nicht mehr in der Mitte startet. Deshalb jetzt am oberen Rand des
   normalen Produkt-UI-Fensters (150-250ms) statt der frueheren 0.35s-Ausnahme fuer eine lange
   Strecke, die es nicht mehr gibt. */
::view-transition-group(cms-konsole) {
  animation-duration: 0.25s;
  animation-timing-function: cubic-bezier(0.25, 1, 0.5, 1); /* ease-out-quart: ankommen, nicht federn */
  overflow: clip;      /* der Kasten schliesst sich UEBER dem Inhalt (siehe object-fit:none unten) */
  border-radius: 16px; /* wie Karte und Leiste - die Ecken bleiben waehrend der Fahrt rund */
}

/* Das Gemeinsame von Karte und Leiste ist die FLAECHE, nicht der Inhalt - ihre Inhalte haben
   nichts miteinander zu tun. Also darf auch nur die Flaeche morphen. Der Inhalt wird NIE verzerrt:
   er GEHT, die Flaeche WANDERT, dann KOMMT der neue Inhalt.

   Zwei Fehlversuche liegen dahinter, beide live gesehen:
   - Standardverhalten: die Schnappschuesse behalten ihre natuerliche Hoehe (block-size:auto),
     der Kasten faehrt auf Leistenhoehe zusammen, das ~420px hohe Kartenbild haengt unten heraus
     -> "die Karte rutscht durch den Balken hindurch".
   - object-fit:cover: beschneidet den Karteninhalt beim Zusammenfahren -> sah schlicht kaputt aus.

   DREI Fehlversuche liegen dahinter, alle live gesehen - der Reihe nach, damit sie nicht
   zurueckkommen:
   1. Standard (block-size:auto): das ~420px hohe Kartenbild behaelt seine Hoehe, waehrend der
      Kasten auf 60px zusammenfaehrt -> es haengt unten heraus: "die Karte rutscht durch den
      Balken hindurch".
   2. object-fit:cover: beschneidet den Inhalt beim Zusammenfahren -> sah kaputt aus.
   3. object-fit:contain: schrumpft das GANZE Kartenbild proportional in den flachen Kasten
      hinein, bis es ein winziges Vorschaubildchen ist -> "wird ganz schnell ganz klein".

   Richtig ist: object-fit:none - GAR KEINE Skalierung. Der Inhalt behaelt seine echte Groesse,
   und der Kasten (overflow:clip, siehe oben) schliesst sich ueber ihm, wie ein Rollo, das
   herunterfaehrt. Nichts wird klein, nichts wird gestaucht, nichts haengt heraus. */
::view-transition-old(cms-konsole),
::view-transition-new(cms-konsole) {
  height: 100%;
  object-fit: none;
  object-position: top center; /* der Kopf bleibt der Anker, der Kasten schliesst von unten */
}

/* UEBERBLENDUNG, keine Staffelung mit Luecke. Der vorige Versuch liess den Karteninhalt in 0.12s
   verschwinden und die Knoepfe erst ab 0.22s kommen - dazwischen ein leerer Kasten. Das liest sich
   zwangslaeufig als "nichts ... und dann Plopp", also als Gegenteil eines Uebergangs. Die beiden
   Inhalte muessen sich UEBERLAPPEN und ineinander aufloesen, waehrend der Kasten faehrt: dann ist
   es EINE durchgehende Bewegung. */
::view-transition-old(cms-konsole) {
  animation-duration: 0.25s;
  animation-timing-function: ease-out;
}
::view-transition-new(cms-konsole) {
  animation-duration: 0.28s;
  animation-delay: 0.1s;          /* setzt ein, waehrend die Karte noch verblasst - kein Loch */
  animation-fill-mode: backwards; /* bleibt bis dahin unsichtbar, statt aufzublitzen */
  animation-timing-function: ease-out;
}

/* Bearbeiten-Zustand: exakt die .es-leiste-Optik, nur unter dem geteilten Klassennamen -
   editor-shell.js baut modusBtn/status/speichernBtn/logoutBtn direkt in dieses Element. */
.cms-console-app {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.55rem 0.7rem;
  background: #141414; /* EINE Konsolen-Flaeche - identisch mit .cms-console-login (Karte) */
  color: #fff;
  border-radius: 16px; /* wie .cms-console-login - crisp, kohaerent Karte<->Leiste */
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
  font-size: 0.95rem;

  /* Die Leiste steigt leicht von unten ein - hier IST die Richtung ehrlich: sie ist am unteren
     Bildschirmrand verankert, sie kommt wirklich von dort. Die Bewegung liegt bewusst auf der
     Leiste selbst und nicht auf der Konsole (die positioniert nur, siehe oben).
     Gleiche 10px und gleiche Kurve wie der Abgangs-Drift der Karte (.cms-console-login): beim
     Anmelden bewegen sich beide aufeinander zu und das Ganze liest sich als EINE Uebergabe -
     ohne dass eines am anderen haengt. */
  opacity: 1;
  transform: translateY(0);
  transform-origin: center;
  /* transform-Dauer traegt jetzt zusaetzlich den Griff-Rutsch an den oberen Rand (.es-oben).
     Dieselbe Kurve wie der Karte->Leiste-Uebergang beim Anmelden (weiter unten,
     ::view-transition-group(cms-konsole): ease-out-quart, bewusst laenger als die ueblichen
     150-250ms, weil ein Shared-Element-Weg an der STRECKE haengt, nicht an einer festen Zeit).
     Dort sind es 0.35s fuer knapp den halben Bildschirm; der Griff-Weg (an den oberen Rand) ist
     laenger als das - nach derselben Logik entsprechend laenger: 0.45s. Gilt auch fuers normale
     Ein-/Aussteigen beim Anmelden/Abmelden mit - der Unterschied zur vorherigen Dauer (0.35s) ist
     dort kaum wahrnehmbar, eine zweite, eigene Transition nur dafuer waere unnoetiger Aufwand. */
  transition: opacity 0.2s cubic-bezier(0.25, 1, 0.5, 1),
              transform 0.45s cubic-bezier(0.25, 1, 0.5, 1),
              display 0.2s allow-discrete;
}
/* Abgang: zieht sich an Ort und Stelle leicht zusammen, statt nur zu verblassen.
   Gemessen bewegt sich hier NICHTS (oben=1006.4 konstant, transform = Einheitsmatrix ueber die
   ganze Ausblendung) - trotzdem las es sich als "rutscht nach unten weg" (Kilian, live). Der Grund
   ist Wahrnehmung, kein Bug: ein dunkler Balken am unteren BILDRAND, der einfach durchsichtig wird,
   hat keinen Anker; das Auge braucht eine Erklaerung fuer "weg" und nimmt am Rand die
   naheliegendste - er sei hinausgerutscht. Ein leichtes Zusammenziehen ist eindeutig ("geht zu")
   und laesst diese Lesart nicht mehr zu. Dieselbe Sprache wie die Login-Karte (scale 0.97). */
.cms-console-app[hidden] {
  display: none;
  opacity: 0;
  transform: scale(0.92);
  /* EIGENE Kurven fuer den Abgang (die Regel oben gilt nur fuer den Auftritt).
     Vorher liefen Deckkraft und Massstab beide auf ease-out - beide vorne steil. Gemessen:
     nach 75ms war der Balken schon zu 80% durchsichtig, aber erst 3% kleiner. Man sah also nie
     ein Schrumpfen, sondern nur einen Schleier, der sich aufloest - und ein dunkler Kasten mit
     weichem Schatten, dessen Kanten verschwimmen, liest sich als "blaeht sich auf wie ein
     Ballon" (Kilian, live). Die Deckkraft frass die Form, bevor die Form sich bewegen konnte.
     Jetzt: Deckkraft mit ease-IN (bleibt lange sichtbar, geht dann zuegig), Massstab weiter
     ease-out und mit spuerbarem Weg (0.92). Man sieht den Kasten schrumpfen - DANN ist er weg. */
  transition: opacity 0.2s ease-in,
              transform 0.24s cubic-bezier(0.25, 1, 0.5, 1),
              display 0.24s allow-discrete;
}
/* Auftritt = gespiegelter Abgang, dieselbe Sprache wie die Karte: an Ort und Stelle, gleicher
   Massstabssprung. Frueher stieg die Leiste hier 10px von unten auf - ein Rest aus der Zeit vor
   dem Morph. Sie feuert ohnehin fast nie (normalerweise ENTSTEHT die Leiste aus dem Uebergang,
   siehe view-transition unten; dieser Weg greift nur, wo der Browser keinen Morph kann), aber ein
   Element, das aufsteigt und sich zusammenziehend verabschiedet, spraeche zwei Sprachen. */
@starting-style { .cms-console-app:not([hidden]) { opacity: 0; transform: scale(0.96); } }

/* Griff getippt - Leiste rutscht an den oberen Bildschirmrand (Kilian, live: "der ganze Kasten
   soll nach oben rutschen... unten hat man dann Platz frei"). translateY kombiniert vh
   (Bildschirmhoehe) mit % (der EIGENEN Hoehe, CSS loest translateY(%) gegen die eigene Boxhoehe
   auf) - die genaue Pixel-Hoehe der Leiste muss dafuer nicht bekannt sein. 2.5rem = 1.25rem
   oberer + 1.25rem unterer Zielabstand, derselbe Abstand wie unten. dvh vor vh genannt (letzte
   verstandene Deklaration gewinnt) fuer den Fall, dass die Handy-Werkzeugleiste ein-/ausblendet.
   Bewusst NACH der [hidden]-Regel notiert: beide setzen "transform", .es-oben soll im (praktisch
   nie vorkommenden) Fall gleichzeitiger Zustaende gewinnen - Position ist ohnehin unwichtig,
   waehrend die Leiste unsichtbar ist. */
.cms-console-app.es-oben {
  transform: translateY(calc(-100vh + 100% + 2.5rem));
  transform: translateY(calc(-100dvh + 100% + 2.5rem));
}

/* Struktur der Karte (.ga-bar/.ga-bar-form, Basis-Form von .cms-console-close) lebt jetzt in
   auth.css - auch eigenstaendige helle Seiten (demo-supabase.html) laden nur auth.css, keine
   Konsole. Hier bleiben nur noch die FARBEN fuer die dunkle Konsolen-Flaeche. */
.cms-console .cms-console-close { color: #8e8e93; }
.cms-console .cms-console-close:hover { background: rgba(255, 255, 255, 0.08); color: #fff; }
.cms-console .cms-console-close:focus-visible { outline: none; box-shadow: 0 0 0 2px #fff; color: #fff; }
.cms-console .ga-hint { color: #8e8e8e; }

/* ----- Scoped Overrides fuer auth.css INNERHALB der dunklen Konsole -----
   auth.css selbst bleibt neutral/hell (wird z.B. in demo-supabase.html auch ohne diese
   Konsole als eigenstaendige, helle Seite genutzt). Nur wenn die auth.js-Elemente in DIESER
   Konsole stecken, gelten die dunklen Gegenstuecke. */
.cms-console .ga-field-label { color: #999; }
.cms-console .ga-toggle-pw { color: #707070; }
.cms-console .ga-toggle-pw:hover { color: #fff; }
/* inset, nicht outset: .ga-toggle-pw sitzt in .ga-input-wrap, das jetzt overflow:hidden hat
   (siehe auth.css) - ein nach aussen zeigender Ring wuerde dort abgeschnitten. */
.cms-console .ga-toggle-pw:focus-visible { box-shadow: inset 0 0 0 2px #fff; }
.cms-console .ga-merken { color: #b0b0b0; }
.cms-console .ga-merken input { accent-color: #fff; }
.cms-console .ga-merken input:focus-visible { box-shadow: 0 0 0 2px #fff; }
/* "Passwort vergessen?" ist ein Neben-Link, kein zweiter Haupt-Knopf: gleiches gedaempftes
   Grau und Gewicht wie "Angemeldet bleiben" daneben (#b0b0b0), ohne Unterstreichung - fett+
   unterstrichen wog frueher schwerer als die Checkbox und liess die Reihe schief wirken. */
.cms-console .ga-link { color: #b0b0b0; font-weight: 500; text-decoration: none; }
.cms-console .ga-link:hover { color: #fff; }
.cms-console .ga-link:focus-visible { box-shadow: 0 0 0 2px #fff; }
.cms-console .ga-submit:focus-visible { box-shadow: 0 0 0 2px #fff; }
/* Fehlte bisher: .ga-logout selbst wird in der dunklen Konsole nirgends verwendet (diese
   Seite haengt onLogout ueber EditorShell/.es-logout ein), aber falls eine andere Seite
   renderLogoutButton() HIER einbindet, waeren #444-Text/#ccc-Rahmen auf #111 kaum lesbar. */
.cms-console .ga-logout { color: #bbb; border-color: #555; }
.cms-console .ga-logout:hover { border-color: #fff; color: #fff; }
.cms-console .ga-logout:disabled { color: #666; border-color: #333; }
.cms-console .ga-logout:focus-visible { box-shadow: 0 0 0 2px #fff; }

/* Eingabefelder als dunkle Flaeche statt weisses Kaestchen im schwarzen Kasten - ein
   durchgehend dunkler Look wirkt ruhiger/"cleaner" als weiss-auf-schwarz-Fleckerlteppich.
   Farben angelehnt an Apples Dark-Mode-Gruppierung (Grundflaeche #111, Feld eine Stufe
   heller #1c1c1e). KEIN Rahmen (border:none statt eines Graus, der auf #111 kaum zu treffen
   ist, ohne entweder unsichtbar oder zu hell zu wirken) - die Flaechen-Helligkeit allein
   liefert genug Kontrast, exakt wie im Apple/Referenz-Vorbild. */
.cms-console .ga-input {
  background: #0d0d0d; /* klar dunklerer Well-Schritt unter der Konsolen-Flaeche #141414 */
  color: #fff;
  border: 1px solid #2b2b2b;
  border-radius: 10px; /* crisper (Konsole), passt zu .cms-console-login 16px */
  min-height: 44px; /* Tippflaeche */
  height: 50px;
  box-sizing: border-box;
}
/* Rundung auch am Wrap: der hat overflow:hidden (auth.css) und klammert die sichtbare Ecke -
   ohne das behielte das Feld optisch die 14px des Wraps. */
.cms-console .ga-input-wrap { height: 50px; border-radius: 10px; }
/* Platzhaltertext braucht >= 4.5:1. #707070 (Vorbild-Ton) auf dem dunklen Feld #0d0d0d liegt
   nur bei ~3.5:1 - deshalb minimal aufgehellt auf #8a8a8a (~5.5:1). Kaum sichtbar heller, aber
   lesbar. Die Icons duerfen bei #707070 bleiben (Nicht-Text-UI: 3:1 reicht). */
.cms-console .ga-input::placeholder { color: #8a8a8a; }
.cms-console .ga-input:focus { box-shadow: inset 0 0 0 2px #fff; }

/* Browser-Autofill (Chrome/Edge merkt sich das Login, siehe auth.js) faerbt Felder sonst
   eigenmaechtig ein - lavendel-blaeulicher Ton, der das dunkle Design durchbricht (sichtbar
   nur bei einem ECHTEN gespeicherten Zugang; eine Testseite ohne gespeicherte Daten zeigt
   den Fehler nie).

   Wir brauchen ZWEI Mechanismen zusammen, weil es zwei Fuell-Zeitpunkte gibt:

   1) FREEZE (transition ... calc(infinity*1s) step-end): friert den Autofill-Farbwechsel
      auf dem STARTwert ein, der Lavendel-Zielwert erscheint nie -> der eigene #1c1c1e-Grund
      bleibt, den der .ga-input-wrap (14px + overflow:hidden, auth.css) SAUBER rundet, ganz
      ohne Schatten -> perfekte Ecke. Wirkt aber NUR, wenn Autofill NACH dem ersten Rendern
      passiert (z.B. manuelles Auswaehlen aus dem Passwortmanager bei sichtbarem Feld).
      (step-end + infinity = robuste Form des "600000s"-Tricks,
       Quelle: noahliebman.net/2024/08/beating-important-user-agent-styles)

   2) DECKSCHATTEN (inset box-shadow): faengt den EAGER-FILL ab. Seit das Passwortfeld wieder
      autocomplete=current-password hat (auth.js - noetig, damit der Passwortmanager ueberhaupt
      sauber fuellt), fuellt Chrome BEIDE Felder sofort beim Erscheinen. Dann ist der einge-
      frorene Startwert schon Lavendel, der Freeze also wirkungslos (live bestaetigt: bg
      lavendel trotz aktiver Freeze-Regel). Der Schatten uebermalt das Lavendel.
      Sein Preis: die unsauber gerundete Eck-Sichel (Mozilla 527695 / WebKit 103087). ABER:
      im Freeze-Fall (1) zeigt die Sichel #1c1c1e (unsichtbar), nur im Eager-Fall eine sehr
      feine Lavendel-Sichel - weit besser als das ganze Feld lavendel.

   OFFEN: reicht die feine Sichel im Eager-Fall nicht, ist der naechste Schritt der Wrapper-
   Ansatz (Rundung+#1c1c1e auf den .ga-input-wrap, Input quadratisch nach innen versetzt) -
   oder renderLoginForm erst beim Oeffnen der Konsole aufrufen (dann fuellt Chrome nach dem
   Rendern und der Freeze allein wuerde reichen). Beides bewusst noch nicht gebaut. */
.cms-console .ga-input:-webkit-autofill,
.cms-console .ga-input:-webkit-autofill:hover {
  -webkit-text-fill-color: #fff;
  caret-color: #fff;
  transition:
    background-color calc(infinity * 1s) step-end,
    color            calc(infinity * 1s) step-end;
  -webkit-box-shadow: 0 0 0 200px #0d0d0d inset;
  box-shadow: 0 0 0 200px #0d0d0d inset;
}
/* autofill UND fokussiert: box-shadow ist ein Einzelwert - der weisse 2px-Fokusring (sonst
   aus .ga-input:focus) wuerde vom Deckschatten sonst verschluckt. Darum hier beide zusammen. */
.cms-console .ga-input:-webkit-autofill:focus {
  -webkit-text-fill-color: #fff;
  caret-color: #fff;
  transition:
    background-color calc(infinity * 1s) step-end,
    color            calc(infinity * 1s) step-end;
  -webkit-box-shadow: inset 0 0 0 2px #fff, 0 0 0 200px #0d0d0d inset;
  box-shadow: inset 0 0 0 2px #fff, 0 0 0 200px #0d0d0d inset;
}

/* (Frueher stand hier ein ::after-Deckring, der die Eck-Sichel UEBERDECKEN sollte - ein
   Kaschieren des Symptoms, das nie ganz sauber wurde. Entfernt: die Ursache ist jetzt an der
   Wurzel geloest, indem auth.js das Login-Formular erst rendert, wenn die Konsole sichtbar
   wird. Dann greift der Freeze auch beim Re-Login (Feld malt dunkel, DANN fuellt Chrome),
   der Deckschatten oben zeigt nie mehr eine Sichel, weil der Grund echt #1c1c1e ist. Siehe
   IntersectionObserver in auth.js init(). */

.cms-console .ga-submit {
  background: #ffffff; /* echtes Weiss statt mausgrau (#ededed) - selbstbewusste Hauptaktion */
  color: #111;
  /* GLEICHE Rundung wie .ga-input (10px), NICHT volle Pille - der Knopf steckt im selben
     Formular wie die Felder und teilt deren Rundungs-Sprache. */
  border-radius: 10px;
  font-weight: 600;
  padding: 0.55rem 1.2rem;
  min-height: 44px; /* Tippflaeche */
  box-sizing: border-box;
  /* Auto-Breite statt der frueheren 100% ("Apple-Sheet-Konvention"): das war fuer die
     gestapelte Karte gedacht, der Knopf steht jetzt NEBEN dem Feld in derselben Zeile
     (.ga-bar-form), nicht mehr darunter. */
  flex: 0 0 auto;
}
.cms-console .ga-submit:hover { background: #e9e9e9; }
.cms-console .ga-submit:disabled { background: #555; color: #999; }

/* Warnrot auf dunklem Grund aufgehellt - #b00020 (Grundfarbe, siehe DESIGN.md) haette auf
   #111 zu wenig Kontrast (< 4.5:1). Gleiche Logik fuer den Erfolgs-Hinweis (Gruen). */
.cms-console .ga-error { color: #ff6b6b; }
.cms-console .ga-hinweis { color: #4ade80; }

@media (max-width: 480px) {
  /* Die Konsole selbst bleibt unangetastet (sie ist die volle Schicht) - nur die LEISTE geht am
     Handy randnah auf volle Breite. Die Login-Zeile (.cms-console-login) braucht diese Anpassung
     nicht: sie ist seit 23.07.2026 selbst schon schmal und einreihig (width:min(400px,
     100vw-2rem) reagiert von selbst auf jede Fensterbreite, ohne eigene Breakpoint-Regel).
     ERSTER ANLAUF (verworfen, Kilian live am Handy): flex-wrap + justify-content:space-between.
     Bei GENAU 3 Knoepfen (Vorschau/Modus, Speichern, Abmelden) passen nur zwei in die erste
     Zeile - der dritte faellt allein in eine zweite Zeile. space-between verteilt ihn dort aber
     weiterhin wie eine ganze Zeile: er haengt links, rechts bleibt eine leere Ecke. Sah kaputt
     aus, nicht wie Absicht.
     ZWEITER ANLAUF (verworfen, Kilian live): Spalte statt Zeile - loeste den Bruch, nahm aber
     Kilian zu viel Hoehe auf dem Bildschirm ("das nimmt zu viel Platz ein"). Wunsch: so lange wie
     moeglich nebeneinander bleiben, so stark zusammengequetscht wie geht, statt gleich auf Spalte
     zu wechseln.
     DRITTER ANLAUF (dieser Stand): Zeile bleibt Zeile, aber enger - Luecke, Innenabstand und
     Schrift schrumpfen gemeinsam. Die Mindestbreiten fuer "Vorschau/Bearbeiten" (.es-modus,
     120px) und "Speichern/Gespeichert" (.es-speichern, 130px) waren auf die GROESSERE
     Basis-Schrift (0.95rem) vermessen, um genau diese Woerter ohne Wackeln aufzunehmen (siehe
     Kommentare dort) - bei kleinerer Schrift (0.82rem, ~86%) schrumpfen sie proportional mit,
     sonst waeren sie hier unnoetig grosszuegig und quetschen die Nachbarn ohne Grund.
     min-height (44px, --wz-ziel) bleibt UNVERAENDERT - das ist die Mindest-Tippflaeche fuers
     Fingers, keine Design-Reserve, an der man drehen darf. Sollte selbst das nicht mehr auf
     JEDES Telefon passen, faengt die zweite Media-Query darunter (sehr schmale Geraete) den
     Rest ab - erst DORT der Rueckfall auf Spalte.
     VIERTER ANLAUF (verworfen, Kilian live): justify-self:stretch entfernt, Pille faellt auf
     ihre Inhaltsgroesse zurueck (place-self: end center, wie am Desktop). Loeste die Luecke,
     wirkte dann aber "unproportional... klein" - eine kleine schwebende Pille auf einem grossen
     Handy-Bildschirm mit viel weissem Rand links/rechts wirkt verloren, nicht clean.
     FUENFTER ANLAUF (dieser Stand): Leiste bleibt breit (stretch zurueck) WIE EIN NORMALER
     mobiler Aktions-Balken am unteren Rand - aber die drei Knoepfe wachsen jetzt SELBST mit
     (flex-grow), statt dass ungenutzter Freiraum stehen bleibt. Das behebt beide bisherigen
     Fehler zugleich: keine leere Flaeche mehr (Anlauf 4s Beschwerde), und die Leiste wirkt nicht
     mehr wie eine verlorene kleine Pille (Anlauf 3/4s eigentliches Problem), weil sie den Platz
     jetzt wirklich ausfuellt. Die bestehenden Mindestbreiten (.es-modus 105px, .es-speichern
     112px) bleiben als UNTERGRENZE stehen (Wackel-Schutz), flex-grow verteilt nur den
     zusaetzlichen Freiraum obendrauf gleichmaessig - "Speichern" bleibt trotz gleicher Breite
     durch seine helle Fuellfarbe weiter der optisch wichtigste Knopf ("One Bright Button Rule",
     DESIGN.md), die Gleichmacherei betrifft nur die Breite, nicht die Farbe.
     SECHSTER ANLAUF (Ergaenzung): der Griff (.es-griff) kam NACH diesem Tuning dazu und ist
     flex-shrink:0 - bei bestimmten Fensterbreiten reicht der Platz fuer ihn UND die drei
     Mindestbreiten der Knoepfe zusammen nicht mehr, er quoll ueber die runde Ecke hinaus (Kilian,
     live, Screenshot). Statt einen weiteren exakten Pixel-Grenzwert zu erraten (den ich nicht
     selbst am Bildschirm pruefen kann): flex-wrap erlaubt einen sauberen Zeilenumbruch, sobald es
     eng wird - strukturell sicher, unabhaengig von der genauen Fensterbreite. */
  .cms-console-app {
    justify-self: stretch;
    max-width: calc(100vw - 1.5rem);
    margin: 0 0.75rem 1.25rem;
    flex-wrap: wrap;
    justify-content: flex-end;
    row-gap: 0.4rem;
    gap: 0.4rem;
    padding: 0.4rem 0.5rem;
    font-size: 0.82rem;
    --es-pad-x: 0.55rem;
    --es-speichern-pad: 0.5rem;
  }
  .es-modus,
  .es-speichern,
  .es-logout {
    flex: 1 1 0;
    min-width: 0;
  }
  .es-modus { min-width: 105px; }
  .es-speichern { min-width: 112px; }
  /* Beim Wackel-Schutz oben vergessen: ohne eigene Mindestbreite schrumpft "Abmelden" auf
     dieselbe min-width:0 wie seine Geschwister VOR ihrer Untergrenze - gemessener Inhalt bei
     dieser Schriftgroesse/Polsterung ~78px, 90px mit Reserve wie bei den anderen zwei. */
  .es-logout { min-width: 90px; }
}

@media (max-width: 340px) {
  /* Sehr schmales Telefon: selbst zusammengequetscht (Anlauf 3 oben) passt die Zeile
     rechnerisch nicht mehr sicher - hier erst der Rueckfall auf Spalte (Anlauf 2). Der Griff
     (.es-griff, flex-shrink:0) bleibt dabei oben rechts stehen, statt mit auf volle Breite
     gezogen zu werden - er ist kein gleichwertiger vierter Aktions-Knopf. */
  .cms-console-app {
    flex-wrap: wrap;
    justify-content: flex-end;
  }
  .es-modus,
  .es-speichern,
  .es-logout {
    flex-basis: 100%;
  }
}

/* Barrierefreiheit: Ein-/Ausblenden faellt fast auf null statt komplett zu verschwinden - so
   bleibt [hidden]/display weiterhin durch allow-discrete gesteuert (kein Sprung-Bug), nur
   ohne wahrnehmbare Bewegung/Weichzeichnung. */
@media (prefers-reduced-motion: reduce) {
  .cms-console,
  .cms-console-login,
  .cms-console-app,
  .cms-console-close,
  .cms-backdrop,
  .es-leiste {
    transition-duration: 0.01ms;
  }
  /* Kein Massstabssprung, kein Aufsteigen - Karte und Leiste erscheinen einfach, ohne Bewegung.
     .es-oben bleibt bewusst ausgenommen: die Position (oben/unten) SOLL weiter wechseln, nur
     ohne animierten Rutsch - sonst wuerde reduzierte Bewegung die ganze Funktion abschalten,
     nicht nur ihre Animation. */
  .cms-console-login,
  .cms-console-login[hidden],
  .cms-console-app:not(.es-oben),
  .cms-console-app[hidden] { transform: none; }
  /* Auch der Karte->Leiste-Uebergang faellt weg: harter, sofortiger Wechsel statt Morph.
     Die VERZOEGERUNG muss mit auf null - sonst wechselt der Kasten zwar sofort, die Knoepfe
     erschienen aber erst 0.22s spaeter aus dem Nichts (animation-delay der neuen Ebene).
     Ausgerechnet bei reduzierter Bewegung ein Aufpoppen: eine Dauer abzuschalten und die
     Verzoegerung stehenzulassen, ist keine halbe Loesung, sondern eine falsche. */
  ::view-transition-group(cms-konsole),
  ::view-transition-old(cms-konsole),
  ::view-transition-new(cms-konsole) {
    animation-duration: 0.01ms;
    animation-delay: 0s;
  }
}
