From 98bce1b0da675715b2e5482c0ad61ba21135f62f Mon Sep 17 00:00:00 2001
From: Server-Bibliothek <server-bibliothek@lokal>
Date: Di, 04 Aug 2026 07:00:04 +0200
Subject: [PATCH] Add a desktop client that knows what is installed locally

---
 packages/bibliothek-client/src/global.css |  336 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 336 insertions(+), 0 deletions(-)

diff --git a/packages/bibliothek-client/src/global.css b/packages/bibliothek-client/src/global.css
new file mode 100644
index 0000000..644d3a7
--- /dev/null
+++ b/packages/bibliothek-client/src/global.css
@@ -0,0 +1,336 @@
+html,
+body {
+  margin: 0;
+  min-height: 100%;
+  background: var(--md-sys-color-surface, #ffffff);
+  color: var(--md-sys-color-on-surface, #1a1a1a);
+  font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;
+}
+
+.bibliothek-app-rahmen {
+  padding: 24px;
+  /* Dauerhaft Platz für die schwebende Auswahl-Leiste — so verschiebt sich
+     auch am Listenende nichts, wenn sie erscheint. */
+  padding-bottom: 96px;
+  max-width: 1100px;
+  margin: 0 auto;
+}
+
+.kopf {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  gap: 16px;
+  margin-bottom: 16px;
+}
+
+.kopf-aktionen {
+  display: flex;
+  gap: 8px;
+  align-items: center;
+}
+
+.theme-select {
+  min-width: 150px;
+}
+
+.hinweis {
+  background: var(--md-sys-color-secondary-container, #e6e0ec);
+  color: var(--md-sys-color-on-secondary-container, #1d1b20);
+  padding: 12px 16px;
+  border-radius: 8px;
+  margin-bottom: 16px;
+}
+
+/* --- Kompakte Katalog-Liste --- */
+
+.suche {
+  display: block;
+  max-width: 420px;
+  margin-bottom: 12px;
+}
+
+dh-tab {
+  display: block;
+}
+
+/* Inhalt eines nicht gewählten Reiters (die Komponente setzt die Klasse ebenfalls). */
+[slot='tab-content'].hidden {
+  display: none;
+}
+
+.leer {
+  padding: 16px 4px;
+  opacity: 0.7;
+}
+
+.liste {
+  border: 1px solid var(--md-sys-color-outline-variant, #cac4d0);
+  border-radius: 8px;
+  overflow: hidden;
+}
+
+/*
+ * Die Trennlinie sitzt auf der Gruppe (Tool + seine Zusatzinhalte), nicht auf der
+ * einzelnen Zeile — so wirken zusammengehörige Einträge als ein Block.
+ */
+.liste > bibliothek-zeile {
+  display: block;
+  border-bottom: 1px solid var(--md-sys-color-outline-variant, #e7e0ec);
+}
+
+.liste > bibliothek-zeile:last-child {
+  border-bottom: none;
+}
+
+.zeile {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  gap: 16px;
+  padding: 8px 16px;
+}
+
+.zeile-auswahl {
+  display: flex;
+  align-items: center;
+  flex: 0 0 28px;
+}
+
+/* Bei knapper Breite lieber abschneiden als umbrechen — sonst franst die Liste aus. */
+.zeile-info {
+  display: flex;
+  flex-direction: column;
+  min-width: 0;
+  flex: 1 1 auto;
+  overflow: hidden;
+}
+
+.zeile-info > * {
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.warnung {
+  padding: 12px 16px;
+  margin-bottom: 16px;
+  border-radius: 8px;
+  border: 1px solid var(--md-sys-color-error, #b00020);
+  background: var(--md-sys-color-error-container, rgba(176, 0, 32, 0.12));
+  color: var(--md-sys-color-on-error-container, #410002);
+}
+
+/*
+ * Schwebt über dem Inhalt statt ihn zu verschieben: Beim Anhaken soll die Liste
+ * an Ort und Stelle bleiben. Bleibt beim Blättern sichtbar — bei langen Listen
+ * ist die Auswahl sonst aus dem Blick.
+ *
+ * Bewusst eine gewöhnliche erhobene Fläche statt der umgekehrten Farbe: Auf
+ * einer umgekehrten Fläche greift keine der Button-Gestaltungen des Themes,
+ * die Schaltflächen wären dann nicht mehr als solche zu erkennen.
+ */
+.auswahl-leiste {
+  position: fixed;
+  bottom: 24px;
+  left: 50%;
+  transform: translateX(-50%);
+  z-index: 10;
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  padding: 8px;
+  border-radius: var(--md-sys-shape-corner-large, 16px);
+  border: 1px solid var(--md-sys-color-outline-variant, #cac4d0);
+  background: var(--md-sys-color-surface-container-high);
+  color: var(--md-sys-color-on-surface);
+  box-shadow:
+    0 3px 5px -1px rgba(0, 0, 0, 0.2),
+    0 6px 10px 0 rgba(0, 0, 0, 0.14),
+    0 1px 18px 0 rgba(0, 0, 0, 0.12);
+  max-width: calc(100vw - 32px);
+}
+
+.auswahl-anzahl {
+  font-weight: 500;
+}
+
+.zeile-name {
+  font-weight: 600;
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.lizenz-marke,
+.intern-marke {
+  flex-shrink: 0;
+}
+
+.zeile-meta {
+  font-size: 0.85em;
+  opacity: 0.7;
+}
+
+/* Handhabungs-Hinweise stehen unter den Metadaten, etwas zurückgenommen. */
+.zeile-hinweis {
+  font-size: 0.85em;
+  color: var(--md-sys-color-on-surface-variant, #49454f);
+  font-style: italic;
+}
+
+/*
+ * Aktionen in festen Spalten, damit gleichartige Schaltflächen über alle Zeilen
+ * hinweg exakt untereinander stehen. Fehlt eine Aktion, bleibt ihre Spalte leer.
+ * Reihenfolge: Plug-ins | Anleitung | Herunterladen [| Prüfen | Bearbeiten | Löschen]
+ */
+.zeile-aktionen {
+  display: grid;
+  grid-template-columns: 84px 48px;
+  gap: 8px;
+  align-items: center;
+  flex-shrink: 0;
+}
+
+.liste.verwaltung .zeile-aktionen {
+  grid-template-columns: 84px 48px 84px 108px 88px;
+}
+
+.aktion {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  min-width: 0;
+}
+
+.aktion dh-button {
+  max-width: 100%;
+}
+
+/* --- Zusatzinhalte: eingerückt, ohne eigene Trennlinie --- */
+
+.zeile-eingerueckt {
+  padding-left: 44px;
+  padding-top: 4px;
+  padding-bottom: 4px;
+}
+
+.intern-marke {
+  font-size: 0.72em;
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.04em;
+  padding: 2px 8px;
+  border-radius: 999px;
+  background: var(--md-sys-color-primary-container, #ffe4cc);
+  color: var(--md-sys-color-on-primary-container, #4a1e00);
+}
+
+.lizenz-marke {
+  font-size: 0.72em;
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.04em;
+  padding: 2px 8px;
+  border-radius: 999px;
+  background: var(--md-sys-color-tertiary-container, #ffd9a0);
+  color: var(--md-sys-color-on-tertiary-container, #2b1700);
+}
+
+.status-ok {
+  color: var(--md-sys-color-primary, #ff8014);
+}
+
+.status-fehler {
+  color: var(--md-sys-color-error, #b00020);
+}
+
+.status-ausstehend {
+  font-style: italic;
+}
+
+.signatur-gut {
+  color: var(--md-sys-color-primary, #ff8014);
+}
+
+.signatur-unklar {
+  color: var(--md-sys-color-error, #b00020);
+}
+
+.warnhinweis {
+  color: var(--md-sys-color-error, #b00020);
+  opacity: 1;
+}
+
+.anleitung {
+  color: var(--md-sys-color-primary, #ff8014);
+  font-size: 0.9em;
+  text-decoration: none;
+  white-space: nowrap;
+}
+
+.anleitung:hover {
+  text-decoration: underline;
+}
+
+/* --- Formular --- */
+
+dh-card {
+  display: block;
+  margin-bottom: 16px;
+}
+
+[slot='actions'] {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px;
+  align-items: center;
+}
+
+.umzug {
+  margin-top: 24px;
+  padding-top: 16px;
+  border-top: 1px solid var(--md-sys-color-outline-variant, #cac4d0);
+}
+
+.umzug h3 {
+  margin: 0 0 4px;
+  font-size: 1em;
+}
+
+.umzug-aktionen {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px;
+  margin: 12px 0 8px;
+}
+
+.einstellungen-infos {
+  margin: 20px 0 0;
+  display: grid;
+  grid-template-columns: max-content 1fr;
+  gap: 4px 16px;
+  font-size: 0.9em;
+}
+
+.einstellungen-infos dt {
+  opacity: 0.7;
+}
+
+.einstellungen-infos dd {
+  margin: 0;
+  font-family: ui-monospace, 'Cascadia Code', Consolas, monospace;
+  word-break: break-all;
+}
+
+.feldhinweis {
+  display: block;
+  font-size: 0.8em;
+  opacity: 0.7;
+  margin-top: 4px;
+}
+
+.fehler {
+  color: var(--md-sys-color-error, #b00020);
+  margin-right: auto;
+}

--
Gitblit v1.9.3