Fix wheel-photo squareness bug, native select popups, image-cycle crash

.bildbox.radbild lost to a same-specificity, later-declared .bildbox rule,
so the wheel photo stayed a full-width 4:3 box despite the earlier crop
fix - only which slice showed ever changed. Fixed with a compound selector
and moved "Montiert" to top-left to match the now-correctly-sized photo.

Native <select> popups had no color-scheme hint and rendered in the
browser's default light palette regardless of the app's dark theme -
this is what made "Modell" and other dropdowns flash bright white.

bildWeiter() (Mein Audi image-cycle tap) referenced a CSS class that was
never emitted (.platzhalter-datei vs. the real .platzhalter-aktion),
throwing and aborting before the page-dot indicator update - the photo
advanced but the dots never moved.

Merged the separate "Fahrzeugbilder" upload grid into "Bild der
Übersicht": pick a view from the existing dropdown, tap its preview to
upload/replace/delete - same generic popup plumbing, no new mechanism.
Removed the now-dead BILDER_UPLOAD_SLOTS/.bildgrid/.bildslot/.carfix.mini.

Back arrow changed from red to the neutral headline color, matching every
other navigation-color decision in this project.

Investigated but could not reproduce: user-reported "whole tab bar
disappears" when hiding labels. Traced the exact commit that added the
icon+label highlight and confirmed it's correctly scoped to :not(.ohne);
live DOM/computed-style testing across toggle, navigation, and both
mobile/desktop widths showed the tab bar staying visible throughout.
Left unchanged pending a repro from the user.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-16 20:40:14 +02:00
parent 367985ba44
commit 17b25d492a
7 changed files with 156 additions and 83 deletions
+21 -29
View File
@@ -207,10 +207,6 @@ const BILDER = [
];
let bild = 0;
const SEITE_WINTER = { label: "Auto Seite mit Winterrädern", datei: "seitenansicht-winter.webp" };
// Alle einzeln hochladbaren Bild-Plätze (§ Fahrzeugbilder-Upload in
// Einstellungen) - dieselben festen Dateinamen wie BILDER, plus die separat
// geführte Winter-Variante der Seitenansicht.
const BILDER_UPLOAD_SLOTS = [...BILDER, { name: "Seitenansicht (Winter)", label: SEITE_WINTER.label, datei: SEITE_WINTER.datei }];
// Bei jedem Hochladen/Löschen eines Fahrzeugfotos hochgezählt und als
// Query-Parameter an alle bilder/-URLs gehängt (siehe bildInfo()
// unten) - ohne das würde der Browser nach einem Upload weiter das alte Bild
@@ -225,8 +221,9 @@ let bildVersion = Date.now();
Klassen erhalten, siehe carfix/carfix.klein/radbild in audi-dashboard.css). */
/* A5: Der Platzhalter nennt das Motiv und die nächste Handlung - der
Dateiname ist Entwicklersprache und steht nur noch in den Einstellungen
(siehe BILDER_UPLOAD_SLOTS). Die Maße bleiben über die CSS-Klassen erhalten,
das Layout springt beim Nachliefern eines Fotos nicht. */
(Bild der Übersicht: Ansicht wählen, dann auf das Bild tippen). Die Maße
bleiben über die CSS-Klassen erhalten, das Layout springt beim Nachliefern
eines Fotos nicht. */
function bildMitPlatzhalter(src, datei, label, klasse, imgId, dateiZeigen = false) {
const idTeil = imgId ? ` id="${imgId}"` : "";
return `<div class="bildbox ${klasse}" data-bildbox title="${esc(label)}">
@@ -294,7 +291,6 @@ function bildWeiter() {
if (box) {
box.classList.remove("bild-fehlt"); // neues Bild kann laden, auch wenn das vorherige fehlte
box.querySelector(".platzhalter-label").textContent = info.label;
box.querySelector(".platzhalter-datei").textContent = info.datei;
}
const sz = ROOT.getElementById("szene");
if (sz) sz.className = "szene " + szeneKlasse(bild);
@@ -2004,28 +2000,24 @@ function vEinst() {
<div class="tile"><span class="label">Bild der Übersicht</span>
<div class="feld" style="border-bottom:0"><label for="startbild">Ansicht</label>
<select id="startbild" data-startbild>${BILDER.map((b) => `<option ${b.name === CONFIG.startbild ? "selected" : ""}>${b.name}</option>`).join("")}</select></div>
<div style="margin-top:16px">${(() => { const info = bildInfo(startIndex()); return bildMitPlatzhalter(info.src, info.datei, info.label, "carfix"); })()}</div>
</div>
<div class="tile"><span class="label">Fahrzeugbilder</span>
<span class="label" style="margin-top:10px;color:var(--fg2);letter-spacing:0;
text-transform:none;font-size:12.5px;line-height:1.6">
Auf ein Bild tippen, um ein eigenes Foto hochzuladen oder zu ersetzen.</span>
<div class="bildgrid">
${BILDER_UPLOAD_SLOTS.map((s) => `
<div class="bildslot">
<div data-bildklick="${esc(s.datei)}">
${bildMitPlatzhalter(`/local/bilder/${s.datei}?v=${bildVersion}`, s.datei, s.label, "carfix mini", null, true)}
</div>
<input type="file" accept="image/*" hidden data-bildupload="${esc(s.datei)}">
<span class="bildslot-label">${esc(s.name)}</span>
${bildMenuOffen === s.datei ? `
<div class="bildmenu-catcher" data-bildmenu-schliessen></div>
<div class="bildmenu slot">
<button type="button" data-bildersetzen="${esc(s.datei)}">Foto ersetzen</button>
<button type="button" class="loeschen" data-bildloeschen="${esc(s.datei)}">Löschen</button>
</div>` : ""}
</div>`).join("")}
</div>
Auf das Bild tippen, um für diese Ansicht ein eigenes Foto hochzuladen oder zu ersetzen.</span>
${(() => {
const info = bildInfo(startIndex());
return `<div style="margin-top:12px">
<div data-bildklick="${esc(info.datei)}">
${bildMitPlatzhalter(info.src, info.datei, info.label, "carfix", null, true)}
</div>
<input type="file" accept="image/*" hidden data-bildupload="${esc(info.datei)}">
${bildMenuOffen === info.datei ? `
<div class="bildmenu-catcher" data-bildmenu-schliessen></div>
<div class="bildmenu ansicht">
<button type="button" data-bildersetzen="${esc(info.datei)}">Foto ersetzen</button>
<button type="button" class="loeschen" data-bildloeschen="${esc(info.datei)}">Löschen</button>
</div>` : ""}
</div>`;
})()}
</div>
<div class="tile"><span class="label">Kraftstoff-Rabatt</span>
<div class="feld"><label for="sdAktiv" style="display:flex;align-items:center;gap:6px">
@@ -3563,7 +3555,7 @@ function ereignisseVerdrahten() {
if (bildKlick) {
const dateiname = bildKlick.dataset.bildklick;
const box = bildKlick.querySelector(".bildbox");
const container = bildKlick.closest(".tile, .bildslot");
const container = bildKlick.closest(".tile");
if (box && box.classList.contains("bild-fehlt")) {
const input = container.querySelector(`[data-bildupload="${dateiname}"]`);
if (input) input.click();
@@ -3575,7 +3567,7 @@ function ereignisseVerdrahten() {
if (e.target.closest("[data-bildmenu-schliessen]")) { bildMenuOffen = null; render(); return; }
const bildErsetzen = e.target.closest("[data-bildersetzen]");
if (bildErsetzen) {
const container = bildErsetzen.closest(".tile, .bildslot");
const container = bildErsetzen.closest(".tile");
const input = container.querySelector(`[data-bildupload="${bildErsetzen.dataset.bildersetzen}"]`);
if (input) input.click();
return;