*{box-sizing:border-box} body{margin:0;background:var(--bg);color:var(--text);font-family:var(--font-ui);font-size:var(--text-base)}
a{color:var(--brand);text-decoration:none} a:hover{text-decoration:underline}
.vortex{height:3px;background:var(--vortex-line)}
header{padding:11px 24px;display:flex;align-items:center;gap:14px;border-bottom:1px solid var(--border);background:var(--surface)}
.logo{font-family:var(--font-display);font-weight:700;font-size:var(--text-sub)}
.logo span{color:var(--brand)}
.spacer{flex:1} .muted{color:var(--muted)} .mono{font-family:var(--font-mono)}
main{max-width:1440px;margin:0 auto;padding:20px 24px}
h1{font-size:var(--text-sub);margin:0;font-weight:600}
.karte{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;margin-bottom:10px}
.karte-kopf{padding:8px 14px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px;background:var(--surface-2);font-size:var(--text-sm)}
table{width:100%;border-collapse:collapse}
th{text-align:left;font-size:10px;text-transform:uppercase;letter-spacing:.7px;color:var(--muted);padding:6px 14px;font-weight:600}
td{padding:7px 14px;border-top:1px solid var(--border);vertical-align:middle;font-size:var(--text-sm)}
.chip{display:inline-flex;align-items:center;gap:5px;padding:2px 8px;border-radius:999px;font-size:11px;font-weight:600;border:1px solid var(--border);background:var(--surface-2)}
.punkt{width:7px;height:7px;border-radius:50%;flex:none}
.b-up{background:var(--tunnel-up)} .b-down{background:var(--tunnel-down)}
.b-disabled{background:var(--tunnel-disabled)} .b-unknown{background:var(--tunnel-unknown)}
.t-flowing{background:var(--traffic-flowing)} .t-idle{background:var(--traffic-idle)}
.t-oneway{background:var(--traffic-oneway)} .t-unknown{background:var(--tunnel-unknown)}
.knopf{display:inline-block;padding:9px 16px;border-radius:var(--radius);border:0;cursor:pointer;font-family:inherit;font-weight:600;font-size:var(--text-sm);color:#fff;background:var(--brand-gradient);box-shadow:0 4px 20px rgba(247,148,29,.3)}
.knopf:hover{box-shadow:0 6px 24px rgba(247,148,29,.45)}
.leer{padding:16px 14px;text-align:center;color:var(--muted);font-size:var(--text-sm)}
#keycloak-bg{position:fixed;inset:0;z-index:0;pointer-events:none}
.login{min-height:100vh;display:grid;place-items:center;position:relative;z-index:1}
.version{text-align:center;color:var(--muted);font-size:var(--text-caption);margin-top:16px}
.qr-reihe{display:flex;gap:22px;align-items:center;flex-wrap:wrap}
.qr{background:#fff;padding:12px;border-radius:var(--radius);line-height:0}
.qr svg{width:190px;height:190px;display:block}
.login-karte{width:min(380px,92vw);background:rgba(22,22,29,.82);backdrop-filter:var(--glass-blur);border:1px solid var(--border);border-radius:var(--radius-xl);padding:32px;box-shadow:0 24px 60px rgba(0,0,0,.5)}
label{display:block;font-size:var(--text-sm);margin:14px 0 6px;color:var(--muted)}
input{width:100%;padding:11px 13px;border-radius:var(--radius-sm);border:1px solid var(--border);background:var(--surface-2);color:var(--text);font-family:inherit;font-size:var(--text-base)}
input:focus{outline:0;border-color:var(--brand);box-shadow:0 0 0 3px var(--ring)}
.fehler{color:var(--state-error);font-size:var(--text-sm);margin-top:12px}
.aktionen{white-space:nowrap;text-align:right}
.tunnelname{font-weight:600}
.unterzeile{color:var(--muted);font-size:11px;margin-top:2px}
.marke{font-size:10px;text-transform:uppercase;letter-spacing:.5px;color:var(--muted);border:1px solid var(--border);border-radius:4px;padding:1px 5px;vertical-align:middle}
.chip.leise{background:transparent;border-color:transparent;color:var(--muted);padding-left:4px}
.punkt.gross{width:11px;height:11px;display:inline-block;margin-right:5px;cursor:help}
.pruef{white-space:nowrap}
.klein.haupt{border-color:var(--brand);color:var(--brand)}
.pruefchip{margin-right:4px}
.kopfzeile{display:flex;align-items:baseline;gap:12px;margin-bottom:14px;flex-wrap:wrap}
.zaehler{font-size:var(--text-sm)}
.filter{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.filter select,.filter input{padding:4px 8px;font-size:11px;width:auto;border-radius:var(--radius-sm)}
.filter input{width:160px}
.mandant{font-size:10px;text-transform:uppercase;letter-spacing:.7px;color:var(--muted);border:1px solid var(--border);border-radius:4px;padding:1px 6px;margin-right:2px}
.stift{background:none;border:0;color:var(--muted);cursor:pointer;font-size:var(--text-base);padding:0 4px;line-height:1}
.stift:hover{color:var(--brand)}
.modal{background:var(--surface);color:var(--text);border:1px solid var(--border);border-radius:var(--radius-lg);padding:24px;max-width:min(520px,94vw);width:94vw}
.modal.breit{max-width:880px}
.modal::backdrop{background:rgba(0,0,0,.6)}
.modal h3{margin:0 0 6px;font-size:var(--text-sub)}
.modal-fuss{display:flex;gap:10px;justify-content:flex-end;margin-top:20px}
.reiter{display:flex;gap:8px;align-items:center;margin:14px 0 12px;flex-wrap:wrap}
.zeile-eingabe{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:12px}
.zeile-eingabe input,.zeile-eingabe select{width:auto}
.messwert{background:var(--surface);border:1px solid var(--border);border-radius:999px;color:var(--text);font-family:var(--font-mono);font-size:11px;padding:3px 10px;cursor:pointer;margin-right:6px}
.messwert:hover{border-color:var(--brand)}
.messwert .pfeil{color:var(--muted);margin:0 3px 0 6px}
.messwert .pfeil:first-child{margin-left:0}
.schritte{list-style:none;padding:0;margin:14px 0 0;font-size:var(--text-sm)}
.schritte li{padding:6px 0 6px 20px;border-top:1px solid var(--border);position:relative}
.schritte li::before{position:absolute;left:0;top:6px}
.schritte li.ok::before{content:"✓";color:var(--state-ok)}
.schritte li.fehler::before{content:"✕";color:var(--state-error)}
.schritte li.laeuft::before{content:"…"}
/* Abfragestand je Standort: wann zuletzt gelesen, wann wieder. Bewusst leise — es ist
   eine Randnotiz, solange nichts schiefgeht, und faellt nur im Fehlerfall auf. */
.stand{display:flex;align-items:center;gap:8px;padding:6px 12px;
  border-top:1px solid var(--border);font-size:var(--text-caption);color:var(--text-muted)}
.stand .standtext.fehler{color:#e06c6c}
.stand form{margin:0}
.fehlermarke{color:#e06c6c;border-color:#e06c6c55;text-transform:none;letter-spacing:0;cursor:help}
/* Ein Link, der wie die Schaltflaechen daneben aussehen soll. Bewusst ein <a> und kein
   <button>: Er fuehrt woanders hin, also gehoert er in die Verlaufsliste des Browsers,
   laesst sich mit der mittleren Maustaste oeffnen und zeigt sein Ziel in der Statuszeile. */
.knopf-link{text-decoration:none;display:inline-block}
.knopf-link:hover{text-decoration:none;border-color:var(--brand);color:var(--brand)}
/* Fortschrittszeile: EIN Satz, was gerade passiert. */
.obJetzt{font-size:var(--text-sm);padding:8px 0;min-height:1.4em}
.obJetzt.laeuft{color:var(--text-muted)}
.obJetzt.laeuft::after{content:"";display:inline-block;width:.9em;text-align:left;
  animation:punkte 1.2s steps(4,end) infinite}
@keyframes punkte{0%{content:""}25%{content:"."}50%{content:".."}75%{content:"..."}}
.obJetzt.ok{color:var(--gruen,#3fb27f)}
.obJetzt.fehler{color:#e06c6c}
/* Ein gesperrter Knopf muss auch gesperrt AUSSEHEN — sonst klickt man ein zweites Mal. */
button:disabled,button[disabled]{opacity:.45;cursor:not-allowed;filter:saturate(.4)}
button:disabled:hover{border-color:var(--border)}
.grafik{background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);padding:12px}
.legende{display:flex;gap:18px;justify-content:center;color:var(--muted);font-size:var(--text-caption);margin-top:8px}
.legende i{display:inline-block;width:10px;height:10px;border-radius:2px;margin-right:6px;vertical-align:middle}
/* --- Protokollansicht (aus protokoll.ts hierher, siehe /stil.css) ------- */
  .filterleiste{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin:14px 0}
  .filterleiste input[type=search]{flex:1;min-width:180px}
  .tabellenrahmen{overflow-x:auto}
  table.protokoll{width:100%;border-collapse:collapse;font-size:var(--text-sm)}
  table.protokoll th{text-align:left;font-weight:600;color:var(--text-muted);
    font-size:var(--text-caption);text-transform:uppercase;letter-spacing:.04em;
    padding:6px 10px;border-bottom:1px solid var(--border)}
  table.protokoll td{padding:7px 10px;border-bottom:1px solid var(--border);vertical-align:top}
  table.protokoll tr:hover td{background:var(--surface-hover)}
  .zeit{white-space:nowrap;color:var(--text-muted)}
  .mono{font-family:'Fira Code',monospace;font-size:var(--text-caption)}
  .detail{font-size:var(--text-caption);margin-top:2px}
  .kat{display:inline-block;width:6px;height:6px;border-radius:50%;margin-right:7px;
    vertical-align:middle}
  .kat-anmeldung{background:#5b8def}.kat-steuerung{background:var(--brand)}
  .kat-diagnose{background:#3fb27f}.kat-verwaltung{background:#9b7fd4}
  .fehlgeschlagen td{background:rgba(220,80,80,.06)}
  .marke{font-size:var(--text-caption);color:#e06c6c;border:1px solid #e06c6c40;
    border-radius:4px;padding:1px 5px;margin-left:4px}
  @media (max-width:640px){ table.protokoll{font-size:var(--text-caption)} }
/* --- Tablet ------------------------------------------------------------- */
@media (max-width: 1100px){
  main{padding:16px}
  .modal.breit{max-width:96vw}
}
/* --- Telefon: Tabellen werden zu gestapelten Bloecken -------------------- */
@media (max-width: 780px){
  header{padding:10px 14px;gap:10px;flex-wrap:wrap}
  header .logo{font-size:var(--text-base)}
  main{padding:12px}
  .kopfzeile{gap:8px}
  .filter{width:100%}
  .filter select,.filter input{flex:1 1 130px;width:auto}
  .karte-kopf{flex-wrap:wrap;gap:6px}
  table,thead,tbody,tr,td{display:block;width:100%}
  thead{display:none}
  tr{border-top:1px solid var(--border);padding:8px 0}
  tr:first-child{border-top:0}
  td{border:0;padding:4px 14px;display:flex;gap:10px;align-items:flex-start}
  /* Die Spaltenueberschrift wandert vor den Wert — sonst ist ohne Kopfzeile
     nicht erkennbar, was ein Wert bedeutet. */
  td::before{content:attr(data-spalte);flex:0 0 84px;color:var(--muted);font-size:10px;
             text-transform:uppercase;letter-spacing:.7px;padding-top:3px}
  td[data-spalte="Tunnel"]::before{display:none}
  td[data-spalte="Tunnel"]{padding-top:8px}
  .aktionen{text-align:left;white-space:normal}
  .aktionen form{display:inline-block;margin-bottom:4px}
  .modal{padding:16px;width:96vw;max-height:92vh;overflow:auto}
  .reiter,.zeile-eingabe{gap:6px}
  .ausgabe{font-size:10px;max-height:48vh}
  .grafik{padding:6px}
}
.ausgabe{background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);padding:14px;font-family:var(--font-mono);font-size:var(--text-caption);line-height:1.55;max-height:52vh;overflow:auto;white-space:pre-wrap;word-break:break-word;margin:0}
.gruppe{margin-bottom:20px}
.gruppentitel{display:flex;align-items:baseline;gap:10px;font-size:var(--text-base);font-weight:600;margin:0 0 8px;padding-bottom:5px;border-bottom:1px solid var(--border)}
.klein{padding:4px 9px;margin-right:4px;border-radius:var(--radius-sm);border:1px solid var(--border);background:var(--surface-2);color:var(--text);font-family:inherit;font-size:11px;font-weight:600;cursor:pointer}
.klein:hover{border-color:var(--brand);color:var(--brand)}
.klein.warnend:hover{border-color:var(--state-warn);color:var(--state-warn)}
.hinweis{padding:12px 16px;border-radius:var(--radius);border:1px solid var(--border);background:var(--surface-2);margin-bottom:18px;font-size:var(--text-sm)}
.hinweis.fehlerbox{border-color:var(--state-error);color:var(--state-error)}
.trenner{display:flex;align-items:center;gap:12px;margin:20px 0 14px;color:var(--muted);font-size:var(--text-caption)}
.trenner::before,.trenner::after{content:"";flex:1;height:1px;background:var(--border)}
.knopf-zweit{display:block;text-align:center;padding:10px 16px;border-radius:var(--radius);border:1px solid var(--border);background:var(--surface-2);color:var(--text);font-weight:600;font-size:var(--text-sm);text-decoration:none}
.knopf-zweit:hover{border-color:var(--brand);color:var(--brand);text-decoration:none}