/* app.css — Öffentliche Oberfläche.
   Werte stammen aus den Design-Tokens in README.md und sind dort verbindlich.
   Schriften werden selbst gehostet (fonts.css), damit die CSP ohne Ausnahme
   für externe Hosts auskommt. */

:root {
  /* Flächen */
  --bg:            #0b0d0f;
  --bg-glow:       #16191d;
  --surface:       #15181b;
  --surface-sub:   #101316;
  --surface-tile:  #191d20;
  --chip:          #22262a;
  --black:         #07080a;

  /* Rahmen */
  --bd-card:   #262b30;
  --bd-div:    #23282c;
  --bd-row:    #1e2226;
  --bd-input:  #343b41;
  --bd-muted:  #3f464c;

  /* Text */
  --tx:        #f1ece5;
  --tx-2:      #9aa3a9;
  --tx-muted:  #828a90;
  --tx-label:  #8e9599;
  --tx-off:    #6d7579;

  /* Akzent */
  --acc:       #d9600f;
  --acc-hover: #b74e08;
  --acc-tint:  #20160e;
  --acc-text:  #f5b177;
  --acc-ring:  rgba(217, 96, 15, .22);

  /* Zustände */
  --ok:        #3fbf98;
  --ok-text:   #8ff0cf;
  --ok-tint:   #14302a;
  --warn:      #f0a23c;
  --warn-text: #f5c78d;
  --warn-tint: #33261a;
  --warn-bd:   #4a3620;
  /* Rot für "Blockiert" - im Prototyp nicht vorhanden, ergänzt für den
     Scan-Status (DECISIONS.md). */
  --bad:       #e06060;
  --bad-text:  #f0a0a0;
  --bad-tint:  #3a1c1c;
  --bad-bd:    #5a2a2a;

  --glyph:     #4a5257;
  --glyph-2:   #3a4145;
  --link:      #f08a3c;
  --link-hover:#ffab63;

  --sh-card: 0 1px 2px rgba(20,24,28,.05), 0 14px 34px -22px rgba(20,24,28,.28);
  --sh-row:  0 8px 22px -16px rgba(20,24,28,.4);
  --sh-tile: 0 6px 18px -12px rgba(20,24,28,.35);

  --font: 'Instrument Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* Einheitliche Höhe für Knöpfe und Chips in einer Zeile. */
  --ctl-h: 52px;
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: radial-gradient(1100px 520px at 50% -140px, var(--bg-glow) 0%, var(--bg) 62%);
  background-attachment: fixed;
  color: var(--tx);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* Desktop-only laut DECISIONS.md - unter dieser Breite erscheint der
     Hinweis in #too-small. */
  min-width: 320px;
}

/* Bildschirme werden per Zustand umgeschaltet, nicht per Seitenwechsel:
   ein Reload würde die Sitzung nicht verlieren, aber den Ablauf unterbrechen. */
.screen { display: none; }
.screen.active { display: block; }

/* --- Typografie ------------------------------------------------------- */
h1 { font-size: 26px; font-weight: 600; letter-spacing: -.02em; margin: 0 0 24px; }
.mono { font-family: var(--mono); }
.label {
  display: block; font-family: var(--mono); font-size: 11px; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--tx-label);
  margin-bottom: 8px;
}
.muted { color: var(--tx-2); }
.small { font-size: 12.5px; }

/* --- Öffentliche Karte (Bildschirm 1) --------------------------------- */
.auth-wrap { max-width: 520px; margin: 0 auto; padding: 56px 24px 80px; }

.brandbar { display: flex; align-items: center; gap: 12px; margin-bottom: 34px; }
/* Das Zeichen trägt die Farbe selbst - es steht auf dunklem Grund und braucht
   keinen Rahmen. flex:none, damit es beim Umbruch nicht gequetscht wird. */
.mark { flex: none; display: block; }
.wordmark { font-size: 17px; font-weight: 600; }
.brandbar .divider { width: 1px; height: 20px; background: var(--bd-input); }
.brandbar .tagline {
  font-family: var(--mono); font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--tx-label);
}

.tabs {
  display: flex; gap: 6px; padding: 5px; margin-bottom: 18px;
  background: var(--surface-sub); border-radius: 11px;
}
.tabs button {
  flex: 1; padding: 11px 14px; border: 0; border-radius: 8px;
  background: transparent; color: var(--tx-2);
  font: inherit; font-size: 14px; cursor: pointer;
  transition: background .15s, color .15s;
}
.tabs button[aria-selected="true"] {
  background: var(--chip); color: var(--tx); box-shadow: inset 0 0 0 1px var(--bd-input);
}
.tabs button:hover:not([aria-selected="true"]) { color: var(--tx); }

.card {
  background: var(--surface); border: 1px solid var(--bd-card);
  border-radius: 14px; padding: 34px 32px 30px; box-shadow: var(--sh-card);
}

/* --- Formulare --------------------------------------------------------- */
.field { margin-bottom: 18px; }
input[type=text], input[type=email], input[type=password], input[type=number], select, textarea {
  width: 100%; padding: 13px 15px; font: inherit; font-size: 14.5px;
  color: var(--tx); background: var(--surface-sub);
  border: 1.5px solid var(--bd-input); border-radius: 9px;
  transition: border-color .15s, box-shadow .15s;
}
input::placeholder { color: var(--tx-off); }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--acc); box-shadow: 0 0 0 4px var(--acc-ring);
}
input:disabled { opacity: .55; cursor: not-allowed; }

/* Alle Bedienelemente einer Kopfzeile teilen dieselbe Höhe. Vorher war der
   ghost-Knopf kleiner als der gefüllte (14px statt 15px Schrift, weniger
   Innenabstand) und der Ablauf-Chip wieder anders hoch - nebeneinander sah
   das nach drei verschiedenen Bauteilen aus. Der Unterschied gehört in die
   Farbe, nicht in die Größe. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 0 20px; min-height: var(--ctl-h); border: 0; border-radius: 9px;
  background: var(--acc); color: #fff; font: inherit; font-size: 15px; font-weight: 600;
  cursor: pointer; transition: background .15s;
}
.btn:hover:not(:disabled) { background: var(--acc-hover); }
.btn:disabled { opacity: .6; cursor: not-allowed; }
.btn.full { width: 100%; }
.btn.ghost {
  background: var(--surface); color: var(--tx); border: 1px solid var(--bd-input);
  padding: 0 19px;            /* 19 + 1px Rahmen = 20, wie beim gefüllten */
  font-size: 15px; border-radius: 9px;
}
.btn.ghost:hover:not(:disabled) { background: var(--chip); }
/* Kleine Varianten für die Leiste der Mehrfachauswahl - gleiche Maße wie in
   der Verwaltung, damit beide Oberflächen zusammenpassen. */
.btn.small { padding: 7px 12px; font-size: 12.5px; border-radius: 7px; }
.btn.danger { background: var(--bad-tint); color: var(--bad-text); border: 1px solid var(--bd-card); }
.btn.danger:hover:not(:disabled) { background: #4a2020; }

.linkrow { display: flex; justify-content: space-between; align-items: center; margin-top: 16px; }
a, .linklike {
  color: var(--link); text-decoration: none; font-size: 13.5px;
  background: none; border: 0; padding: 0; font-family: inherit; cursor: pointer;
}
a:hover, .linklike:hover { color: var(--link-hover); text-decoration: underline; }

.note { font-size: 12.5px; color: var(--tx-muted); }
.card-foot {
  margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--bd-div);
  font-size: 12.5px; color: var(--tx-muted);
}

/* Fehlermeldung. role="alert", damit Screenreader sie ansagen. */
.error {
  margin-bottom: 18px; padding: 12px 14px; border-radius: 9px;
  background: var(--bad-tint); border: 1px solid var(--bad-bd);
  color: var(--bad-text); font-size: 13.5px;
}
.error:empty { display: none; }

/* Gleicher Kasten in gruen - fuer Hinweise, die keine Stoerung melden
   ("Sie wurden abgemeldet."). Ohne diese Regel stand der Satz nackt auf der
   Karte, weil das Element beim Umschalten seine .error-Klasse verliert. */
.ok-msg {
  margin-bottom: 18px; padding: 12px 14px; border-radius: 9px;
  background: var(--ok-tint); border: 1px solid #1e4a3e;
  color: var(--ok-text); font-size: 13.5px;
}
.ok-msg:empty { display: none; }

/* --- Zugangscode ------------------------------------------------------- */
#code-input {
  font-family: var(--mono); font-size: 22px; letter-spacing: .22em;
  text-transform: uppercase; text-align: center;
}

/* --- PIN --------------------------------------------------------------- */
.chip-ok {
  display: inline-block; padding: 6px 12px; border-radius: 20px;
  background: var(--ok-tint); color: var(--ok-text);
  font-family: var(--mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  margin-bottom: 20px;
}
.pin-wrap { position: relative; margin-bottom: 20px; }
.pin-boxes { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.pin-box {
  aspect-ratio: 1 / 1.15; display: grid; place-items: center;
  border: 1.5px solid var(--bd-input); border-radius: 9px; background: var(--surface-sub);
  font-family: var(--mono); font-size: 26px; color: var(--tx);
}
.pin-box.filled { border-color: var(--acc); }
/* Das echte Eingabefeld deckt die Kästchen ab. opacity:0 statt
   visibility/display: so bleibt es fokussierbar, anklickbar und für
   Passwortmanager auffindbar - nur eben unsichtbar. Ohne das stünde die
   PIN doppelt auf dem Bildschirm. */
.pin-input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; border: 0; padding: 0; background: transparent;
  font-size: 16px; /* verhindert das Hineinzoomen auf Touchgeräten */
  cursor: pointer;
}
/* Fokus muss trotzdem sichtbar sein - er wandert auf die Kästchen. */
.pin-input:focus-visible { outline: none; }
.pin-input:focus-visible ~ .pin-boxes .pin-box,
.pin-wrap:focus-within .pin-box { border-color: var(--bd-muted); }
.pin-wrap:focus-within .pin-box.filled { border-color: var(--acc); }

/* Nur für Screenreader. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --- Datenräume (Bildschirm 2) ---------------------------------------- */
.page { max-width: 900px; margin: 0 auto; padding: 34px 26px 90px; }
.page-wide { max-width: 1180px; }
.page-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px; margin-bottom: 26px; }
.page-head h1 { font-size: 28px; margin-bottom: 6px; }
.eyebrow {
  font-family: var(--mono); font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--tx-label); margin-bottom: 10px;
}

.room-list { display: grid; gap: 11px; }
.room-row {
  display: flex; align-items: center; gap: 18px;
  background: var(--surface); border: 1px solid var(--bd-card); border-radius: 12px;
  padding: 18px 20px; cursor: pointer; text-align: left; width: 100%;
  font: inherit; color: inherit;
  transition: border-color .15s, box-shadow .15s;
}
.room-row:hover { border-color: var(--bd-muted); box-shadow: var(--sh-row); }
.room-icon {
  width: 34px; height: 34px; flex: none; border: 2px solid var(--acc);
  border-radius: 8px; display: grid; place-items: center;
}
.room-icon i { width: 12px; height: 12px; background: var(--acc); opacity: .25; display: block; }
.room-name { font-size: 16px; font-weight: 600; }
.room-meta { font-family: var(--mono); font-size: 12.5px; color: var(--tx-muted); }
.chevron { margin-left: auto; color: var(--tx-off); }

/* --- Datenraum (Bildschirm 3) ----------------------------------------- */
.room-grid { display: grid; grid-template-columns: minmax(0,1fr) minmax(220px,300px); gap: 22px; }
.panel {
  background: var(--surface); border: 1px solid var(--bd-card);
  border-radius: 13px; padding: 22px;
}
.panel h2 { font-size: 16px; font-weight: 600; margin: 0 0 16px; }

/* Auskunftszeilen im Benutzerprofil: links die Bezeichnung, rechts der Wert.
   Derselbe Aufbau wie in der Verwaltung, damit beide Seiten gleich lesen. */
.sys-row {
  display: flex; justify-content: space-between; gap: 14px; align-items: baseline;
  padding: 7px 0; border-bottom: 1px solid var(--bd-row); font-size: 13px;
}
.sys-row:last-child { border-bottom: 0; }
.sys-row .k { color: var(--tx-2); }
.sys-row .v { font-family: var(--mono); font-size: 12.5px; text-align: right; word-break: break-all; }
.panel-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 16px; }
.panel-head h2 { margin: 0; }

.expiry-chip {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--warn-tint); border: 1px solid var(--warn-bd); color: var(--warn-text);
  /* Gleiche Höhe wie die Knöpfe daneben, Pillenform bleibt. */
  padding: 0 17px; min-height: var(--ctl-h);
  border-radius: calc(var(--ctl-h) / 2); font-size: 14px;
}
.dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.dot.live { animation: dmzpulse 2.4s ease-in-out infinite; }
@keyframes dmzpulse { 0%,100% { opacity: 1 } 50% { opacity: .35 } }

.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; }
.tile {
  border: 1px solid var(--bd-card); border-radius: 10px; padding: 14px;
  background: var(--surface-tile); position: relative;
  transition: border-color .15s, box-shadow .15s;
}
.tile:hover { border-color: var(--bd-muted); box-shadow: var(--sh-tile); }
/* Abrufbar: anklickbar mit Akzentrahmen. Gesperrt: sichtbar, aber gedämpft. */
.tile-open { cursor: pointer; }
.tile-open:hover { border-color: var(--acc); }
.tile-locked { opacity: .72; }
.doc-glyph {
  width: 30px; height: 36px; border: 1.5px solid var(--glyph); border-radius: 3px;
  padding: 6px 5px; display: grid; gap: 3px; align-content: start; margin-bottom: 12px;
}
.doc-glyph span { height: 2px; background: var(--glyph-2); display: block; }
.doc-glyph span:nth-child(3) { width: 60%; }
.tile-name {
  font-size: 13.5px; font-weight: 500; margin-bottom: 4px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tile-meta { font-family: var(--mono); font-size: 11.5px; color: var(--tx-muted); margin-bottom: 10px; }
.tile-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* Auswahl-Haken auf der Kachel. Die ganze Kachel ist ein Download-Knopf,
   deshalb sitzt der Haken in einer eigenen Flaeche mit eigenem Klickbereich -
   und das Skript stoppt dort die Weitergabe des Klicks. */
.tile { position: relative; }
.tile-check {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 6px; cursor: pointer;
  background: var(--surface-sub); border: 1px solid var(--bd-card);
}
.tile-check:hover { border-color: var(--acc); }
.tile-check input { margin: 0; cursor: pointer; }
.tile.selected { border-color: var(--acc); }

/* Leiste fuer die Mehrfachauswahl - nur sichtbar, wenn etwas gewaehlt ist. */
.bulkbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; margin-bottom: 12px;
  background: var(--surface-sub); border: 1px solid var(--bd-card); border-radius: 8px;
}
.bulkbar[hidden] { display: none; }
.bulk-count { font-family: var(--mono); font-size: 12px; color: var(--tx-2); }
.bulk-clear { margin-left: auto; font-size: 12.5px; background: none; border: 0; padding: 0; }
@media (max-width: 380px) {
  .bulkbar { gap: 8px; }
  .bulk-clear { margin-left: 0; }
}

.badge {
  display: inline-block; padding: 3px 8px; border-radius: 5px;
  font-family: var(--mono); font-size: 10.5px; font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase;
}
.badge.neu     { background: var(--ok-tint);   color: var(--ok-text); }
.badge.ablauf  { background: var(--warn-tint); color: var(--warn-text); }
.badge.neutral { background: var(--chip);      color: var(--tx-2); }
.badge.pruef   { background: var(--warn-tint); color: var(--warn-text); }
.badge.blockiert { background: var(--bad-tint); color: var(--bad-text); }

/* --- Dropzone ---------------------------------------------------------- */
.dropzone {
  border: 1.5px dashed var(--bd-muted); border-radius: 11px;
  padding: 34px 20px; background: var(--surface-sub); text-align: center;
  cursor: pointer; transition: border-color .15s, background .15s;
}
.dropzone:hover, .dropzone.over { border-color: var(--acc); background: var(--acc-tint); }
.up-glyph {
  width: 38px; height: 38px; margin: 0 auto 12px; position: relative;
}
.up-glyph::before {
  content: ''; position: absolute; left: 50%; top: 4px; width: 2px; height: 22px;
  background: var(--glyph); transform: translateX(-50%);
}
.up-glyph::after {
  content: ''; position: absolute; left: 50%; top: 5px; width: 13px; height: 13px;
  border-left: 2px solid var(--glyph); border-top: 2px solid var(--glyph);
  transform: translateX(-50%) rotate(45deg);
}
.dz-title { font-size: 15px; font-weight: 600; margin-bottom: 4px; }


/* --- Verlauf ----------------------------------------------------------- */
.timeline { display: grid; gap: 18px; }
.tl-item { display: grid; grid-template-columns: 9px 1fr; gap: 12px; position: relative; }
.tl-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--ok); margin-top: 6px; }
.tl-dot.warn { background: var(--warn); }
.tl-dot.off  { background: var(--tx-off); }
.tl-item:not(:last-child)::before {
  content: ''; position: absolute; left: 4px; top: 17px; bottom: -18px;
  width: 1.5px; background: var(--bd-div);
}
.tl-text { font-size: 13px; font-weight: 500; }
.tl-meta { font-family: var(--mono); font-size: 11.5px; color: var(--tx-muted); margin-top: 2px; }

/* --- Übertragung (Bildschirm 4) --------------------------------------- */
.transfer { max-width: 820px; margin: 0 auto; padding: 34px 26px 90px; }
.xfer-head {
  display: flex; align-items: center; gap: 12px; margin-bottom: 20px;
  padding-bottom: 16px; border-bottom: 1px solid var(--bd-div);
}
.xfer-state {
  font-family: var(--mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--tx-label);
}
.xfer-pct { margin-left: auto; font-family: var(--mono); font-size: 13px; }
.xfer-row { padding: 14px 0; border-bottom: 1px solid var(--bd-row); }
.xfer-row:last-child { border-bottom: 0; }
.xfer-line { display: flex; align-items: baseline; gap: 12px; margin-bottom: 8px; }
.xfer-line .name { flex: 1; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.xfer-line .size, .xfer-line .st { font-family: var(--mono); font-size: 11.5px; color: var(--tx-muted); }
.bar { height: 6px; border-radius: 4px; background: var(--chip); overflow: hidden; }
.bar > i { display: block; height: 100%; width: 0; background: var(--warn); transition: width .3s linear; }
.bar.done > i { background: var(--ok); }

.done-panel {
  margin-top: 22px; background: var(--black); border: 1px solid var(--bd-card);
  border-radius: 12px; padding: 26px; text-align: center;
}
.check {
  width: 42px; height: 42px; margin: 0 auto 14px; border-radius: 50%;
  border: 2px solid var(--ok); display: grid; place-items: center; color: var(--ok);
  font-size: 20px;
}

/* Trenner zwischen den beiden Zugangswegen auf der Anmeldekarte. */
.or {
  display: flex; align-items: center; gap: 14px;
  margin: 26px 0 20px; color: var(--tx-off); font-size: 12.5px;
}
.or::before, .or::after {
  content: ""; flex: 1; height: 1px; background: var(--bd-div);
}

/* --- Abruflink ---------------------------------------------------------- */
.linkfile { padding: 30px 26px; text-align: center; }
.linkfile .dz-title { margin-top: 14px; word-break: break-all; }
.linkfile .btn { display: inline-flex; }
.mb26 { margin-bottom: 26px; }

/* --- Sammellink: Liste der bereitgestellten Dateien -------------------------
   Eigene Klassen und NICHT .linkrow: das gehoert der Anmeldemaske (Zeile mit
   "Passwort vergessen"). Zwei Bedeutungen an einer Klasse waeren die Stelle,
   an der eine spaetere Aenderung die jeweils andere Ansicht zerlegt. */
.linklist { margin-top: 18px; text-align: left; }
.filerow {
  display: flex; align-items: center; gap: 14px;
  padding: 11px 14px; border: 1px solid var(--bd-row); border-radius: 8px;
  background: var(--surface-sub); margin-bottom: 8px;
}
.filerow:last-child { margin-bottom: 0; }
.filerow-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
/* break-all wie bei .linkfile .dz-title: Dateinamen ohne Leerzeichen sprengen
   die Karte sonst waagerecht. */
.filerow-name { color: var(--tx); font-size: 13.5px; word-break: break-all; }
.filerow-size { white-space: nowrap; }
.filerow .btn { flex: none; }

/* --- Hilfszustände ----------------------------------------------------- */
.spinner {
  width: 15px; height: 15px; border: 2px solid rgba(255,255,255,.25);
  border-top-color: #fff; border-radius: 50%; animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.empty { padding: 30px 10px; text-align: center; color: var(--tx-muted); font-size: 13.5px; }

/* Desktop-only: Hinweis statt kaputtem Layout (DECISIONS.md Frage 1). */
/* Der frühere Riegel "#too-small" ist weg: die öffentliche Seite ist jetzt
   auch auf dem Telefon bedienbar. Die Verwaltung bleibt Desktop-only - dort
   stehen Tabellen mit sechs Spalten, Audit-Log und Systemansicht, die auf
   einem Telefon niemand ernsthaft bedient. */
#too-small { display: none; }

/* ---------------------------------------------------------------------------
   Kleine Bildschirme
   ---------------------------------------------------------------------------
   Eine Fassung, nicht zwei: dieselbe Adresse, dasselbe HTML, nur andere
   Layoutregeln. Eine getrennte Mobilseite driftet auseinander, und jede
   Änderung müsste man zweimal bauen.

   Die Grenze liegt bei 860px, weil dort das zweispaltige Raster des
   Datenraums zu eng wird - nicht an einer Gerätebreite. */
@media (max-width: 860px) {
  .auth-wrap { padding: 28px 16px 56px; }
  .page, .page-wide, .transfer { padding: 22px 16px 64px; }

  .brandbar { gap: 10px; margin-bottom: 22px; }
  .wordmark { font-size: 16px; }

  .card { padding: 24px 18px 22px; }
  h1 { font-size: 23px; margin-bottom: 20px; }
  .page-head h1 { font-size: 24px; }
  .h1-lg { font-size: 26px; }

  /* Kopfzeile: Titel oben, Bedienelemente darunter über die volle Breite.
     Nebeneinander bliebe für den Raumnamen nichts übrig. */
  .page-head { flex-direction: column; align-items: stretch; gap: 16px; }
  .head-right { justify-content: flex-start; }
  .head-right > .btn { flex: 1 1 auto; min-width: 44%; }
  .expiry-chip { width: 100%; justify-content: center; }

  /* Verlauf rutscht unter die Dateien statt daneben. */
  .room-grid { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .self-start { align-self: stretch; }

  /* Kacheln einspaltig: zwei nebeneinander lassen vom Dateinamen nichts
     übrig, und der ist das Einzige, worauf es ankommt. */
  .tiles { grid-template-columns: minmax(0, 1fr); }
  .panel { padding: 18px 16px; }

  /* Auf Touchgeräten zoomt iOS in jedes Feld hinein, dessen Schrift kleiner
     als 16px ist. Das verschiebt das Layout und wirkt wie ein Fehler. */
  input[type=text], input[type=email], input[type=password], input[type=number],
  select, textarea { font-size: 16px; }
  #code-input { font-size: 20px; letter-spacing: .18em; }

  .pin-boxes { gap: 8px; }
  .pin-box { font-size: 22px; }

  .linkrow { flex-direction: column; align-items: flex-start; gap: 8px; }
  .foot-row { flex-direction: column; align-items: stretch; gap: 12px; }
  .foot-row .btn { width: 100%; }

  .dropzone { padding: 26px 14px; }
  .linkfile { padding: 22px 14px; }
  .room-row { padding: 15px 16px; gap: 14px; }

  /* Untere Kante freihalten: auf Geräten mit Gestensteuerung liegt dort die
     Leiste des Systems. */
  body { padding-bottom: env(safe-area-inset-bottom); }
}

/* Sehr schmale Geräte - iPhone SE und Ähnliches. */
@media (max-width: 380px) {
  .head-right > .btn { min-width: 100%; }
  .pin-box { font-size: 19px; }
  .page-head h1 { font-size: 21px; }
}

/* Fokus muss immer sichtbar sein - Tastaturbedienung ist kein Sonderfall. */
:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* --- Hilfsklassen ------------------------------------------------------
   Ersetzen die frueheren style="..."-Attribute. Die CSP erlaubt bewusst kein
   style-src 'unsafe-inline'; Chrome verwirft Inline-Styles daher stillschweigend.
   Klassen statt Attribute ist ohnehin die sauberere Loesung. */
.intro      { margin-top:-14px; margin-bottom:24px; }
.h1-lg      { font-size:30px; }
.h1-md      { font-size:28px; }
.code-input { font-family:var(--mono); font-size:20px; letter-spacing:.25em; text-align:center; }
.stack10    { display:grid; gap:10px; }
.stack22    { display:grid; gap:22px; min-width:0; }
/* Drei Knöpfe plus Ablauf-Chip: auf schmalen Fenstern umbrechen statt den
   Kopfbereich aus der Seite zu schieben. */
.head-right { display:flex; align-items:center; gap:12px; flex:none;
              flex-wrap:wrap; justify-content:flex-end; }
.self-start { align-self:start; }
.foot-row   { display:flex; justify-content:space-between; align-items:center; margin-top:22px; }
.dot-warn   { color:var(--warn); }
.mt14 { margin-top:14px; } .mt16 { margin-top:16px; } .mt18 { margin-top:18px; }
.mt22 { margin-top:22px; } .mt26 { margin-top:26px; } .mt6 { margin-top:6px; } .mt8 { margin-top:8px; }
.mb22 { margin-bottom:22px; } .mb24 { margin-bottom:24px; }
.ml-auto { margin-left:auto; } .ml0 { margin-left:0; }
.flex1 { flex:1; min-width:0; }
.hidden { display:none !important; }
/* Siehe intern: das eingebaute [hidden] wird von jeder Klasse mit eigenem
   display ueberstimmt. Hier vorsorglich derselbe Riegel. */
[hidden] { display:none !important; }

.done-title { font-weight:600; margin:0 0 6px; }
.m0 { margin:0; }

/* --- Zwei-Faktor einrichten -------------------------------------------- */
.qr-box {
  display:grid; place-items:center; padding:14px; margin-bottom:14px;
  /* Weiß, damit die Ruhezone des QR-Codes wirklich hell ist - ein in
     Themefarben invertierter Code wird von vielen Scannern nicht gelesen. */
  background:#fff; border:1px solid var(--bd-card); border-radius:11px;
}
.qr-box img { display:block; border-radius:6px; }
.secret-plain {
  text-align:center; font-family:var(--mono); font-size:15px; letter-spacing:.16em;
  color:var(--ok); background:var(--black); border:1px solid var(--bd-card);
  border-radius:8px; padding:10px; margin:8px 0 18px; word-break:break-all;
}
.center { text-align:center; }

/* Anklickbarer Dateiname in "Von Ihnen gesendet". */
.linkish { color: var(--tx); cursor: pointer; text-decoration: underline; text-decoration-color: var(--bd-muted); text-underline-offset: 3px; }
.linkish:hover { color: var(--link-hover); text-decoration-color: currentColor; }

/* Knopf in Badge-Form, passend zu den Statusbadges daneben. Ein "×" in der
   Ecke war kaum sichtbar und sagte nicht, was es tut. */
.badge-btn {
  display:inline-block; padding:4px 10px; border-radius:5px;
  font-family:var(--mono); font-size:10.5px; font-weight:500; letter-spacing:.08em;
  text-transform:uppercase; white-space:nowrap;
  background:var(--chip); color:var(--tx-2); border:1px solid transparent;
  cursor:pointer; transition:background .12s, color .12s, border-color .12s;
}
.badge-btn:hover:not(:disabled) {
  background:var(--bad-tint); color:var(--bad-text); border-color:var(--bad-bd);
}
.badge-btn:disabled { opacity:.5; cursor:not-allowed; }

/* Bedienbarkeit (14.10.2026): Rückmeldung beim Download, Prüfstatus, Fehlergrund. */
.tile-busy { opacity: .85; pointer-events: none; }
.tile-hint { font-size: 11.5px; line-height: 1.45; color: var(--tx-muted); margin: 8px 0 0; }
.badge .dot { display: inline-block; vertical-align: middle; margin-right: 2px; }
.xfer-err { font-size: 12px; line-height: 1.45; color: var(--bad-text); margin: 6px 0 0; }
.xfer-err[hidden] { display: none; }
.foot-row { flex-wrap: wrap; gap: 10px; }
#btn-xfer-retry { margin-left: auto; }
