/*
 * testr. Verwaltung (admin.html) - seiteneigenes Stylesheet
 * =========================================================
 *
 * Ergaenzt css/core.css und ueberschreibt sie, wo diese Seite abweicht. Alles
 * Gemeinsame - Farben, feste Leiste, Knoepfe, Dialog- und Hilfefenster, Bildvorschau -
 * steht dort und gilt fuer Testbogen und Verwaltung gleichermassen.
 *
 * Hier steht, was es nur in der Verwaltung gibt: Reiter, Fragenkatalog samt Ziehen und
 * Verschieben, Tabellen mit ihrer Kartenansicht auf schmalen Schirmen, Auswertung mit
 * Ringdiagramm, der Testbogen eines Testers und der Druck davon.
 *
 * Eingebunden im Kopf von admin.html NACH core.css.
 */

html,body{margin:0;background:var(--bg);color:var(--ink);
  font-family:ui-sans-serif,-apple-system,"Segoe UI",Roboto,sans-serif;font-size:17px}
body{padding-top:var(--navh);padding-bottom:70px}
.wrap{max-width:1400px;margin:0 auto;padding:0 26px}
.navbar .wrap{max-width:1400px}
.navlinks{display:flex;align-items:center;gap:10px}
.navlinks .who{font-size:14.5px;color:var(--ink-soft);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;max-width:38vw}
.logo{display:inline-flex;align-items:center;font-size:21px;font-weight:750;
  letter-spacing:-.02em;text-decoration:none;color:var(--ink);white-space:nowrap}
/* Ohne border-radius: das PNG bringt seine runden Ecken schon mit. */
.logo img{display:block;height:30px;width:auto;margin-right:10px}
.logo .sub{font-weight:650;font-size:17px;color:var(--ink-soft);letter-spacing:0}
/* Auf kleinen Schirmen weicht der Zusatz, damit Name und Abmelden Platz behalten. */
@media (max-width:640px){
  .logo .sep,.logo .sub{display:none}
  .navlinks .who{display:none}
}

header.top{background:linear-gradient(180deg,var(--accent-soft),transparent 80%);border-bottom:1px solid var(--border);padding:26px 0 0}
header.top h1{font-size:30px;font-weight:750;margin:0 0 4px;letter-spacing:-.01em;
  display:flex;align-items:center;flex-wrap:wrap}
/* Zeichen, Wortmarke, blauer Punkt - dieselbe Kopfzeile wie auf der Startseite und im
   Testbogen. Das Zeichen waechst per em mit der Ueberschrift mit; kein border-radius,
   das PNG bringt seine runden Ecken selbst mit. */
h1 .brandmark{height:1.15em;width:auto;flex:0 0 auto;margin-right:.32em}
h1 .dot{color:var(--accent)}
h1 .sep{color:var(--ink-soft);font-weight:400;margin:0 .35em}
header.top p{margin:0 0 18px;color:var(--ink-soft);font-size:16px;max-width:74ch;line-height:1.55}
.tabs{display:flex;gap:4px;flex-wrap:wrap}
.tab{background:transparent;border:1px solid transparent;border-bottom:none;border-radius:9px 9px 0 0;
  padding:12px 22px;font-size:16.5px;font-weight:650;color:var(--ink-soft);cursor:pointer}
.tab:hover{color:var(--ink)}
.tab.on{background:var(--bg);border-color:var(--border);color:var(--accent)}
.panel{display:none;padding-top:24px}
.panel.on{display:block}
.projbar{display:flex;gap:8px;align-items:flex-end;flex-wrap:wrap;margin:0 0 16px}
.projbar select{min-width:300px}
.projbar .muted{padding-bottom:8px}

.bar{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:18px}
.bar .grow{flex:1 1 auto}
/* Zeichen und Beschriftung stehen ueber inline-flex mittig im Knopf. Ohne das
   entscheidet allein der Innenabstand ueber die Lage des Textes - ein Knopf mit
   eigener Hoehe (etwa "Anlegen & einladen" in der Einladungszeile) haette seinen
   Text dann nicht auf derselben Linie wie die Knoepfe daneben. */
.btn{font:inherit;font-size:15px;font-weight:600;color:var(--ink-soft);background:var(--surface);
  border:1px solid var(--border);border-radius:9px;padding:10px 17px;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;gap:7px;line-height:1.2}
.btn.primary{background:var(--accent);color:#fff;border-color:transparent}
.btn.danger{color:var(--crit-ink)}
.btn.danger:hover{border-color:var(--crit-ink)}
.btn:disabled{opacity:.45;cursor:not-allowed}
.icon{width:36px;height:36px;padding:0;display:grid;place-content:center;font-size:15px}

.card{background:var(--surface);border:1px solid var(--border);border-radius:12px;
  box-shadow:var(--shadow);padding:22px 26px;margin-bottom:18px}
/* Gefahrenzone im Reiter Konto. Nur die Umrandung und die Überschrift tragen die
   Warnfarbe - ein rot hinterlegter Block hätte den ganzen Reiter beherrscht, obwohl er
   das Seltenste enthält, was jemand hier tut. */
.card.danger-zone{border-color:var(--crit-ink)}
.card.danger-zone h2{color:var(--crit-ink)}
.card.danger-zone .muted{margin:0 0 14px}
.card h2{font-size:21px;font-weight:750;margin:0 0 14px;display:flex;align-items:center;gap:10px}
.card h2 .sp{margin-left:auto;display:flex;gap:4px}
.muted{color:var(--ink-soft);font-size:15px;line-height:1.6}
a:hover{color:var(--accent);text-decoration:underline}

input[type=text],input[type=email],input[type=password],textarea,select{
  font:inherit;color:var(--ink);background:var(--bg);border:1px solid var(--border);
  border-radius:8px;padding:11px 13px;width:100%}
input:focus-visible,textarea:focus-visible,select:focus-visible{border-color:var(--accent);outline:none}
/* Ein select mit width:auto richtet sich nach seiner laengsten Option. In der
   Auswertung stehen dort die Bereichsnamen des Katalogs - auf dem Telefon wird das
   Feld damit breiter als das Bild, die ganze Seite bekommt einen Seitwaertsschieber
   und jeder Inhalt darunter sieht aus, als stuende er nicht in voller Breite. Die
   Obergrenze gilt fuer alle Felder, auch die mit width:auto im style-Attribut:
   max-width sticht die dort gesetzte Breite. */
input,textarea,select{max-width:100%}

/* --- Ankreuzfelder ------------------------------------------------------
   Dieselbe Groesse und dieselbe Form wie im Testbogen (index.html, ul.chk):
   26px Kantenlaenge, 6px Radius, Haken in Weiss. Das Kaestchen des Browsers ist
   rund 13px gross - auf dem Telefon kaum zu treffen und neben 15px-Text zu klein.
   appearance:none schaltet die Darstellung des Systems ab; ohne sie bliebe das
   Kaestchen bei seiner Groesse und ignorierte Rahmen und Farbe. */
input[type=checkbox]{appearance:none;-webkit-appearance:none;flex:0 0 26px;
  width:26px;height:26px;margin:0;border:2px solid var(--ink-soft);border-radius:6px;
  background:var(--surface);cursor:pointer;display:inline-grid;place-content:center;
  vertical-align:middle;transition:background .12s,border-color .12s}
input[type=checkbox]::after{content:"";width:13px;height:7px;
  border-left:3px solid #fff;border-bottom:3px solid #fff;
  transform:rotate(-45deg) translate(1px,-1px) scale(0);transition:transform .12s}
input[type=checkbox]:checked{background:var(--accent);border-color:var(--accent)}
input[type=checkbox]:checked::after{transform:rotate(-45deg) translate(1px,-1px) scale(1)}
label.fld{display:flex;flex-direction:column;gap:6px;font-size:12.5px;text-transform:uppercase;
  letter-spacing:.05em;color:var(--ink-soft);flex:1 1 180px}

/* Zustimmung zu AGB und Datenschutz auf der Registrierungsmaske. Bewusst NICHT
   label.fld: Dort steht die Beschriftung ueber dem Feld, in Grossbuchstaben und
   gesperrt - fuer einen Satz mit Link ist das unlesbar. Hier steht das Kaestchen
   links daneben, oben ausgerichtet, damit ein zweizeiliger Satz nicht am Haken
   klebt. */
label.consent{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;
  line-height:1.45;color:var(--ink);cursor:pointer}
label.consent a{color:var(--accent)}

/* --- Datums- und Zahlenfelder -------------------------------------------------
   Die Browser bauen diese beiden Feldarten selbst zusammen: Zifferngruppen und
   Kalendersymbol beim Datum, Pfeiltasten bei der Zahl. Beide bringen ihre eigenen
   Innenabstaende mit und stehen ohne die Regeln hier hoeher als ein gewoehnliches
   Textfeld daneben - in einer Zeile aus beidem faellt das sofort auf. */
.fld input[type=date],.fld input[type=number]{height:43px;line-height:1.2;
  font-variant-numeric:tabular-nums}
.fld input[type=date]{padding-right:9px}
.fld input[type=date]::-webkit-calendar-picker-indicator{opacity:.55;cursor:pointer}
.fld input[type=date]:hover::-webkit-calendar-picker-indicator{opacity:1}
/* Die Pfeiltasten stehen sonst gedraengt am rechten Rand und nehmen der Zahl den Platz. */
.fld input[type=number]{padding-right:8px}

/* Eigener Platzhalter fuer ein leeres Datumsfeld. Das Muster, das der Browser von sich
   aus hineinschreibt (dd/mm/yyyy), folgt SEINER Spracheinstellung, nicht der hier
   gewaehlten - auf einer deutschen Oberflaeche steht dann englischer Text. Aendern
   laesst sich das nicht, also wird es verdeckt: ein Feld ohne Wert bekommt die Klasse
   "empty", und darueber liegt der eigene Hinweis. Sobald ein Datum drinsteht, ist er
   weg und der Browser zeigt es in seinem Format - das ist in Ordnung, weil es dann
   ein echtes Datum ist und kein Muster. */
.datebox{position:relative;display:block}
.datebox .ph{position:absolute;left:1px;right:36px;top:1px;bottom:1px;display:flex;
  align-items:center;padding-left:12px;border-radius:8px;background:var(--bg);
  color:var(--ink-soft);text-transform:none;letter-spacing:0;font-size:15px;
  pointer-events:none}
.datebox input:not(.empty) + .ph{display:none}

/* Nummerierte Anleitung im Reiter "Fragen". Die Ziffer steht in einem eigenen Kreis
   links neben dem Schritt, damit die drei Schritte als Abfolge lesbar sind und nicht
   als drei gleichrangige Absätze. */
ol.steps{list-style:none;counter-reset:step;margin:0;padding:0}
ol.steps>li{counter-increment:step;position:relative;padding:0 0 18px 44px;
  border-left:1px dashed var(--border);margin-left:14px}
ol.steps>li:last-child{border-left-color:transparent;padding-bottom:0}
ol.steps>li::before{content:counter(step);position:absolute;left:-14px;top:0;
  width:28px;height:28px;border-radius:50%;background:var(--accent-soft);color:var(--accent);
  display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:750}
ol.steps>li>b{display:block;font-size:16px;color:var(--ink);margin-bottom:4px}
ol.steps>li>p{margin:0 0 10px}

.grp{border-left:2px solid var(--border);padding-left:12px;margin:14px 0}
.grp-head{display:flex;gap:6px;align-items:center;margin-bottom:8px}
.grp-head input{flex:1 1 auto;font-weight:650}
.row{display:flex;gap:8px;align-items:flex-start;padding:7px 0;border-bottom:1px dashed var(--border)}
.row:last-child{border-bottom:none}
.row .txt{flex:1 1 auto}
.row .bdg{display:flex;gap:3px;flex:0 0 auto;padding-top:3px}
.bdg button{font:inherit;font-size:11.5px;font-weight:700;border-radius:6px;padding:5px 10px;
  border:1px solid var(--border);background:var(--bg);color:var(--ink-soft);cursor:pointer;white-space:nowrap}
.bdg button.on.crit{background:var(--crit-bg);color:var(--crit-ink);border-color:var(--crit-ink)}
.bdg button.on.tier{background:var(--tier-bg);color:var(--tier-ink);border-color:var(--tier-ink)}
.bdg button.on.plat{background:var(--plat-bg);color:var(--plat-ink);border-color:var(--plat-ink)}
.row .act{display:flex;gap:2px;flex:0 0 auto;padding-top:2px}

/* --- Punkte zwischen Gruppen verschieben ---------------------------------
   Der Griff ist ein eigenes Element und NICHT die ganze Zeile: Die Zeile enthält ein
   Texteingabefeld, und wäre sie selbst ziehbar, ließe sich der Text darin nicht mehr
   mit der Maus markieren - jeder Markierungsversuch würde zum Ziehen. */
/* touch-action:none haelt den Finger auf dem Griff beim Ziehen: Ohne das nimmt der
   Browser die Bewegung als Wischen und scrollt die Seite, statt den Punkt zu
   verschieben. Es gilt nur fuer den Griff - der Rest der Seite scrollt weiter. */
.row .grip{flex:0 0 auto;cursor:grab;user-select:none;color:var(--ink-soft);
  font-size:15px;line-height:1;padding:8px 7px;border-radius:6px;align-self:flex-start;
  touch-action:none;-webkit-tap-highlight-color:transparent}
.row .grip:hover{background:var(--accent-soft);color:var(--accent)}
.row .grip:active{cursor:grabbing}
.row.dragging{opacity:.4}
/* Einfügemarke: eine Linie ober- oder unterhalb der Zeile, auf der man gerade steht.
   Als box-shadow und nicht als border, damit die Zeile dabei nicht um 2px springt. */
.row.mark-before{box-shadow:0 -2px 0 var(--accent)}
.row.mark-after{box-shadow:0 2px 0 var(--accent)}
.grp.dropinto{background:var(--accent-soft);border-left-color:var(--accent)}
.sheet .card{width:100%;max-width:540px;margin:0;max-height:84vh;overflow:auto;
  border-radius:16px;box-shadow:0 12px 40px rgba(0,0,0,.28);animation:sheetIn .16s ease-out}
.sheet .card .quote{border-left:3px solid var(--accent);padding:6px 0 6px 12px;
  margin:0 0 16px;font-size:16px}

/* --- Hilfefenster -------------------------------------------------------
   Aufbau und Klassennamen absichtlich identisch zur MyTripWallet-App
   (/_mytripwallet/index.html) und zum Testbogen: #help-modal >
   .modal-content > .modal-header mit .modal-grabber, .close-btn und
   darunter das iframe. Ganzseitig statt als Kasten wie .sheet: Die Hilfe
   ist eine Seite zum Lesen und Scrollen, kein Dialog mit einer Frage.
   Der Inhalt kommt aus hilfe_admin_<lang>.html - siehe openHelpModal. */
/* Dieselbe Form fuer alle Zeichen-Knoepfe der Leiste - Hilfe und Abmelden. Sie
   stehen nebeneinander und muessen deshalb dieselbe Groesse haben; der Knopf
   hell/dunkel aus js/i18n.js bringt die gleichen Masse im style-Attribut mit. */
.help-btn,.nav-icon{font-family:inherit;font-size:15.5px;line-height:1;
  color:var(--ink-soft);background:var(--surface);border:1px solid var(--border);
  border-radius:9px;width:37px;height:37px;padding:0;cursor:pointer;flex:0 0 auto;
  display:inline-flex;align-items:center;justify-content:center}
.help-btn:hover,.nav-icon:hover{border-color:var(--accent);color:var(--accent)}
.modal .close-btn{font-family:inherit;font-size:22px;line-height:1;color:var(--ink-soft);
  background:none;border:0;padding:6px 4px;cursor:pointer}
@media print{.modal{display:none !important}}

table{width:100%;border-collapse:collapse;font-size:16px}
th,td{text-align:left;padding:13px 14px;border-bottom:1px solid var(--border);vertical-align:top}
/* Bereichstrenner in der Matrix - dieselbe Einteilung, die der Tester vor sich hat */
tr.sec-sep td{background:var(--surface);border-top:2px solid var(--accent);
  padding:11px 14px;font-family:ui-monospace,"SF Mono",Menlo,monospace;font-size:14px;
  letter-spacing:.06em;text-transform:uppercase;color:var(--accent);position:sticky;left:0}
tr.sec-sep td .cnt{color:var(--ink-soft);text-transform:none;letter-spacing:0;margin-left:8px}
th{font-size:13px;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-soft);
  position:sticky;top:0;background:var(--surface);z-index:2}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
tbody tr:hover{background:var(--accent-soft)}
.pill{display:inline-block;font-size:12px;font-weight:700;padding:4px 9px;border-radius:5px;white-space:nowrap}
.p-ok{background:var(--done-soft);color:var(--done)}
.p-fail{background:var(--crit-bg);color:var(--crit-ink)}
.p-na{background:var(--border);color:var(--ink-soft)}
/* Wartet auf die Freigabe durch den Admin - dieselbe Farbe wie die Tarif-Kennzeichnung
   im Katalog: etwas, das noch entschieden werden muss, aber kein Fehler ist. */
.p-wait{background:var(--tier-bg);color:var(--tier-ink)}
/* Woher jemand kommt. Zwei Kennzeichen statt eines: Ein fehlendes Merkmal liest sich
   als "unbekannt", und gerade bei den Bestandstestern soll klar dastehen, dass sie
   eingeladen wurden und sich nicht selbst gemeldet haben. */
.p-src-apply{background:var(--plat-bg);color:var(--plat-ink)}
.p-src-inv{background:transparent;color:var(--ink-soft);border:1px solid var(--border)}
.p-open{background:transparent;color:var(--ink-soft);border:1px dashed var(--border)}

.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(172px,1fr));gap:12px;margin-bottom:16px}
/* Jede Kachel trägt links ihren eigenen Ring - derselbe Bauplan wie der große Donut,
   nur mit einem einzigen Segment in der Farbe der Kachel. Der graue Rest ist der
   Bezugswert; welcher das je Kachel ist, sagt der Titel am Ring (siehe renderEval). */
.stat{border:1px solid var(--border);border-radius:10px;padding:14px 16px;background:var(--surface)}
/* Ring und Zahl nebeneinander, die Beschriftung darunter über die ganze Breite und links
   bündig mit dem Ring: Der Text ist oft zweizeilig ("von niemandem geprüft") und würde
   neben der Zahl entweder die Kachel breit machen oder umbrechen, wo er nicht soll. */
.stat-head{display:flex;align-items:center;gap:12px}
.stat-ring{flex:0 0 44px;width:44px;line-height:0}
.stat-ring svg{display:block;width:100%;height:auto}
.stat-ring .track{stroke:var(--border)}
.stat .n{font-size:34px;font-weight:750;line-height:1.1;font-variant-numeric:tabular-nums}
.stat .l{font-size:13.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-soft);
  margin-top:9px;text-align:left}

/* Donut der Auswertung. Zwei ineinanderliegende Ringe mit EINEM Zweck je Ring:
     innen  - wie die Prüfpunkte stehen (geprüft / mit Fehlermeldung / ungeprüft)
     aussen - wie viel vom Kontingent des Tarifs der Katalog braucht
   Die Segmente entstehen als Kreise mit stroke-dasharray, nicht als Pfade: Damit
   bleibt jedes Segment ein einzelnes Element mit eigener Farbe und eigenem <title>,
   ohne dass irgendwo Bogenmathematik im Skript steht.
   Die Zahlen im Loch stehen als <text> im SVG und skalieren deshalb mit - eine
   absolut positionierte HTML-Ebene darüber wäre bei jedem Fensterwechsel verrutscht. */
.donut-wrap{display:flex;flex-wrap:wrap;gap:24px;align-items:center}
.donut-fig{flex:0 0 230px;max-width:230px}
.donut-fig svg{display:block;width:100%;height:auto}
.donut-fig .seg{transition:opacity .12s}
.donut-fig .track{stroke:var(--border)}
.donut-hole-n{fill:var(--ink);font-size:34px;font-weight:750;font-variant-numeric:tabular-nums}
.donut-hole-l{fill:var(--ink-soft);font-size:12px;letter-spacing:.05em;text-transform:uppercase}
.donut-side{flex:1 1 260px;min-width:240px}
.donut-legend{list-style:none;margin:0;padding:0}
.donut-legend li{display:flex;align-items:center;gap:10px;padding:6px 0;border-bottom:1px solid var(--border)}
.donut-legend li:last-child{border-bottom:0}
.donut-legend .dot{flex:0 0 12px;width:12px;height:12px;border-radius:50%}
.donut-legend .k{flex:1 1 auto;font-size:15px}
.donut-legend .v{font-weight:750;font-variant-numeric:tabular-nums}
.donut-legend .p{color:var(--ink-soft);font-variant-numeric:tabular-nums;min-width:52px;text-align:right}
.donut-note{margin-top:12px;font-size:14px;color:var(--ink-soft)}
.donut-note b{color:var(--ink);font-variant-numeric:tabular-nums}
.donut-note.over b{color:var(--crit-ink)}
/* Auf dem Telefon steht die Legende unter dem Ring, und der Ring darf nicht die halbe
   Bildschirmhöhe fressen. */
@media (max-width:560px){
  .donut-wrap{gap:16px}
  .donut-fig{flex:1 1 100%;max-width:200px;margin:0 auto}
  .donut-side{flex:1 1 100%;min-width:0}
}

.fail-item{border-left:4px solid var(--crit-ink);background:var(--crit-bg);border-radius:0 8px 8px 0;
  padding:12px 15px;margin-bottom:12px}
.fail-item .q{font-weight:650;font-size:17px;color:var(--crit-ink);margin-bottom:5px}
.fail-item .src{font-size:13.5px;color:var(--ink-soft);margin-bottom:5px}
.fail-item .cmt{font-family:inherit;font-size:16.5px;white-space:pre-wrap;
  line-height:1.5;border-top:1px dashed var(--border);padding-top:6px;margin-top:5px}
.na-item{border-left-color:var(--ink-soft);background:transparent;border:1px solid var(--border);border-left-width:3px}
.na-item .q{color:var(--ink-soft)}
.ok-item{border-left-color:var(--done);background:transparent;border:1px solid var(--border);border-left-width:3px}
.ok-item .q{color:var(--done)}

/* Bilder eines Prüfpunkts. Die Kacheln sind bewusst klein: Sie sollen zeigen, DASS es
   einen Beleg gibt - angesehen wird er groß, per Klick. */
.fail-item .shots,.sheet-item .shots{display:flex;flex-wrap:wrap;gap:8px;margin-top:9px}
.fail-item .shot,.sheet-item .shot{width:82px;height:82px;border-radius:8px;overflow:hidden;border:1px solid var(--border);
                 background:var(--bg);display:flex;align-items:center;justify-content:center;
                 font-size:12px;color:var(--ink-soft)}
.fail-item .shot img,.sheet-item .shot img{width:100%;height:100%;object-fit:cover;display:block;cursor:zoom-in}
.fail-item .shot.gone,.sheet-item .shot.gone{border-style:dashed}

/* --- Testbogen eines Testers -------------------------------------------
   Liest sich als Liste, nicht als Tabelle: Man geht sie mit dem Tester der Reihe nach
   durch. Der Zustand steht deshalb VOR dem Prüfpunkt und nicht in einer Spalte am
   rechten Rand, wo das Auge ihn suchen müsste. */
.sheet-head{display:flex;flex-wrap:wrap;gap:6px 22px;padding:12px 15px;margin-bottom:16px;
  background:var(--bg);border:1px solid var(--border);border-radius:9px}
.sheet-head div{font-size:15px}
/* Bezeichnung und Wert stehen in einer Zeile. Der Doppelpunkt steht im Markup und
   NICHT als ::after im Stylesheet: Erzeugter Inhalt fehlt beim Kopieren der Seite und
   wird von manchen Sprachausgaben uebergangen - die Zeile las sich dann als
   "NameMichaela Kuegler". In den Sprachdateien hat er trotzdem nichts zu suchen, er
   ist in allen drei Sprachen derselbe (siehe renderSheet).
   Der Abstand zum Wert kommt weiterhin von hier: ein Leerzeichen im Markup wuerde beim
   Umbruch am Zeilenende verschwinden. */
.sheet-head .k{font-size:12.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-soft);
  margin-right:7px}

/* Dieselben Bereichstrenner wie in der Matrix (tr.sec-sep): schmale Grossbuchstaben in
   der Akzentfarbe auf abgesetzter Flaeche. Der Tester sieht in beiden Ansichten
   dieselbe Einteilung - sie soll auch gleich aussehen. */
.sheet-sec{margin:22px 0 8px;background:var(--surface);border-top:2px solid var(--accent);
  padding:11px 14px;font-family:ui-monospace,"SF Mono",Menlo,monospace;font-size:14px;
  letter-spacing:.06em;text-transform:uppercase;color:var(--accent)}
.sheet-sec:first-child{margin-top:4px}
.sheet-sec .cnt{color:var(--ink-soft);text-transform:none;letter-spacing:0;margin-left:8px}
.sheet-grp{margin:14px 0 6px;font-size:13.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-soft)}
.sheet-item{display:flex;gap:11px;align-items:flex-start;padding:9px 12px;margin-bottom:7px;
  border:1px solid var(--border);border-radius:8px}
.sheet-item>.pill{flex:0 0 auto;margin-top:2px}
.sheet-item .body{flex:1 1 auto;min-width:0}
.sheet-item .q{font-size:16.5px;line-height:1.45}
.sheet-item .cmt{font-size:16px;white-space:pre-wrap;line-height:1.5;margin-top:6px;
  border-left:3px solid var(--border);padding-left:10px;color:var(--ink-soft)}
/* Ein Fehler soll sich beim Blättern vom Rest abheben - er ist der Grund des Gesprächs. */
.sheet-item.is-fail{border-color:var(--crit-ink);background:var(--crit-bg)}
.sheet-item.is-fail .q{font-weight:650;color:var(--crit-ink)}
.sheet-item.is-fail .cmt{border-left-color:var(--crit-ink);color:var(--ink)}
.sheet-item.is-open{border-style:dashed}
.sheet-item.is-open .q{color:var(--ink-soft)}
.sheet-item .own{font-size:12.5px;color:var(--ink-soft);margin-left:6px}

pre.json{background:var(--bg);border:1px solid var(--border);border-radius:9px;padding:14px;
  font-family:ui-monospace,Menlo,monospace;font-size:14px;line-height:1.55;
  max-height:60vh;overflow:auto;white-space:pre;margin:0}
/* Klebt unter der festen Leiste, nicht dahinter. */
.toolbar-sticky{position:sticky;top:var(--navh);z-index:20;background:color-mix(in srgb,var(--bg) 92%,transparent);
  backdrop-filter:blur(8px);padding:10px 0;margin:-10px 0 10px;border-bottom:1px solid var(--border)}
.flash{position:fixed;left:50%;bottom:22px;transform:translateX(-50%) translateY(20px);
  background:var(--ink);color:var(--bg);padding:13px 22px;border-radius:999px;
  font-weight:600;opacity:0;pointer-events:none;transition:opacity .2s,transform .2s;z-index:99;font-size:16px;
  max-width:80vw;text-align:center}
.flash.on{opacity:1;transform:translateX(-50%) translateY(0)}
.flash.bad{background:var(--crit-ink);color:#fff}
code{font-family:ui-monospace,Menlo,monospace;font-size:.92em;background:var(--accent-soft);padding:2px 6px;border-radius:4px}
details>summary{cursor:pointer;font-weight:650;font-size:16px;padding:10px 0}
.lock{max-width:560px;margin:90px auto;padding:34px;background:var(--surface);border:1px solid var(--border);
  border-radius:14px;box-shadow:var(--shadow)}
.lock h1{font-size:25px;margin:0 0 8px;display:flex;align-items:center;flex-wrap:wrap}

/* --- Dialogfenster -----------------------------------------------------
   Ersetzt alert/confirm/prompt des Browsers: Die halten das ganze Fenster an, sehen
   auf jedem System anders aus und lassen sich nicht beschriften. Es benutzt dieselbe
   .sheet-Flaeche wie das Verschieben-Fenster darueber - es soll in dieser Oberflaeche
   nur EINE Art von Ueberlagerung geben. Bedienung siehe ask() im Skript. */
#ask .card{max-width:460px}
#ask h2{margin-bottom:8px}
.ask-text{color:var(--ink-soft);font-size:16px;line-height:1.55;margin:0;white-space:pre-line}
#ask .fld{margin-top:16px}
/* label.fld setzt display:flex - ohne das hier bliebe das Feld trotz hidden stehen. */
#ask .fld[hidden]{display:none}
/* Loeschen bekommt einen roten Knopf statt eines blauen - der Unterschied zwischen
   "speichern" und "unwiderruflich weg" darf nicht nur im Wort stecken. */
.btn.primary.danger{background:var(--crit-ink);color:#fff;border-color:transparent}
.btn.primary.danger:hover{filter:brightness(1.08);color:#fff}
@media (max-width:480px){
  #ask .bar{flex-direction:column-reverse;align-items:stretch}
  #ask .bar .btn{width:100%}
  #ask .bar .grow{display:none}
}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

/* --- Schmale Schirme ----------------------------------------------------
   Auf dem Telefon passt keine Tabelle mit acht bis zehn Spalten nebeneinander.
   Sie seitwaerts scrollen zu lassen ist die schlechteste Loesung: Der Name steht
   dann links, die Zahl dazu rechts ausserhalb des Bildes, und beim Zurueckscrollen
   ist die Zeile verloren. Stattdessen wird jede Zeile zu einer Karte: Sichtbar
   bleibt die erste Spalte - Tester, Bewerber, Pruefpunkt -, alles Weitere klappt
   per Knopf auf und traegt dann die Beschriftung aus dem Tabellenkopf vor dem Wert.
   Die Klasse "stack" bekommt die Tabelle im HTML, die Beschriftungen und der
   Aufklapp-Knopf entstehen nach jedem Aufbau in stackify().

   Der Knopf steht bewusst als eigenes Element in der Ecke und nicht als Klick auf
   die ganze Zeile: Ein Klick in die Zeile oeffnet in der Tester- und der
   Ergebnistabelle bereits den Testbogen, und beides an derselben Stelle waere
   nicht mehr vorhersehbar. */
.rowtog{display:none}
@media (max-width:760px){
  /* Der Rahmen um die Tabelle darf nicht mehr scrollen, sonst bliebe der Balken
     trotz passender Karten stehen. Gilt fuer die Wrapper mit overflow:auto. */
  .card>div[style*="overflow"]{overflow:visible !important}
  #matrixBox{max-height:none !important}

  table.stack,table.stack tbody,table.stack tr,table.stack td{display:block;width:auto}
  table.stack thead{display:none}
  table.stack tr{position:relative;border:1px solid var(--border);border-radius:10px;
    background:var(--bg);margin-bottom:10px;padding:4px 0}
  table.stack tbody tr:hover{background:var(--bg)}
  table.stack td{border-bottom:0;padding:7px 14px;text-align:left}
  /* nowrap gehoert zur Zahlenspalte einer Tabelle - in der Karte steht der Wert
     unter seiner Beschriftung und darf umbrechen. */
  table.stack td.num{text-align:left;white-space:normal}
  table.stack td:first-child{padding-right:52px;font-size:16.5px}
  /* Die Beschriftung aus dem Tabellenkopf steht VOR dem Wert in derselben Zeile -
     ohne sie waere eine aufgeklappte Karte nur eine Reihe zusammenhangloser Zahlen.
     Pro Beschriftung eine Zeile: Die Zelle ist ein Block, die Beschriftung ein
     inline-block mit fester Mindestbreite. Damit stehen die Werte aller Zeilen einer
     Karte untereinander auf derselben Kante, und "Status", "Bereiche" oder "Zuletzt
     gespeichert" haengen nicht mehr allein ueber ihrem Wert.

     Gemacht ist es als haengender Einzug: Die Zelle bekommt links Platz in Breite der
     Beschriftung, und der negative text-indent holt NUR die erste Zeile - die mit der
     Beschriftung - wieder an den Rand zurueck. Alles Weitere in der Zelle (Umbruch,
     zweite Zeile nach einem <br>) bleibt damit unter dem Wert stehen und nicht unter
     der Beschriftung. */
  table.stack td[data-label]{padding-left:126px;text-indent:-112px}
  table.stack td[data-label]::before{content:attr(data-label);display:inline-block;
    width:112px;text-indent:0;font-size:11.5px;text-transform:uppercase;
    letter-spacing:.05em;color:var(--ink-soft);vertical-align:baseline}
  /* Der Einzug gehoert der Zelle, nicht ihrem Inhalt. */
  table.stack td[data-label]>*{text-indent:0}
  /* .btn.icon ist ein Raster und stuende sonst in einer eigenen Zeile. */
  table.stack td[data-label] .btn.icon{display:inline-grid;vertical-align:middle}
  /* In der Karte steht der Wert ohnehin schon unter seiner Beschriftung - ein
     zusaetzlicher Umbruch INNERHALB der Zelle (Zustand / Herkunft beim Tester)
     zerreisst zwei Kennzeichen, die zusammen EINE Angabe sind. Sie stehen deshalb
     hier nebeneinander; das Leerzeichen dahinter steht im Markup. */
  table.stack td br.brk{display:none}
  table.stack tr[data-more]>td:not(:first-child){display:none}
  table.stack tr[data-more].open>td{display:block}
  /* Bereichstrenner der Matrix bleibt Trenner und wird keine Karte. */
  table.stack tr.sec-sep{border:0;background:transparent;padding:0;margin:16px 0 8px}
  table.stack tr.sec-sep td{background:var(--surface);position:static}
  .rowtog{display:flex;align-items:center;justify-content:center;position:absolute;
    top:5px;right:6px;width:38px;height:38px;padding:0;font:inherit;font-size:15px;
    line-height:1;color:var(--ink-soft);background:var(--surface);
    border:1px solid var(--border);border-radius:9px;cursor:pointer}
  tr.open .rowtog{transform:rotate(180deg);color:var(--accent);border-color:var(--accent)}

  /* Reiter "Fragen": Griff, Feld und die vier Tasten bleiben in EINER Zeile, nur die
     drei Kennzeichen ruecken darunter. Vorher standen die Tasten in einer eigenen
     Zeile unter dem Punkt - man sah dann eine Reihe Pfeile, ohne zu erkennen, zu
     welchem Punkt sie gehoeren. Die Tasten sind dafuer etwas kleiner. */
  .row{flex-wrap:wrap;gap:5px}
  .row .grip{order:0;align-self:center;padding:8px 4px}
  .row .txt{order:1;flex:1 1 90px;min-width:0}
  .row .act{order:2;flex:0 0 auto;padding-top:0;gap:1px}
  .row .act .btn.icon{width:32px;height:32px;font-size:14px}
  .row .txt input{padding:9px 8px}
  .row .bdg{order:3;flex:1 1 100%;flex-wrap:wrap;padding-top:0}
  .grp-head{flex-wrap:wrap}
  .grp-head input{flex:1 1 100%}
  .card{padding:16px 15px}
  .card h2{flex-wrap:wrap}
  .card h2 .sp{margin-left:0}
  /* Der Bogen eines Testers: Zustand ueber die Frage statt daneben. */
  .sheet-item{flex-wrap:wrap}
  .sheet-item .body{flex:1 1 100%}
  pre.json{white-space:pre-wrap;word-break:break-word}

  /* Reiter "Auswertung": Die beiden Filterpaare stehen nebeneinander nur, solange
     Platz dafuer ist. Auf dem Telefon bekommt jedes Feld eine eigene Zeile in voller
     Breite - das ist auch die einzige Groesse, in der ein langer Bereichsname noch
     lesbar bleibt. Ohne !important bliebe das width:auto aus dem style-Attribut. */
  #matrixFilter,#matrixSection,#sheetFilter,#sheetSection{width:100% !important}
  /* Die Projektauswahl steht ueber allen Reitern und darf ihre 300px hier nicht
     erzwingen - unter dem Rand der Seite bleiben davon weniger uebrig. */
  .projbar select{min-width:0}

  /* Angemerkter Text kommt vom Tester und kann eine Adresse oder eine Kennung ohne
     Leerzeichen enthalten. Ein solches Wort bricht von sich aus nicht um und schiebt
     die Seite auf. */
  .fail-item,.fail-item *,.sheet-item,.sheet-item *{overflow-wrap:anywhere}

  /* Derselbe Grund in der Matrix und in den Tabellenkarten: Ein Pruefpunkt, ein
     Bereichstitel oder ein Testername kann als ein einziges langes Wort ohne
     Leerzeichen dastehen (Adresse, Kennung, Dateiname). Eine Zelle ohne
     Umbruchpunkt waechst dann ueber die Kartenbreite hinaus und schiebt die ganze
     Seite auf - genau das Bild, das die Karten vermeiden sollen. "anywhere" bricht
     nur dann mitten im Wort, wenn es sonst nicht passt, und zaehlt anders als
     break-word auch bei der Mindestbreite mit. Das Sternchen ist noetig, weil der
     Text in der ersten Spalte in eigenen Elementen steckt (Gruppe, Kennzeichen). */
  table.stack td,table.stack td *,.sheet-sec,.sheet-grp{overflow-wrap:anywhere}
}

/* --- Druck --------------------------------------------------------------
   Gedruckt wird ausschliesslich der Testbogen, und auch nur dann, wenn er offen ist.
   Alles andere dieser Seite - Leiste, Reiter, Matrix, Fehlerliste, Rohdaten - ist
   Bedienung und auf Papier wertlos. Deshalb wird nicht einzeln ausgeblendet, sondern
   der Bogen aus dem Fluss herausgehoben: Was nicht in ihm steht, verschwindet. */
@media print{
  @page{margin:14mm}
  /* Auf Papier immer hell. Ohne das druckte ein dunkel eingestellter Bildschirm
     helle Schrift auf weisses Blatt - lesbar ist daran nichts. Der zweite
     Selektor muss sein: Er sticht das :root[data-theme="dark"] von oben. */
  :root,:root[data-theme]{
    --bg:#fff; --surface:#fff; --ink:#111; --ink-soft:#555;
    --accent:#0a4bb3; --accent-soft:#fff; --border:#bbb;
    --done:#0b7a45; --done-soft:#fff; --crit-bg:#fff; --crit-ink:#a3231b;
    --tier-bg:#fff; --tier-ink:#6b4a00; --plat-bg:#fff; --plat-ink:#0a4bb3;
    --shadow:none;
  }
  body{background:#fff}
  body>*{display:none !important}
  body>#app{display:block !important}
  #app>*{display:none !important}
  #app>#projectPanels{display:block !important}
  #projectPanels>.panel{display:none !important}
  #projectPanels>#p-auswertung{display:block !important;padding:0}
  #p-auswertung>*{display:none !important}
  #p-auswertung>#sheetCard{display:block !important;border:0;box-shadow:none;padding:0;margin:0}
  /* Die Bedienelemente des Bogens selbst gehen ebenfalls nicht mit aufs Papier. Die
     eingestellte Ansicht geht trotzdem mit: renderSheet() schreibt sie als Zeile
     "Ansicht" in den Kopf, damit auf dem Blatt steht, was es zeigt. */
  #sheetCard h2 .sp,#sheetBar{display:none !important}
  #sheetCard h2{border:0;padding:0;margin:0 0 4px}
  .sheet-head{background:transparent;border:1px solid #999}
  .stat{border:1px solid #999;box-shadow:none}
  /* Ein Prüfpunkt samt Kommentar und Bildern soll nicht über den Seitenrand
     auseinandergerissen werden - sonst steht die Anmerkung ohne ihre Frage da. */
  .sheet-item,.sheet-sec{break-inside:avoid}
  /* Die abgesetzte Flaeche des Bereichstrenners kostet auf Papier nur Toner und traegt
     nichts bei - die Linie darueber reicht, um den Bereich abzugrenzen. */
  .sheet-sec{break-after:avoid;background:transparent;padding-left:0;padding-right:0}
  .sheet-item .shot{width:64px;height:64px}
  .lightbox{display:none !important}
}
