/* ============================================================
   Komponente: suchleiste
   ------------------------------------------------------------
   Quelle: Figma „Design System" → Component Set „Search Bar"
   56:2994, alle 13 Varianten ausgelesen am 08.09.2026 (Lisi hat
   die Komponente an diesem Tag neu aufgesetzt und dokumentiert).
   Vorher gemessen an den Instanzen 13866:15977 (Vor Ort, 621
   breit) und 12845:14657 (Inhalte-Seite, 320 breit).

   DIE DREI ACHSEN DES SETS
     type    Search slim · Search and filter · Search thick ·
             Search inverted
     focus   no · yes
     filled  empty · filled

   DIE ZWEI EBENEN AUS FIGMA
     außen   Zeile, gap 8 — nur „Search and filter" hat darin ein
             zweites Kind, den 87 x 45 breiten Filter-Knopf.
             Die Pille selbst ist flex: 1.
     innen   die Pille, darin die Gruppe aus Lupe und Text
             (gap 12) und, wenn gefüllt, die ✕-Scheibe (gap 6).

   WAS SICH JE ZUSTAND ÄNDERT — alles am Component Set gemessen:

     leer, ohne Fokus     Rand 1 px label-outline, Polster 16
                          rundum, Lupe weiß, Text
                          text-description
     gefüllt, ohne Fokus  Rand 1 px label-outline, links 16 und
                          rechts 8, Text text-primary
     Fokus (beide)        Rand 2 px label-outline-active,
                          Schein 0 0 2 auf glow, Lupe blau,
                          links 16 und rechts 8

   DIE HÖHE IST FEST, DAS POLSTER NUR SEITLICH. 45 (slim: 36),
   Innenabstand links 16 und rechts 8, oben und unten 0 — von
   Lisi am 08.09.2026 in Figma so gesetzt und bestätigt. Deshalb
   steht hier height und kein padding-block: die Pille darf beim
   ersten Zeichen nicht wachsen.
     Search inverted      Fläche label-fill-inverted statt
                          searchbar, Scheibe eine Stufe zurück
                          nach oben (label-fill). Sonst gleich.

   SKILL.md §6 beschreibt die Suchleiste, eine Datei dafür gibt
   es im System noch nicht. Diese füllt die Lücke; die Werte sind
   aus den Instanzen gemessen.

   ZWEI FLÄCHEN, EINE REGEL (§6, Komponenten-Beschreibung):
     auf surface-primary  → .suchleiste            (--searchbar)
     auf einer Karte      → .suchleiste--auf-karte (--label-fill-inverted)
   Grund: --searchbar ist in Light derselbe Farbwert wie
   surface-card — auf einer Karte verschwindet das Feld und es
   bleibt nur der Rand. Dieselbe Regel wie beim Chip (§5).

   ZWEI FASSUNGEN, WEIL SIE ZWEI DINGE TUT:

     Als BUTTON steht sie in der Kopfzeile eines Screens und
     öffnet die Suche. Dort wird nichts getippt — sie ist ein
     Versprechen, kein Feld.

     Als FELD (.suchleiste--feld) steht sie IM Suchscreen. Dort
     wird getippt, also gehört ein echtes <input> hinein — nur
     so öffnet das Betriebssystem seine Tastatur, und nur so
     gibt es eine Schreibmarke.

   Der Satz „im Prototyp ist die Leiste ein Button" ist damit
   überholt (05.09.2026, Suchscreen gebaut).

   SCHRIFTGRÖSSE: Das FELD trägt medium text (18), der BUTTON
   small text (14). Kein Widerspruch — im Button wird nicht
   getippt, also gibt es dort auch keinen iOS-Zoom. Bedingung
   dafür ist, dass der Button ein <button> bleibt: ein <input>
   mit readonly oder disabled zoomt trotzdem. In Flutter
   InkWell + Semantics(button: true), damit der Screenreader
   eine Schaltfläche ansagt und kein leeres Textfeld.

   Setzt tokens.css und base.css voraus.

   ZWEI EBENEN, WIE IN FIGMA: die Pille hat gap 8, und darin
   sitzt eine Gruppe aus Lupe und Text mit gap 12. Der Leeren-
   Knopf ist das dritte Kind der Pille, nicht Teil der Gruppe —
   nur so steht er rechts und der Abstand zum Text stimmt.

   VERWENDUNG — als Button
     <button class="suchleiste" type="button">
       <span class="suchleiste__gruppe">
         <svg class="suchleiste__ikon"><use href="#icon-search"></use></svg>
         <span class="suchleiste__text">Suche</span>
       </span>
     </button>

   VERWENDUNG — als Feld, leer
     <label class="suchleiste suchleiste--feld">
       <span class="suchleiste__gruppe">
         <svg class="suchleiste__ikon"><use href="#icon-search"></use></svg>
         <input class="suchleiste__eingabe" type="search"
                placeholder="Suche"
                aria-label="Suche in Magazine &amp; Zeitungen">
       </span>
     </label>

   VERWENDUNG — als Feld, gefüllt (mit Leeren-Knopf)
     <div class="suchleiste suchleiste--feld suchleiste--gefuellt">
       <label class="suchleiste__gruppe">
         <svg class="suchleiste__ikon"><use href="#icon-search"></use></svg>
         <input class="suchleiste__eingabe" type="search" value="Bastian"
                aria-label="Suche in Magazine &amp; Zeitungen">
       </label>
       <button class="suchleiste__leeren ikon-button ikon-button--klein
                      ikon-button--suchfeld touch-target"
               type="button" aria-label="Eingabe leeren">
         <svg class="ikon-button__ikon"><use href="#icon-close"></use></svg>
       </button>
     </div>

   Im gefüllten Zustand ist die Pille ein <div> und das <label>
   wandert auf die Gruppe: ein <label> um einen Button herum
   würde jeden Klick auf das ✕ ins Feld umleiten.

   ------------------------------------------------------------
   GEMESSENE MASSE OHNE TOKEN-GRUNDLAGE
     45      Höhe. Wie .btn--sm und der Icon-Button.
     36      Höhe der Slim-Fassung.
     16,58   Lupe. Native Größe der Figma-Komponente (14,578
             Zeichenfläche plus 1 Strich rundum).
     6       Zwischen Gruppe und ✕-Scheibe.
     87 x 45 Filter-Knopf.
     5       Zwischen Label und Icon im Filter-Knopf.
   ============================================================ */

.suchleiste {
  display: flex;
  align-items: center;
  /* 6 zwischen Gruppe und Leeren-Knopf. Kein Token — in Figma
     steht an der Pille gap-[6px], und nur in den Varianten mit
     Scheibe (56:2994, filled=filled und focus=yes). Die 12
     zwischen Lupe und Text sitzen an .suchleiste__gruppe.
     Am Component Set nachgemessen 08.09.2026; vorher stand hier
     irrtümlich 8. */
  gap: 6px;                                /* gemessen, siehe Kopf */
  flex: 1 0 0;
  min-width: 0;

  height: 45px;                            /* gemessen, siehe Kopf */
  padding-inline: var(--space-md);         /* 16 */
  border-radius: var(--radius-full);

  background-color: var(--searchbar);
  color: var(--text-description);
  cursor: pointer;
  text-align: left;

  /* Der Rand ist immer da, nur oft in derselben Farbe wie die
     Fläche — sonst springt die Leiste, sobald der Fokus ihn
     einfärbt (AGENTS.md §15). */
  border: var(--outline-default) solid var(--label-outline);
}

/* Auf einer Karte liegt das Feld VERTIEFT, nicht heller — genau
   wie der Chip dort (§5, §6). */
.suchleiste--auf-karte {
  background-color: var(--label-fill-inverted);
}

/* ------------------------------------------------------------
   Slim
   ------------------------------------------------------------
   36 statt 45. So steht die Leiste auf den mobilen Screens —
   gemessen an „Entdecken Mobile" (9018:8518) und am
   Inhalte-Screen (11784:8961), beide 353 x 36.

   Sie ist immer der TRIGGER, nie das Feld: darin wird nicht
   getippt, ein Klick führt auf den Suchscreen. Deshalb bleibt
   der Text bei 14 — die Ausnahme, die Lisi am 07.09.2026
   festgehalten hat. Als Eingabefeld dürfte sie nicht 36 hoch
   sein und der Text nicht 14.
   ------------------------------------------------------------ */

.suchleiste--slim {
  height: 36px;                            /* gemessen, siehe oben */
}

/* ------------------------------------------------------------
   Als Feld
   ------------------------------------------------------------
   Dieselbe Pille, aber mit einem echten <input> darin. Das
   <label> ist der Träger: ein Klick irgendwo auf die Pille
   setzt damit die Schreibmarke ins Feld, ohne eigenes JS.

   DER AKTIVE RAND HÄNGT AN :focus-within, nicht an :focus — das
   Fokus-Ziel ist das <input>, gerahmt wird die Pille.
   ------------------------------------------------------------ */

.suchleiste--feld {
  cursor: text;
}

/* MEDIUM TEXT, NICHT SMALL — zwei Gründe, beide zwingend.
   iOS Safari zoomt in jedes Formularfeld unter 16 px hinein,
   sobald es den Fokus bekommt; der Screen springt und kommt
   nicht von allein zurück. Und was getippt wird, ist Inhalt,
   den man beim Schreiben prüft — kein Label. Der Platzhalter
   erbt die Größe von hier, er braucht keine eigene Regel.
   Umgestellt am 08.09.2026, SKILL.md §6. */
.suchleiste__eingabe {
  flex: 1 0 0;
  min-width: 0;
  border: 0;
  padding: 0;
  background: none;
  color: var(--text-primary);

  font-family: var(--font-family-inter);
  font-size: var(--font-size-medium-text);
  line-height: var(--line-height-medium-text);
  font-weight: var(--font-weight-regular);
}

/* DER PLATZHALTER IST IMMER „Suche" — auch in der Kategorie-Suche.
   Der Geltungsbereich steht im Chip unter dem Feld, nicht hier: ein
   Platzhalter verschwindet beim ersten Tastendruck, der Chip bleibt
   und ist entfernbar. Zwei Folgen:
     · nichts läuft mehr über (53,6 von 190,6 px bei 393)
     · eine Zeichenkette statt einer je Kategorie
   Der Bereich muss aber im ZUGÄNGLICHEN NAMEN stehen — aria-label
   am Feld, in Flutter Semantics(label:). Wer nicht sieht, verknüpft
   den Chip unter dem Feld nicht mit dem Feld.
   Entschieden am 08.09.2026, SKILL.md §6. */
.suchleiste__eingabe::placeholder {
  color: var(--text-description);
  opacity: 1;                              /* Firefox dimmt sonst nach */
}

/* Sicherheitsnetz für lange Werte: text-overflow greift auch auf
   dem Platzhalter eines <input> — geprüft in Chromium 08.09.2026.
   Damit kürzt ein zu langer Text sichtbar mit …, statt mitten im
   Wort abgeschnitten zu werden. In Flutter läuft das über den
   TextField, nicht über CSS. */
.suchleiste__eingabe {
  text-overflow: ellipsis;
}

/* Der Ring gehört der Pille, nicht dem Feld darin — sonst lägen
   zwei Rahmen ineinander. */
.suchleiste__eingabe:focus-visible {
  outline: none;
}

/* DER FOKUS HAT DREI TEILE, nicht zwei (nachgemessen am
   Component Set 08.09.2026):
     1. Rand 2 px label-outline-active — hier als Randfarbe plus
        innerem Schatten, damit die Breite nicht springt (§23.6).
     2. Ein Schein nach außen: in Figma drop-shadow 0 0 2 auf
        Tags Labels/glow. Als äußerer box-shadow gebaut und nicht
        als filter: drop-shadow — ein filter macht aus der Pille
        einen eigenen Bezugsrahmen, und daran hängt hier nichts.
     3. Die Lupe wechselt auf denselben Akzent (siehe unten). */
.suchleiste--feld:focus-within {
  border-color: var(--label-outline-active);
  box-shadow:
    inset 0 0 0 var(--outline-default) var(--label-outline-active),
    0 0 2px var(--label-glow);
}

.suchleiste__ikon {
  display: block;
  overflow: visible;
  flex-shrink: 0;
  width: 16.58px;                          /* gemessen, siehe Kopf */
  height: 16.58px;
  /* Die Lupe ist in Figma weiß, nicht grau: sie ist das Signal
     „hier wird gesucht" und trägt die Affordanz. Der Text daneben
     ist der Platzhalter und bleibt grau. */
  color: var(--text-primary);
  transition: color calc(var(--motion-press) * var(--motion-scale)) var(--motion-ease-out);
}

/* IM FOKUS WIRD DIE LUPE BLAU. In Figma liegt in den
   focus-Varianten eine andere Zeichnung: derselbe Pfad, aber
   stroke #56B2DD statt #FCFDFD (56:2994, ausgelesen 08.09.2026).
   Das ist dieselbe Farbe wie der aktive Rand — Rand, Schein und
   Lupe sagen zusammen „hier tippst Du gerade". */
.suchleiste--feld:focus-within .suchleiste__ikon,
.suchleiste:focus-visible .suchleiste__ikon {
  color: var(--label-outline-active);
}

/* ------------------------------------------------------------
   Die innere Gruppe: Lupe + Text/Feld
   ------------------------------------------------------------
   Eigene Ebene, weil die Pille zwei verschiedene Abstände
   braucht: 12 zwischen Lupe und Text, 6 zwischen dieser Gruppe
   und dem Leeren-Knopf. Ein einzelnes Flex kann nur einen gap.
   ------------------------------------------------------------ */
.suchleiste__gruppe {
  display: flex;
  align-items: center;
  gap: var(--space-sm);                    /* 12 */
  flex: 1 1 auto;
  min-width: 0;
  cursor: inherit;
}

/* ------------------------------------------------------------
   Leeren-Knopf
   ------------------------------------------------------------
   Erscheint, sobald Text im Feld steht (§6). Die Optik kommt
   komplett aus icon-button.css: .ikon-button--klein für die
   30er Scheibe, .ikon-button--suchfeld für Fläche und Rand.
   Hier steht nur, wie er in der Pille sitzt.

   RECHTS 8 STATT 16: mit Leeren-Knopf zieht Figma das rechte
   Padding der Pille von 16 auf 8 (56:2994, filled=filled).
   Links bleiben 16.

   DIE HÖHE BLEIBT 45. In Figma wächst die Pille im gefüllten
   Zustand auf 46,23, weil die Scheibe 30,23 hoch ist und die
   Pille umschließt — das Feld würde beim ersten Zeichen um
   1,23 px höher springen. Hier ist die Höhe fest; die 0,23 ist
   in Figma nachzuziehen (siehe OFFEN).
   ------------------------------------------------------------ */
.suchleiste--gefuellt {
  padding-right: var(--space-xs);          /* 8 */
}

.suchleiste__text {
  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);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ------------------------------------------------------------
   Zustände
   ------------------------------------------------------------
   Der Fokus wächst den Rand von 1 auf 2 px — als inset
   box-shadow, NICHT über border-width (§23.6). Ein Wechsel der
   Randbreite verschiebt bei border-box den Inhalt um 1 px; ein
   Schatten läuft mit, ein Padding springt.
   ------------------------------------------------------------ */

@media (hover: hover) and (pointer: fine) {
  .suchleiste:hover {
    border-color: var(--button-ghost-outline);
  }
}

.suchleiste:focus-visible {
  border-color: var(--label-outline-active);
  box-shadow:
    inset 0 0 0 var(--outline-default) var(--label-outline-active),
    0 0 2px var(--label-glow);
  /* Der eigene Rand trägt den Fokus, wie beim Eingabefeld
     (§14, zwei Ausnahmen) — der weiße Ring aus base.css würde
     hier doppelt liegen. */
  outline: none;
}

.suchleiste {
  transition:
    border-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);
}

/* ============================================================
   OFFEN
   ------------------------------------------------------------
   · Erledigt am 08.09.2026: „Search thick" trägt bei focus=no,
     filled=filled jetzt 1 px label-outline. Der Hinweis in der
     Komponenten-Beschreibung („hatte GAR KEINEN Rand, ist dort
     nachzuziehen") ist damit abgearbeitet — am Set gegengeprüft.
   · Erledigt am 08.09.2026: die ✕-Scheibe ist gemessen. 30 x 30
     mit 8er Glyphe, aus `close icon button small` (11558:2130).
     Die 28 x 28 mit 7,3, die hier als Platzhalter standen, sind
     weg.
   · Erledigt am 08.09.2026: die Höhe. Ich hatte gemeldet, die
     Pille sei im gefüllten Zustand 1 px zu klein für ihren
     Inhalt — 45 hoch mit py 8 lässt 29 für eine 30 hohe
     Scheibe. Lisi hat es aufgelöst: „45px ist fixe höhe,
     padding ist entfernt". In Figma steht jetzt Höhe 45 fest,
     Innenabstand links 16, rechts 8, oben und unten 0. Genau so
     steht es hier auch; die Scheibe steht mittig mit 7,5 über
     und unter sich.
   · Erledigt am 08.09.2026: die Scheibe ist 30 x 30, bestätigt
     von Lisi („X ist 30 x 30"). Die 29,78 aus einer einzelnen
     Instanz sind in icon-button.css korrigiert.
   ============================================================ */

/* ------------------------------------------------------------
   Die ✕-Scheibe
   ------------------------------------------------------------
   Sie erscheint, sobald etwas im Feld steht, und leert es.

   ZUERST MUSS DIE DES BROWSERS WEG. Chrome malt an jedem
   <input type="search"> sein eigenes Kreuz
   (::-webkit-search-cancel-button). Das ist nicht das Zeichen
   aus dem System — es hat eine andere Form, eine andere Farbe
   und keine Scheibe darunter. Genau das war im Prototyp zu
   sehen (Lisi, 08.09.2026).

   DIE FLÄCHE FOLGT DEM UNTERGRUND, wie überall (§5, §6): auf
   surface-primary label-fill-inverted, auf einer Karte eine
   Stufe zurück nach oben auf label-fill. Steht so in der
   Komponenten-Beschreibung in Figma — auf der vertieften Fläche
   wäre label-fill-inverted derselbe Wert wie das Feld selbst,
   in Dark also Schwarz auf Schwarz.
   ------------------------------------------------------------ */

.suchleiste__eingabe::-webkit-search-cancel-button,
.suchleiste__eingabe::-webkit-search-decoration {
  -webkit-appearance: none;
  appearance: none;
}

/* SEIT 08.09.2026 IST DAS EINE KOMPONENTE, KEIN EIGENBAU.
   In Figma sitzt in der Variante filled=filled eine Instanz von
   `close icon button small` mit type=searchbar (56:2994 →
   11558:2130). Fläche, Rand, Zustände und die 30er Scheibe
   stehen deshalb in icon-button.css unter .ikon-button--klein
   und .ikon-button--suchfeld. Hier steht nur noch, WO der Knopf
   sitzt und WANN er da ist.

   Der vorher hier gebaute Eigenbau ist ersetzt. Er hatte 28
   statt 30, ein 7,3er Glyph statt 8, keinen Rand — und sein
   Hover zeigte auf --ghost-fill-hover, ein Token, das es nicht
   gibt (es heißt --button-ghost-fill-hover). Der Hover war also
   wirkungslos. */

.suchleiste__leeren {
  flex: 0 0 auto;
  display: none;                           /* erst mit Inhalt */
}

.suchleiste--gefuellt .suchleiste__leeren {
  display: inline-flex;
}

/* AUF EINER KARTE IST ES EIN ANDERER TYP, KEINE ÜBERSCHRIEBENE
   FARBE. Figma löst den Fall seit dem 08.09.2026 so: die Variante
   `Search inverted, filled=filled` setzt keine searchbar-Scheibe
   ein, sondern `close icon button small` mit type=filled. Dessen
   Fläche icon-button-fill ist in beiden Modes derselbe Wert wie
   label-fill — also genau die Stufe zurück nach oben, die §6
   verlangt: auf der vertieften Fläche wäre label-fill-inverted
   derselbe Wert wie das Feld, in Dark Schwarz auf Schwarz.

   Im Markup heißt das: auf einer Karte OHNE .ikon-button--suchfeld
   arbeiten, nur .ikon-button--klein. Dann kommt auch das
   Zustandsmodell des gefüllten Knopfes mit (Fläche wechselt,
   Rand erst beim Drücken) statt des searchbar-Modells (Fläche
   bleibt, Rand wechselt).

     <button class="suchleiste__leeren ikon-button
                    ikon-button--klein touch-target" …>

   Deshalb steht hier keine Farbregel mehr. */

/* ============================================================
   Filter-Button
   ------------------------------------------------------------
   Quelle: Figma „Screens: App und Web" → filter button,
   Instanz I12845:14657;11142:1452, ausgelesen am 04.09.2026.

   Er gehört zur Suchleiste, nicht zu den Buttons: in Figma
   liegt er IM Search-Bar-Frame, und SKILL.md §6 führt
   „Listen-Controls (Filter · Sortieren)" als eigene Familie
   neben der Suchleiste. Deshalb steht er hier und nicht in
   einer Button-Datei.

   Die Farben sind die des Icon-Buttons — es ist derselbe
   neutrale, freistehende Typ, nur mit Label.

   VERWENDUNG
     <div class="suchzeile">
       <button class="suchleiste">…</button>
       <button class="filter-button" type="button">
         Filter
         <svg class="filter-button__ikon"><use href="#icon-filter"></use></svg>
       </button>
     </div>

   ------------------------------------------------------------
   GEMESSENE MASSE OHNE TOKEN-GRUNDLAGE
     5           Abstand Label zu Icon (Figma gap-[5px]).
     17,7 x 14,2 Icon.
   ============================================================ */

/* Suchleiste und Filter-Button sitzen zusammen in einer Zeile —
   in Figma ist das ein Frame, der als Ganzes 320 breit ist. */
.suchzeile {
  display: flex;
  align-items: center;
  gap: var(--space-xs);                    /* 8 */
  flex-shrink: 0;
}

.filter-button {
  display: inline-flex;
  align-items: center;
  gap: 5px;                                /* gemessen, siehe Kopf */
  flex-shrink: 0;

  height: 45px;
  padding-inline: var(--space-md);         /* 16 */
  border-radius: var(--radius-full);

  background-color: var(--button-icon-button-fill);
  /* Innerer Schatten statt border: die Breite ergibt sich aus
     dem Inhalt, ein border machte den Knopf 89,8 statt 87
     (AGENTS.md §8a). Nachgezogen am 04.09.2026. */
  --fb-strich: var(--button-icon-button-outline);
  box-shadow: inset 0 0 0 var(--outline-default) var(--fb-strich);
  color: var(--button-icon-button-text);
  cursor: pointer;

  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);
  white-space: nowrap;
}

.filter-button__ikon {
  display: block;
  overflow: visible;
  flex-shrink: 0;
  width: 17.7px;                           /* gemessen, siehe Kopf */
  height: 14.2px;
}

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

.filter-button:active {
  background-color: var(--button-icon-button-fill-press);
  --fb-strich: var(--button-icon-button-outline-press);
  transform: scale(0.97);
}

.filter-button {
  transition:
    transform        calc(var(--motion-press) * var(--motion-scale)) var(--motion-ease-out),
    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) {
  .filter-button:active {
    transform: none;
  }
}
