/* labor.sh: Oberfläche der Aufgabenplattform
   Farben und Schriften nach Styleguide Fassung 1.0.
   Der Akzent liegt ausschliesslich auf Cursor und Punkt, nie auf Flächen. */

:root {
  --labor-ink: #1E2A22;
  --labor-accent: #D2652F;
  --labor-accent-dark-bg: #EE8A4E;
  --labor-bg: #F5F6F2;
  --labor-line: #DDE2DD;
  --font-display: Archivo, Helvetica, Arial, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --surface: #FFFFFF;
  --text: #1E2A22;
  --muted: #5C6A61;
  --accent: #D2652F;
  --danger: #8E2F1F;
  --danger-hover: #7A2718;
  --ok: #2F6B4F;
  --shade: #EDEFE9;
  --field: #FFFFFF;
  --mark-bg: #1E2A22;
  --mark-ring: transparent;
}

@media (prefers-color-scheme: dark) {
  :root {
    --labor-bg: #171F1A;
    --labor-line: #33413A;
    --surface: #1E2A22;
    --text: #F5F6F2;
    --muted: #9CAA9F;
    --accent: #EE8A4E;
    --danger: #A83A26;
    --danger-hover: #C04730;
    --ok: #79B698;
    --shade: #232F27;
    --field: #141C17;
    --mark-bg: transparent;
    --mark-ring: #FFFFFF;
  }
}

* { box-sizing: border-box; }

/* hidden muss auch gegen eigene display-Regeln gewinnen. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--labor-bg);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }

/* Die Seite wächst mit dem Fenster, statt in einer 1040er-Spalte in der
   Mitte zu kleben: Auf einem grossen Bildschirm sollen Listen und Tabellen
   den Platz auch nutzen. Nach oben bleibt eine Grenze, sonst laufen Zeilen
   auf einem 4K-Schirm quer über den Tisch. Der Seitenrand wächst mit. */
.wrap {
  width: 100%;
  max-width: 1680px;
  margin: 0 auto;
  padding: 0 clamp(18px, 2.6vw, 44px) 96px;
}
/* Fliesstext bleibt trotzdem lesbar: Eine Zeile über die volle Breite
   verliert man beim Zurückspringen. Betrifft nur Prosa, nicht Listen. */
.wrap p.lede, .wrap p.hint, .wrap .prosa { max-width: 78ch; }
/* „Schmal" begrenzt den Inhalt, nicht die Seite: Die Spalte steht links,
   bündig unter der Marke, sonst rückt der Titel gegenüber dem Kopf ein. */
.wrap.narrow:not(.band) > * { max-width: 720px; }
/* Kopf- und Fusszeile stehen in einem eigenen Band, damit die Navigation
   auf jeder Seite gleich breit ist und nicht umbricht. */
.wrap.band { padding-bottom: 0; }
.wrap.band + .wrap { padding-top: 0; }
/* Der Arbeitsplatz nimmt die ganze Breite: Jeder Pixel weniger ist Auflösung,
   die in der Sitzung fehlt. */
.wrap.wide { max-width: none; padding-left: 20px; padding-right: 20px; }
/* Auf dem Arbeitsplatz zählt jede Zeile: Titel dichter, Fläche grösser. */
.wrap.wide .title-block { padding: 20px 0 4px; }
.wrap.wide h1 { font-size: clamp(24px, 2.4vw, 32px); }

/* ---------- Marke und Navigation ---------- */

.labor-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.094em;
  width: 1em;
  height: 1em;
  font-size: 28px;
  flex: none;
  background: var(--mark-bg);
  box-shadow: inset 0 0 0 1.5px var(--mark-ring);
}
.labor-mark::before {
  content: "$";
  font-family: var(--font-mono);
  font-size: 0.469em;
  font-weight: 500;
  line-height: 1;
  color: #fff;
}
.labor-mark::after {
  content: "";
  width: 0.156em;
  height: 0.344em;
  background: var(--accent);
}

.labor-wordmark { font-weight: 600; letter-spacing: -0.03em; font-size: 19px; }
.labor-wordmark .dot { color: var(--accent); }

/* Eine Zeile, immer. Marke links, Konto und Abmelden rechts, dazwischen
   gibt das Menü nach: Wird es eng, schiebt es sich seitlich, statt die
   Abmelden-Schaltfläche in eine zweite Zeile zu drängen. Umbrechen sah bei
   sechs Punkten und einem längeren Namen schief aus. */
.masthead {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: nowrap;
  padding: 22px 0 12px;
  border-bottom: 1px solid var(--labor-line);
}
.masthead .brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  text-decoration: none;
  flex: none;
}
.masthead nav {
  display: flex;
  gap: 14px;
  flex-wrap: nowrap;
  margin-left: 4px;
  /* Der einzige Teil, der schrumpfen darf. */
  flex: 0 1 auto;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.masthead nav::-webkit-scrollbar { display: none; }
.masthead nav a { flex: none; white-space: nowrap; }
/* Abmelden bleibt immer stehen; der Name gibt vor ihm nach und wird
   notfalls mit Auslassungspunkten gekürzt, statt die Zeile zu sprengen. */
.masthead > form { flex: none; }
.masthead > .meta, .masthead > a.meta {
  /* Gibt deutlich schneller nach als das Menü: Ein gekürzter Name stört
     weniger als ein halb abgeschnittener Menüpunkt. */
  flex: 0 8 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.masthead nav a {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
}
.masthead nav a:hover { color: var(--text); }
.masthead nav a.on { color: var(--text); border-bottom-color: var(--accent); }
/* Nimmt den freien Platz, gibt ihn aber als Erster wieder her. */
.masthead .spacer { flex: 1 1 0; min-width: 0; }
.masthead form { margin: 0; }

/* Die Hülle um Menü, Name und Abmelden. Auf breiten Fenstern löst sie sich
   auf, dann stehen ihre Kinder direkt in der Kopfzeile wie zuvor. Schmal
   wird daraus die Schublade (siehe Media Query weiter unten). */
.menue { display: contents; }

/* Der Knopf für die Schublade: drei Striche, im offenen Zustand ein Kreuz. */
.menue-knopf {
  display: none;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 34px;
  flex: none;
  padding: 0;
  background: none;
  border: 1px solid var(--labor-line);
  color: inherit;
  cursor: pointer;
}
.menue-knopf .striche,
.menue-knopf .striche::before,
.menue-knopf .striche::after {
  display: block;
  width: 18px;
  height: 1.5px;
  background: currentColor;
  transition: transform 0.15s ease, opacity 0.15s ease;
}
.menue-knopf .striche { position: relative; }
.menue-knopf .striche::before,
.menue-knopf .striche::after {
  content: "";
  position: absolute;
  left: 0;
}
.menue-knopf .striche::before { top: -6px; }
.menue-knopf .striche::after { top: 6px; }
.menue-knopf[aria-expanded="true"] .striche { background: transparent; }
.menue-knopf[aria-expanded="true"] .striche::before { transform: translateY(6px) rotate(45deg); }
.menue-knopf[aria-expanded="true"] .striche::after { transform: translateY(-6px) rotate(-45deg); }
.menue-knopf:hover { border-color: var(--accent); color: var(--accent); }

.meta {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.colophon {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin-top: 56px;
  padding-top: 12px;
  border-top: 1px solid var(--labor-line);
}

/* ---------- Titel ---------- */

.title-block { padding: 40px 0 6px; }
h1 {
  font-weight: 600;
  letter-spacing: -0.035em;
  font-size: clamp(30px, 5vw, 42px);
  line-height: 1.06;
  margin: 0;
  text-wrap: balance;
}
h1 .sub { display: block; color: var(--muted); }
h2 { font-weight: 600; letter-spacing: -0.025em; font-size: 21px; margin: 0 0 4px; }
h3 { font-weight: 600; letter-spacing: -0.02em; font-size: 16px; margin: 0 0 4px; }
p { margin: 0 0 12px; }
.lede { color: var(--muted); max-width: 62ch; margin-top: 12px; }

.label {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 40px 0 12px;
}
.label:first-child { margin-top: 24px; }

code {
  font-family: var(--font-mono);
  font-size: 0.88em;
  background: var(--shade);
  padding: 1px 5px;
}
pre {
  font-family: var(--font-mono);
  font-size: 13px;
  background: var(--shade);
  border: 1px solid var(--labor-line);
  padding: 12px 14px;
  overflow-x: auto;
}
pre code { background: none; padding: 0; }

/* ---------- Meldungen ---------- */

.flashes { list-style: none; margin: 20px 0 0; padding: 0; }
.flashes li {
  border-left: 2px solid var(--labor-line);
  padding: 2px 0 2px 14px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--muted);
}
.flashes li + li { margin-top: 6px; }
.flashes .success { border-left-color: var(--ok); }
.flashes .danger { border-left-color: var(--danger); color: var(--text); }

/* ---------- Flächen ---------- */

.panel {
  border: 1px solid var(--labor-line);
  background: var(--surface);
  padding: 20px;
}
.panel + .panel { margin-top: -1px; }

.list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--labor-line); background: var(--surface); }
.list > li + li { border-top: 1px solid var(--labor-line); }
.row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px 16px;
  padding: 14px 18px;
  text-decoration: none;
  color: inherit;
  /* Passt der Knopf nicht mehr neben den Titel, rutscht er darunter:
     besser als eine Zeile, die aus dem Fenster läuft. */
  flex-wrap: wrap;
}
.row > * { min-width: 0; }
a.row:hover { background: var(--shade); }
/* Zeile mit eigenen Schaltflächen: der Titel bleibt der Link. */
.row-main { flex: 1; min-width: 0; text-decoration: none; color: inherit; }
.row-main:hover .name { color: var(--accent); }
.row .name { font-weight: 600; }
.row .sub { color: var(--muted); font-size: 14px; }
.empty { padding: 24px 18px; color: var(--muted); font-family: var(--font-mono); font-size: 13px; }

/* ---------- Schaltflächen ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--labor-ink);
  background: var(--labor-ink);
  color: #F5F6F2;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  padding: 10px 16px;
  border-radius: 0;
  cursor: pointer;
  text-decoration: none;
  transition: background 120ms ease, border-color 120ms ease;
}
.btn:hover { background: #2C3D33; border-color: #2C3D33; }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn[disabled] { opacity: 0.45; cursor: not-allowed; }
@media (prefers-color-scheme: dark) {
  .btn { background: #F5F6F2; border-color: #F5F6F2; color: #1E2A22; }
  .btn:hover { background: #FFFFFF; border-color: #FFFFFF; }
}

.btn-ghost { background: transparent; color: var(--text); border-color: var(--labor-line); }
.btn-ghost:hover { background: var(--shade); border-color: var(--muted); }
@media (prefers-color-scheme: dark) {
  .btn-ghost { background: transparent; color: var(--text); border-color: var(--labor-line); }
  .btn-ghost:hover { background: var(--shade); border-color: var(--muted); }
}

.btn-danger { background: var(--danger); border-color: var(--danger); color: #FFFFFF; }
.btn-danger:hover { background: var(--danger-hover); border-color: var(--danger-hover); }
@media (prefers-color-scheme: dark) {
  .btn-danger { background: var(--danger); border-color: var(--danger); color: #FFFFFF; }
}

.btn-sm { padding: 7px 12px; font-size: 11px; }
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.btn-row form { margin: 0; }

/* ---------- Formulare ---------- */

form { margin: 0; }
.field { display: block; margin-bottom: 14px; }
.field > span.k {
  display: block;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 5px;
}
input[type="text"], input[type="password"], input[type="number"],
input[type="file"], select, textarea {
  width: 100%;
  font-family: var(--font-display);
  font-size: 15px;
  color: var(--text);
  background: var(--field);
  border: 1px solid var(--labor-line);
  border-radius: 0;
  padding: 9px 11px;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--text);
}
textarea { font-family: var(--font-mono); font-size: 13.5px; line-height: 1.5; resize: vertical; }

/* Dateiauswahl: Der Knopf gehört dem Browser, so weit wie möglich
   angeglichen. */
input[type="file"] {
  padding: 7px 9px;
  font-size: 13.5px;
  cursor: pointer;
}
input[type="file"]::file-selector-button {
  appearance: none;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text);
  background: transparent;
  border: 1px solid var(--labor-line);
  border-radius: 0;
  padding: 7px 14px;
  margin: 0 12px 0 0;
  cursor: pointer;
}
input[type="file"]::file-selector-button:hover {
  border-color: var(--text);
  background: var(--shade);
}
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 16px; }
.inline-check { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; color: var(--muted); }
/* Mehrere Schalter in einem Feld untereinander. */
.field .inline-check { display: flex; min-height: 32px; }
.hint { color: var(--muted); font-size: 13.5px; margin-top: -6px; }
.hint.warn {
  color: var(--text);
  border-left: 2px solid var(--accent);
  padding: 8px 0 8px 12px;
  margin-top: 14px;
}
.hint.warn code, .hint.warn kbd {
  font-family: var(--font-mono);
  font-size: 12.5px;
  background: var(--shade);
  padding: 1px 5px;
}

/* ---------- Kennzeichen ---------- */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 3px 9px;
  border: 1px solid var(--labor-line);
  color: var(--muted);
  white-space: nowrap;
}
.pill.open { }
/* Marke und Satz nebeneinander, ohne dass die Marke im Text schwimmt. */
.stand-zeile {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 0 0 14px;
}
.stand-zeile .pill { flex: none; margin-top: 3px; }
.pill.submitted { border-color: var(--accent); color: var(--accent); }
.pill.accepted { border-color: var(--ok); color: var(--ok); }
.pill.returned { border-color: var(--danger); color: var(--danger); }
.pill.on { border-color: var(--ok); color: var(--ok); }
.pill.off { }

/* ---------- Aufteilung ---------- */

.split { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 32px; align-items: start; }
.side { position: sticky; top: 20px; display: grid; gap: 18px; }

/* Arbeitsplatz: Konsole links und gross, Aufgabe rechts als Spalte */
.workbench {
  /* Breite der Aufgabenspalte: per Ziehgriff verstellbar, in Grenzen. */
  --spalte: 400px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 14px var(--spalte);
  gap: 0;
  align-items: start;
  margin-top: 24px;
}
.worksheet {
  position: sticky;
  top: 16px;
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  padding: 0 4px 0 12px;
}
.worksheet .label:first-child { margin-top: 0; }

/* Griff zwischen Konsole und Aufgabe. */
.griff {
  position: sticky;
  top: 16px;
  align-self: stretch;
  min-height: 120px;
  height: calc(100vh - 32px);
  border: 0;
  padding: 0;
  margin: 0;
  width: 100%;
  z-index: 2;
  background: transparent;
  cursor: col-resize;
  display: flex;
  align-items: center;
  justify-content: center;
  touch-action: none;
}
.griff::before {
  content: "";
  width: 1px;
  height: 100%;
  background: var(--labor-line);
  transition: background 120ms ease, width 120ms ease;
}
.griff:hover::before,
.griff.zieht::before { width: 3px; background: var(--accent); }
.griff:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Bildlaufleisten im Stil des Hauses. */
.worksheet,
.console-tabs,
.joblog,
.scroll,
.wahl {
  scrollbar-width: thin;
  scrollbar-color: var(--labor-line) transparent;
}
.worksheet::-webkit-scrollbar,
.console-tabs::-webkit-scrollbar,
.joblog::-webkit-scrollbar,
.scroll::-webkit-scrollbar,
.wahl::-webkit-scrollbar { width: 10px; height: 10px; }
.worksheet::-webkit-scrollbar-track,
.console-tabs::-webkit-scrollbar-track,
.joblog::-webkit-scrollbar-track,
.scroll::-webkit-scrollbar-track,
.wahl::-webkit-scrollbar-track { background: transparent; }
.worksheet::-webkit-scrollbar-thumb,
.console-tabs::-webkit-scrollbar-thumb,
.joblog::-webkit-scrollbar-thumb,
.scroll::-webkit-scrollbar-thumb,
.wahl::-webkit-scrollbar-thumb {
  background: var(--labor-line);
  border: 3px solid transparent;
  background-clip: content-box;
}
.worksheet:hover::-webkit-scrollbar-thumb,
.scroll:hover::-webkit-scrollbar-thumb { background: var(--muted); background-clip: content-box; }

/* ---------- Konsole ---------- */

.console-pane {
  border: 1px solid var(--labor-line);
  background: var(--surface);
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.console-tabs {
  display: flex;
  overflow-x: auto;
  border-bottom: 1px solid var(--labor-line);
}
.console-tab {
  appearance: none;
  border: 0;
  border-right: 1px solid var(--labor-line);
  background: transparent;
  color: var(--muted);
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 11px 16px;
  cursor: pointer;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.console-tab:hover { color: var(--text); background: var(--shade); }
.console-tab.on {
  color: var(--text);
  background: var(--shade);
  box-shadow: inset 0 -2px 0 var(--accent);
}
.console-tab .led {
  width: 7px;
  height: 7px;
  background: var(--muted);
  flex: none;
}
.console-tab .led.on { background: var(--ok); }

/* Die Bühne ist der Bezug für alles, was über der Konsole liegt, etwa die
   Marke des Präsentiermodus. */
.console-stage { background: #0B0F0C; min-height: 460px; display: grid; position: relative; }
/* Sobald eine Sitzung darin liegt, gibt die Bühne ihre Mindesthöhe auf und
   setzt die Fläche mittig: Die Fläche misst dann genau das Bild, und
   darunter soll kein schwarzer Streifen stehen bleiben. Passt ein
   Bildschirm im ganz anderen Seitenverhältnis nicht in die Breite, bleibt
   links und rechts der dunkle Grund, gleich viel auf beiden Seiten. Die
   Mindesthöhe gilt weiter für den leeren Zustand mit dem Verbinden-Knopf. */
.console-stage:has(> .console-live:not([hidden])) {
  min-height: 0;
  justify-items: center;
  align-items: center;
}
.console-stage iframe {
  width: 100%;
  height: min(82vh, 1400px);
  min-height: 460px;
  border: 0;
  display: block;
  background: #0B0F0C;
}
/* Fläche, in die guacamole-common-js die Sitzung zeichnet. */
/* Eine Zelle, so gross wie die Fläche: Das Bild liegt darin in der Mitte,
   und was die Auflösung nicht hergibt, bleibt als gleich breiter Rand
   rundherum. Ohne die feste Zelle hinge die Fläche am Bild, und ein Bild,
   das kleiner ist als die Fläche, klebte oben links in der Ecke. */
.console-live {
  width: 100%;
  /* Die Höhe ist eine Obergrenze, keine Vorgabe: Sobald ein Bild da ist,
     legt sich die Fläche genau darauf, damit ringsum keine schwarze Kante
     steht, sondern nur die Konsole. */
  height: min(82vh, 1400px);
  max-height: min(82vh, 1400px);
  min-height: 0;
  background: #0B0F0C;
  overflow: hidden;
  display: grid;
  grid-template: 1fr / 1fr;
}
/* Wohin die Tastatur geht, soll man sehen: Hat die Konsole den Fokus,
   bekommt sie einen schmalen Rahmen. Ohne das rätselt man, warum das
   Getippte im Antwortfeld landet. */
.console-live:focus { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
/* Die Leinwand der Sitzung bleibt so gross, wie sie angelegt ist.
   Weiter unten steht die Regel, die alles Breite im Kasten hält
   (`img, svg, video, canvas … { max-width: 100% }`). Für diese eine
   Leinwand ist sie falsch, und zwar auf eine Art, die man nicht sofort
   sieht: Guacamole legt die Leinwand in Schritten von 64 Pixeln an, für
   einen Bildschirm von 1630 mal 847 also 1664 mal 896, und schneidet den
   Überstand mit seiner Ebene ab. Die Regel deckelt die Leinwand auf die
   Breite dieser Ebene, 1630 statt 1664, und weil eine Leinwand ihr
   Seitenverhältnis behält, geht die Höhe im selben Zug auf 878 herunter.
   Das ganze Bild steht damit zwei Prozent zu klein in seiner Ebene: rechts
   bleibt ein Streifen frei, unten schiebt sich der nie gezeichnete Teil
   der Leinwand ins Bild. Wie breit der Streifen ist, hängt davon ab, wie
   weit die Auflösung vom nächsten 64er-Schritt entfernt liegt, und damit
   an Fensterbreite und Browser: mal ein Saum, mal ein Balken. */
.console-live canvas { display: block; max-width: none; max-height: none; }
/* Die Bibliothek legt ihre Ebenen mit z-index:-1 an. Ohne eigenen
   Stapelkontext liegen sie hinter dem Hintergrund dieser Fläche, und man
   sieht nur Schwarz, obwohl richtig gezeichnet wird. */
.console-live > div {
  position: relative;
  z-index: 0;
  isolation: isolate;
}
/* Je Maschine eine Fläche; nur die vorderste ist sichtbar, die anderen
   laufen im Hintergrund weiter. Alle liegen in derselben Zelle und sind
   so gross wie ihr Bild, damit place-self sie mittig setzen kann. */
.console-live .sitzung {
  grid-area: 1 / 1;
  place-self: center;
  /* Die Hülle wird auf das gezeichnete Bild gesetzt; was darüber hinaus
     steht, liegt unter ihrem Rand. Der Inhalt beginnt oben links, denn
     genau dort beginnt auch die Zeichnung: Überstand ist immer unten und
     rechts, nie oben. */
  display: block;
  overflow: hidden;
}

/* Reiter im Editor: Inhalt und Technik sind zwei Seiten. Die Klasse heisst
   noch sprungmarken, weil sie einmal genau das war. */
.sprungmarken {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 10px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.sprungmarken a {
  color: var(--muted);
  text-decoration: none;
  padding-bottom: 4px;
  border-bottom: 2px solid transparent;
}
.sprungmarken a:hover { color: var(--text); }
/* Der Reiter, auf dem man steht. */
.sprungmarken a.on { color: var(--text); border-bottom-color: var(--accent); }
/* Das Ziel eines Sprungs soll nicht am oberen Rand kleben. */
#grunddaten, #maschinen, #instanzen, #schritte { scroll-margin-top: 18px; }

/* ---------- Präsentiermodus ---------- */
/* Die Schicht, in die der Betreuer zeigt. Sie liegt genau auf dem Bild,
   nicht auf der Fläche: Im Mitschau-Fenster steht das Bild mittig in einer
   grösseren Fläche, und ein Zeiger, der am Rand danebenläge, hilft
   niemandem. */
.console-live .sitzung { position: relative; }
.zeigen-flaeche {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 3;
  /* Beim Zusehen greift die Schicht nichts ab: Der Azubi arbeitet unter
     ihr weiter, als läge sie nicht da. */
  pointer-events: none;
}
/* Beim Zeigen schon: Ein Strich soll nicht in der Sitzung landen. */
.zeigen-flaeche.leitend { pointer-events: auto; cursor: crosshair; }
.zeigen-flaeche.leitend.stift { cursor: cell; }

/* Die Werkzeuge im Mitschau-Fenster. */
.zeigen-leiste {
  display: flex;
  align-items: center;
  gap: 6px;
}
.zeigen-leiste[hidden] { display: none; }
.zeigen-leiste .farbe {
  width: 18px;
  height: 18px;
  padding: 0;
  border: 1px solid #556158;
  cursor: pointer;
  background: currentColor;
}
.zeigen-leiste .farbe.an { outline: 2px solid #E7EBE6; outline-offset: 1px; }
.zeigen-leiste .btn.an {
  border-color: var(--labor-accent-dark-bg);
  color: var(--labor-accent-dark-bg);
}

/* Der Hinweis beim Azubi. Er soll wissen, dass jemand auf seinen
   Bildschirm zeigt, und zwar wer: Ein Punkt, der von allein über das Bild
   wandert, ist sonst unheimlich. */
.zeigen-marke {
  position: absolute;
  left: 12px;
  top: 12px;
  z-index: 4;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 10px;
  background: rgba(11, 15, 12, 0.82);
  border: 1px solid var(--labor-line);
  color: #E7EBE6;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  pointer-events: none;
}
.zeigen-marke[hidden] { display: none; }
.zeigen-marke .led {
  width: 7px;
  height: 7px;
  background: #FF3B30;
  animation: zeigen-blinken 1.4s ease-in-out infinite;
}
@keyframes zeigen-blinken {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}
@media (prefers-reduced-motion: reduce) {
  .zeigen-marke .led { animation: none; }
}
/* Zusehen und Zeigen können gleichzeitig laufen. Die zweite Marke stellt
   sich deshalb unter die erste, statt sie zu verdecken. */
.zusehen-marke { top: 44px; }
/* Zusehen ist kein Alarm: ruhiger Punkt, kein Blinken. Erst wer mitsteuert,
   bekommt dieselbe Aufmerksamkeit wie das Zeigen. */
.zusehen-marke .led { background: #9CAA9F; animation: none; }
.zusehen-marke.steuert .led { background: #FF3B30;
  animation: zeigen-blinken 1.4s ease-in-out infinite; }

.console-empty {
  align-self: center;
  justify-self: center;
  text-align: center;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 13px;
  padding: 40px 24px;
  line-height: 1.8;
}
.console-empty p { margin: 0 0 14px; }
.console-empty .hint {
  margin: 12px 0 0;
  font-size: 11.5px;
  letter-spacing: 0.06em;
  color: #7D8C82;
}

/* Störungstafel: was schiefging, und was jetzt hilft. */
.stoerung {
  align-self: center;
  justify-self: center;
  width: min(460px, 100%);
  padding: 36px 28px;
  text-align: center;
  color: #F5F6F2;
}
.stoerung .sinnbild {
  display: block;
  width: 52px;
  height: 52px;
  margin: 0 auto 16px;
  color: var(--labor-accent-dark-bg);
}
.stoerung .sinnbild svg { display: none; width: 100%; height: 100%; }
.stoerung[data-art="verbindung"] .sb-verbindung,
.stoerung[data-art="berechtigung"] .sb-berechtigung,
.stoerung[data-art="belegt"] .sb-belegt,
.stoerung[data-art="getrennt"] .sb-getrennt { display: block; }
/* Ein abgewiesener Schlüssel ist kein Defekt, sondern eine Entscheidung:
   und eine beendete Sitzung erst recht kein Alarm. */
.stoerung[data-art="berechtigung"] .sinnbild { color: #E0B341; }
.stoerung[data-art="belegt"] .sinnbild,
.stoerung[data-art="getrennt"] .sinnbild { color: #7D8C82; }
.stoerung h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 22px;
  margin: 0 0 8px;
  color: #F5F6F2;
}
.stoerung .klartext {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.6;
  color: #B7C4BA;
  margin: 0 0 14px;
  overflow-wrap: anywhere;
}
.stoerung .tipp {
  font-size: 13px;
  line-height: 1.7;
  color: #9CAA9F;
  margin: 0 0 20px;
}
.stoerung .btn-row { justify-content: center; }

/* Auf der dunklen Fläche kehren sich die Knöpfe um: der Weg nach vorn ist
   der helle, alles andere bleibt ein Umriss. */
.stoerung .btn,
.console-empty .btn,
.connect .btn {
  background: var(--labor-accent-dark-bg);
  border-color: var(--labor-accent-dark-bg);
  color: #0B0F0C;
}
.stoerung .btn:hover,
.console-empty .btn:hover,
.connect .btn:hover { filter: brightness(1.1); }
.stoerung .btn:disabled,
.connect .btn:disabled { opacity: 0.45; }
.stoerung .btn-ghost {
  background: transparent;
  border-color: #556158;
  color: #F5F6F2;
}
.stoerung .btn-ghost:hover {
  border-color: #9CAA9F;
  background: rgba(255, 255, 255, 0.05);
}

/* Anmeldung waehlen, bevor die Sitzung aufgebaut wird */
.connect {
  align-self: center;
  justify-self: center;
  width: min(520px, 100%);
  padding: 40px 28px;
  text-align: center;
  color: #F5F6F2;
}
.connect .meta { color: #9CAA9F; }
.connect h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 24px;
  margin: 4px 0 6px;
  color: #F5F6F2;
}
.connect-state {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  color: #9CAA9F;
  margin: 0 0 22px;
}
.connect-hint {
  font-size: 12.5px;
  line-height: 1.6;
  color: #7D8C82;
  margin: 16px 0 0;
}

.logins { display: grid; gap: 8px; text-align: left; }
.login {
  appearance: none;
  border: 1px solid #33413A;
  background: transparent;
  color: #F5F6F2;
  padding: 12px 14px;
  cursor: pointer;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 12px;
  text-align: left;
  font: inherit;
}
.login:hover { border-color: #556158; background: rgba(255, 255, 255, 0.03); }
.login.on { border-color: var(--labor-accent-dark-bg); background: rgba(238, 138, 78, 0.08); }
.login-label { font-weight: 600; font-size: 14px; }
.login-who {
  grid-column: 1;
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: #B7C4BA;
  overflow-wrap: anywhere;
}
.login-hint {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #7D8C82;
  white-space: nowrap;
}

.connect-remember {
  display: flex;
  align-items: center;
  gap: 9px;
  justify-content: center;
  margin: 18px 0 20px;
  font-size: 13px;
  color: #B7C4BA;
  cursor: pointer;
}
.connect-remember input { width: 15px; height: 15px; accent-color: var(--labor-accent-dark-bg); }

.console-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 14px;
  border-top: 1px solid var(--labor-line);
}
.console-bar .who {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.08em;
  color: var(--muted);
}
/* Die Leiste des eingebauten Browsers steht bei den übrigen Knöpfen,
   gehört aber zum Bild darüber: eine Trennlinie sagt das ohne Worte. */
.console-bar .browser-leiste {
  margin-right: auto;
  padding-left: 12px;
  border-left: 1px solid var(--labor-line);
}
.console-bar .browser-leiste[hidden] { display: none; }

/* Schritte in der schmalen Spalte */
.steps.compact .step { grid-template-columns: 26px minmax(0, 1fr); padding: 14px 16px; }
.steps.compact .step h3 { font-size: 15px; }
.steps.compact .step .body { font-size: 14px; }
.steps.compact .question .qt { font-size: 14px; }

/* Aufgabenspalte ausgekoppelt: die Konsole bekommt die ganze Breite. */
.workbench.detached { grid-template-columns: minmax(0, 1fr) 14px 260px; }

/* Konsole ausgekoppelt: Aufgabe über die ganze Breite. */
.workbench.console-out { grid-template-columns: minmax(0, 1fr); }
.workbench.console-out .griff,
.workbench.collapsed .griff,
.workbench.detached .griff { display: none; }
.workbench.console-out .worksheet {
  position: static;
  max-height: none;
  overflow: visible;
}

/* Eingeklappt: nur noch eine schmale Leiste zum Aufklappen. */
.workbench.collapsed { grid-template-columns: minmax(0, 1fr) 16px 40px; }
.workbench.collapsed .worksheet { max-height: none; overflow: visible; }

.rail {
  appearance: none;
  width: 100%;
  border: 1px solid var(--labor-line);
  background: var(--surface);
  color: var(--muted);
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 18px 0;
  min-height: 260px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.rail:hover { color: var(--text); background: var(--shade); }
.rail-label { writing-mode: vertical-rl; }

@media (max-width: 1100px) {
  .workbench,
  .workbench.collapsed { grid-template-columns: 1fr; }
  .griff { display: none; }
  .worksheet { position: static; max-height: none; overflow: visible; }
  .rail { padding: 12px 0; min-height: 0; }
  .rail-label { writing-mode: horizontal-tb; }
}

/* ---------- Schritte ---------- */

.steps { display: grid; gap: 0; border: 1px solid var(--labor-line); background: var(--surface); }
.step { display: grid; grid-template-columns: 34px minmax(0, 1fr); gap: 0 14px; padding: 18px 20px; }
.step + .step { border-top: 1px solid var(--labor-line); }
.step.is-done { background: var(--shade); }

.step .box { padding-top: 2px; }
/* Das Kästchen der Schrittliste gilt überall: keine blauen Systemhaken. */
input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 17px;
  height: 17px;
  flex: none;
  border: 1.5px solid var(--muted);
  background: var(--field);
  display: inline-grid;
  place-content: center;
  cursor: pointer;
  margin: 0;
  vertical-align: -3px;
}
input[type="checkbox"]:checked { border-color: var(--text); background: var(--text); }
input[type="checkbox"]:checked::after {
  content: "";
  width: 8px;
  height: 4px;
  border-left: 2px solid var(--labor-bg);
  border-bottom: 2px solid var(--labor-bg);
  transform: rotate(-45deg) translate(1px, -1px);
}
input[type="checkbox"]:disabled { cursor: default; opacity: 0.55; }
input[type="checkbox"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* In der Schrittliste etwas grösser, das ist die Hauptgeste. */
.step input[type="checkbox"] { width: 19px; height: 19px; }
.step input[type="checkbox"]:checked::after { width: 9px; height: 5px; }

.step .n {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  color: var(--muted);
}
.step h3 { margin: 2px 0 6px; font-size: 16.5px; }
.step .body { color: var(--text); font-size: 15px; }
.step .body p:last-child { margin-bottom: 0; }
.step .body ul, .step .body ol { margin: 0 0 10px; padding-left: 20px; }

.question { margin-top: 14px; border-left: 2px solid var(--accent); padding-left: 14px; }
.question .q {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
}
.question .qt { font-size: 15px; margin-bottom: 8px; }
.question textarea { min-height: 76px; }
.answer-static {
  background: var(--shade);
  border: 1px solid var(--labor-line);
  padding: 10px 12px;
  font-family: var(--font-mono);
  font-size: 13.5px;
  white-space: pre-wrap;
}
.answer-empty { color: var(--muted); font-family: var(--font-mono); font-size: 13px; }

/* Prüfung: Musterantwort und das Urteil je Frage. */
.question.urteil-ok { border-left-color: var(--ok, #3E7C4F); }
.question.urteil-falsch { border-left-color: var(--danger); }
.muster {
  margin-top: 10px;
  border: 1px solid var(--labor-line);
  background: var(--shade);
  padding: 8px 12px;
}
.muster > summary {
  cursor: pointer;
  list-style: none;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.muster > summary::-webkit-details-marker { display: none; }
.muster > summary::before { content: "+ "; }
.muster[open] > summary::before { content: "− "; }
.muster .body { margin-top: 8px; font-size: 14px; }
.muster .body > :first-child { margin-top: 0; }
.muster .body > :last-child { margin-bottom: 0; }

.urteil {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
}
.urteil-knopf {
  appearance: none;
  border: 1px solid var(--labor-line);
  background: var(--surface);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 6px 12px;
  cursor: pointer;
}
.urteil-knopf:hover { border-color: var(--muted); color: var(--text); }
.urteil-knopf.ok.an {
  border-color: var(--ok, #3E7C4F);
  background: var(--ok, #3E7C4F);
  color: #FFFFFF;
}
.urteil-knopf.falsch.an {
  border-color: var(--danger);
  background: var(--danger);
  color: #FFFFFF;
}
.urteil .stand {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  color: var(--danger);
}

/* Wer die Aufgabe geschrieben hat. */
.von {
  margin: 8px 0 0;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.von strong { font-weight: 500; color: var(--text); }

/* Rückmeldung an den Azubi, nachdem geprüft wurde. */
.bewertet {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.bewertet.ok { color: var(--ok, #3E7C4F); }
.bewertet.falsch { color: var(--danger); }

.save-state {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  min-height: 14px;
}

/* ---------- Maschinenleiste ---------- */

.machine {
  border: 1px solid var(--labor-line);
  background: var(--surface);
  padding: 13px 15px;
}
.machine + .machine { border-top: none; }
.machine .top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.machine .nm { font-weight: 600; font-size: 15px; }
.machine .det { font-family: var(--font-mono); font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.machine .acts { margin-top: 10px; display: flex; gap: 6px; flex-wrap: wrap; }

/* ---------- Auftragsprotokoll ---------- */

.joblog {
  border: 1px solid var(--labor-line);
  background: var(--surface);
  padding: 12px 14px;
  font-family: var(--font-mono);
  font-size: 12px;
  white-space: pre-wrap;
  max-height: 220px;
  overflow-y: auto;
  color: var(--muted);
}

/* ---------- Zugangsdaten im Schritt ---------- */

.creds { margin-top: 14px; border: 1px solid var(--labor-line); background: var(--shade); }
.creds .head {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 8px 12px 0;
}
.cred-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  flex-wrap: wrap;
}
.cred-row + .cred-row { border-top: 1px solid var(--labor-line); }
.cred-row .k {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  width: 62px;
  flex: none;
}
.cred-row .v {
  font-family: var(--font-mono);
  font-size: 12.5px;
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}
.cred-row .v.hidden-value { letter-spacing: 0.18em; }
/* Die Knöpfe bleiben beieinander und rutschen gemeinsam um, statt dass
   einer allein in der nächsten Zeile landet. */
.cred-row .tools {
  display: flex;
  gap: 6px;
  flex: none;
  margin-left: auto;
}
.copy {
  appearance: none;
  border: 1px solid var(--labor-line);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 5px 9px;
  cursor: pointer;
  flex: none;
}
.copy:hover { border-color: var(--muted); }
.copy.done { border-color: var(--ok); color: var(--ok); }

.slot { padding: 10px 12px; }
.slot + .slot { border-top: 1px solid var(--labor-line); }
.slot-head { margin-bottom: 8px; }
.slot-head .nm { display: block; font-weight: 600; font-size: 14px; }
.slot-head .scope {
  display: block;
  margin-top: 2px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  line-height: 1.5;
  color: var(--muted);
}

/* Eine Zeile je Feld: Beschriftung, Eingabe, Knöpfe. */
/* Flex statt Raster: In einer schmalen Aufgabenspalte rutschen die Knöpfe
   unter das Feld, statt es auf drei Zeichen zusammenzudrücken. Der
   Bildschirm ist dabei egal, es zählt die Breite der Spalte. */
.slot-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
}
.slot-row + .slot-row { margin-top: 6px; }
.slot-row .k {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  flex: none;
  width: 68px;
}
.slot-row input {
  font-family: var(--font-mono);
  font-size: 12.5px;
  padding: 7px 9px;
  flex: 1 1 150px;
  min-width: 110px;
}
.slot-row .tools { display: flex; gap: 6px; flex: none; margin-left: auto; }

/* ---------- Dialog ---------- */

.modal {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(11, 15, 12, 0.78);
  z-index: 60;
}
.modal[hidden] { display: none; }
.modal-card {
  background: var(--surface);
  border: 1px solid var(--labor-line);
  max-width: 470px;
  width: 100%;
  padding: 26px;
}
.modal-card h2 { font-size: 22px; margin: 8px 0 8px; }
.modal-card p { color: var(--muted); font-size: 14.5px; }
.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 22px;
  flex-wrap: wrap;
}

/* ---------- Splashscreen ---------- */

.splash {
  border: 1px solid var(--labor-line);
  background: var(--surface);
  /* Nimmt die Seite unterhalb der Kopfzeile ein. */
  min-height: calc(100vh - 190px);
  display: grid;
  place-content: center;
  text-align: center;
  padding: 56px 32px;
  gap: 6px;
  position: relative;
  overflow: hidden;
}
.splash::before {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    135deg, transparent, transparent 16px,
    rgba(128, 140, 130, 0.05) 16px, rgba(128, 140, 130, 0.05) 32px);
  pointer-events: none;
}
.splash > * { position: relative; }
.splash .mark-row {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  justify-content: center;
  margin-bottom: 22px;
}
.splash h2 {
  font-size: clamp(24px, 3vw, 32px);
  letter-spacing: -0.03em;
  margin: 0 0 10px;
}
.splash p {
  color: var(--muted);
  max-width: 46ch;
  margin: 0 auto 4px;
  font-size: 15px;
}
.splash .actions { margin-top: 26px; display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.splash .note {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 26px;
}
/* Auftragsprotokoll: ohne Versalien, besser lesbar. */
.splash .note.live {
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: none;
}

/* Fortschrittsbalken ohne Prozentangabe. */
.splash .bar-run {
  width: 220px;
  height: 3px;
  margin: 26px auto 0;
  background: var(--shade);
  border: 1px solid var(--labor-line);
  overflow: hidden;
}
.splash .bar-run i {
  display: block;
  width: 40%;
  height: 100%;
  background: var(--accent);
  animation: bar-slide 1.6s ease-in-out infinite;
}
@keyframes bar-slide {
  0% { transform: translateX(-110%); }
  100% { transform: translateX(260%); }
}
@media (prefers-reduced-motion: reduce) {
  .splash .bar-run i { animation: none; width: 100%; opacity: 0.5; }
}

/* ---------- Zustand des Labs ---------- */

.lab-state {
  border: 1px solid var(--labor-line);
  background: var(--surface);
  padding: 18px 20px;
  margin-bottom: 14px;
}
.lab-state.busy { border-left: 2px solid var(--accent); }
.lab-state.foreign { border-left: 2px solid var(--danger); }
.lab-state h2 { font-size: 18px; margin-bottom: 4px; }
.lab-state p { margin: 0; color: var(--muted); font-size: 14.5px; }

.console-stage.locked { position: relative; }
.console-stage.locked::after {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    45deg, transparent, transparent 12px,
    rgba(255, 255, 255, 0.02) 12px, rgba(255, 255, 255, 0.02) 24px);
}

/* ---------- Tabellen ---------- */

.scroll { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 14.5px; }
th, td { text-align: left; padding: 10px 14px 10px 0; border-bottom: 1px solid var(--labor-line); vertical-align: top; }
th {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  border-bottom-color: var(--text);
}
td.mono, th.mono { font-family: var(--font-mono); font-size: 13px; }
td.num { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---------- Fortschrittsmatrix ---------- */

.dots { display: inline-flex; gap: 4px; flex-wrap: wrap; }
/* Auf .dots eingegrenzt: .dot heisst auch der Punkt der Wortmarke. */
.dots .dot {
  width: 13px;
  height: 13px;
  border: 1.4px solid var(--muted);
  display: inline-block;
}
.dots .dot.done { background: var(--text); border-color: var(--text); }
.bar { height: 4px; background: var(--shade); border: 1px solid var(--labor-line); min-width: 90px; }
.bar > i { display: block; height: 100%; background: var(--text); }

details.card { border: 1px solid var(--labor-line); background: var(--surface); padding: 14px 18px; }
details.card + details.card { border-top: none; }
details.card summary { cursor: pointer; font-weight: 600; }
details.card summary::-webkit-details-marker { display: none; }
details.card[open] > summary { margin-bottom: 12px; }

.stack { display: grid; gap: 16px; }
.two { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; align-items: start; }

@media (max-width: 860px) {
  /* Auf schmalen Geräten wird das Menü zur Schublade hinter dem Knopf. */
  .masthead { position: relative; }
  .menue-knopf { display: inline-flex; margin-left: auto; }
  .menue {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 60;
    background: var(--surface);
    border: 1px solid var(--labor-line);
    border-top: none;
    padding: 6px 16px 14px;
    box-shadow: 0 18px 30px rgba(0, 0, 0, 0.18);
  }
  .menue.offen { display: block; }
  .menue nav {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin-left: 0;
    overflow: visible;
  }
  .menue nav a {
    padding: 12px 2px;
    border-bottom: 1px solid var(--labor-line);
    font-size: 12px;
  }
  .menue nav a.on { border-bottom-color: var(--accent); }
  .menue > .spacer { display: none; }
  .menue > .konto-link {
    display: block;
    max-width: 100%;
    padding: 12px 2px;
  }
  .menue > form { padding: 4px 0 2px; }
  .menue > form .btn { width: 100%; }

  .split, .two { grid-template-columns: 1fr; }
  .side { position: static; }
  .grid-2, .grid-3 { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .wrap { padding-bottom: 72px; }
  .step { grid-template-columns: 28px minmax(0, 1fr); padding: 15px; }
}

/* ---------- Konto: QR, Codes, Trenner ---------- */

.qr {
  width: 200px;
  padding: 10px;
  margin: 14px 0;
  background: #fff;
  border: 1px solid var(--labor-line);
}
.qr svg { display: block; width: 100%; height: auto; }

.codes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(160px, 100%), 1fr));
  gap: 8px;
  margin-top: 12px;
}
.codes span {
  padding: 8px 10px;
  border: 1px solid var(--labor-line);
  background: var(--labor-bg);
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 0.06em;
}

.trenner {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 18px 0 14px;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.trenner::before,
.trenner::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--labor-line);
}

/* ---------- Editor: Arbeitsstand ---------- */

.entwurf {
  display: flex;
  align-items: center;
  gap: 8px 18px;
  flex-wrap: wrap;
  margin: 22px 0 0;
  padding: 12px 16px;
  border: 1px solid var(--labor-line);
  border-left: 2px solid var(--accent);
  background: var(--surface);
}
.entwurf .spacer { flex: 1 1 auto; min-width: 12px; }
.entwurf form { margin: 0; }
.entwurf .btn-row { gap: 8px; flex-wrap: wrap; }
.entwurf .zahl,
.entwurf .stand {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--muted);
}
.entwurf .zahl { color: var(--accent); }
/* Trennpunkt zwischen den Angaben, damit sie nicht als ein Satz gelesen werden. */
.entwurf .zahl + .stand::before,
.entwurf .meta + .stand::before {
  content: "·";
  margin-right: 12px;
  color: var(--labor-line);
}
.entwurf .stand.gut { color: var(--ok); }
.entwurf .stand.fehler { color: var(--danger); }

.entwurf-hinweis { margin: 10px 0 0; }

input.fehler,
textarea.fehler,
select.fehler { border-color: var(--danger); }

table.diff td.alt { color: var(--muted); text-decoration: line-through; }
table.diff td.neu { color: var(--text); }
table.diff tr.neu td:first-child { border-left: 2px solid var(--ok); }
table.diff tr.weg td:first-child { border-left: 2px solid var(--danger); }
table.diff tr.geaendert td:first-child { border-left: 2px solid var(--accent); }

/* ---------- Zugänge: Verweise im Text und Knöpfe an den Feldern ---------- */

.zugang {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin: 2px 0;
  padding: 3px 8px;
  border: 1px solid var(--labor-line);
  background: var(--shade);
  vertical-align: middle;
}
.zugang .zn {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.zugang code { background: none; padding: 0; font-size: 13px; }
.zugang.leer em { color: var(--muted); font-style: normal; font-size: 13px; }

/* ---------- Tippbarer Text im Anleitungstext ---------- */

.tippbar {
  display: inline-flex;
  align-items: flex-start;
  gap: 4px;
  vertical-align: baseline;
  /* Ein langer Befehl darf umbrechen, statt die Spalte zu sprengen. */
  max-width: 100%;
}
.tippbar code {
  background: var(--shade);
  padding: 1px 5px;
  overflow-wrap: anywhere;
}
.tippbar .tippknopf { flex: none; margin-top: 1px; }
.tippknopf {
  appearance: none;
  border: 1px solid var(--labor-line);
  background: var(--surface);
  color: var(--muted);
  font-size: 11px;
  line-height: 1;
  padding: 3px 5px;
  cursor: pointer;
}
.tippknopf:hover { color: var(--text); border-color: var(--muted); }
.tippknopf.done { color: var(--ok); border-color: var(--ok); }

/* ---------- Konten ---------- */

.konten { border: 1px solid var(--labor-line); background: var(--surface); }
.konto { padding: 16px 18px; }
.konto + .konto { border-top: 1px solid var(--labor-line); }

.konto-kopf {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px 20px;
  flex-wrap: wrap;
}
.konto .wer { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.konto .nm { font-weight: 600; font-size: 16px; }
.konto .knr {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--muted);
}
.konto .marken { display: flex; gap: 6px; flex-wrap: wrap; }

.chip {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  border: 1px solid var(--labor-line);
  padding: 3px 8px;
}
.chip.stark { color: var(--text); border-color: var(--muted); }
.chip.leise { border-style: dashed; }
.chip.aus { color: var(--danger); border-color: var(--danger); }

.konto-aktionen {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: flex-start;
  margin-top: 12px;
}
/* Geöffnet nimmt der Aufklapper die ganze Zeile, sonst steht er als
   schmaler Knopf neben den anderen. */
.konto-aktionen .aufklapper { margin-top: 0; }
.konto-aktionen .aufklapper[open] { flex: 1 1 100%; }
.konto-aktionen form { margin: 0; }
.konto-aktionen .gefahr { color: var(--danger); }
.konto-aktionen .gefahr:hover:not([disabled]) {
  border-color: var(--danger);
  background: var(--shade);
}

/* Aufklapper im Stil eines schmalen Knopfes. */
.aufklapper { margin-top: 10px; }
.aufklapper > summary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  list-style: none;
  cursor: pointer;
  border: 1px solid var(--labor-line);
  padding: 6px 12px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}
.aufklapper > summary::-webkit-details-marker { display: none; }
.aufklapper > summary::before { content: "+"; }
.aufklapper[open] > summary::before { content: "–"; }
.aufklapper > summary:hover { color: var(--text); border-color: var(--muted); }
.aufklapper .inhalt {
  margin-top: 10px;
  padding: 14px;
  border: 1px solid var(--labor-line);
  background: var(--shade);
}
.aufklapper .reihe { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.aufklapper .reihe input[type="password"] { width: 240px; }

.rollenwahl {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  gap: 10px 20px;
  margin-bottom: 14px;
}
.rolle { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; }
.rolle input[type="checkbox"] { margin-top: 3px; }
.rolle .rn { display: block; font-size: 14.5px; }
.rolle .rh { display: block; color: var(--muted); font-size: 13px; line-height: 1.4; }

/* --- Einstellungen ---------------------------------------------------- */
/* Zahl und Einheit gehören zusammen; das Feld bleibt schmal, damit „15“
   nicht in einer Spalte über die halbe Seite steht. */
.stellungen .stell-zeile {
  border-top: 1px solid var(--labor-line);
  padding-top: 16px;
}
.stell-zeile .field { margin-bottom: 6px; }
.mit-einheit { display: flex; align-items: center; gap: 10px; }
.mit-einheit input { max-width: 130px; }
.mit-einheit .einheit { color: var(--muted); font-size: 14px; }

/* Der Countdown im Übernahme-Fenster: gross genug, um ihn im Augenwinkel
   zu sehen, ohne dass man die Sekunden lesen muss. */
.modal-card .countdown {
  font-family: var(--font-mono);
  font-size: 20px;
  color: var(--accent);
}

/* Die Frist als Leiste. Die Zahl muss man lesen, die Leiste sieht man.
   Sie läuft von voll nach leer, einen Schritt je Sekunde und gleichmässig:
   Eine weiche Kurve bremste am Ende und liesse die Frist länger aussehen,
   als sie ist. */
.frist {
  height: 6px;
  margin-top: 16px;
  background: var(--shade);
  border: 1px solid var(--labor-line);
  overflow: hidden;
}
.frist > i {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--danger);
  transition: width 1s linear;
}
/* Die letzten zwanzig Sekunden. Rot steht ohnehin die ganze Zeit da,
   deshalb kommt hier Bewegung dazu: Ein ruhiges Pulsieren fällt auch auf,
   wenn das Fenster nur am Rand des Blickfelds liegt. Wer Bewegung
   abgestellt hat, bekommt den roten Rahmen ohne Puls; der Hinweis geht
   nicht verloren, er wird nur still. */
.modal-card.eilig {
  border-color: var(--danger);
  animation: frist-puls 1.1s ease-in-out infinite;
}
@keyframes frist-puls {
  0%, 100% { box-shadow: 0 0 0 0 rgba(198, 64, 64, 0); }
  50% { box-shadow: 0 0 0 8px rgba(198, 64, 64, 0.34); }
}
@media (prefers-reduced-motion: reduce) {
  .modal-card.eilig { animation: none; }
  .frist > i { transition: none; }
}

/* Konsolen unter ihrem Lab: eingerückt und leiser als die Lab-Zeile.
   Oben und unten gleich viel Luft, sonst stösst der Knopf an die
   gestrichelte Linie und sieht verrutscht aus. */
.konsolen-zeile {
  padding-top: 9px;
  padding-bottom: 9px;
  padding-left: 34px;
  border-top: 1px dashed var(--labor-line);
}
.konsolen-zeile .meta { min-width: 0; }
/* Die kleinen Knöpfe haben einen Rahmen; ohne diese Zeile entscheidet die
   Schrifthöhe über die Zeilenhöhe und die Zeile wird ungleichmässig. */
.konsolen-zeile .btn-sm { line-height: 1.2; }

/* ---------- Kartenraster ---------- */
/* Abschnitte, die nebeneinander passen, statt untereinander zu stapeln und
   die halbe Seite leer zu lassen. Jede Karte ist ein .block aus Beschriftung
   und Tafel, damit die beiden zusammenbleiben. */
.karten { display: grid; gap: 4px 32px; align-items: start; }
.karten > .block { min-width: 0; }
@media (min-width: 1080px) {
  .karten { grid-template-columns: 1fr 1fr; }
}

/* Einstellungen nebeneinander, sobald Platz ist. */
.stellungen {
  display: grid;
  gap: 20px 32px;
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
  align-items: start;
}
.stellungen .stell-zeile { min-width: 0; }

/* ---------- Schmale Geräte: nichts läuft über den Rand ---------- */
/* Die Regeln stehen absichtlich am Ende und ohne Media Query, wo sie
   überall gelten sollen: Ein Formularfeld, das breiter ist als sein
   Kasten, ist auf jedem Bildschirm falsch. */
input, select, textarea, img, svg, video, canvas, table { max-width: 100%; }
/* Lange Namen ohne Leerzeichen, Maschinen, Snapshots, Anmeldenamen:
   brechen lieber mitten im Wort, als die Seite breitzuziehen. */
.name, .sub, .meta, .hint, .empty, h1, h2, h3, p, li, td, th {
  overflow-wrap: break-word;
}
.mono, code, kbd { overflow-wrap: anywhere; }
/* Protokolle und Tabellen scrollen in sich selbst. */
.joblog { overflow: auto; }

@media (max-width: 700px) {
  /* Titel oben, Knöpfe darunter, nebeneinander wird es hier zu eng. */
  .row { align-items: flex-start; }
  .row .btn-row { width: 100%; }
  .konsolen-zeile { padding-left: 18px; }
  /* Der Fortschrittsbalken neben dem Titel braucht keine feste Breite. */
  .bar { max-width: 100%; }
}

/* ---------- Schritte sortieren ---------- */
/* Der Griff sitzt in der Zusammenfassung, damit sich die Reihenfolge
   ändern lässt, ohne jeden Schritt aufzuklappen. */
.schritt-karte > summary { display: flex; align-items: center; gap: 6px; }
.schritt-karte > summary .spacer { flex: 1 1 auto; }
.schritt-karte > summary .nummer { flex: none; }
.griff-punkte {
  flex: none;
  cursor: grab;
  color: var(--muted);
  font-size: 15px;
  line-height: 1;
  padding: 2px 6px 4px 0;
  user-select: none;
}
.griff-punkte:active { cursor: grabbing; }
/* Auf Tablets soll das Ziehen am Griff nicht die Seite scrollen. */
.griff-punkte { touch-action: none; }
body.sortiert-gerade { cursor: grabbing; user-select: none; }
.sortieren { display: flex; gap: 4px; flex: none; }
.sortieren .btn { padding: 2px 8px; line-height: 1.2; }
.sortieren .btn[disabled] { opacity: 0.35; cursor: default; }
/* Die gezogene Karte bleibt sichtbar, tritt aber zurück. */
.schritt-karte.zieht { opacity: 0.45; outline: 1px dashed var(--accent); }

@media (max-width: 700px) {
  .schritt-karte > summary { flex-wrap: wrap; }
  .schritt-karte > summary .spacer { display: none; }
}

/* Der Griff in Listenzeilen sitzt links vor dem Titel. */
.list .row > .griff-punkte { align-self: center; padding-left: 0; }
.list .row > .sortieren { align-self: center; }

/* ---------- Maschinenliste: suchen, filtern, gruppieren ---------- */
/* Dreissig Maschinen sind eine Wand. Die Leiste steht über der Liste und
   bleibt beim Scrollen oben, sonst tippt man blind. */
.werkzeugleiste {
  position: sticky;
  top: 8px;
  z-index: 4;
  margin-bottom: 14px;
}
.suchfeld {
  flex: 1 1 260px;
  min-width: 180px;
  padding: 8px 12px;
  border: 1px solid var(--labor-line);
  border-radius: var(--radius-sm, 6px);
  background: var(--panel, transparent);
  color: var(--text);
  font: inherit;
}
.suchfeld:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Ein eingeschalteter Filter sieht aus wie gedrückt. */
.filterknopf.on,
.werkzeugleiste .btn.on {
  border-color: var(--accent);
  color: var(--accent);
}
.maschinen-gruppe + .maschinen-gruppe { margin-top: 20px; }
.gruppenkopf { display: flex; align-items: baseline; gap: 8px; }
/* Wofür eine Maschine da ist, steht rechts in der Kopfzeile, klein. */
.maschine .wofuer {
  display: block;
  width: 100%;
  margin-top: 4px;
  font-size: 12px;
}

/* ---------- Hinweis auf eine neuere Fassung ---------- */
/* Zwei Stufen, beide nur für Betreuer: eine Marke in der Fusszeile, die
   überall mitläuft, und eine Karte auf der Übersicht. Ein Update ist nie
   dringend genug, um jemanden mitten in einer Sitzung zu unterbrechen,
   deshalb blinkt hier nichts und nichts legt sich über die Seite. */
.fassung-marke {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 8px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  color: var(--accent);
  font-size: 11px;
  text-decoration: none;
  white-space: nowrap;
}
.fassung-marke:hover { background: var(--accent); color: #fff; }
.fassung-marke.dringend { border-color: var(--danger); color: var(--danger); }
.fassung-marke.dringend:hover { background: var(--danger); color: #fff; }

.fassung-hinweis {
  margin: 0 0 24px;
  padding: 14px 16px;
  border: 1px solid var(--accent);
  border-left-width: 4px;
  border-radius: var(--radius-sm, 6px);
  background: var(--surface);
}
.fassung-hinweis.dringend { border-color: var(--danger); }
.fassung-hinweis .name { font-weight: 600; }

/* Die Notizen aus dem Feed sind Markdown und können lang sein. */
.fassung-notizen {
  margin: 12px 0 14px;
  padding-top: 12px;
  border-top: 1px solid var(--labor-line);
  max-height: 260px;
  overflow: auto;
  font-size: 14px;
}
.fassung-notizen ul { margin: 0; padding-left: 20px; }
.fassung-notizen li + li { margin-top: 6px; }

/* Eine Zeile der Bereitschaftsprüfung: Port und der Haken darunter. */
.bereit-zeile { margin-bottom: 4px; }
.bereit-zeile .field input:disabled { opacity: .45; }

/* Zugänge der Sitzung: vier kleine Knöpfe, die auch nebeneinander passen
   sollen, wenn die Seitenleiste schmal ist. */
.zugang-knoepfe { flex-wrap: wrap; gap: 6px; }
.zugang-geheim { font-family: var(--font-mono); font-size: 11.5px; }
.zugang-geheim .hidden-value { margin: 0 4px; }
