/* FormDialog — öffentliches Formular (das Gesicht des Produkts).
   Markup-Kontrakt: siehe render_field() in lib/bootstrap.php.
   Die Akzentfarbe kommt pro Formular als --accent auf .bform-card.

   Responsive-Grundsatz: fließende Größen über clamp() statt harter Sprünge,
   ein einziger Umbruchpunkt (560px) für „zweispaltig → einspaltig". Nirgends
   wird waagerecht gescrollt — lange Inhalte brechen um.

   Gestaltungs-Grundsatz: eine einzige Strichstärke (1.5px) trägt Felder,
   Kästchen und Rahmen — dieselbe Hand über das ganze Formular. Alle Farben
   stammen aus den Tokens oder werden per color-mix() daraus abgeleitet,
   damit die zehn Farbwelten und die freie Akzentfarbe von selbst mitziehen.

   Diese Datei lädt NACH themes.css. Deshalb übernimmt sie die dort gesetzten
   Stellschrauben ausdrücklich (--feld-bg, --feld-radius, --knopf-radius,
   --titel-scale) — sonst überschriebe sie die gewählte Vorlage. */

body.bform-page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(16px, 4vw, 48px) clamp(12px, 4vw, 28px) clamp(28px, 5vw, 48px);
}

.bform-card {
  --accent: var(--green);
  /* fließende Abstandsleiter: gilt für Felder, Absätze und den Absendebereich */
  --bf-gap-y: clamp(1.05rem, .85rem + .9vw, 1.45rem);
  --bf-gap-x: clamp(.85rem, .7rem + .7vw, 1.15rem);
  /* Tiefe des Bogens am Kartenkopf */
  --bf-arc: clamp(9px, 2vw, 14px);
  width: 100%;
  max-width: 660px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-card), var(--kante);
  padding: clamp(24px, 5.5vw, 44px) clamp(20px, 5vw, 40px) clamp(26px, 5vw, 40px);
  position: relative;
  overflow: hidden;
  /* ein einziges Erbstück statt Dutzender Einzelregeln: nichts läuft aus der Karte */
  overflow-wrap: break-word;
}

/* Das Zeichen am Kartenkopf: die Sehne (gerade, kräftig) und der Bogen
   (dünn, gespannt), die sich in den beiden oberen Ecken treffen. Der Bogen ist
   eine halbe Ellipse — nur die untere Kante eines Kastens wird gezeichnet, mit
   waagerechtem Radius von halber Breite und senkrechtem Radius voller Höhe.
   Dadurch läuft die Linie von Ecke zu Ecke und hängt in der Mitte am tiefsten
   durch. Zwei Striche, kein Farbfeld: das trägt jede der zehn Farbwelten und
   jede freie Akzentfarbe. (.bcd-flach blendet beides aus — dort gibt es keine
   Karte, an der die Sehne spannen könnte; siehe themes.css.) */
.bform-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: var(--accent);
  pointer-events: none;
}
.bform-card::after {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: var(--bf-arc);
  border-bottom: 1.5px solid var(--accent);
  border-radius: 0 0 50% 50% / 0 0 100% 100%;
  opacity: .5;
  pointer-events: none;
}

.bform__title {
  /* Größe und Schnitt folgen dem gewählten Schriftpaar (themes.css):
     Serifen tragen bei gleicher Größe kleiner auf, Monospace breiter. */
  font-size: calc(clamp(1.5rem, 1.18rem + 1.5vw, 1.95rem) * var(--titel-scale, 1));
  font-weight: var(--titel-weight, 650);
  letter-spacing: -.018em;
  margin-bottom: .3em;
}
.bform__desc {
  color: var(--ink-soft);
  max-width: 52ch;               /* angenehme Zeilenlänge (~65 Zeichen) auf breiten Schirmen */
  margin-bottom: clamp(1.35rem, 1.1rem + 1.1vw, 1.9rem);
  white-space: pre-line;
}

.bform__fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--bf-gap-y) var(--bf-gap-x);
  margin: 0 0 clamp(1.5rem, 1.2rem + 1.3vw, 2.1rem);
}
.bfield { grid-column: 1 / -1; min-width: 0; }
.bfield--half { grid-column: span 1; }
/* Bedingte Felder: Verstecken muss die Rasterregeln schlagen. Ohne diese Zeile
   bliebe ein ausgeblendetes Feld sichtbar, sobald hier je display gesetzt wird. */
.bfield[hidden],
.bform__heading[hidden],
.bform__text[hidden] { display: none !important; }
@media (max-width: 560px) {
  .bfield--half { grid-column: 1 / -1; }
}
/* Zwei halbe Felder nebeneinander: die Eingabefelder sollen auf einer Linie
   stehen, auch wenn eine Beschriftung umbricht oder nur eines der Felder einen
   Hinweis trägt. Nebeneinander stehende Felder sind gleich hoch, also muss der
   überschüssige Platz im kürzeren Feld dorthin, wo die Differenz entsteht.

   Zwei Fälle, zwei Richtungen:
   a) Kein halbes Feld hat einen Hinweis. Dann kommt die Differenz von einer
      umbrechenden Beschriftung, und der Platz gehört zwischen Beschriftung und
      Eingabe.
   b) Mindestens eines hat einen Hinweis. Dann kommt die Differenz von unten,
      und der Platz gehört ans Feldende. Mit Regel (a) würde die Eingabe des
      Feldes ohne Hinweis um genau die Höhe des Hinweises nach unten rutschen.

   Beides nur, wenn alle halben Felder einzeilige Bedienelemente haben: neben
   einer halbhohen Auswahlliste würde ein Eingabefeld sonst wegrutschen. */
@media (min-width: 561px) {
  .bform__fields:not(:has(.bfield--half:is(.bfield--checkboxes, .bfield--radio,
    .bfield--checkbox, .bfield--rating, .bfield--textarea, .bfield--file))) .bfield--half {
    display: flex;
    flex-direction: column;
  }
  /* (a) ohne Hinweis: Platz unter die Beschriftung */
  .bform__fields:not(:has(.bfield--half:is(.bfield--checkboxes, .bfield--radio,
    .bfield--checkbox, .bfield--rating, .bfield--textarea, .bfield--file))):not(:has(.bfield--half > .bfield__help)) .bfield--half > .bfield__label + * {
    margin-top: auto;
  }
  /* (b) mit Hinweis: Platz ans Feldende */
  .bform__fields:not(:has(.bfield--half:is(.bfield--checkboxes, .bfield--radio,
    .bfield--checkbox, .bfield--rating, .bfield--textarea, .bfield--file))):has(.bfield--half > .bfield__help) .bfield--half > :last-child {
    margin-bottom: auto;
  }
}

/* Zwischenüberschrift: trennt Abschnitte, ohne oben ins Leere zu greifen.
   Die Trennlinie ist ein Haarstrich in --line, dessen erste 28 Pixel die
   Akzentfarbe tragen — ein gesetzter Reiter statt einer zweiten Linie.
   Beides steckt in einem einzigen Verlauf auf einem 1px hohen Element, damit
   keine halben Pixel entstehen. */
.bform__heading {
  grid-column: 1 / -1;
  position: relative;
  font-size: clamp(1.06rem, 1rem + .3vw, 1.2rem);
  font-weight: var(--titel-weight, 650);
  letter-spacing: -.012em;
  margin: clamp(.5rem, 1vw, .9rem) 0 0;
  padding-top: clamp(.9rem, .65rem + 1.1vw, 1.35rem);
}
.bform__heading::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 1px;
  background-image: linear-gradient(90deg, var(--accent) 0 28px, var(--line) 28px);
}
.bform__heading:first-child {
  margin-top: 0;
  padding-top: 0;
}
.bform__heading:first-child::before { display: none; }

/* Hinweistext: als Randnotiz gesetzt. Der Haarstrich links trennt ihn von den
   Beschriftungen darüber und darunter — ohne eine weitere Schriftgröße oder
   Farbe einzuführen. */
.bform__text {
  grid-column: 1 / -1;
  color: var(--ink-soft);
  font-size: .95rem;
  line-height: 1.65;
  max-width: 56ch;
  margin: 0;
  padding-left: clamp(.7rem, 2vw, .95rem);
  border-left: 1.5px solid var(--line);
}

.bfield__label {
  display: block;
  font-weight: 600;
  font-size: .95rem;
  line-height: 1.4;
  letter-spacing: -.006em;
  color: var(--ink);
  margin-bottom: .4rem;
}
/* Das Sternchen ist eine Fußnote, kein Ausruf: eine Spur kleiner und höher
   gesetzt, damit es die Beschriftung nicht anschiebt. */
.bfield__req {
  color: var(--accent);
  font-weight: 700;
  font-size: .9em;
  vertical-align: .12em;
  margin-left: .06em;
}
.bfield__help {
  font-size: .84rem;
  line-height: 1.45;
  color: var(--ink-soft);
  max-width: 62ch;
  margin: -.15rem 0 .45rem;
}
.bfield__error {
  font-size: .85rem;
  line-height: 1.4;
  color: var(--red);
  font-weight: 600;
  margin: .4rem 0 0;
}

/* Eingabefeld: ruhige Ruhelage, klarer Fokus, kein Springen. Beim Fokus
   wechselt der Untergrund auf die Kartenfarbe — das Feld hebt sich vom Papier
   ab, ohne seine Maße zu ändern; der Ring liegt im Schatten, nicht im Rahmen. */
.bfield__input {
  width: 100%;
  max-width: 100%;
  font: 400 1rem/1.45 var(--font-body);   /* 16px: iOS zoomt sonst beim Antippen */
  color: var(--ink);
  background: var(--feld-bg, #FBFAF7);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--feld-radius, 10px);
  padding: .75em .875em;                  /* 12px / 14px bei 16px Schrift */
  transition:
    border-color .18s var(--ease),
    background-color .18s var(--ease),
    box-shadow .18s var(--ease);
}
/* Der Platzhalter darf leichter stehen als eine Eingabe, muss aber lesbar
   bleiben: 88 % der weichen Tinte halten den Kontrast über 4.5:1. */
.bfield__input::placeholder {
  color: color-mix(in srgb, var(--ink-soft) 88%, transparent);
}
textarea.bfield__input {
  resize: vertical;
  min-height: clamp(96px, 76px + 6vw, 132px);
}
@media (hover: hover) {
  .bfield__input:hover:not(:focus) {
    border-color: color-mix(in srgb, var(--accent) 38%, var(--line-strong));
  }
}
.bfield__input:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--card);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent);
}
.bfield--error .bfield__input { border-color: var(--red); }
.bfield--error .bfield__input:focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--red) 16%, transparent);
}

/* Auswahlliste: das Systemdreieck fällt aus jeder Vorlage heraus. Der eigene
   Winkel besteht aus zwei Verlaufsstreifen — zwei 7px-Kästchen, die sich
   genau an der Spitze treffen, mit derselben 1.5px-Strichstärke wie alle
   Rahmen. Die Farbe steckt in --pfeil und springt beim Fokus auf den Akzent,
   ganz wie das Symbol im Kurztextfeld. */
select.bfield__input {
  --pfeil: var(--ink-soft);
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.2em;
  background-image:
    linear-gradient(45deg,  transparent calc(50% - .75px), var(--pfeil) calc(50% - .75px),
                            var(--pfeil) calc(50% + .75px), transparent calc(50% + .75px)),
    linear-gradient(-45deg, transparent calc(50% - .75px), var(--pfeil) calc(50% - .75px),
                            var(--pfeil) calc(50% + .75px), transparent calc(50% + .75px));
  background-size: 7px 7px;
  background-position: right 15px center, right 8px center;
  background-repeat: no-repeat;
}
select.bfield__input:focus { --pfeil: var(--accent); }
.bfield--error select.bfield__input { --pfeil: var(--red); }

/* Dunkle Vorlagen: Datumswähler, Auswahlliste und Bildlaufleisten kommen vom
   Betriebssystem. Eine Zeile stellt sie auf dunkel um — sonst blitzt ein
   weißes Fenster aus der ruhigen Nacht heraus. */
.bth-nacht, .bth-kupfer { color-scheme: dark; }

/* Kurztext mit gewählter Art: Symbol links im Feld. Der Innenabstand wächst
   entsprechend, damit der Text nicht unter dem Symbol beginnt. */
.binput { position: relative; display: flex; align-items: center; }
.binput .bfield__input { padding-left: 2.75em; }
.binput__icon {
  position: absolute;
  left: 14px;                      /* auf einer Senkrechten mit dem Textbeginn */
  width: 17px;
  height: 17px;
  color: color-mix(in srgb, var(--ink-soft) 82%, transparent);
  pointer-events: none;
  transition: color .18s var(--ease);
}
.binput:focus-within .binput__icon { color: var(--accent); }
.bfield--error .binput__icon { color: var(--red); }

/* Auswahl-Optionen: ganze Zeile ist Tippfläche (≥ 40px hoch). Die gewählte
   Zeile bekommt einen Hauch Akzent — man sieht die eigene Antwort, ohne dass
   die Schrift ihr Gewicht ändert und die Zeile umbricht. */
.bfield__choices { display: flex; flex-direction: column; gap: .1rem; }
.bchoice {
  display: flex;
  align-items: flex-start;
  gap: .65rem;
  cursor: pointer;
  font-size: 1rem;
  line-height: 1.5;
  padding: .55rem .5rem;
  margin-inline: -.5rem;         /* Kästchen bleibt bündig mit den Eingabefeldern */
  border-radius: var(--feld-radius, 10px);
  transition: background-color .18s var(--ease);
}
@media (hover: hover) {
  .bchoice:hover { background: color-mix(in srgb, var(--accent) 6%, transparent); }
}
/* Am Finger darf keine Zeile unter 44px liegen */
@media (pointer: coarse) {
  .bchoice { padding-block: .7rem; }
}
.bchoice:has(input:checked) {
  background: color-mix(in srgb, var(--accent) 9%, transparent);
}
.bchoice input {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
}
/* 20px Kästchen, 1.5px Strich — dieselbe Hand wie bei den Eingabefeldern.
   Der Innenabstand ist ganzzahlig: (1.5em − 20px) / 2 = 2px. */
.bchoice__box {
  flex: 0 0 auto;
  width: 20px; height: 20px;
  margin-top: calc((1.5em - 20px) / 2);   /* sitzt auf der ersten Zeile, auch mehrzeilig */
  border: 1.5px solid var(--line-strong);
  border-radius: 6px;
  background: var(--feld-bg, #FBFAF7);
  position: relative;
  transition:
    border-color .18s var(--ease),
    background-color .18s var(--ease),
    box-shadow .18s var(--ease);
}
.bchoice__text { min-width: 0; }
.bchoice input[type="radio"] + .bchoice__box { border-radius: 50%; }
@media (hover: hover) {
  .bchoice:hover .bchoice__box { border-color: color-mix(in srgb, var(--accent) 55%, var(--line-strong)); }
}
.bchoice input:checked + .bchoice__box {
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 1px 3px -1px color-mix(in srgb, var(--accent) 55%, transparent);
}
/* Häkchen: 45° statt 42° — der Winkel liegt auf dem Raster, die Arme sind
   gleich stark wie die Rahmen (2px auf 20px Kästchen). */
.bchoice input[type="checkbox"]:checked + .bchoice__box::after {
  content: '';
  position: absolute;
  left: 6px; top: 3px;
  width: 5px; height: 9px;
  /* Weiß, nicht --card: die Akzentfarbe wird frei gewählt, und Weiß auf
     Akzent ist im ganzen Formular der verlässliche Kontrast (Knopf, Blase). */
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.bchoice input[type="radio"]:checked + .bchoice__box::after {
  content: '';
  position: absolute;
  inset: 5px;
  border-radius: 50%;
  background: #fff;
}
.bchoice input:focus-visible + .bchoice__box {
  outline: 3px solid var(--marker);
  outline-offset: 2px;
}
.bchoice--single { font-weight: 500; }
.bfield--error .bchoice__box { border-color: var(--red); }

/* Datei-Upload: Ablagefeld mit Knopf. Schmal = Knopf oben, Dateiname darunter,
   damit ein langer Name die volle Breite bekommt und der Knopf erreichbar bleibt. */
.bfield__file {
  display: block;
  width: 100%;
  font: 400 1rem/1.45 var(--font-body);   /* 16px: kein iOS-Zoom beim Antippen */
  color: var(--ink-soft);
  background: var(--feld-bg, #FBFAF7);
  border: 1.5px dashed color-mix(in srgb, var(--line-strong) 85%, transparent);
  border-radius: var(--feld-radius, 10px);
  padding: .6em .75em;
  cursor: pointer;
  overflow: hidden;                        /* langer Dateiname bleibt im Feld */
  text-overflow: ellipsis;
  transition: border-color .18s var(--ease), background-color .18s var(--ease);
}
.bfield__file::file-selector-button {
  font: 600 .95rem/1.2 var(--font-body);
  letter-spacing: -.004em;
  color: #fff;
  background: var(--accent);
  border: none;
  border-radius: var(--knopf-radius, 999px);
  padding: .58em 1.2em;
  min-height: 40px;
  margin: 0 .7em 0 0;
  cursor: pointer;
  transition: background-color .18s var(--ease);
}
.bfield__file::-webkit-file-upload-button {
  font: 600 .95rem/1.2 var(--font-body);
  letter-spacing: -.004em;
  color: #fff;
  background: var(--accent);
  border: none;
  border-radius: var(--knopf-radius, 999px);
  padding: .58em 1.2em;
  min-height: 40px;
  margin: 0 .7em 0 0;
  cursor: pointer;
  transition: background-color .18s var(--ease);
}
.bfield__file:hover::file-selector-button {
  background: color-mix(in srgb, var(--accent) 88%, var(--ink));
}
.bfield__file:hover::-webkit-file-upload-button {
  background: color-mix(in srgb, var(--accent) 88%, var(--ink));
}
@media (max-width: 560px) {
  .bfield__file { padding: .65em .7em .7em; }
  .bfield__file::file-selector-button {
    display: block;
    width: 100%;
    margin: 0 0 .5em;
  }
  .bfield__file::-webkit-file-upload-button {
    display: block;
    width: 100%;
    margin: 0 0 .5em;
  }
}
.bfield__file:hover {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 4%, var(--feld-bg, #FBFAF7));
}
.bfield__file:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent);
}
.bfield--error .bfield__file { border-color: var(--red); }

/* Bereits übertragene Datei: Symbol links, Name und Größe rechts untereinander —
   ein langer Name bricht sauber um, statt die Größe wegzudrücken. */
.bfile__have {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  column-gap: .55em;
  row-gap: .1em;
  font-size: .92rem;
  line-height: 1.4;
  /* aus dem Akzent abgeleitet statt fest grün: die Datei gehört sichtbar zu
     diesem Formular, egal welche Farbe es trägt */
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  border-radius: var(--feld-radius, 10px);
  padding: .6em .75em;
  margin: 0 0 .55rem;
}
.bfile__have svg {
  grid-column: 1;
  grid-row: 1;
  width: 18px;
  height: 18px;
  margin-top: .12em;
  color: var(--accent);
}
.bfile__name {
  grid-column: 2;
  font-weight: 600;
  min-width: 0;
  overflow-wrap: anywhere;
}
.bfile__size {
  grid-column: 2;
  color: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: .8rem;
}
.bfile__hint { margin: .5rem 0 0; }

/* Kamera am Datei-Feld: das Feld selbst und darunter der Knopf „Foto
   aufnehmen". Das Kamerafeld (capture) ist unsichtbar, bleibt aber im
   Tab-Weg: Wer es mit der Tastatur erreicht, sieht den Ring am Knopf. */
.bfile {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .55rem;
}
.bfile > .bfield__file { align-self: stretch; }
.bfile__cap {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0); overflow: hidden; white-space: nowrap;
}
.bfile__cap[hidden], .bfile__cam[hidden] { display: none !important; }
.bfile__cam {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5em;
  min-height: 44px;
  padding: .55em 1.15em;
  font: 600 .95rem/1.2 var(--font-body);
  letter-spacing: -.004em;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 7%, transparent);
  border: 1.5px solid color-mix(in srgb, var(--accent) 55%, transparent);
  border-radius: var(--knopf-radius, 999px);
  cursor: pointer;
  user-select: none;
  transition: background-color .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease);
}
.bfile__cam svg { width: 20px; height: 20px; flex: 0 0 auto; }
.bfile__cam:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.bfile__cap:focus-visible + .bfile__cam {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
@media (max-width: 560px) {
  .bfile__cam { align-self: stretch; }
}

/* Webcam-Schicht am Rechner: Vorschau, Auslöser, Übernahme. Im Rahmen einer
   fremden Seite liegt sie absolut über der Seite (bcam--rahmen), form.js
   setzt Höhe der Schicht und Lage der Box. */
.bcam {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(10, 12, 10, .62);
}
.bcam[hidden] { display: none !important; }
.bcam--rahmen {
  position: absolute;
  inset: 0 0 auto 0;
  align-items: flex-start;
}
.bcam--rahmen .bcam__box {
  position: absolute;
  left: 16px;
  right: 16px;
  margin: 0 auto;
}
.bcam__box {
  width: 100%;
  max-width: 560px;
  background: var(--card);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-card);
  padding: clamp(16px, 3vw, 24px);
}
.bcam__title {
  margin: 0 0 .75rem;
  font: 700 1.1rem/1.2 var(--font-body);
  letter-spacing: -.01em;
}
.bcam__stage {
  position: relative;
  aspect-ratio: 4 / 3;
  background: #111;
  border-radius: var(--feld-radius, 10px);
  overflow: hidden;
}
.bcam__video, .bcam__canvas {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.bcam__video--spiegel { transform: scaleX(-1); }
.bcam__video[hidden], .bcam__canvas[hidden], .bcam__msg[hidden], .bcam__btn[hidden] { display: none !important; }
.bcam__msg {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 1.5rem;
  text-align: center;
  color: #fff;
  font-size: .95rem;
  line-height: 1.5;
}
.bcam__actions {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-top: .9rem;
}
.bcam__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: .55em 1.2em;
  font: 600 .95rem/1.2 var(--font-body);
  color: var(--ink);
  background: transparent;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--knopf-radius, 999px);
  cursor: pointer;
  transition: background-color .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease);
}
.bcam__btn:hover { border-color: var(--ink); }
.bcam__btn--primary {
  color: #fff;
  background: var(--accent);
  border-color: var(--accent);
}
.bcam__btn--primary:hover {
  background: color-mix(in srgb, var(--accent) 88%, var(--ink));
  border-color: transparent;
}
.bcam__btn[disabled] { opacity: .5; cursor: default; }
.bcam__btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 28%, transparent);
}
@media (max-width: 560px) {
  .bcam { padding: 10px; }
  .bcam__btn { flex: 1 1 auto; }
}

/* Gesammelte Dateien: bereits übertragene und frisch gewählte in einer Liste.
   Aufbau je Zeile: Symbol | Name / Größe | Entfernen. */
.bfiles {
  list-style: none;
  margin: 0 0 .55rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .35rem;
}
.bfiles[hidden] { display: none; }
.bfiles__item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  column-gap: .55em;
  row-gap: .1em;
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  border-radius: var(--feld-radius, 10px);
  padding: .45em .5em .45em .75em;
  font-size: .92rem;
  line-height: 1.4;
}
.bfiles__icon {
  grid-column: 1;
  grid-row: 1 / span 2;
  width: 18px;
  height: 18px;
  color: var(--accent);
}
.bfiles__name {
  grid-column: 2;
  font-weight: 600;
  min-width: 0;
  overflow-wrap: anywhere;
}
.bfiles__size {
  grid-column: 2;
  color: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: max(.75rem, 12px);
}
.bfiles__del {
  grid-column: 3;
  grid-row: 1 / span 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background-color .12s ease, color .12s ease;
}
.bfiles__del svg { width: 15px; height: 15px; }
.bfiles__del:hover { background: var(--red-tint); color: var(--red); }
@media (pointer: coarse) {
  .bfiles__del { width: 44px; height: 44px; }
}

/* Bewertung: fünf Sterne teilen sich eine feste Breite — je Stern bleibt ein
   Tippziel von mindestens 44px, auch auf 320px. */
.bstars {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(2px, 1vw, 8px);
  max-width: min(100%, 17rem);
}
.bstars__star {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  border-radius: 10px;
  cursor: pointer;
  position: relative;
}
.bstars__star input { position: absolute; opacity: 0; width: 1px; height: 1px; }
/* Ungewählt ist der Stern eine gezogene Kontur, keine graue Fläche: feiner —
   und er trägt auf hellen wie auf dunklen Vorlagen, weil die Linie aus einem
   Token kommt statt aus einem festen Grau. */
.bstars__star svg {
  width: clamp(28px, 8.5vw, 34px);
  height: auto;
  fill: none;
  stroke: var(--line-strong);
  stroke-width: 1.2;
  stroke-linejoin: round;
  transition: fill .18s var(--ease), stroke .18s var(--ease), transform .18s var(--ease);
}
.bstars__star:hover svg { transform: scale(1.06); }
.bstars__star:active svg { transform: scale(.98); }
.bstars__star:hover svg,
.bstars__star:has(~ .bstars__star:hover) svg,
.bstars__star:has(input:checked) svg,
.bstars__star:has(~ .bstars__star input:checked) svg {
  fill: var(--marker);
  /* dunklerer Rand auf hellem Papier, hellerer auf dunklem — eine Formel
     statt zweier fester Farben */
  stroke: color-mix(in srgb, var(--marker) 74%, var(--ink));
}
@media (prefers-reduced-motion: reduce) {
  .bstars__star:hover svg,
  .bstars__star:active svg { transform: none; }
}
.bstars__star input:focus-visible ~ svg {
  outline: 3px solid var(--marker);
  outline-offset: 2px;
  border-radius: 4px;
}
.bstars__star:has(input:focus-visible) {
  outline: 3px solid var(--marker);
  outline-offset: -1px;
}
.bstars__star:has(input:focus-visible) svg { outline: none; }

/* Absenden. Der Knopf trägt einen aus dem Akzent gemischten Schatten — er
   liegt auf dem Papier, statt darauf gedruckt zu sein. Beim Zeigen dunkelt er
   nicht per filter nach (das trübt auch die Schrift), sondern mischt sich
   Richtung Tinte: auf dunklen Vorlagen wird er dadurch heller, wie es sich
   dort gehört. */
.bform__submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5em;
  font: 600 clamp(1rem, .97rem + .2vw, 1.08rem)/1.2 var(--font-body);
  letter-spacing: -.006em;
  color: #fff;
  background: var(--accent);
  border: none;
  border-radius: var(--knopf-radius, 999px);
  min-height: 50px;
  padding: .8em 1.9em;
  cursor: pointer;
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--accent) 30%, transparent),
    0 10px 22px -14px color-mix(in srgb, var(--accent) 80%, transparent);
  transition:
    background-color .18s var(--ease),
    box-shadow .18s var(--ease),
    transform .1s var(--ease);
}
.bform__submit:hover {
  background: color-mix(in srgb, var(--accent) 88%, var(--ink));
  box-shadow:
    0 1px 2px color-mix(in srgb, var(--accent) 34%, transparent),
    0 14px 26px -14px color-mix(in srgb, var(--accent) 90%, transparent);
}
.bform__submit:active { transform: translateY(1px); }
.bform__submit[disabled] { opacity: .6; cursor: wait; box-shadow: none; }
@media (max-width: 560px) {
  .bform__submit { width: 100%; }
}

/* Fehlermeldung über dem Formular: der senkrechte Strich links macht sie zur
   Randbemerkung des Bogens, statt zum roten Kasten. */
.bform__toperror {
  background: var(--red-tint);
  color: var(--red);
  font-weight: 600;
  font-size: .93rem;
  line-height: 1.45;
  border-radius: var(--feld-radius, 10px);
  border-left: 3px solid var(--red);
  padding: .75em 1em;
  margin-bottom: clamp(1rem, .85rem + .6vw, 1.35rem);
}

/* Erfolg — der Augenblick, in dem der Bogen abgegeben ist.
   Bild dafür: das Siegel. Eine runde Fläche in der Akzentfarbe wird auf das
   Papier gesetzt (sie kommt kurz aus der Tiefe, mit einem weichen Schatten
   darunter), und erst danach zieht die Feder Ring und Haken hinein. Die
   Scheibe ist kein zweites Element im Markup, sondern Polster und Hintergrund
   des vorhandenen SVG — deshalb bleibt sie in jeder Vorlage mittig. */
.bform__success {
  --erfolg: clamp(54px, 42px + 4vw, 70px);
  text-align: center;
  padding: clamp(1.5rem, .9rem + 3vw, 2.6rem) 0 clamp(.75rem, .5rem + 1.4vw, 1.5rem);
}
.bform__success svg {
  box-sizing: content-box;
  width: var(--erfolg);
  height: var(--erfolg);
  padding: calc(var(--erfolg) * .26);
  margin: 0 auto clamp(.9rem, .7rem + 1vw, 1.3rem);
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  box-shadow: 0 12px 26px -16px color-mix(in srgb, var(--accent) 85%, transparent);
  animation: cf-siegel .5s var(--ease) both;
}
@keyframes cf-siegel {
  from { opacity: 0; transform: scale(.92); }
  to   { opacity: 1; transform: none; }
}
.bform__success circle {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  stroke-dasharray: 210;
  stroke-dashoffset: 210;
  animation: cf-draw .8s var(--ease) forwards;
}
.bform__success path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 3.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 42;
  stroke-dashoffset: 42;
  animation: cf-draw .45s var(--ease) .5s forwards;
}
@keyframes cf-draw { to { stroke-dashoffset: 0; } }
.bform__success h2 {
  font-size: calc(clamp(1.3rem, 1.2rem + .5vw, 1.6rem) * var(--titel-scale, 1));
  font-weight: var(--titel-weight, 650);
  letter-spacing: -.02em;
  margin-bottom: .4em;
}
.bform__success p {
  color: var(--ink-soft);
  max-width: 46ch;
  margin-inline: auto;
  white-space: pre-line;
}
.bform__success .btn {
  min-height: 44px;
  padding-inline: 1.4em;
  margin-top: .7rem;
}

/* Geschlossen */
.bform__closed {
  text-align: center;
  padding: clamp(1.25rem, .8rem + 2.2vw, 2.1rem) 0 clamp(.5rem, 1.5vw, 1.1rem);
  color: var(--ink-soft);
}
.bform__closed h2 {
  color: var(--ink);
  font-size: calc(clamp(1.2rem, 1.1rem + .5vw, 1.45rem) * var(--titel-scale, 1));
  font-weight: var(--titel-weight, 650);
  letter-spacing: -.018em;
}
.bform__closed p {
  max-width: 46ch;
  margin-inline: auto;
  margin-bottom: 0;
}

/* Honigtopf */
.bform__hp { position: absolute; left: -9999px; top: -9999px; }

/* Getarnte Falle: sieht im Quelltext aus wie ein Feld, steht zwischen den
   echten und heißt auch so. Absolut positioniert, damit sie im Raster keine
   Zelle und keine Lücke erzeugt; ohne display:none, weil manche Bots genau
   das auswerten und solche Felder dann auslassen. */
.bfield--aux {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  opacity: 0;
  pointer-events: none;
}

/* Fußzeile: die Herkunftszeile. Sie steht unter der Karte und soll dort
   ruhen — gesperrt gesetzt, in weicher Tinte, beim Zeigen voll da. */
.bform-foot {
  margin-top: clamp(1.1rem, .9rem + .6vw, 1.5rem);
  font-family: var(--font-mono);
  font-size: max(.78rem, 12px);
  letter-spacing: .07em;
  color: var(--ink-soft);
  text-align: center;
}
.bform-foot a {
  color: inherit;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .45em;
  min-height: 40px;
  padding: 0 .4em;
  transition: color .18s var(--ease);
}
.bform-foot a:hover { color: var(--ink); }
@media (pointer: coarse) {
  .bform-foot a { min-height: 44px; }
}
.bform-foot svg { width: 15px; height: 15px; flex: 0 0 auto; }

/* Embed-Modus: keine Karte, kein Seitenrand — nur so viel Luft, dass die
   Fokusringe und die ausgerückten Auswahlzeilen im schmalen iframe nicht am
   Rand abgeschnitten werden (10px ≥ Ausrückung der .bchoice). */
body.bform-embed {
  background: transparent;
  min-height: 0;
  /* Luft rundum: eingebettet steht das Formular sonst hart an der Kante
     der einbettenden Seite. */
  padding: clamp(16px, 3vw, 30px) clamp(14px, 3vw, 26px);
}
body.bform-embed .bform-card {
  max-width: 660px;
  border: none;
  border-radius: 0;
  box-shadow: none;
  overflow: visible;
  padding: 4px 6px 10px;
}
body.bform-embed .bform-card::before,
body.bform-embed .bform-card::after { display: none; }
body.bform-embed .bform-foot { margin: .8rem 0 0; }
