/* audi-dashboard.css — Stil des Panels, aufgebaut auf den Tokens und Komponenten des Design-Systems AudiDashUI (_ds_bundle.css). Klassennamen wie im Prototyp/Panel (unpräfixiert), Werte 1:1 aus dem Design-System. */ :host { --red: #F50537; --r-tile: 20px; --r-pill: 999px; --r-func: 8px; --rahmen-hg: #111; --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 22px; --canvas: #161b23; --tile: #1f2733; --tile-2: #2a3341; --line: rgba(255,255,255,.10); --line-strong: rgba(255,255,255,.20); --fg: #FFFFFF; --fg2: #9aa1ad; /* A2: von #657081 (3,0:1 auf --tile) auf 4,6:1 angehoben. Unterhalb von 12 px wird diese Farbe nicht mehr verwendet. */ --fg3: #8a94a3; --ok: #15da15; --warn: #ffaa00; --bad: #fd2c4e; --shade: rgba(255,255,255,.05); --font-stack: "Audi Type", Helvetica, Arial, sans-serif; /* Bugfix: in der echten HA-Einbettung liefert partial-panel-resolver (display:inline, height:auto) keine definierte Höhe - eine height:100%-Kette von hier nach oben rechnet also gegen eine Auto-Box und kollabiert auf die Inhaltshöhe (nur Topbar+Tabbar sichtbar, main#view ohne Fläche zum Scrollen). Deshalb wie im ursprünglichen Prototyp direkt an der Viewport-Höhe verankert, unabhängig von der Elternkette - und zentriert wie eine Telefon-Karte, statt randlos zu füllen. */ display: flex; align-items: center; justify-content: center; height: 100vh; height: 100dvh; overflow: hidden; } :host([data-theme=tag]) { --canvas: #FFFFFF; --tile: #f2f2f2; --tile-2: #e5e5e5; --line: rgba(0,0,0,.10); --line-strong: rgba(0,0,0,.22); --fg: #000000; --fg2: #4c4c4c; --fg3: #666666; --ok: #0DA20D; --warn: #ffaa00; --bad: #eb0d3f; --shade: rgba(0,0,0,.04); } * { box-sizing: border-box; } /* Sichtbarer Tastatur-Fokus. Bis hierher gab es .feld input:focus als einzige Fokus-Regel im ganzen Blatt - alle Knöpfe, Kacheln und Tabs waren zwar fokussierbar, aber ohne jede sichtbare Markierung. Auf dem Telefon fällt das nicht auf, per Bluetooth-Tastatur (iPadOS/Desktop über Tailscale) oder mit iOS-Vollzugriff per Tastatur ist die App dadurch praktisch unbedienbar. :focus-visible statt :focus, damit Maus- und Tipp-Bedienung unverändert ohne Rahmen bleibt - der Browser entscheidet, was "echte" Tastaturnavigation ist. */ :focus-visible { outline: 2px solid var(--red); outline-offset: 2px; border-radius: 2px; } /* Zwischen-Wrapper, den _aufbauen() in den Shadow Root haengt - bekommt hier die einzige "echte" (viewport-verankerte) Höhe der ganzen Kette; .phone darunter kann sich dann gefahrlos mit height:100% darauf beziehen. */ :host > div { width: 100%; max-width: 412px; height: min(880px, calc(100vh - 24px)); height: min(880px, calc(100dvh - 24px)); min-height: 0; /* Verhindert, dass eine Zieh-Geste, die main#view unten nach oben hin verlaesst, an die dahinterliegende HA-Seite weitergereicht wird - sonst kann der Browser selbst ein natives Overscroll/Pull-to-Refresh starten und der eigene Ziehen-zum-Aktualisieren-Indikator bekommt die Geste nie zu Ende. */ overscroll-behavior: none; } /* ------------------------------------------------------------- Gerüst */ .phone { display: flex; flex-direction: column; height: 100%; min-height: 0; /* B4: Bezugsrahmen für Action Sheet und Popups. */ position: relative; background: var(--canvas); color: var(--fg); font-family: var(--font-stack); font-variant-numeric: tabular-nums; overflow: hidden; /* B2: kein graues Safari-Rechteck beim Tippen - Rückmeldung kommt aus den :active-Regeln unten. */ -webkit-tap-highlight-color: transparent; } .topbar { display: flex; align-items: center; gap: var(--sp-3); /* B1: oben Platz für Statusbalken/Dynamic Island. */ padding: max(22px, calc(env(safe-area-inset-top) + 10px)) 20px 14px; flex: 0 0 auto; background: var(--canvas); } .back { /* B6: 44 px Trefferfläche. */ width: 44px; height: 44px; margin-left: -5px; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; border: none; border-radius: 50%; background: none; color: var(--fg3); cursor: pointer; padding: 0; opacity: 0; pointer-events: none; } .back.on { opacity: 1; pointer-events: auto; } .back:hover { background: var(--tile-2); color: var(--fg); } .back:active { background: var(--tile-2); color: var(--fg); transform: scale(.92); } .head { flex: 1; min-width: 0; } .eyebrow { font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--fg3); min-height: 12px; } .title { font-size: 23px; letter-spacing: -.015em; line-height: 1.15; color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .sync { display: flex; align-items: center; gap: 6px; margin-top: 4px; font-size: 11px; color: var(--fg3); white-space: nowrap; } .themebtn, .rings { display: inline-flex; align-items: center; justify-content: center; border: none; background: none; color: var(--fg3); cursor: pointer; padding: 0; flex: 0 0 auto; } .themebtn { width: 44px; height: 44px; border-radius: 50%; } /* A6: Die Topbar-Taste ist entfallen - die Wahl liegt in den Einstellungen und folgt sonst der Systemeinstellung. display:inline-flex oben würde das hidden-Attribut sonst überstimmen. */ .themebtn[hidden] { display: none; } .themebtn:hover { background: var(--tile-2); color: var(--fg); } .themebtn:active { background: var(--tile-2); color: var(--fg); transform: scale(.92); } .themebtn svg { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; } /* Wie .themebtn (44px Trefferflaeche), aber ohne die Kontur-Stroke-Regel - fuer CI-Symbole (ciSVG()), deren Pfade ihr eigenes fill="currentColor" mitbringen (z. B. list-s im Kopf der Batteriespannungs-Kachel). */ .iconbtn { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 50%; border: none; background: none; color: var(--fg3); cursor: pointer; padding: 0; flex: 0 0 auto; } .iconbtn:hover { background: var(--tile-2); color: var(--fg); } .iconbtn:active { background: var(--tile-2); color: var(--fg); transform: scale(.92); } /* "Neue Räder anlegen" auf der Reifen-Seite: bewusst dauerhaft mit sichtbarem Hintergrund statt nur bei Hover/Tap wie .iconbtn sonst - sitzt direkt neben dem gefüllten "Montiert"-Knopf und wirkt ohne eigene Fläche zu unscheinbar, um dort als eigenständiger Knopf erkannt zu werden. */ .archivbtn { background: var(--tile-2); color: var(--fg2); } .archivbtn:hover, .archivbtn:active { color: var(--fg); } /* D4 war urspruenglich: die Ringe sind Marke, kein Knopf. Seit die iOS-Auflage in Telefonbreite das Zahnrad ausblendet, sind sie dort aber der einzige Zugang zu den Einstellungen - und als reines div mit pointer-events:none war dieser Zugang fuer Tastatur und Sprachausgabe gar nicht erreichbar. Sie sind deshalb jetzt ein echter Knopf, in jeder Breite bedienbar. Auf grossen Bildschirmen gibt es damit zwei Wege in die Einstellungen (Ringe und Zahnrad) - unschaedlich, und der Zugang haengt nicht mehr davon ab, ob audi-dashboard-ios.css geladen wurde. */ /* Design-Audit 2026-08-13: in Telefonbreite ist dies der einzige Zugang zu den Einstellungen (siehe Kommentar oben), war mit 42px aber deutlich kleiner als jeder andere Symbol-Knopf in der Kopfzeile (.themebtn/ .profilbtn/.back sind alle 44px) und lag damit unter der ueblichen 44px-Mindestgroesse fuer Tippflaechen. */ .rings { width: 58px; height: 32px; color: var(--fg); } .rings svg { width: 58px; height: auto; } /* Der Markenklon in der Seitenleiste wird vom Skript unbedingt in die Menueleiste gehaengt; sichtbar macht ihn erst die iOS-Auflage ab 860px. Das Verstecken gehoert deshalb hierher: laedt die Auflage nicht (404, Cache), waere er sonst ein sechstes Element im fuenfspaltigen Raster und die Menueleiste zerfiele. */ .navmarke { display: none; } .profilbtn { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 50%; border: none; background: var(--tile); color: var(--fg2); cursor: pointer; padding: 0; flex: 0 0 auto; } .profilbtn svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; } .profilbtn:hover { color: var(--fg); } .profilbtn:active { background: var(--tile-2); color: var(--fg); transform: scale(.94); } .ptr { height: 0; overflow: hidden; display: flex; align-items: center; justify-content: center; gap: 8px; color: var(--fg3); font-size: 12.5px; transition: height .2s; flex: 0 0 auto; } .ptr.spin svg { animation: drehen 1s linear infinite; } @keyframes drehen { to { transform: rotate(360deg); } } main#view { /* Der seitliche Rand steht als Variable, weil randlose Elemente ihn per negativem Rand ausgleichen muessen (siehe .standort-vollbild). Wer das Padding aendert, ohne die Variable zu benutzen, verschiebt die randlosen Elemente unbemerkt. */ --seitenrand: 20px; flex: 1 1 0; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: 10px var(--seitenrand) 34px; scroll-behavior: smooth; -webkit-overflow-scrolling: touch; scrollbar-width: none; /* Ohne das hier greift auf echten Touch-Geraeten oft das native Overscroll/Pull-to-Refresh des Browsers, sobald am oberen Rand weiter nach unten gezogen wird - das nimmt der eigenen "Ziehen zum Aktualisieren"-Geste (siehe ptrY0-Logik in ereignisseVerdrahten()) die Kontrolle weg, obwohl deren JS/CSS für sich genommen korrekt arbeitet. */ overscroll-behavior-y: contain; } main#view::-webkit-scrollbar { width: 0; height: 0; } #overlay:empty { display: none; } .tabbar { display: grid; grid-template-columns: repeat(5, 1fr); border-top: 1px solid var(--line); flex: 0 0 auto; background: var(--canvas); /* B1: Luft über dem Home-Indikator. */ padding-bottom: max(6px, env(safe-area-inset-bottom)); } /* B5: kein roter Oberkantenstrich (Desktop-Muster), sondern eine gefüllte Pille um das aktive Symbol - wie in der myAudi-App. */ .tab { display: flex; flex-direction: column; align-items: center; gap: 7px; padding: 12px 0 10px; background: none; border: none; color: var(--fg3); font-family: inherit; cursor: pointer; transition: color .15s; } .tab.on { color: var(--fg); } /* Die Pille ist ein eigenes Feld um das Symbol - so bleibt ihre Groesse unabhaengig vom Symbol und der Wechsel laeuft sauber ueber background. */ .tabpille { display: flex; align-items: center; justify-content: center; width: 60px; height: 34px; border-radius: var(--r-pill); transition: background .18s; } .tab.on .tabpille { background: var(--tile-2); } .tab svg { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; transition: transform .18s; } .tab svg.voll { fill: currentColor; stroke: none; } .tab:active svg { transform: scale(.9); } .tab span { font-size: 11px; letter-spacing: .01em; } /* :not(.tabpille) - die Icon-Huelle ist selbst ein , ein blosses ".tab span" hier hiess frueher auch der Pille (samt Icon) display:none. Ueberschrieben von derselben Regel in audi-dashboard-ios.css (dieselbe Spezifitaet, spaeter geladen), aber auch hier falsch und daher fixiert. */ .tabbar.ohne .tab span:not(.tabpille) { display: none; } .tabbar.ohne .tab { padding: 14px 0 12px; } .tabbar.ohne .tab svg { width: 26px; height: 26px; } /* -------------------------------------------------------------- Kacheln */ .tile { background: var(--tile); border-radius: var(--r-tile); padding: var(--sp-5); margin-bottom: var(--sp-4); position: relative; } .tile.flat { background: none; padding: 0; } button.tile, .tilebtn { display: block; width: 100%; border: none; font-family: inherit; text-align: left; cursor: pointer; color: inherit; } button.tile:hover { background: var(--tile-2); } button.tile:active, .tilebtn:active { background: var(--tile-2); transform: scale(.99); } button.tile, .tilebtn { transition: background .15s, transform .1s; } .go { position: absolute; top: var(--sp-5); right: var(--sp-5); width: 6px; height: 10px; color: var(--fg3); fill: none; stroke: currentColor; stroke-width: 1.4; } .zahnrad { position: absolute; top: 11px; right: 11px; width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center; border: none; border-radius: 50%; background: none; color: var(--fg3); cursor: pointer; padding: 0; } .zahnrad:hover { background: var(--tile-2); color: var(--fg); } .zahnrad:active { background: var(--tile-2); color: var(--fg); transform: scale(.92); } .zahnrad svg { width: 17px; height: 17px; } /* Titelzeile nie unter dem Zahnrad/Chevron hindurchlaufen lassen */ .tile:has(> .zahnrad) > .label:first-child, .tile:has(> .go) > .label:first-child { padding-right: 44px; } /* C1: Abschnittstitel gemischt geschrieben, 14 px, ohne Sperrung - wie in der aktuellen myAudi-App. Versalien trägt nur noch .eyebrow über dem Seitentitel. */ .label { font-size: 14px; letter-spacing: normal; color: var(--fg2); display: block; line-height: 1.3; } /* HIG "Loading": statt reinem Text ein sichtbar laufender Indikator, solange DATEN_GELADEN false ist - hilft auch, "lädt noch" optisch von "hängt fest" zu unterscheiden (dieser Bildschirm hatte schon ein echtes Hänger-Problem). */ .lade-spinner { width: 16px; height: 16px; flex: none; border: 2px solid var(--line-strong); border-top-color: var(--fg2); border-radius: 50%; animation: lade-spin .8s linear infinite; } @keyframes lade-spin { to { transform: rotate(360deg); } } /* Echte Überschrift innerhalb einer Kachel (z.B. "Sommerräder"/"Winterräder") statt des sonst üblichen kleinen, gedämpften .label-Abschnittstitels - selbe Typografie-Stufe wie .title (Seitentitel), nur etwas kleiner, weil sie innerhalb einer Kachel steht statt in der Kopfzeile. */ .tile-headline { font-size: 20px; letter-spacing: -.01em; line-height: 1.2; color: var(--fg); display: block; } /* Icon + Text statt reinem Fließtext-Label (z.B. Batterie-Symbol vor "Ruhespannung") - dieselbe Zeilen-Geometrie wie .sync in der Kopfzeile. */ .bv-skala-kopf { display: flex; align-items: center; gap: 6px; } /* A4: Messwerte erben nie mehr das uppercase der Label-Klasse. */ .wert { font-size: 14px; letter-spacing: normal; text-transform: none; color: var(--fg2); } .fig { font-family: "Audi Type Wide", var(--font-stack); font-weight: 300; letter-spacing: -.02em; line-height: .95; color: var(--fg); } .fig .unit { /* A3: relativ zur Zahl, aber nie unter der Lesbarkeitsgrenze - bei einer 29-px-Zahl ergäbe .32em nur 9,3 px. */ font-size: max(11px, .32em); font-weight: 400; letter-spacing: normal; color: var(--fg2); margin-left: .32em; } .werte { font-size: 14px; color: var(--fg); display: block; } .rows { margin: 0; } .row { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-4); padding: 15px 0; border-bottom: 1px solid var(--line); } .row dt { font-size: 13px; color: var(--fg2); line-height: 1.4; } .row dd { margin: 0; font-size: 14px; color: var(--fg); text-align: right; } .row dd small { display: block; font-size: 12.5px; color: var(--fg3); margin-top: 3px; } .rows-fest dd { min-width: 120px; } /* .row-fussnote ist mit dem Umbau der Service-Seite auf .termingruppe entfallen (2026-08-18) - dort gibt es keine dt/dd-Spalten mehr, die um Platz konkurrieren. Die beiden Regeln dafuer standen seither ohne passendes Markup da. */ /* Sammelzeilen der Sicherheit-Ansicht (vSicherheit()): Kreis-Häkchen + Text + optionaler Chevron statt dt/dd. Erbt Abstand/Trennlinie von .row, ersetzt aber dessen space-between-Layout und setzt die Button-Vorgaben zurück, wenn die Zeile klickbar ist (Türen und Klappen). */ .sicherheitszeile { justify-content: flex-start; width: 100%; background: none; border: none; border-bottom: 1px solid var(--line); font: inherit; color: inherit; text-align: left; cursor: default; } button.sicherheitszeile { cursor: pointer; } button.sicherheitszeile:active { background: var(--tile-2); } .sicherheitsliste .sicherheitszeile:last-child { border-bottom: 0; } .sicherheitszeile-text { flex: 1; font-size: 14px; color: var(--fg); } .sicherheitszeile .chev { margin-left: auto; } /* Wert als Kommentar statt als Angabe - fuer Zeilen, deren rechte Seite nur beschreibt, was hinter der Kachel liegt (Mein Audi, "Details"). Groesse und Farbe wie jede andere Nebenzeile. */ .row dd.row-hinweis { font-size: 12.5px; color: var(--fg3); } .leaf { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); width: 100%; background: none; border: none; font-family: inherit; text-align: left; padding: 14px 0 14px 40px; min-height: 56px; border-bottom: 1px solid var(--line); color: inherit; } .leaf .k { font-size: 14px; color: var(--fg); display: flex; flex-direction: column; gap: 3px; line-height: 1.35; } .leaf .k small { font-size: 12.5px; color: var(--fg3); } .leaf .v { font-size: 13px; color: var(--fg2); text-align: right; display: flex; flex-direction: column; gap: 3px; flex: 0 0 auto; } .leaf .v small { font-size: 12.5px; color: var(--fg3); } /* .teaser (die "Zuletzt"-Kachel auf der Übersicht, teaser()): genau zwei Zeilen mit sehr unterschiedlich breiten Werten ("offen" vs. "51,59 l") - .v ist sonst flex:0 0 auto und damit genau so breit wie sein eigener Inhalt, wodurch die linke Kante des Wertes je Zeile unterschiedlich weit rechts beginnt (rechte Kante bleibt an der Chevron-Spalte gleich, das täuscht Ausrichtung nur vor). min-width sorgt für eine gemeinsame Spaltenbreite, damit beide Werte auf derselben linken Kante beginnen. Das allein reicht aber nicht: .leaf selbst verteilt seine drei Kinder (.k/.v/Chevron) per justify-content:space-between, und .k hat kein flex-grow - unterschiedlich lange Beschriftungen ("→" vs. "Hermann Mogler Mineralölg. GmbH") verschieben dadurch die GESAMTE restliche Zeile (.v + Chevron) um die Differenz, obwohl .v selbst jetzt gleich breit ist. .k bekommt deshalb flex:1, damit es den verbleibenden Platz füllt und .v dadurch wirklich immer am selben Abstand vom rechten Rand sitzt. */ .teaser .leaf .k { flex: 1 1 auto; min-width: 0; } .teaser .leaf .v { min-width: 72px; } /* cursor/:active nur für echte .leaf-Buttons (data-go, navigieren bei Klick) - die Batterie-Messwertliste (vBatterieliste()) ist bewusst ein reines
, keine Zeilennavigation, nur Wischen zum Löschen; sie soll deshalb weder den Hand-Cursor noch die Tipp-Rückmeldung zeigen, die sonst "hier passiert beim Klick etwas" versprechen. */ button.leaf { cursor: pointer; transition: background .15s; } button.leaf:active { background: var(--tile-2); } .chev { width: 6px; height: 10px; color: var(--fg3); flex: 0 0 auto; fill: none; stroke: currentColor; stroke-width: 1.4; } /* ------------------------------------------------------------- Status */ .status { display: flex; align-items: center; gap: var(--sp-3); width: 100%; background: none; border: none; padding: 16px 0 0; min-height: 44px; text-align: left; font-family: inherit; cursor: pointer; color: inherit; } .dot { width: 11px; height: 11px; border-radius: 50%; flex: 0 0 auto; background: var(--ok); display: inline-block; } .dot.warn { background: var(--warn); } .dot.bad { background: var(--bad); } /* Kreis-Häkchen statt einfarbigem Punkt - für die Sicherheit-Ansicht (vSicherheit()/vTuerenKlappen()), nach Nutzer-Vorlage: erfüllt/offen/ unbekannt sofort am Symbol erkennbar, nicht nur an der Farbe. */ .statuskreis { width: 22px; height: 22px; border-radius: 50%; flex: 0 0 auto; background: var(--ok); display: inline-flex; align-items: center; justify-content: center; } .statuskreis.warn { background: var(--warn); } .statuskreis.bad { background: var(--bad); } .status .t { font-size: 14px; color: var(--fg); } .status { transition: opacity .15s; } .status:active { opacity: .55; } /* -------------------------------------------------------------- Übersicht */ .tankzeile { display: flex; align-items: flex-end; justify-content: space-between; gap: 14px; margin-bottom: 14px; } .pct { font-size: 15px; color: var(--fg2); padding-bottom: 6px; } .balken { height: 4px; border-radius: var(--r-pill); background: var(--line); overflow: hidden; } .balken i { display: block; height: 100%; background: var(--fg); border-radius: var(--r-pill); } /* Der Außenabstand sitzt am Raster, nicht an den Kacheln - sonst wird er im 2×2-Raster (vHome) zum zusätzlichen internen Zeilenabstand und der Abstand innerhalb der Gruppe wäre größer als der zur nächsten. */ /* Übersicht: "Nächster Service" als tippbare Kennzahl, darunter der Kilometerstand als Wertezeile (siehe Kommentar in vHome()). Der Knopf sitzt INNERHALB einer normalen .tile - nicht die Kachel selbst ist der Knopf, sondern nur ihr oberer Teil, damit die Kilometerstand-Zeile erkennbar reine Anzeige bleibt. Der Chevron steht deshalb auf right:0 relativ zum Knopf und landet damit genau auf demselben Innenabstand wie ein normales .go in einer gepolsterten Kachel. */ .serviceblock { position: relative; display: block; width: 100%; border: 0; background: none; padding: 0; font-family: inherit; text-align: left; color: inherit; cursor: pointer; } .serviceblock > .go { top: 3px; right: 0; } /* Rückmeldung beim Tippen: ein Hintergrundwechsel wie bei .tilebtn ginge hier nicht, der Knopf liegt ja schon auf der Kachelfläche. */ .serviceblock:active { opacity: .55; } /* Beschriftung nie unter dem Chevron hindurchlaufen lassen */ .serviceblock > .label:first-child { padding-right: 24px; } /* Serviceart-Icon links der Kennzahl statt des Wortes "bis zum/zur ...". */ .fig-zeile { display: flex; align-items: center; gap: 8px; margin-top: 8px; } .fig-zeile svg { color: var(--fg2); flex: 0 0 auto; } .servicezeile { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-4); border-top: 1px solid var(--line); margin-top: 14px; padding-top: 13px; } /* Anstehende Termine (vService): drei sichtbar getrennte Bloecke statt einer dt/dd-Liste - Apple HIG ("essential information... don't obscure it by crowding it with nonessential details") plus Audi-CI (Flaeche mit Haarlinien statt Karten, eigene Groessenklasse fuer Zahlen). Trennung ueber Abstand und eine Haarlinie zwischen den Bloecken, nicht ueber verschachtelte Kacheln. Jeder Block: Kopfzeile (Icon + Art-Name, optional ein Chip fuer einen vereinbarten Werkstatttermin), optionale Herstellervorgabe-Zeile, der Wert, optional die eigene Prognose als Fusszeile. */ .termingruppe { padding: 18px 0; border-top: 1px solid var(--line); } .termingruppe:first-of-type { padding-top: 2px; border-top: 0; } .tg-kopf { display: flex; align-items: center; justify-content: space-between; gap: 10px; } .tg-name { display: flex; align-items: center; gap: 9px; min-width: 0; } .tg-name svg { color: var(--fg2); flex: 0 0 auto; } .tg-name span { font-size: 16px; color: var(--fg); font-weight: 400; } /* Chip statt rotem Fliesstext fuer einen vereinbarten Werkstatttermin - Rot bleibt Akzent (Text/Rahmen), nie Flaeche, wie im Rest der App. */ .tg-chip { font-size: 10.5px; color: var(--red); border: 1px solid var(--red); border-radius: var(--r-pill); padding: 3px 8px; white-space: nowrap; flex: 0 0 auto; } .tg-vorgabe { font-size: 12.5px; color: var(--fg2); margin-top: 8px; } .tg-wert { font-family: "Audi Type Wide", var(--font-stack); font-weight: 300; font-size: 22px; color: var(--fg); letter-spacing: -.005em; margin-top: 4px; } .tg-wert.leer { font-family: var(--font-stack); font-weight: 400; font-size: 15px; color: var(--fg3); margin-top: 8px; } .tg-prognose { font-size: 12.5px; color: var(--fg2); margin-top: 6px; } .badge { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; } .badge img { height: 18px; width: auto; display: none; } :host([data-theme=nacht]) .badge img.negative { display: block; } :host([data-theme=tag]) .badge img.positive { display: block; } .badge .zusatz { font-size: 13px; color: var(--fg2); } .szene { position: relative; padding: 8px 0 18px; } /* C5: randloses Fahrzeugbild - hebt die 20 px Seitenrand von main#view auf und blendet nach unten in die Fläche aus. */ .szene.bleed { margin: -10px -20px 0; padding: 0 0 10px; } .szene.bleed .carbox { padding: 0 8px; } /* Der Ausblend-Verlauf und der Bodenschatten sind am 2026-08-31 entfallen. Beide lagen ueber dem unteren Teil des Fotos, und der Eigentuemer hat zweimal darum gebeten, das Fahrzeug unverdeckt zu sehen. Zurueckholen waere ein linear-gradient auf .szene.bleed::before bzw. ein radial-gradient auf .szene.strasse::after - beides steht in der Versionsgeschichte. */ .carbox { position: relative; } .carfix { width: 100%; aspect-ratio: 16 / 9; } /* Das Fahrzeugfoto wird nicht mehr beschnitten. Gemessen am echten Foto (2026-08-31): es ist 2000x1125 gross, also 16:9. Der Kasten stand auf 16:8 - bei object-fit:cover wurde das Bild auf die Kastenbreite skaliert und oben wie unten je ein Viertel abgeschnitten (796x220 Kasten, 796x448 skaliertes Bild). Das Dach lag darin. Statt das Seitenverhaeltnis auf 16:9 festzuschreiben - was beim naechsten Foto in einem anderen Format wieder schneiden wuerde - bestimmt jetzt das Bild selbst die Hoehe. Der Platzhalter behaelt sein festes Verhaeltnis, er hat ja keines von sich aus. */ .bildbox.carfix.klein { aspect-ratio: auto; height: auto; } img.carfix.klein { aspect-ratio: auto; height: auto; } /* Reifenfoto ist oft eine breite Aufnahme; statt beide Ränder symmetrisch wegzuschneiden (object-fit:cover-Standard), bleibt bewusst der rechte Rand des Originalfotos erhalten - dort sitzt das Rad meist im Bild. */ .radbild { object-position: right center; } /* .bildbox.radbild statt .radbild allein: .bildbox unten setzt width/aspect- ratio auf derselben Spezifitaet (eine Klasse) und gewinnt als spaeter notierte Regel sonst automatisch - die Box blieb dadurch bislang die volle Kachelbreite im 4:3-Format statt eines echten 96x96-Quadrats. Rechtsbündig sitzt es jetzt ueber .radkopf-row (display:flex; justify-content:space- between), kein margin-left:auto mehr noetig. */ .bildbox.radbild { width: 96px; height: 96px; aspect-ratio: 1 / 1; } .bildbox { position: relative; width: 100%; aspect-ratio: 4 / 3; border-radius: 12px; overflow: hidden; } .bildbox img { display: block; width: 100%; height: 100%; object-fit: cover; } .bildbox .platzhalter { display: none; position: absolute; inset: 0; } .bildbox.bild-fehlt img { display: none; } .bildbox.bild-fehlt .platzhalter { display: flex; } /* D1: Solange kein Foto vorliegt, bleibt die Bildfläche flach - vorher standen 260 px gestrichelte Leerfläche vor der Reichweite, der wichtigsten Zahl der App. Mit Foto gilt wieder das volle Seitenverhältnis. */ .bildbox.bild-fehlt.carfix { aspect-ratio: auto; height: 132px; } /* Der Platzhalter belegt denselben Kasten wie ein echtes Foto (16:8). Er war zwischenzeitlich auf 120 und dann 72px gestaucht, um die Reichweite hoeher zu ruecken - auf Ansage des Besitzers steht er wieder in voller Groesse, weil ein Streifen nicht erkennen laesst, was dort hingehoert. */ .bildbox.bild-fehlt.carfix.klein { aspect-ratio: 16 / 8; height: auto; } .szene.bleed:has(.bild-fehlt)::before { display: none; } .szene.bleed:has(.bild-fehlt) { margin-left: 0; margin-right: 0; } .szene.bleed:has(.bild-fehlt) .carbox { padding: 0; } /* A5/C5: kein gestrichelter Rahmen und kein Dateiname mehr - Motivname plus Aufforderung, die Fläche ist tippbar. */ .platzhalter { width: 100%; height: 100%; flex-direction: column; align-items: center; justify-content: center; gap: 7px; background: var(--shade); border: 1px solid var(--line); border-radius: inherit; color: var(--fg3); text-align: center; padding: var(--sp-3); } .platzhalter-icon { width: 26px; height: 26px; color: var(--fg3); } .platzhalter-label { font-size: 13px; letter-spacing: normal; color: var(--fg2); } .platzhalter-aktion { font-size: 12.5px; color: var(--fg3); } .dots { display: flex; gap: 6px; justify-content: center; margin-top: 12px; } .dots i { width: 5px; height: 5px; border-radius: 50%; background: var(--line-strong); } .dots i.on { background: var(--red); } .marke { display: inline-flex; align-items: center; gap: 6px; } .marke-logo { display: inline-flex; align-items: center; } /* 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; } /* -------------------------------------------------------------- Formulare */ .feld { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-4); padding: 14px 0; min-height: 56px; border-bottom: 1px solid var(--line); } /* :not(.switch): der Schalter (Tanken/Einstellungen etc.) ist selbst ein