/* ============================================================
   Komponente: toast
   ------------------------------------------------------------
   Quelle: Figma „Design System" → toast, node 11157-796,
   übergeben am 27.08.2026.

   Ersetzt: error toast · success message · Undo-Banner.

   ABGRENZUNG ZU message (§20)
     toast    läuft nach Zeit ab und SCHWEBT unten über dem
              Inhalt. Schatten allseitig.
     message  bleibt stehen, bis sich der Zustand ändert, und
              steht im Fluss. → message.css

   Eine Dimension: art = fehler · erfolg · undo

   Standzeiten (§20)
     fehler 5 s · erfolg 5 s · undo 8 s
   Undo bleibt länger, weil der Nutzer lesen, entscheiden und
   treffen muss. Fortschrittsbalken hat NUR fehler — bei undo
   ist Verpassen folgenlos, die Aktion lässt sich wiederholen.

   VERWENDUNG
     <div class="toast-schicht">
       <div class="toast toast--fehler" role="alert">
         <span class="toast__icon"><svg …></svg></span>
         <div class="toast__texte">
           <p class="toast__titel">Titel konnte nicht geladen werden</p>
         </div>
         <span class="toast__balken" aria-hidden="true"></span>
       </div>
     </div>

   KEIN ✕, IN KEINER ROLLE (§20.1b, 15.09.2026). Der Toast geht
   von selbst; ein sichtbarer zweiter Ausgang verlangte eine
   Entscheidung, die nichts ändert. Bis dahin trugen fehler und
   erfolg eins und nur undo nicht — jetzt keiner.

   DAFÜR IST DIE FLÄCHE DER AUSGANG:

     undo               ein Tap auf die Fläche IST „Rückgängig".
                        Der Link Button bleibt sichtbar; er sagt,
                        was der Tap tut.
     fehler · erfolg    Fläche unbelegt, der Tap schließt.

   WEGWISCHEN NACH UNTEN schließt ebenfalls, in allen Rollen. Es
   wird NICHT angezeigt — kein Griff, kein Hinweis: es bietet
   sich nicht an, es ist da, wenn der Toast stört.

   Beides ist Verhalten und gehört deshalb in das JS des Screens,
   nicht hierher. Die Komponente stellt nur sicher, dass die
   Fläche Zeiger annimmt (siehe .toast-schicht > *).

   DIE POSITION IST ENTSCHIEDEN (§20.1a, 15.09.2026) und stand
   hier bis dahin als „noch zu bestätigen": unten, in allen
   Rollen, 12 über der Oberkante der Bottom Nav einschließlich
   der überstehenden Bubble. Eine Position für alle Rollen ist
   eine Regel statt drei Sonderfällen.

   NICHT AUS FIGMA ÜBERGEBEN und weiterhin zu bestätigen ist der
   Innenaufbau (Klassennamen, Gap, Icon-Farben je art). Er folgt
   message.css, damit beide gleich zu bauen sind. Werte, die
   übergeben wurden, sind unten markiert.
   ============================================================ */

/* ------------------------------------------------------------
   Schwebeschicht
   ------------------------------------------------------------
   Der Toast liegt über dem Inhalt, aber nie über der Bottom Nav
   — sonst verdeckt er die einzige jederzeit sichtbare Struktur
   der App (§7).

   12 ÜBER DER OBERKANTE DER NAV, EINSCHLIESSLICH DER
   ÜBERSTEHENDEN BUBBLE (§20.1a). Bis zum 15.09.2026 standen hier
   16 zum Fensterrand; damit lag der Toast auf der Bar.

   --nav-h IST GEMESSEN UND KOMMT VON AUSSEN, so wie --headh im
   klebenden Kopf (§26). Eine Zahl wäre hier falsch: die Bar ist
   81 hoch, aber der Verlauf darunter und die Bubble ragen
   darüber hinaus — gemessen sind es 105, und wer 81 schreibt,
   schiebt den Toast 24 zu tief.

   Die Anwendung sucht dafür den höchsten Punkt, den irgendetwas
   in der Bar erreicht, und setzt --nav-h neu, sooft sich das
   ändern kann: beim Öffnen eines Toasts und bei jedem
   Screenwechsel. Der Rückfallwert 0 gilt dort, wo es unten keine
   Navigation gibt — auf dem Tablet steht sie als Streifen links,
   und auf Voll-Screens gibt es keine.
   ------------------------------------------------------------ */
.toast-schicht {
  position: fixed;
  left: var(--layout-screen-margin);
  right: var(--layout-screen-margin);
  bottom: calc(var(--nav-h, 0px) + var(--space-sm));   /* 12 (§20.1a) */
  z-index: 100;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  pointer-events: none;
}

.toast-schicht > * {
  pointer-events: auto;
}

.toast {
  position: relative;
  overflow: hidden;                                  /* für den Balken */
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  width: 100%;                                       /* übergeben: FILL */
  padding: var(--space-md);                          /* übergeben: 16 */
  border-radius: var(--radius-md);                   /* übergeben: 20 */
  /* Der Strich liegt in Figma INNEN und zählt nicht zur Höhe;
     ein CSS-border tut das bei automatischer Höhe doch und macht
     das Element 2 px höher. AGENTS.md §8a verbietet ihn
     ausdrücklich („NIE ein CSS-border an beiden"). Er liegt
     deshalb als inset box-shadow in --toast-outline.
     Nachgezogen am 04.09.2026, zusammen mit .btn. */
  --toast-outline: transparent;                      /* übergeben: 1 px je art */
  /* DER SCHATTEN IST SUBTILER GEWORDEN (09.09.2026, Lisi: „drop
     shadow ist in figma angepasst, muss subtiler sein").

     Am Effekt der Komponente abgelesen: X 0, Y 0, Weichzeichnen
     35, Streuung 0, Farbe Black 15. Vorher standen hier 24 px
     Weichzeichnen auf scrim-full-black-60 — kleiner gestreut und
     viermal so kräftig, was den Toast wie ausgeschnitten
     aussehen ließ. Jetzt liegt er weiter und leiser: die Kante
     trägt der 1-px-Strich, nicht der Schatten. */
  box-shadow:
    inset 0 0 0 var(--outline-default) var(--toast-outline),
    0 0 35px var(--transparent-black-15);            /* gemessen */
}

.toast__icon {
  display: flex;
  flex: 0 0 auto;
  padding-block: var(--space-2xs);
}

.toast__texte {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  flex: 1;
  min-width: 0;
  padding-left: var(--space-xs);   /* gleiche Achse wie in message.css */
}

.toast__titel {
  font-size: var(--font-size-small-text);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-small-text);
  color: var(--text-primary);
}

.toast__untertitel {
  font-size: var(--font-size-small-text);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-small-text);
  color: var(--text-primary);
}

/* HIER STAND DAS ✕ (.toast__schliessen). Es ist am 15.09.2026
   mit §20.1b entfallen — in allen drei Rollen, nicht nur bei
   undo. Ersatzlos: die Fläche schließt, und Wegwischen nach
   unten auch. Siehe Kopf. */

/* Slot für den Link Button („Rückgängig"). Erbt seine Textfarbe
   selbst, Padding wie in message.css. */
.toast__aktion {
  flex: 0 0 auto;
  padding: var(--space-2xs) var(--space-xs);
  font-size: var(--font-size-small-text);
  line-height: var(--line-height-small-text);
}

/* ------------------------------------------------------------
   Fortschrittsbalken — nur art=fehler
   ------------------------------------------------------------
   Zeigt die Restzeit. Nicht das einzige Signal: die Standzeit
   endet ohnehin, ein Tap auf die Fläche schließt jederzeit
   sofort, und der Balken ist aria-hidden (§20.1c).
   ------------------------------------------------------------ */

.toast__balken {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  transform-origin: left center;
  background-color: var(--red-label-text);
  animation: toast-restzeit var(--toast-dauer) linear forwards;
}

@keyframes toast-restzeit {
  from { transform: scaleX(1); }
  to   { transform: scaleX(0); }
}

@media (prefers-reduced-motion: reduce) {
  .toast__balken { animation: none; }
}

/* ------------------------------------------------------------
   Arten
   ------------------------------------------------------------ */

.toast--fehler {
  --toast-dauer: 5s;                        /* übergeben */
  background-color: var(--warning-red-fill);
  --toast-outline: var(--red-label-stroke);
}

.toast--fehler .toast__icon {
  color: var(--red-label-text);
}

/* Kein Balken, keine Aktion. */
.toast--erfolg {
  --toast-dauer: 5s;                        /* übergeben */
  background-color: var(--green-label-fill);
  --toast-outline: var(--green-label-stroke);
}

.toast--erfolg .toast__icon {
  color: var(--green-label-text);
}

/* ------------------------------------------------------------
   art=erfolg — die Zeichen-Fläche und ihre Animation
   ------------------------------------------------------------
   Quelle: Figma „art=erfolg" (11570:92, 353 x 72) und das
   Bewegungs-JSON „Fancy Success Motion", 15.09.2026.

   DIE 36 SIND KEINE ICON-GRÖSSE, sondern eine Fläche, in der
   eine Animation läuft — der Kopf nennt 17 für Toast-Icons und
   19 für den Undo-Stern, die gelten hier nicht. Gemessen:
   Fläche 36 bei x 16, Text beginnt bei 64 = 16 + 36 + 12.

   ZWEI ABWEICHUNGEN VOM FEHLER-TOAST, beide gemessen:
   Titel und Untertitel sitzen bei y 0 und y 21, also ohne
   Abstand — mit den 4 aus .toast__texte wäre der Toast 78 statt
   72 hoch. Und der Untertitel ist grau: bei fehler trägt die
   zweite Zeile die Meldung, bei erfolg steht dort eine Angabe,
   und die tritt zurück.

   VERWENDUNG — drei Ebenen in einem SVG:
     <span class="toast__icon toast__icon--erfolg">
       <svg viewBox="0 0 36 36" aria-hidden="true">
         <mask id="nur-aussen" maskUnits="userSpaceOnUse"
               x="-24" y="-24" width="84" height="84">
           <rect x="-24" y="-24" width="84" height="84" fill="#fff"/>
           <circle cx="18" cy="18" r="16" fill="#000"/>
         </mask>
         <circle class="toast__schein" cx="18" cy="18" r="17"
                 mask="url(#nur-aussen)"/>
         <circle class="toast__ring"   cx="18" cy="18" r="17"/>
         <path   class="toast__haken"  d="…"/>
       </svg>
     </span>

   DER SCHEIN LIEGT NUR AUSSEN (Lisi: „glow nur outer glow. kein
   inner glow."). Er ist derselbe Kreis mit doppelter
   Strichstärke und Weichzeichner; ohne Maske läge die halbe
   Unschärfe im Loch des Rings. Die Maske schneidet sie weg:
   weiß außen, schwarz innerhalb des Innenradius 16 (= 17 minus
   halbe Strichstärke).

   DIE MASKE BRAUCHT EINEN AUSDRÜCKLICHEN BEREICH. Ohne
   maskUnits="userSpaceOnUse" und die Maße nimmt der Browser
   120 % der Zeichenfläche — dann wäre der Schein ausgerechnet
   AUSSEN abgeschnitten, also genau verkehrt herum.

   --haken-laenge KOMMT VON AUSSEN, aus getTotalLength() (18,905)
   und MIT EINHEIT. Ohne px ist die Rechnung im Keyframe
   ungültig, er fällt still aus, und der Haken steht von Anfang
   an ganz da. Der Vorgabewert hier hält den Fall ohne JS.
   ------------------------------------------------------------ */

.toast__icon--erfolg {
  width: 36px;                              /* gemessen, siehe oben */
  height: 36px;
  padding-block: 0;
}

/* DIE ZEICHENFLÄCHE DARF NICHT ABSCHNEIDEN. Ein <svg> tut das von
   sich aus an seinem viewBox-Rand, und der Schein ist mit dem
   Weichzeichner rund 62 breit — also deutlich mehr als die 36.
   Eine weiche Kante wird dabei zu einer harten, geraden: der
   Schein sieht eckig aus (Lisi, 15.09.2026: „der glow wird hier
   abgeschnitten und sieht eckig aus"). Nachgestellt mit zwei
   Toasts nebeneinander — mit `hidden` ein helles Quadrat, mit
   `visible` ein runder Schein.

   Hinausragen ist unbedenklich: der Schein sitzt bei 34 vom
   linken Toast-Rand und reicht rund 31 weit, bleibt also innen.
   Der Toast selbst schneidet für den Balken weiter ab. */
.toast__icon--erfolg > svg {
  overflow: visible;
}

.toast__schein,
.toast__ring {
  fill: none;
  stroke: currentColor;
  transform-origin: center;
}

.toast__ring {
  stroke-width: 2;
}

/* Doppelte Strichstärke plus Weichzeichner — das ist der ganze
   Unterschied zum Ring. */
.toast__schein {
  stroke-width: 4;
  filter: blur(var(--glow-blur-s));
}

/* Der Haken wächst vom ENDE her: im JSON läuft pathTrimStart von
   1 auf 0, in CSS ist das ein NEGATIVER Versatz. Am Zahlenwert
   ist das nicht zu prüfen, nur am gezeichneten Strich. */
.toast__haken {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: var(--haken-laenge, 19px);
  stroke-dashoffset: 0;
}

/* Eine Dauer für alle drei, Keyframes in Prozent von 1800 —
   sonst laufen die Ebenen auseinander. Der Ausschlag steht in
   den Werten, nicht in der Kurve: --motion-ease-bubble kommt
   nachgemessen über 1,005 nicht hinaus, ihr Kontrollpunkt wirkt
   auf den Weg zum Ziel, nicht auf den Zielwert. Ein sichtbarer
   Pop braucht einen Keyframe über 1. */
.toast--erfolg .toast__schein,
.toast--erfolg .toast__ring,
.toast--erfolg .toast__haken {
  animation-duration: calc(1800ms * var(--motion-scale));
  animation-timing-function: var(--motion-ease-in-out);
  animation-fill-mode: both;
}

.toast--erfolg .toast__schein { animation-name: toast-erfolg-schein; }
.toast--erfolg .toast__ring   { animation-name: toast-erfolg-ring; }
.toast--erfolg .toast__haken  { animation-name: toast-erfolg-haken; }

/* Größe 0,80 → 1,04 (950) → 1 · Deckkraft 0 → 4 % (280)
   → 62 % (920) → 34 % */
@keyframes toast-erfolg-schein {
  0%     { transform: scale(0.80); opacity: 0; }
  15.6%  { opacity: 0.04; }
  51.1%  { opacity: 0.62; }
  52.8%  { transform: scale(1.04); }
  100%   { transform: scale(1);    opacity: 0.34; }
}

/* Größe 0,72 → 1,04 (780) → 1 (1050) · Deckkraft 0 → 100 % (820).
   Der Ring zeichnet sich nicht, er poppt als Ganzes herein. */
@keyframes toast-erfolg-ring {
  0%     { transform: scale(0.72); opacity: 0; }
  43.3%  { transform: scale(1.04); }
  45.6%  { opacity: 1; }
  58.3%  { transform: scale(1); }
  100%   { transform: scale(1);    opacity: 1; }
}

/* Deckkraft ab 560, voll 720 · Strich 580 → 1420 */
@keyframes toast-erfolg-haken {
  0%     { opacity: 0; stroke-dashoffset: calc(-1 * var(--haken-laenge, 19px)); }
  31.1%  { opacity: 0; }
  32.2%  { stroke-dashoffset: calc(-1 * var(--haken-laenge, 19px)); }
  40%    { opacity: 1; }
  78.9%  { stroke-dashoffset: 0; }
  100%   { opacity: 1; stroke-dashoffset: 0; }
}

/* Kein Zeichnen, kein Pop — alles steht sofort da (motion.md §6). */
@media (prefers-reduced-motion: reduce) {
  .toast--erfolg .toast__schein,
  .toast--erfolg .toast__ring,
  .toast--erfolg .toast__haken {
    animation: none;
  }

  .toast--erfolg .toast__schein { opacity: 0.34; }
}

.toast--erfolg .toast__texte {
  gap: 0;                                   /* gemessen, siehe oben */
}

.toast--erfolg .toast__untertitel {
  color: var(--text-description);
}

/* ------------------------------------------------------------
   art=undo
   ------------------------------------------------------------
   Quelle: Figma „Design System" → toast, node 11570:104,
   ausgelesen am 04.09.2026.

   Kein Balken, kein ✕ — nur „Rückgängig". Er weicht in vier
   Punkten von den anderen beiden ab; die vier standen bis zum
   04.09.2026 im Tablet-Prototypen und stehen jetzt hier:

     Polster    16 seitlich, 12 oben und unten (sonst 16 rundum)
     Abstand    12 zwischen Meldung und Aktion
     Schatten   Radius 12 (sonst 24)
     Textgewicht regular (sonst bold) — er meldet einen Zustand,
                keinen Erfolg

   Die Höhe von 69 ergibt sich: 12 + 45 Link Button + 12. Der
   Link Button behält also seine 45, obwohl der Toast nur 69
   hoch ist. Wer ihm hier `height: auto` gibt, bekommt 61.
   ------------------------------------------------------------ */

.toast--undo {
  --toast-dauer: 8s;                        /* übergeben */
  background-color: var(--surface-card);
  --toast-outline: var(--label-outline);

  align-items: center;
  gap: var(--space-sm);                    /* 12 */
  padding: var(--space-sm) var(--space-md);   /* 12 / 16 */
  /* Derselbe Schatten wie an den anderen Arten — siehe oben. Hier
     standen 12 px, also noch enger. */
  box-shadow:
    inset 0 0 0 var(--outline-default) var(--toast-outline),
    0 0 35px var(--transparent-black-15);            /* gemessen */
}

/* Der Link Button ist in der Komponente ein direktes Kind — der
   Slot bringt kein eigenes Polster mit. Mit den 4 aus
   .toast__aktion wäre der Toast 77 statt 69. */
.toast--undo .toast__aktion {
  padding: 0;
}

/* Der Text meldet einen Zustand, er feiert nichts — regular. */
.toast--undo .toast__titel {
  font-weight: var(--font-weight-regular);
}

/* Der durchgestrichene Stern ist 19, nicht 17 wie die anderen
   Toast-Icons (11577:708). */
.toast--undo .toast__icon .ikon {
  width: 19px;
  height: 19px;
}

/* Der Balken hat NUR fehler (§20.1c). Das ✕ stand hier bis zum
   15.09.2026 mit in der Zeile — es gibt keins mehr, in keiner
   Rolle. */
.toast--erfolg .toast__balken,
.toast--undo   .toast__balken {
  display: none;
}
