/* ============================================================
   Komponente: banner
   ------------------------------------------------------------
   Quelle: Figma „Design System" → banner, Komponenten-Satz
   11919:1842, ausgelesen am 04.09.2026.

   Liegt oben am Screen über dem Inhalt, blockiert nicht, und
   BLEIBT STEHEN, BIS DER ZUSTAND ENDET — kein Timer, kein
   Fortschrittsbalken.

   ------------------------------------------------------------
   DIE ABGRENZUNG IST DER GANZE PUNKT
     toast    verschwindet von selbst          → kein ✕
     banner   bleibt, bis der Zustand endet    → ✕ nur, wenn er
              sonst stehen bliebe
     message  dieselbe Gestalt IM FLUSS, unter dem Feld oder im
              Screen                           → nie ein ✕
     dialog   verlangt eine Entscheidung       → nie ein ✕

   Aus der Figma-Doku: „Bleibt der Zustand über die Anzeige
   hinaus bestehen, ist es kein Toast, sondern ein banner."

   ------------------------------------------------------------
   DREI ROLLEN
     fehler   Der Code oder die Eingabe ist das Problem.
     info     Die Ursache liegt weder beim Nutzer noch bei uns
              (offline, Zugang läuft ab).
     zugang   Kein Fehler, sondern ein Zustand. Neutrale Karte,
              KEIN Icon.

   DREI AKTIONEN
     keine    Es gibt nichts zu tun. Token-Fehler tragen nie
              einen Button — denselben Code erneut zu senden
              ändert nichts.
     link     Textlink unter dem Text: „du kannst es nochmal
              versuchen".
     button   Button small rechts daneben: „das ist der Weg".

   DIE MATRIX IST BEWUSST NICHT VOLL BESETZT. `aktion=button`
   gibt es nur bei `rolle=zugang`. Ein Fehler ist kein Fehler
   mehr, wenn wir einen Weg anbieten können, und ein Hinweis
   informiert, statt zu führen. Der Primär-Button bleibt dem
   Zugang vorbehalten, damit „Zugang aktivieren" im ganzen
   Produkt derselbe Knopf ist.

   ZWEI AUSRICHTUNGEN
     mittig   Icon auf halber Höhe. Nur bei keine und button,
              also solange der Text zweizeilig bleibt.
     oben     Icon auf Höhe der ersten Zeile. IMMER bei
              aktion=link — der Link macht den Banner so hoch,
              dass ein mittiges Icon neben dem Nichts stünde.

   Das ✕ gibt es nur bei fehler und info. `zugang` trägt nie
   eines: der Zustand endet erst mit dem Wechsel nach Ziel A.
   Es ist 45 x 45 (§11.2) — NICHT gegen `close icon button
   small` (30) tauschen, der ist für Flächen gedacht, die von
   selbst verschwinden.

   Setzt tokens.css und base.css voraus, für aktion=link
   zusätzlich components/link-button.css und für aktion=button
   components/button.css.

   VERWENDUNG
     <div class="banner banner--fehler banner--oben" role="alert">
       <div class="banner__zeile">
         <div class="banner__row">
           <span class="banner__icon">
             <svg class="ikon" aria-hidden="true">…</svg>
           </span>
           <div class="banner__texte">
             <div class="banner__zeilen">
               <p class="banner__titel">Titel</p>
               <p class="banner__untertitel">Beschreibung</p>
             </div>
             <button class="link-button" type="button">…</button>
           </div>
         </div>
         <button class="banner__schliessen" type="button"
                 aria-label="Meldung schließen">…</button>
       </div>
     </div>

   aktion=button — der Knopf steht NEBEN dem Text, in der Reihe,
   und es gibt weder Icon noch ✕:

     <div class="banner banner--zugang">
       <div class="banner__zeile">
         <div class="banner__row">
           <div class="banner__texte">
             <div class="banner__zeilen">
               <p class="banner__titel">Kein Zugang</p>
               <p class="banner__untertitel">Scanne den Code vor Ort.</p>
             </div>
           </div>
           <button class="btn btn--primary btn--sm" type="button">
             <span class="btn__label">Zugang aktivieren</span>
           </button>
         </div>
       </div>
     </div>

   ------------------------------------------------------------
   GEMESSENE MASSE OHNE TOKEN-GRUNDLAGE
     17,18  Icon (info und attention).
     10     ✕ im Schließen-Knopf.
     3      Blur hinter dem Schließen-Knopf.
   ============================================================ */

.banner {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-sm);                    /* 12 */

  width: 100%;                             /* Figma: FILL */
  padding: var(--space-md);                /* 16 */
  border-radius: var(--radius-md);         /* 20 */

  /* Der Strich als innerer Schatten, nicht als border: er liegt
     in Figma INNEN und darf die automatische Höhe nicht
     vergrößern (AGENTS.md §8a). */
  --banner-outline: transparent;
  box-shadow: inset 0 0 0 var(--outline-default) var(--banner-outline);
}

.banner__zeile {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);                    /* 8 */
  width: 100%;
}

.banner__row {
  display: flex;
  flex: 1 0 0;
  min-width: 0;
  gap: var(--space-xs);                    /* 8 */
  align-self: stretch;
  align-items: center;                     /* ausrichtung=mittig */
}

/* ausrichtung=oben: das Icon steht auf Höhe der ERSTEN Zeile,
   nicht auf halber Banner-Höhe. */
.banner--oben .banner__row {
  align-items: flex-start;
}

/* Das Icon sitzt in einem Kasten mit 4 Polster oben und unten —
   so kommt es auf dieselbe optische Achse wie die erste
   Textzeile, deren Zeilenhöhe 150 % ist. Dieselbe Lösung wie in
   message.css. */
.banner__icon {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  padding-block: var(--space-2xs);         /* 4 */
}

.banner__icon .ikon {
  display: block;
  overflow: visible;
  width: 17.18px;                          /* gemessen, siehe Kopf */
  height: 17.18px;
}

/* aktion=button (nur bei rolle=zugang): Der Button small steht
   als Geschwister von .banner__texte in derselben Reihe, nicht
   unter dem Text. `flex-shrink: 0`, sonst drückt der Text ihn
   schmaler als sein Label — gemessen an 11919:1804.
   Ergänzt 14.09.2026. */
.banner__row > .btn {
  flex-shrink: 0;
}

.banner__texte {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-xs);                    /* 8 */
  flex: 1 0 0;
  min-width: 0;
}

/* Die 8 Einrückung links stehen an den ZEILEN, nicht am Icon —
   so bleibt der Text auch dann eingerückt, wenn es kein Icon
   gibt (rolle=zugang). */
.banner__zeilen {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2xs);                   /* 4 */
  padding-left: var(--space-xs);           /* 8 */
  width: 100%;
  color: var(--text-primary);
  overflow-wrap: anywhere;
}

.banner__titel {
  margin: 0;
  font-family: var(--font-family-inter);
  font-size: var(--font-size-title-text);
  line-height: var(--line-height-title-text);
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--letter-spacing-small-text-bold);   /* 1 % */
}

/* Die Farbe muss hier stehen: .banner__zeilen setzt text-primary
   für den Titel, und ohne eigene Angabe erbt der Untertitel sie
   und wird weiß. Die Komponentenbeschreibung nennt ihn „Regel
   ohne Ausnahme: immer small text in text-description" —
   ergänzt 14.09.2026 (11919:1804). */
.banner__untertitel {
  margin: 0;
  font-family: var(--font-family-inter);
  font-size: var(--font-size-small-text);
  line-height: var(--line-height-small-text);
  font-weight: var(--font-weight-regular);
  color: var(--text-description);
}

/* ------------------------------------------------------------
   Rollen
   ------------------------------------------------------------
   Farbe ist NIE das alleinige Signal (WCAG 1.4.1): fehler und
   info tragen zusätzlich ihr Icon, zugang trägt keines und ist
   daran zu erkennen, dass es neutral ist.
   ------------------------------------------------------------ */

.banner--fehler {
  background-color: var(--warning-red-fill);
  --banner-outline: var(--red-label-stroke);
}

.banner--fehler .banner__icon {
  color: var(--red-label-text);
}

.banner--info {
  background-color: var(--blue-label-fill);
  --banner-outline: var(--blue-label-stroke);
}

.banner--info .banner__icon {
  color: var(--blue-label-text);
}

/* Zugang ist kein Fehler, sondern ein Zustand — deshalb die
   neutrale Karte und kein Icon. */
.banner--zugang {
  background-color: var(--surface-card);
  --banner-outline: var(--label-outline);
}

/* ------------------------------------------------------------
   Schließen
   ------------------------------------------------------------
   45 x 45 nach §11.2, mit Blur dahinter: der Banner liegt in
   #101–#111 über dem Kamerabild, und dort trägt eine
   durchsichtige Fläche die Lesbarkeit nicht (§18).
   ------------------------------------------------------------ */

.banner__schliessen {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;

  width: 45px;                             /* gemessen, siehe Kopf */
  height: 45px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-full);
  background: none;
  backdrop-filter: blur(3px);              /* gemessen, siehe Kopf */
  color: var(--text-primary);
  cursor: pointer;
}

.banner__schliessen .ikon {
  display: block;
  overflow: visible;
  width: 10px;                             /* gemessen, siehe Kopf */
  height: 10px;
}

@media (hover: hover) and (pointer: fine) {
  .banner__schliessen:hover {
    background-color: var(--button-icon-button-fill-hover);
  }
}

.banner__schliessen:active {
  background-color: var(--button-icon-button-fill-press);
  box-shadow: inset 0 0 0 var(--outline-default) var(--button-icon-button-outline-press);
}

.banner__schliessen {
  transition:
    background-color calc(var(--motion-press) * var(--motion-scale)) var(--motion-ease-out),
    box-shadow       calc(var(--motion-press) * var(--motion-scale)) var(--motion-ease-out);
}

@media (prefers-reduced-motion: reduce) {
  .banner__schliessen {
    transition: none;
  }
}

/* ============================================================
   OFFEN
   ------------------------------------------------------------
   · Hover und Press am Schließen-Knopf stehen nicht an der
     Komponente. Beide sind hier aus dem Icon-Button übernommen,
     weil es derselbe Knopf in anderer Umgebung ist.
   · `zugang` mit `aktion=button` ist am 14.09.2026 gebaut
     (11919:1804). Offen bleibt nur die Fassung
     `ausrichtung=oben` (11919:1816) — bei zugang ohne Icon
     ändert sie nichts am Bild, ist aber nicht nachgemessen.
   ============================================================ */
