/* Selbst ausgeliefert statt über fonts.googleapis.com — dieselbe Entscheidung wie im
   Cockpit (public/cockpit/styles.css), hier aber wichtiger: DIESE Oberfläche sehen die
   ENDKUNDEN des Versorgers. Ein Schriftabruf bei Google übermittelt deren IP in ein
   Drittland, und zwar bei jedem Aufruf, ohne dass der Kunde davon erfährt oder der
   Versorger es in seinen Datenschutzhinweisen abbilden könnte. Dass das Cockpit (interne
   Nutzer) das vermied und die Kundenoberfläche nicht, war die Asymmetrie auf der falschen
   Seite; behoben am 04.08.2026.

   Nebeneffekt wie im Cockpit: die Optik hängt nicht mehr davon ab, ob das CDN erreichbar
   ist, und der Service Worker kann die Schrift mit in die Shell nehmen (offline).

   Plus Jakarta Sans ist eine VARIABLE FONT: Google liefert für die Gewichte 400–800
   dieselbe Datei je Subset aus, deshalb genügen zwei Dateien und `font-weight: 400 800`
   interpoliert dazwischen. Lizenz: OFL 1.1, siehe fonts/OFL-Plus-Jakarta-Sans.txt.

   ⚠️ Bewusst nur latin + latin-ext (wie im Cockpit), NICHT cyrillic/vietnamese. Tippt ein
   Kunde kyrillische Zeichen, fällt der Browser für DIESE Zeichen auf system-ui zurück —
   `unicode-range` regelt das je Zeichen, es bricht also nichts. Wer das Produkt in einen
   Markt mit anderem Schriftsystem verkauft, ergänzt hier die Subsets. */
@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('fonts/plus-jakarta-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('fonts/plus-jakarta-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* White-Label-Tokens: Defaults (warm, versorgernah). Der Tenant überschreibt sie zur Laufzeit
   via /api/widget-config (branding) — kraftwerk bleibt unsichtbar. */
:root {
  --brand-primary: #F7A600;
  --brand-primary-strong: #E2900A;
  --brand-ink: #14233A;
  --brand-on-primary: #14233A;
  --brand-surface: #FFFFFF;
  --brand-bg: #F4F6F8;
  --brand-user-bubble: #FFF1D6;
  --brand-line: #E7EAF0;
  --brand-success: #2E9E5B;
  --brand-muted: #6B7688;
  --radius: 16px;
  --font: "Plus Jakarta Sans", system-ui, -apple-system, sans-serif;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  color: var(--brand-ink);
  background: var(--brand-bg);
  -webkit-font-smoothing: antialiased;
}

#app {
  display: flex;
  flex-direction: column;
  height: 100dvh;
  max-width: 640px;
  margin: 0 auto;
  background: var(--brand-bg);
}

/* --- Kopfzeile --- */
#bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  padding-top: max(14px, env(safe-area-inset-top));
  background: var(--brand-ink);
  color: #fff;
}
#brand-mark {
  width: 40px; height: 40px;
  border-radius: 11px;
  background: var(--brand-primary);
  color: var(--brand-on-primary);
  display: grid; place-items: center;
  font-weight: 800; font-size: 19px;
  flex: none;
}
/* Echtes Versorger-Logo statt Buchstabenkachel. Weißer Grund, weil die meisten Logos für
   helle Flächen gezeichnet sind und auf der dunklen Kopfzeile sonst verschwinden. */
#brand-mark.has-logo { background: #fff; padding: 4px; }
#brand-mark.has-logo img { width: 100%; height: 100%; object-fit: contain; display: block; }
#title { font-weight: 800; font-size: 17px; letter-spacing: -0.01em; }
#status { font-size: 12.5px; color: #B9C2D0; display: flex; align-items: center; gap: 6px; margin-top: 2px; }
#status .dot { width: 7px; height: 7px; border-radius: 50%; background: #46D07E; box-shadow: 0 0 0 3px rgba(70,208,126,.18); }

/* --- Nachrichtenbereich --- */
#log {
  flex: 1;
  overflow-y: auto;
  padding: 20px 16px 8px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.msg {
  max-width: 82%;
  padding: 12px 15px;
  font-size: 16px;
  line-height: 1.5;
  border-radius: var(--radius);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  animation: rise .28s cubic-bezier(.22,.61,.36,1);
}
.msg.bot {
  align-self: flex-start;
  background: var(--brand-surface);
  border: 1px solid var(--brand-line);
  border-bottom-left-radius: 6px;
  box-shadow: 0 1px 2px rgba(20,35,58,.05);
}
.msg.user {
  align-self: flex-end;
  background: var(--brand-user-bubble);
  border-bottom-right-radius: 6px;
}

/* §5.6: „optisch klar unterscheidbar, wer gerade schreibt (Bot vs. Mensch)".
   Dieselbe Seite wie der Bot — es antwortet weiter der Versorger — aber mit einem
   farbigen Streifen und einer Kennzeichnung darüber. Eine andere Ausrichtung wäre
   verwirrend: der Kunde spricht nicht mit einer dritten Partei, sondern weiter mit
   demselben Serviceteam. */
.msg.human {
  align-self: flex-start;
  background: var(--brand-surface);
  border: 1px solid var(--brand-line);
  border-left: 3px solid var(--brand-primary);
  border-bottom-left-radius: 6px;
  box-shadow: 0 1px 2px rgba(20,35,58,.05);
}
.msg.human::before {
  content: 'Serviceteam';
  display: block;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--brand-primary-strong, var(--brand-primary));
  margin-bottom: 4px;
  letter-spacing: .2px;
}

/* Ereignisse im Gespräch — weder Kunde noch Bot noch Mensch. Mittig und zurückgenommen,
   damit sie nicht wie eine Äußerung wirken. */
.msg.system {
  align-self: center;
  max-width: 90%;
  background: none;
  padding: 6px 12px;
  font-size: 13.5px;
  color: var(--brand-muted, #6B7480);
  text-align: center;
}

/* Tipp-Indikator */
/* Nur für Screenreader: aus dem Blickfeld, aber im Baum — display:none oder visibility:hidden
   würde den Text auch für Vorleser entfernen und damit genau den Zweck aufheben. */
.nur-vorleser {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.msg.typing { display: flex; gap: 5px; align-items: center; padding: 15px; }
.msg.typing span { width: 7px; height: 7px; border-radius: 50%; background: #AEB8C6; animation: blink 1.3s infinite both; }
.msg.typing span:nth-child(2) { animation-delay: .18s; }
.msg.typing span:nth-child(3) { animation-delay: .36s; }

/* --- Willkommen + Chips --- */
#welcome { display: flex; flex-direction: column; gap: 14px; }
#greeting {
  align-self: flex-start;
  max-width: 82%;
  margin: 0;
  padding: 14px 16px;
  font-size: 16.5px;
  line-height: 1.5;
  background: var(--brand-surface);
  border: 1px solid var(--brand-line);
  border-radius: var(--radius);
  border-bottom-left-radius: 6px;
  box-shadow: 0 1px 2px rgba(20,35,58,.05);
}
#chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  font: inherit;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--brand-ink);
  background: var(--brand-surface);
  border: 1.5px solid var(--brand-line);
  border-radius: 999px;
  padding: 9px 15px;
  cursor: pointer;
  transition: border-color .15s, background .15s, transform .05s;
}
.chip:hover { border-color: var(--brand-primary); }
.chip:active { transform: scale(.97); }

/* Der Ausweg aus einem beendeten Gespräch (public/app.js, zeigeNeuanfang).
   Mittig und mit Abstand: er ist keine Nachricht im Verlauf, sondern eine Handlung — als Blase
   getarnt würde er wie eine Äußerung des Bots gelesen. */
.neuanfang { display: flex; justify-content: center; margin: 18px 0 6px; }
.neuanfang button {
  font: inherit;
  font-size: 14.5px;
  font-weight: 700;
  color: var(--brand-on-primary);
  background: var(--brand-primary);
  border: none;
  border-radius: 999px;
  padding: 11px 22px;
  cursor: pointer;
  transition: background .15s, transform .05s;
}
.neuanfang button:hover { background: var(--brand-primary-strong); }
.neuanfang button:active { transform: scale(.97); }

#welcome.hide { display: none; }

/* --- §5.9 Installationshinweis ---
   Über der Eingabezeile, nicht als Overlay: er soll dezent sein und nichts blockieren.
   Der Kunde kann weiterschreiben, ohne ihn wegzuklicken. */
#install-hint {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 0 14px 10px;
  padding: 12px 14px;
  background: var(--brand-surface);
  border: 1px solid var(--brand-line);
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(20,35,58,.05);
  animation: rise .28s cubic-bezier(.22,.61,.36,1);
}
#install-hint[hidden] { display: none; }
#install-text { flex: 1 1 220px; min-width: 0; font-size: 14px; line-height: 1.45; color: var(--brand-ink); }
#install-actions { display: flex; gap: 8px; flex: none; margin-left: auto; }
#install-actions button {
  font: inherit; font-size: 14px; font-weight: 700;
  padding: 9px 14px; border-radius: 10px; cursor: pointer;
}
#install-yes { border: none; background: var(--brand-primary); color: var(--brand-on-primary); }
#install-yes:hover { background: var(--brand-primary-strong); }
.install-ghost { border: 1px solid var(--brand-line); background: transparent; color: var(--brand-muted); }
.install-ghost:hover { background: #F0F2F5; }

/* Honeypot (§B1) — siehe Kommentar bei #betreff-wrap in index.html. Bewusst NICHT
   display:none/visibility:hidden: beide Eigenschaften prüfen etwas raffiniertere
   Formular-Bots gezielt und überspringen dann genau die Felder, bei denen sie zutreffen.
   Stattdessen aus dem sichtbaren Bereich herausgeschoben — für einen Bot, der nur die
   Feldliste des DOM abgreift, bleibt das Feld "da". */
#betreff-wrap {
  position: absolute;
  left: -9999px;
  top: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --- Eingabeleiste --- */
#form {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  padding-bottom: max(12px, env(safe-area-inset-bottom));
  background: var(--brand-bg);
  border-top: 1px solid var(--brand-line);
}
#field {
  flex: 1;
  display: flex;
  align-items: center;
  background: var(--brand-surface);
  border: 1.5px solid var(--brand-line);
  border-radius: 999px;
  padding: 4px 6px 4px 18px;
  transition: border-color .15s;
}
#field:focus-within { border-color: var(--brand-primary); }
#input {
  flex: 1;
  border: none;
  outline: none;
  background: transparent;
  font: inherit;
  font-size: 16px;
  color: var(--brand-ink);
  padding: 10px 0;
}
#input::placeholder { color: #9AA4B2; }
#send {
  flex: none;
  width: 38px; height: 38px;
  border: none; border-radius: 50%;
  background: transparent;
  color: var(--brand-ink);
  display: grid; place-items: center;
  cursor: pointer;
  transition: background .15s, color .15s;
}
#send:hover { background: #EEF1F5; }

/* Voice-Button = Signature: rund, in Markenfarbe, nie kleiner als Senden */
#mic {
  flex: none;
  width: 52px; height: 52px;
  border: none; border-radius: 50%;
  background: var(--brand-primary);
  color: var(--brand-on-primary);
  display: grid; place-items: center;
  cursor: pointer;
  box-shadow: 0 6px 16px rgba(247,166,0,.32);
  transition: transform .06s, box-shadow .15s, background .15s;
}
#mic:hover { background: var(--brand-primary-strong); }
#mic:active { transform: scale(.94); }
#mic.recording { animation: pulse 1.4s infinite; }

button:focus-visible, .chip:focus-visible { outline: 3px solid rgba(247,166,0,.45); outline-offset: 2px; }

@keyframes rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes blink { 0%, 100% { opacity: .3; } 40% { opacity: 1; } }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(247,166,0,.5); } 70% { box-shadow: 0 0 0 16px rgba(247,166,0,0); } 100% { box-shadow: 0 0 0 0 rgba(247,166,0,0); } }

/* --- Sprachmodus-Overlay --- */
#voice {
  position: fixed; inset: 0;
  z-index: 50;
  background: var(--brand-ink);
  color: #fff;
  display: flex; flex-direction: column; align-items: center;
  padding: max(20px, env(safe-area-inset-top)) 24px max(28px, env(safe-area-inset-bottom));
  animation: fade .2s ease;
}
#voice[hidden] { display: none; }
#voice-close {
  position: absolute; top: max(16px, env(safe-area-inset-top)); right: 18px;
  width: 40px; height: 40px; border: none; border-radius: 50%;
  background: rgba(255,255,255,.1); color: #fff; cursor: pointer;
  display: grid; place-items: center;
}
#voice-title { margin-top: 8px; font-size: 15px; color: #B9C2D0; }
#voice-orb {
  margin: auto 0 26px;
  width: 160px; height: 160px; border-radius: 50%;
  background: var(--brand-primary); color: var(--brand-on-primary);
  display: grid; place-items: center;
  animation: breathe 2s ease-in-out infinite;
}
#voice.processing #voice-orb { animation: none; opacity: .8; }
#voice-hint { max-width: 320px; text-align: center; font-size: 16px; line-height: 1.5; color: #D5DBE4; margin: 0 auto auto; }
#voice-done {
  width: 100%; max-width: 420px;
  padding: 16px; border: none; border-radius: 16px;
  background: #fff; color: var(--brand-ink);
  font: inherit; font-size: 17px; font-weight: 700; cursor: pointer;
}
#voice-done:active { transform: scale(.98); }

@keyframes breathe {
  0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(247,166,0,.45); }
  50% { transform: scale(1.06); box-shadow: 0 0 0 28px rgba(247,166,0,0); }
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

/* --- Aktionskarten (§5.4) --- */
.card {
  align-self: flex-start;
  max-width: 86%;
  background: var(--brand-surface);
  border: 1px solid var(--brand-line);
  border-left: 3px solid var(--brand-line);
  border-radius: var(--radius);
  border-bottom-left-radius: 6px;
  box-shadow: 0 1px 2px rgba(20,35,58,.05);
  padding: 14px 16px;
  animation: rise .28s cubic-bezier(.22,.61,.36,1);
}
.card.success { border-left-color: var(--brand-success); }
.card-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.card-icon {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  background: var(--brand-success); color: #fff;
  display: grid; place-items: center; font-size: 15px; font-weight: 800;
}
.card-title { font-weight: 700; font-size: 15.5px; }
.card-lines { margin: 0; display: grid; gap: 8px; }
.card-lines > div { display: flex; justify-content: space-between; gap: 16px; font-size: 15px; }
.card-lines dt { color: var(--brand-muted); margin: 0; }
.card-lines dd { margin: 0; font-weight: 600; text-align: right; }
.card-note { margin: 12px 0 0; font-size: 13.5px; line-height: 1.45; color: var(--brand-muted); }
.card.auth { border-left-color: var(--brand-primary); }
.card.auth .card-icon { background: var(--brand-primary); color: var(--brand-on-primary); }
.card.ticket { border-left-color: var(--brand-ink); }
.card.ticket .card-icon { background: var(--brand-ink); color: #fff; }
.card.handoff { border-left-color: var(--brand-ink); }
.card.handoff .card-icon { background: var(--brand-ink); color: #fff; }
.card.tariff { border-left-color: var(--brand-primary); }
.card.tariff .card-icon { background: var(--brand-primary); color: var(--brand-on-primary); }

/* Hervorgehobene Zeile (z.B. Jahresersparnis): setzt sich mit einer Trennlinie vom
   Vergleich darüber ab, damit das Ergebnis nicht als vierter gleichrangiger Wert untergeht. */
.card-lines > div.highlight {
  margin-top: 2px; padding-top: 10px;
  border-top: 1px solid var(--brand-line);
}
.card-lines > div.highlight dt { color: var(--brand-ink); font-weight: 600; }
.card-lines > div.highlight dd { font-size: 17px; font-weight: 800; }

.card-secondary {
  display: block;
  margin: 10px 0 0; padding: 0;
  border: none; background: none;
  color: var(--brand-muted);
  font: inherit; font-size: 13.5px; font-weight: 600;
  text-decoration: underline; text-underline-offset: 2px;
  cursor: pointer;
}
.card-secondary:hover { color: var(--brand-ink); }
.card-action {
  margin-top: 14px;
  width: 100%;
  padding: 12px;
  border: none; border-radius: 12px;
  background: var(--brand-primary); color: var(--brand-on-primary);
  font: inherit; font-size: 15px; font-weight: 700; cursor: pointer;
  transition: background .15s, transform .06s;
}
.card-action:hover { background: var(--brand-primary-strong); }
.card-action:active { transform: scale(.98); }

/* Zustimmungsschritt (§5.5). Zwei Knöpfe nebeneinander, GLEICH breit — der Brief
   verlangt eine aktive Entscheidung. Ein breiteres „Ja" wäre eine Voreinstellung
   durch die Hintertür. */
.card.consent { border-left-color: var(--brand-primary); }
.card.consent .card-icon { background: var(--brand-primary); color: var(--brand-on-primary); }
/* Beantwortet: die Karte bleibt als Beleg stehen, sieht aber nicht mehr nach einer
   offenen Frage aus. */
.card.consent.decided { border-left-color: var(--brand-line); }
.card.consent.decided .card-icon { background: #F0F2F5; color: var(--brand-muted); }
.card.consent.decided .card-note { color: var(--brand-ink); font-weight: 600; }

.card-choice { display: flex; gap: 10px; margin-top: 14px; }
.card-choice button {
  flex: 1 1 0; min-width: 0;
  padding: 12px 10px;
  border-radius: 12px;
  font: inherit; font-size: 15px; font-weight: 700; cursor: pointer;
  transition: background .15s, transform .06s, opacity .15s;
}
.card-choice-yes { border: none; background: var(--brand-primary); color: var(--brand-on-primary); }
.card-choice-yes:hover { background: var(--brand-primary-strong); }
.card-choice-no { border: 1px solid var(--brand-line); background: transparent; color: var(--brand-ink); }
.card-choice-no:hover { background: #F0F2F5; }
.card-choice button:active { transform: scale(.98); }
.card-choice button:disabled { opacity: .55; cursor: progress; }

/* Unter 340 px (kleine Telefone im Querformat der Tastatur) stehen zwei Knöpfe
   nebeneinander zu eng, um sie sicher zu treffen. */
@media (max-width: 340px) {
  .card-choice { flex-direction: column; }
}

@media (prefers-reduced-motion: reduce) {
  .msg, .card, #mic.recording, #voice-orb, #voice { animation: none; }
}
