/* ============================================================
   ACTANOL Assistent — Styles (Vollversion)
   Dynamische Werte (Fenstergröße, Launcher-Breite, Segment-Zustände)
   setzt chatbot.js inline.

   FARBGEBUNG: Stand der Demo-Fassung (demo-properus/quellen/assistent/chatbot.css).
   Am 09.08.2026 waren hier Textgrün, Rahmen und weisse Schrift auf Gruen abgedunkelt
   worden, um WCAG 2.2 AA zu erreichen (Befunde A2, A3, A4 in docs/a11y-befunde.md).
   Am 10.08.2026 auf Wunsch von ACTANOL zurueckgesetzt — der Kunde kennt und will die
   Demo-Fassung. Die frueheren Werte stehen jeweils als Kommentar daneben.

   Zielstandard Barrierefreiheit bleibt WCAG 2.2 AA. An den zurueckgesetzten Stellen
   wird er NICHT mehr erreicht; die Messwerte stehen vollstaendig in
   docs/a11y-befunde.md und als datierte Ausnahmeliste in tools/a11y-ausnahmen.mjs.
   Alles ausserhalb dieser Liste bleibt scharf geprueft.
   ============================================================ */

@keyframes acDot{0%,60%,100%{transform:translateY(0);opacity:.3}30%{transform:translateY(-4px);opacity:.9}}
@keyframes acRise{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes acRing{0%{transform:scale(1);opacity:.5}80%{transform:scale(2.1);opacity:0}100%{opacity:0}}
@keyframes acPop{from{opacity:0;transform:translateY(10px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}
/* `@keyframes acWin` ist entfallen. Eine Keyframe-Animation laeuft beim Einblenden
   unabhaengig vom Zustand ab und schreibt dabei `transform` — auf dem Handy fiel der
   Autofokus mitten in diese 0,42 s. Das Oeffnen laeuft jetzt als `transition` ueber
   `.ja-win--offen` (siehe .ja-win). */
@keyframes acAurora{0%{transform:translate3d(0,0,0) scale(1)}50%{transform:translate3d(-5%,8%,0) scale(1.18)}100%{transform:translate3d(4%,-6%,0) scale(1.06)}}
@keyframes acBlink{0%,49%{opacity:1}50%,100%{opacity:0}}
@keyframes acFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-3px)}}

/* Bildlaufleiste: bis 09.08.2026 #8A939C (3,47:1). Kein Erfolgskriterium beruehrt —
   eine Bildlaufleiste ist kein Bedienelement im Sinne von SC 1.4.11 —, aber gleiche
   Herkunft wie die uebrigen Rueckstellungen. */
.ja-sc{scrollbar-width:thin;scrollbar-color:var(--muted-2) transparent;}
.ja-sc::-webkit-scrollbar{width:7px;height:7px}
.ja-sc::-webkit-scrollbar-thumb{background:var(--muted-2);border-radius:20px}
.ja-sc::-webkit-scrollbar-track{background:transparent}

/* ---------- Root ---------- */
/* ---- Farbrollen, die css/site.css nicht kennt -----------------------------
   Alles andere kommt direkt aus den Tokens der Website (--navy, --blue-600, …).
   Diese drei Rollen hat site.css nicht als Variable: Fehlerflaeche und -rand
   stehen dort nur inline in .form-status, der Online-Punkt nur im alten Chat. */
.ja-root{
  --ja-danger:#b3261e;
  --ja-danger-bg:#fdecec;
  --ja-danger-line:#f3c2c2;
  --ja-online:#41d59a;
}

.ja-root{position:fixed;z-index:2147483000;font-family:var(--font);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;}

/* ---- Gastgeber im Hero-Vollbild (10.09.2026) ----
   Einstellungen, Kontakt und Datenschutz werden fuer die Dauer der Anzeige aus dem Panel
   in den Hero-Kasten umgehaengt (siehe `zeigeAnsicht()` in js/assistent.js). Der
   Gastgeber traegt deshalb `ja-root`: Der ganze Kontrastblock am Ende dieser Datei
   haengt daran, ebenso der Reset und die Fokusringe. Diese Regel nimmt ihm nur, was ein
   schwebendes Fenster braucht und ein eingebetteter Kasten nicht.
   `position:static` ist Absicht — der Kasten soll im Fluss der Karte stehen. */
.ja-root--im-hero{position:static;z-index:auto;display:flex;flex-direction:column;flex:1 1 auto;min-height:0;}
.ja-root *{box-sizing:border-box;margin:0;padding:0;}
.ja-root button{font-family:inherit;}
.ja-root textarea,.ja-root input{font-family:inherit;}

/* ---------- Teaser ---------- */
/* Breite folgt dem laengsten der beiden Saetze (25.08.2026, vorher fest 224px). Damit
   steht jeder Satz auf einer Zeile, in beiden Sprachen und unabhaengig davon, welche
   Schrift die Wirtsseite bereitstellt.
   `width:auto` waere hier FALSCH: `.ja-root` hat keine eigene Breite und enthaelt nur
   absolut positionierte Kinder, ist also 0 px breit — `auto` liefe auf Shrink-to-fit gegen
   0 hinaus und braeche jedes Wort um. `max-content` fragt den umgebenden Kasten nicht.
   Der Deckel haelt den Kasten auf schmalen Geraeten im Bild: er sitzt 82 px vom rechten
   Rand des Wurzelelements, das selbst 16 px Abstand haelt. 106 px lassen 8 px Luft nach
   links; darunter bricht der Text um wie frueher — Rueckfall, nicht Normalfall. */
.ja-teaser{position:absolute;bottom:6px;right:82px;width:max-content;max-width:min(300px,calc(100vw - 106px));background:#fff;border:1px solid var(--line);box-shadow:0 14px 34px -14px rgba(14,33,72,.4);border-radius:16px 16px 4px 16px;padding:14px 16px;animation:acPop .4s cubic-bezier(.2,.9,.3,1) both;}
/* Groesse bleibt 24x24 (SC 2.5.8), die Demo hat 22x22 an -8px. Zurueckgesetzt ist nur
   die Farbe: bis 09.08.2026 var(--muted), Hover-Rand #8A939C. */
.ja-teaser-close{position:absolute;top:-9px;left:-9px;width:24px;height:24px;border-radius:50%;border:1px solid var(--line-2);background:#fff;color:var(--muted-2);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;box-shadow:0 2px 6px -2px rgba(14,33,72,.25);}
.ja-teaser-close:hover{color:var(--text);border-color:var(--muted-2);}
.ja-teaser-top{display:flex;align-items:center;gap:7px;margin-bottom:5px;}
.ja-teaser-dot{width:7px;height:7px;border-radius:50%;background:var(--blue-600);box-shadow:0 0 0 3px rgba(29,73,194,.22);flex:0 0 auto;}
/* bis 09.08.2026: #5F7A32 (4,73:1). */
.ja-teaser-label{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--blue-600);}
.ja-teaser-text{font-size:13.5px;line-height:1.4;color:var(--text);}

/* ---------- Launcher ---------- */
.ja-launcher{position:absolute;bottom:0;right:0;border:none;border-radius:20px;cursor:pointer;background:var(--navy);padding:0;overflow:visible;display:flex;align-items:center;justify-content:flex-end;transition:width .35s cubic-bezier(.3,.9,.3,1);box-shadow:0 20px 44px -14px rgba(14,33,72,.55),0 4px 12px -4px rgba(0,0,0,.25);}
.ja-launcher-label{flex:1 1 auto;white-space:nowrap;overflow:hidden;color:#fff;font-size:14px;font-weight:700;letter-spacing:.02em;padding-left:20px;text-align:left;animation:acRise .28s ease both;}
.ja-launcher-iconwrap{position:relative;flex:0 0 auto;}
.ja-launcher-ring{position:absolute;inset:0;border-radius:20px;border:2px solid rgba(29,73,194,.85);animation:acRing 2.8s ease-out infinite;}
.ja-launcher-img{position:absolute;inset:0;width:100%;height:100%;border-radius:20px;}
.ja-badge{position:absolute;top:-2px;right:-2px;min-width:20px;height:20px;padding:0 5px;border-radius:12px;background:var(--ja-danger);border:2px solid #fff;color:#fff;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;}

/* ---------- Fenster ----------
   Geoeffnet wird ueber die Klasse `.ja-win--offen`, nicht ueber eine Keyframe-Animation.
   Grund steht oben bei den Keyframes. */
/* Fensterflaeche weiss seit 10.09.2026 (vorher var(--paper)). Das ist die Voraussetzung
   dafuer, dass die graue Bot-Blase sich abhebt — auf --paper laege --mist praktisch
   unsichtbar darauf. Vorbild ist die Hero-Karte auf der Startseite. Der Wechsel liegt
   unter ALLEN vier Ansichten; die Kontrastwerte sind danach neu gemessen worden. */
.ja-win{position:fixed;transform-origin:bottom right;display:flex;flex-direction:column;background:#fff;overflow:hidden;box-shadow:0 44px 96px -22px rgba(11,18,32,.55),0 14px 32px -14px rgba(11,18,32,.32),0 2px 8px rgba(0,0,0,.12);border:1px solid rgba(255,255,255,.6);color:var(--text);opacity:0;transform:translateY(20px) scale(.96);transition:opacity .3s cubic-bezier(.16,1,.3,1),transform .3s cubic-bezier(.16,1,.3,1);}
.ja-win--offen{opacity:1;transform:none;}

/* ---------- Header ---------- */
.ja-header{position:relative;flex:0 0 auto;padding:16px 16px 15px;background:#fff;color:var(--text);border-bottom:1px solid var(--line);overflow:hidden;}
.ja-aurora{position:absolute;inset:-40%;background:radial-gradient(60% 70% at 80% 20%,rgba(29,73,194,.14),transparent 60%),radial-gradient(45% 60% at 15% 90%,rgba(29,73,194,.07),transparent 55%);animation:acAurora 9s ease-in-out infinite alternate;}
.ja-header-row{position:relative;display:flex;align-items:center;gap:12px;}
/* Seit die Unterzeile zweizeilig ist, ist der Textblock hoeher als der Avatar und bestimmt
   die Zeilenhoehe. Mit `align-items:center` waeren Avatar und Kopfknoepfe dadurch um 5 bzw.
   7 px nach unten gerutscht. `align-self:flex-start` haelt sie an ihrer angestammten Hoehe.
   In allen Ansichten ohne Chat ist die Zeile genauso hoch wie vorher — dort aendert die
   Regel nichts. */
.ja-avatar,.ja-hbtns{align-self:flex-start;}
/* Die zwei Pixel, die die alte Zentrierung des 34-px-Textblocks in der 38-px-Zeile ergab.
   Nur in der Chat-Ansicht am Schreibtisch gesetzt — nur dort ist die Zeile ueberhaupt
   zweizeilig. So stehen Titel, Punkt und Hinweistext auf denselben Pixeln wie vorher. */
.ja-header-row--zweizeilig .ja-htext,
.ja-header-row--zweizeilig .ja-hbtns{margin-top:2px;}
.ja-hbtn{flex:0 0 auto;width:34px;height:34px;border:none;border-radius:10px;background:var(--paper);color:var(--muted);cursor:pointer;display:flex;align-items:center;justify-content:center;}
.ja-hbtn:hover{background:var(--blue-50);color:var(--blue-700);}
.ja-avatar{flex:0 0 auto;width:38px;height:38px;border-radius:10px;overflow:hidden;box-shadow:inset 0 0 0 1px rgba(26,34,48,.08),0 4px 12px -6px rgba(14,33,72,.25);animation:acFloat 4s ease-in-out infinite;}
.ja-avatar .ja-mark{width:100%;height:100%;}
.ja-htext{flex:1 1 auto;min-width:0;}
.ja-htitle{font-size:15px;font-weight:700;letter-spacing:.01em;line-height:1.1;}
/* bis 09.08.2026: var(--muted). Gilt fuer alle mit „bis 09.08." markierten Unterzeilen. */
/* Grundzustand unveraendert: eine Zeile, Punkt mittig dazu. `position:relative` legt die
   Zeile ueber die Aurora, wenn sie auf dem Handy direkt im Kopf haengt. */
.ja-hsub-row{position:relative;display:flex;align-items:center;gap:7px;margin-top:3px;font-size:12px;color:var(--muted-2);}
.ja-online{position:relative;width:7px;height:7px;flex:0 0 auto;}
.ja-online i{position:absolute;inset:0;border-radius:50%;background:var(--blue-600);}
.ja-online b{position:absolute;inset:0;border-radius:50%;border:1px solid var(--blue-600);animation:acRing 2.2s ease-out infinite;}
/* Grundzustand wie bisher: eine Zeile, bei Platzmangel mit „…" gekuerzt. Das gilt fuer die
   kurzen Untertitel der Nebenansichten und fuer das verkleinerte Fenster — dort bleibt die
   Kopfzeile dadurch exakt so hoch wie vor dem 26.08.2026. */
.ja-hsub{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}

/* ---- Zustand „zweizeilige KI-Kennzeichnung" ----
   Greift an genau zwei Stellen: im grossen Fenster am Schreibtisch (Klasse vom Skript) und
   auf dem Handy, wo die Zeile als eigener Streifen direkt im Kopf haengt. Alles hier sind
   Zusaetze zum Grundzustand darueber — die Reihenfolge ist tragend. */
.ja-header-row--zweizeilig .ja-hsub-row,
.ja-header > .ja-hsub-row{align-items:flex-start;line-height:1.35;}
/* haelt den gruenen Punkt an der ersten Zeile, statt ihn mittig zwischen beide zu setzen */
.ja-header-row--zweizeilig .ja-online,
.ja-header > .ja-hsub-row .ja-online{margin-top:3px;}
/* `pre-line` laesst das `\n` aus `STR.*.status` wirken */
.ja-header-row--zweizeilig .ja-hsub,
.ja-header > .ja-hsub-row .ja-hsub{overflow:visible;text-overflow:clip;white-space:pre-line;}
.ja-hbtns{flex:0 0 auto;display:flex;align-items:center;gap:6px;}

/* ---------- Views (gemeinsam) ----------
   `min-height:0`, weil das Fenster auf dem Handy `height:auto` hat: Ohne die Zeile
   schrumpft ein Flex-Kind nicht unter seinen Inhalt und schiebt die Eingabezeile
   unten aus dem Fenster. `overscroll-behavior:contain` haelt die Wirtsseite ruhig,
   wenn man am Ende der Liste weiterwischt. */
.ja-view{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;}

.ja-view--settings{padding:20px 18px;}
.ja-view--contact{padding:22px 20px;}
.ja-view--privacy{padding:22px 20px;}
.ja-view-title{margin:0 0 6px;font-size:21px;font-weight:700;letter-spacing:-.01em;color:var(--text);}
.ja-view-sub{margin:0 0 18px;font-size:13.5px;line-height:1.45;color:var(--muted);}

 
/* ---------- Chat: Banner + Kontextzeile ---------- */
.ja-offline-banner{flex:0 0 auto;display:flex;align-items:center;gap:8px;padding:8px 16px;background:var(--paper);border-bottom:1px solid var(--line);}
.ja-offline-banner span{font-size:11.5px;color:var(--muted);line-height:1.35;}

 

/* ---------- Chat: Log + Nachrichten ---------- */
.ja-log{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:18px 16px 8px;display:flex;flex-direction:column;gap:14px;}
.ja-brow{display:flex;align-items:flex-end;gap:9px;max-width:88%;align-self:flex-start;animation:acPop .32s cubic-bezier(.2,.9,.3,1) both;}
.ja-bavatar{flex:0 0 auto;width:28px;height:28px;border-radius:8px;overflow:hidden;margin-bottom:2px;}
.ja-bavatar .ja-mark{width:100%;height:100%;}
.ja-bcol{min-width:0;}
/* Graue Flaeche ohne Rand und ohne Schatten (10.09.2026, Entscheidung Nico). Vorher
   weiss mit 1 px Rand und Schlagschatten — dieselbe Blase steht im Hero-Chat der
   Startseite seit jeher als `.cmsg--bot .cmsg__bub` in --mist, und die beiden Fenster
   sollen sich nicht unterscheiden. --text auf --mist misst 13,8:1. */
.ja-bubble-bot{background:var(--mist);border-radius:16px 16px 16px 5px;padding:11px 14px;font-size:14px;line-height:1.5;color:var(--text);white-space:pre-line;}
.ja-bubble-bot b{font-weight:700;}
.ja-caret{display:inline-block;width:2px;height:14px;background:var(--blue-600);margin-left:3px;vertical-align:-2px;animation:acBlink 1s steps(1) infinite;}
.ja-urow{align-self:flex-end;max-width:86%;animation:acPop .32s cubic-bezier(.2,.9,.3,1) both;}
/* Weisse Schrift auf Markengruen: bis 09.08.2026 var(--navy) (6,16:1). Gleiche Ruecknahme bei
   .ja-btn-green und den Zeilen der Anruf-Kachel. */
.ja-bubble-user{background:var(--blue-600);color:#fff;border-radius:16px 16px 5px 16px;padding:11px 14px;font-size:14px;line-height:1.5;box-shadow:0 6px 16px -6px rgba(29,73,194,.55);white-space:pre-line;}
.ja-utime{font-size:10.5px;color:var(--muted-2);margin:5px 4px 0 0;text-align:right;} /* bis 09.08.: #6B7078 */

/* ---- Quellenkarten (10.09.2026) --------------------------------------------
   Aufbau uebernommen aus der ACTANOL-Demo (Spezifikation Quellenangabe, Abschnitt 3),
   Farben ausschliesslich aus den JOAL-Tokens von css/site.css. ACTANOLs Gruen und
   Graphit sind bewusst NICHT mitgekommen — das sind fremde Markenfarben.

   DIESE STELLEN SIND NEU UND ERFUELLEN DEN ZIELSTANDARD. Neue Bedienelemente sind nie
   Teil einer alten Abnahme; sie gehoeren in keine Ausnahmeliste. Gerechnet (Sollwert
   4,5:1 bei dieser Schriftgroesse), gemessen von tools/a11y-check.mjs:
     Label auf Weiss     var(--muted)    5,82:1     Label auf --mist   5,04:1
     Titel auf --paper   var(--text)    14,88:1
     Chip website        --blue-600 auf --blue-50    6,96:1
     Chip intern         --navy     auf --mist      13,68:1
     Aktion + Fokusring  --blue-600 auf --paper      7,03:1
   var(--muted-2) steht hier NICHT: 3,10:1 auf Weiss — genau der Wert, der schon auf der
   Ausnahmeliste steht.

   Der linke Farbbalken traegt keine Aussage allein: Der Typ steht daneben als Text im
   Chip (SC 1.4.1). ---- */
.ja-srcs{margin-top:8px;}
.ja-src-label{font-size:9.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin:2px 0 0 2px;}
.ja-src-list{list-style:none;margin:6px 0 0;padding:0;display:flex;flex-direction:column;gap:6px;}
.ja-src{display:flex;align-items:center;gap:10px;background:var(--paper);border:1px solid var(--line);border-left:3px solid var(--muted);border-radius:4px;padding:8px 11px;text-decoration:none;}
a.ja-src:hover{background:var(--blue-50);}
/* Der Fokusring gehoert in `outline` und nirgendwo sonst. Eine Dauer-Dekoration in
   diesem Kanal loescht die Fokusanzeige, ohne dass eine Zeile daran geaendert wird. */
a.ja-src:focus-visible{outline:2px solid var(--blue-600);outline-offset:2px;}
.ja-src--website{border-left-color:var(--blue-600);}
.ja-src--intern{border-left-color:var(--muted);}
.ja-src--amtlich{border-left-color:var(--navy);}
.ja-src-body{flex:1 1 auto;min-width:0;}
.ja-src-type{display:inline-block;font-size:9px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;border-radius:3px;padding:2px 6px;margin-bottom:3px;}
.ja-src-type--web{color:var(--blue-600);background:var(--blue-50);}
.ja-src-type--int{color:var(--navy);background:var(--mist);}
.ja-src-type--amt{color:var(--navy);background:#fff;}
.ja-src-title{display:block;font-size:11.5px;font-weight:500;color:var(--text);line-height:1.3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.ja-src-open{flex:0 0 auto;display:inline-flex;align-items:center;gap:4px;font-size:10px;font-weight:700;color:var(--blue-600);}
/* Im Hero liegt die Karte in der Blase auf var(--mist) — dort hebt Weiss sie ab,
   im Panel (weisse Flaeche) tut das var(--paper). */
.ja-srcs--im-hero{margin-top:10px;}
.ja-srcs--im-hero .ja-src{background:#fff;}
.ja-srcs--im-hero a.ja-src:hover{background:var(--blue-50);}

/* Meta-Zeile (Zeit + Feedback) */
.ja-meta{display:flex;align-items:center;gap:8px;margin:5px 0 0 4px;}
.ja-meta-time{font-size:10.5px;color:var(--muted-2);} 
 

 /* bis 09.08.: #5F7A32 */

/* Retry-Buttons (Fehler / Offline) */
.ja-retry{margin-top:8px;display:flex;align-items:center;gap:8px;background:#fff;border-radius:10px;padding:9px 13px;font-size:12.5px;font-weight:700;cursor:pointer;animation:acRise .3s ease both;}
.ja-retry--err{border:1px solid var(--ja-danger-line);color:var(--ja-danger);}
.ja-retry--err:hover{background:var(--ja-danger-bg);}
.ja-retry--off{border:1px solid var(--line-2);color:var(--muted);}
.ja-retry--off:hover{background:var(--paper);}

/* CTA-Karte (dunkel) */
.ja-cta{margin-top:8px;display:flex;align-items:center;gap:12px;width:100%;text-align:left;background:var(--navy);border:none;border-radius:14px;padding:12px 13px;cursor:pointer;box-shadow:0 12px 26px -12px rgba(14,33,72,.5);animation:acRise .35s ease both;}
.ja-cta:hover{transform:translateY(-1px);}
.ja-cta-icon{flex:0 0 auto;width:38px;height:38px;border-radius:10px;background:var(--blue-600);display:flex;align-items:center;justify-content:center;}
.ja-cta-body{flex:1 1 auto;min-width:0;}
.ja-cta-title{display:block;font-size:13.5px;font-weight:700;color:#fff;line-height:1.2;}
.ja-cta-sub{display:block;font-size:11.5px;color:rgba(255,255,255,.65);margin-top:2px;}

 
 
.ja-seg{display:flex;background:var(--mist);border-radius:12px;padding:4px;margin-bottom:6px;}
.ja-seg--settings{margin-bottom:24px;}
.ja-seg-btn{flex:1;border:none;cursor:pointer;border-radius:9px;padding:10px 6px;font-size:12.5px;font-weight:700;transition:all .2s;background:transparent;color:var(--muted-2);box-shadow:none;} /* bis 09.08.: var(--muted) */
.ja-seg-btn--lg{padding:10px;font-size:13.5px;}
.ja-seg-btn.is-active{background:#fff;color:var(--text);box-shadow:0 2px 6px -2px rgba(14,33,72,.2);}

 

 

 

/* Typing-Indikator */
.ja-typing{display:flex;align-items:flex-end;gap:9px;align-self:flex-start;animation:acPop .25s ease both;}
.ja-typing-bubble{background:#fff;border:1px solid var(--line);border-radius:16px 16px 16px 5px;padding:13px 15px;display:flex;gap:5px;}
.ja-typing-bubble i{width:6px;height:6px;border-radius:50%;background:var(--muted-2);animation:acDot 1.3s infinite;} /* bis 09.08.: #767F88 */
.ja-typing-bubble i:nth-child(2){animation-delay:.18s;}
.ja-typing-bubble i:nth-child(3){animation-delay:.36s;}

/* ---------- Hinweis „Neue Nachricht" ----------
   Kehrseite des Autoscroll-Schutzes (chatbot.js, zumEndeScrollen): Wer hochgescrollt eine
   aeltere Antwort liest, bekaeme sonst nicht mit, dass unten weitergeschrieben wird.
   Erscheint nur in genau diesem Fall. */
.ja-neu{flex:0 0 auto;align-self:center;margin:0 0 8px;padding:9px 14px;min-height:36px;display:inline-flex;align-items:center;gap:7px;background:var(--navy);color:#fff;border:none;border-radius:999px;font-size:12.5px;font-weight:700;cursor:pointer;box-shadow:0 10px 24px -10px rgba(14,33,72,.55);animation:acRise .22s ease both;}
.ja-neu:hover{background:var(--text);}
.ja-neu:active{transform:scale(.97);}

/* ---------- Chips / Aktionen ---------- */
.ja-actions{flex:0 0 auto;padding:6px 14px 4px;overflow-x:auto;animation:acRise .3s ease both;}
.ja-sugg-label{font-size:10.5px;font-weight:700;letter-spacing:.08em;color:var(--muted-2);margin:0 2px 7px;text-transform:uppercase;} /* bis 09.08.: var(--muted) */
/* nowrap statt wrap: eine Chip-Zeile bleibt fuer jede Branche in fester Hoehe, laengere
   FAQ-Texte (z. B. Branche "kommune") liessen die Zeile sonst 2-3-zeilig werden und
   drueckten .ja-log nach oben, bis die erste Nachricht verdeckt war. .ja-actions hat
   bereits overflow-x:auto — das faengt jetzt die ueberschuessige Breite ab. */
.ja-chip-row{display:flex;flex-wrap:nowrap;gap:7px;}
/* Chip-Rahmen bis 09.08.2026: #7E8790 (3,47:1). Der Rahmen macht den Chip als Bedienelement
   erkennbar und faellt damit unter SC 1.4.11; der Demo-Wert var(--muted-2) erreicht die 3:1 nicht. */
.ja-chip{background:#fff;border:1px solid var(--muted-2);color:var(--muted);border-radius:999px;padding:8px 13px;font-size:12.5px;font-weight:500;line-height:1.15;cursor:pointer;text-align:left;white-space:nowrap;flex-shrink:0;transition:transform .15s ease,border-color .15s ease;}
/* bis 09.08.2026: #55702C fuer Rand und Schrift. Der Hover legt var(--blue-50) unter die Schrift,
   nicht den helleren Fenstergrund — der Demo-Wert var(--blue-700) kommt dort auf 2,84:1. Gefunden
   im Codex-Review vom 09.08.2026, nachdem a11y-check.mjs Mauszustaende herstellt. */
.ja-chip:hover{border-color:var(--blue-600);background:var(--blue-50);color:var(--blue-700);transform:translateY(-1px);}
.ja-chip:active{transform:scale(.96);}

/* ---------- Eingabebereich ---------- */
/* Heller Blauton unter der Eingabe seit 10.09.2026, vorher halbtransparentes Weiss. Auf
   dem jetzt weissen Fenstergrund war die Zeile nicht mehr vom Verlauf zu unterscheiden.
   Entspricht `.herochat__foot` im Hero-Chat. `backdrop-filter` entfaellt damit — es
   filterte gegen eine Flaeche, die nicht mehr durchscheint. */
.ja-inputwrap{flex:0 0 auto;padding:14px 16px 12px;background:var(--blue-50);border-top:1px solid var(--line);}
/* DER KASTEN UM DIE EINGABE — die Stelle, um die es ACTANOL ausdruecklich geht.
   var(--line-2) auf dem Grund des Eingabebereichs ist mit 1,29:1 praktisch unsichtbar; genau
   so soll es sein. Bis 09.08.2026 stand hier #7E8790 (3,62:1).
   Was dabei aufgegeben wird, offen benannt: Das Textfeld hat keinen eigenen Rahmen, und die
   Fuellung der Leiste (#fff) unterscheidet sich vom Grund des Eingabebereichs
   (var(--blue-50)) um 1,08:1. Dieser Rahmen ist also das Einzige, was die Eingabe als
   Eingabe erkennbar macht — er faellt unter SC 1.4.11 und braeuchte 3:1.
   Siehe docs/a11y-befunde.md, Befund A3.
   Fuellung seit 10.09.2026 weiss statt var(--paper), passend zu `.chatinput` im Hero-Chat;
   an der Aussage oben aendert das nichts, nur die zwei Zahlen. */
.ja-inputbar{display:flex;align-items:flex-end;gap:8px;background:#fff;border:1px solid var(--line-2);border-radius:22px;padding:8px 8px 8px 18px;transition:border-color .2s ease,box-shadow .2s ease;}
/* Fokusring der Eingabeleiste. Stand HIER frueher NICHT — chatbot.js setzte ihn als
   Inline-Stil aus dem Zustandsfeld `inputFocus`. Jedes `focus` und `blur` lief dadurch
   durch einen vollen synchronen Rerender, an dessen Ende die Nachrichtenliste ans Ende
   sprang — auf iOS genau in dem Moment, in dem Safari das fokussierte Feld ins Bild holt.
   DASS er aus dem CSS kommt, bleibt (mobil-check.mjs prueft es). Nur die FARBEN sind die
   der Demo: bis 09.08.2026 #5F7A32 mit rgba(22,53,118,.20), also 4,82:1. */
.ja-inputbar:focus-within{border-color:var(--blue-600);box-shadow:0 0 0 3px rgba(29,73,194,.18);}
.ja-textarea{flex:1 1 auto;border:none;background:transparent;resize:none;outline:none;font-size:16px;line-height:1.5;color:var(--text);max-height:96px;padding:8px 0;}
/* Runder Knopf mit weissem Pfeil, deckungsgleich mit `.chatinput__send` im Hero-Chat
   (10.09.2026). Vorher 40x40 mit 14 px Radius und einem Papierflieger.
   `color:#fff` IST DER EIGENTLICHE FIX: Das Symbol traegt `stroke="currentColor"`, und
   ohne eigene Farbe erbte es var(--text) vom Fenster — ein dunkler Pfeil auf
   var(--blue-600), rund 1,7:1. Das Pruefwerkzeug misst Textstellen und die Fokusanzeige,
   nicht die Strichfarbe eines Symbols; der Wert ist deshalb nie aufgefallen.
   Weiss auf var(--blue-600) misst 7,5:1. */
.ja-send{flex:0 0 auto;width:42px;height:42px;border:none;border-radius:50%;cursor:pointer;background:var(--blue-600);color:#fff;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 12px -4px rgba(29,73,194,.55);transition:transform .15s ease;}
.ja-send:hover{transform:scale(1.06);}
.ja-send:active{transform:scale(.92);}
/* Gesperrt, solange eine Antwort laeuft (S8). Ohne diese Regel waere die Sperre nur
   technisch vorhanden und fuer sehende Nutzer nicht erkennbar.
   Der Pfeil wird dabei dunkel: Weiss auf var(--blue-300) haelt 1,96:1. SC 1.4.11 nimmt
   inaktive Bedienelemente ausdruecklich aus, es ist also kein Verstoss — man saehe den
   Pfeil nur schlicht nicht mehr. var(--blue-700) darauf misst 6,2:1 und laesst den
   Knopf ueber die helle Flaeche trotzdem als gesperrt lesen. */
.ja-send:disabled{background:var(--blue-300);cursor:default;box-shadow:none;transform:none;}
.ja-send:disabled svg{stroke:var(--blue-700);}
.ja-send:disabled:hover{transform:none;}
/* ACHTUNG: Diese Farbe ist wirkungslos, solange der Zaehler sichtbar ist. renderCounter()
   in chatbot.js setzt sie bei jedem Render inline (var(--muted-2), bei vollem Feld var(--ja-danger)) —
   in der Demo genauso. Der Wert hier greift nur, falls die Inline-Zuweisung entfaellt.
   In beiden Fassungen steht der sichtbare Zaehler damit bei 2,51:1. */
.ja-counter{text-align:right;font-size:10.5px;color:var(--muted-2);margin:4px 6px 0 0;} /* bis 09.08.: var(--muted) */
.ja-footer{margin:8px 4px 0;text-align:center;}
.ja-foot{font-size:10px;color:var(--muted-2);line-height:1.4;} /* bis 09.08.: var(--muted) */
.ja-foot + .ja-foot{margin-top:2px;}
.ja-foot b{font-weight:700;color:var(--muted);}
.ja-foot .ja-foot-sep{font-weight:400;color:var(--muted-2);margin:0 6px;} /* bis 09.08.: var(--muted) */
.ja-foot-btn{background:transparent;border:none;color:var(--blue-600);font-size:10px;cursor:pointer;text-decoration:underline;text-underline-offset:2px;padding:0;}
.ja-foot a{color:var(--blue-600);text-decoration:underline;text-underline-offset:2px;}
/* Die KI-Kennzeichnung. Bis 09.08.2026 #6B7078 (4,73:1). Sie bleibt Pflichtangabe und
   steht unveraendert da — nur eben blasser. */
.ja-footnote{font-size:10px;color:var(--muted-2);line-height:1.4;font-style:italic;margin-top:8px;}

/* ---------- Settings ---------- */
.ja-sec-label{font-size:11px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--muted-2);margin-bottom:11px;} 

 /* bis 09.08.: var(--muted) */
/* DER WEG IN DEN KONTRASTMODUS MUSS SELBST LESBAR SEIN (25.08.2026, Entscheidung Nico
   nach einem Codex-Review). Die uebrigen Abschnittslabels und Segmentknoepfe bleiben auf
   dem Demo-Stand — sie sind Teil der Abnahme. Diese eine Zeile ist es NICHT: Es gab sie
   bei der Abnahme nicht, also wird hier auch nichts Vereinbartes veraendert.
   Ohne diese Haertung muesste jemand mit eingeschraenktem Sehvermoegen einen Schalter mit
   2,51:1 bzw. 2,79:1 finden, um die lesbare Darstellung einzuschalten — und der
   Auslieferungszustand waere durch die Zeile an drei Stellen SCHLECHTER geworden (90 statt
   87 Fehlstellen). var(--muted) erreicht 5,59:1 auf dem Ansichtsgrund und 5,3:1 auf var(--mist).
   Preis, offen benannt: Die Zeile ist sichtbar dunkler als „SPRACHE" darueber. */
.ja-sec-label--a11y{color:var(--muted);}
.ja-seg-btn--a11y{color:var(--muted);}
.ja-set-list{border-top:1px solid var(--line);padding-top:16px;display:flex;flex-direction:column;gap:4px;}
.ja-set-item{display:flex;align-items:center;gap:11px;background:transparent;border:none;cursor:pointer;padding:11px 4px;font-size:14px;font-weight:600;color:var(--text);text-align:left;}
.ja-set-item:hover{color:var(--blue-600);} /* bis 09.08.: #5F7A32 */
.ja-set-item--danger{color:var(--ja-danger);}
.ja-set-item--danger:hover{color:var(--ja-danger);}
.ja-set-footer{margin-top:18px;text-align:center;}

/* ---------- Kontakt ---------- */
.ja-contact-icon{width:52px;height:52px;border-radius:14px;background:var(--blue-600);display:flex;align-items:center;justify-content:center;margin-bottom:16px;box-shadow:0 10px 22px -10px rgba(29,73,194,.6);}
.ja-view-sub--contact{margin:0 0 22px;line-height:1.5;}
.ja-tile{display:flex;align-items:center;gap:14px;text-decoration:none;border-radius:16px;padding:16px 16px;margin-bottom:12px;}
.ja-tile--call{background:var(--blue-600);box-shadow:0 10px 24px -12px rgba(29,73,194,.6);}
.ja-tile--call:hover{transform:translateY(-1px);}
.ja-tile--mail{background:#fff;border:1px solid var(--line);margin-bottom:20px;}
.ja-tile--mail:hover{border-color:var(--blue-600);}
.ja-tile-icon{flex:0 0 auto;width:42px;height:42px;border-radius:11px;display:flex;align-items:center;justify-content:center;}
.ja-tile-icon--call{background:rgba(255,255,255,.18);}
.ja-tile-icon--mail{background:var(--blue-50);}
.ja-tile-body{flex:1 1 auto;min-width:0;}
.ja-tile-title{display:block;font-size:15px;font-weight:700;line-height:1.15;}
/* Anruf-Kachel: weisse Schrift auf Markengruen, mit den abgestuften Deckkraeften der Demo.
   Bis 09.08.2026: var(--ink) / var(--ink) / var(--navy), alle ohne opacity.
   Die opacity macht es schlechter als die reine Farbe vermuten laesst — 2,36:1 bzw. 2,10:1
   statt der 2,51:1 von vollem Weiss. a11y-check.mjs rechnet opacity NICHT mit ein und
   meldet deshalb den guenstigeren Wert; nachgetragen in docs/a11y-befunde.md. */
.ja-tile-title--call{color:#fff;}
.ja-tile-title--mail{color:var(--text);}
.ja-tile-value{display:block;font-size:14px;font-weight:600;margin-top:2px;}
.ja-tile-value--call{color:#fff;opacity:.92;}
.ja-tile-value--mail{color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.ja-tile-desc{display:block;font-size:12px;margin-top:2px;}
.ja-tile-desc--call{color:#fff;opacity:.78;}
.ja-tile-desc--mail{color:var(--muted-2);} /* bis 09.08.: var(--muted) */
/* KEIN .ja-hours-Block. Die Demo hat hier eine Kachel „Erreichbarkeit — Mo–Fr, 8–17 Uhr".
   Die Angabe ist unbestaetigt und in der Vollversion bewusst nicht vorhanden; Begruendung
   in chatbot.js bei renderContact(). */
.ja-contact-note{margin:0;font-size:11.5px;line-height:1.5;color:var(--muted-2);} /* bis 09.08.: #6B7078 */

/* ---------- Datenschutz ---------- */
.ja-priv-title{margin:0 0 16px;font-size:19px;font-weight:700;color:var(--text);}
.ja-priv-p{margin:0 0 13px;font-size:13.5px;line-height:1.55;color:var(--muted);}
.ja-priv-link{display:inline-flex;align-items:center;gap:7px;margin-top:6px;color:var(--blue-600);font-size:13px;font-weight:700;text-decoration:none;} /* bis 09.08.: #5F7A32 */

/* ============================================================
   Mobilfassung
   ============================================================
   HIER STEHT ABSICHTLICH KEINE TASTATURNACHFUEHRUNG.

   In der Demo wurde das dreimal versucht und dreimal am iPhone verworfen:

     1. `--ja-kb`  — Tastaturhoehe samt `visualViewport.offsetTop` in ein unten
        verankertes `bottom`. Das Fenster sprang beim Antippen des Eingabefelds.
     2. `body{position:fixed}` mit gemerkter Scrollposition. Das Fenster verschob sich
        beim Tippen nach oben und BLIEB verschoben.
     3. `--ja-vvtop`/`--ja-vvh` — `offsetTop` in `top`, `visualViewport.height` in
        `height`. Das Fenster erschien beim Oeffnen gar nicht mehr.

   DER GRUND, in einem Satz: Auf iOS verankert WebKit `position:fixed`-Elemente am
   SICHTBAREN Viewport und verschiebt die Fixed-Ebene bereits selbst. Wer denselben
   Versatz noch einmal ins CSS rechnet, verschiebt zweimal — bei rund 300 px Tastatur
   rutscht das Fenster 600 px nach unten und ist weg. Anlauf 1 und 3 sind derselbe
   Fehler in anderer Verkleidung.

   Chrome verankert am LAYOUT-Viewport und rechnet deshalb nichts doppelt. Genau daher
   kommt der Unterschied zwischen den Browsern — und genau deshalb belegt ein gruener
   Chrome-Lauf hier nichts ausser dem Ausschluss der Ursache.

   Was hier steht, ist der Rueckbau vom 06.08.2026: reine CSS-Geometrie ueber
   `env(safe-area-inset-*)`, kein Wert aus JavaScript. Wortgleich mit `.chatbot-panel`
   auf properus.de und `.chatfab__panel` auf junges-ostallgaeu.de — beide laufen auf
   demselben iPhone.

   PREIS, offen benannt: Bei offener Tastatur kann die Eingabezeile kurz teilverdeckt
   sein, bis iOS das fokussierte Feld selbst ins Bild holt. Die beiden anderen Chatbots
   verhalten sich genauso.
   ============================================================ */

/* Ab 768 px setzt chatbot.js eine feste Fensterhoehe. `max-height` deckelt sie, damit
   das Fenster in einem niedrigen Browserfenster oben nicht aus dem Bild waechst. */
@media (min-width:768px){
  .ja-win{max-height:calc(100dvh - 40px);}
}

@media (max-width:767px){
  .ja-win{
    top:calc(env(safe-area-inset-top,0px) + 8px);
    left:max(8px,env(safe-area-inset-left,0px));
    right:max(8px,env(safe-area-inset-right,0px));
    bottom:max(8px,env(safe-area-inset-bottom,0px));
    width:auto;height:auto;
    border-radius:18px;
    /* iOS Safari clippt `overflow:hidden` neben `backdrop-filter` nicht zuverlaessig —
       die Kopfzeile stoesst sonst als harte Ecke durch. */
    clip-path:inset(0 round 18px);
    transform-origin:center;
    transform:translateY(14px) scale(.985);
  }
  .ja-win--offen{transform:none;}

  /* Wirtsseite ruhig halten, solange das Fenster den Bildschirm fuellt.

     HIER STAND IN DER DEMO ZEITWEISE `position:fixed` samt gemerkter Scrollposition
     (Anlauf 2). Das setzte den Scroll-Spielraum auf 0 — und damit fehlte Safari der Weg,
     den Versatz zurueckzunehmen, den es beim Fokus eines Eingabefelds selbst erzeugt.
     Das Fenster blieb nach dem Absenden verschoben stehen. Begruendung ausfuehrlich in
     chatbot.js (setzeVollbildSperre). */
  body.ja-vollbild{overflow:hidden;}

  /* HIER STAND `.ja-textarea,.ja-input,.ja-textarea-sm{font-size:16px;}` — die Regel gegen
     den iOS-Zoom beim Fokus. Sie stand nur hier, weil die Grundregeln 14,5 / 13,5 px
     hatten. Seit dem 10.08.2026 setzen die Grundregeln selbst 16 px (Demo-Stand), damit
     waere die Wiederholung wirkungslos. Die Anforderung bleibt: unter 16 px zoomt iOS
     hinein und nie wieder heraus. Geprueft in tools/mobil-check.mjs, die Pruefung selbst
     in tools/mobil-gegenprobe.mjs (G5). */

  /* Bedienelemente auf Fingergroesse. Die Kopfzeile hatte drei 34-px-Knoepfe mit 6 px
     Abstand — auf Touch zu eng beieinander. */
  .ja-hbtn{width:44px;height:44px;}
  .ja-hbtns{gap:10px;}
  /* Hier bestimmen die 44-px-Knoepfe die Zeilenhoehe, nicht der Textblock — die Unterzeile
     haengt in der Chat-Ansicht ohnehin darunter. Die Ausrichtung bleibt deshalb mittig. */
  .ja-avatar,.ja-hbtns{align-self:center;}
  /* Streifenoptik fuer die KI-Kennzeichnung. Der Selektor greift nur, wenn die Unterzeile
     direkt im Kopf haengt — und dorthin haengt sie das Skript ausschliesslich auf dem Handy
     und nur in der Chat-Ansicht. Ueberall sonst steht sie unveraendert unter dem Titel.
     Die negativen Aussenabstaende ziehen den Streifen bis an die Kopfkanten (seitlich 16 px,
     unten die 11 px aus der Regel darunter), damit die Trennlinie durchlaeuft.
     Der Hintergrund bleibt WEISS: Ein grauer Streifen saehe besser abgesetzt aus, wuerde
     aber den Kontrast von var(--muted-2) genau dort verschlechtern, wo tools/a11y-check.mjs mit
     seinem 1280-px-Viewport nicht hinsieht — die Verschlechterung bliebe unbemerkt. */
  .ja-header > .ja-hsub-row{
    margin:8px -16px -11px;
    padding:7px 16px 8px;
    border-top:1px solid var(--line);
    line-height:1.3;
  }
  /* Wo der Streifen steht, traegt der Kopf drei statt einer Zeile. Nur dort wird die
     Polsterung knapper gesetzt, damit dem Chatverlauf bei offener Tastatur nicht noch mehr
     Hoehe verloren geht — die uebrigen Ansichten behalten ihre bisherige Kopfhoehe. */
  .ja-header--streifen{padding:12px 16px 11px;}

  /* HIER STAND BIS ZUM 10.09.2026: „Die Schrift bleibt bei 12 px: Die KI-Kennzeichnung
     ist Pflichttext, sie wird nicht kleiner gerechnet, um Zeilen zu sparen."
     Nico hat am 10.09.2026 anders entschieden: Bei 12 px fiel „generiert." in eine dritte
     Zeile, und der Streifen nahm dem Chatverlauf drei Zeilen Hoehe weg.

     11 px ist gemessen, nicht geschaetzt: Der zweite Satz braucht bei 12 px 346,2 px,
     zur Verfuegung stehen 326 px (390 px Geraetebreite). Rechnerisch noetig waeren
     11,3 px — 11 px laesst 8,7 px Luft.

     Grenze, die dazugehoert: Das haelt ab rund 381 px Geraetebreite. Auf einem iPhone SE
     oder 13 mini (375 px) bricht „generiert." weiterhin um. Weiter herunter geht dieser
     Text nicht ohne neue Entscheidung.

     Der Kontrast aendert sich dadurch nicht (Farbe unveraendert, 3,10:1), und 11 px
     liegt wie 12 px unter der Grossschrift-Schwelle von 24 px — der Sollwert bleibt
     4,5:1, der Ausnahmeeintrag `ja-hsub` gilt unveraendert weiter. tools/a11y-check.mjs
     misst mit 1440 px Viewport und sieht diesen Streifen nicht — der Lauf belegt fuer
     diese Zeile nichts.

     NACHTRAG, wenige Stunden spaeter: 11 -> 10,5 px. Nico wollte oben und unten dieselbe
     Schriftgroesse, und der Fussbereich stand auf 10 px. Getroffen haben wir sie in der
     Mitte — der Fussbereich geht auf 10,5 px hoch, dieser Streifen auf 10,5 px herunter.
     Nebenwirkung, die dabei erwuenscht ist: Der zweite Satz braucht jetzt 303 statt
     317 px und passt damit auch auf 375 px (iPhone SE, 13 mini), wo er bei 11 px noch
     dreizeilig war. Erst unter rund 360 px bricht er weiterhin um. */
  .ja-header > .ja-hsub-row{font-size:10.5px;}
  .ja-send{width:44px;height:44px;}
  .ja-chip{padding:15px;font-size:13.5px;}
  /* Textknoepfe: Mindestmass 24 px nach WCAG 2.2 AA (SC 2.5.8). Die Polsterung
     vergroessert nur die Trefferflaeche, die Schrift bleibt wie sie ist. Die oft
     zitierten 44 px sind Level AAA (2.5.5) — das behaupten wir hier nicht.

     10.09.2026: 7 -> 6 px. Diese Polsterung ist der Grund, warum die drei Fusszeilen
     UNGLEICH standen: Die beiden oberen enthalten Links und sind dadurch 27 px hoch, die
     Fussnote enthaelt keinen und ist 13 px hoch. Gemessen waren die Abstaende 27,0 und
     23,0 px. Bei 6 px ergeben Kastenhoehe (25,7) und der Aussenabstand der Fussnote
     (6 px) denselben Rhythmus — und die Trefferflaeche bleibt mit 25,7 px ueber dem
     Mindestmass. Bei 5 px waere sie 23,7 px und damit darunter; das ist die Untergrenze,
     nicht eine Frage des Geschmacks. */
  .ja-foot-btn,.ja-foot a{display:inline-block;padding:6px 4px;}

  /* Bei offener Tastatur bleiben vom Fenster nur rund 470 px. Eingabezeile und Fussbereich
     nahmen davon fast die Haelfte. Enger gesetzt — aber VOLLSTAENDIG: KI-Kennzeichnung,
     Verarbeiter und Datenschutzweg bleiben sichtbar, sie sind Pflicht und keine Zierde. */
  /* Enger gesetzt am 10.09.2026 (Nico: „Disclaimer unten etwas naeher aneinander"),
     wenige Stunden spaeter auf GLEICHE Abstaende gebracht (Nico: „zwischen allen drei
     Zeilen unten den gleichen Abstand") und auf 10,5 px vereinheitlicht mit dem Streifen
     oben (Nico: „oben und unten gleiche Schriftgroesse").

     Der ganze Rhythmus haengt an drei Zahlen, und sie muessen zusammen gerechnet werden:
       Zeilenhoehe 10,5 px x 1,3            = 13,7 px
       + Polsterung der Links 2 x 6 px      = 25,7 px Kastenhoehe der oberen zwei Zeilen
       Aussenabstand der Fussnote             6 px, damit 12,85 + 6 + 6,85 = 25,7
     Wer eine davon anfasst, muss die anderen nachziehen, sonst stehen die Zeilen wieder
     ungleich. Die Schriftgroesse steht bewusst hier und nicht in der Grundregel: am
     Schreibtisch bleiben es 10 px. */
  .ja-inputwrap{padding:10px 14px 6px;}
  .ja-footer{margin:2px 4px 0;}
  /* `.ja-foot-btn` MUSS mit: „Datenschutz" ist im Panel kein Link, sondern ein Knopf mit
     eigener Schriftgroesse (10 px in der Grundregel). Ohne diese Zeile stand er 0,5 px
     kleiner als der Satz, in dem er steht — in der Messung sichtbar, mit dem Auge kaum. */
  .ja-foot,.ja-foot-btn{font-size:10.5px;}
  .ja-foot{line-height:1.3;}
  .ja-foot + .ja-foot{margin-top:0;}
  .ja-footnote{font-size:10.5px;margin-top:6px;line-height:1.3;}
  .ja-counter{margin-top:2px;}
  
  .ja-priv-link{padding:6px 0;}

  
  .ja-teaser-close::after{
    content:'';position:absolute;top:50%;left:50%;
    width:44px;height:44px;transform:translate(-50%,-50%);
  }
}

/* ============================================================
   Barrierefreiheit (WCAG 2.2 AA)
   ============================================================ */

/* ---------- Sichtbarer Fokus ----------
   Vorher stand an mehreren Stellen outline:none ohne Ersatz — Tastaturbedienung
   war damit blind. Zwei Ringe: aussen hell, innen gruen, damit die Marke sowohl
   auf hellem als auch auf dunklem Grund sichtbar bleibt. */
.ja-root :focus-visible{outline:2px solid var(--text);outline-offset:2px;border-radius:6px;}

.ja-root .ja-textarea:focus-visible{outline:2px solid var(--blue-700);outline-offset:2px;}
/* Der Fokusrahmen der Textfelder erscheint nur noch bei Tastaturbedienung.
   Anlass: Kundenwunsch vom 14.08.2026 — beim Klick in ein Feld wirkte das Rechteck wie
   eine aufgesetzte Kachel innerhalb der abgerundeten Leiste.
   Was hier NICHT passiert: die Regel abschalten. Bei Tab-Bedienung steht sie unveraendert;
   chatbot.js schaltet ueber `data-eingabeart` am Wurzelelement. Faellt das Attribut aus
   (etwa eine alte, gecachte chatbot.js), greifen diese Zeilen nicht und der Rahmen ist da —
   der Ausfall geht also in die sichere Richtung.
   Die Leiste selbst (`.ja-inputbar:focus-within`) bleibt in beiden Faellen gruen.
   `border-color` wird bewusst NICHT zurueckgesetzt: Der Wechsel var(--line-2) -> var(--blue-700) ist ein
   Farbwechsel und kein Kasten, und ein Reset hier waere spezifischer als
   `.ja-input.is-invalid` und wuerde den roten Fehlerrand ueberschreiben.
   `border-radius` dagegen schon: Die Auffangregel oben setzt 6px und ist spezifischer als
   `.ja-input` (10px) — die Feldecken wurden beim Reinklicken sichtbar kantiger. */
.ja-root[data-eingabeart="maus"] .ja-textarea:focus-visible{outline:none;}

.ja-root .ja-send:focus-visible{outline:2px solid var(--navy);outline-offset:3px;}
.ja-root .ja-launcher:focus-visible{outline:3px solid var(--text);outline-offset:3px;border-radius:999px;}
.ja-root .ja-hbtn:focus-visible,
.ja-root .ja-teaser-close:focus-visible{outline:2px solid #fff;outline-offset:2px;box-shadow:0 0 0 4px rgba(14,33,72,.55);}
/* Fokus im Header: dunkler Ring auf hellem Grund.
   Vorher stand hier ein WEISSER Ring mit dem Kommentar „liegt auf dunklem Grund" — der
   Kommentar stammt aus einer Zeit, in der die Kopfleiste dunkel war. Sie ist heute
   #fff (siehe .ja-header): Der weisse Ring hatte damit 1:1 und war schlicht nicht da.
   Sichtbar blieb der Fokus nur ueber den Schlagschatten aus der Regel darueber — also
   ueber eine Schicht, die niemand als tragend gekennzeichnet hatte. Gemessen mit
   tools/a11y-check.mjs. */
.ja-header .ja-hbtn:focus-visible{outline:2px solid var(--text);outline-offset:2px;}

/* ---------- Nur fuer Screenreader ---------- */
.ja-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;}

 
/* ---------- Hinweis am Eingabefeld ----------
   `.ja-inputhint` („Bitte keine sensiblen Daten eingeben.") ist am 10.08.2026 entfallen —
   die Demo-Fassung hat ihn nicht. Der Hinweis ist damit nicht verschwunden: Er steht
   weiterhin als dritter Absatz in der Datenschutzansicht (PRIVACY in chatbot.js).
   `.ja-inputbusy` BLEIBT — das ist der sichtbare Grund fuer die gesperrte Eingabe und
   damit Funktion, keine Zierde. Das Textfeld verweist per aria-describedby darauf. */
.ja-inputbusy{font-size:10.5px;line-height:1.4;color:var(--muted);margin:3px 6px 0 2px;font-weight:600;}

/* ---------- Bewegungsreduktion ----------
   Dauerlaeufer (Aurora, Ring, Float) werden abgeschaltet, Ein-/Ausblendungen auf
   eine sehr kurze Blende reduziert. Das Wort-fuer-Wort-Streaming schaltet
   chatbot.js zusaetzlich selbst ab (prefersReducedMotion). */
@media (prefers-reduced-motion: reduce){
  .ja-root *,.ja-root *::before,.ja-root *::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
  .ja-aurora,.ja-launcher-ring{display:none !important;}
  /* Das Fenster erscheint ohne Versatz. Die Regel darueber kuerzt die Dauer bereits auf
     .01ms; ohne diese Zeile liefe die Verschiebung trotzdem, nur sehr schnell. */
  .ja-win{transform:none;}
}

/* ============================================================
   BARRIEREFREIHEITSMODUS — zuschaltbar, Standard bleibt unberuehrt
   ============================================================

   WOZU DIESER BLOCK DA IST
   ACTANOL hat die Optik der Demo-Fassung ausdruecklich verlangt; die Kontrast-Haertung vom
   09.08.2026 wurde dafuer am 10.08.2026 zurueckgenommen. Der Assistent verfehlt seither
   WCAG 2.2 Level AA an 65 gemessenen Stellen (61 im Widget, 4 am Launcher). Dieser Block
   holt die gehaerteten Werte zurueck — aber nur fuer den, der sie einschaltet.
   Geschaltet wird ueber `data-kontrast="hoch"` am Wurzelelement (chatbot.js).

   Die Werte sind NICHT neu erfunden. Es sind die Werte vom 09.08.2026, die im Stylesheet
   darueber als „bis 09.08."-Kommentar stehen und damals mit 50/50 gruen gemessen waren.
   Herleitung je Stelle in docs/a11y-befunde.md (Befunde A2, A3, A4, A6).

   WARUM EIN EIGENER BLOCK UND KEINE CSS-VARIABLEN
   Variablen waeren sauberer, wuerden aber jede vorhandene Regel anfassen. Genau das hat der
   Kunde ausgeschlossen. So gilt: Fehlt das Attribut, greift hier keine einzige Zeile — der
   abgenommene Zustand ist damit nachweisbar unberuehrt, nicht nur vermutlich.

   WAS DIESER MODUS NICHT IST
   Er macht den Assistenten NICHT WCAG 2.2 AA konform. Konformitaet wird am ausgelieferten
   Standardzustand gemessen, und der bleibt an 65 Stellen darunter. Der Modus ist ausserdem
   erst erreichbar, NACHDEM das Fenster offen ist — der Launcher bleibt beim ersten Besuch
   unveraendert. Nicht anders formulieren.

   DIE FALLE, DIE DIESEN BLOCK EINMAL FALSCH GEMACHT HAT
   Eine Grundregel hier ist mit (0,3,0) spezifischer als die Zustandsregeln oben, die meist
   (0,2,0) haben. `.ja-root[data-kontrast="hoch"] .ja-chip` ueberschreibt damit auch
   `.ja-chip:hover`, `.ja-seg-btn.is-active`, `.ja-input:focus-visible` und
   `.ja-set-item--danger:hover` — Hover, Fokus und Fehlerfarbe fielen still auf die
   Grundfarbe zurueck. Deshalb steht hinter JEDER Grundregel ihr Zustandssatz, und die
   Reihenfolge innerhalb einer Gruppe ist tragend: Grundrahmen, dann Fokus, dann Fehler.
   Wer hier etwas ergaenzt, prueft beide Punkte.

   ZWEITE FALLE: Inline-Stile aus chatbot.js schlagen jeden Selektor hier. renderCounter()
   ist deshalb dort umgestellt. Wer eine weitere Farbe inline setzt, muss sie dort mitziehen.

   Nachweis: `npm run a11y-kontrast` — erwartet 0 Ausnahmen. Jeder Fund ist rot.
   ============================================================ */

/* ---- Teaser und Bildlaufleiste.
        VON KEINEM LAUF GEDECKT: a11y-check.mjs misst das GEOEFFNETE Widget, der Teaser
        gehoert zum geschlossenen Zustand. Diese drei Werte stehen deshalb in keiner
        Ausnahmeliste — nicht weil sie in Ordnung waeren, sondern weil sie nie gemessen
        wurden. Sie tragen denselben „bis 09.08."-Rueckfallwert wie alles andere hier und
        gehoeren mitgezogen; gefunden beim Abgleich aller 33 Marker am 25.08.2026.
        Wie beim Launcher gilt: greift erst ab dem zweiten Besuch. ---- */
.ja-root[data-kontrast="hoch"] .ja-teaser-close{color:var(--muted);}
.ja-root[data-kontrast="hoch"] .ja-teaser-close:hover{color:var(--text);border-color:var(--muted-2);}
.ja-root[data-kontrast="hoch"] .ja-teaser-label{color:var(--blue-700);}
/* Eine Bildlaufleiste ist kein Bedienelement im Sinne von SC 1.4.11 — hier steht sie nur
   der Vollstaendigkeit halber, gleiche Herkunft wie die uebrigen Rueckstellungen. */
.ja-root[data-kontrast="hoch"] .ja-sc{scrollbar-color:var(--muted-2) transparent;}
.ja-root[data-kontrast="hoch"] .ja-sc::-webkit-scrollbar-thumb{background:var(--muted-2);}

/* ---- Kopfleiste, Zielgruppenwahl ---- */
.ja-root[data-kontrast="hoch"] .ja-hsub-row{color:var(--muted);}

/* ---- Nachrichten ----
   HIER STAND `.ja-bubble-user{color:var(--ink)}` — entfernt am 10.09.2026, DRITTE Stelle
   desselben Uebertragungsfehlers (nach der Anruf-Kachel und dem Sendeknopf):
   Beim ACTANOL-Assistenten liegt die Nutzerblase auf hellem Markengruen (#88B04B), dort
   waren dunkle Buchstaben die Verbesserung — 6,16:1 statt 2,51:1. Die JOAL-Fassung liegt
   auf var(--blue-600), einer DUNKLEN Flaeche. Gemessen am 10.09.2026: Der Standardzustand
   haelt dort 7,54:1 mit weisser Schrift, der Kontrastmodus drueckte ihn auf 2,48:1.
   Der Modus verschlechterte also ausgerechnet die eigenen Nachrichten des Nutzers.
   Gefunden ist das nur, weil ein Screenshot es zeigte: `a11y-check.mjs` schickte keine
   Nachricht und hatte deshalb nie eine Nutzerblase im Bild. Der Lauf sendet jetzt eine. */
.ja-root[data-kontrast="hoch"] .ja-utime{color:var(--muted);}
.ja-root[data-kontrast="hoch"] .ja-meta-time{color:var(--muted);}

/* ---- Quellenkarten: hier steht bewusst NICHTS.
        Sie sind am 10.09.2026 neu entstanden und erfuellen den Zielstandard bereits im
        Auslieferungszustand (schlechtester Wert 5,04:1 gegen einen Sollwert von 4,5:1).
        Der Kontrastmodus haette an ihnen nichts zu verbessern, und jede zusaetzliche
        Grundregel hier ueberschriebe still `:hover` und `:focus-visible` — der Fehler,
        der beim ACTANOL-Assistenten am 25.08.2026 den Fokusring geloescht hat.
        Wenn hier einmal etwas hinzukommt, gehoert der Zustandssatz direkt dahinter. ---- */

 
 
 

 

 

/* ---- Segmentleisten (Sprache, Darstellung, Kontaktzeit).
        Der aktive Knopf MUSS hinter der Grundregel stehen, sonst wird er heller statt
        dunkler und die Auswahl ist nicht mehr abzulesen. ---- */
.ja-root[data-kontrast="hoch"] .ja-seg-btn{color:var(--muted);}
.ja-root[data-kontrast="hoch"] .ja-seg-btn.is-active{color:var(--text);}

/* ---- Vorschlags-Chips ---- */
.ja-root[data-kontrast="hoch"] .ja-sugg-label{color:var(--muted);}
.ja-root[data-kontrast="hoch"] .ja-chip{border-color:var(--muted-2);}
.ja-root[data-kontrast="hoch"] .ja-chip:hover{border-color:var(--blue-700);color:var(--blue-700);}

/* ---- Eingabebereich. Der Rahmen der Leiste ist das Einzige, was die Eingabe als Eingabe
        erkennbar macht (Befund A3) — Demo-Wert 1,42:1 ruhend, 2,49:1 im Fokus. ---- */
.ja-root[data-kontrast="hoch"] .ja-inputbar{border-color:var(--muted-2);}
.ja-root[data-kontrast="hoch"] .ja-inputbar:focus-within{border-color:var(--blue-700);box-shadow:0 0 0 3px rgba(22,53,118,.20);}
/* HIER STAND `.ja-root[data-kontrast="hoch"] .ja-send svg{stroke:var(--ink)}` — entfallen
   am 10.09.2026, und der Grund gehoert festgehalten, damit es niemand zurueckbaut:
   Beim ACTANOL-Assistenten liegt der Sendeknopf auf hellem Markengruen, dort war dunkler
   Strich die Verbesserung. Die JOAL-Fassung liegt auf var(--blue-600), einer DUNKLEN
   Flaeche — var(--ink) darauf misst 1,3:1 und war damit schlechter als der Zustand, den
   der Modus verbessern soll. Dieselbe Kippstelle wie bei der Anruf-Kachel weiter unten.
   Der Standardzustand traegt jetzt `color:#fff` (7,5:1), der Modus muss nichts mehr tun. */
.ja-root[data-kontrast="hoch"] .ja-counter{color:var(--muted);}

/* ---- Fusszeile und KI-Kennzeichnung. Pflichtangabe, deshalb besonders unangenehm blass:
        2,01:1 im Chat, 1,92:1 in den Einstellungen. ---- */
.ja-root[data-kontrast="hoch"] .ja-foot{color:var(--muted);}
.ja-root[data-kontrast="hoch"] .ja-foot .ja-foot-sep{color:var(--muted);}
.ja-root[data-kontrast="hoch"] .ja-footnote{color:var(--muted);}

/* ---- Einstellungen. Der Zuruecksetzen-Eintrag ist rot und MUSS hinter der Hover-Regel
        stehen, sonst wird die gefaehrliche Aktion beim Ueberfahren gruen. ---- */
.ja-root[data-kontrast="hoch"] .ja-sec-label{color:var(--muted);}

.ja-root[data-kontrast="hoch"] .ja-set-item:hover{color:var(--blue-700);}
.ja-root[data-kontrast="hoch"] .ja-set-item--danger:hover{color:var(--ja-danger);}

/* ---- Kontakt. Die Anruf-Kachel traegt zusaetzlich opacity (.92/.78). Die muss WEG, sonst
        bleibt sie trotz dunkler Schrift unter dem Grenzwert — das Pruefwerkzeug rechnet
        Deckkraft nicht mit ein und meldete sonst einen zu guenstigen Wert. ---- */
/* Die Anruf-Kachel ist die einzige Stelle, an der die Farbrichtung beim Umzug KIPPT:
   Beim ACTANOL-Assistenten liegt sie auf hellem Markengruen, dort brauchte der
   Kontrastmodus DUNKLEN Text. Die JOAL-Fassung liegt auf --blue-600, einer dunklen
   Flaeche — dunkler Text darauf ergibt 2,48:1 und ist schlechter als der
   Standardzustand, den der Modus verbessern soll.
   Deshalb hier weiss (7,54:1 auf --blue-600) und die Deckkraft auf 1: Die
   Abschwaechung der Unterzeilen faellt im Kontrastmodus weg, das ist sein Zweck. */
.ja-root[data-kontrast="hoch"] .ja-tile-title--call{color:#fff;}
.ja-root[data-kontrast="hoch"] .ja-tile-value--call{color:#fff;opacity:1;}
.ja-root[data-kontrast="hoch"] .ja-tile-desc--call{color:#fff;opacity:1;}
.ja-root[data-kontrast="hoch"] .ja-tile-icon--call svg{stroke:#fff;}
.ja-root[data-kontrast="hoch"] .ja-tile-desc--mail{color:var(--muted);}
.ja-root[data-kontrast="hoch"] .ja-contact-note{color:var(--muted);}

/* ---- Datenschutz ---- */
.ja-root[data-kontrast="hoch"] .ja-priv-link{color:var(--blue-700);}

/* ---- Launcher. GREIFT ERST AB DEM ZWEITEN BESUCH, weil der Modus vorher nicht gesetzt
        sein kann — der Launcher ist zu sehen, bevor der Schalter erreichbar ist. Das ist
        die Grenze der Entscheidung „nur Schalter" und keine Nachlaessigkeit.
        Die sichtbare Randfarbe kommt aus dem Icon-BILD (.ja-launcher-img deckt den Knopf
        vollstaendig ab), nicht aus background-color; eine Farbueberschreibung ginge deshalb
        ins Leere. Stattdessen eine eigene Fassung aussen herum. Siehe Nachtrag vom
        15.08.2026 in docs/a11y-befunde.md. ---- */
/* DIE FASSUNG LIEGT IM box-shadow, NICHT IM outline — und das ist der Punkt.
   Der erste Entwurf setzte hier `outline:2px solid var(--text)`. Diese Regel ist mit (0,3,0)
   genauso spezifisch wie `.ja-root .ja-launcher:focus-visible` (Zeile 501) und steht
   spaeter — sie gewann damit AUCH IM FOKUS. Ein Tastaturnutzer im Kontrastmodus sah beim
   Antabben genau denselben Rahmen wie ohne Fokus: eine Fokusanzeige, die ausgerechnet im
   Barrierefreiheitsmodus verschwindet. Gefunden im Codex-Review vom 25.08.2026.
   `outline` ist der Kanal der Fokusanzeige und bleibt ihr deshalb allein vorbehalten; die
   dauerhafte Fassung kommt als zusaetzlicher Ring im box-shadow. Die beiden Schlagschatten
   dahinter sind die aus `.ja-launcher` und muessen mitgefuehrt werden — box-shadow
   ersetzt, es ergaenzt nicht. */
.ja-root[data-kontrast="hoch"] .ja-launcher{box-shadow:0 0 0 2px var(--text),0 20px 44px -14px rgba(14,33,72,.55),0 4px 12px -4px rgba(0,0,0,.25);}

/* ---- Das Markenzeichen ----------------------------------------------------
   Ersetzt das PNG des ACTANOL-Assistenten. Die Flaeche steht hier, der Schriftzug
   folgt ueber fill="currentColor" der Textfarbe — deshalb genuegt EIN SVG fuer
   Launcher (64 px), Kopfzeile (38 px) und Bot-Avatar (28 px).
   Anders als beim PNG traegt hier wieder background-color die sichtbare Flaeche;
   der Kommentar weiter oben zum Launcher-Rand gilt fuer diese Fassung nicht mehr. */
.ja-mark{display:flex;align-items:center;justify-content:center;
  background:var(--navy);color:#fff;border-radius:inherit;}
.ja-mark svg{width:78%;height:78%;display:block;}
.ja-launcher-img.ja-mark{border-radius:20px;}
