Workspace: Zurueck-Knopf hochwertiger, auf der Startseite entfernt

Zwei Rueckmeldungen umgesetzt.

1. Auf der Startseite gibt es den Knopf jetzt gar nicht mehr im
   Dokument. Vorher erschien er dort, sobald man von einer anderen
   Workspace-Seite kam -- aber die Startseite IST die oberste Ebene, ein
   "davor" gibt es nicht.

2. Aussehen: statt des Textzeichens "<-" jetzt ein echtes SVG-Winkel-
   symbol, Pillenform, und ein Verlaufsrahmen.

   Wichtig dabei: Die Fuellung ist DECKEND. Beim ersten Versuch war sie
   halbtransparent, dadurch schien der Rahmenverlauf durch die ganze
   Flaeche und der Knopf sah aus wie eine Hauptaktion -- genau das soll
   er nicht. Jetzt bleibt vom Verlauf nur der 1px schmale Rand sichtbar.

   Ruhezustand: dunkle Pille, feine Stahlkante, gedaempfter Text.
   Ueberfahren: Cyan-Violett-Rand, heller Text, weicher Schein, und der
   Pfeil rueckt zwei Pixel nach links -- die Bewegung sagt die Richtung
   ohne zusaetzlichen Text. Bei prefers-reduced-motion faellt sie weg.

Geprueft: Start -> kein Knopf; Aufgaben -> "Zurueck", fuehrt zurueck;
Personen direkt aufgerufen -> "Uebersicht". Keine Konsolenfehler.

Nur statische Dateien, kein Neustart noetig.
This commit is contained in:
2026-08-28 00:40:19 +02:00
parent 75d05d05d2
commit d3212a3f60
8 changed files with 139 additions and 21 deletions
+68
View File
@@ -0,0 +1,68 @@
/* ===================================================================
Gemeinsames Verhalten der Kopfleiste: Zurück-Knopf und Abmelden.
Liegt bewusst in einer eigenen Datei. Vorher stand das Abmelden in
jeder Seitendatei noch einmal -- fünfmal derselbe Block, fünfmal eine
Stelle zum Vergessen, wenn sich etwas ändert.
=================================================================== */
(() => {
'use strict';
const START = '/workspace/start.html';
/* Gibt es eine sinnvolle vorherige Seite INNERHALB des Workspace?
Blindes history.back() reicht nicht: Wer die Adresse direkt eingibt
oder gerade von der Anmeldung kommt, landet damit außerhalb des
Workspace oder wieder im Anmeldeformular. Deshalb wird zuerst
geprüft, woher der Aufruf kam. */
function hatVorherigeSeite() {
if (!document.referrer) return false;
let u;
try { u = new URL(document.referrer); } catch { return false; }
if (u.origin !== location.origin) return false;
if (!u.pathname.startsWith('/workspace/')) return false;
/* Die Anmeldeseite ist kein sinnvolles Ziel -- wer angemeldet ist,
würde dort sofort wieder weitergeleitet. */
if (u.pathname === '/workspace/' || u.pathname.endsWith('/index.html')) return false;
/* Gleiche Seite heißt: neu geladen, nicht hergekommen. */
if (u.pathname === location.pathname) return false;
return true;
}
/* Die Startseite hat den Knopf gar nicht erst im Dokument -- dort gibt
es kein "davor". Deshalb genügt hier die Prüfung, ob er existiert. */
const knopf = document.getElementById('zurueck');
if (knopf) {
const beschriftung = knopf.querySelector('.zurueck-knopf__text');
if (hatVorherigeSeite()) {
knopf.hidden = false;
knopf.addEventListener('click', () => {
/* history.back() statt eines festen Ziels: Es führt wirklich
dorthin zurück, wo man war -- samt Bildlaufposition. Nur wenn
es keine Historie gibt, wird ersatzweise umgeleitet. */
if (history.length > 1) history.back();
else location.assign(START);
});
} else {
/* Kein Verlauf, aber wir sind in einem Unterbereich: dann wenigstens
ein Weg zur Übersicht. */
knopf.hidden = false;
if (beschriftung) beschriftung.textContent = 'Übersicht';
knopf.addEventListener('click', () => location.assign(START));
}
}
const abmelden = document.getElementById('abmelden');
if (abmelden) {
abmelden.addEventListener('click', async () => {
abmelden.disabled = true;
try {
await fetch('/workspace/api/abmelden', {
method: 'POST', credentials: 'same-origin',
});
} catch { /* Auch ohne Antwort weiterleiten -- das Cookie läuft ohnehin ab. */ }
location.assign('/workspace/');
});
}
})();
+42 -11
View File
@@ -39,26 +39,57 @@ body.start {
.kopfleiste .marke { margin: 0; font-size: .72rem; }
/* Zurück-Knopf. Steht ganz links, weil dort jeder ihn erwartet -- gleiche
Stelle wie im Browser. Bleibt verborgen (hidden), wenn es nichts gibt,
wohin er führen könnte; das entscheidet kopf.js. */
Stelle wie im Browser. Auf der Startseite gibt es ihn gar nicht: Dort
ist kein "davor", und ein Knopf, der nichts tut, ist schlimmer als
keiner. Auf den übrigen Seiten entscheidet kopf.js, ob er erscheint. */
.zurueck-knopf {
flex: 0 0 auto;
padding: 7px 13px;
background: rgba(255, 255, 255, .045);
border: 1px solid var(--rand);
border-radius: 9px;
display: inline-flex; align-items: center; gap: 7px;
padding: 8px 15px 8px 12px;
/* Verlaufsrahmen: Die Füllung ist DECKEND, dadurch bleibt vom unteren
Verlauf nur der 1px schmale Rand sichtbar. Wäre sie durchsichtig,
schiene der Rahmenverlauf durch die ganze Fläche und der Knopf sähe
aus wie eine Hauptaktion -- das soll er gerade nicht. */
background:
linear-gradient(180deg, #151c28, #10161f) padding-box,
linear-gradient(180deg, rgba(158, 196, 230, .40), rgba(158, 196, 230, .12)) border-box;
border: 1px solid transparent;
border-radius: 999px;
color: var(--text-leise);
font: inherit; font-size: .82rem;
font: inherit; font-size: .82rem; font-weight: 500;
letter-spacing: .01em;
cursor: pointer;
white-space: nowrap;
transition: background var(--tempo), border-color var(--tempo), color var(--tempo);
box-shadow: 0 1px 2px rgba(0, 0, 0, .35), inset 0 1px 0 rgba(255, 255, 255, .06);
transition: color var(--tempo), box-shadow var(--tempo), background var(--tempo);
}
.zurueck-knopf__pfeil {
width: 15px; height: 15px; flex: 0 0 auto;
fill: none; stroke: currentColor;
stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
transition: transform var(--tempo);
}
.zurueck-knopf:hover {
background: rgba(255, 255, 255, .08);
border-color: var(--rand-hell);
color: var(--text);
background:
linear-gradient(180deg, #1a2431, #131b25) padding-box,
linear-gradient(180deg, rgba(63, 189, 245, .62), rgba(138, 118, 255, .30)) border-box;
box-shadow: 0 2px 12px -4px rgba(63, 189, 245, .35), inset 0 1px 0 rgba(255, 255, 255, .08);
}
/* Der Pfeil rückt beim Überfahren ein Stück nach links -- die Bewegung
sagt in welche Richtung es geht, ohne zusätzlichen Text. */
.zurueck-knopf:hover .zurueck-knopf__pfeil { transform: translateX(-2px); }
.zurueck-knopf:active { box-shadow: inset 0 1px 3px rgba(0, 0, 0, .4); }
.zurueck-knopf:active .zurueck-knopf__pfeil { transform: translateX(-3px); }
@media (prefers-reduced-motion: reduce) {
.zurueck-knopf__pfeil { transition: none; }
.zurueck-knopf:hover .zurueck-knopf__pfeil,
.zurueck-knopf:active .zurueck-knopf__pfeil { transform: none; }
}
.zurueck-knopf:active { transform: translateX(-1px); }
.kopfleiste__rechts { display: flex; align-items: center; gap: 12px; }