diff --git a/Icon.png b/Icon.png
new file mode 100644
index 0000000..704bb81
Binary files /dev/null and b/Icon.png differ
diff --git a/web/app/index.html b/web/app/index.html
index b1ee8aa..f6f584b 100644
--- a/web/app/index.html
+++ b/web/app/index.html
@@ -6,16 +6,18 @@
Flaro
-
-
+ Nachgezeichnet war es vorher, und das ging daneben: die Grafik füllt
+ die Fläche, statt klein in der Mitte zu sitzen. Ein Icon, das dem
+ echten nur ähnelt, driftet beim nächsten Entwurf wieder auseinander.
+
+ Bei 16 und 32 Bildpunkten verliert sich die Glasoptik — das liegt am
+ Entwurf, nicht am Export: ein Icon für 1024 Punkte hat dort mehr
+ Feinheit, als ein Browsertab zeigen kann. -->
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/web/app/public/icon-180.png b/web/app/public/icon-180.png
index 4de6600..be218bf 100644
Binary files a/web/app/public/icon-180.png and b/web/app/public/icon-180.png differ
diff --git a/web/app/public/icon-192.png b/web/app/public/icon-192.png
index 3b39a54..b24195f 100644
Binary files a/web/app/public/icon-192.png and b/web/app/public/icon-192.png differ
diff --git a/web/app/public/icon-32.png b/web/app/public/icon-32.png
index 56d3bf0..6fdc951 100644
Binary files a/web/app/public/icon-32.png and b/web/app/public/icon-32.png differ
diff --git a/web/app/public/icon-512.png b/web/app/public/icon-512.png
index 04d96a0..dabc01e 100644
Binary files a/web/app/public/icon-512.png and b/web/app/public/icon-512.png differ
diff --git a/web/app/src/auswahl.ts b/web/app/src/auswahl.ts
index 93a503b..4c4ee7d 100644
--- a/web/app/src/auswahl.ts
+++ b/web/app/src/auswahl.ts
@@ -28,6 +28,20 @@ export type Auswahlfeld = {
setzen: (optionen: Option[]) => void;
};
+/** Das eine offene Auswahlfeld — oder keines.
+ *
+ * **Modulweit, nicht je Feld.** Vorher merkte sich jedes Feld nur seine
+ * eigene Liste; drei Felder nebeneinander liessen sich alle drei aufklappen
+ * und überlagerten einander. Ein Auswahlfeld ist ein Menü, und von denen ist
+ * immer höchstens eines offen — genauso hält es das Kontextmenü.
+ */
+let offenesFeld: { schliessen: () => void } | null = null;
+
+export function alleAuswahlenSchliessen(): void {
+ offenesFeld?.schliessen();
+ offenesFeld = null;
+}
+
export function auswahl(optionen: Option[], vorgabe = ''): Auswahlfeld {
let liste = [...optionen];
let wert = vorgabe;
@@ -56,8 +70,11 @@ export function auswahl(optionen: Option[], vorgabe = ''): Auswahlfeld {
offen?.remove();
offen = null;
knopf.setAttribute('aria-expanded', 'false');
+ if (offenesFeld === steuerung) offenesFeld = null;
}
+ const steuerung = { schliessen };
+
function waehlen(neu: string): void {
const geaendert = neu !== wert;
wert = neu;
@@ -70,6 +87,10 @@ export function auswahl(optionen: Option[], vorgabe = ''): Auswahlfeld {
function oeffnen(): void {
if (offen) { schliessen(); return; }
+ // Erst das andere zu, dann dieses auf.
+ alleAuswahlenSchliessen();
+ offenesFeld = steuerung;
+
const box = document.createElement('div');
box.className = 'auswahl-liste';
box.setAttribute('role', 'listbox');
@@ -172,8 +193,11 @@ export function auswahl(optionen: Option[], vorgabe = ''): Auswahlfeld {
// Kontextmenü. Je Feld registriert und nicht global: es gibt wenige davon,
// und beim Entfernen des Feldes gehen sie mit.
document.addEventListener('click', e => {
- if (offen && !offen.contains(e.target as Node) && e.target !== knopf) schliessen();
+ if (offen && !offen.contains(e.target as Node) && !knopf.contains(e.target as Node)) {
+ schliessen();
+ }
});
+ document.addEventListener('keydown', e => { if (e.key === 'Escape' && offen) schliessen(); });
window.addEventListener('scroll', () => schliessen(), { passive: true, capture: true });
return {
diff --git a/web/app/src/views/admin.ts b/web/app/src/views/admin.ts
index 37a7612..488d0ba 100644
--- a/web/app/src/views/admin.ts
+++ b/web/app/src/views/admin.ts
@@ -999,7 +999,12 @@ function bibliotheksbereich(
knoepfe.appendChild(freigeben);
function freigabeSchreiben(): void {
- freigeben.hidden = aktuell.pendingCount === 0;
+ // **`hidden` reicht hier nicht.** Das Attribut wirkt über
+ // `display: none` mit der Spezifität von Null — `.btn` setzt
+ // `display: inline-flex` und gewinnt. Der Knopf stand deshalb als
+ // „0 Titel freigeben" da, obwohl nichts wartet. `.hidden` trägt ein
+ // `!important` und setzt sich durch.
+ freigeben.classList.toggle('hidden', aktuell.pendingCount === 0);
freigeben.textContent = `${aktuell.pendingCount} Titel freigeben`;
}
freigabeSchreiben();