/* style-room – wird von views/partials/head.ejs geladen
   ============================================================
   Ergänzungen zur Ordneransicht (Vorbild: Mac Finder / Datasite)

     1. (entfallen — Gliederungsziffern)
     2. Eingangsordner und Papierkorb in eigener Farbe
     3. Schnellaktionen und Kategorien je Dokument
     4. Einblendung für das DD-Assessment

   Diese Datei ergänzt public/style.css und verändert dort nichts.
   ============================================================ */

/* ============================================================
   0. Breite der Datenraumansicht
   ------------------------------------------------------------
   public/style.css begrenzt jede Seite mit `.wrap` auf 1280 px. Für
   Fließtext ist das richtig — jenseits von rund 90 Zeichen je Zeile
   findet das Auge den Zeilenanfang nicht mehr. Die Ordneransicht ist
   aber kein Fließtext, sondern eine Tabelle aus kurzen Feldern; dort
   kostet dieselbe Grenze auf einem 1920er Bildschirm rund 600 px, die
   ungenutzt neben der Ansicht stehen bleiben.

   Deshalb gilt hier ein eigenes Maß, und zwar NUR hier: Die Klasse
   „rm-wrap" trägt allein views/room.ejs. Hilfe, Rechtshinweis und
   Datenschutz behalten ihre 1280 px.

   Warum 1680 px und nicht „so breit wie das Fenster":
     · 1920 px abzüglich der 96 px breiten Seitenleiste ergibt 1824 px
       nutzbare Fläche. 1680 px füllen davon 92 % und lassen beidseitig
       eine Handbreit Luft — die Ansicht klebt weder in der Mitte noch
       am Bildschirmrand.
     · Die Spaltenansicht teilt diese Breite auf: zwei feste Spalten zu
       306 px und den Rest für den geöffneten Ordner. Dessen Zeilen
       werden damit rund 1000 px breit. Darin stehen Name links und
       Größe, Zeitpunkt, Art und die drei Symbole rechts — vier
       Haltepunkte auf 1000 px. Wächst die Zeile darüber hinaus, ist
       zwischen Name und Symbolen nur noch Weißraum, und die Zuordnung
       „welches Symbol gehört zu welcher Datei" bricht.
     · Unterhalb von 1680 px greift die Grenze ohnehin nicht: Bei 1440
       und 1600 px nutzt die Ansicht die volle verfügbare Breite.
   ============================================================ */
.wrap.rm-wrap { max-width: 1680px; }

/* ============================================================
   1./2. Eingangsordner und Papierkorb
   ============================================================ */

/* Die Regeln für die Gliederungsziffer (.fcol-idx) standen hier. Sie sind
   entfallen: Die Anwendung setzt vor die Ordnernamen keine eigene Ziffer mehr
   (1 · 2.1 · 3.10). Die Namen tragen ihre Nummer selbst — „01 Allgemeine
   Informationen“ — und die zweite Zählung daneben hat nur verwirrt. Das
   Markup in views/room.ejs ist mit den Regeln zusammen entfallen; hier bleibt
   bewusst kein Rest stehen, der eine Klasse beschreibt, die es nicht gibt. */

/* Eingangsordner: eigenes Symbol in der Akzentfarbe statt im Ordner-Blau. */
.ficon.inbox { color: var(--red-soft); }
.fcol-row.inbox .fcol-name { color: var(--red); }
.fcol-tag.inbox,
.badge.inbox { background: var(--rose-bg); color: var(--red); }
.finder-list tr.inbox-row td { background: #FFFAFA; }
.finder-list tr.inbox-row:hover td { background: #FFF4F4; }
.tree .inbox-mark {
  margin-left: 6px; font-size: 10.5px; font-weight: 600; letter-spacing: .3px;
  color: var(--red); background: var(--rose-bg); border-radius: 4px; padding: 0 5px;
}

/* Papierkorb: eigenes Symbol, gedeckte Marke. Bewusst grau und nicht rot —
   Rot ist in diesem Datenraum die Akzentfarbe des Eingangs und der Schwärzung.
   Der Papierkorb soll auffindbar sein, aber nicht laut. */
.ficon.trash { color: var(--slate); }
.fcol-row.trash .fcol-name { color: var(--grey); }
.fcol-tag.trash,
.badge.trash { background: var(--soft); color: var(--grey); }
.finder-list tr.trash-row td { background: #FCFCFD; }
.finder-list tr.trash-row:hover td { background: #F6F6F9; }
.tree .trash-mark {
  margin-left: 6px; font-size: 10.5px; font-weight: 600; letter-spacing: .3px;
  color: var(--grey); background: var(--soft); border-radius: 4px; padding: 0 5px;
}

/* Liste im Papierkorb (views/papierkorb.ejs). Die beiden Handlungen stehen
   nebeneinander und brechen auf schmalen Geräten untereinander um. */
.korbliste .korb-name { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.korbliste .korb-akt { display: flex; gap: 6px; justify-content: flex-end; flex-wrap: wrap; }
.korbliste .korb-akt form { display: inline; }
/* Die Kurzfassung unter dem Namen ersetzt die Spalten, die auf schmalen
   Geräten wegfallen — sichtbar wird sie deshalb erst dort. */
.korbliste .korb-klein { display: none; }
@media (max-width: 900px) {
  .korbliste .hide-s { display: none; }
  .korbliste .korb-klein { display: block; margin-top: 3px; }
}

/* ============================================================
   3. Kategorien (Tags)
   ============================================================ */

/* Kleine farbige Marke. Feste Palette – frei wählbare Farben machen die
   Dateiliste unlesbar. */
.tagchip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 500; line-height: 1.5;
  padding: 1px 8px; border-radius: 20px; letter-spacing: .2px;
  background: var(--soft); color: var(--grey);
  max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tagchip.c-navy   { background: #E4EAF2; color: var(--navy); }
.tagchip.c-red    { background: var(--rose-bg); color: var(--red); }
.tagchip.c-green  { background: #E1F0E6; color: #1D6B34; }
.tagchip.c-amber  { background: #F8EBD3; color: #855312; }
.tagchip.c-violet { background: #EBE4F4; color: #5B3A86; }
.tagchip.c-slate  { background: var(--soft); color: var(--grey); }
.tagchip-n { font-size: 10.5px; opacity: .65; font-variant-numeric: tabular-nums; }

/* Filterleiste über der Ordneransicht */
.tagbar {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  margin: 0 0 16px; padding: 10px 14px;
  background: #fff; border-radius: var(--radius); box-shadow: var(--shadow-sm);
}
.tagbar-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .7px;
  color: var(--grey); font-weight: 600; margin-right: 4px;
}
a.tagchip.pick { padding: 3px 11px; font-size: 12px; }
a.tagchip.pick:hover { opacity: .82; }
a.tagchip.pick.on { box-shadow: inset 0 0 0 1.5px currentColor; font-weight: 600; }

/* Kategorien am Dokument */
.doctags { display: inline-flex; align-items: center; gap: 5px; flex-wrap: wrap; }

/* Schnellaktionen: Symbole mit Titel-Text, keine breiten Knöpfe. */
.docacts { display: inline-flex; align-items: center; gap: 2px; flex: 0 0 auto; }
.docact {
  display: inline-flex; align-items: center; justify-content: center;
  width: 25px; height: 25px; border-radius: 6px;
  color: var(--slate); flex: 0 0 auto; transition: background .12s, color .12s;
}
.docact:hover { background: var(--bg); color: var(--navy); }
.docact:focus-visible { outline: 2px solid var(--navy); outline-offset: 1px; }
.docact svg { width: 15px; height: 15px; display: block; }

/* „Verfügbar seit" an der Dokumentzeile.
   Sie steht in beiden Ansichten an der Zeile, und trotzdem nie doppelt:
     · ab 961 px zeigt der Datenraum die Spaltenansicht, die kompakte Liste ist
       ausgeblendet (public/style.css) — sichtbar ist dort die Marke;
     · darunter zeigt er die kompakte Liste, deren Spalte „Verfügbar seit"
       zusammen mit Größe und Art über „hide-s" entfällt — sichtbar ist dann
       ebenfalls die Marke.
   Ohne diese Marke stünde auf schmalen Geräten bei keiner Datei mehr, seit
   wann sie verfügbar ist. */
.docsince {
  font-size: 11px; color: var(--grey); font-variant-numeric: tabular-nums;
  white-space: nowrap; flex: 0 0 auto;
}

/* Größe und Art am Dokument. Sie werden nur in der Spaltenansicht ausgegeben
   (views/room.ejs) — in der kompakten Liste stehen beide bereits in eigenen
   Tabellenspalten. Gleiche Schrift und gleicher Grauton wie „Verfügbar seit":
   Die drei Angaben gehören zusammen und sollen die Dateinamen nicht
   überstimmen. */
.docsize, .dockind {
  font-size: 11px; color: var(--grey); white-space: nowrap; flex: 0 0 auto;
  overflow: hidden; text-overflow: ellipsis;
}
.docsize { font-variant-numeric: tabular-nums; }
.dockind { letter-spacing: .3px; }

/* Kompakte Liste (schmale Geräte): Marken links, Aktionen rechts. */
.finder-list td.act {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 8px; flex-wrap: wrap;
}
.finder-list td.act .doctags { order: -1; }

/* Schmale Geräte: feste Spaltenbreiten, damit die Aktionen nicht aus dem
   Bild wandern und der Dateiname sauber abgekürzt wird. */
@media (max-width: 960px) {
  /* Der Dateiname wird begrenzt und abgekürzt, damit die Aktionsspalte
     im Bild bleibt und die Tabelle nicht seitlich davonläuft. */
  .finder-list .finder-name { max-width: 30vw; }
  .finder-list td.act {
    flex-direction: column; align-items: flex-end; gap: 6px;
    padding: 9px 12px; white-space: normal; max-width: 122px;
  }
  /* Vier Schaltflächen im Zweier-Block – nebeneinander wäre die Spalte
     auf einem Telefon zu breit. */
  .finder-list td.act .docacts { flex-wrap: wrap; justify-content: flex-end; max-width: 56px; }
  /* „Verfügbar seit" steht in dieser Ansicht über den Schaltflächen: Die
     Spalte daneben ist hier ausgeblendet, und die Angabe gehört trotzdem an
     jede Datei. `order` hebt sie über die Schaltflächen, ohne die Reihenfolge
     im Markup zu ändern. */
  .finder-list td.act .docsince { order: -2; }
  .finder-list td.act .doctags { flex-wrap: wrap; justify-content: flex-end; }
  .finder-list .tagchip { max-width: 92px; }
}

/* ============================================================
   Spaltenansicht: Dokumentzeile mit Aktionen
   Nur am Breitbild sichtbar – darunter bleibt die kompakte Liste.
   ============================================================ */
@media (min-width: 961px) {
  /* Etwas mehr Breite je Spalte: Nummer, Name und vier Schaltflächen
     brauchen Platz, sonst überlappt es. */
  .fcol { flex-basis: 306px; min-width: 306px; max-width: 306px; }
  .fcol:last-child { flex: 1 1 380px; max-width: none; }

  /* Jede Spalte ist ihr eigener Maßstab. Ob eine Dokumentzeile Platz für
     eine rechte Spalte aus Größe, Zeitpunkt, Art und Symbolen hat, hängt
     nicht an der Fensterbreite, sondern an der Breite DIESER Spalte: Bei
     tiefem Pfad stehen links mehrere feste 306er-Spalten, und der Rest
     kann auch auf einem 1920er Bildschirm schmal ausfallen. Eine
     Fensterabfrage träfe dann die falsche Entscheidung.
     Wo Container-Abfragen fehlen, greift die Regel nicht und es bleibt bei
     der bisherigen gestapelten Darstellung — kein kaputtes Bild. */
  .fcol { container-type: inline-size; container-name: fcol; }

  .fcol-row.doc {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 2px 9px; padding: 5px 8px 5px 12px;
  }
  /* Kennzeichen (V2, S, „Eingang") stehen direkt am Namen, nicht am
     rechten Rand – sonst wirken sie wie ein eigener Eintrag.
     flex-basis 0 am Verweis: so brechen die Schaltflächen auch in einer
     schmalen Spalte nicht in eine zweite Zeile um. */
  .fcol-row.doc .fcol-link { flex: 1 1 0; min-width: 0; }
  .fcol-row.doc .fcol-name,
  .fcol-row.inbox .fcol-name { flex: 0 1 auto; }
  .fcol-row.inbox .fcol-chev { margin-left: auto; }
  .fcol-row.doc:hover { background: #F4F4F7; }
  .fcol-link {
    display: flex; align-items: center; gap: 9px;
    flex: 1 1 auto; min-width: 0; color: inherit;
  }
  /* Kein auto-Rand: der Verweis (flex-grow) schiebt die Schaltflächen an den
     rechten Rand. Ein auto-Rand würde den freien Platz vorab aufbrauchen und
     den Dateinamen unnötig abkürzen. */
  .fcol-row.doc .docacts { opacity: .6; transition: opacity .12s; }
  .fcol-row.doc:hover .docacts,
  .fcol-row.doc:focus-within .docacts { opacity: 1; }
  /* Kategorien in eine eigene zweite Zeile, bündig unter dem Namen –
     so überlagern sie den Dateinamen nicht. */
  .fcol-row.doc .doctags { flex: 1 0 100%; padding-left: 45px; margin-top: 1px; }
  /* „Verfügbar seit" stand hier zuvor in einer EIGENEN Zeile unter dem Namen.
     Damit brauchte jede Datei drei Zeilen: Name, Datum, Schaltflächen — und
     die Liste wurde unnötig hoch. Das Datum steht jetzt in derselben Zeile
     wie die Schaltflächen, unmittelbar links davon.

     Warum das trägt, obwohl die feste Spalte nur 306 px breit ist: Das Datum
     ist ein kurzer, in der Breite berechenbarer Wert (10 Zeichen im Format
     TT.MM.JJJJ). Es bekommt eine feste Breite und schrumpft nicht; der
     Dateiname darüber nimmt den Rest und wird bei Bedarf gekürzt — er trägt
     ohnehin schon eine Kürzung mit Auslassungspunkten. Größe und Art bleiben
     in der schmalen Spalte weg (siehe unten); nur sie hätten hier gefehlt. */
  .fcol-row.doc .docsince {
    flex: 0 0 auto; margin-left: auto; margin-top: 0;
    font-variant-numeric: tabular-nums; white-space: nowrap;
  }
  /* Der Verweis darf die Zeile nicht mehr allein füllen, sonst drückt er das
     Datum in die nächste Zeile. */
  .fcol-row.doc .fcol-link { flex: 1 1 60px; }
  /* Größe und Art bleiben in einer festen 306er-Spalte weg. Sie sind dort
     neu und würden entweder eine dritte Zeile je Datei erzwingen oder den
     Namen zusammenschieben — beides ist schlechter als der Zustand vorher.
     Wo Platz ist, blendet der Container-Block sie wieder ein. */
  .fcol-row.doc .docsize,
  .fcol-row.doc .dockind { display: none; }
}

/* ============================================================
   Spaltenansicht, breite Spalte: eigene Spalte für die Aktionen
   ------------------------------------------------------------
   Der Wunsch des Betreibers: das graue Auge, das Herunterladen und die
   Schwärzung nicht mehr unter dem Dateinamen, sondern rechts neben den
   Angaben zur Datei — in einer eigenen Spalte am rechten Rand.

   Umgesetzt als Container-Abfrage auf .fcol (siehe oben). 560 px ist die
   Schwelle, unter der es nicht mehr aufgeht: 66 px Größe + 84 px Zeitpunkt
   + 46 px Art + rund 106 px für vier Symbole + vier Abstände + Innenrand
   belegen zusammen etwa 362 px. Was übrig bleibt, gehört dem Dateinamen;
   unter 560 px wären das weniger als 200 px und der Name bräche mitten im
   Wort ab — dann ist die gestapelte Darstellung die bessere.

   Die festen Breiten sind der eigentliche Punkt: Sie sind es, die die drei
   Symbole über alle Zeilen hinweg untereinander bündig halten. Dass in jeder
   Zeile gleich viele Symbole stehen, ist gesichert — views/room.ejs gibt
   allen Dokumenten einer Spalte dieselbe Berechtigung (col.parent.perm) mit,
   und die entscheidet in views/partials/docrow.ejs über jedes einzelne
   Symbol. Wer nur Stufe 1 hat, sieht in jeder Zeile genau ein Auge, und zwar
   an derselben Stelle.

   Diese Regeln stehen NACH dem @media-Block darüber: Sie sind gleich scharf
   (Klasse + Klasse), also entscheidet die Reihenfolge. Eine @container-
   Abfrage erhöht die Spezifität ebenso wenig wie eine @media-Abfrage.
   ============================================================ */
@container fcol (min-width: 560px) {
  .fcol-row.doc { gap: 3px 10px; padding: 6px 12px 6px 12px; }
  /* Der Verweis nimmt den ganzen freien Platz und schiebt damit alles
     Übrige nach rechts. flex-basis 0 statt auto: sonst bestimmt die Länge
     des Dateinamens die Spaltenaufteilung, und die Symbole stünden von
     Zeile zu Zeile woanders. */
  .fcol-row.doc .fcol-link { flex: 1 1 0; min-width: 0; }
  .fcol-row.doc .docsize   { display: block; flex: 0 0 66px; padding-left: 0; margin-top: 0; text-align: right; }
  .fcol-row.doc .docsince  { flex: 0 0 84px; padding-left: 0; margin-top: 0; text-align: right; }
  .fcol-row.doc .dockind   { display: block; flex: 0 0 46px; padding-left: 0; margin-top: 0; text-align: right; }
  /* Die Symbolspalte. Kein auto-Rand — der Verweis links schiebt bereits.
     Volle Deckkraft statt der bisherigen 0.6: Eine Spalte, die erst beim
     Überfahren sichtbar wird, ist keine Spalte. Ein zweites Auge sucht man
     sonst zeilenweise. */
  .fcol-row.doc .docacts {
    flex: 0 0 auto; justify-content: flex-end; gap: 2px;
    padding-left: 4px; opacity: 1;
  }
  /* Die Kategorien behalten ihre eigene zweite Zeile, bündig unter dem
     Namen — in der Zeile selbst wäre für sie kein Platz mehr. */
  .fcol-row.doc .doctags { flex: 1 0 100%; padding-left: 45px; margin-top: 2px; }
}

/* ============================================================
   4. Einblendungen (Kategorie-Zuordnung, DD-Assessment)
   Nutzt .modal-veil/.modal aus style.css und ergänzt nur das Nötige.
   ============================================================ */
.modal.modal-wide { max-width: 1040px; max-height: 90vh; }
.modal-head.modal-head-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.modal-x {
  background: none; border: 0; cursor: pointer; padding: 6px; margin: -6px -6px 0 0;
  border-radius: var(--radius-sm); color: var(--grey); line-height: 0; flex: 0 0 auto;
}
.modal-x:hover { background: var(--bg); color: var(--navy); }
.modal-x svg { width: 16px; height: 16px; display: block; }

/* Karten innerhalb einer Einblendung tragen keinen eigenen Schlagschatten. */
.modal-body .card {
  box-shadow: none; border: 1px solid var(--soft); padding: 18px 20px; margin-bottom: 16px;
}
.modal-body .card:last-child { margin-bottom: 0; }
.modal-body .page-head { margin-bottom: 16px; }
.modal-body .stat { box-shadow: none; border: 1px solid var(--soft); padding: 12px 18px; min-width: 128px; }
.modal-body .stat .n { font-size: 22px; }

/* Zuordnung der Kategorien: Auswahl in zwei Spalten, Marke statt Klartext. */
.modal-body .checkgrid .checkitem { align-items: center; }

/* ============================================================
   5. Kurzer Datenstatus je Ordner
   ------------------------------------------------------------
   Bewusst nur ein Punkt von 7 px. Kein Balken, keine Marke, keine
   Ampel über die halbe Zeile: In einer Liste mit dreißig Ordnern
   wäre alles Größere lauter als die Dateinamen selbst.

   Der Punkt darf die Zeilenhöhe NICHT verändern. Deshalb 7 px
   Kantenlänge (die Zeilen sind rund 19–22 px hoch), flex: 0 0 auto
   und vertical-align: middle — er wächst nie über die Schriftzeile
   hinaus und schiebt nichts auseinander.

   Die Farben stammen ausnahmslos aus der vorhandenen IHC-Palette
   (siehe :root in style.css und die Kategorie-Farben oben). Es gibt
   keine neue Farbwelt und keine Signalfarben.
   ============================================================ */
.fstat {
  display: inline-block; vertical-align: middle; flex: 0 0 auto;
  width: 7px; height: 7px; border-radius: 50%;
  margin: 0 0 0 7px;
  background: var(--line);
  /* Hebt den Punkt auch auf farbigem Zeilenhintergrund sauber ab. */
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .75);
}
.fstat-offen        { background: var(--line); }
.fstat-angefordert  { background: #855312; }   /* Bernstein, wie .tagchip.c-amber  */
.fstat-teilweise    { background: #7FA0C4; }   /* Ordnerblau, wie .ficon.folder    */
.fstat-vollstaendig { background: #1D6B34; }   /* Grün, wie .tagchip.c-green       */
.fstat-geprueft     { background: var(--navy); }
/* „entfällt": bewusst als leerer Ring — nichts zu tun ist kein Zustand,
   der Farbe verdient. */
.fstat-entfaellt    { background: transparent; box-shadow: inset 0 0 0 1.5px var(--line); }

/* Status samt Bemerkung in der Fußzeile des geöffneten Ordners. */
.fstat-line { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.fstat-line .fstat { margin-left: 0; }

/* Nur für Vorleseprogramme: Ein reiner Farbpunkt ist für sie sonst nicht
   vorhanden. Das Attribut title allein wird nicht zuverlässig vorgelesen. */
.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;
}

/* ============================================================
   6. Ziehen und Ablegen
   ------------------------------------------------------------
   Während des Ziehens muss unmissverständlich sein, WO die Datei
   landet. Deshalb bekommt genau ein Ziel — das unter dem Zeiger —
   die Hervorhebung, und zwar deutlich: Rahmen, Fläche und ein
   Hinweistext. Alle anderen Ziele bleiben unverändert.
   ============================================================ */

/* Solange etwas über dem Fenster schwebt, tritt der Rest zurück. Das
   allein sagt schon: „Jetzt geht es ums Ablegen." */
.dd-aktiv .finder { outline: 2px dashed var(--line); outline-offset: 3px; }

/* Das aktive Ziel. position: relative wird gebraucht, damit der
   Hinweistext daran hängen kann. */
[data-drop].dd-ziel,
[data-drop-root].dd-ziel {
  position: relative;
  background: var(--rose-bg) !important;
  box-shadow: inset 0 0 0 2px var(--red-soft);
  border-radius: 6px;
  color: var(--navy);
}
[data-drop].dd-ziel .fcol-name,
[data-drop].dd-ziel .finder-name { color: var(--red); }
/* Eine ganze Spalte bzw. Fläche als Ziel: gestrichelter Rahmen statt
   voller Fläche — sonst leuchtet die halbe Ansicht rot. */
.fcol.dd-ziel,
.finder-empty.dd-ziel,
div[style*="overflow-x"].dd-ziel {
  background: #FFF7F7 !important;
  box-shadow: inset 0 0 0 2px var(--red-soft);
}
/* Die Zeile darunter darf beim Überfahren nicht auch noch aufleuchten. */
.dd-aktiv .fcol-row:hover { background: none; }

/* ---- Verschieben innerhalb des Datenraums ----
   Die Hervorhebung des Ziels teilt sich mit dem Hochladen darüber; sie soll
   für beide Vorgänge gleich aussehen. Eigen sind nur diese drei Dinge. */

/* Was gezogen werden kann, sagt es beim Überfahren — mit dem Zeiger, nicht
   mit einem Symbol in der Zeile. Eine Ansicht mit 60 Zeilen verträgt keinen
   Griff an jeder davon. */
[data-move-art] { cursor: grab; }
[data-move-art]:active { cursor: grabbing; }
/* Die gezogene Zeile tritt zurück, solange sie unterwegs ist. */
.dd-aktiv [data-move-art]:active { opacity: .55; }

/* Die Rückmeldung nach dem Verschieben: schmale Zeile unten links. Bewusst
   auf der anderen Seite als die Übertragungsanzeige (.ddpanel, rechts unten) —
   beides kann gleichzeitig dastehen, wenn während einer laufenden Übertragung
   verschoben wird. */
.vs-melder {
  position: fixed; z-index: 70; left: 18px; bottom: 18px;
  display: flex; align-items: center; gap: 10px;
  max-width: min(460px, calc(100vw - 36px));
  background: var(--navy); color: #fff;
  font-size: 13px; line-height: 1.45;
  padding: 10px 14px; border-radius: 8px;
  box-shadow: var(--shadow-sm);
}
.vs-melder[hidden] { display: none; }
/* Ein Fehler bleibt stehen, bis er weggeklickt wird — deshalb bekommt er die
   auffällige Farbe UND den Schließknopf. */
.vs-melder.fehler { background: var(--red); }
.vs-melder-x {
  flex: 0 0 auto; background: none; border: 0; cursor: pointer;
  color: #fff; font-size: 17px; line-height: 1; padding: 0 2px; opacity: .85;
}
.vs-melder-x:hover { opacity: 1; }

/* Hinweis „Hier ablegen" am aktiven Ziel. Wird von app-room.js gesetzt. */
.dd-fahne {
  position: absolute; z-index: 60; pointer-events: none;
  background: var(--navy); color: #fff;
  font-size: 11.5px; font-weight: 500; letter-spacing: .2px;
  padding: 3px 9px; border-radius: 20px; white-space: nowrap;
  box-shadow: var(--shadow-sm);
  max-width: 300px; overflow: hidden; text-overflow: ellipsis;
}

/* ---- Fortschritt der Übertragung ----
   Rechts unten, klein, immer sichtbar. Bewusst KEIN Modal: Der Nutzer
   soll währenddessen weiterlesen und weiterziehen können. */
.ddpanel {
  position: fixed; right: 20px; bottom: 20px; z-index: 180;
  width: 360px; max-width: calc(100vw - 32px); max-height: 62vh;
  display: flex; flex-direction: column;
  background: #fff; border-radius: var(--radius); box-shadow: var(--shadow);
  border: 1px solid var(--soft); overflow: hidden;
}
.ddpanel-head {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px; border-bottom: 1px solid var(--soft); background: #FCFCFD;
}
.ddpanel-head h3 { margin: 0; font-size: 13.5px; font-weight: 600; color: var(--navy); flex: 1; min-width: 0; }
.ddpanel-head .sub { display: block; font-size: 11.5px; font-weight: 400; color: var(--grey); }
.ddpanel-x {
  background: none; border: 0; cursor: pointer; padding: 5px; border-radius: var(--radius-sm);
  color: var(--grey); line-height: 0; flex: 0 0 auto;
}
.ddpanel-x:hover { background: var(--bg); color: var(--navy); }
.ddpanel-list { overflow-y: auto; padding: 4px 0; }
.ddrow { padding: 7px 14px; font-size: 13px; }
.ddrow + .ddrow { border-top: 1px solid #F4F4F7; }
.ddrow-top { display: flex; align-items: baseline; gap: 8px; }
.ddrow-name {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink);
}
.ddrow-state { flex: 0 0 auto; font-size: 11.5px; color: var(--grey); font-variant-numeric: tabular-nums; }
.ddrow.ok .ddrow-state { color: #1D6B34; }
.ddrow.err .ddrow-state { color: var(--red); }
.ddrow-msg { font-size: 11.5px; color: var(--red); margin-top: 2px; }
.ddrow-sub { font-size: 11.5px; color: var(--grey); margin-top: 2px; }
/* Balken je Datei. 3 px hoch – er soll den Namen nicht überstimmen. */
.ddbar { height: 3px; border-radius: 2px; background: var(--soft); margin-top: 5px; overflow: hidden; }
.ddbar > span { display: block; height: 100%; width: 0; background: var(--navy); transition: width .25s; }
.ddrow.run .ddbar > span { width: 100%; background: var(--red-soft); animation: ddpuls 1.1s ease-in-out infinite; }
.ddrow.ok  .ddbar > span { width: 100%; background: #1D6B34; }
.ddrow.err .ddbar > span { width: 100%; background: var(--red); }
@keyframes ddpuls { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
/* Wer Bewegung abbestellt hat, bekommt keine. */
@media (prefers-reduced-motion: reduce) {
  .ddrow.run .ddbar > span { animation: none; opacity: .7; }
  .ddbar > span { transition: none; }
}
.ddpanel-foot {
  border-top: 1px solid var(--soft); background: #FCFCFD; padding: 9px 14px;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.ddpanel-foot .small { flex: 1; min-width: 0; }
/* Begründung, warum die Anzeige nach einem Fehler stehen bleibt, statt von
   selbst zu verschwinden. Sie bekommt eine eigene Zeile unter Zusammenfassung
   und Knopf – als dritter Baustein daneben gequetscht wäre sie unlesbar.
   „flex: 1 0 100%" erzwingt den Umbruch, den .ddpanel-foot mit flex-wrap
   ohnehin zulässt. Steht NACH `.ddpanel-foot .small`, weil die Zeile beide
   Klassen trägt und die spätere, gleich scharfe Regel gewinnt. */
.ddpanel-foot .ddpanel-note {
  flex: 1 0 100%; line-height: 1.4; color: var(--grey);
}

@media (max-width: 520px) {
  .ddpanel { right: 8px; left: 8px; bottom: 8px; width: auto; }
}

/* Der Punkt gehört zum Ordnernamen und soll unmittelbar dahinter stehen, nicht
   am rechten Rand der Spalte — sonst liest er sich wie eine eigene Spalte und
   verliert den Bezug zum Ordner. In der Spaltenansicht wächst .fcol-name
   normalerweise über die freie Breite; steht ein Statuspunkt in der Zeile,
   hört der Name mit seinem Text auf und das Winkelzeichen rückt stattdessen
   nach rechts. In der kompakten Liste steht der Punkt ohnehin am Namen. */
@media (min-width: 961px) {
  .fcol-row:has(> .fstat) .fcol-name { flex: 0 1 auto; }
  .fcol-row:has(> .fstat) .fcol-chev { margin-left: auto; }
}

/* ==========================================================================
   Anforderungsliste (IRL) — views/irl.ejs
   --------------------------------------------------------------------------
   Warum keine Tabelle: Die Positionstexte des Kunden sind bis zu sechs Zeilen
   lang („Übersicht nach Standorten und Arzten: Schwerpunkt, …"). In einer
   Tabelle mit fester Spaltenbreite laufen sie entweder aus dem Bild oder
   werden abgeschnitten — beides ist bei einer Anforderungsliste untragbar,
   denn der Wortlaut IST die Anforderung. Jede Zeile ist deshalb ein Raster
   mit minmax(0, 1fr) in der Textspalte: Der Text bricht um, die Zeile wächst
   nach unten, und in keiner Breite entsteht seitlicher Überlauf.

   Diese Regeln stehen in style-room.css und nicht in einer eigenen Datei,
   damit views/partials/head.ejs nur eine einzige neue Zeile braucht (die für
   app-irl.js). style-room.css wird nach style-nav.css geladen; gleich
   spezifische Regeln von dort würden hier gewinnen — deshalb tragen alle
   Klassen das Präfix „irl-" und kollidieren mit nichts.
   ========================================================================== */

.irl-notice { margin-bottom: 18px; }

.irl-kopf {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 12px; flex-wrap: wrap;
}
.irl-kopf-titel { margin: 0; }

/* Zählzeile. Die Trennpunkte sind Schmuck und werden beim Umbruch unsichtbar,
   damit keine Zeile mit einem Punkt beginnt. */
.irl-zaehlzeile {
  margin: 14px 0 0; display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 4px 8px; font-size: 14px;
}
.irl-zaehlzeile .irl-punkt { color: var(--line); }
.irl-z { white-space: nowrap; }
.irl-z.irl-offen { color: var(--red); }
.irl-z.irl-teilweise { color: #8a5a00; }
.irl-z.irl-vorhanden { color: var(--green); }
.irl-z.irl-nr { color: var(--grey); }

/* Statusfarben als Marke. „Teilweise" bekommt einen eigenen Ton: Mit Grau
   wäre es von „nicht relevant" nicht zu unterscheiden, und beides bedeutet
   etwas völlig anderes. */
.badge.irl-offen { background: var(--rose-bg); color: var(--red); }
.badge.irl-teilweise { background: #FBEEDA; color: #8a5a00; }
.badge.irl-vorhanden { background: var(--green-bg); color: var(--green); }
.badge.irl-nr { background: var(--soft); color: var(--grey); }

/* ---------- Filter ---------- */
.irl-filterkarte { padding-top: 16px; padding-bottom: 16px; }
.irl-filter { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 18px; }
.irl-nuroffen { display: inline-flex; align-items: center; gap: 8px; }
/* Der eingeschaltete Filter sieht anders aus als der ausgeschaltete — sonst
   bliebe unklar, ob man ihn gerade setzt oder aufhebt. */
.irl-nuroffen.an { background: var(--red); }
.irl-nuroffen.an:hover { background: var(--red-soft); }
.irl-filterform {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 0;
}
/* Ohne width:auto greift die allgemeine Regel select { width: 100% } aus
   style.css: Jedes Auswahlfeld nähme dann eine eigene Zeile ein, und aus einer
   Filterzeile würde ein Formular über vier Zeilen. */
.irl-filterform label { margin: 0; font-size: 13px; color: var(--slate); }
.irl-filterform select { width: auto; min-width: 9rem; max-width: 100%; }
.irl-filterhinweis { margin: 10px 0 0; }

/* ---------- KI-Abgleich ---------- */
.irl-kiknoepfe { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.irl-kiknoepfe form { margin: 0; }

/* ---------- Eine Position ---------- */
.irl-zeile {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr) 22rem;
  gap: 10px 18px;
  padding: 14px 0;
  border-top: 1px solid var(--soft);
  align-items: start;
}
.irl-gruppe .irl-zeile:first-of-type { border-top: 0; }
.irl-spaltenkopf {
  padding: 6px 0; border-top: 0; font-size: 12px; letter-spacing: .3px;
  text-transform: uppercase; color: var(--slate);
}
.irl-c-nr { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.irl-nr { font-weight: 600; color: var(--navy); }
.irl-prio { align-self: flex-start; }
/* min-width: 0 ist die eigentliche Absicherung gegen Überlauf: Ein Rasterfeld
   ist standardmäßig mindestens so breit wie sein längstes unteilbares Wort. */
.irl-c-text { min-width: 0; }
.irl-text {
  margin: 0; line-height: 1.5;
  overflow-wrap: anywhere; word-break: break-word; hyphens: auto;
}
.irl-marken { margin: 8px 0 0; display: flex; flex-wrap: wrap; gap: 6px; }
.irl-nurlesen {
  margin: 0; color: var(--slate); font-size: 14px;
  overflow-wrap: anywhere; white-space: pre-wrap;
}

/* ---------- Arbeitsspalte: Status und Kommentar ---------- */
.irl-c-arbeit { min-width: 0; }
.irl-statusform { margin: 0; display: flex; flex-direction: column; gap: 8px; }
.irl-statusform select, .irl-statusform textarea { width: 100%; max-width: 100%; }
.irl-statusform textarea { resize: vertical; font-size: 14px; }
.irl-statuswahl { font-weight: 500; }
.irl-statuswahl.irl-offen { border-color: var(--rose); }
.irl-statusfuss { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.irl-melder { min-height: 1em; }

/* ---------- Bearbeiten ---------- */
.irl-bearbeiten { margin-top: 10px; }
.irl-bearbeiten > summary {
  cursor: pointer; font-size: 13px; color: var(--slate); width: fit-content;
}
.irl-bearbeiten > summary:hover { color: var(--navy); }
.irl-editform { margin: 10px 0 0; display: flex; flex-direction: column; gap: 8px; }
.irl-editform textarea { width: 100%; resize: vertical; }
.irl-editreihe { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.irl-editreihe > span { min-width: 0; }
.irl-editreihe label { display: block; margin: 0 0 3px; font-size: 13px; color: var(--slate); }
.irl-editreihe select { width: auto; min-width: 8rem; max-width: 100%; }
.irl-editknoepfe { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.irl-editknoepfe form { margin: 0; }
.irl-editknoepfe .btn.small.ghost { display: inline-flex; align-items: center; gap: 4px; }

/* ---------- Vorschlag der KI ---------- */
.irl-vorschlag {
  margin-top: 10px; padding: 10px 12px; border-left: 3px solid var(--line);
  background: var(--bg); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.irl-vorschlag p { margin: 6px 0 0; overflow-wrap: anywhere; }
.irl-vorschlag-kopf { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.irl-vorschlag-kopf form { margin: 0; }

/* ---------- Anlegen und Kategorien ---------- */
.irl-neu { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; }
.irl-neu > div { min-width: 0; }
.irl-neu-text { flex: 1 1 22rem; }
.irl-neu textarea { width: 100%; resize: vertical; }
.irl-neu label, .irl-katform label { display: block; margin: 0 0 3px; font-size: 13px; color: var(--slate); }
.irl-katreihe { display: flex; flex-wrap: wrap; gap: 26px; }
.irl-katform { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; margin: 0; }
.irl-katform input, .irl-katform select { width: auto; min-width: 12rem; max-width: 100%; }
.irl-neu > div > select { width: auto; min-width: 10rem; max-width: 100%; }

/* ---------- Schmalere Bildschirme ----------
   Ab hier reicht die Breite für drei Spalten nicht mehr. Zuerst rutscht die
   Arbeitsspalte unter den Text, dann fällt auch die Nummernspalte weg. Die
   Spaltenüberschrift verschwindet dabei: Sie stünde sonst über etwas, das
   nicht mehr in Spalten steht. */
@media (max-width: 1180px) {
  /* Die Nummernspalte bleibt breit genug für die Prioritätsmarke: Bei 3.5 rem
     ragte „Medium" in die Textspalte und las sich wie ein Teil der
     Anforderung. */
  .irl-zeile { grid-template-columns: 5.5rem minmax(0, 1fr); }
  .irl-c-arbeit { grid-column: 2; }
  .irl-spaltenkopf { display: none; }
}
@media (max-width: 560px) {
  .irl-zeile { grid-template-columns: minmax(0, 1fr); }
  .irl-c-arbeit { grid-column: 1; }
  /* Eine Spalte: Nummer und Priorität stehen nebeneinander in einer Kopfzeile
     über dem Text, nicht mehr untereinander. */
  .irl-c-nr { flex-direction: row; align-items: center; gap: 8px; }
  .irl-filter { align-items: stretch; }
  .irl-filterform { width: 100%; }
  /* Beschriftung auf eigene Zeile: Sonst reißt der Umbruch das Paar aus
     Beschriftung und Auswahlfeld auseinander, und „Priorität" steht neben
     dem Auswahlfeld für den Status. */
  .irl-filterform label { flex: 1 1 100%; }
  .irl-filterform select { flex: 1 1 8rem; width: 100%; min-width: 0; }
  .irl-filterform button, .irl-filterform .btn { flex: 0 0 auto; }
  .irl-katreihe { gap: 18px; }
  .irl-katform input, .irl-katform select { min-width: 0; width: 100%; }
  .irl-neu > div > select { width: 100%; min-width: 0; }
  .irl-katform > div { flex: 1 1 100%; }
}

/* ============================================================
   Datenraum-Export in der Kopfzeile der Datenraumansicht
   ------------------------------------------------------------
   Ein Formular mit einem einzigen Knopf (views/room.ejs). „.page-head" richtet
   seine Kinder an der Grundlinie aus (align-items: flex-end) und darf umbrechen;
   auf schmalen Geräten rutscht der Knopf damit unter die Überschrift statt neben
   sie. Deshalb hier nur zwei Dinge: Symbol und Beschriftung als Paar halten und
   den Knopf ab 560 px die volle Breite nehmen lassen — sonst steht er einzeln und
   halb so breit unter einem Titel, der über die ganze Zeile läuft.
   ============================================================ */
.rm-ausfuhr { flex: 0 0 auto; }
.rm-ausfuhr .btn {
  display: inline-flex; align-items: center; gap: 8px;
  white-space: nowrap;
}
.rm-ausfuhr .btn svg { flex: 0 0 auto; }
@media (max-width: 560px) {
  .rm-ausfuhr { flex: 1 1 100%; }
  .rm-ausfuhr .btn { width: 100%; justify-content: center; }
}

/* ==========================================================================
   Ordneraktionen im Datenraum — Kontextmenü und Dreipunktmenü
   --------------------------------------------------------------------------
   Rechtsklick auf eine Ordnerzeile oder auf den leeren Bereich einer Spalte
   öffnet ein kleines Menü (views/room.ejs, public/app-room.js). Alles hier
   erscheint ausschließlich mit Verwaltungsrecht — ohne es steht kein einziges
   dieser Elemente im HTML, und die Ansicht ist Zeichen für Zeichen dieselbe
   wie zuvor.

   Warum die drei Punkte und kein „+" am Spaltenkopf: Auf einem Tablet gibt es
   keinen Rechtsklick, und ein „+" böte allein das Anlegen an — Umbenennen und
   Löschen blieben dort unerreichbar. Die drei Punkte öffnen dasselbe Menü an
   derselben Zeile; es gibt damit eine Bedienung und einen Pfad im Skript.
   ========================================================================== */

/* Hülle um Ordnerzeile und Knopf in der Spaltenansicht. Der Verweis selbst
   bleibt unangetastet (.fcol-row); der Knopf liegt darüber, weil ein Knopf
   INNERHALB eines Verweises kein gültiges HTML wäre. */
.kx-zeile { position: relative; }
.kx-zeile .kx-dots {
  position: absolute; right: 9px; top: 50%; transform: translateY(-50%);
}
/* Platz für den Knopf, damit der Ordnername nicht darunter läuft. */
.kx-zeile > .fcol-row { padding-right: 32px; }

.kx-dots {
  flex: 0 0 auto; background: none; border: 0; cursor: pointer;
  padding: 3px 4px; border-radius: var(--radius-sm); line-height: 0;
  color: var(--grey); opacity: .5; transition: opacity .12s, background .12s;
}
.kx-dots svg { display: block; width: 15px; height: 15px; }
.kx-dots:hover, .kx-dots:focus-visible { opacity: 1; background: var(--soft); color: var(--navy); }
.kx-zeile:hover .kx-dots, .kx-zeile:focus-within .kx-dots { opacity: 1; }
/* Auf Geräten ohne Zeigegerät gibt es kein „Überfahren": Dort steht der Knopf
   dauerhaft sichtbar da — er ist genau für diesen Fall der zweite Weg. */
@media (hover: none) {
  .kx-dots { opacity: .85; }
}

/* Das Menü selbst. Absolut zur Seite (nicht fest zum Fenster): Es wird beim
   Blättern ohnehin geschlossen, und so wandert es beim Öffnen nicht. */
.kx-menu {
  position: absolute; z-index: 260; min-width: 208px; max-width: 280px;
  background: #fff; border-radius: var(--radius-sm);
  box-shadow: 0 12px 32px rgba(0,24,54,.20); border: 1px solid var(--soft);
  padding: 5px; display: flex; flex-direction: column; gap: 1px;
}
.kx-item {
  display: flex; align-items: center; gap: 9px; width: 100%;
  background: none; border: 0; cursor: pointer; text-align: left;
  font: inherit; font-size: 13.5px; color: var(--ink);
  padding: 7px 10px; border-radius: 6px; line-height: 1.3;
}
.kx-item:hover, .kx-item:focus-visible { background: var(--bg); color: var(--navy); }
.kx-item .kx-ico { flex: 0 0 auto; line-height: 0; color: var(--slate); }
.kx-item .kx-ico svg { display: block; width: 14px; height: 14px; }
/* Ein Eintrag, der nicht geht, verschwindet nicht — er sagt, warum
   (Zeile .kx-note darunter). */
.kx-item-info { color: var(--grey); cursor: default; opacity: .6; }
.kx-item-info:hover { background: none; color: var(--grey); }
.kx-note {
  font-size: 11.5px; line-height: 1.4; color: var(--grey);
  padding: 2px 10px 7px; max-width: 260px;
}

/* Die Einblendung zum Anlegen und Umbenennen. Sie benutzt .modal-veil/.modal
   aus public/style.css und ergänzt nur die Felder. */
.modal.kx-modal { max-width: 460px; }
.kx-feld { margin: 0 0 14px; }
.kx-feld:last-child { margin-bottom: 0; }
.kx-feld label {
  display: block; font-size: 12.5px; font-weight: 600; color: var(--navy);
  margin: 0 0 5px; letter-spacing: .2px;
}
.kx-feld input { width: 100%; }
.kx-feld p { margin: 5px 0 0; }

/* Die Hinweiszeile im Fuß der Ordneransicht. Sie bricht auf schmalen Geräten
   in eine eigene Zeile, statt den Fuß zu sprengen. */
.finder-foot .kx-hint { flex: 1 1 100%; line-height: 1.4; }
@media (max-width: 560px) {
  .kx-menu { min-width: 176px; max-width: calc(100vw - 16px); }
}

/* ---------------------------------------------------------------------------
   Verzeichnis herunterladen (views/room.ejs, Kopf des Datenraums)

   Zwei Wege für dieselbe Sache: PDF zum Abheften, CSV zum Weiterverarbeiten.
   Sie stehen als EIN Element zusammen, damit die Kopfzeile nicht in drei
   gleichrangige Knöpfe zerfällt.
   --------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   Die beiden Ausfuhren in der Kopfzeile: Index und ZIP
   --------------------------------------------------------------------------
   Sie standen an zwei Enden derselben Zeile, weil sie zu verschiedenen Zeiten
   dazugekommen sind — der Betreiber wollte sie beieinander haben. Eine Gruppe
   ganz rechts, beide klein, beide mit Zeichen. Was sie ausfuehrlich bedeuten,
   steht im title und in der Rueckfrage; die Kopfzeile traegt schon Raumname,
   Kennung und Marke.
   -------------------------------------------------------------------------- */
.rm-kopfaktionen {
  display: flex; align-items: center; gap: 8px;
  margin-left: auto; flex: 0 0 auto;
}

/* Index und CSV sind EIN Weg in zwei Formaten. Deshalb ohne Luecke
   aneinander, mit gemeinsamer Rundung nach aussen — das sagt der Blick,
   bevor irgendein Wort gelesen wird. */
.rm-verzeichnis { display: inline-flex; align-items: center; }
.rm-verzeichnis .btn { display: inline-flex; align-items: center; gap: 7px; }
.rm-vz-pdf { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.rm-verzeichnis-csv {
  padding-left: 9px; padding-right: 9px;
  border-top-left-radius: 0; border-bottom-left-radius: 0;
  margin-left: -1px;
}

@media (max-width: 560px) {
  .rm-kopfaktionen { flex: 1 1 100%; margin-left: 0; }
}
