frontend: Mobile Sprachwahl als Overlay, eingeklappt nur aktive Sprache
- eingeklappt zeigt die Leiste nur noch die aktive Sprache (kein EN-Default, kein „…“); ein Tipp klappt die volle Liste als Overlay über die Kopfzeile auf (position:absolute, z-index) statt die Zeile zu verbreitern - nach Auswahl klappt sie wieder auf die gewählte Sprache ein; Tipp daneben schließt ebenfalls; applyMobile() startet eingeklappt - nur body.mobile betroffen; Desktop (DE EN ES FR + „…“, inline) unverändert - SPEC §9 (Kleiner Bildschirm) und DECISIONS D17 nachgeführt Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
63cfd82f07
commit
fe818b6c2c
+6
-2
@@ -145,8 +145,12 @@ Fenster-Buttons entfallen, der **Splitter bleibt** (Teilen per Ziehen möglich).
|
|||||||
Die Legende wird von der Bereichs-
|
Die Legende wird von der Bereichs-
|
||||||
Umschaltung **entkoppelt** und über einen eigenen Umschalter im Editor-Kopf
|
Umschaltung **entkoppelt** und über einen eigenen Umschalter im Editor-Kopf
|
||||||
gesteuert — das dauerhafte „AGENDA“-Band kostet sonst zu viel Höhe. Die
|
gesteuert — das dauerhafte „AGENDA“-Band kostet sonst zu viel Höhe. Die
|
||||||
Sprachleiste zeigt nur Englisch + aktive Sprache + „…“. Voreinstellung ist
|
Sprachleiste zeigt eingeklappt nur die **aktive** Sprache; ein Tipp klappt die
|
||||||
**Vollbild** (maximale Fläche). Umgesetzt über die Klasse `body.mobile` (per
|
volle Leiste als **Overlay über die Kopfzeile** auf (rechtsbündig, `z-index`,
|
||||||
|
verdeckt die übrigen Elemente statt die Zeile umzubrechen), nach der Auswahl —
|
||||||
|
oder einem Tipp daneben — klappt sie wieder ein. So bleibt die Kopfzeile schmal
|
||||||
|
und die vollständige Sprachliste dennoch erreichbar (frühere Lösung
|
||||||
|
„EN + aktive + …“ ersetzt). Voreinstellung ist **Vollbild** (maximale Fläche). Umgesetzt über die Klasse `body.mobile` (per
|
||||||
`matchMedia`), damit CSS und JS denselben Schwellwert teilen; die Vollbild-
|
`matchMedia`), damit CSS und JS denselben Schwellwert teilen; die Vollbild-
|
||||||
Voreinstellung greift nur, wenn noch **keine** gespeicherte Nutzerwahl vorliegt
|
Voreinstellung greift nur, wenn noch **keine** gespeicherte Nutzerwahl vorliegt
|
||||||
(eine bewusste Abschaltung bleibt so erhalten, siehe localStorage-Persistenz).
|
(eine bewusste Abschaltung bleibt so erhalten, siehe localStorage-Persistenz).
|
||||||
|
|||||||
+7
-4
@@ -153,10 +153,13 @@ Min/Normal/Max-Buttons entfallen; geteilt wird weiterhin über den **Splitter**
|
|||||||
Umschalter im Editor-Kopf (statt der dauerhaften „AGENDA“-Zeile), damit sie
|
Umschalter im Editor-Kopf (statt der dauerhaften „AGENDA“-Zeile), damit sie
|
||||||
zugeklappt keinen Platz kostet. Der **Modus-Wähler** zeigt nur das aktive Icon
|
zugeklappt keinen Platz kostet. Der **Modus-Wähler** zeigt nur das aktive Icon
|
||||||
und schaltet bei jedem Tippen reihum weiter (horizontal → kompakt → vertikal →
|
und schaltet bei jedem Tippen reihum weiter (horizontal → kompakt → vertikal →
|
||||||
…), spart also zwei Drittel der Breite. Die **Sprachwahl** zeigt nur Englisch
|
…), spart also zwei Drittel der Breite. Die **Sprachwahl** zeigt eingeklappt
|
||||||
und die aktive Sprache plus „…“ (das alle Sprachen aufklappt). Der **Untertitel**
|
nur die aktive Sprache; ein Tipp darauf klappt die volle Leiste als **Overlay
|
||||||
wird auf eine garantiert einzeilige Kurzfassung reduziert. Voreinstellung auf
|
über die Kopfzeile** auf (verdeckt die übrigen Bedienelemente, statt die Zeile
|
||||||
kleinem Bildschirm ist **Vollbild** (siehe D17).
|
zu verbreitern), nach der Auswahl klappt sie wieder auf die gewählte Sprache
|
||||||
|
ein (Tipp daneben schließt ebenfalls). Der **Untertitel** wird auf eine
|
||||||
|
garantiert einzeilige Kurzfassung reduziert. Voreinstellung auf kleinem
|
||||||
|
Bildschirm ist **Vollbild** (siehe D17).
|
||||||
|
|
||||||
### Günstigster Pfad (Kosten-Hervorhebung)
|
### Günstigster Pfad (Kosten-Hervorhebung)
|
||||||
Ein Umschalter (Icon-Button im Diagramm-Kopf, Voreinstellung **an**, Zustand
|
Ein Umschalter (Icon-Button im Diagramm-Kopf, Voreinstellung **an**, Zustand
|
||||||
|
|||||||
+35
-4
@@ -550,11 +550,20 @@
|
|||||||
/* Legende: keine dauerhafte Summary-Zeile, dafür der #legendBtn im Kopf */
|
/* Legende: keine dauerhafte Summary-Zeile, dafür der #legendBtn im Kopf */
|
||||||
body.mobile .agenda>summary{display:none}
|
body.mobile .agenda>summary{display:none}
|
||||||
body.mobile .legendbtn{display:inline-flex}
|
body.mobile .legendbtn{display:inline-flex}
|
||||||
/* Sprachwahl schlank: nur EN + aktuelle Sprache + „…“; „…“ klappt alle auf */
|
/* Sprachwahl schlank: eingeklappt nur die aktive Sprache. Ein Tipp klappt die
|
||||||
|
volle Leiste als Overlay über die Kopfzeile auf (verdeckt fsToggle usw.,
|
||||||
|
statt die Zeile zu verbreitern); nach der Auswahl klappt sie wieder ein
|
||||||
|
(JS). Das „…“ entfällt hier — die aktive Sprache ist selbst der Auslöser. */
|
||||||
|
body.mobile .header-tools{position:relative}
|
||||||
body.mobile .langsel button[data-lang]{display:none}
|
body.mobile .langsel button[data-lang]{display:none}
|
||||||
body.mobile .langsel.expanded button[data-lang]{display:inline-block}
|
|
||||||
body.mobile .langsel button[data-lang="en"],
|
|
||||||
body.mobile .langsel button[data-lang].active{display:inline-block}
|
body.mobile .langsel button[data-lang].active{display:inline-block}
|
||||||
|
body.mobile .langmore{display:none}
|
||||||
|
body.mobile .langsel.expanded{
|
||||||
|
position:absolute;top:0;right:0;z-index:40;
|
||||||
|
background:var(--card);
|
||||||
|
box-shadow:0 6px 18px rgba(36,52,71,.28);
|
||||||
|
}
|
||||||
|
body.mobile .langsel.expanded button[data-lang]{display:inline-block}
|
||||||
/* Modus-Wähler kompakt: nur das aktive Icon (ein Drittel Platz), Tippen
|
/* Modus-Wähler kompakt: nur das aktive Icon (ein Drittel Platz), Tippen
|
||||||
schaltet reihum weiter (horizontal → kompakt → vertikal → …, siehe JS). */
|
schaltet reihum weiter (horizontal → kompakt → vertikal → …, siehe JS). */
|
||||||
body.mobile .seg label{display:none}
|
body.mobile .seg label{display:none}
|
||||||
@@ -1697,8 +1706,29 @@ langMore.addEventListener('click', () => {
|
|||||||
const exp = langsel.classList.toggle('expanded');
|
const exp = langsel.classList.toggle('expanded');
|
||||||
langMore.setAttribute('aria-expanded', String(exp));
|
langMore.setAttribute('aria-expanded', String(exp));
|
||||||
});
|
});
|
||||||
|
function collapseLangsel(){
|
||||||
|
langsel.classList.remove('expanded');
|
||||||
|
langMore.setAttribute('aria-expanded', 'false');
|
||||||
|
}
|
||||||
document.querySelectorAll('.langsel button[data-lang]').forEach(b => {
|
document.querySelectorAll('.langsel button[data-lang]').forEach(b => {
|
||||||
b.addEventListener('click', () => applyLang(b.dataset.lang));
|
b.addEventListener('click', () => {
|
||||||
|
/* Mobil: eingeklappt ist nur die aktive Sprache sichtbar — ein Tipp klappt
|
||||||
|
die volle Leiste als Overlay auf; erst im aufgeklappten Zustand wählt ein
|
||||||
|
Tipp die Sprache und klappt wieder ein. */
|
||||||
|
if(isMobile() && !langsel.classList.contains('expanded')){
|
||||||
|
langsel.classList.add('expanded');
|
||||||
|
langMore.setAttribute('aria-expanded', 'true');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
applyLang(b.dataset.lang);
|
||||||
|
if(isMobile()) collapseLangsel();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
/* Mobil: Tipp außerhalb der aufgeklappten Leiste schließt sie wieder. */
|
||||||
|
document.addEventListener('click', e => {
|
||||||
|
if(isMobile() && langsel.classList.contains('expanded') && !langsel.contains(e.target)){
|
||||||
|
collapseLangsel();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* ---------- Vollbild: Panels über die ganze Fensterbreite ---------- */
|
/* ---------- Vollbild: Panels über die ganze Fensterbreite ---------- */
|
||||||
@@ -1797,6 +1827,7 @@ seg.addEventListener('click', e => {
|
|||||||
function applyMobile(){
|
function applyMobile(){
|
||||||
const m = isMobile();
|
const m = isMobile();
|
||||||
document.body.classList.toggle('mobile', m);
|
document.body.classList.toggle('mobile', m);
|
||||||
|
if(m) collapseLangsel(); /* Sprachleiste eingeklappt starten (Overlay-Logik) */
|
||||||
if(!m) return;
|
if(!m) return;
|
||||||
/* Nur ein Panel sichtbar: normal/custom passen nicht — auf Diagramm (b). */
|
/* Nur ein Panel sichtbar: normal/custom passen nicht — auf Diagramm (b). */
|
||||||
if(splitState !== 'a' && splitState !== 'b'){ splitState = 'b'; applySplit(); }
|
if(splitState !== 'a' && splitState !== 'b'){ splitState = 'b'; applySplit(); }
|
||||||
|
|||||||
Reference in New Issue
Block a user