Versicherung/Steuer: Wortlaut-Feinschliff und Vertrag komplett editierbar
Mein-Audi-Kachel "Versicherung/Steuer" (vAudi()) und Kfz-Steuer-Detail (vSteuer()): "Zusammen" heisst jetzt "Summe", die Fusszeile "feste Kosten im Jahr" darunter entfaellt ersatzlos. Die Kfz-Steuer-Zeile zeigt "im Jahr" statt des rohen Datenwerts "jaehrlich", deckungsgleich mit der Versicherungs-Zeile darueber - nur wenn steuer.zeitraum tatsaechlich "jaehrlich" ist. Der gespeicherte Wert und die "jaehrlich"/"halbjaehrlich"-Auswahl in vSteuerBearbeiten() bleiben unveraendert, das war ein reiner Anzeige-Fix, keine Datenmodell- Aenderung. companion-app hatte an keiner der beiden Stellen ein Gegenstueck (kein "Zusammen"-Tile, keine Nur-Lese-Anzeige des Zeitraums) - dokumentiert als vorbestehende strukturelle Luecke statt kommentarlos uebersprungen. Vertrag-Kachel: war komplett nur lesbar (Gesellschaft, Umfang, Vertragsnummer, Selbstbeteiligung, Schadenfreiheitsklasse). Neue vVertragBearbeiten()-Ansicht (Panel, Route "vertrag") ueber ein neues Zahnrad auf der Vertrag-Kachel - alle Felder editierbar, Selbstbeteiligung zusaetzlich mit Hinzufuegen/Loeschen pro Zeile (neue .zeile-loeschen-Klasse, 44x44pt-Tippflaeche wie .km-edit). Die aktuelle Schadenfreiheitsklasse bleibt bewusst nur ueber "Beitrag anpassen" editierbar (Querverweis statt Duplikat), nur "zuvor" (sfAlt) ist neu in der Vertrag-Ansicht. companion-app: neue Vertrag()-Seite (Route "vertrag", eigene NaviKachel auf der Versicherungs-Seite) nach dem dortigen etablierten Muster (lokaler Entwurf-State + expliziter Speichern-Knopf statt Panel-Autosave pro Feld - gleiches Verhalten, eigenes Idiom). Die bisherige Nur-Lese-Selbstbeteiligung in Vertragsdetails() entfaellt, da sie jetzt (editierbar) in Vertrag() lebt. Schadenfreiheitsklasse wird in companion-app bewusst nicht ergaenzt: das Feld war dort noch nie sichtbar, auch nicht lesend - eine komplette neue UI-Sektion dafuer waere kein "Zeile editierbar machen" mehr, sondern ein neues Feature; als Luecke dokumentiert statt still uebergangen. tsc --noEmit sauber, companion-app-Tests 100/100 (inkl. dem Alle-Seiten-Rendertest, der jetzt auch "vertrag" abdeckt), vite build erfolgreich. Panel live im Docker-Testcontainer geprueft: Zeile hinzufuegen/bearbeiten/loeschen, Daten bleiben nach Re-Render erhalten. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# AGENTS.md — Project state, review findings, open items, and working rules
|
||||
|
||||
**Last updated: 2026-08-18** (merged the `umsetzung-datametric360` branch — companion app phases
|
||||
**Last updated: 2026-08-19** (merged the `umsetzung-datametric360` branch — companion app phases
|
||||
1–10 done, see `UMSETZUNGSPLAN.md`; 2026-08-13: cleaned up remaining EU Data Act residue, fixed
|
||||
oversized toggle switches, and fixed a desktop-layout audit (settings button / rings logo / popups
|
||||
overflowing past the capped content column) — see `DESIGN_AUDIT_2026-08-13.md`; 2026-08-16: fixed
|
||||
@@ -52,7 +52,41 @@ solve them - both answer the same way, and the merged "9,0 tkm/ 04/27" number fi
|
||||
"Anstehende Termine" boxes ("Lost information") - no code from that proposal was built; instead the
|
||||
existing Nächster-Service box on the Übersicht had its "bis zum/zur ..." wording replaced by the
|
||||
real Audi CI oil-change/inspection icons (user-supplied SVGs) placed left of the figure, in both
|
||||
codebases, per the owner's explicit request).
|
||||
codebases, per the owner's explicit request); 2026-08-19: two small wording fixes on the panel's
|
||||
"Mein Audi" Versicherung/Steuer summary tile (`vAudi()`) and its "Kfz-Steuer" detail tile
|
||||
(`vSteuer()`) — "Zusammen" renamed to "Summe" and the "feste Kosten im Jahr" caption under the sum
|
||||
dropped entirely, and the Kfz-Steuer amount's period caption now reads "im Jahr" instead of the raw
|
||||
data value "jährlich" (matching the Versicherung row above it) whenever `steuer.zeitraum ===
|
||||
"jährlich"`; the underlying stored value and the "jährlich"/"halbjährlich" edit-form dropdown
|
||||
(`vSteuerBearbeiten()`) were deliberately left untouched, since this was a display-label fix, not a
|
||||
data-model rename. No companion-app port was needed for the "Zusammen" row: `companion-app`'s "Mein
|
||||
Audi" page (`MeinAudi.tsx`) only links to the Versicherung/Steuer screen via a `NaviKachel`, it never
|
||||
rendered a combined Versicherung+Steuer sum in the first place, so there was nothing to change there
|
||||
(pre-existing structural gap, not part of this fix). Companion's `Steuer()` edit screen has no
|
||||
read-only "im Jahr"/"jährlich" display either — its only "jährlich" is a fallback default string
|
||||
inside an editable-sentence, structurally different from the panel's read-only tiles — so it was left
|
||||
as-is too. Later the same day: the "Vertrag" tile on that same "Mein Audi" Versicherung/Steuer page
|
||||
was previously read-only end-to-end (Gesellschaft, Umfang, Vertragsnummer, Selbstbeteiligung,
|
||||
Schadenfreiheitsklasse) — made every line editable, plus add/delete for the Selbstbeteiligung list
|
||||
specifically (the only true repeating list among those fields). Panel: new `vVertragBearbeiten()`
|
||||
view (route `vertrag`, back to `vers`) reached via a new zahnrad button on the "Vertrag" tile in
|
||||
`vVers()`; Selbstbeteiligung rows get a small inline "×" delete button (new `.zeile-loeschen` CSS,
|
||||
same 44×44pt invisible-`::before` tap-target trick as `.km-edit`) and a "+ Position hinzufügen"
|
||||
`.aktion` button that pushes `["", ""]`; Schadenfreiheitsklasse "zuvor" (`sfAlt`) is edited here too
|
||||
(the *current* SF stays editable only via the pre-existing "Beitrag anpassen" screen, cross-
|
||||
referenced with a hint span, not duplicated). Companion: new `Vertrag()` screen (route `vertrag`,
|
||||
its own NaviKachel on the Versicherung page) follows the codebase's own established edit-screen idiom
|
||||
(local `entwurf` state + explicit "Speichern" button) rather than the panel's per-field autosave —
|
||||
same behavior, different idiom, per the parity rule. Selbstbeteiligung edit/add/delete moved here
|
||||
from the old read-only display inside `Vertragsdetails()`, which is removed (was showing the same
|
||||
list twice would have been confusing). Schadenfreiheitsklasse is *not* added to companion's new
|
||||
screen: companion never displayed `teile[].sf`/`sfAlt` anywhere before this change (not even
|
||||
read-only) — building a whole new UI section for a field the app never surfaced is out of scope for
|
||||
"make the existing lines editable"; documented here as a pre-existing gap, not silently dropped.
|
||||
Verified live in the Docker test container (panel: add/edit/delete a Selbstbeteiligung position,
|
||||
values persisted through profilSpeichern()+re-render) and via `tsc --noEmit` + the companion-app test
|
||||
suite (100/100 incl. the render-every-page smoke test, which now also covers `vertrag`) + `vite
|
||||
build`, since companion-app needs a live backend connection the local dev server doesn't have.
|
||||
This file is the entry point for every new agent
|
||||
session: what this repo is, what is finished, what is missing, and how to work here. Detail lives in
|
||||
the linked documents — this file points, it does not duplicate.
|
||||
@@ -1650,6 +1684,27 @@ wraps the web app for iPhone; a PWA home-screen install is the accepted intermed
|
||||
|
||||
- [ ] **Archive** `audi-dashboard-app.js`, don't delete (settled decision, architecture §1)
|
||||
|
||||
### E) Versicherungs-Details overhaul (planned, not started — noted 2026-08-19)
|
||||
|
||||
The owner wants to revisit "Versicherung/Steuer" more broadly next session, beyond the line-editing
|
||||
work already done (see section C in the changelog above: "Vertrag" tile made fully editable with
|
||||
add/delete for Selbstbeteiligung). Three separate asks, none scoped or started yet:
|
||||
|
||||
- [ ] Store the insurer's own Vertragsdetails PDF against the policy (upload/attach + view later) —
|
||||
needs a decision on storage location (mirrors the existing vehicle-photo/backup file handling
|
||||
under `www/bilder/`? a new profile-attachment concept?) and where it's surfaced (new tile on
|
||||
"Vertragsdetails", or the main "Vertrag" tile)
|
||||
- [ ] A free-text field for the owner's own manual notes/summary on the insurance (not derived from
|
||||
any structured field) — likely a `notiz`-style textarea, panel already has a `.notiz` CSS class
|
||||
pattern used elsewhere (see `feld.notiz` in `audi-dashboard.css`) that could apply here
|
||||
- [ ] Redesign the "Versicherung/Steuer" Übersicht/summary box — **owner explicitly said they don't
|
||||
yet know what they want here**; needs a requirements conversation (what should be surfaced at a
|
||||
glance vs. moved to detail screens) before any mockup, not just a straight implementation
|
||||
|
||||
Not planned/scoped in either codebase yet — start with clarifying questions on the PDF storage model
|
||||
and the summary-box redesign goals before touching code, per this project's mockup-first convention
|
||||
for open-ended redesign asks (see the "Anstehende Termine" 3-round mockup process, section C).
|
||||
|
||||
---
|
||||
|
||||
## Working conventions (observed — keep them)
|
||||
|
||||
@@ -23,6 +23,7 @@ export type SeitenName =
|
||||
| "reifen"
|
||||
| "vers"
|
||||
| "beitrag"
|
||||
| "vertrag"
|
||||
| "vertragsdetails"
|
||||
| "schutz"
|
||||
| "notruf"
|
||||
@@ -54,6 +55,7 @@ export const ZURUECK: Partial<Record<SeitenName, SeitenName>> = {
|
||||
battverlauf: "audi",
|
||||
vers: "audi",
|
||||
beitrag: "vers",
|
||||
vertrag: "vers",
|
||||
vertragsdetails: "vers",
|
||||
schutz: "vertragsdetails",
|
||||
steuer: "vers",
|
||||
@@ -80,6 +82,7 @@ export const TITEL: Record<SeitenName, string> = {
|
||||
reifen: "Reifen",
|
||||
vers: "Versicherung & Steuer",
|
||||
beitrag: "Beitrag",
|
||||
vertrag: "Vertrag",
|
||||
vertragsdetails: "Vertragsdetails",
|
||||
schutz: "Schutzbrief",
|
||||
notruf: "Notruf",
|
||||
|
||||
@@ -56,6 +56,11 @@ export function Versicherung({ geheZu }: { geheZu: (name: SeitenName, id?: strin
|
||||
|
||||
<div className="dm-raster">
|
||||
<NaviKachel titel="Beitrag" wert="Einzelposten bearbeiten" beiKlick={() => geheZu("beitrag")} />
|
||||
<NaviKachel
|
||||
titel="Vertrag"
|
||||
wert="Gesellschaft, Nummer, Selbstbeteiligung"
|
||||
beiKlick={() => geheZu("vertrag")}
|
||||
/>
|
||||
<NaviKachel
|
||||
titel="Vertragsdetails"
|
||||
wert="Leistungen und Schutzbrief"
|
||||
@@ -155,13 +160,115 @@ export function Beitrag() {
|
||||
)
|
||||
}
|
||||
|
||||
export function Vertrag() {
|
||||
const { fahrzeug, profilSpeichern } = useDaten()
|
||||
const v = fahrzeug?.versicherung ?? {}
|
||||
const [gesellschaft, setzeGesellschaft] = useState((v["gesellschaft"] as string) ?? "")
|
||||
const [umfang, setzeUmfang] = useState((v["vertrag"] as string) ?? "")
|
||||
const [nummer, setzeNummer] = useState((v["nummer"] as string) ?? "")
|
||||
const [selbst, setzeSelbst] = useState<string[][]>(() =>
|
||||
((v["selbst"] as (string | number)[][]) ?? []).map(([b, w]) => [String(b ?? ""), String(w ?? "")]),
|
||||
)
|
||||
const [laeuft, setzeLaeuft] = useState(false)
|
||||
const [gespeichert, setzeGespeichert] = useState(false)
|
||||
|
||||
if (!fahrzeug) return null
|
||||
|
||||
const speichern = async () => {
|
||||
setzeLaeuft(true)
|
||||
setzeGespeichert(false)
|
||||
try {
|
||||
await profilSpeichern({
|
||||
fahrzeug: {
|
||||
...fahrzeug,
|
||||
versicherung: { ...v, gesellschaft, vertrag: umfang, nummer, selbst },
|
||||
},
|
||||
})
|
||||
setzeGespeichert(true)
|
||||
} finally {
|
||||
setzeLaeuft(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tile>
|
||||
<span className="ads-eyebrow">Vertrag</span>
|
||||
<Feld label="Gesellschaft">
|
||||
<input
|
||||
className="dm-eingabe"
|
||||
value={gesellschaft}
|
||||
onChange={(e) => setzeGesellschaft(e.target.value)}
|
||||
/>
|
||||
</Feld>
|
||||
<Feld label="Umfang">
|
||||
<input className="dm-eingabe" value={umfang} onChange={(e) => setzeUmfang(e.target.value)} />
|
||||
</Feld>
|
||||
<Feld label="Vertragsnummer" last>
|
||||
<input className="dm-eingabe" value={nummer} onChange={(e) => setzeNummer(e.target.value)} />
|
||||
</Feld>
|
||||
</Tile>
|
||||
|
||||
<Tile>
|
||||
<span className="ads-eyebrow">Selbstbeteiligung</span>
|
||||
{selbst.map((zeile, i) => (
|
||||
<Feld key={i} label={`Position ${i + 1}`} last={i === selbst.length - 1}>
|
||||
<span className="dm-selbst-zeile">
|
||||
<input
|
||||
className="dm-eingabe"
|
||||
style={{ minWidth: 84, maxWidth: 110 }}
|
||||
placeholder="Bezeichnung"
|
||||
value={zeile[0]}
|
||||
onChange={(e) => {
|
||||
const wert = e.target.value
|
||||
setzeSelbst((alt) => alt.map((z, idx) => (idx === i ? [wert, z[1] ?? ""] : z)))
|
||||
}}
|
||||
/>
|
||||
<input
|
||||
className="dm-eingabe"
|
||||
style={{ minWidth: 64, maxWidth: 90 }}
|
||||
placeholder="Betrag"
|
||||
value={zeile[1]}
|
||||
onChange={(e) => {
|
||||
const wert = e.target.value
|
||||
setzeSelbst((alt) => alt.map((z, idx) => (idx === i ? [z[0] ?? "", wert] : z)))
|
||||
}}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="dm-zeile-loeschen"
|
||||
aria-label={`Position ${i + 1} löschen`}
|
||||
onClick={() => setzeSelbst((alt) => alt.filter((_, idx) => idx !== i))}
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</span>
|
||||
</Feld>
|
||||
))}
|
||||
{selbst.length === 0 && <p className="dm-fussnote">Keine Selbstbeteiligung hinterlegt.</p>}
|
||||
<div style={{ marginTop: 14 }}>
|
||||
<ActionButton onClick={() => setzeSelbst((alt) => [...alt, ["", ""]])}>
|
||||
+ Position hinzufügen
|
||||
</ActionButton>
|
||||
</div>
|
||||
</Tile>
|
||||
|
||||
{gespeichert && <p className="dm-erfolg">Gespeichert.</p>}
|
||||
<div style={{ marginTop: 14 }}>
|
||||
<ActionButton onClick={() => void speichern()} disabled={laeuft}>
|
||||
{laeuft ? "Speichere …" : "Speichern"}
|
||||
</ActionButton>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export function Vertragsdetails({ geheZu }: { geheZu: (name: SeitenName, id?: string) => void }) {
|
||||
const { fahrzeug } = useDaten()
|
||||
if (!fahrzeug) return null
|
||||
|
||||
const v = fahrzeug.versicherung
|
||||
const leistungen = (v["leistungen"] ?? []) as { bez?: string; wert?: string }[]
|
||||
const selbst = (v["selbst"] ?? []) as (string | number)[][]
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -178,17 +285,6 @@ export function Vertragsdetails({ geheZu }: { geheZu: (name: SeitenName, id?: st
|
||||
)}
|
||||
</Tile>
|
||||
|
||||
{selbst.length > 0 && (
|
||||
<Tile>
|
||||
<span className="ads-eyebrow">Selbstbeteiligung</span>
|
||||
<Werteliste
|
||||
kinder={selbst.map((zeile, i) => (
|
||||
<Wertzeile key={i} label={String(zeile[0] ?? "")} wert={String(zeile[1] ?? "")} />
|
||||
))}
|
||||
/>
|
||||
</Tile>
|
||||
)}
|
||||
|
||||
<NaviKachel
|
||||
titel="Schutzbrief"
|
||||
wert="Bedingungen im Detail"
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
Schutzbrief,
|
||||
Steuer,
|
||||
Versicherung,
|
||||
Vertrag,
|
||||
Vertragsdetails,
|
||||
} from "./Versicherung"
|
||||
|
||||
@@ -78,6 +79,8 @@ export function SeiteFuer(props: SeitenProps) {
|
||||
return <Versicherung geheZu={geheZu} />
|
||||
case "beitrag":
|
||||
return <Beitrag />
|
||||
case "vertrag":
|
||||
return <Vertrag />
|
||||
case "vertragsdetails":
|
||||
return <Vertragsdetails geheZu={geheZu} />
|
||||
case "schutz":
|
||||
|
||||
@@ -24,6 +24,42 @@
|
||||
color: var(--fg3);
|
||||
}
|
||||
|
||||
/* Eine Zeile aus einer bearbeitbaren Liste (z. B. Selbstbeteiligung im
|
||||
Vertrag) - zwei Eingaben plus Löschen-Knopf in einer Reihe, deckungsgleich
|
||||
mit .feld/.zeile-loeschen im Panel (audi-dashboard.css). */
|
||||
.dm-selbst-zeile {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-2);
|
||||
}
|
||||
|
||||
.dm-zeile-loeschen {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border: none;
|
||||
background: none;
|
||||
color: var(--fg3);
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.dm-zeile-loeschen::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: -11px;
|
||||
}
|
||||
|
||||
.dm-zeile-loeschen:active {
|
||||
color: var(--bad);
|
||||
}
|
||||
|
||||
.dm-auswahl {
|
||||
text-align: right;
|
||||
appearance: none;
|
||||
|
||||
@@ -1415,9 +1415,9 @@ function vAudi() {
|
||||
<svg class="go" viewBox="0 0 6 10"><polyline points="1,1 5,5 1,9"/></svg>
|
||||
<dl class="rows" style="margin-top:10px">
|
||||
<div class="row"><dt>Versicherung</dt><dd>${eur(CAR.versicherung.beitrag)} €<small>im Jahr</small></dd></div>
|
||||
<div class="row"><dt>Kfz-Steuer</dt><dd>${eur(CAR.steuer.betrag)} €<small>${esc(CAR.steuer.zeitraum)}</small></dd></div>
|
||||
<div class="row" style="border-bottom:0"><dt>Zusammen</dt>
|
||||
<dd>${eur(CAR.versicherung.beitrag + CAR.steuer.betrag)} €<small>feste Kosten im Jahr</small></dd></div>
|
||||
<div class="row"><dt>Kfz-Steuer</dt><dd>${eur(CAR.steuer.betrag)} €<small>${CAR.steuer.zeitraum === "jährlich" ? "im Jahr" : esc(CAR.steuer.zeitraum)}</small></dd></div>
|
||||
<div class="row" style="border-bottom:0"><dt>Summe</dt>
|
||||
<dd>${eur(CAR.versicherung.beitrag + CAR.steuer.betrag)} €</dd></div>
|
||||
</dl></button>
|
||||
<button class="tile tilebtn" data-go="reifen:x">
|
||||
<span class="label">Reifen · ${r.aktiv} montiert</span>
|
||||
@@ -1915,6 +1915,9 @@ function vVers() {
|
||||
</div>
|
||||
</div>
|
||||
<div class="tile"><span class="label">Vertrag</span>
|
||||
<button class="zahnrad" data-go="vertrag:x" aria-label="Vertrag bearbeiten">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M9.4 2h4.2v2.84c.37.13.75.27 1.11.44L16.7 3.3l3 3.01-1.98 1.99c.17.36.31.74.44 1.11H21v4.3h-2.84c-.13.37-.27.75-.44 1.11l2 2-3.03 2.89-1.98-1.98c-.36.17-.74.31-1.11.44V21H9.4v-2.84a9 9 0 0 1-1.11-.44L6.3 19.7l-3-3.01 1.98-1.99a9 9 0 0 1-.44-1.11H2V9.4h2.84c.13-.37.27-.75.44-1.11L3.3 6.3l3.01-3L8.3 5.28c.36-.17.74-.31 1.11-.44V2Zm1 1v2.56l-.34.11c-.61.2-1.16.4-1.6.66l-.34.2L6.3 4.71 4.7 6.3l1.83 1.82-.2.34c-.27.44-.45.99-.66 1.6l-.11.34H3v2.2h2.56l.11.34c.2.61.4 1.16.66 1.6l.2.34-1.82 1.82 1.59 1.6 1.82-1.83.34.2c.44.27.99.45 1.6.66l.34.11V20h2.2v-2.56l.34-.11a8.3 8.3 0 0 0 1.6-.66l.34-.2 1.83 1.83 1.57-1.5-1.81-1.82.2-.34c.27-.44.45-.99.66-1.6l.11-.34H20v-2.3h-2.56l-.11-.34a8.2 8.2 0 0 0-.66-1.6l-.2-.34 1.82-1.82-1.59-1.6-1.82 1.83-.34-.2a8.2 8.2 0 0 0-1.6-.66l-.34-.11V3zm-2.9 8.5c0-2.18 1.82-4 4-4s4 1.82 4 4-1.82 4-4 4-4-1.82-4-4m4-3c-1.62 0-3 1.38-3 3s1.38 3 3 3 3-1.38 3-3-1.38-3-3-3"/></svg>
|
||||
</button>
|
||||
<dl class="rows" style="margin-top:8px">
|
||||
<div class="row"><dt>Gesellschaft</dt><dd>${esc(v.gesellschaft)}</dd></div>
|
||||
<div class="row"><dt>Umfang</dt><dd>${esc(v.vertrag)}</dd></div>
|
||||
@@ -1976,6 +1979,40 @@ function vVertragsdetails() {
|
||||
</dl></div>`).join("")}`;
|
||||
}
|
||||
|
||||
function vVertragBearbeiten() {
|
||||
const v = CAR.versicherung;
|
||||
return `
|
||||
<div class="tile"><span class="label">Vertrag</span>
|
||||
<div class="feld"><label for="vGesellschaft">Gesellschaft</label>
|
||||
<input id="vGesellschaft" style="width:180px" value="${esc(v.gesellschaft)}" data-vvertrag="gesellschaft"></div>
|
||||
<div class="feld"><label for="vUmfang">Umfang</label>
|
||||
<input id="vUmfang" style="width:180px" value="${esc(v.vertrag)}" data-vvertrag="vertrag"></div>
|
||||
<div class="feld" style="border-bottom:0"><label for="vNummer">Vertragsnummer</label>
|
||||
<input id="vNummer" style="width:180px" value="${esc(v.nummer)}" data-vvertrag="nummer"></div>
|
||||
</div>
|
||||
<div class="tile" style="margin-top:26px"><span class="label">Selbstbeteiligung</span>
|
||||
${v.selbst.map(([b, w], i) => `
|
||||
<div class="feld" ${i === v.selbst.length - 1 ? 'style="border-bottom:0"' : ""}>
|
||||
<label for="vSelbstB${i}">Position ${i + 1}</label>
|
||||
<span style="display:inline-flex;align-items:center;gap:8px">
|
||||
<input id="vSelbstB${i}" style="width:100px" value="${esc(b)}" placeholder="Bezeichnung" data-vselbst="${i}|0">
|
||||
<input id="vSelbstW${i}" style="width:80px" value="${esc(w)}" placeholder="Betrag" data-vselbst="${i}|1">
|
||||
<button class="zeile-loeschen" data-vselbstdel="${i}" aria-label="Position ${i + 1} löschen">×</button>
|
||||
</span>
|
||||
</div>`).join("")}
|
||||
${!v.selbst.length ? `<span class="label" style="margin-top:8px">Keine Selbstbeteiligung hinterlegt</span>` : ""}
|
||||
<button class="aktion" data-vselbstadd>+ Position hinzufügen</button>
|
||||
</div>
|
||||
<div class="tile" style="margin-top:26px"><span class="label">Schadenfreiheitsklasse · zuvor</span>
|
||||
<div class="feld"><label for="vSfHaftAlt">Haftpflicht</label>
|
||||
<input id="vSfHaftAlt" style="width:132px" value="${esc(v.teile[0]?.sfAlt || "")}" data-vteil="0|sfAlt"></div>
|
||||
<div class="feld" style="border-bottom:0"><label for="vSfKaskoAlt">Vollkasko</label>
|
||||
<input id="vSfKaskoAlt" style="width:132px" value="${esc(v.teile[1]?.sfAlt || "")}" data-vteil="1|sfAlt"></div>
|
||||
<span class="label" style="margin-top:14px">Die aktuelle Schadenfreiheitsklasse änderst du unter
|
||||
"Beitrag anpassen" — hier steht nur der vorherige Wert für den Vergleich.</span>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function vSchutz() {
|
||||
const v = CAR.versicherung, sb = v.schutzbrief;
|
||||
return `
|
||||
@@ -2028,7 +2065,7 @@ function vSteuer() {
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M9.4 2h4.2v2.84c.37.13.75.27 1.11.44L16.7 3.3l3 3.01-1.98 1.99c.17.36.31.74.44 1.11H21v4.3h-2.84c-.13.37-.27.75-.44 1.11l2 2-3.03 2.89-1.98-1.98c-.36.17-.74.31-1.11.44V21H9.4v-2.84a9 9 0 0 1-1.11-.44L6.3 19.7l-3-3.01 1.98-1.99a9 9 0 0 1-.44-1.11H2V9.4h2.84c.13-.37.27-.75.44-1.11L3.3 6.3l3.01-3L8.3 5.28c.36-.17.74-.31 1.11-.44V2Zm1 1v2.56l-.34.11c-.61.2-1.16.4-1.6.66l-.34.2L6.3 4.71 4.7 6.3l1.83 1.82-.2.34c-.27.44-.45.99-.66 1.6l-.11.34H3v2.2h2.56l.11.34c.2.61.4 1.16.66 1.6l.2.34-1.82 1.82 1.59 1.6 1.82-1.83.34.2c.44.27.99.45 1.6.66l.34.11V20h2.2v-2.56l.34-.11a8.3 8.3 0 0 0 1.6-.66l.34-.2 1.83 1.83 1.57-1.5-1.81-1.82.2-.34c.27-.44.45-.99.66-1.6l.11-.34H20v-2.3h-2.56l-.11-.34a8.2 8.2 0 0 0-.66-1.6l-.2-.34 1.82-1.82-1.59-1.6-1.82 1.83-.34-.2a8.2 8.2 0 0 0-1.6-.66l-.34-.11V3zm-2.9 8.5c0-2.18 1.82-4 4-4s4 1.82 4 4-1.82 4-4 4-4-1.82-4-4m4-3c-1.62 0-3 1.38-3 3s1.38 3 3 3 3-1.38 3-3-1.38-3-3-3"/></svg>
|
||||
</button>
|
||||
<dl class="rows" style="margin-top:10px">
|
||||
<div class="row"><dt>Betrag</dt><dd>${eur(t.betrag)} €<small>${esc(t.zeitraum)}</small></dd></div>
|
||||
<div class="row"><dt>Betrag</dt><dd>${eur(t.betrag)} €<small>${t.zeitraum === "jährlich" ? "im Jahr" : esc(t.zeitraum)}</small></dd></div>
|
||||
<div class="row" style="border-bottom:0"><dt>Nächste Fälligkeit</dt>
|
||||
<dd>${t.faellig ? dedat(new Date(t.faellig)) : "unbekannt"}</dd></div>
|
||||
</dl>
|
||||
@@ -3157,6 +3194,7 @@ let route = { name: "home" };
|
||||
const ZURUECK = {
|
||||
trip: "trips", fill: "fuel", service: "audi", reifen: "audi", ident: "audi",
|
||||
vers: "audi", beitrag: "vers", vertragsdetails: "vers", schutz: "vertragsdetails",
|
||||
vertrag: "vers",
|
||||
steuer: "vers", notruf: "vers", werkstatt: "service", sbuch: "service", einst: "home",
|
||||
battverlauf: "audi",
|
||||
/* Fehlte: die Sicherheitsansicht war eine Sackgasse ohne sichtbaren
|
||||
@@ -3439,6 +3477,7 @@ function render() {
|
||||
else if (route.name === "vers") { head = ["Fahrzeug", "Versicherung/Steuer"]; v.innerHTML = vVers(); }
|
||||
else if (route.name === "beitrag") { head = ["Versicherung", "Beitrag anpassen"]; v.innerHTML = vBeitrag(); }
|
||||
else if (route.name === "vertragsdetails") { head = ["Versicherung", "Vertragsdetails"]; v.innerHTML = vVertragsdetails(); }
|
||||
else if (route.name === "vertrag") { head = ["Versicherung", "Vertrag"]; v.innerHTML = vVertragBearbeiten(); }
|
||||
else if (route.name === "steuer") { head = ["Versicherung", "Kfz-Steuer"]; v.innerHTML = vSteuerBearbeiten(); }
|
||||
else if (route.name === "notruf") { head = ["Versicherung", "Rufnummern"]; v.innerHTML = vNotrufBearbeiten(); }
|
||||
else if (route.name === "schutz") { head = ["Im Ernstfall", "Schutzbrief"]; v.innerHTML = vSchutz(); }
|
||||
@@ -4105,6 +4144,9 @@ function ereignisseVerdrahten() {
|
||||
}
|
||||
const del = e.target.closest("[data-loeschen]");
|
||||
if (del) { delete CAR.service.vereinbart[del.dataset.loeschen]; profilSpeichern(); render(); return; }
|
||||
const vseldel = e.target.closest("[data-vselbstdel]");
|
||||
if (vseldel) { CAR.versicherung.selbst.splice(+vseldel.dataset.vselbstdel, 1); profilSpeichern(); render(); return; }
|
||||
if (e.target.closest("[data-vselbstadd]")) { CAR.versicherung.selbst.push(["", ""]); profilSpeichern(); render(); return; }
|
||||
const oel = e.target.closest("[data-oel]");
|
||||
if (oel) { CAR.oel.modus = oel.dataset.oel; profilSpeichern(); render(); return; }
|
||||
const mode = e.target.closest("[data-mode]");
|
||||
@@ -4363,6 +4405,14 @@ function ereignisseVerdrahten() {
|
||||
if (e.target.dataset.vgueltigab !== undefined) { CAR.versicherung.gueltigAb = e.target.value; profilSpeichern(); render(); return; }
|
||||
const vnotruf = e.target.dataset.vnotruf;
|
||||
if (vnotruf) { CAR.versicherung[vnotruf] = e.target.value; profilSpeichern(); render(); return; }
|
||||
const vvertrag = e.target.dataset.vvertrag;
|
||||
if (vvertrag) { CAR.versicherung[vvertrag] = e.target.value; profilSpeichern(); render(); return; }
|
||||
const vselbst = e.target.dataset.vselbst;
|
||||
if (vselbst) {
|
||||
const [i, feld] = vselbst.split("|");
|
||||
CAR.versicherung.selbst[+i][+feld] = e.target.value;
|
||||
profilSpeichern(); render(); return;
|
||||
}
|
||||
if (e.target.dataset.pause !== undefined) { CONFIG.pauseMin = parseInt(e.target.value, 10) || 0; profilSpeichern(); return; }
|
||||
if (e.target.dataset.sd !== undefined) {
|
||||
if (e.target.checked) { smartdealPopupOffen = true; render(); }
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version": 1787013003}
|
||||
{"version": 1787014000}
|
||||
|
||||
@@ -1044,6 +1044,21 @@ button.tile, .tilebtn { transition: background .15s, transform .1s; }
|
||||
.km-edit:hover { color: var(--fg); }
|
||||
.km-edit:active { color: var(--fg); transform: scale(.92); }
|
||||
|
||||
/* Zeile aus einer bearbeitbaren Liste entfernen (z. B. Selbstbeteiligung im
|
||||
Vertrag) - 44x44pt Tippflaeche per unsichtbarem ::before wie bei .km-edit,
|
||||
optisch bleibt nur das kleine × sichtbar. */
|
||||
.zeile-loeschen {
|
||||
position: relative;
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
width: 22px; height: 22px;
|
||||
border: none; background: none; color: var(--fg3);
|
||||
font-size: 18px; line-height: 1;
|
||||
padding: 0; cursor: pointer; flex: 0 0 auto;
|
||||
}
|
||||
.zeile-loeschen::before { content: ""; position: absolute; inset: -11px; }
|
||||
.zeile-loeschen:hover { color: var(--bad); }
|
||||
.zeile-loeschen:active { color: var(--bad); transform: scale(.92); }
|
||||
|
||||
/* Kompakte Pille statt voller Breite (Apple-HIG-Pull-down-Maß): normale
|
||||
Flusslage unter der Kachel-Überschrift/km, nicht mehr über dem Foto
|
||||
überlagert (das saß nur dort, solange Überschrift+km diesen Platz noch
|
||||
|
||||
@@ -1415,9 +1415,9 @@ function vAudi() {
|
||||
<svg class="go" viewBox="0 0 6 10"><polyline points="1,1 5,5 1,9"/></svg>
|
||||
<dl class="rows" style="margin-top:10px">
|
||||
<div class="row"><dt>Versicherung</dt><dd>${eur(CAR.versicherung.beitrag)} €<small>im Jahr</small></dd></div>
|
||||
<div class="row"><dt>Kfz-Steuer</dt><dd>${eur(CAR.steuer.betrag)} €<small>${esc(CAR.steuer.zeitraum)}</small></dd></div>
|
||||
<div class="row" style="border-bottom:0"><dt>Zusammen</dt>
|
||||
<dd>${eur(CAR.versicherung.beitrag + CAR.steuer.betrag)} €<small>feste Kosten im Jahr</small></dd></div>
|
||||
<div class="row"><dt>Kfz-Steuer</dt><dd>${eur(CAR.steuer.betrag)} €<small>${CAR.steuer.zeitraum === "jährlich" ? "im Jahr" : esc(CAR.steuer.zeitraum)}</small></dd></div>
|
||||
<div class="row" style="border-bottom:0"><dt>Summe</dt>
|
||||
<dd>${eur(CAR.versicherung.beitrag + CAR.steuer.betrag)} €</dd></div>
|
||||
</dl></button>
|
||||
<button class="tile tilebtn" data-go="reifen:x">
|
||||
<span class="label">Reifen · ${r.aktiv} montiert</span>
|
||||
@@ -1915,6 +1915,9 @@ function vVers() {
|
||||
</div>
|
||||
</div>
|
||||
<div class="tile"><span class="label">Vertrag</span>
|
||||
<button class="zahnrad" data-go="vertrag:x" aria-label="Vertrag bearbeiten">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M9.4 2h4.2v2.84c.37.13.75.27 1.11.44L16.7 3.3l3 3.01-1.98 1.99c.17.36.31.74.44 1.11H21v4.3h-2.84c-.13.37-.27.75-.44 1.11l2 2-3.03 2.89-1.98-1.98c-.36.17-.74.31-1.11.44V21H9.4v-2.84a9 9 0 0 1-1.11-.44L6.3 19.7l-3-3.01 1.98-1.99a9 9 0 0 1-.44-1.11H2V9.4h2.84c.13-.37.27-.75.44-1.11L3.3 6.3l3.01-3L8.3 5.28c.36-.17.74-.31 1.11-.44V2Zm1 1v2.56l-.34.11c-.61.2-1.16.4-1.6.66l-.34.2L6.3 4.71 4.7 6.3l1.83 1.82-.2.34c-.27.44-.45.99-.66 1.6l-.11.34H3v2.2h2.56l.11.34c.2.61.4 1.16.66 1.6l.2.34-1.82 1.82 1.59 1.6 1.82-1.83.34.2c.44.27.99.45 1.6.66l.34.11V20h2.2v-2.56l.34-.11a8.3 8.3 0 0 0 1.6-.66l.34-.2 1.83 1.83 1.57-1.5-1.81-1.82.2-.34c.27-.44.45-.99.66-1.6l.11-.34H20v-2.3h-2.56l-.11-.34a8.2 8.2 0 0 0-.66-1.6l-.2-.34 1.82-1.82-1.59-1.6-1.82 1.83-.34-.2a8.2 8.2 0 0 0-1.6-.66l-.34-.11V3zm-2.9 8.5c0-2.18 1.82-4 4-4s4 1.82 4 4-1.82 4-4 4-4-1.82-4-4m4-3c-1.62 0-3 1.38-3 3s1.38 3 3 3 3-1.38 3-3-1.38-3-3-3"/></svg>
|
||||
</button>
|
||||
<dl class="rows" style="margin-top:8px">
|
||||
<div class="row"><dt>Gesellschaft</dt><dd>${esc(v.gesellschaft)}</dd></div>
|
||||
<div class="row"><dt>Umfang</dt><dd>${esc(v.vertrag)}</dd></div>
|
||||
@@ -1976,6 +1979,40 @@ function vVertragsdetails() {
|
||||
</dl></div>`).join("")}`;
|
||||
}
|
||||
|
||||
function vVertragBearbeiten() {
|
||||
const v = CAR.versicherung;
|
||||
return `
|
||||
<div class="tile"><span class="label">Vertrag</span>
|
||||
<div class="feld"><label for="vGesellschaft">Gesellschaft</label>
|
||||
<input id="vGesellschaft" style="width:180px" value="${esc(v.gesellschaft)}" data-vvertrag="gesellschaft"></div>
|
||||
<div class="feld"><label for="vUmfang">Umfang</label>
|
||||
<input id="vUmfang" style="width:180px" value="${esc(v.vertrag)}" data-vvertrag="vertrag"></div>
|
||||
<div class="feld" style="border-bottom:0"><label for="vNummer">Vertragsnummer</label>
|
||||
<input id="vNummer" style="width:180px" value="${esc(v.nummer)}" data-vvertrag="nummer"></div>
|
||||
</div>
|
||||
<div class="tile" style="margin-top:26px"><span class="label">Selbstbeteiligung</span>
|
||||
${v.selbst.map(([b, w], i) => `
|
||||
<div class="feld" ${i === v.selbst.length - 1 ? 'style="border-bottom:0"' : ""}>
|
||||
<label for="vSelbstB${i}">Position ${i + 1}</label>
|
||||
<span style="display:inline-flex;align-items:center;gap:8px">
|
||||
<input id="vSelbstB${i}" style="width:100px" value="${esc(b)}" placeholder="Bezeichnung" data-vselbst="${i}|0">
|
||||
<input id="vSelbstW${i}" style="width:80px" value="${esc(w)}" placeholder="Betrag" data-vselbst="${i}|1">
|
||||
<button class="zeile-loeschen" data-vselbstdel="${i}" aria-label="Position ${i + 1} löschen">×</button>
|
||||
</span>
|
||||
</div>`).join("")}
|
||||
${!v.selbst.length ? `<span class="label" style="margin-top:8px">Keine Selbstbeteiligung hinterlegt</span>` : ""}
|
||||
<button class="aktion" data-vselbstadd>+ Position hinzufügen</button>
|
||||
</div>
|
||||
<div class="tile" style="margin-top:26px"><span class="label">Schadenfreiheitsklasse · zuvor</span>
|
||||
<div class="feld"><label for="vSfHaftAlt">Haftpflicht</label>
|
||||
<input id="vSfHaftAlt" style="width:132px" value="${esc(v.teile[0]?.sfAlt || "")}" data-vteil="0|sfAlt"></div>
|
||||
<div class="feld" style="border-bottom:0"><label for="vSfKaskoAlt">Vollkasko</label>
|
||||
<input id="vSfKaskoAlt" style="width:132px" value="${esc(v.teile[1]?.sfAlt || "")}" data-vteil="1|sfAlt"></div>
|
||||
<span class="label" style="margin-top:14px">Die aktuelle Schadenfreiheitsklasse änderst du unter
|
||||
"Beitrag anpassen" — hier steht nur der vorherige Wert für den Vergleich.</span>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function vSchutz() {
|
||||
const v = CAR.versicherung, sb = v.schutzbrief;
|
||||
return `
|
||||
@@ -2028,7 +2065,7 @@ function vSteuer() {
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M9.4 2h4.2v2.84c.37.13.75.27 1.11.44L16.7 3.3l3 3.01-1.98 1.99c.17.36.31.74.44 1.11H21v4.3h-2.84c-.13.37-.27.75-.44 1.11l2 2-3.03 2.89-1.98-1.98c-.36.17-.74.31-1.11.44V21H9.4v-2.84a9 9 0 0 1-1.11-.44L6.3 19.7l-3-3.01 1.98-1.99a9 9 0 0 1-.44-1.11H2V9.4h2.84c.13-.37.27-.75.44-1.11L3.3 6.3l3.01-3L8.3 5.28c.36-.17.74-.31 1.11-.44V2Zm1 1v2.56l-.34.11c-.61.2-1.16.4-1.6.66l-.34.2L6.3 4.71 4.7 6.3l1.83 1.82-.2.34c-.27.44-.45.99-.66 1.6l-.11.34H3v2.2h2.56l.11.34c.2.61.4 1.16.66 1.6l.2.34-1.82 1.82 1.59 1.6 1.82-1.83.34.2c.44.27.99.45 1.6.66l.34.11V20h2.2v-2.56l.34-.11a8.3 8.3 0 0 0 1.6-.66l.34-.2 1.83 1.83 1.57-1.5-1.81-1.82.2-.34c.27-.44.45-.99.66-1.6l.11-.34H20v-2.3h-2.56l-.11-.34a8.2 8.2 0 0 0-.66-1.6l-.2-.34 1.82-1.82-1.59-1.6-1.82 1.83-.34-.2a8.2 8.2 0 0 0-1.6-.66l-.34-.11V3zm-2.9 8.5c0-2.18 1.82-4 4-4s4 1.82 4 4-1.82 4-4 4-4-1.82-4-4m4-3c-1.62 0-3 1.38-3 3s1.38 3 3 3 3-1.38 3-3-1.38-3-3-3"/></svg>
|
||||
</button>
|
||||
<dl class="rows" style="margin-top:10px">
|
||||
<div class="row"><dt>Betrag</dt><dd>${eur(t.betrag)} €<small>${esc(t.zeitraum)}</small></dd></div>
|
||||
<div class="row"><dt>Betrag</dt><dd>${eur(t.betrag)} €<small>${t.zeitraum === "jährlich" ? "im Jahr" : esc(t.zeitraum)}</small></dd></div>
|
||||
<div class="row" style="border-bottom:0"><dt>Nächste Fälligkeit</dt>
|
||||
<dd>${t.faellig ? dedat(new Date(t.faellig)) : "unbekannt"}</dd></div>
|
||||
</dl>
|
||||
@@ -3157,6 +3194,7 @@ let route = { name: "home" };
|
||||
const ZURUECK = {
|
||||
trip: "trips", fill: "fuel", service: "audi", reifen: "audi", ident: "audi",
|
||||
vers: "audi", beitrag: "vers", vertragsdetails: "vers", schutz: "vertragsdetails",
|
||||
vertrag: "vers",
|
||||
steuer: "vers", notruf: "vers", werkstatt: "service", sbuch: "service", einst: "home",
|
||||
battverlauf: "audi",
|
||||
/* Fehlte: die Sicherheitsansicht war eine Sackgasse ohne sichtbaren
|
||||
@@ -3439,6 +3477,7 @@ function render() {
|
||||
else if (route.name === "vers") { head = ["Fahrzeug", "Versicherung/Steuer"]; v.innerHTML = vVers(); }
|
||||
else if (route.name === "beitrag") { head = ["Versicherung", "Beitrag anpassen"]; v.innerHTML = vBeitrag(); }
|
||||
else if (route.name === "vertragsdetails") { head = ["Versicherung", "Vertragsdetails"]; v.innerHTML = vVertragsdetails(); }
|
||||
else if (route.name === "vertrag") { head = ["Versicherung", "Vertrag"]; v.innerHTML = vVertragBearbeiten(); }
|
||||
else if (route.name === "steuer") { head = ["Versicherung", "Kfz-Steuer"]; v.innerHTML = vSteuerBearbeiten(); }
|
||||
else if (route.name === "notruf") { head = ["Versicherung", "Rufnummern"]; v.innerHTML = vNotrufBearbeiten(); }
|
||||
else if (route.name === "schutz") { head = ["Im Ernstfall", "Schutzbrief"]; v.innerHTML = vSchutz(); }
|
||||
@@ -4105,6 +4144,9 @@ function ereignisseVerdrahten() {
|
||||
}
|
||||
const del = e.target.closest("[data-loeschen]");
|
||||
if (del) { delete CAR.service.vereinbart[del.dataset.loeschen]; profilSpeichern(); render(); return; }
|
||||
const vseldel = e.target.closest("[data-vselbstdel]");
|
||||
if (vseldel) { CAR.versicherung.selbst.splice(+vseldel.dataset.vselbstdel, 1); profilSpeichern(); render(); return; }
|
||||
if (e.target.closest("[data-vselbstadd]")) { CAR.versicherung.selbst.push(["", ""]); profilSpeichern(); render(); return; }
|
||||
const oel = e.target.closest("[data-oel]");
|
||||
if (oel) { CAR.oel.modus = oel.dataset.oel; profilSpeichern(); render(); return; }
|
||||
const mode = e.target.closest("[data-mode]");
|
||||
@@ -4363,6 +4405,14 @@ function ereignisseVerdrahten() {
|
||||
if (e.target.dataset.vgueltigab !== undefined) { CAR.versicherung.gueltigAb = e.target.value; profilSpeichern(); render(); return; }
|
||||
const vnotruf = e.target.dataset.vnotruf;
|
||||
if (vnotruf) { CAR.versicherung[vnotruf] = e.target.value; profilSpeichern(); render(); return; }
|
||||
const vvertrag = e.target.dataset.vvertrag;
|
||||
if (vvertrag) { CAR.versicherung[vvertrag] = e.target.value; profilSpeichern(); render(); return; }
|
||||
const vselbst = e.target.dataset.vselbst;
|
||||
if (vselbst) {
|
||||
const [i, feld] = vselbst.split("|");
|
||||
CAR.versicherung.selbst[+i][+feld] = e.target.value;
|
||||
profilSpeichern(); render(); return;
|
||||
}
|
||||
if (e.target.dataset.pause !== undefined) { CONFIG.pauseMin = parseInt(e.target.value, 10) || 0; profilSpeichern(); return; }
|
||||
if (e.target.dataset.sd !== undefined) {
|
||||
if (e.target.checked) { smartdealPopupOffen = true; render(); }
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version": 1787013003}
|
||||
{"version": 1787014000}
|
||||
|
||||
@@ -1044,6 +1044,21 @@ button.tile, .tilebtn { transition: background .15s, transform .1s; }
|
||||
.km-edit:hover { color: var(--fg); }
|
||||
.km-edit:active { color: var(--fg); transform: scale(.92); }
|
||||
|
||||
/* Zeile aus einer bearbeitbaren Liste entfernen (z. B. Selbstbeteiligung im
|
||||
Vertrag) - 44x44pt Tippflaeche per unsichtbarem ::before wie bei .km-edit,
|
||||
optisch bleibt nur das kleine × sichtbar. */
|
||||
.zeile-loeschen {
|
||||
position: relative;
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
width: 22px; height: 22px;
|
||||
border: none; background: none; color: var(--fg3);
|
||||
font-size: 18px; line-height: 1;
|
||||
padding: 0; cursor: pointer; flex: 0 0 auto;
|
||||
}
|
||||
.zeile-loeschen::before { content: ""; position: absolute; inset: -11px; }
|
||||
.zeile-loeschen:hover { color: var(--bad); }
|
||||
.zeile-loeschen:active { color: var(--bad); transform: scale(.92); }
|
||||
|
||||
/* Kompakte Pille statt voller Breite (Apple-HIG-Pull-down-Maß): normale
|
||||
Flusslage unter der Kachel-Überschrift/km, nicht mehr über dem Foto
|
||||
überlagert (das saß nur dort, solange Überschrift+km diesen Platz noch
|
||||
|
||||
Reference in New Issue
Block a user