/* ==========================================================================
   components/formular.css
   Formularfelder und Absendeknopf. Als Komponente angelegt, nicht
   seitenspezifisch: /kontakt/ braucht sie zuerst, /handel/kontakt/ und
   /karriere/initiativbewerbung/ sind im Stand ebenfalls vorgesehen.

   Es gibt im Projekt bisher keine Formularregeln und keine Knopfklasse -
   dieser Baustein legt beides an. Alle Werte kommen aus Tokens.

   TREFFERFLAECHEN: jedes Feld mindestens 2,75rem hoch, das sind 44 px. Auf
   dem Telefon ist ein Formular sonst nicht bedienbar.
   ========================================================================== */

.form {
  display: grid;
  /* --sp-4 statt --sp-5, also 16 statt 24 px: die Felder tragen ihr Label
     direkt darueber, der Abstand zum NAECHSTEN Feld muss deutlich groesser
     sein als der zwischen Label und Feld (--sp-2, 8 px). 16 zu 8 haelt das
     Verhaeltnis, 24 zu 8 zog das Formular unnoetig auseinander.
     Wunsch vom 28.08.2026. */
  gap: var(--sp-4);
  /* Ein Formular ist eine Spalte Lesetext. Ueber 34rem wandert das Auge beim
     Zeilenwechsel zu weit, und die Felder wirken wie eine Tabelle. */
  max-width: 34rem;
}

/* Zwei Felder in einer Zeile, wo es inhaltlich zusammengehoert - Name und
   E-Mail, Telefon und Firma. Bricht unter 30rem auf eine Spalte. */
.form__reihe {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* Senkrecht wie das Formular, waagerecht mehr: nebeneinanderstehende
     Felder brauchen eine deutlichere Trennung als uebereinanderstehende,
     sonst liest man sie als ein Feld. */
  gap: var(--sp-4) var(--sp-5);
}
@media (max-width: 30rem) {
  .form__reihe { grid-template-columns: 1fr; }
}

/* margin: 0 ZWINGEND. Das Feld ist ein <p> und traegt sonst den
   Standardrand des Browsers von 16 px oben und unten. Der addiert sich zum
   Gitterabstand, weil Raender an Gitterkindern nicht kollabieren - gemessen
   ergab das 48 px zwischen zwei Feldern und 32 px zur Reihe darueber,
   obwohl 16 px eingestellt waren. Die Abstaende waren dadurch auch
   ungleich, je nachdem ob ein <p> oder ein <div> davor stand.
   Dasselbe gilt fuer .form__hinweis und .form__honigtopf, die ebenfalls
   <p> sind - beide setzen ihren Rand selbst auf 0. */
.form__feld {
  display: grid;
  /* align-content: start ZWINGEND, sonst sind die Felder ungleich hoch.
     Gemessen am 16.09.2026: in einer Reihe aus zwei Feldern bestimmt das
     höhere die Zeilenhöhe - trägt das eine einen Hilfetext und das andere
     nicht, streckt sich das Eingabefeld ohne Hilfetext auf 59 px, während
     seine Nachbarn auf 46 stehen. Am auffälligsten beim Aktionsprodukt
     neben dem Gewinncode und bei der E-Mail neben dem Geburtsdatum.
     Dieselbe Krankheit wie bei den Rasterreihen im Projekt: überschüssige
     Höhe wandert in das Kind, das sich strecken darf. */
  align-content: start;
  gap: var(--sp-2);
  margin: 0;
  min-width: 0;
}

/* Label IMMER sichtbar, nie nur als Platzhalter im Feld. Ein Placeholder
   verschwindet beim Tippen - wer beim dritten Feld nachsehen will, was oben
   gefragt war, hat es dann nicht mehr. */
.form__label {
  font-size: var(--fs-200);
  font-weight: 500;
  color: var(--toem-blau);
}
/* Pflichtstern: das Sternchen ist Dekoration, die Aussage traegt required am
   Feld. Deshalb aria-hidden am Stern und ein Hinweissatz ueber dem Formular. */
.form__pflicht {
  color: var(--toem-gold);
  /* Auf hell haelt Gold als Schrift nur 1,46:1. Hier vertretbar, weil das
     Zeichen reine Wiederholung ist - required steht am Feld und der
     Hinweissatz nennt die Regel im Klartext. */
  margin-left: 0.15em;
}
.form__hinweis {
  font-size: var(--fs-100);
  color: var(--text-muted);
  margin: 0;
}

/* --- Eingabefelder ------------------------------------------------------ */
.form__eingabe,
.form__auswahl,
.form__text {
  width: 100%;
  min-height: var(--feld-hoehe, 2.875rem);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--c-grau-300);
  border-radius: var(--r-md);
  font: inherit;
  font-size: var(--fs-200);
  line-height: var(--lh-snug);
  color: var(--text-body);
  transition: border-color var(--dur) var(--ease);
}
/* EINE FESTE HOEHE FUER ALLE EINZEILIGEN FELDER, Wunsch vom 16.09.2026.
   min-height allein reicht nicht: gemessen standen Texteingaben auf 45 px
   (Inhalt: 15 px Schrift plus 2x12 px Innenabstand plus Rahmen), das
   Datumsfeld auf 47 (es bringt seinen eigenen Kalenderknopf mit) und das
   Dateifeld auf 50. Der Inhalt war jedes Mal höher als die Mindesthöhe,
   also griff sie nie.
   2,875rem sind 46 px - die Höhe, auf der die Texteingaben auf Touchbreiten
   ohnehin schon standen. Damit ändert sich am abgenommenen Kontaktformular
   nichts Sichtbares, und die Trefferfläche bleibt über 44 px. */
.form__eingabe,
.form__auswahl { height: var(--feld-hoehe, 2.875rem); }

/* --- Das Datumsfeld auf iOS ---------------------------------------------
   GEMELDET AM 16.09.2026 mit Bildschirmfoto vom iPhone: „Geburtsdatum" steht
   breiter als jedes andere Feld, ragt ueber den rechten Rand und zieht eine
   waagerechte Scrollbahn durch die ganze Seite. Auffallend auf dem Bild: das
   Feld ist auch HOEHER als seine Nachbarn. Beide Masse, die wir setzen,
   werden also uebergangen.

   Das ist die Signatur eines nativen Bedienelements. Mobile Safari rendert
   input[type=date] nicht als Textfeld, sondern als eigenes Steuerelement mit
   eigener Mindestgroesse; width und height des Autors greifen daran nicht.
   Erst -webkit-appearance: none macht aus dem Steuerelement wieder ein Feld,
   das sich an unsere Angaben haelt. Das Auswahlrad bleibt, es haengt am
   Eingabetyp und nicht an der Darstellung.

   WARUM ES HIER NICHT NACHZUSTELLEN WAR: geprueft in Chromium und in WebKit,
   bei 320/360/375/390/414/430/480/540 - beide setzen das Feld exakt in seine
   Bahn (350 von 350 bei 390 px) und zeigen keinen Ueberlauf. Desktop-WebKit
   ist dieselbe Engine, aber nicht dasselbe Steuerelement: den nativen Typ von
   iOS gibt es nur auf dem Geraet.

   min-width: 0 daneben, weil die Mindestbreite sonst aus dem Inhalt kommt -
   dieselbe Krankheit, nur eine Ebene tiefer.
   Die beiden Pseudoelemente raeumen den Innenraum: ohne sie sitzt der Wert
   auf iOS mittig und traegt einen eigenen Rand, und das Feld liest sich neben
   den linksbuendigen Nachbarn falsch.
   In Chromium bleibt das Kalendersymbol erhalten - nachgemessen, appearance:
   none entfernt dort nur den Rahmen, den wir ohnehin selbst zeichnen. */
.form__eingabe[type="date"] {
  -webkit-appearance: none;
  appearance: none;
  min-width: 0;
}
.form__eingabe[type="date"]::-webkit-date-and-time-value {
  text-align: left;
  margin: 0;
  min-width: 0;
}
.form__eingabe[type="date"]::-webkit-datetime-edit {
  padding: 0;
}

.form__text {
  height: auto;
  min-height: 8rem;
  /* Nur senkrecht: waagerechtes Ziehen sprengt das Raster. */
  resize: vertical;
}
.form__eingabe:hover,
.form__auswahl:hover,
.form__text:hover { border-color: var(--toem-blau); }

/* Der globale Fokusring aus base.css liegt aussen. An einem Feld mit eigener
   Kante ergibt das zwei Linien; deshalb hier die Kante mitfaerben, damit es
   als ein Ring liest. */
.form__eingabe:focus-visible,
.form__auswahl:focus-visible,
.form__text:focus-visible { border-color: var(--toem-blau); }

/* Eigener Pfeil am Auswahlfeld: der Systempfeil sieht auf jedem Betriebs-
   system anders aus. Als data-URI, damit kein zusaetzlicher Request
   entsteht - dieselbe Strichstaerke wie die Chevrons der Navigation. */
.form__auswahl {
  appearance: none;
  padding-right: var(--sp-8);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%230c243e' stroke-width='1.75'%3E%3Cpath d='M4 6.5l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  /* --sp-5 statt --sp-4, Wunsch vom 16.09.2026: 24 statt 16 px Abstand zur
     rechten Kante. Gemessen sass der Winkel bei calc(100% - 16px) und damit
     naeher am Rand als jeder Text im Formular - die Beschriftungen und
     Eingaben beginnen bei 16 px vom LINKEN Rand, der Winkel stand rechts
     also auf derselben Linie wie Text, obwohl er kleiner ist und dadurch
     gedraengt wirkt.
     Das Polster rechts bleibt --sp-8 (64 px): der Winkel belegt damit 24 bis
     40 px, der Text endet bei 64 - 24 px Luft dazwischen. */
  background-position: right var(--sp-5) center;
  background-size: 1rem 1rem;
  cursor: pointer;
}

/* --- Einwilligung ------------------------------------------------------- */
/* Kein vorausgefuelltes Haekchen. Eine Einwilligung, die schon gesetzt ist,
   ist keine Einwilligung. */
.form__einwilligung {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: var(--sp-3);
  font-size: var(--fs-100);
  line-height: var(--lh-body);
  color: var(--text-muted);
}
.form__haken {
  /* 1,25rem Kasten in einer 2,75rem hohen Trefferflaeche: das Label liegt
     daneben und gehoert dazu, angetippt wird also der ganze Block. */
  width: 1.25rem;
  height: 1.25rem;
  margin: 0.15rem 0 0;
  accent-color: var(--toem-blau);
  flex: none;
  cursor: pointer;
}
/* KEINE UNTERSTRICHE AN TEXTLINKS. Projektregel vom 28.08.2026: Links werden
   ueber Schriftdicke und Farbe gekennzeichnet, nicht ueber eine Linie. Wo ein
   Link am Satzende steht, darf der Pfeil aus den uebrigen Bausteinen dazu
   kommen. */
.form__einwilligung a {
  font-weight: 600;
  color: var(--toem-blau);
  transition: color var(--dur) var(--ease);
}
.form__einwilligung a:hover,
.form__einwilligung a:focus-visible { color: var(--toem-gold); }

/* --- Honigtopf ---------------------------------------------------------- */
/* Spamschutz ohne Drittanbieter-Captcha, wie im Stand gefordert: ein Feld,
   das nur ein Automat ausfuellt. Serverseitig verwerfen, wenn es gefuellt
   ankommt. Zusaetzlich prueft die Verarbeitung den Zeitstempel.
   NICHT display: none - manche Automaten erkennen das. Aus dem Blickfeld
   geschoben, aus der Tabreihenfolge genommen und fuer Screenreader
   verborgen. */
.form__honigtopf {
  margin: 0;
  /* NICHT MEHR left: -9999px, geaendert am 16.09.2026.

     Die alte Fassung schob den Koeder 9999 px nach links aus dem Bild. Das
     ist die verbreitete Technik und in Chromium harmlos - links
     ueberstehender Inhalt wird dort nicht scrollbar. Auf mobilen Browsern
     ist das aber nicht verlaesslich, und gemeldet wurde genau das: auf dem
     Telefon stand dauerhaft ein Scrollbalken. Nachgemessen war dieser
     Absatz das EINZIGE Element der Seite ausserhalb des Sichtfelds
     (-9999 bis -9846 px).

     Der Ersatz ist die Standardtechnik fuer optisch verborgene Inhalte: ein
     Punkt von 1 px, dessen Inhalt weggeschnitten wird. Der Koeder bleibt
     damit an seinem Platz im Dokument, hat aber keine Flaeche mehr.

     WICHTIG FUER DEN ZWECK: es bleibt bei `position: absolute` und einem
     sichtbaren Element - kein display: none und kein visibility: hidden.
     Genau das ist der erste Test, den ein halbwegs gebauter Automat macht;
     wer das Feld versteckt, verraet es damit. clip-path faellt bei dieser
     Pruefung nicht auf. */
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
/* Auch der Inhalt bleibt im Punkt. Der Elternkasten schneidet zwar ab, aber
   das Eingabefeld darin war weiter 153 px breit und ragte bei 320 px Fenster
   rechnerisch ueber den Rand - sichtbar nichts, messbar schon. Was nicht
   ueber den Rand ragt, kann auch keinen Balken erzeugen. */
.form__honigtopf label,
.form__honigtopf input { width: 1px; }

/* --- Absenden ----------------------------------------------------------- */
/* Erste Knopfklasse im Projekt. Blau als Flaeche mit weisser Schrift -
   gemessen 15,70:1. Gold als Flaeche mit blauer Schrift waere die
   Alternative, traegt aber schlechter, wenn der Knopf auf einer hellen Bahn
   allein steht. */
/* Aussehen kommt aus components/knopf.css - EINE Definition fuer den
   Haus-Knopf. Hier bleibt nur, was am Formularraster haengt. */
.form__senden {
  justify-self: start;
}
.form__senden svg {
  width: var(--zeichen-inline);
  height: var(--zeichen-inline);
  transition: transform var(--dur-hover) var(--ease-hover);
}
.form__senden:hover svg,
.form__senden:focus-visible svg { transform: translateX(3px); }

/* --- Eingabefelder auf Touchgeraeten: 16 px, nicht 15 -------------------
   Gefunden beim responsiven Durchgang am 10.09.2026. Gemessen trugen die
   sichtbaren Felder des Kontaktformulars 15 px (--fs-200):
     form__eingabe text/email  15 px
     form__auswahl select      15 px
     form__text    textarea    15 px

   DAS IST KEIN SCHOENHEITSFEHLER, SONDERN EIN BEDIENFEHLER auf iOS. Safari
   zoomt beim Fokus automatisch in die Seite hinein, wenn ein Eingabefeld
   kleiner als 16 px gesetzt ist - der Besucher tippt in ein Feld und muss
   danach von Hand wieder herauszoomen. Das gilt fuer iPhone UND iPad,
   deshalb greift die Regel bis 64rem und nicht nur bis zur Telefonbreite.

   NUR AUF TOUCHBREITEN, damit die abgenommene Desktopgestaltung unangetastet
   bleibt: dort sind 15 px eine bewusste Wahl und richten keinen Schaden an.
   Das Bewerbungsformular hatte es bei den Textfeldern schon richtig (16 px);
   dort fehlten nur die sechs Dateifelder, siehe pages/bewerbung.css. */
@media (max-width: 64rem) {
  .form__eingabe,
  .form__auswahl,
  .form__text { font-size: 1rem; }
}

/* --- Meldung nach dem Absenden ------------------------------------------ */
/* DIESE ZWEI REGELN HAT DER ENTWURF NICHT, weil es dort keine Verarbeitung
   gibt. Sie erscheinen nur nach einem Absenden - auf der ruhenden Seite ist
   das Markup unverändert, und der Vergleich gegen den Prototyp bleibt
   deckungsgleich.
   KEIN ROT UND KEIN GRUEN AUS DEM NICHTS: die gute Meldung traegt das Gold
   der Marke als Linie, die schlechte das Rot, das die Sorte "heiss braten"
   ohnehin mitbringt. */
.form__meldung {
  /* ANGEGLICHEN AN DIE BEWERBUNG, Wunsch vom 17.09.2026. Vorher 16 px
     Abstand und ein Balken von 3 px - auf dem Grund der Seite war das kein
     Signal, und die Meldung las sich wie die erste Zeile des Formulars.
     32 statt 48 px, weil diese Meldung kleiner ist und naeher am Formular
     sitzt; das Verhaeltnis zum Innenabstand ist dasselbe. */
  margin: 0 0 var(--sp-6);
  padding: var(--sp-3) var(--sp-4);
  border-left: 6px solid var(--toem-gold);
  /* ABSTAND FUER DIE FIXIERTE KOPFZEILE. Die Umleitung springt auf
     #formular-<kennung>, und ohne diese Zeile landet die Meldung unter der
     Kopfzeile - derselbe Fehler, der auf der Bewerbungsseite gemessen wurde
     (Oberkante 32 px, Kopfzeile 68 px hoch). */
  scroll-margin-top: calc(var(--h-nav-compact) + var(--sp-5));
  /* WEISS, NICHT --bg-soft. Die Kontaktsektion steht selbst auf --bg-soft;
     die Meldung hatte damit exakt die Farbe ihrer Unterlage und war kein
     Kasten mehr, sondern ein Balken mit Text daneben. Gemeldet am
     17.09.2026. Auf der Bewerbungsseite stand von Anfang an --surface. */
  background: var(--surface);
  font-size: var(--fs-300);
  line-height: var(--lh-body);
  color: var(--c-ink);
}

/* Das Sprungziel ist das Formular, nicht die Meldung - es traegt die id.
   Derselbe Abstand, damit der Sprung nicht unter der Kopfzeile endet. */
.form { scroll-margin-top: calc(var(--h-nav-compact) + var(--sp-5)); }

.form__meldung--schlecht {
  border-left-color: var(--c-sorte-braten, #b23);
}

/* --- Fehler am Feld ------------------------------------------------------
   NACHGETRAGEN AM 29.09.2026 fuer /gold/, Wunsch des Kunden: „in den Feldern
   direkt rot markieren, wo ich noch was machen muss". Dasselbe Muster wie
   im Bewerbungsformular (pages/bewerbung.css): Kante UND Satz. Nur eine rote
   Kante waere fuer Menschen mit Rot-Gruen-Schwaeche keine Information; nur
   ein Satz ohne Kante findet man im langen Formular nicht wieder.
   aria-invalid setzen js/gold.js und, ohne Skript, inc/gewinnspiel.php. */
.form__eingabe[aria-invalid="true"],
.form__auswahl[aria-invalid="true"],
.codefeld__stelle[aria-invalid="true"] { border-color: var(--c-fehler); }
.form__fehler {
  font-size: var(--fs-100);
  font-weight: 600;
  color: var(--c-fehler);
}
/* Unter der Einwilligung steht der Satz unter dem Text, nicht unter dem
   Haken - das Feld ist ein Raster aus Haken und Text. */
.form__einwilligung .form__fehler { grid-column: 2; }
.form__haken[aria-invalid="true"] { outline: 2px solid var(--c-fehler); outline-offset: 2px; }

/* --- Feldgruppen ---------------------------------------------------------
   NACHGETRAGEN AM 16.09.2026 fuer die Gewinnspielseite /gold/. Das
   Kontaktformular kommt mit fuenf Feldern aus und braucht keine Gliederung;
   das Einsendeformular hat sechzehn, und die zerfallen in drei Gruppen:
   was auf der Flasche steht, wer einsendet, und was freiwillig ist.

   ALS <fieldset> MIT <legend>, nicht als div mit Ueberschrift. Ein
   Screenreader nennt bei jedem Feld die Gruppe mit, in der es steht - bei
   sechzehn Feldern ist das der Unterschied zwischen Orientierung und Raten.
   Dieselbe Entscheidung wie im Bewerbungsformular, siehe pages/bewerbung.css.

   DER BROWSER-EIGENE RAHMEN MUSS WEG, sonst steht das Formular in drei
   verschachtelten Kaesten. border, margin und padding werden deshalb alle
   drei gesetzt; min-inline-size verhindert, dass ein fieldset im Raster auf
   min-content zusammenfaellt - das ist die alte Eigenart des Elements und
   der Grund, warum fieldsets in Gitterlayouts als kaputt gelten. */
.form__gruppe {
  display: grid;
  gap: var(--sp-4);
  border: 0;
  margin: 0;
  padding: 0;
  min-inline-size: 0;
}
/* Abstand ZWISCHEN den Gruppen, nicht innerhalb: die Gruppe selbst haelt
   --sp-4 wie das Formular, zur naechsten Gruppe gehoert mehr. --sp-4 aus
   dem Gitter plus --sp-5 hier ergeben gemessen 40 px. */
.form__gruppe + .form__gruppe { margin-top: var(--sp-5); }

/* legend sitzt von Haus aus IN der Rahmenlinie und traegt eigenes padding.
   Ohne float/display-Korrektur laesst sich sein Abstand nach unten nicht
   setzen - deshalb display: block und die Breite ausdruecklich auf 100 %. */
.form__gruppe-titel {
  display: block;
  width: 100%;
  padding: 0;
  margin: 0 0 var(--sp-2);
  /* --fs-400 statt --fs-300, Wunsch vom 16.09.2026: 18 statt 16 px. Eine
     Zwischenueberschrift, die genauso gross ist wie die Feldbeschriftungen
     darunter, fuehrt sie nicht an - sie steht nur dabei.
     NICHT --fs-450 (20 px): so gross war sie im Bewerbungsformular, als sie
     noch auf einer weissen Karte sass und sich gegen deren Flaeche behaupten
     musste. Ohne Karte traegt die goldene Linie die Trennung, und die
     Ueberschrift darf leiser sein. */
  font-size: var(--fs-400);
  font-weight: 600;
  color: var(--toem-blau);
  /* Die Linie ersetzt den Rahmen: sie trennt die Gruppen, ohne sie
     einzukasten. Gold als reine Trennlinie, nicht als Schrift - fuer
     dekorative Grafik gilt die 3:1-Regel nicht. */
  border-bottom: 1px solid var(--toem-gold);
  padding-bottom: var(--sp-2);
}
/* ABSTAND ZUR ERSTEN BESCHRIFTUNG, Wunsch vom 16.09.2026. Vorher standen
   zwischen der Linie unter "Angaben von Flasche und Deckel" und dem ersten
   Feldnamen 8 px Rand plus 16 px Rasterabstand, also 24 - genauso viel wie
   zwischen zwei Feldern derselben Gruppe. Die Ueberschrift klebte damit an
   ihrem Inhalt, statt ihn anzufuehren.
   GEMESSEN WIRD DAVON NUR DER RAND: ein <legend> ist in Chrome KEIN
   Rasterkind seines fieldsets - der Browser setzt es ausserhalb der
   anonymen Inhaltsbox. Der Zeilenabstand des Rasters (16 px) greift
   zwischen Ueberschrift und erstem Feld also nicht, der Rand steht allein
   da. Mit --sp-5 waren es deshalb 24 statt der erwarteten 40 px; mit
   --sp-6 sind es 32. */
.form__gruppe-titel { margin-bottom: var(--sp-6); }

/* --- Breiteres Formular --------------------------------------------------
   .form deckelt auf 34rem, weil ein Formular eine Spalte Lesetext ist. Das
   stimmt bei fuenf Feldern. Bei sechzehn wird die Spalte zur Schlange:
   gemessen 1340 px Hoehe auf dem Desktop, also zweimal scrollen, bevor der
   Absendeknopf auftaucht. 48rem lassen zwei Felder nebeneinander stehen und
   bleiben trotzdem schmaler als die Inhaltsbahn. */
.form--weit { max-width: 48rem; }

/* Zwei Felder, von denen eins schmal ist - PLZ und Ort. Fuenf Ziffern in
   einem Feld von Ortsbreite sehen aus wie ein Fehler. */
.form__reihe--ungleich { grid-template-columns: minmax(0, 9rem) minmax(0, 1fr); }
@media (max-width: 30rem) {
  .form__reihe--ungleich { grid-template-columns: 1fr; }
}
/* Ein einzelnes schmales Feld ausserhalb einer Reihe, etwa die Anrede.
   min() statt einer festen Breite: unter 14rem Bahnbreite gewinnt sonst die
   Angabe und das Feld ragt hinaus. */
.form__feld--schmal { max-width: min(14rem, 100%); }


/* --- Dateifeld ----------------------------------------------------------
   DER KNOPF DES BROWSERS IST KEINE GESTALTUNG. „Datei auswaehlen | Keine
   ausgewaehlt" sieht auf jedem Betriebssystem anders aus, traegt die
   Systemschrift und liest sich neben den uebrigen Feldern wie ein Fremdkoerper.
   Beanstandet am 16.09.2026 - zu Recht; das Bewerbungsformular hat dieselbe
   Stelle und sieht genauso aus.

   DAS FELD WIRD NICHT ERSETZT, SONDERN GELEGT: das echte input[type=file]
   liegt durchsichtig ueber der gestalteten Flaeche. Damit bleibt alles, was
   ein natives Dateifeld kann - anklicken, Tabulator, Enter, Dateien
   hineinziehen - und zwar OHNE Javascript. Ein nachgebauter Knopf aus
   <span> plus Skript verliert genau das, und bei einem Pflichtfeld ist das
   kein hinnehmbarer Ausfall (dieselbe Ueberlegung steht seit dem 04.09.2026
   in pages/bewerbung.css, dort fuehrte sie zum rohen Knopf - hier fuehrt sie
   zu diesem Aufbau).

   RUECKMELDUNG OHNE SKRIPT ueber :required:valid. Ein PFLICHTFELD ohne
   Datei ist ungueltig, mit Datei gueltig - daran haengen Rahmen, Farbe und
   Haken, ganz ohne Javascript.
   WARUM :required DAZUGEHOERT: im Bewerbungsformular sind die sechs
   Dateifelder NICHT verpflichtend, eines von sechs genuegt und das prueft
   das Skript. Ein leeres optionales Feld ist aber :valid - ohne den Zusatz
   truegen dort alle sechs Felder von Anfang an den Haken. Fuer sie setzt
   js/main.js die Klasse .dateifeld--gefuellt, sobald wirklich etwas drin
   ist; beide Wege fuehren zur selben Darstellung.

   GESTRICHELT, solange nichts drin ist: dieselbe Sprache wie bei den
   Bildplaetzen und den fehlenden Haendlerlogos - hier gehoert etwas hin,
   das noch fehlt. Mit Datei wird die Linie durchgezogen. */
.dateifeld {
  position: relative;
  display: block;
}
/* Nicht display:none und nicht visibility:hidden - beides naehme dem Feld
   die Bedienbarkeit. Durchsichtig und deckend darueber ist der einzige Weg,
   der Maus, Tastatur und Ziehen erhaelt. */
.dateifeld__quelle {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}
.dateifeld__flaeche {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--feld-hoehe, 2.875rem);
  padding: 0 var(--sp-4);
  border: 1px dashed var(--c-grau-300);
  border-radius: var(--r-md);
  background: var(--surface);
  font-size: var(--fs-200);
  color: var(--text-muted);
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.dateifeld:hover .dateifeld__flaeche { border-color: var(--toem-blau); }

/* Der Fokusring des durchsichtigen Feldes waere unsichtbar. Er wird deshalb
   auf die Flaeche gezeichnet - dieselben Werte wie der globale Ring in
   base.css, damit es derselbe Ring ist und nicht einer, der so aussieht. */
.dateifeld__quelle:focus-visible + .dateifeld__flaeche {
  outline: 2px solid var(--toem-blau);
  outline-offset: 3px;
  border-color: var(--toem-blau);
}

.dateifeld__zeichen {
  flex: none;
  width: var(--zeichen-klein);
  height: var(--zeichen-klein);
  color: var(--toem-blau);
}
.dateifeld__zeichen--haken { display: none; color: var(--toem-gold); }

/* WELCHES ZEICHEN, entscheidet die Seite: eine Kamera, wo ein Foto vom
   Deckel verlangt wird (/gold/), ein Dokument, wo PDF-Unterlagen hochgeladen
   werden (/karriere/bewerbung/). Eine Kamera ueber einem Lebenslauf waere
   eine falsche Ansage. */
.dateifeld__zeichen--dokument { color: var(--toem-blau); }

/* Mit Datei: durchgezogene Linie, Haken statt Kamera oder Dokument, Text in
   Fliesstinte. */
.dateifeld__quelle:required:valid + .dateifeld__flaeche,
.dateifeld--gefuellt .dateifeld__flaeche { border-style: solid; }
.dateifeld__quelle:required:valid + .dateifeld__flaeche .dateifeld__text,
.dateifeld--gefuellt .dateifeld__text { color: var(--text-body); }
.dateifeld__quelle:required:valid + .dateifeld__flaeche .dateifeld__zeichen--kamera,
.dateifeld__quelle:required:valid + .dateifeld__flaeche .dateifeld__zeichen--dokument,
.dateifeld--gefuellt .dateifeld__zeichen--kamera,
.dateifeld--gefuellt .dateifeld__zeichen--dokument { display: none; }
.dateifeld__quelle:required:valid + .dateifeld__flaeche .dateifeld__zeichen--haken,
.dateifeld--gefuellt .dateifeld__zeichen--haken { display: block; }

/* FEHLER MUSS SICHTBAR BLEIBEN. js/bewerbung.js setzt aria-invalid an das
   Feld; das Feld ist hier aber durchsichtig, die rote Kante der uebrigen
   Felder traefe also niemanden. Sie wandert deshalb auf die Flaeche.
   Ohne diese Regel waere der Umbau eine Verschlechterung: die Meldung
   stuende da, das zugehoerige Feld saehe aus wie jedes andere. */
.dateifeld__quelle[aria-invalid="true"] + .dateifeld__flaeche {
  border-style: solid;
  border-color: var(--c-fehler, #a3242f);
}

/* Ein Dateiname kann sehr lang sein. Er bricht nicht um, sondern endet mit
   drei Punkten - sonst waere das Feld je nach Datei zwei Zeilen hoch und
   stuende neben den anderen schief. */
.dateifeld__text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Codefeld aus sieben Stellen ----------------------------------------
   SIEBEN ECHTE EINGABEFELDER, Wunsch vom 16.09.2026. Hier stand vorher EIN
   Feld, dessen Untergrund sieben Striche zeichnete - sichtbar dasselbe, aber
   eben nur gezeichnet, und der Wunsch war ausdruecklich ein anderer.

   WAS DAS KOSTET, und wie es aufgefangen wird: sieben Felder koennen nicht
   von selbst weiterspringen, nehmen einen eingefuegten Code nicht an und
   heissen fuer einen Screenreader sieben Mal gleich. Das erste und zweite
   erledigt js/gold.js, das dritte ein aria-label je Stelle. Ohne Javascript
   bleibt das Formular vollstaendig bedienbar - sieben Mal Tab.

   GLEICHE HOEHE WIE JEDES ANDERE FELD (--feld-hoehe): die Stellen stehen in
   derselben Spalte wie Mindesthaltbarkeitsdatum und Charge.

   Schreibmaschinenschrift, damit ein I so breit ist wie ein W und die
   Zeichen mittig in ihren Kaestchen stehen - siehe --font-code. */
.codefeld {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--sp-2);
  /* UEBER DIE GANZE FORMULARBREITE, Wunsch vom 16.09.2026: der Code soll
     der Blickfang des Formulars sein. Die Deckelung auf 24rem ist deshalb
     entfallen; die Zeile gehoert jetzt ihm allein. */
}
.codefeld__stelle {
  width: 100%;
  /* QUADRATISCH STATT ZEILENHOCH. Ueber die volle Breite sind die Kaestchen
     bei 1440 px rund 99 px breit - mit den 46 px der uebrigen Felder waeren
     das Briefschlitze. Mit aspect-ratio wachsen sie mit und sehen auf jeder
     Breite wie ein Codefeld aus.
     Gedeckelt auf 5rem: ganz ohne Grenze stuenden am Schirm sieben Quadrate
     von 99 px, und das Formular haette einen Kopf statt eines ersten Feldes.
     Die Untergrenze von --feld-hoehe haelt sie auf dem Telefon so hoch wie
     jedes andere Feld. */
  aspect-ratio: 1 / 1;
  height: auto;
  min-height: var(--feld-hoehe, 2.875rem);
  max-height: 5rem;
  padding: 0;
  background: var(--surface);
  border: 1px solid var(--c-grau-300);
  border-radius: var(--r-md);
  font-family: var(--font-code);
  /* Waechst mit dem Kaestchen: 20 px auf dem Telefon - gross genug, dass
     ein O von einer 0 zu unterscheiden ist, und ueber der 16-px-Grenze, ab
     der iOS beim Antippen in die Seite zoomt - bis 28 px am Schirm. */
  font-size: clamp(1.25rem, 2.4vw, 1.75rem);
  font-weight: 600;
  line-height: 1;
  text-align: center;
  text-transform: uppercase;
  color: var(--text-body);
  transition: border-color var(--dur) var(--ease);
}
.codefeld__stelle:hover { border-color: var(--toem-blau); }
.codefeld__stelle:focus-visible { border-color: var(--toem-blau); }
/* Unter 30rem misst die Bahn 280 px. Mit 8 px Luft blieben 33 px je
   Kaestchen; mit 4 px sind es 36. */
@media (max-width: 30rem) {
  .codefeld { gap: var(--sp-1); }
}
/* HIER STAND .form__reihe--code: die Codereihe brach frueher auf eine
   Spalte um, weil sie sich die Zeile mit dem Aktionsprodukt teilte und bei
   600 px nur 31 px je Kaestchen uebrig blieben. Seit dem 16.09.2026 steht
   der Code allein in seiner Zeile - die Sonderregel ist damit gegenstandslos
   und entfallen. */
