Teilen-Blatt, HIG-Blaetter, geteilte Ansichtseinstellungen (2026.8.31.1)
Share-Erweiterung: ein PDF aus Mail landet ueber Teilen -> DataMetric360 als Tankbeleg. Alles Native liegt versioniert unter companion-app/native/, weil ios/ gitignored ist und npx cap add ios es sonst wieder frisst; scripts/ios-teilen-einrichten.mjs haengt es bei jedem Bau ins Xcode-Projekt und ist in ios-signieren.sh eingehaengt. Der pbxproj-Teil ist auf keinem Mac erprobt - er bricht vor dem Schreiben ab, und docs/SHARE_EXTENSION.md beschreibt dieselben Handgriffe fuer Xcode. "In den Kalender uebernehmen" ging in der App nie: WKWebView ignoriert das download-Attribut, der Klick lief ins Leere. Auf dem Geraet jetzt @capacitor/filesystem plus @capacitor/share. useTheme/useBoden legten je Aufrufer eigenen Zustand an - fuenf Kopien. Der Schalter aenderte nur seine eigene, data-theme in App.tsx blieb stehen, die Tag/Nacht-Umschaltung wirkte erst nach einem Neustart. Jetzt ein Speicher je Einstellung ueber useSyncExternalStore. Zwei Regressionstests, gegen den alten Stand als fehlschlagend nachgewiesen. Alle Popups nach Apple HIG: neue Bausteine Sheet und ActionSheet, blickdicht und mit abgedunkeltem Schleier, in beiden Codebasen. Popup portalierte nach document.body - ausserhalb von [data-theme] - und war deshalb im Tagmodus fast unsichtbar; Portal zielt jetzt auf .ads-root. ImagePlaceholder merkte sich "fehlgeschlagen" ohne die Adresse: nach einem leeren Galerieplatz zeigten auch die mit Foto nur noch den Platzhalter. Vier Regressionstests, ebenfalls gegen den alten Stand geprueft. Bildadressen tragen jetzt einen Cache-Brecher - HA liefert /local/ mit 31 Tagen Cache-Vorgabe aus, im Panel eingefuegte Radfotos erschienen in der App deshalb nicht. uebersichtsbild: Panel speichert den Namen, die App verglich gegen den Dateinamen - der Vergleich traf nie zu. Kanonisch ist der Name. Weiter: Navigationspfeil statt gleichschenkligem Dreieck auf der Streckenlinie (die Kerbe unterscheidet Kopf und Ende), CI-Symbol tour-s als Fahrten-Icon, Datumsfelder zeigen ihren Wert ohne erstes Antippen, feste Beispielnamen im Setup, Kopf-Gegengewicht fuer mittige Titel, Standort-Blatt mit festem Fussabstand, NSLocationWhenInUseUsageDescription, watchPosition fuer die Live-Ortung, Art-Pille wieder als Knopf, Zwischenablage fuer Tankbelege. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -599,8 +599,12 @@ button.leaf:active { background: var(--tile-2); }
|
||||
.szene.bleed::before {
|
||||
content: "";
|
||||
position: absolute; left: 0; right: 0; bottom: 0;
|
||||
height: 42%;
|
||||
background: linear-gradient(to bottom, transparent, var(--canvas) 78%);
|
||||
/* 26/96 statt 42/78: der Verlauf soll die harte Bildkante ausblenden,
|
||||
nicht das Fahrzeug. Mit 42% Hoehe und Vollton ab 78% war das untere
|
||||
Drittel des Fotos praktisch einfarbig - Raeder und Schweller lagen
|
||||
darunter (gemeldet vom Eigentuemer, 2026-08-31). */
|
||||
height: 26%;
|
||||
background: linear-gradient(to bottom, transparent, var(--canvas) 96%);
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
}
|
||||
@@ -668,7 +672,9 @@ button.leaf:active { background: var(--tile-2); }
|
||||
|
||||
.marke { display: inline-flex; align-items: center; gap: 6px; }
|
||||
.marke-logo { display: inline-flex; align-items: center; }
|
||||
.marke-logo img { height: 13px; width: auto; }
|
||||
/* Auf Zeilenhoehe (16px) statt 13px: das Markenlogo stand neben Text
|
||||
derselben Zeile und wirkte daneben zu klein. */
|
||||
.marke-logo img { height: 16px; width: auto; }
|
||||
.marke-logo .ph { display: none; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--fg3); }
|
||||
.marke-logo.logo-fehlt img { display: none; }
|
||||
.marke-logo.logo-fehlt .ph { display: inline; }
|
||||
@@ -1011,19 +1017,23 @@ button.leaf:active { background: var(--tile-2); }
|
||||
gezaehlt, das Blatt war auf dem Geraet rund 16px hoeher als noetig und
|
||||
schob sich entsprechend weiter hoch. Am Rechner faellt das nicht auf,
|
||||
dort ist der Einzug 0. */
|
||||
padding: 0 20px 18px;
|
||||
padding: 0 20px 34px;
|
||||
transform: translateY(calc(100% - var(--standort-peek)));
|
||||
transition: transform .28s cubic-bezier(.22,.61,.36,1);
|
||||
}
|
||||
/* Aufgezogen rastet das Blatt auf der mittleren Hoehe ein, nicht auf seiner
|
||||
Inhaltshoehe. Apple beschreibt genau das als "detents": Hoehen, auf denen
|
||||
ein Blatt natuerlich zur Ruhe kommt - large ist das voll ausgefahrene
|
||||
Blatt, medium etwa die Haelfte davon. Vorher war die Rasthoehe schlicht
|
||||
die Hoehe des Inhalts, dadurch schlossen die Knoepfe unten buendig mit der
|
||||
Menueleiste ab. Der Ueberschuss liegt unter den Knoepfen und haelt sie von
|
||||
der Leiste frei. Die eingeklappte Hoehe bleibt unberuehrt: die Verschiebung
|
||||
rechnet mit 100% der jeweiligen Blatthoehe minus dem Guckwert. */
|
||||
.standortmenu.offen { transform: translateY(0); min-height: 50%; }
|
||||
/* Aufgezogen bleibt unter den Knoepfen ein fester Abstand stehen, statt dass
|
||||
sie buendig mit der Menueleiste abschliessen.
|
||||
|
||||
Vorher stand hier min-height:50% - Apples "medium detent". Gemessen ergab
|
||||
das 89px (Panel) bzw. 76px (App) Luft unter dem letzten Knopf, und das war
|
||||
sichtbar zu viel: das Blatt zog ueber die Haelfte des Bildschirms auf,
|
||||
obwohl sein Inhalt dort laengst zu Ende war. Eine Raste ist nur dann
|
||||
richtig, wenn zwischen ihr und der Inhaltshoehe kein grosses Loch klafft.
|
||||
|
||||
Jetzt bestimmt der Inhalt die Hoehe, und die 34px Fussabstand halten die
|
||||
Knoepfe von der Leiste frei - hergeleitet aus der Beanstandung, nicht
|
||||
geraten: 18px waren zu wenig, 76-89px zu viel. */
|
||||
.standortmenu.offen { transform: translateY(0); }
|
||||
.standortmenu-griffzone { padding: 10px 0 14px; touch-action: none; cursor: grab; position: relative; }
|
||||
/* Der Griff ist jetzt ein Knopf (Tastaturzugang zum Menue). Die Knopf-
|
||||
Voreinstellungen des Browsers werden deshalb zurueckgesetzt; die
|
||||
@@ -1090,38 +1100,62 @@ button.leaf:active { background: var(--tile-2); }
|
||||
.standort-pille[disabled] { opacity: .4; pointer-events: none; }
|
||||
|
||||
/* ------------------------------------------------------- Bilderverwaltung */
|
||||
.bildmenu-catcher { position: fixed; inset: 0; z-index: 1000; }
|
||||
/* ---------------------------------------------------------- Blätter
|
||||
Apples Vorgabe kennt für etwas Modales auf dem Telefon kein frei
|
||||
schwebendes Fenster: es kommt von der unteren Kante. Das Aktionsblatt
|
||||
(eine kurze Liste von Wegen) und das Formularblatt (eine Eingabe) sind
|
||||
die beiden Formen; die Karte in der Bildschirmmitte war keine von
|
||||
beiden und stand ausserdem ohne abgedunkelten Grund über der voll
|
||||
sichtbaren Seite.
|
||||
|
||||
Der Schleier gehört dazu und ist nicht Geschmack: modal heisst, dass
|
||||
der Inhalt dahinter nicht bedienbar ist - das soll man sehen. */
|
||||
.bildmenu-catcher {
|
||||
position: absolute; inset: 0; z-index: 1000;
|
||||
background: rgba(0,0,0,.45);
|
||||
animation: sheet-fade .18s ease-out;
|
||||
}
|
||||
.bildmenu {
|
||||
position: absolute; z-index: 1001;
|
||||
background: var(--tile-2);
|
||||
border-radius: 14px;
|
||||
padding: var(--sp-2);
|
||||
left: 10px; right: 10px;
|
||||
bottom: max(10px, env(safe-area-inset-bottom));
|
||||
top: auto;
|
||||
transform: none;
|
||||
background: var(--tile-deckend, var(--canvas));
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
display: flex; flex-direction: column;
|
||||
min-width: 160px;
|
||||
animation: sheet-rein .24s cubic-bezier(.22,.61,.36,1);
|
||||
}
|
||||
.bildmenu.rad { top: 90px; left: 22px; }
|
||||
/* "Bild der Übersicht": das Vorschaubild füllt die ganze Kachelbreite, seine
|
||||
Unterkante liegt daher immer nah an der Kachel-Unterkante - das Menü von
|
||||
dort aus verankern statt mit einem festen top-Wert, der bei jedem
|
||||
Bildseitenverhältnis neu nachgemessen werden müsste. */
|
||||
.bildmenu.ansicht { bottom: var(--sp-5); left: 50%; transform: translateX(-50%); }
|
||||
/* Die beiden Lage-Varianten sind gegenstandslos geworden - ein Blatt
|
||||
kommt immer von unten. Die Klassen bleiben im Markup stehen, damit die
|
||||
Aufrufstellen unberührt bleiben; hier tragen sie nichts mehr bei. */
|
||||
.bildmenu.rad, .bildmenu.ansicht { left: 10px; right: 10px; top: auto; transform: none; }
|
||||
.bildmenu button {
|
||||
display: block; width: 100%; text-align: left;
|
||||
background: none; border: none;
|
||||
color: var(--fg); font-family: inherit; font-size: 15px;
|
||||
padding: 13px 10px; min-height: 46px; border-radius: 10px;
|
||||
color: var(--fg); font-family: inherit; font-size: 16px;
|
||||
padding: 16px 18px; min-height: 52px; border-radius: 0;
|
||||
border-bottom: 1px solid var(--line);
|
||||
cursor: pointer;
|
||||
}
|
||||
.bildmenu button:last-child { border-bottom: none; }
|
||||
.bildmenu button:active { background: var(--shade); }
|
||||
.bildmenu button.loeschen { color: var(--bad); }
|
||||
|
||||
/* Formularblatt (siehe Kasten oben): unten angeschlagen, nur oben rund,
|
||||
blickdicht. Stand vorher als Karte 60px unter dem oberen Rand - ausser
|
||||
Daumenreichweite und ohne sichtbaren Weg hinaus. */
|
||||
.sdpopup {
|
||||
position: absolute; z-index: 1001;
|
||||
left: var(--sp-5); right: var(--sp-5); top: 60px;
|
||||
background: var(--tile-2);
|
||||
border-radius: 14px;
|
||||
padding: var(--sp-4);
|
||||
left: 0; right: 0; bottom: 0; top: auto;
|
||||
background: var(--tile-deckend, var(--canvas));
|
||||
border-radius: 16px 16px 0 0;
|
||||
padding: var(--sp-4) 20px max(20px, env(safe-area-inset-bottom));
|
||||
animation: blatt-hoch .28s cubic-bezier(.22,.61,.36,1);
|
||||
}
|
||||
@keyframes blatt-hoch { from { transform: translateY(100%) } to { transform: none } }
|
||||
|
||||
/* Beleg-Fenster: PDF hineinziehen (Rechner) oder einfügen (Telefon). */
|
||||
.beleg-catcher {
|
||||
@@ -1129,15 +1163,20 @@ button.leaf:active { background: var(--tile-2); }
|
||||
background: rgba(0,0,0,.45);
|
||||
animation: sheet-fade .18s ease-out;
|
||||
}
|
||||
/* Formularblatt (siehe Kasten oben). Traegt drei Fenster: Beleg
|
||||
hochladen, Daten importieren, Datensatz sichern/laden. */
|
||||
.beleg-popup {
|
||||
position: absolute; z-index: 1001;
|
||||
left: var(--sp-5); right: var(--sp-5);
|
||||
top: 50%; transform: translateY(-50%);
|
||||
/* Wie .setup-popup: --tile-2 ist im Nacht-Theme transluzent, ein frei
|
||||
schwebendes Fenster braucht einen blickdichten Grund. */
|
||||
left: 0; right: 0; bottom: 0;
|
||||
top: auto; transform: none;
|
||||
max-height: 88%;
|
||||
overflow-y: auto;
|
||||
/* --tile-2 ist im Nacht-Theme transluzent; ein Blatt ueber der Seite
|
||||
braucht einen blickdichten Grund. */
|
||||
background: var(--tile-deckend, var(--canvas));
|
||||
border-radius: var(--r-tile);
|
||||
padding: var(--sp-4);
|
||||
border-radius: 16px 16px 0 0;
|
||||
padding: var(--sp-4) 20px max(20px, env(safe-area-inset-bottom));
|
||||
animation: blatt-hoch .28s cubic-bezier(.22,.61,.36,1);
|
||||
}
|
||||
.beleg-drop {
|
||||
margin-top: var(--sp-3);
|
||||
|
||||
Reference in New Issue
Block a user