Files
audi-app/dashboard-muster-ohne-bilder.html
tobias e1d570992e Initialer Import: HA-Panel, Design-System, Companion-App
Drei zusammengehörige Teile in einem Repository:

- homeassistant/  Das fertige, im Einsatz befindliche Home-Assistant-Panel
  (panel_custom Custom Element + pyscript-Backend). Echte Fahrzeug- und
  Personendaten (fahrzeugprofil.json, fahrten.jsonl, tankvorgaenge.jsonl,
  Tankbelege) bleiben per .gitignore außen vor; die anonymisierte Vorlage
  fahrzeugprofil.example.json ist mit dabei.

- design-system/  Eigenständige React-Komponentenbibliothek (@audi-dash/ui),
  die die visuelle Sprache des Panels nachbildet - ohne Audi-Markenzeichen
  und ohne die lizenzierte Hausschrift. Dient als Grundlage für Claude
  Design. War bis hierher ein eigenes Repository und ist in dieses
  eingeschmolzen worden.

- companion-app/  Datenschicht der neuen App DataMetric360 (iOS/Android via
  Capacitor, zusätzlich als Iframe im HA-Dashboard). Noch ohne Oberfläche:
  REST- und WebSocket-Zugriff auf Home Assistant plus Warteschlange für
  Änderungen ohne Netz. Ersetzt das eingespritzte hass-Objekt, das nur
  innerhalb des HA-Frontends existiert.

Dazu die Projektdokumentation: SPECIFICATION.md (Ist-Stand des Panels),
COMPANION_APP_ARCHITECTURE.md (Architekturentscheidungen der neuen App),
AUDIT_2026-08-10.md, DESIGN_BRIEF_DATAMETRIC360.md und der ursprüngliche
Bauauftrag.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 00:20:05 +02:00

1946 lines
184 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="de" data-theme="nacht">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>RS 4 Avant — Oberflächenmuster</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.js"></script>
<style>
@font-face{font-family:"Audi Type";src:url(data:font/woff2;base64,d09GMgABAAAAAFlUABEAAAAAoSwAAFjyAAQHrgAAAAAAAAAAAAAAAAAAAAAAAAAAG5xYHDYGYBaXOgCCcghuCYMeERQKgfIogeULATYCJAODcguCAAAEIAWELAcgDIVlG2GYB9DbxiPcDpi/30vDRFHCWJUjEcLGAYid2ZD9/39POoZooD0hoFXdTdAQqeoRRg9a4fB99dDE942EQlz7FG7v7nYIMp3M/C2EVDUxIdC7+9y440JGkm6ZqqoqU1VV/43uDxuCtAJpsvSZdWovI0x92MyBtBf3xeGWG6jyGkIg5/F2vBjh7rAKU4HYtKQzCDoE6Uz+mczz5MYrPxtl+VqB2whpaAYIhXPGkpMJOSQ98vn6f9C0xZw4CTJpl+Fw44XpnAHusGL8ivfV0q+IrITIiKzKrC5orupWW5ZastxqyzKQbH8kDwB6Zpn4Bnzct6d590X+P+VW/18RkkpOoGJCjBCHpqGBEFqAFhi7M1f8mflKfPXFZGWy+vPdtyrDv5v+HyQCaSl1m1HZvO2MAIUESg2iFSNKNyrkRLo7x+4TM/m6Qvy7u7d9aguSkCILgmLOgrV2ZvviGiGLJUIoJHIkvtjOnvjRftrPbMIzAbI9FrrCn/1QJsU7+0zApa07ZNDpQH11IRcPSYGWWq7UwaDlGnpxdNeK4tClKhSqGo1wuKqRCIlxCI3E8c09mwG+nf+2YcMORzRCEkLIcRdqhVxTuUKOmkhzXCHXvZwby3XOMKNc15p7Y4eZ2Xl/2+w4//8z5VaeehfTLl6J1+m+T1JUYl0rWlQpxWG5+3fYXSAz3AO3womye7z2P4A/eIy4DUWqgT+UY3Zq2Dvf0lR8ciLiH18mQKA9bRMofScGJBNHunnrZ6Zft3nXfrdP+1pRkxPkdSpRtAQimSze3DZHJkhk2HQ7LxmiKZsv+C74LvguhsZCY6FBtLEQTXGh+femmu1f7PG4lwHJgc7URQoOcfrTOYfKlTt3Hlc/vL9/PxYglguRwoIKOEqZDiAp31HCBSxIMUDSpVQ5xICgm2NQoEgFJuVIh5yru84hlSpKd6WL1nOVnYuyvNKVM48ft/MP0osGhM1GTFmsWVmo3eIkmF7FBIqK7oX4C/HxvM2mViZrmK5Mn1GIMQJUR4yu/UrLw58s72cbajpJlMOhQzatsC5Qn/h34khC7IJFIMj62xEQADt2gV3xuSzo2nqwC7rOopQHXW+0eBN0YQHAE8R5rnRwE+DAIHGkOgGt8E3e3pMo5yGBCz1u0TbWqu34rlU3FTmbyqUw5BoamVlqrKxtpWQwOG4LV4vVMEsXKxm+xyyPekLEFz/f/MDSnVsVpJ+yX1TTZigfK98AJet4vnnzXMvI3SYvjIC99z8ICcTWbDlwbs3XqX6zetVHaX6sND5FRLbfrnM+LtpyFIswScs4vqo36Hra37zBI7rVNgul0sqXycjGVVufvqRZAir9bofF1BYASQRzJwcXQVPBAV9wgsTTX2ZeJ9UQfLqjUJn2eMSHuSz+lrAP6PYDwX0E2arkyUqGYDHmG1lrEjNpHK56i+aJUvmLXy8J8EjP5iojgzUftG83/OHgd/wzzbwa9Tg5ua8TT0MFFCP2CS0IAGGbDws8rzS3BspGxe2k9wS3dyZ4GFRLXIayBwQ0rptg9J0CX5SoWU/nxrQXQBHa9O37VYZlVnaT4bBu+6RZbVXwYI1s9IsubA17yQVD4SRwKWejJETV7AcU49HO9MHV4jKLoegErUPTdhaUArJaUT/piIs9rcw+43J+uNB7I+/WK5sWcfFKVCb3Rh29aAeZq08yt15CruIJ3frNc2lOG8UhAh5RRgsXTD1uef6kHbkJkpZ6Cpfztnq7rW6nZvhEc2vD1UJ/p211AtbBxtW9qK1ZBqpQzX8xW9Bu23pSZrZ8i/RbPts88JBPME80BU2zXkpS3xotSsFLXuNC/TEcWhbKGidjX8zDoQ8f4aM/8QuH8n15CXd8t7HN2Zq55WG0a4gvxeLMX+YcO5GBWSAvz8gVnNIRwda14w7ku+zOvV8B+H2LrnrCF8b4SBx94+zTHpxfyQBoJhptOZOIkwkTQV6CEyWeotJin0u/tc+Q5mg6vrVDNkepbmOfJ9AX9gSzByJxc48JBADnGajnFBTeHUoK1W/QWR4NHjSs2qIoIYU0HGG0zJDOXbCGjPixQ0Q6mD0XGTIwpZg5uZLe1cHStXORNyOaQ1ACXTYG1JAaVAgPVGKX0uL1vMpPayr3eArUIx7QmaX0eFIydEGjKUngYD+M9XGZkgJV9AyNShU8DQhrPBX0VRiZIYuM4gFFs08BhOPHBiSaMNRBFRQ2PYQl8HDsHC4dUj5SPvYlmKsj6kjxSArMYfxX4KOBlMAJv3o8fXuVnf8h3NG8lNxKTKap1qrsC4A/GoBeo3ufGi+AMAwsvyzt/L+l/qk4N3u3exTAp/I18FAEjFS2QqVAftXY6B+ISIQJbkIbovi7vsKnldJVrqdiZAz/5KJQqFQabboUMYrJnCWF7OJwzuVx1y9J+CXgCwWLJIjLQCwx2FBiacmkctkK6aEslVKt2ki6G5cjYxNHO5ZupmVm6sTM3MkW0tWyNJZWmrXSxbqcWjtzunPp7KJsXNi6vp10clmuRFyL7kY6eimv4t4k9i4dNJe4FFfJc+MuteOH9IFHIZlHtjCKtM2zeFnmLTMf6R++hYrlh5u/9F5AoREFWlmQ9E5wCbGObmMM6a0TJdQ2ph1hcguX3mCVCAo2dSel1yJLlLxou4uRXoktcQri7S1BeimxcBxKUlyy9EJK4TKlspYmPZdeMhxdpiy3ln1Oz+SUXFnyZC9feqqgFMpTJH/F0hOnCk+REsUrlR4rK+VKVChdpfTI6XJGhSqVq5YeOlv4qtSoVuvs6qQH6kuDWo3q1iTd11xaNGrVtDbpnvbSoVWntp2T7uoq53Xqdm490pbeckG3Pj27KN3RXwb0nYDQxQ3epk1DZZjACOFGpdvGyrhhE0Y2KW2YKtPGzZjYrHTLpSIy7bKZzUnr5ssCkUWXtyTdtFxWLLhi0VVLW5VuWCvXXHHd1d2QrrtZ1l1zy/VtSNfcLpvW3XFrW9Kau+WeTffd2QNp1cPyyD2P3d8T6aqn5ZlH99wLj/fyKV3xqrz2zBvP91Za8a6898o/Xm9bWvahfPTOJ++3Iy35XL6o76sG+yYt+l5+aOynJvslvPG7/FHoXwn/Se5/4bW/9ewC4f/Yt3PnTjssJrBMNiayj03QB05ThJVMtHYWbJDcdNsbCIxZsOWh515677OEdvJJ9b5Cg12K8o6tXVq0RVZIVu4oT4reKAn10bptiDlAoKVuGCLUwD6EbUh1RoCD37Nz8vlj7XEcaFaiBThZOyZ0EHRxo77NY9YV7ERqha6UjCzBnoR5SSk0qpMHOTluk1tF/7O72mL/sbqv+3yBp6SxVizpN5TKFZZWWmunzl3YIkVExXDm8FY1eZsrf5YfnplSpfaUD1n32l9bO21G0Ih498xWNDu2lvkf+Wth/r6/pjV/7Y+tCZIVNzyVraxOv1Uy2DMQv5UAUOv5z2X+oI6eb2Wu+UwHX5qvHYSdA3tQWkrywH8etCMhgK68DPTV1R0iCII9IRtuK/Rgx2yOgn1ajhQq3E+dN1rOoZHkqM6ihwrEtDS5bMzk+aEEQE1VD+cJakQ695NUmADrBxmSmH5+NhCYyO+VVDH8HkelOvs1VDYvzP+TKA4BOB6J6jw4gUeHJyNktQV7CfKIa67qS9L2pAqwEAHwHI/nxeEwQXY2IJ/Dfv5ZiK5zfA9QjoPFi6XlUCPZpKiRHQHIC1xxsfwgUwLBQF8A3Dzbe0LwisnwbHCNoiCG93gfl4Pb+fX9HYLHO4Xg8iuWFoRT1Vcu4T8Y9H5kETx50btA6v70XVnq8nou+lDY88K7fgP3SL5hwH9oIpP+tBv3zr9Cuon9w6jWAUP6Z1Nt91VEmB8h+f8z+rLW/U/N/tVj0N+ib0Ru/ezGJPpV/uheGFoaSoWDQD33DCIelSsLiMBDDIEEBunngHI/d5zWSmURzFgJDK7oLGys5oW0U0EtBAlO3p2ViiTOA+tWXDzr97VuMet37+C+vF5o4lHpGKO7TmsN0ZERsKypjXYV9HVgXqZ7/VjU1w3DkHVdaUXrjRN0GLen14/3sSxdKOYbrB693+frJ8B3dGTyx7Vem6ae5WQv7/RlkzhzPJ5MZjLs7NQOz4FgqDzAEHX/sPsH2rYkKK0rxKwGnMq/Od1glEp/3zrxgiZ+Ln8+jWWMkzg4y9/RmisMQ6DUmMA6ig3QP5AdqkOp1WBsHghkMr0CDBWQm0FNQOaMDD6EbxbnZbfazyoAuWSFymnQTkk3UEj6AyzppTb072fUgKCoxpA4s8/oO2g7DU5CZKmL+mf3DEvODsCmpA0Kpb+zj/JdR+UU+wd2n314QQ0qvlWhY7Em8YSJZ901bKaW/kWWE1aW83+RHk9PXdVJhMmbfUXJqSQJ3vfIoExx04yLYpKWS4w/LuYDx8Xus0w7G+f21afeQH/ib1T7IWqYdKvEBXcNvz7eRiZzmmWu0Jf+ihx14q1O9//lZdC8Ihxx/134QJMA+9s4osaEib7C2oV9oPObHCUUDaiokC86vCW1sjl4EWQZPJcAFcdZZOWxzYrUE4lOvOWodRRxNOE4YZTkOqJf0y6daolHtONsifL4iyfaWd7ZViuZMHBVNPJ2slIUTeeMxk+NbDXCHyB20YTN5Jzm2uk23yNmgEeWuntQUgkgm2tIIOnfn83FmK9FKbXTB/3+r59TAXA0sR8PSgwujKhC8O/WNfSIbnX42it3HyJ3Z0Q4ndG/Aw8csOlB5a30354DVbLz0xN5TmoLUUpfQUbUfdvYHioaCIfnphKqIsa6mVJ1f7MKO8HXswtgIxQBmlxB995+Qy0vUl6RfSBShZAESIX5GNrefyVYOEiagGZOE5R5DorGSuzczggN3L3gOKgZodmX+z9VR3QSXLKSZ7lwf384PHv09GuOF74jefplG51k1K4LRRurnk6XbXFwKec/BmnxGzdop/yk1ZUFUBraTyoJFDk49+P0avVw07gimuFu0wKeLpBevCfV0LkPiYkna//dB08aEVbhAQESsBNncAZngK7Vi4+/ppGzaCIPVvxXjKXtCO/MBnCVUfeKJhZ+IKIbyrCRhMQLlE+XwTZVFVhIUaeSNv5papXAKY1nJtcogZvvoLKInnxgH0H9QWuNyODZ39OoXVds/rkA3bHkXAxlA89WCH3Hsp6YkiTZsfgeq3KX7psuNGtO0m2JigxPfDM+ON8nMfthCzFWSKkDOUJYe0PEayqkQukxFOVcC9QI4kkjDxFh2+ltAyAiHHXlb663EqtFoT2JkscqnhATcKykyjwzQWYkG9sQDyQ0PufJrE3cRDDjPL5WzhO+lsn7vdim2c7yIzy0DSv2wDDPpu2H0W3StBBlI7vjzjNcGkSDg1uPhJjDhOx4Y9Q/cGzs7PMkxISYxPNkvkQlATpS+dqMKk+Gp0A8CzPBHdNfl/aeKbXTQ5/ImFVVzvcvKr1V7heImz3AIEWoATSQ5nM9w3gGMWSE3hyEh7gGGKGvTo/2MaX1RN6Eq3bHnkEp18mPdevr/KeaAjEEYiuu+76NpdIZHKCAA5N36gMzCZdL4Ry0v8Tf339oU6kfiYv2WK9WDDQ69QkNkdg9a4/Kra+gB+uhrNb+DSm/Pb5KpTLXWx83SWYbY0TUHjAFzaQnlzaIuupCoIMTguaZMG8vFgxyKmatVgnZFevM6mXtCdB0k2ZqmPGjlJYePRaR2xQWXCuIhDMQFeK4Mw+vo9lWksXMvlMDKtv3mvi1MFgzjxMZlBZubfvrz4QAGbBtLY3c9IUitotIuSm1AqQzlG2Dcz92S2th86+D09VlqhFiSpBUPrpptIRN9fPha71/y2C9jKMLwT82F77tzpjwIriyd3+LtthNbgOzNbNwOOa4bHKnqHwpL2vkv+OhfkNyjl2h8olfyZRu0l+GAKupoc0BepjesA1qVGo8I0RTamKDFCMu0SYM8wDLcUaOk4HjiKXTg0KqaEopSZaomMRyuLYarawFyyv+sAHJLQJXo5u8tNT3rMAqfLNtGGNHZRt1kbIZ1fpkJeeqzGJeljE1wfODu/nR7o89WYFqns5IksUjhVv0VcK82hTvAJ9wpf5jIgO3yj9zLIBPHH+k5mMpOsKSZWFEyj5Kmp07u+cMmgHgo3+cDP+8nASfSjAWBTYUc331kw1mKvNmHF7lco03I4Y6yp+fgJuNQCwGfjs3F7hMJ3DwC2fK33p0GSupMLGtDxyLCzCzKWwXYUPWJ8fOsjfrZZUMN41Oizmt13IVlwi+Un1re0q8nM7/9xx7Jo+yfPjQFCX0esJDxUXdbswrIhZ2zuqS7qZibNUn4lRp8Rr1gB5uct3CmyVdsyDKfm2Xn3Jddkyjy9QD9rKiu63sawpTeWpeMoVonrlx2yI7zWVFSn06J+wXxLDnMOFmIX85WMwAOzuLxAdJVK2sF8kQ+h4AgmW0X84YEnDNVwT8wXxLgVJuNx4JGkvw4URWB0YLVgtA57Bl8fdT3L+PeaY1Ol3QUdCyVJTFy0m3zIuEU1+ON9aRX+4zGEjwf+jOl6yQL4CkwFn6tUQsrMtqTveuYvzX2PJfmhnTqAe2QYmHui7fSvtlXUrtOFAjx1N5MV68A6hD9c2eJXEB4XMBs9/w7I84ge1trnjk8971NLCglBliXovD7hiA15vhYIBV/8thv3qLiZ4C3zoXJuaYLQIeeMcBJi6XPru5n3W76th5jUJNYtpmOAwSjqW6FIA3m1N2PQevWUIFIQBgkN/+Fwc5BlzGXeRxA69nf2qgZw0mIaaRRjG+0jHS91kAgWIB4feafD+j4+zcAWWoMtw7kM5T2bXU+12tJBu4t7xqy8j7YZofeCBbPH1vvBHgVt17c9pta1VkG22XjM68FCCZIZ66Ny5ZidsIN/2fGj8KCN8vGpdNpJiVPXxkXp7oPSkneTmQ9fgRLfyAaKLyeZqX9qMiyWtSXkoUxNq0q35LFtSkb3kcgmMEAjja4RH78XfkqrMSE9ZkYAoaYXAuhbDnzcP8Zbu/9YDlrcjGZtaa6a/K00a/mWstTY9OqlkOiTHUzMsGvnnWtji8qeI5vKzueOPfAfzZq6dyQaBl2m7yzGUFprh5Bb+P/G8w0xD9Q0FASSTZf7h6zXmfBste7Srk3ASyoQdPTF11nHoIUnqWj7gd+vf+B3rY9k0OZutSqEr/1X8yCtXWYxIsKLr5qh7awLe+J7RVeD2sLXZcO1v4Bt/2gL178OWIE3QWfVf/vTKnT5w0UO4ninVVTz7GYJJ4hH5MhFqh9jtPEfNsRliL+ZWsdNMH7In2qkdhyhYXsx7KT+u02uJ1iC66PZhZnQ35pKbXxJo8l7EYF1gCPijMpQTXb8NWK9J+7y2KqM5hdpitZqXaPEq+NNj4MRqJHs7/BtrSHcEQELuv5wExyMsqF0Arr96xz21AR6TUYi4Rc/NCw/twpMn4uPTvXXhPQ/RNc4kWACtxAXdDeFy8s++vl3AQePJc33hoCkMMGLgSfp0hq1QtwLxPJkg+2LJXjWZILT2Fc+XvdoWxwPmxjftqSZBTCtkRJYqZKqdUkq5qn98otw7gn0b8Kh1T9ACRZCmp/kcosiQFjzGd8VIujLE6QY50mOLvv4zXjKNLJEmeTt5Fu3+WbgTsft2AuMNwUPz6M3W8Os4WovViox99bsfqbFe/RlWhip06Tp3w/BaUAMMdV9HYKOxfHCD6+84uWqzC1nI/X0sz2B8ZrMPUjhAX14lAMg2D2aHBv3UqXVJfa8/sgTIqgVWmANgO/wR/RDbQlNIrAfv80zKPJqt+NXrdH8pgXciDU3H2UxlVE1FfnfThQj1XO7XKHMvRpMRJ81yWSKVXv8IyAv6l2X4ItaTCHtFz3exLVLoOdAoU8wYb1xFG03TfKoaLUWyI22lt+vEK+ULdbLv3v2JHMoAAYzU+L6M02wigjDXb3LtSsWdkFHM7P0A8yteCzytW6+cdawTl6hQvZpjlq5cfPl6xFX76KhEhuozXKVm5FVZBrpIv0s3Gbt+Lusn4L8+8CSEEBz2kVLyGJLXLt5gqh3+sn71esNex0bPlSJkaF3nf6gdXt1StQY5ceZtVMk9QHrzuYlC+eD0kP/KCYik8Ud9iV+atX7GPNA7udKjFXAdpgiWhwtSsznwfU4R0isAnTv1H+I8rZE8C6pRWgzJln0NNWYixkwPCz8JOI8zWw8vmhFa0nLVdlAxk92x0JRAOvSj3akULoYw1u/z70nFVMoq5HR+UPMrWAlrAFQZZx3pjWECAKRZWbWVYF2iWybhXbDFPLxERcyI8ouTKengF6bR8kW6uHVZvMelm2JNqy0HEuiK3SQy/nts4y/ppqj/QaKgUvHN6br74p3NN9Q/HhZwzoyFPjMTKQVIImJQvCTD97gdrRl8ENnAWwOc1eYZdMglM8Xzne7n1k55JSROeefWu9/bn7z6tcEQKBjipVeQqZDZUfVIkRe9yzpWMkaWB3REXPeWo0oFiFjm91qGputO5XzqRnQAvlRcpI3hRTmmxGVCjr9nm35WODe2Xs6BzR6uMcp0ugsuxAOl+LogH/vdlzg5LJHtRvd4Qp4Lml+i3wydA4Xtm9oiT2nocJSYALvoEDGoX2JIA6BQkWLVHh3eg2F51iuWoYie8EWATTuJAWd2vKn3abUdhYSkr2m2u3DhKjc5kLGBmGRkAmbNkUyqe2u5l9Ro+zVU4i+QMkDm96P1jAD7AAsj43wT2jfcasQNKGreTbmt94Kck+bB2gG7H5CTtngdcufWJ9l5zfOjHILG1AKuiddpfa/mu3aELMFZ2l/U5FChhyu4xS0q0H80DRB8WwAbmcu4dRCULuxzpB4SFp6wVa9Re4l2rWPFpdj5mgsvGASYq4g55nfEmKAbff7yI4Es/zlA77cZh4SlXEG3uqQkIN4Jjc/wo6QYyKURzQZoFzifdtN+RUJdsY+FRt82y2qWQr/pK9fVGEObXhuU7ZXJuvYNKbi6hZjn4KxIS86KUQtESku+BYdfzxJJbGPiAEIMo2Xye1NUpWUo3bRHCAVt46a34EuYPgje6AHhABD8ErnMIGvqEkJXWBqrQzbQ7pQoYVDbGNB9afvAph51eIWq/yrci5bt8WturJg8UedYtKbKeIcZ/T7LQc4nLqwzpt4xwT1capI47ynhIe0sgjyWqhln4uDhQzU58BVwZ7LfFKH/1CNUEpWS5JCnrrHmdfHd8nAvJLiaZ1GcdrdSh9X9wXwl1qYzn83y6Vd930y5ZMlo2TClAnaQNQh7z1gyChilFysVL2kS3aUYQTaNdSDYRCc7dJtHgc5q7zP5q/2tlvOg3D8470Lbo04q9WhXGyF02NqcAkWFYplmr6M4dcI5JND9DtFKhm/m4u9OdOASchrUe5ndUuEGNf7i/PU0jWPqEOdmmLIk1hOGmLRB4Jc63KwH8jgV4aDnuTdLIuYJlnxe6qcUvjcapJWmBfNTFwFLydsfi92uHXaFZcUek/lRITTQn3aNSp5vhjxRQmwuKhhkvLXm+zYqlWinG0ruHEzKwHLZaCihHGtuwjWutJu8MLLCQrKKIoj/IP91svQIv1yyIl020FFOOCnblnBQB1vmnJR4NVn1qwZ2NtfcOLTujWe1GkcfL5QoRWbZYvcxTtamjjZGot+Y5agVLICeDNjm/w37GrUfxapxVDqrbfBeaUwk4TMJTbd4Rd1l3OO/ppCcs5F1zLkRr1ABedZh0hKRdZaCcSSeJ/q9VdcNhY0SVKsR8NAW5clQbYvxcjKvQsHl0O0rT2AAk1gtNkIDOSzQbgICNpvkuYBfmHhNDevAUuKYnvYOzvQa0E6aNWJSq9N8kRWBRk/A1Z+Js/qDXbUS2wvNFvtju5NrfkcVBBpKOBTrv6MHxnml2oHQu2h/MP9RwsEeqV6KDiOAhiIRv1qGeMCqdb7/yIQoyRc0uzSKQ8yj4VRNfH/o5QVaf+xDTk5iWSenRpTvkSqXLJ6nGaLENldwIOt24ef0H4BTqhIrAtpHOKSIIYyNRM5TeyNoUXkZ2g+Sho5HgKtTs8mzyirdGoMOspZmbgl4F0kyWjYi3TfXmxdY7+JKZ+r2bnSsGeZbCaJ5usBqNqi6ALCNlKIp+MsArGJibZzps9DAIFCcbJy9pZo2IagXy9TGTIf1R10aws4FcyeUyN4fw5PaodLlNiJcxUzhoHFZY5da+9WQj1jGY5Tz9sFUmC+1HRtF6e1ABqlAWplV26mGEMwmTcsAnm4UZE9DTi6IZ6J14jmMG+Bg+mnVUutw6xMs4bFBozHRWuY1vPbkdW3bI13Qgb1ZebwPgv7Z1/c/pG6l87Z+eGzkjpvtouoWnn0muQl/spj8825XC0SKzx9nku+VKnkYDNmMX8QpexTvwrk0c8+7eMDnIzij6YG1AJxlahDtJJ+EgOCW6B44NzSd1BxxsMIoLwpKH12c+p69zFIuKC6MB3aSVOI7N8MjjOAiDdCAOLSJ33kprUdFBdj29967rrlVmkcnT7s0AeLYrmaNFYY+zKa3lSplG/Te7F/EKXu2465zzkn/J5zerSlhFXHk/GOesqWW/g51C3nehb8wsVpoHsgEbw6bFQ3zGN1a4hJfx2rzLU0pYMK6/XHHv8atvcr9l1oxYvsYfwkvixFX3Z1XF7cMfwEu/yfGNfKZH9K6xt0vRX3FaQUKHxjuet2JrDPI4WrfozUW00TSy5cUT7SUlXqhvRB/jCKVM96r0Vx+b/ClPop5Crhh0YVDYyPPoFdRDtajMVbVKB/dYMgkdmuDYZXVSQ8jjaBOgkdwWfSdaT/EoqE1HqhE7K8uLffG03cOvzG3laf169MZIb7CZMFxXEZMY94TwTfFqRV50iwhIpLmzaaivQ5zhvJDnExvbBAsp9AqxHGPqYnbCZ96N3ZhX0V6VobLnLraHe1X3w0HVJ08u3khzXyjkjTizHBKh4YYBFt6GFCjS2ldlGOosLUeBldlxqLRI+wx1R4ckKMsw0MLX0HPrGCqkJ4Z0pfPtOhdoID955uFw5N2cu8jWkmNODdrC/9Oi0IYFnrcL8nlQ/CfoqFFTl6LlE2ZvRdyA9WpsoFqX3Vl6YUFqbwzLtBF4QKysju7GLaZFmUzR68pTxsiP9XJEhoybvdEvcgqD3vRc2e4tdco3YjwytCjVrJfvDpC4Ag/Zmwx/ir0ZMGvtzXRI04pbSbTpTo+uMDsXGkMdP5//2aU2flVj1KGV6Yg3rH6VjRvLTSq2qPK0sUiJZLTZRga1GSYF4SsZNL0iShI33sNB+i+4T+7KUIh6hHIiKPdwpQRZ+11c8S0tg4UU+tQvfL7Nn8es1EUJSImxwlxi8A0g6PImZS4/IidVolbefGiQ9ig5fkYtxY4aJI81wafSK+3OqdJ4/4RfuBwi33fWVj9Fbvjj9oBWaL9jkVyaZrTVJi5CClTwbd+W0iqXjXFHtDxarKuSs0eD/1jYLlywxWTLrzxTaAunPhG7nBL/Qt1hsT7stdxjt9x6+7d/OheK/T5yV2QuQM8aEtT2/wozpkDpirEHsamrxPastH7ymu6z+FTL8bD0Snu/gEpoCjrUa2MXMll/6cbCgNqctBbfSVRY2CSqxTcnLaDWWEgf9+Tm320tjhVrzvcimVezEmoJDIZY4QmjRfKaW+Gx8U0VTmo1vmYd/kbUKBtE0Sl7+EivnO7dLPfusjVr7Tom/L2oWZbuqVsa60cF3atN/h+RHWvJLmuRXFUTtmV/CIIRCCBoh0fs43njrKwF8pma0C27mII2MA6P2Mfzv9fWk0IAEI23My2tZC6+AoBvAYU+fRkXf/l6ywxX4Nmt1+mZ7njlTNkLt8bkDblL2r1oV103gk6b7azOA/lsIcTiYXgTP+wS6nV+LvZT/LOmOxO3bq6z2V+++t0EmmKLEWfoKPqG/gvlpK6fxzvKyHOcHL9bQ/wj5DEpjFTta3xDwfGFHDd4Jj6M4Z5uylf2ibkOGTdswLS4Mem6cZqZqsWgCmmXN4H07cvJMFGU2XL4hfryUNN8k/m67Dnb11lpFo9iZntrX0VqWAsLP4Cu6fZjHBEzjErgy7QdoBk4thEFuNVPVp+qwLUUnLhQnGbkEnr2kZXXuG1S7IgTdAR9U/+5Mkf4x7elweVuTjylrzxnhrpl8xL2QGZRzG3PPoXlE+rA3Wt7NghhYs8VX+s9w6+F9p/KGiO+O5Nrun1ytavzdaKu/Xj+Nui67kUMAdHD46liQXlap5U7jgQ/cSl6cSirSl7qGKaRMUC4rMnukME9SO28GH3H8g8v0+xT5Gbn4JMcCPHinooReXrFAa/q1iiHro/33Nn9h6uVMuEFIUvmwO8Zmnhvp/bURY6YhDe8C27oc/9YccZ9p7H3Y2AbbUjlArqDesuAPOkTUglsuU+BLZnt4xRvAQqAVQckxnrmWVQrt/ummt+LnuitfhuuYzk6jrR8F66wipvdS/WNxy2rvfJSdkJVgD8s3KihNGzAZC1elALbvhxCf/s6mP7hMhcmijddYw00lu4ZUot3vd7S9COwr+9noMNjlniO+2JbxQ9yz3nBqoPjixKcv/EuwtLUa/a5+cDI6iyMj8eLiktveJSWAAOPu2MpJeV7vuZpSMeR4Bce5S8gGd0yynjbRrqQMK/J/hZX8vNXOnUt3exd5I3OvifpEIeLwBdEOUnSUxnwZsDzO4gRGzaF+T5JbeWHCVEnsuwBDZ3uL4tL3V41tX/0y9TBnfTQ9vubYSmO4LovuK2DpjR8XZLTN3KQM3DdR6njpM4iuSeZ10yfM0/4n1Hq7F+gN53A0ZvxL0QHDHqZM61Qf4aToD9NK8gapvlKDEtxhHkcE3hUSVKSEo52tNHAQ/6V4lzM/kdJquBR3BSfFpfG32VqKhmOGrUWg1p35PLfZmRp/l3hmvyBIv+Y7otD48SzxLF/kUiTx6Iwtf8yiz6zrymO6zZhzmKEdVaDukuKrFYJn8VzRZ9gdcHISve9WQT03jh8JTJca5AvfueCpGddzKxsL7zO1Bm2a42X+UiI3LeuNmnQZFNhOhyHyNWqhFYrVh9yapXEXEpmCzjH9Tlkv8Rjlebd+jTwsol12tZg3K8Bfsj/l0QqWVPgOGJoqNiEaqdBGTrXiKDZixWhbipHlj7Dtib79LAyqtTRBjRFz1CPkvc9voIpmlci7bpSb47jOraxHVZN7ihwIXHnBnjbTN3KXD0zLKtoCDgjjC6Bn2z1U9Kx7x/nnX9e4IDf4LoiXCOIEW4IN66JK/5XS8vt25J2mEj7XqOdfBOAs2GKcI1yrdCQcfKwWF0q/pPcKT6XmLeJ0fgvS/mV08/MAYEHmX//TBtZRe8+/x27bdxfCdxKjyQjAP6CDzV+u50cP7e6/TZFGoQ1qckyPxaolQg5V/Tt7CTl0ATl0QxQQfEiVfZEe0mWpu2LYtsTKlxW0/iBum2g8ynWUaI1nDyjX2+UKcaDOI79ZGxOnUOANVPV34Bi5mbgqAo32uErOJr/4WAmonOXNZqVf4CBp5m7ATHnWZCjY6nc7+W6U3VnZHrUROw6j/3strNj/hDQAJSDz8P3g6ePUo5TZ4psFShh3MJn/iF5zr82xMNn4XcApnw2fMkFo+hzg4VH+T/OKIQfQymo/1bnoz8Ha8Gl/3E4HLowlJB3D+48Ve7TAYUnxjwNAPH+49k/wFl4EW42gXoreDJEd/8x1nTBHywSCBBC9wGIy+Jx9L/64AeMcpp/r8HPnhz3SF7v24S/S+Sngyx4FwD8vNjwK9ShJ7KJPFCqE/jS/yWb0P74feAxH88OwT/IaPbavID7um8zV8nz73ZB1YuRRuiZMKCS+nmVrBVtMlgTs6bOCclAMuuMVpJlnfB6pnPd6Ht6Vcsai3pY78qlPmhOK7qsqZ6tl+mh/q97ekenWWtBAYiEcZUbuBN3y/Fuxx26miuSW7gVb6KMU53lqi521nXdhmNu6lLkXJSNbOQt8gp5VfYD8J3JA3kHch5LhztnLzIoFbV1JvaLX7T/zckXGZqG5U1IiWOoPlRkCddY/iAJnZ5S9eu3r8AKLlGPog9DspLds6MTmqKJK1qlfYeyrOGtbGRSrSpaAckSuyhHpAIMCpy2hN60qIulbc06P1jKJHPW8kaIYshZ1elGD4a1g2NKFsXABRSEIJFOwzJiMmWEURJbTVZcMVQAkcJIDbNSsQHCrunFb9kXwsev6xvjgb5geEkdjV4Pja2+qBeMO8YzjKeMecZK41XDMSrSzpFxJnwO0DEBjgkghHOXZhzEc6idG1IISqJOaLpbh8DvdoBCKbxzUJYhkA6VTkR8sqnrF7/Iu7GIsqtCrm3VQ8QzeuecT+w559zISuPNnoxqh+RNcbRkG9M0q+JQcqUkQg4Y8/opH6ueGhusYYzK0A3DJPZ+iQUG1MDABe1QpnVS/KcJKdOZCEKv3/rR1iRkZsuyw3AkC2EeANuDHbdO5jBo/KOOdgYOdIgjHLs7HgcCVIDFb8fTcsqQ7XT6fVM3HU/NKZ9GU6e73Y4EMGvSTnDagzQekylaW1HiS2HNNydrtVIAVILBe16091EGc7uWFEqGvazIuSkPCidyBbficq4wTTMPdsomNsoKV+kJxCK3r4qWd8hJNYw9Tmpg+ZEzFyziiqS5hYKkKhQx6ad9+ZErHBOj4VmhAywFBDQr7gB5XjI3GtoTmyEjRrwjFkaoYP6GD57gCqGppv5It/t5J89faXJ50RTzsoG5kmpONpYuozYzChImfVjASGkkrOgZkJFgnivBOxDtO0FZFuVj4ibhcGBS4KEKSPS2ORgYCXO2IYIliWLtx1nIDJGjCqf9Gf3JHr4BEx78zIOdtz6N5j/qL/H7vuETX/h2dz4fCNAAMrywJuME5z305nMKYScIPgq/Jjul4MtgZTKEB9gLBvWPPh5slEZ9RuaGXMqVyrAiooRSVFa4c41NrNNhWrewYsgYZiXXSmoMjRpqllQTHLiMBO2iUrhIyxVxvhCGJSqs6keUIYQEonNDJxShU52wEftK1lwjNF5elRkPKJLSIURLVOEkQjaq3+mVC8BKbrzU7OYn5EogPRqdwBOmkpeTQqwSmlB1qLza5lOhAtWyGqkFLNyudAA4g8EGrIKkTC5YmzyBI04IfxBWQ7IKrtBuRxBdoo9SOqMVndAT9E56jdqUFaJBxqlOGAM4g0TIYKF+s7pSzYiDT1afrb6qDtU0HjDDFXVyX0C8wHQyBUp5nWw1TneArdVWZ/pWRnVKvNRXQnWI/sZ5VBi89UWV3m73Mq0PIzxY3qr2M7iBHk7RTTzXmjwALa3DmHCl2giquXaQfQigk9Yt3Qv3Da7jVl3mGvdl13a7buSSPBE6vvWZ3/uaz1ZeaCuWmIghdvG7oour43r0YxidFLUWlaQ9b2ee4GBzLSFqY9C9NtF80AlNJm6kRwEQOIOPwJO0B645ZoHeNBLgC7tJETgurrEf/KbmgeWI5aa6brnuztzylsgT85Cd1nL8jMtcyWVY2qVruQ03ZtbOusQwKSZDMmeItXwQvWIVp4aDDgo2PdKWAiSQNgpa5k7Aqvh5wFSm+4HGkCqwMz3WTNQ5M1iRg7o96S4EeC4AvbgdOAw8K4hKQ7Ig9CPYxoBDyqkYgoV2bhc55FjkRdFAg6t8VRwggVROFRxwyOd8oYCCaq4WPUTt4zItlTWzT3ElyXAFLG3mDSDRgMEhqAhyUCBAiHNcUKDIclZIkIgcRZtpSRoHqCIoZgBQegPcNlNa3PbANz2Iq0nykcQjrpg4jI6vbb4WdMVhKErL+/o6NuHmFFHWjsylEzhFpmROyZTSlE/LrCvQQpCT7Gq0FipMexrTlOZszCbshC1kKGOZylyN1USdqIWRLT00qgcVsKQCZhVVeBWaEMkkpnnSSEZyaXeCm9xswbV88ZKLwoWX3BnmjdaTi+P15uJB2Hhzba2fcfHoer4tdLFq7VwML/YvBqIuR2fLDS2Ucx4QyqTQQlm24wMMBgEg8iNfeGboQyEjRKO32opt2l51VLdbVEzRhqfo7o2SwdvI9Yb3RqbtOobjZZC7pVvKLcu7gMuH+bPNXVONLQc7pjVD2SCLQl8UBw10UGBONAmkoG7ewhVDvFoE9HfNcjHUdvFqrRVQ2wVeL94HdgFYEgz3MXi78hYgqgHRr8k6wZ3bzTkt3u5BPheCsJM4rkudRJi9Kk/yk/wqz+Q7OcYcbZMHeSN/Ll+Ud/ONvCDv5UEI4mYy+cjEI26YJCSJrxUAdAG3aMKtOuCGzNq0nNgJq9iM29IYzdqVeemccuaZm8WlVNaN+7QjgNDIjgZaU9GCiNZ0TKc076Blp2zDdjIkx3IqszVu1anaqJ3ptDAs1AHog0i6kJZK0U0AaYzjoWkMxwVut6w4AJmDMLMwJEyhfCJpW+eM24FI9eKSi85EVDkQgKWQ6Z970COe9ExpOlVDiBl4vTFgQLtisDuztdw41aKQm8NGgEWXqEPTBploJdtLUYZZLJrCK8IyWKCy+gHY6Ctvj1iQAUIZItjUyMYgiiZD8lynBRZld2UCU0T6SUFKoUSlVHSIYIQJKlBHFElEIXoXDaZCFrQ37QAjSxAlvm1JFpeEEYlYgF78Tb/tCdg8Go4IYHfbNEuX6T5lU7RzdJOSU5iW0ygVqU4HKUxJKtKMl6aVAD2HjwpgDCW0cBsEQBe7WwMbatCCGByMwQQOEdSmCHW8PLrGwxM86cHeTe3z8xDewq7IG6Yj8wiQzXc2IdOHA8hlLZK7vmNPwNxbSG9ANnddN/U8nzW+2bUm1srh3bP+ZVKXFMN8OB+u0zY9zdwCV67a1tsReRRZR25m4tLc/aXprM9JwtnqZW5K6spBvqlNi2uD2NU9GUiYyEl9Xt/VI/vg3jXjcMKOBF6+oPHwJtxC0mq1XNuz+1UPK1glZs14WDdql/xNSlePMLfukxZiBJeRfXwpig+PHDJlG6+9lrADVlO0IineM4aMHK4c2nniYQPYATnYwSlCkyfCoTCnCqd5zQ+ywVVu3iX/rimNcqk1a3O9NXpGMlZY91edhpBpcYu3a7f2zm9L8daOohSJU4mrYSGDZNh1gqJCUhwBI4BA5DebWioQWpEXExiP++D40vYI+KVgE1Re8SUpJxidkNaBjIFsgIqABBzTRj6WGZI4KPvUGAmimF6DeLoOek1xa9Nzh2btNh0+x63z4yCGNMVyukkfpBspRibqpJvFeDF9RvxI+nQ8Py5DrYzeMh9jk6Unlm6KkWjQ+r1ZEsu9MFLJibxCvCRLWckt0cSSqjQklq5sCJdIiESsWghCO8N76C5wiHvkUMFbWMbZuAwHaGMPd5AY0doiN6R0hTuploEuoaMLb1wCbdhjAmihgx72iRDeXzI1WLZqp1Pm9URXehlaaM0hUEAZLvDA21xQbR6M4EApEGgGmjHVBgFx+BZYmFtBUW3ARH8SSZFNT1k2hLvAGzSc8cDQDcd4kZE1G5HDqZViqMdQYXjaIPo3V7VTFhGUs4FncGQhvbwItgEDSdP0OFcMi7x4ptgsysXTxZJiWOS5KCzYnThAsrNTcng9Kovy2bJQ1sp5ZacclXlxvea4C4dsgUeGMsnPmUUm7thBWDf4Abu/9p7MBoJ2ZoEVbLDRmWb9zM+qXCqgzMtJ6S2rrdD0G3/lrry2u3fjOS3TPpNzXc7lfb4SZaWr9NRSrWDPrCzO6tplxav2Q52uIAgKB1yNsTNwwhKXgzJcSItZy7d1G6/RenrTj0sUT+lUTKNknZO4PlfxiCfeUySlr1QqUkn1DvtFCYLpm5XVtVybOkK30GSnD6UHZw9W0Ec9FFEK8qAISuzWUC2vT5v9UAoPKDDkwPP2VCAxlV11EEvxTCM9NZQVF9xs2AUHC3Kd8+N4DjvUfxX0dbQ5MIfmM6ZiIqRNAje2I3tu71okt6EwdgqaCmskd94/wUHP9Zfgz7tha3Ly9cYS+4LLw1LknMrzf8gTkucWlkL3x+G3hJ+FKeh7jlsupJcKasxy4pEYrQuEwOBrTGr0mn4GgruZKCGemdme71jiZLnSAaGfvgYxM94TJTFJSJrpkp4MZMwcyUklBGZEIilE4YxLPL2AXpglUpKWoCUz3XNdR+qkPvo3U3pa15SayUDGDPbMzpKs1EGdGenxLpCCFKJw9uhJF0phelIM1d5SoBE5j9E7HGKODR4QGSJq9BAhOokshEmV/Ju1VH6hRKUDKluIpGZ9b3mi4ogvoDtHZuj6nD4sDAB2ix1HCQWftdEOTpbFIpSZQDSiz+hvIgs8ExFBMtcTVfAMQJxVJBrRmdGIpV3AeOZBtcvkLPjkKfBv9//0uveuOzmls1/Xe7ImkPXGOobR5BrluqGq3VydumuVclm14nIq74rqyD1QdbdOVTAfxH3guWv2tdbjP/wKAFwkoK5bsDsWzLKJ03gR72M2lmMY4/Yy7mPYG7Cw2eQcVQoHa+LWlG8xWiJeLucw7wDaOxR1BzLpHCE+msPkDoXuPLx4xcXaC43v8FY2xc2CJHy2KQS7BohhrfdiUHrgH2lBAYWldKCvX5rtp+y0ch5E2c7BsLJ7ns8Pil7t332pPAuriERrOhNEXFKu7dnJYAZ6YAIq6CBM6UBT6efb5ztmvpK9ruF+H5lEfjiyMpIlgkZnwmLD4ykS2VicDWwPkxsAxgmYfQfUORiMCQyHWM0UwaM1VteYPiW8Jfs8oOHQ6QZCVr+f+GTFKBvPAcGPgD8A8SKlk0LflBHITBQwlbbfJCl/kCOOOeVsIruRG7upm+WQpwaatBdZVqO6VFOLWEsrLYlINrLw+laIhEw1tUjLoFjmXlIBScnwX6pXaDnjJb/KG77sI79Ad5HZlR7W1t5iLdmCVtnKHycPrbl1YzGW9PIwiKznrcVWz9It35pZGWLNMJTAiT8c1zQcTuu6Pq3v1kKt1Xb91npZ/VJt1926TA7PYzBrUra9Z30S3RD9oUXqt9UvqNP6oSjyhRWVLYcw9/elLHf0pA/7MCI7rO1ta7laR4ZFwb22Y4dyIA9No2KMeexkwR2HnFBhN/cEQrz1rqkNxyS2cqzj0jpzCq5Uy3rptPS+jjs0Ta85vcZtMArR+26OFxb85fGchsuTeTVfz2/Phbk+t+Zvnnfmk7k15/NoniKXNxhu9BjMoolodlFHabSI9hEbyRGMylEUvRAtifqREXWiMMqQaBfDpHBvdMUbGS1PcOrGSexu8d27nQS+mbfVvApAc9Ewov1FNCfzinT7fJJv8gc5QnkOBAyUKCKGiC5XZP62+Qvmcp7RL4sa3+UeN83YnWhnI8HQgfVP0XN43hR/P9A3OoK2Yhu2nQc1OY13o5VqOR7jowpzP4tSsLrUokkkiZ5ETqJXkWiUibLH2bF0JR+Xx8YV7Ctdwb7wKuoTgQ4mMjy1ZHLKZGlxzgWPevLYvGOo7wbUeNLMzYE9c5rUzwbFrGwWg6XfNuvZM43iK4Hp26R1jKDK3Tu1b8F2BOm5moaTax3DBJKHmXQAzRFFHUEm9hzI0e+PPxsnyRETwbEsaAyNSzPDn7TrSM8ubGxTmzU9c2HGZmpmhVAUK78qXpOb+aM00+PXLthMjuTMxjUa+VaxRBYFtEXUV57H7yaudCvHThboWXN3TptFumDusBlhNwtmIS2MxfcWnUW48PXTDiyOOagW0XH0hejpaH6URYtPRKNIx4uF1un2iMGKP0A4+K4qqTrVpDIrXkWVQw4O0sqFNGuxmNxEJHfhg2QniCcdkMOz+q21Bx1+fe3jQ94Glw9Iga/UucGg81T8EBSJBpQrpIXD3lFQ3CY7sImbuRNv+rE/arGZzIGZmDPzxDGdsXM0Vl49gIMyhh4y3EG07bNDUYFOAjOwgvE2yLqaHBIukRJpph8dIgONxjRNy+KdsmIiawYD+9yBKtbwfFuahsO/qtF5szQNiyfqrG6DDW3fTtqXtIX2E+2nbba5ThY2r7nItX5FdwTqv48c1p/R+E3vPdC3e62kZGBgtKJhTd4Ws1sSTwnNk7/1PeKcqWnnAwUpyZHMCIkpjVE9VHeUhzR/vMcJXvmOQojyjd1xVSIeAbT/IH9vRWsPoZ0Ru0sEumXBXCKIRxHqJQa/Mx6Ug3ZweyAMUHdnkGOY1XqHQCmd2SHurMnYYrKlpgNxZ0e0mgysOezqlh1quPf75GdksuEed4nRMHQf4vY3gzsRC5iLNtQF991CI/X2sl3Y1q6brnnZXJituS7xqmjpNcEMj7oZnr+2vlWyc3YtlPJcXmvlmOCKx9RyrRyPTdfmA7fl8jLrJuC37yt069iaZTYnqW7PAUgil2BYXhqUGgeEFmvVe6fkzwHFMJduhDOgc+CYY8w7iTp3GeJ9t6F6fT/ece0MnW8wDbq9khgYFi1AbYnLNGRzcV0nMm10LWbd45h3mwMzwDDjJR16uDoVtuSISQR6oCOwnEI0mnhCRD8IjnUbRHttkRXvNVVDC1nk81/FZwKPcx4xoiqo+M3CHxQ9p7z8Fnuq+7UlXCAX0+L54iPFG8VmMS/sQeEI7ZZSmlUkrzh6SA9y2tTL7aT2gN5Jf/b9a1mN5sh6WxhsifqG/nN6GtVJn+lXOq+/Qu/qnr6v+27NJMOYcYN708MA7ffPwWjnhwM33YpSN4eFu4ZZR/lkneqlKl4T9ZVeDmSn10Xk1CVEivWEkuon9R7SwYdpZQu/Ty04ddUeLGeV/DtoWQ+7Nm9gVbcDtZ5asXRKBov5XAhjZG43I2gcddUWwB0d0QXdJ4E0qmWrW1RiMFr5QPUSRCWkLQ+7ZT8FSg4O+inHywbTWVNisqb+GodbPNnidIubOaCDKC+ifpiBP/PBj77IEWECMaYzme4mJnMkc+80YxW7nPBwYlpDCKUoHQzzt3lPTFGfGMXwJC1sn5oXMqwiFMpCF74L41E7uj0SRtoIdRcP2LS6jackkeuidksEYLbApSJLHYjdIvjo8auBbx1vOHDG5vVz7VvECiedAiizUMxGOEt6W6otvpG8aIlo+bb4G3FSWvru0VQ9BvC41o222v1WbyW2+YAdZ5Bnuc59zkVZaIVT2j1u3x75wA/bwjxyAmeYy438HrkiS5BrOVahSrRqbCs6PRioNhA1bSTompKlOom4XArUidx67RaVneSVn7SyJdkTh+6/f9d8oGG/t51szD3ERFcPPdtLO0PrvCIblpelzoe0oeSHZoUP8ILvUly2rWiaK+uNnwhRxNUirylWWGTpzOfocMg5GhS2keL+ynhq40c9PHprtnrhFYwbY0wF7m0zgwcguoSyaKktbpNABtCZ1vVZuPq0NcLeJE5RtAkh7Bu54jlf72xXcwU9MChbICsZyGXDLM8OGZcpGZpnGSCsRWNQOgAiKRrTJpiLgu7TjpasXouPHeusKdll07JX9awRN339bmz9K0fA5o63vDGumiRNFslNwiRSApNyUrRXScXDNHh3RDSBCtY90njFC4g379gIW2cyBzMmfUKrq8RsWx9QeBjuhH+ElA/cAkIm9tthDVAXQZ5uTwl/tGt5SO17A/aKbbzI27pnXnVEd3s4pS3aph3uVLAEW3A0Gza2XbXx6QadU7HDrGmMU9fOTyv7pFnZp/pVQ9lzOlzs2QF6eQEbrD++bDThqmVwjeumsWdOeHFk29yeC12xHD4UcpG1dpHJubaUG21P4qeSLAVyru6MoBHA3NqVGkACAczRItjhsyGJOnrGZkLRypCggU/8AZ+dUlmM9rRH7ZrcuqWpEQ+b6d1JM4YBq5u7LD3jDoigow56RsvWW+MUn41BnfrQu4L4ypX8+rqXEAcDhMQFv5k9FYt7TfQKzs+B7B3nD/Mk2ePHNDK9psyGGCAtdryOFpNjAH1i3cDJts3e5cPFtiSboSZZ7a/GEolQqVU9+4Sm7Dmv+LraGQmDMs9lJ/uWbUUi3ZOHlA0c1Hxc4RqP6IpVnOedOJFzeTCJyUyrWhyZvHVgj+w1r7qjqApHk7Ph9fhofr695tDu80Vjcb9sKs8Xt1bzt9308/Ud2mBZuhAuxEoBVvredZhp0LFWIaXxQSw4hk2gKcAEe692w4znQnNblJZtKD6v0Ec9rGls5yltmlzRmu6QSChWX0R4BrgJqMaBTdZzp0rIlry4PIcuKRPFT5icuXR3QtPzTU7rIBGKEEK+LFhH8JRr/vrAaNloJY5jMQYxjoM+DgeTeDLght4MHsQLg414Y1CIC4NvxquDQs8woT7zrNsPgzo7s7etYL2tjZQvH23Vra8TwUx68Zcjyo7YUpMiyF1RPfqEFO9Yz3t6yyLMkc9v9iruIrwHit687wMVNLGCUyjwI+yhQM/79UsKJ+pWmOoHFnjDWzRUzWrBBNvaIeCzceZIFkqosiasYCVr7dufX5Ja1FLQDLJtE9w7NgSiwCy3pOdVS6wGZ10YeuSpZ5n0yCZi68lLwUaRi22s4mlkJ5oIdSXCyEe6AfqIHsztfgB+bWuElU5EzxQxvhg3o4dj1Gy54RGf8Q0bjAZ+G8sM+Xks+G3u8Ihdz6xhpMnobXbB9oijkc/i+div/BP/yhf9B34ezSv/pb7t3/cT3/k/+Fu+i+dzll30XHP7/d0vmhWkoj8PPoflHTtC4IASdYqlMCVxHi8pniqZniUFREk0hHeD23gdz6VUQtlUQYObboVWeuVX89ZsrXX3gBMBhSiDEiiN8ukubdJIvhbf44dqTx0e4mJtEWvkaLfQA3qwDkgwIlodNSmsw4AajLABs7nAqzaSIFF6WSmsoqqVrQKDjDeVxba2QV9TEaBmbWgIYbJqqjJDqjB+ZNVdFADestbIzMqKO1AibInbhqI4WojgM7FL6RjRLlMLYTLBKdIe0cFSQJzLA0u57522M3pvfFo/vHJe3T4833Dfzgf4MU9mcsipUIUtfSnLbGkaaGilVrb1rchEkauVrg3riOtc75EPIQ/VUKe2lMpVvqYxTPjdbOsyYz3UgBEgjRXmo4tugx5esHIefsoRNJj3J89bARueU7pDGa7Y3aGNi7orPxyaihGA0FZmYrbm8+aOaZs1s4CCQDHSv5tM1bTMqtkwY/NN0zMjk4S2VbqhSFIGBFyYhVFYhheG3QBDORRiaMIjobu6xpUwFUT4KPSCCL4PIZYolmU6VDsGQjDrXWUaTWTtM5jyliKrTGhDqFs9ry/GdoS3lTX3rr2sx7icxYOQclbO0+Q8FMeGZcsOPBwDC9pYJhANW7glQmStlNgyYEvrdKye+9f721dFtdZd3dP7SEQ11VlP1uhtg0h4bBxAtapF26OW6vKlwb/o3UMAzVvGfxLL77HBm/rQkYcatgOxCVDPjstv7YAuoWCq2d60GPB72jnu+AToHqpKEmTs0BjEw3R0gBw0yl3v94FyvURIxcNnvUMtikTNwORamAau2UrMJwLBELo8gfGJbuapX9CH81ymZGZWFVq+QpjV4abGJYhlsgERrodSChAZuEyXpRicOPAxyRWY89zMjqCZevKToUWdajQzlPwIeBzjXczjEb4EZ2HeI1toIYMlzKD4XBCgYQAQCFQ/ehMIqDk0jKT/QFjfWvigQ0sxfbo8h0SfEjOOpNdvoamhZDGoiRGLV503Ue3Q9EPlri8PR+O2KWZLc9jiHmWE+HzMecSUrRhjhUObC6WsOo+ZWqhl6jxxxSKr/BXOF/a5RbKMC+GZvGqCywq81CTQCNdEG9RGBzceFXroagXErlhQ0IbAx3khAHNhMQ4TqcAWYT72S/95X/cP/A/5Yz8nzpl3OHA2iHBrUmCReAv4u7ggoT/bRmv/xmd8RJvbgApwvQjt2CzN503dPDCrpjPHZl5sQVH7FEgARXmNHEPapKLp62EhB6EFtBIFPOoTMHNqpSsV4iRghkjaKZZBIQ/FlGpUnSjI6hoWwNI5B8sKTwbdlRc0zBMFeQ5zEK/PF7g9nPaybQB8f81AxV4LvrgGq7T6y9VoZUjXuMfXawLOB/NhcyYcvHQ2cEKK61RYRd4b5haDxCzqOIpOdHsm1OE4dCfMRE/GE3fDbPRmvHEfMAt6Ybzgiqw41ll97LDO+FGWjDnLx1sOYHZ/BTgKJnn3/DqjYL1GbnG100nHi+WRQ6l5QbgTchHVi+rLVkCRir8sRoUh7TPFp6MXlHRgCuzToIQLfKCyqmzdqTlDUAfTFMjTKIimx8HxdBuEp0zATKVAmhqBMS0FYBoG4XQ9DD+qPgZ23Q0tEvYhLfSMhmgORd1KNSApBdoHrh8Znd3Qm8FmuJlvvntjNsMN2tBNXjtrjVAKcrfsKnNlrFwo36NYZaRghSl5rWwNXhqGffCUQc6j/DhnIH94H9rmi/lmvpf/IM/7PLcNCIdoHJJRP5qMNqMHI36kjt44WjBaPVobFaULF9q0bbl0F3MjW1imslxsemNiMG7TtSQ/vOBWygBJEw2Pcr+ESWaMexACG+Fz1i1lAddufe4gsKym2FvVuF59T2rTUYo5vFvU2bdUng+8V9xmtDlMmOeadJpepvdpNq2kzXQlTdOl9uceAeOVP8BAK0Sr30omiZXwJEosabUqMMwrzWcOt6+e+weEyxMnuP8ukzh/5/MRpo3QHtgqSWP9c89NBS7eeHn1am91FIC9Snqr+rW2GhCrkd3TqlWP6eTyfmCqCIS8EYNvFKf4zVPL+QQ66PzRFQCdH4HFCWeXRJMJCgHl3jU9jM9v0Nv8bTHkv57Eqth1XfIKIzBBPBGXRcmwzpU3UPIx1a2qGYJfbzBd+ONt0sw7a0/7hI1wIj+u3NA2v5AE/SVgHhrqO6U0KNYn1LEaMzURJkOYCGcnElR5tOKkLAwvC9UkTLaSLrwzWj3TmHeaI/3Q1HTTtPXzZpau+Db9eDS176ZAuutEApixh1CWHYlNOQIVbEG7g3SQztLLdDlF8S6Lg4laqWv1jooIA84aN65Tudam1gP9K4R/YUwlMeUNEoDdCQm9cJx0Vz9/GnivvD30HCZ2XuDmd64+MkfxU9j8FCbsmT27E/TolJtf5WBzmRtfPB9xxm19QM8ZXw1quZY/R+V2V7OHgxP8ytvrD+qzz3eDRy5fz68vgHfrxedmd5vN9bz6QHzxi/sJ78J1HguJ7l4HBnj1k13w4K+yCfzBg4vuJm/m0Ln8N/MEvny5u0QPvGl3GdEx0CUkIt5+7Fw4f+Z5Bt++jZaIr3CX3zPeTFq3ssgQWASvoM5kN/TYtU1di0mrppIKYXbJfkyIIVbuIKD/hHRvWb2tdSN7ny/ly9X1altFRiRGdi1NIw745eKvd+1H3b5hmp7mZR006X4cf3l8h5pgD8I16SBvW0s24XiHndLRyrsghX2YcRWd0VP6ArpJtxj3xJzoF1u5qri4Mx4mVmLrUJe60i+0nGtyuht2lIGjDZFgZuY5c0wFnvGLfMLX/DRgu89JeaFkLS8VRoj59u73yk9FtXph2XI6Oqf371Zyz1so1i925ouA97Hru3+wQxx9jCOuf2g8/UyHaJ5iidW9dnyzKS7acdvyxioZjw0eGeEPTvRKX+t3dFE3cUfHO5uVlRACHAbHX9Tsiz/+6ZsRsw99DLsFo/u5J/DiOdG7+5B0NdzryR8mV5Kvkummey7xsTv3kX1emLnlS7NHeye+kLmvve+rOb+bV/7C4qxZDzzKAf6iTYddn+8P7bncb8RzBn99YjJbQvNKpccey2UwpIZHknzrjnPKeYpB71mBJ4fvsCfte+4xT+nn6cvzrepSnbdie7V9os22zPr4fhsn4/cSl1DXaCf5BNvBOuzz7AqfF46LmRKqknpXzcNtO2znSyLcgtvwADlkTuXjyX/PtycN+R/x3rPnnaW7W3UcZAYa1xGYoT4TjRNcT6AHE3np0sUuUVjyWwqXL1JB+6IHP7x/Tjqxy9jVT5+cFdlRGZRDqepnODPNfzq/RUD5j1cUtXqY7CW/TFJwuOb3Oz/KvH9eKImMmbFZmKUDkO/OkHMumpExNhbG0mRMcUrHdgM3dHO3OKgJm2IpZi4wSzEQC0jDYHVWYcu2OyIRldTnwaIYeURXY09sMLZYklIOAGEnPF0vSPQBgHPjuZ3HVI2Wakttr82v7RuGqqT9m6ZLVdUTZOyLMUXtF1ZxVn//iwtf2F8BVVUlJfQSLahyLVJ86JawG72YoCjQvuinBC0V818vCVY5p0uwM/uV4QJlut57Ak5PVTL0YFZtkiWj490h3ioJBDgcYIjx8N6EaHQP1dbiRjTbft0ewvHxXg6uh1D/GNqs+PgmTr9UcoLretvI7wVJYjJVGptqrTvQozfyYq47PTevOe4RX5tgjx6VB7G6wB8dxYrYKnYrxsfQ7sUwZoBYzIpRwcQCtEdbZUxFgKhBDBuioboA2vpOKI2oCGhBNBErrs095rMUf2ekLqiwW7gXMS+mXXLKntIone6iqzkAxh5g5KEaYqglZtECVRW6rznCDlmF9pG+QrsDrTXHRENSVfE4Xj7XEcpH00K4teCaRS4GGUS0rIA/b7uKX7tbhRpQYUqfWnx97z9ZV2tWq9rWoxrXeSdpCzIAXBDEi2Z+xAFf8ADM80ji3lyYmznBPKL3gAElCN3HSL7B2dqblyi3xKMyPgA00EkhkOuoXBcn3F6Kr4iF00dAlMICgjfZsY71PrqIaeOhk5bDMl1Mb4f0kj7jsNALS+FMciRXwfotqJhu5ZikEW73IpLHNtxE6g1+EvXtgRL2zAHQUTPFc1ML6cBCOKuMYY2i6TDj6qXPD6cDkveDm2vmtaZq6lOAJuL8WW3S49kCoSdOM5g4Pc16vTVlJ/h+T8SPilbfMIz8h8ujZYppbYn6S4Pne0HHqB6LpEHS8LN8CLeyo5ftkduQQTk9dgREEL9Zs8rJaxv2XDgRdtJVmZGPNEcL9Z1x1bgLPfDIduzQ2TmJ0glQQjEYkIQMqUjXTGXJVhR0twrAGUG8YGaHHPCBaIcWId6N7hDjdFeYmRnBFJAM74dHgUPSCY/kagkbuwXyztP0oHMN6NQ141ChQ1Q/ds07mP7gCkRB3ZvezfiU4cBK8kGerCd7P75OzFl/1sYsHks31Ov6DHXbUi27PIAJPmr6NGBYXYwD42+G+4hG7YTeYflScISGg8sswJOIP8mnDp6KvMCgJbaIWxb5ldecxJ84wZ+aEY+/0kOQB2fZb87Oy67MvpodZrP4gwcIePkTywn85ZenkasZ0W768Hlb/wNjmv7mdJx26UE6gz/H7ut1+12tbset02bwde7szqATZ0JPa+8LnvC0N/YyeMqiGZvvMdYMTZoMv9ZeJSz0i+AHGLKeGr4gHoBBw+3HeLcd8ta2mR6mKH5lP3Mrw2esTDXz737eOn9rU15Xcu0si0aoXQ7jPGbI8kfjJXE/NuJOLGK7t1xmAkyHHa+tObhYHR11vHxu4So3vpl2yBQxOOF7E7Ii1+QdUiA10iKrZLHj3u4KDkby+39172hwOl4sdnIorqa7aR/IrRXLuqQt41jeSf7kdwnsFuRLSQ9+j83kIqmXj+SN/EBGcOJLTc7EDw08qzfhGS7oSxqDfZpi7EKDS3f8PrUjFGzP1qsHa9d8OX5mpawd7IyqOBipyvLv8dyR65O/DndXuyZZ0auzjqEwR6RDAJonqeMXeDBHu+PF+GbMjuUx6h6NZ5moncup3EG8hMolkbJOvBu70rWOnTm+IEEAagAi4tNPdhPU1Q7Ccx7ke+NwPL4KowGhIVU5UqFbiaHjY38c0qTnOyOu7s4feF8iaCJ3MeuJ1xPQ55tK6RFgB220qnWs6/qtYqq5kcf5thwqF43Rsu1Ou5DZnfTWO6937d/xBVOeawc9COeO7BwekmgW9+JBLaZrFktXxe8ayMYH2kptdhBg9tjH4aSeIfaiBxdX6I0r29Pu07Pb7g9ZfItYxCYVPXLYSK54/fhwQHM/MUNqfRXKPAZvJHDOmpzXKFMLoFHGWQ4v5HdMMQNlonq2aXkq0hc6TTUPKk/1XIDBBMqElJgVQedMPtfR9laRZW1yrYqsmEieTURjCUryBmjKt1Qblz2CygQfHov3m4rptY0mvOVanfVxuS/pKUNDSjE6bVhbQWD0zI6nghpZcehBE6tQ/e1sRUHvM2dNZp4lgBn2xTMQMYO1oLXKQAH8lP85gbqyvJ+ERRKNLDbl2Hz4AUu3ftJY0WAztzM3cYz58SDbctjaTY1b/zAphQAfdGcTAILGUq8EM6MCDAgagsHcMJ4GLfySpIWssQvKMfFoL3th1pi0NkoZgDcmqThLNhoyjApLtZIsrWCWsp5mUN5S4sQeaCE9Ubuvhxy2WWbBDgQUAxAScWbBGNRa7csC74IIxo34BUIRxSX8/EI4gFQy9rmYb7PJQptCuHyJoNvL+khmiGPP4DflHvlolckq2agXQuFon8KiAlAP44lkOo8Ua0IcYC4aWJ+SYae1Q7cnmDFmAYaEIIP31LBc71aRbdXYruIlChid02hZDwQt7QsYyGDb7IrbwAMIRn14AF9PkDSXgMEhOVb00mW5LDb58Jp2ieDEFtDNFwkWjVM4ULkQVIy9AU6QgohvZ7CTsNkgpv3Ghqrqmz1RwCrmDoroMrmpVPBobHCPWL3aTEvdfD1sgI6wgc+zPWRTAVBJqYnaETyGLcQGSBDBkQkLnj8UUWIJCcBlTiup+fRf2ofO57teFmHyXUTEKe7Isbobys7IXqijMJRxHlVcEgXFuIjTnVMT3jobZKBWSS+0irrXG52RZgW9OlMqqo36+myvPGbeqRxvzpj12SY7y+4uXLy/DYosQ5jKmUWwyS7ssX3ho0++X3jWqnCAaG6u/zvD8gfHXzjw6xoYw7oxE71rDvSpuaEfe9mrvfZN3vJSS8PoeDavr4FkZQW8mKHradtRvcFovv5Z3pRDGIAlcdUnk2STsH7FMEhqpDI82CDASBwAg81/rJVwprqmHe/VQ7r0dT2nW39aX9O0T9VZWvArdY7WfL4u0rY/qtsFMp4ZQmgNMKgflUiEzbnTw0u4q3mQDeB6YTmDXhhwCdnyBjXzWLyvcwYPjgUz/i/CkzQNhoUoAMS6n1uv/Ft+GK/8W+HLgBBCf/zX+uPVF+HcevylsW7/Q+Tt4CH87yGwjyNxBQ2/eENL6NRy68Lvz/4K/7I5xMSHMH8170n8Jh/B/7J3xmnQqF8hG/roT9OLawx/NUm36BJoxXoV8mU+6ib0j/dfuavgh+fyHQe/oz14Iii+W33b8jIk01PQOf7DcIq/B3v7zwEjCx9f3Yf/jHe558Mvmv/8MOhrjb0KT2PUxdbbKv7qMfqAswwKLQZIDGDUIvwKTHLGeJEnuDfD936E+ewb4R5/Dy+6yum+AufCB+AqxfD4uPSU+1tYMvfxM3QJ/tvU4TfgWPy+HO48WDePqJPu2jX+DmxSDL4cXkan9oZXHfMKf2Bj+HEL4BzKv078Z/sL5ExPvsdn0LP/DS/cOXhP9ge8Yr+MDsOvQCfdo/yO4Vd4e/h30ZRzDIao0eD5SnybqWzQf5eBP4sNtDT4OxtfisX9a+Fziq2U/wdCUFL8FXypws+Q1fn4p6jiMfg9rA64suZP/nz/RL4VYhRCAShqYIYx542b85WrAE5oeBoapH6aUmRyWubR+DRtEXeaMcmhzq0ud8RIDmkUN5GcM+DlbAPnJnYMu0DvJnE0QLaUA3nvCpaZuUgtFiziwq3u4woO3cird0ngzBzb5JUjkb3CfParWHY2TaN0Cckc2IUlBg13GDH0TCaulJjyi75O8cZMRyaT3BVziwFF4EzGpl2OfJRKC3IMd2jmPUtupapxoHIObmw5FFI5ORopT8q9U3JZTEUMnO47EJG7MNN+MgefbSa9D7mZ9wMFGYIzA3q1YG4mKycVxSyAM8fIoxNtTrzEYNzxSg/ox0ftwcb9MUo/+huutVOFn/X6d7lSX/cG0Hvli9/p2xV+DNdXNf5Yuy5d/7p53ePhiR7E96dYl96ZOelnn3t94Zjl55xyPhnqxa6fd9xqLFRP6R8xzfvFfnFQHN4xOuhoeMd4/3pwx8E+ZXxKsnvqG37D7QJLFU9Jtw1MfVJ2fEvglx/bhAJ9rOLK+1fH3Pngp/H2d89PDfX96NveMHumx4+55qXrg7rBhsHp6I6dsx87f0fulDtnivlifKJw/DTxmCunCq2FQ48zD/ykfQ9iqzetu21nVc6vd8VzV0LuJHLOo/RV8iVqbOXax66PR92wWnVVo+Cnb+0ZRBjL2GXgadLh8ktlnjv8BbTVYx/SOmLbH/YXkLEjE9mIc3j1+ITGgFBF5e35F5kEAAUaDFhgGDB/LW6mj7b67Ry9cD5cXd8cT5lohigCksOq0RAS0aDJmg0jE1tmAVGixUhKqVCpW49e7Th+pgOnnHZmyKFG8U4Wd76IVIG0MMYmRqDcu8SBkywxBy9OrlynypXObTK1ckpqRzuHOzQMFhQ/aTEQsbj++b84nnJfAKWp/BF2TCkHAAA=) format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Audi Type Wide";src:url(data:font/woff2;base64,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) format("woff2");font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:"Audi Type Extended";src:url(data:font/woff2;base64,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) format("woff2");font-weight:400;font-style:italic;font-display:swap}
/* ---- Farbrollen. Nacht = Grundzustand, Tag als Umschaltung. ---------- */
:root[data-theme="nacht"]{
--canvas:#161b23; /* dunkles Blaugrau wie in der myAudi App */
--tile:#1f2733;
--tile-2:#2a3341;
--line:rgba(255,255,255,.10);
--line-strong:rgba(255,255,255,.20);
--fg:#FFFFFF; --fg2:#9aa1ad; --fg3:#657081;
--ok:#15da15; --warn:#ffaa00; --bad:#fd2c4e;
--shade:rgba(255,255,255,.05);
}
:root[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);
}
:root{ --red:#F50537; --r-tile:20px; --r-pill:999px; }
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
background:#111;font-family:"Audi Type",Helvetica,Arial,sans-serif;font-weight:400;
display:flex;align-items:center;justify-content:center;padding:22px 14px;
-webkit-font-smoothing:antialiased;font-variant-numeric:tabular-nums;
}
.phone{
width:100%;max-width:412px;height:min(880px,calc(100vh - 44px));
background:var(--canvas);color:var(--fg);
display:flex;flex-direction:column;overflow:hidden;position:relative;
transition:background .25s ease,color .25s ease;
}
/* ---------------- Kopf ---------------- */
.topbar{display:flex;align-items:flex-start;gap:12px;padding:16px 20px 6px;flex:0 0 auto}
.back{width:20px;height:20px;border:0;background:none;padding:0;cursor:pointer;display:none;align-items:center}
.back.on{display:flex}
.back svg{stroke:var(--fg);fill:none;stroke-width:1.3}
.head{flex:1 1 auto;min-width:0}
.eyebrow{font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--fg3);margin-bottom:5px}
.title{font-size:23px;font-weight:400;letter-spacing:-.015em;line-height:1.15;
white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sync{display:flex;align-items:center;gap:8px;margin-top:7px;font-size:12.5px;color:var(--fg3)}
.sync svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:1.4}
.rings{
height:26px;width:auto;flex:0 0 auto;display:flex;align-items:center;justify-content:center;
}
.rings{background:none;border:0;padding:0;cursor:pointer}
.rings svg{height:19px;width:auto;display:block;color:var(--fg)}
.badge{display:flex;align-items:flex-end;gap:11px}
.badge svg{height:27px;width:auto;display:block;color:var(--fg)}
.badge .zusatz{font-family:"Audi Type Extended",sans-serif;font-style:italic;
font-size:23px;line-height:1;letter-spacing:.005em;padding-bottom:1px}
.themebtn{
width:34px;height:34px;border:1px solid var(--line);background:none;color:var(--fg2);
cursor:pointer;border-radius:var(--r-pill);flex:0 0 auto;
display:flex;align-items:center;justify-content:center;
}
.themebtn svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.4}
.themebtn:hover{color:var(--fg);border-color:var(--line-strong)}
main{flex:1 1 auto;overflow-y:auto;overscroll-behavior:contain;padding:0 20px 34px}
main::-webkit-scrollbar{width:0}
/* ---------------- Bausteine ---------------- */
.tile{position:relative;background:var(--tile);border-radius:var(--r-tile);padding:22px;margin-bottom:12px}
.tile.flat{background:none;padding:0}
.tilebtn{display:block;width:100%;text-align:left;border:0;font-family:inherit;
color:inherit;cursor:pointer;position:relative}
.tilebtn:hover{background:var(--tile-2)}
.zahnrad{position:absolute;top:16px;right:16px;width:34px;height:34px;border:0;background:none;
cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:var(--r-pill)}
.zahnrad:hover{background:var(--tile-2)}
.zahnrad svg{width:18px;height:18px;stroke:var(--fg3);fill:none;stroke-width:1.3;stroke-linecap:round}
.zahnrad:hover svg{stroke:var(--fg)}
.tilebtn .go{position:absolute;top:24px;right:22px;width:6px;height:10px;
stroke:var(--fg3);fill:none;stroke-width:1.3}
.seg{display:flex;gap:8px;margin-top:14px}
.seg button{flex:1;border:1px solid var(--line-strong);background:none;color:var(--fg2);
font-family:inherit;font-size:11px;letter-spacing:.12em;text-transform:uppercase;
padding:11px 8px;border-radius:var(--r-pill);cursor:pointer}
.seg button.on{border-color:var(--red);color:var(--fg)}
.feld{display:flex;justify-content:space-between;align-items:center;gap:14px;
padding:12px 0;border-bottom:1px solid var(--line)}
.feld label{font-size:13px;color:var(--fg2)}
.feld input,.feld select{background:var(--tile-2);border:1px solid var(--line);
color:var(--fg);font-family:inherit;font-size:13.5px;padding:8px 11px;border-radius:6px;
text-align:right;min-width:132px}
.mitEinheit{display:inline-flex;align-items:center;gap:8px}
.mitEinheit input{min-width:92px;text-align:right}
.mitEinheit span{font-size:13px;color:var(--fg2)}
.notiz{width:100%;margin-top:12px;background:var(--tile-2);border:1px solid var(--line);
border-radius:8px;color:var(--fg);font-family:inherit;font-size:13.5px;line-height:1.6;
padding:12px 13px;resize:vertical}
.feld input[type=checkbox]{min-width:0;width:19px;height:19px;accent-color:var(--red)}
.aktion{display:block;width:100%;margin-top:16px;border:1px solid var(--line-strong);
background:none;color:var(--fg);font-family:inherit;font-size:11px;letter-spacing:.14em;
text-transform:uppercase;padding:14px;border-radius:var(--r-pill);cursor:pointer}
.aktion:hover{border-color:var(--red)}
.label{font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--fg3);display:block}
.fig{font-family:"Audi Type Wide",sans-serif;font-weight:300;letter-spacing:-.02em;line-height:.95}
.unit{font-family:"Audi Type",sans-serif;font-size:.32em;color:var(--fg2);margin-left:.32em;letter-spacing:0}
.sport{font-family:"Audi Type Extended",sans-serif;font-style:italic;letter-spacing:.005em}
.rows{margin-top:4px}
.row{display:flex;justify-content:space-between;align-items:baseline;gap:14px;padding:13px 0;border-bottom:1px solid var(--line)}
.row:last-child{border-bottom:0}
.row dt{font-size:13px;color:var(--fg2)}
.row dd{font-size:14px;text-align:right}
.row dd small{display:block;font-size:11px;color:var(--fg3);margin-top:3px}
.row dd .label{display:block;text-align:right}
.werte{display:block;color:var(--fg);font-size:14px;white-space:nowrap}
.pill{display:inline-block;font-size:10px;letter-spacing:.14em;text-transform:uppercase;
border:1px solid var(--line-strong);border-radius:var(--r-pill);padding:6px 12px;color:var(--fg2)}
.pill.work{border-color:var(--red);color:var(--red)}
/* ---------------- Start ---------------- */
.carbox{position:relative;text-align:center;padding:30px 0 0;display:block;width:100%;background:none;border:0}
.carbox img{width:100%;display:block;-webkit-tap-highlight-color:transparent}
/* Feste Bildhöhe: Front- und Seitenansicht wirken dadurch gleich groß */
.carfix{width:100%;max-width:100%;height:206px;object-fit:contain;display:block}
.carfix.klein{height:165px}
/* Radbild klein und rechtsbündig oben in der Kachel */
.radbild{position:absolute;top:22px;right:22px;width:78px;height:78px;object-fit:contain;display:block}
.radph{position:absolute;top:22px;right:22px;width:78px;height:78px;border:1px dashed var(--line-strong);
border-radius:50%}
/* Kopfbereich hält die Höhe des Radbilds frei, damit die Felder darunter
denselben Abstand haben wie das Bild nach oben und rechts. */
.radkopf{min-height:78px;padding-right:96px}
/* Fahrbahn unter dem Fahrzeug: eine angedeutete Oberfläche, die das Auto
auf den Boden stellt, ohne selbst Aufmerksamkeit zu ziehen.
Innenraum- und Detailbilder bekommen keine. */
.szene{position:relative;border-radius:var(--r-tile);overflow:hidden;margin-bottom:26px}
.szene img{position:relative;z-index:2}
.szene.strasse::before{content:"";position:absolute;left:0;right:0;bottom:0;height:30%;z-index:1;
background:
radial-gradient(ellipse 42% 40% at 50% 76%, rgba(0,0,0,.55) 0%, rgba(0,0,0,0) 72%),
linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.045) 40%,
rgba(255,255,255,.075) 100%);}
.szene.strasse::after{content:"";position:absolute;left:0;right:0;bottom:0;height:30%;z-index:1;
background:linear-gradient(90deg, var(--canvas) 0%, rgba(0,0,0,0) 22%,
rgba(0,0,0,0) 78%, var(--canvas) 100%);}
/* Verschneite Fahrbahn bei montierten Winterrädern */
.szene.winter::before{content:"";position:absolute;left:0;right:0;bottom:0;height:38%;z-index:1;
background-image:url("bilder/fahrbahn-schnee.webp");
background-size:cover;background-position:center bottom;}
.szene.winter::after{content:"";position:absolute;left:0;right:0;bottom:0;height:38%;z-index:1;
background:
radial-gradient(ellipse 40% 44% at 50% 78%, rgba(28,48,70,.5) 0%, rgba(28,48,70,0) 70%),
linear-gradient(90deg, var(--canvas) 0%, rgba(0,0,0,0) 20%,
rgba(0,0,0,0) 80%, var(--canvas) 100%);}
:root[data-theme="tag"] .szene.strasse::before{
background:
radial-gradient(ellipse 42% 40% at 50% 76%, rgba(0,0,0,.28) 0%, rgba(0,0,0,0) 72%),
linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,.05) 40%, rgba(0,0,0,.085) 100%);}
.status{display:flex;align-items:center;gap:12px;padding:16px 0 4px}
.dot{width:11px;height:11px;border-radius:50%;flex:0 0 auto;background:var(--ok)}
.dot.bad{background:var(--bad)}
.status .t{font-size:14px}
.status .s{font-size:11px;color:var(--fg3);margin-top:3px}
.duo{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:12px}
.duo .tile{margin:0}
.tankzeile{display:flex;align-items:flex-end;justify-content:space-between;gap:16px}
.pct{font-size:15px;color:var(--fg2);padding-bottom:9px}
/* Kilometer und Monat nebeneinander. Bricht bei fünfstelligen Kilometern um,
statt die Kachel zu überfüllen. */
.zweizeiler{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
flex-wrap:wrap;margin-top:14px}
.nebenwert{font-size:13px;color:var(--fg2);white-space:nowrap}
.marke{display:inline-flex;align-items:center;gap:8px}
.marke img{height:16px;width:auto;display:block}
.marke .ph{font-size:8px;letter-spacing:.12em;text-transform:uppercase;color:var(--fg3);
border:1px dashed var(--line-strong);border-radius:3px;padding:3px 5px;line-height:1}
.balken{height:4px;border-radius:var(--r-pill);background:var(--line);margin-top:18px;overflow:hidden}
.balken i{display:block;height:100%;border-radius:var(--r-pill);background:var(--fg)}
.ringwrap{position:relative;width:150px;margin:6px auto 0}
.ringwrap .mid{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}
/* ---------------- Aufklappen ---------------- */
.acc-h{
width:100%;border:0;background:none;color:inherit;font-family:inherit;cursor:pointer;text-align:left;
display:flex;align-items:center;gap:13px;padding:16px 0;border-bottom:1px solid var(--line);
}
.mark{width:9px;height:9px;flex:0 0 auto;position:relative}
.mark::before,.mark::after{content:"";position:absolute;background:var(--fg3);transition:transform .18s,background .18s}
.mark::before{left:0;top:4px;width:9px;height:1px}
.mark::after{left:4px;top:0;width:1px;height:9px}
.acc-h[aria-expanded="true"] .mark::after{transform:scaleY(0)}
.acc-h[aria-expanded="true"] .mark::before{background:var(--red)}
.acc-h .k{flex:1 1 auto;font-size:15px}
.acc-h .v{font-size:11.5px;color:var(--fg2);text-align:right;line-height:1.5}
.acc-b{display:none}
.acc-b.on{display:block}
.lvl2 .acc-h{padding-left:22px}
.lvl2 .acc-h .k{font-size:13.5px}
.leaf{
width:100%;border:0;border-bottom:1px solid var(--line);background:none;color:inherit;
font-family:inherit;cursor:pointer;text-align:left;display:flex;align-items:center;gap:12px;
padding:13px 0 13px 44px;
}
.leaf:hover,.acc-h:hover{background:var(--shade)}
.leaf .k{flex:1 1 auto;font-size:13.5px}
.leaf .k small,.leaf .v small{display:block;font-size:11px;color:var(--fg3);margin-top:3px}
.leaf .v{font-size:13px;color:var(--fg2);text-align:right}
.chev{width:6px;height:10px;flex:0 0 auto;stroke:var(--fg3);fill:none;stroke-width:1.3}
/* ---------------- Karte ---------------- */
.mapbox{position:relative;width:100%;aspect-ratio:4/3;border-radius:var(--r-tile);overflow:hidden;background:var(--tile)}
.mapbox .leaflet-container{position:absolute;inset:0;height:100%;width:100%;background:var(--tile);
font-family:inherit;font-size:10px}
.mapbox .leaflet-control-attribution{background:rgba(0,0,0,.45);color:#cfd4dc;font-size:9px}
:root[data-theme="tag"] .mapbox .leaflet-control-attribution{background:rgba(255,255,255,.7);color:#4c4c4c}
.mapbox .leaflet-control-attribution a{color:inherit}
.mapbox .leaflet-control-zoom a{background:var(--tile);color:var(--fg);border-color:var(--line)}
/* ---------------- Statistik ---------------- */
.quad{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-top:14px}
.quad .n{font-family:"Audi Type Wide",sans-serif;font-weight:300;font-size:17px;letter-spacing:-.02em}
.quad .l{font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:var(--fg3);margin-top:6px}
.bar{display:flex;height:4px;border-radius:var(--r-pill);overflow:hidden;margin-top:16px;gap:2px}
.bar i{display:block;height:100%;border-radius:var(--r-pill)}
.legend{display:flex;gap:18px;margin-top:12px;flex-wrap:wrap}
.legend span{font-size:11px;color:var(--fg2);display:flex;align-items:center;gap:7px}
.legend i{width:8px;height:8px;border-radius:50%;display:block}
.tile-h{width:100%;border:0;background:none;color:inherit;font-family:inherit;cursor:pointer;text-align:left;display:block}
.tile-b{display:none;margin-top:6px}
.tile-b.on{display:block}
/* ---------------- Reiter ---------------- */
.tabbar{flex:0 0 auto;display:grid;grid-template-columns:repeat(5,1fr);border-top:1px solid var(--line);background:var(--canvas)}
.tab{background:none;border:0;border-top:2px solid transparent;margin-top:-1px;cursor:pointer;
font-family:inherit;color:var(--fg3);padding:11px 2px 13px;font-size:9px;letter-spacing:.08em;
text-transform:uppercase;display:flex;flex-direction:column;align-items:center;gap:6px}
.tab svg{width:21px;height:21px;stroke:currentColor;fill:none;stroke-width:1.3;
stroke-linecap:round;stroke-linejoin:round}
.tab svg polygon{fill:none;stroke:currentColor;stroke-width:1.3}
.tab:hover{color:var(--fg2)}
.tab.on{color:var(--fg);border-top-color:var(--red)}
.tab.on svg polygon{fill:var(--red);stroke:var(--red)}
.tabbar.ohne .tab span{display:none}
.tabbar.ohne .tab{padding:16px 2px 18px;gap:0}
.tabbar.ohne .tab svg{width:23px;height:23px}
:focus-visible{outline:2px solid var(--red);outline-offset:2px}
@media (prefers-reduced-motion:reduce){*{transition:none!important}}
</style>
</head>
<body>
<div class="phone">
<div class="topbar">
<button class="back" id="back" aria-label="Zurück"><svg viewBox="0 0 12 20"><polyline points="10,1 1,10 10,19"/></svg></button>
<div class="head"><div class="eyebrow" id="eyebrow">Fahrzeug</div><div class="title" id="title">Übersicht</div>
<div class="sync" id="sync"><svg viewBox="0 0 16 16"><path d="M14 8a6 6 0 1 1-1.8-4.3"/><polyline points="14,1 14,4.2 10.8,4.2"/></svg><span></span></div></div>
<button class="themebtn" id="theme" aria-label="Tag- oder Nachtmodus">
<svg id="themeicon" viewBox="0 0 20 20"></svg></button>
<button class="rings" id="ringsbtn" aria-label="Einstellungen"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 289 100" fill="currentColor" aria-hidden="true"> <defs/> <defs> <clipPath id="audiRingsClip" clipPathUnits="userSpaceOnUse"> <path d="M0 100h289V0H0z"/> </clipPath> </defs> <g clip-path="url(#audiRingsClip)" transform="matrix(1 0 0 -1 0 100.00040017)"> <path d="M239 11.1914c-8.885 0-17.075 3.008-23.624 8.05 6.646 8.489 10.624 19.165 10.624 30.759 0 11.593-3.978 22.269-10.624 30.759 6.549 5.041 14.739 8.05 23.624 8.05 21.399 0 38.809-17.41 38.809-38.809 0-21.4-17.41-38.809-38.809-38.809m-86.625 8.05c6.647 8.489 10.625 19.165 10.625 30.759 0 11.593-3.978 22.269-10.624 30.759 6.548 5.041 14.74 8.05 23.624 8.05 8.885 0 17.075-3.009 23.624-8.05-6.646-8.49-10.624-19.166-10.624-30.759 0-11.594 3.978-22.27 10.624-30.759-6.549-5.042-14.739-8.05-23.624-8.05-8.884 0-17.076 3.008-23.625 8.05m-63 0C96.022 27.7304 100 38.4064 100 50.0004c0 11.593-3.978 22.269-10.624 30.759 6.548 5.041 14.74 8.05 23.624 8.05 8.884 0 17.076-3.009 23.624-8.05-6.646-8.49-10.624-19.166-10.624-30.759 0-11.594 3.978-22.27 10.624-30.759-6.548-5.042-14.74-8.05-23.624-8.05-8.884 0-17.076 3.008-23.625 8.05m-78.184 30.759c0 21.399 17.41 38.809 38.809 38.809 8.884 0 17.076-3.009 23.624-8.05C66.978 72.2694 63 61.5934 63 50.0004c0-11.594 3.978-22.27 10.624-30.759-6.548-5.042-14.74-8.05-23.624-8.05-21.399 0-38.809 17.409-38.809 38.809M81.5 27.3734c-4.593 6.375-7.309 14.187-7.309 22.627 0 8.439 2.716 16.252 7.309 22.627 4.593-6.375 7.309-14.188 7.309-22.627 0-8.44-2.716-16.252-7.309-22.627m63 0c-4.593 6.375-7.309 14.187-7.309 22.627 0 8.439 2.716 16.252 7.309 22.627 4.593-6.375 7.309-14.188 7.309-22.627 0-8.44-2.716-16.252-7.309-22.627m63 0c-4.593 6.375-7.309 14.187-7.309 22.627 0 8.439 2.716 16.252 7.309 22.627 4.593-6.375 7.309-14.188 7.309-22.627 0-8.44-2.716-16.252-7.309-22.627m31.5 72.627c-11.932 0-22.896-4.207-31.5-11.207-8.604 7-19.568 11.207-31.5 11.207-11.932 0-22.896-4.207-31.5-11.207-8.604 7-19.569 11.207-31.5 11.207-11.932 0-22.896-4.207-31.5-11.207-8.604 7-19.569 11.207-31.5 11.207-27.57 0-50-22.43-50-50 0-27.571 22.43-50 50-50 11.931 0 22.896 4.206 31.5 11.207C90.104 4.2064 101.068.0004 113 .0004c11.931 0 22.896 4.206 31.5 11.207 8.604-7.001 19.568-11.207 31.5-11.207 11.932 0 22.896 4.206 31.5 11.207 8.604-7.001 19.568-11.207 31.5-11.207 27.57 0 50 22.429 50 50 0 27.57-22.43 50-50 50"/> </g> </svg></button>
</div>
<main id="view"></main>
<nav class="tabbar" id="tabbar"></nav>
</div>
<script>
/* ================================================================
AUSTAUSCHBAR — hier Bild, Ringe und Fahrzeugtitel hinterlegen.
Beide Bildfelder nehmen eine URL oder einen data:-String.
Leer lassen zeigt einen Platzhalter.
================================================================ */
const CONFIG = {
fahrzeugtitel : "RS 4 Avant competition", // Klartext für Kopfzeile und Vorlesefunktion
fahrzeugzusatz : "Avant competition", // steht neben dem Typenschild
fahrzeuguntertitel : "quattro · 331 kW",
kennzeichen : "IN·RS 400",
// Fahrzeugbilder: siehe BILDER weiter unten, durch Antippen umschaltbar
markenlogo : "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgo8c3ZnCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4wIgogICB3aWR0aD0iNjAyLjM2MjE4IgogICBoZWlnaHQ9IjU2MS42MTQxNCIKICAgaWQ9InN2ZzE4ODQiPgogIDxkZWZzCiAgICAgaWQ9ImRlZnMxODg2IiAvPgogIDxnCiAgICAgaWQ9ImxheWVyMSI+CiAgICA8ZwogICAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTQ4LjgxODkxLC0yNTEuNTU1MSkiCiAgICAgICBpZD0iZzE4OTQiPgogICAgICA8cGF0aAogICAgICAgICBkPSJNIDcyLjM1MzU1LDYxMC41NzE4MyBDIDY3LjQzNjE0OSw1ODcuOTc1MDkgNjYuNTM1NDQsNTc5LjA2Mjk3IDY2LjUzNTQ0LDU1NS41NDM1NiBDIDY2LjUzNTQ0LDM5Ni41ODk3NSAxOTIuNjUxMywyNjkuMjY4MDkgMzQ5Ljk4NTQ3LDI2OS4yNjgwOSBDIDUwNy4zNDE2MSwyNjkuMjYxMDEgNjMzLjQ2NDU2LDM5Ni41OTY4MyA2MzMuNDY0NTYsNTU1LjU0MzU2IEMgNjMzLjQ2NDU2LDU3OS4wNjI5NyA2MzIuNTYzODUsNTg3Ljk4MjU0IDYyNy42NDY0NSw2MTAuNTc5MjcgTCA1NDAuMzc1ODYsNjc0LjU0MTI3IEwgNTI3LjA3NjQxLDc4MS4yMjc0MSBMIDM4My4xMjE0Miw3ODEuMjI3NDEgTCAzNzMuOTE4NzQsNzg4LjA0NzU3IEMgMzY3LjAyNTU5LDc5My4wNDUwNSAzNTguMDA0MzMsNzk1LjQ1NjI3IDM0OS43MDIzNiw3OTUuNDU2MjcgQyAzNDAuNzg5ODgsNzk1LjQ1NjI3IDMzMy4wNzYxLDc5Mi43NjkwMyAzMjQuMTg1NTksNzg2LjU2NjExIEwgMzE2LjQ3MTgxLDc4MS4yMjc0MSBMIDE3Mi4zMzUwNCw3ODEuMjI3NDEgTCAxNTguODMyNTYsNjc0LjU0MTI3IEwgNzIuMzUzNTUsNjEwLjU3MTgzIEwgNzIuMzUzNTUsNjEwLjU3MTgzIHogIgogICAgICAgICBzdHlsZT0iZmlsbDojZGYwMDI0O2ZpbGwtcnVsZTpldmVub2RkIgogICAgICAgICBpZD0iXzQ2Nzc0Mzc2IiAvPgogICAgICA8cGF0aAogICAgICAgICBkPSJNIDMyMS42NzIzMiw3MzEuNDgzNjMgTCAzMzMuODk2NzMsNzQwLjc5NTQ1IEMgMzM4LjU4MTY5LDc0NC41MTQ1IDM0NS4yOTM0Myw3NDcuMTAwNDEgMzQ5Ljk4NTQ3LDc0Ny4xMDA0MSBDIDM1NC42OTk0OSw3NDcuMDkyOTYgMzYxLjQxMDg3LDc0NC41MTQ1IDM2Ni4xMDMyNyw3NDAuNzk1NDUgTCAzNzguMzI3NjgsNzMxLjQ4MzYzIEwgNDg0LjAyNTk0LDczMS40ODM2MyBMIDQ5NS4wNDQ1Niw2NDMuODA2MjcgTCA1NzkuMDE3NzUsNTgyLjM2NDYyIEMgNTgyLjMyMjU5LDU2OS42NDYyOCA1ODIuOTEwNzgsNTY0LjgzNzY1IDU4Mi45MTA3OCw1NTIuODI0MDcgQyA1ODIuOTEwNzgsNTM3Ljc5NTg0IDU3OS4wMTAzMSw1MTguOTk3ODkgNTczLjAxNzg3LDUwNS42OTg0NCBMIDU3Mi44MTQ0OCw1MDUuMTc1NDUgTCA0MjAuNzYwOSw2NTguNzI1MzcgTCA1NjcuMDk4MDcsNDc3LjY2MTY3IEMgNTYxLjMwOTM2LDQ1Mi4xMzc0NiA1NDkuNzc0ODQsNDMxLjgyOSA1MzEuODYzMDcsNDE1LjA5Mzk2IEwgNTMxLjA3MTQ5LDQxNC4zODkxOSBMIDM5OS40NDI2LDY0My44MDYyNyBMIDUxNS4yNTg3OCwzOTMuMDcwODkgTCA1MTQuNjQ4NjIsMzkyLjI3OTMxIEMgNDk5LjQyNDQ1LDM3MS42NTA4OSA0ODAuNDA4NTgsMzU3Ljk1MjExIDQ1NS40MDAyNywzNDkuNDQ2NCBMIDM3NC42MTYwNiw2MzQuMzkyNzcgTCA0MzIuODgzNjIsMzM3Ljk0MTI4IEMgNDE1LjU2MDA0LDMyNy45MTAxOCAzOTQuNzUwMiwzMjIuNjE1NDIgMzczLjUxMTk3LDMyMi42MTU0MiBDIDM2Ny43MjI5MSwzMjIuNjE1NDIgMzY1LjcxODExLDMyMi43MTcxMSAzNjAuNDE1OTEsMzIzLjMwNTMgTCAzNDkuNjAwNjcsNjMxLjc4NTI1IEwgMzM1LjY5MTA2LDMyMy41MDg2OCBDIDMyOS45NzQ2NSwzMjIuOTIwNDkgMzI3Ljg3NTU5LDMyMi44MTg4IDMyMy4yNjMyNywzMjIuODE4OCBDIDMwMi45Njg5OCwzMjIuODE4OCAyODQuNDM5OTYsMzI3LjcxNDI0IDI2NS4yMjA3MSwzMzguMzI2MDkgTCAyNjMuOTIwMzIsMzM5LjAzMDg1IEwgMzI1LjE4MDU1LDYzNC45MTU3NiBMIDI0NC4yODcyMSwzNDkuODQ2MDggQyAyMTguMzg1NjMsMzU4LjYzNDkgMTk3LjI2MzYzLDM3My43NjQ4MiAxODQuMTQ1NTksMzkyLjk3NjYzIEwgMzAxLjE0NTk1LDY0My4wMTQ3IEwgMTcwLjIzNTk5LDQxMi4wOTQxOSBDIDE1Mi4xMjA4Myw0MjYuNzk1MzcgMTM3LjQxMjU2LDQ1MS4wNDgyNSAxMzEuNDkyNzYsNDc2LjE1Nzg5IEwgMjc4LjYyMTg1LDY1OS4xMjUwNSBMIDEyNi4yOTE5LDUwNC4zODM4OCBMIDEyNS45Nzk3Myw1MDQuOTc5NTEgQyAxMTkuNjgyMjEsNTE4LjI5MzQ4IDExNS44ODM0Myw1MzYuNDIzMTcgMTE1Ljg4MzQzLDU1My40MzQyMyBDIDExNS44OTA1Miw1NjMuNjI0NzggMTE3LjA4OTIyLDU3Mi45NjU2NSAxMTkuNjc1MTIsNTgzLjI2NTMzIEwgMjA1LjM2OTY1LDY0Ni4yMTA0MSBMIDIxNS44NzIzNyw3MzEuNDgzNjMgTCAzMjEuNjcyMzIsNzMxLjQ4MzYzIHogIgogICAgICAgICBzdHlsZT0iZmlsbDojZjZlMDAwO2ZpbGwtcnVsZTpldmVub2RkIgogICAgICAgICBpZD0iXzQ2MTU3MDQ4IiAvPgogICAgPC9nPgogIDwvZz4KPC9zdmc+Cg==", // Bildmarke des Kraftstoffanbieters
markenname : "Shell",
startbild : "Frontansicht", // Bild der Übersicht, in den Einstellungen änderbar
version : "0.18",
tankvolumen : 58,
nachtVon : "18:59", // Nacht = 18:59 bis 05:59
nachtBis : "05:59",
pauseMin : 15 // kürzere Unterbrechungen zählen als eine Fahrt
};
const CAR = {
fin:"WUAZZZF48PA902804", details:"2.9 TFSI quattro competition · 331 kW · 450 PS",
erstzulassung:"08/2023", odo:20140, tankPct:62, spannung:12.4,
gesichert:true, standAlter:"vor 34 Min.",
hu:"08/2026", inspektionKm:4800, inspektionTage:212, oelKm:2100,
smartdeal:{aktiv:true, laeuftAb:"2027-03-31"},
oel:{modus:"hersteller", km:15000, monate:12, herstellerKm:30000, herstellerMonate:24},
versicherung:{
gesellschaft:"Audi Versicherung",
vertrag:"Haftpflicht, Vollkasko und Teilkasko, Schutzbrief Mobilität",
nummer:"VW-1971391586",
service:"0800 11 222 88", notfall:"+49 531 3939 7430", // Schaden-Notruf, rund um die Uhr
beitrag:2068.45, steueranteil:330.25, steuersatz:"19 %",
gueltigAb:"2026-08-13", zahlweise:"jährlich",
teile:[
{bez:"Haftpflicht und Schutzbrief Mobilität", betrag:293.32, sf:"SF 18", sfAlt:"SF 17", satz:"30 %", satzAlt:"30 %"},
{bez:"Vollkasko inklusive Teilkasko", betrag:1775.13, sf:"SF 17", sfAlt:"SF 16", satz:"26 %", satzAlt:"27 %"}
],
selbst:[["Vollkasko","500 €"],["Teilkasko","150 €"]],
/* Schutzbrief Mobilität, Zusatzvereinbarung KRB 4121/01.
Alle Beträge aus dem Bedingungswerk. */
schutzbrief:{
stand:"KRB 4121/01, Fassung 10.2021",
gilt:"Europa einschließlich europäischer und asiatischer Türkei sowie außereuropäische EU-Gebiete",
versichert:"Halter, berechtigter Fahrer und berechtigte Insassen, inklusive Gepäck, privater Ladung und mitgeführtem Anhänger",
ausloeser:["Panne — jeder Betriebs-, Bruch- oder Bremsschaden","Unfall","Diebstahl",
"Krankheit, Verletzung oder Tod auf einer Reise","Naturkatastrophe"],
/* Der zentrale Punkt: diese drei Leistungen schließen einander aus. */
entweder:[
{bez:"Weiterkommen", grenze:"Bahn 1. Klasse bis 1 200 km, darüber Linienflug Economy",
zusatz:"Taxi zum und vom Bahnhof bis 100 €"},
{bez:"Übernachten", grenze:"3 Nächte, je 100 € und Person", zusatz:""},
{bez:"Mietwagen", grenze:"bis zu 14 Tage, bis das Fahrzeug repariert ist", zusatz:""}
],
gruppen:[
{titel:"Am Schadenort", posten:[
["Pannenhilfe vor Ort","bis 100 €","einschließlich verwendeter Kleinteile"],
["Abschleppen","bis 200 €","zur nächsten Werkstatt, Gepäck und Ladung eingeschlossen"],
["Bergen","volle Kosten","wenn das Fahrzeug von der Straße abgekommen ist"],
["Falschbetankung","bis 500 €","Entfernen des Treibstoffs, Folgeschäden ausgeschlossen"]]},
{titel:"Das Fahrzeug", posten:[
["Rücktransport zur Wunschwerkstatt","volle Kosten","wenn nicht binnen 3 Werktagen fahrbereit, nicht bei Totalschaden"],
["Unterstellung","bis 14 Tage",""],
["Unterstellung bei Totalschaden","bis 14 Tage","bis zur Verzollung oder Verschrottung"],
["Schlüsselverlust","Versandkosten","Ersatzschlüssel selbst nicht ersetzt"],
["Schlüssel eingeschlossen","Öffnen übernommen",""]]},
{titel:"Im Ausland", posten:[
["Ersatzteilversand","Versandkosten","wenn vor Ort nicht beschaffbar"],
["Rücktransport","volle Kosten","wenn nicht binnen 3 Werktagen fahrbereit und Reparatur nicht teurer als ein gleichwertiger Gebrauchtwagen"],
["Rückholung nach Reparatur","volle Kosten",""],
["Verzollung","Verfahrensgebühren","Zoll und Steuern nicht enthalten"],
["Verschrottung","volle Kosten",""],
["Todesfall","bis 5 000 €","Bestattung im Ausland oder Überführung"],
["Rückreise in besonderen Fällen","bis 2 500 € je Person","schwere Erkrankung naher Angehöriger, erheblicher Schaden am Eigentum"]]},
{titel:"Personen", posten:[
["Krankenrücktransport","volle Kosten","ärztlich angeordnet, plus 3 Nächte à 100 €"],
["Rückholung von Kindern","Bahn 1. Klasse","zusätzlich bis 100 € für Taxi"],
["Krankenbesuch","bis 500 €","ab zwei Wochen Krankenhausaufenthalt"],
["Fahrzeugabholung bei Fahrerausfall","volle Kosten","selbst gefahren 0,40 € je km, plus 3 Nächte à 100 €"],
["Medizinischer Beratungsservice","telefonisch","kein Notarzt, keine Diagnose"]]},
{titel:"Naturkatastrophe", posten:[
["Übernachtung","3 Nächte à 100 €","je Person"],
["Verpflegung","3 Tage à 15 €","je Person"],
["Taxi und öffentliche Verkehrsmittel","bis 100 €",""]]}
],
nicht:[
["Rennen","Auch behördlich genehmigte Veranstaltungen mit Höchstgeschwindigkeit — samt Übungsfahrten"],
["Vorsatz","kein Versicherungsschutz"],
["Grobe Fahrlässigkeit","Leistung wird der Schwere entsprechend gekürzt"],
["Krieg, innere Unruhen, Staatsgewalt","kein Versicherungsschutz"],
["Kernenergie","kein Versicherungsschutz"]
],
pflichten:[
"Vor Inanspruchnahme einer Leistung Weisung des Versicherers einholen, soweit möglich",
"Schadenereignis binnen einer Woche melden",
"Behördliche Ermittlungen unverzüglich mitteilen",
"Originalbelege zum Nachweis der Kosten aufbewahren",
"Schaden nach Möglichkeit mindern"
],
rang:"Besteht Anspruch gegen einen Dritten, etwa aus einer Automobilclub-Mitgliedschaft, geht dieser vor. Wendest du dich zuerst an den Versicherer, ist er zur Vorleistung verpflichtet."
},
leistungen:[
{gruppe:"Haftpflicht", posten:[
"Versicherungssumme 100 Mio. €, Personenschäden bis 15 Mio. € je Person",
"Umweltschadensgesetz 5 Mio. € je Fall, 10 Mio. € im Jahr",
"MallorcaDeckung für Mietwagen im europäischen Ausland"]},
{gruppe:"Kasko", posten:[
"Vollkasko mit 500 € Selbstbeteiligung",
"Teilkasko mit 150 € Selbstbeteiligung",
"Unfall sowie mut- und böswillige Handlungen Dritter",
"Hackerangriff auf die Fahrzeugsoftware mitversichert",
"Elementarereignisse, Entwendung, Brand, Explosion, Glasbruch",
"Zusammenstoß mit Tieren jeglicher Art",
"Tierbiss inklusive Folgeschäden bis 10.000 €",
"Kurzschluss an der Verkabelung inklusive Folgeschäden bis 10.000 €",
"Fahrzeugteile und Zubehör bis 20.000 € beitragsfrei"]},
{gruppe:"Nach einem Totalschaden", posten:[
"Neupreisentschädigung bei Totalschaden binnen 12 Monaten nach Erstzulassung",
"Zulassungs- und Verwaltungskosten für das Ersatzfahrzeug bis 200 €",
"Überführungskosten bei Neuwagenkauf bis 1.000 €",
"Austausch der Schlösser bis 1.000 € bei Raub oder Einbruchdiebstahl der Schlüssel"]},
{gruppe:"Werkstatt", posten:[
"Werkstattsteuerung über das Fachwerkstattnetz des Versicherers",
"Außerhalb des Netzes nur 80 % der Reparaturkosten, abzüglich Selbstbeteiligung",
"Reparatur nach Herstellervorgaben mit Originalteilen oder gleichwertigen Teilen"]},
{gruppe:"Mobilität", posten:[
"Schutzbrief Mobilität, europaweit rund um die Uhr",
"Pannen- und Unfallhilfe, auch bei Diebstahl oder Fahrerausfall",
"Ersatzmobilität, wenn das Fahrzeug nicht binnen 60 Minuten fahrbereit ist"]},
{gruppe:"Automatisierte Fahrfunktionen", posten:[
"Kein Rabattverlust, wenn allein die automatisierte Fahrfunktion den Schaden verursacht hat",
"Nachweis durch die gespeicherten Fahrzeugdaten zum Schadenereignis"]}
]},
steuer:{betrag:434, zeitraum:"jährlich", faellig:"", grundlage:"Hubraum und CO₂-Ausstoß",
lastschrift:true, finanzamt:"Hauptzollamt"},
kmProTag: 18.3, // aus dem Servicebuch: 19 864 km in 1 085 Tagen
/* Technische Daten aus dem Fahrzeugdatenblatt (FIN WUAZZZF48PA902804). */
technik:[
{gruppe:"Motor", posten:[
["Bauart","V6 Ottomotor, Direkteinspritzung, Biturbo"],
["Hubraum","2 894 cm³"],
["Leistung","331 kW / 450 PS bei 5 7006 700 min⁻¹"],
["Maximales Drehmoment","600 Nm bei 2 0005 000 min⁻¹"],
["Abgasreinigung","Katalysator, Lambdasonde, Ottopartikelfilter"],
["Abgasnorm","EU6 AP"],
["Motormanagement","vollelektronisch"]]},
{gruppe:"Kraftübertragung", posten:[
["Getriebe","8-Gang tiptronic"],
["Antrieb","quattro, permanent, selbstsperrendes Mittendifferenzial"],
["Kupplung","hydraulischer Drehmomentwandler mit Überbrückung"]]},
{gruppe:"Fahrleistungen", posten:[
["0 auf 100 km/h","3,9 s"],
["Höchstgeschwindigkeit","290 km/h"],
["Effizienzklasse","E"],
["Fahrgeräusch","70 dB(A)"]]},
{gruppe:"Fahrwerk, Lenkung, Bremsen", posten:[
["Fahrwerk","RS-Sportfahrwerk"],
["Vorderachse","5-Lenker, Rohrstabilisator"],
["Hinterachse","5-Lenker, Rohrstabilisator"],
["Lenkung","elektromechanisch, geschwindigkeitsabhängig"],
["Wendekreis","ca. 11,7 m"],
["Bremsanlage","RS-Stahlbremse, Sättel rot glänzend"],
["Vorn","Faustsattel, Scheibe innenbelüftet"],
["Hinten","Faustsattel mit elektrischer Parkbremse, innenbelüftet"]]},
{gruppe:"Räder und Reifen", posten:[
["Räder","Leichtmetall 9J × 20, Audi Sport"],
["Reifen","275/30 R20 97Y XL"],
["Pannenhilfe","Reifenreparaturset, kein Ersatzrad"],
["Radschrauben","Standard"],
["Anzugsmoment","120 Nm"]]},
{gruppe:"Maße, Gewichte, Volumen", posten:[
["Leergewicht","1 820 kg"],
["Zulässiges Gesamtgewicht","2 350 kg"],
["Dachlast / Stützlast","90 / 80 kg"],
["Anhängelast gebremst","2 100 kg bei 8 %, 1 900 kg bei 12 %"],
["Anhängelast ungebremst","750 kg"],
["Gepäckraum","495 / 1 495 l"],
["Tankinhalt","58 l, erhöhtes Füllvolumen für quattro"]]},
{gruppe:"Bordnetz", posten:[
["Batterie","420 A, 75 Ah"],
["Generator","100150 A"],
["Kältemittel","R1234yf"]]},
{gruppe:"Wartung", posten:[
["Serviceanzeige","30 000 km oder 2 Jahre, variabel"],
["Garantie","Anschlussgarantie 3 Jahre, max. 100 000 km"]]}
],
/* Ausstattung. Sonderausstattung vollständig, Serienausstattung auf das
Aussagekräftige gekürzt — Einträge wie „Kein Selbstabholer" sind
Produktionsmerkmale und im Alltag ohne Nutzen. */
ausstattung:[
{gruppe:"RS-Paket", sonder:["RS competition","RS-Designpaket rot","RS-Komfortpaket",
"RS-Sportabgasanlage plus","RS-Sportfahrwerk","RS-Stahlbremsanlage, Sättel rot glänzend",
"Bremssättel rot lackiert","Anhebung der Höchstgeschwindigkeit auf 290 km/h",
"Sicherheitsgurte schwarz mit rotem Rand","RS-Einstiegsleisten"]},
{gruppe:"Außen", sonder:["Optikpaket schwarz plus","Optikpaket schwarz glänzend",
"Panorama-Glasdach","Dachreling schwarz","Anhängevorrichtung",
"Gepäckraumklappe elektrisch öffnend und schließend",
"Matrix-LED-Scheinwerfer mit dynamischer Lichtinszenierung",
"LED-Heckleuchten mit dynamischer Lichtinszenierung",
"Außenspiegel elektrisch, beheiz- und anklappbar, abblendend, mit Memory",
"Außenspiegelgehäuse in Wagenfarbe","Sonnenschutzverglasung abgedunkelt"]},
{gruppe:"Innen", sonder:["Mikrofaser Dinamica/Leder mit Wabensteppung und RS-Stickung",
"Sportsitze plus vorn","Vordersitze elektrisch mit Memory für den Fahrersitz",
"Sitzheizung vorn und hinten","Lendenwirbelstütze mit Massagefunktion",
"Dekoreinlagen Carbon Köper matt","Ambiente-Lichtpaket plus",
"3-Zonen-Komfortklimaautomatik","Lederlenkrad 3-Speichen mit Lenkradheizung",
"Innenspiegel automatisch abblendend, rahmenlos","USB-Ladeschnittstellen im Fond",
"Sonnenschutzrollo hinten","Fußmatten RS-Designpaket"]},
{gruppe:"Infotainment", sonder:["MMI Navigation plus mit MMI touch","Audi virtual cockpit plus",
"Head-up-Display","Bang & Olufsen Premium Sound System mit 3D-Klang","Audi phone box",
"LTE-Unterstützung für Audi phone box","Audi connect Navigation & Infotainment"]},
{gruppe:"Assistenz", sonder:["Assistenzpaket Tour","Assistenzpaket Stadt mit Parken",
"Audi adaptive cruise control","Audi active lane assist","Halteassistent",
"Parkassistent mit Einparkhilfe plus","Umgebungskameras",
"Kamerabasierte Verkehrszeichenerkennung","Audi pre sense rear und basic",
"Garagentoröffner","Komfortschlüssel mit sensorgesteuerter Heckklappe"]},
{gruppe:"Serie, ausgewählt", sonder:["Audi drive select","Audi pre sense city",
"Spurwechselwarnung","Reifendruck-Kontrollanzeige","Start-Stop-System",
"Audi connect Notruf & Service mit Remote & Control","Smartphone-Interface",
"Kraftstoffbehälter mit erhöhtem Füllvolumen","Pedalerie und Fußstütze aus Edelstahl"]}
],
reifen:{aktiv:"Sommer",
wechsel:{datum:"2026-10-15", vereinbart:false},
anzugsmoment:120, // Nm
sommer:{bild:"bilder/rad-sommer.webp", km:31240,marke:"Continental",modell:"SportContact 7",dot:"1224",mass:"275/30 R20 97Y XL",
druck:"2,5 / 2,4 bar",kauf:"04/2024",kommentar:"Profiltiefe 5,1 mm bei der letzten Kontrolle"},
winter:{bild:"bilder/rad-winter.webp", km:24870,marke:"Michelin",modell:"Pilot Alpin 5",dot:"3822",mass:"265/35 R19",
druck:"2,6 / 2,5 bar",kauf:"10/2022",kommentar:"Eingelagert beim Autohaus"}},
service:{
autohaus:{name:"Audi AG Kundendienst Center Ingolstadt",
adresse:"Auto-Union-Straße, 85045 Ingolstadt",
tel:"0841 8930600", mail:"kundendienstcenter.ingolstadt@audi.de",
pos:[48.78108, 11.42408]},
/* Die Termine werden nicht gespeichert, sondern aus Servicebuch und
Einstellungen berechnet. Gespeichert wird nur, was vereinbart wurde. */
vereinbart:{},
buch:[
{datum:"23.07.2026", km:19874, art:"Ölwechsel-Service (flexibel)", werkstatt:"Audi AG Kundendienst Center Ingolstadt", kosten:null},
{datum:"20.10.2025", km:13335, art:"Inspektion", werkstatt:"Audi AG Kundendienst Center Ingolstadt", kosten:null},
{datum:"11.07.2025", km:10000, art:"Ölwechsel-Service (flexibel)", werkstatt:"Audi AG Kundendienst Center Ingolstadt", kosten:null},
{datum:"11.10.2024", km:1500, art:"Ölwechsel-Service (flexibel)", werkstatt:"Audi AG Kundendienst Center Ingolstadt", kosten:null},
{datum:"04.08.2023", km:10, art:"Übergabe-Inspektion", werkstatt:"Audi AG Kundendienst Center Ingolstadt", kosten:null}
]}
};
const TRIPS = [
{id:"t1",jahr:2026,monat:"Juli",tag:"29.07.",zeit:"07:12",von:"Ingolstadt, Am Westpark",nach:"München, Leopoldstr.",
kmA:87220,kmE:87308,dist:88,dauer:"1:04 h",schnitt:82,max:171,kosten:18.55,art:"Arbeitsweg",nacht:false,
a:[48.7628,11.4030],b:[48.1600,11.5860]},
{id:"t2",jahr:2026,monat:"Juli",tag:"29.07.",zeit:"19:40",von:"München, Leopoldstr.",nach:"Ingolstadt, Am Westpark",
kmA:87308,kmE:87396,dist:88,dauer:"0:58 h",schnitt:91,max:184,kosten:18.12,art:"Arbeitsweg",nacht:true,
a:[48.1600,11.5860],b:[48.7628,11.4030]},
{id:"t3",jahr:2026,monat:"Juli",tag:"27.07.",zeit:"10:35",von:"Ingolstadt, Am Westpark",nach:"Rain am Lech, Salbeiweg",
kmA:87074,kmE:87142,dist:68,dauer:"0:51 h",schnitt:80,max:158,kosten:14.41,art:"Privat",nacht:false,
a:[48.7628,11.4030],b:[48.6890,10.9160]},
{id:"t4",jahr:2026,monat:"Juni",tag:"18.06.",zeit:"14:05",von:"Ingolstadt, Am Westpark",nach:"Regensburg, Donaupark",
kmA:86412,kmE:86528,dist:116,dauer:"1:19 h",schnitt:88,max:176,kosten:23.90,art:"Privat",nacht:false,
a:[48.7628,11.4030],b:[49.0195,12.0975]},
{id:"t5",jahr:2025,monat:"Dezember",tag:"22.12.",zeit:"20:15",von:"Ingolstadt, Am Westpark",nach:"Garmisch, Hauptstr.",
kmA:79880,kmE:80062,dist:182,dauer:"2:11 h",schnitt:83,max:169,kosten:36.40,art:"Privat",nacht:true,
a:[48.7628,11.4030],b:[47.4917,11.0955]}
];
/* rabatt = Ersparnis durch SmartDeal, summe = tatsächlich gezahlt */
const FILLS = [
{id:"f1",pctVor:26,pctNach:100,jahr:2026,monat:"Juli",datum:"29.07.2026",zeit:"16:05",liter:42.96,summe:90.60,rabatt:12.46,
odo:87396,seit:322,station:"A. Zrenner GmbH",adresse:"Pascalstr. 8, 85057 Ingolstadt",beleg:true,pos:[48.7476,11.4497]},
{id:"f2",pctVor:18,pctNach:100,jahr:2026,monat:"Juli",datum:"27.07.2026",zeit:"11:28",liter:47.61,summe:100.88,rabatt:13.81,
odo:87074,seit:546,station:"Thomas Bauch GmbH",adresse:"Salbeiweg 2, 86641 Rain am Lech",beleg:true,pos:[48.6903,10.9174]},
{id:"f3",pctVor:22,pctNach:100,jahr:2026,monat:"Juni",datum:"14.06.2026",zeit:"08:12",liter:45.20,summe:94.42,rabatt:13.11,
odo:86528,seit:498,station:"A. Zrenner GmbH",adresse:"Pascalstr. 8, 85057 Ingolstadt",beleg:true,pos:[48.7476,11.4497]},
{id:"f4",pctVor:30,pctNach:96,jahr:2025,monat:"Dezember",datum:"20.12.2025",zeit:"17:41",liter:44.10,summe:85.95,rabatt:12.79,
odo:79880,seit:512,station:"Thomas Bauch GmbH",adresse:"Salbeiweg 2, 86641 Rain am Lech",beleg:true,pos:[48.6903,10.9174]}
];
/* ---------------------------------------------------------------- */
const $ = s => document.querySelector(s);
const de = (n,d=0)=>n.toLocaleString("de-DE",{minimumFractionDigits:d,maximumFractionDigits:d});
const eur = n => de(n,2);
const esc = s => String(s).replace(/[&<>"]/g,c=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[c]));
const sum = (a,f)=>a.reduce((s,x)=>s+f(x),0);
/* Durchschnittspreis IMMER mengengewichtet: Summe Kosten / Summe Liter */
const schnittpreis = list => sum(list,f=>f.summe)/sum(list,f=>f.liter);
/* Symbole der Navigationsleiste. „Mein Audi" nutzt die RS-Raute aus dem
Typenschild — als Umriss, gefüllt sobald der Reiter aktiv ist. */
const ICONS = {
home :'<path d="M4 17a9 9 0 0 1 18 0"/><path d="M13 17l5.5-5"/><circle cx="13" cy="17" r="1.3"/>',
audi :'<polygon points="21.6,5 16.5,19 2.4,19 7.5,5" transform="translate(0,0)"/>',
trips:'<circle cx="6" cy="6" r="2.2"/><circle cx="18" cy="18" r="2.2"/><path d="M8 7.5c4 1.5 4.5 3 3 5s-1 3.5 4.5 5"/>',
stat :'<path d="M4 20V9.5M10 20V4.5M16 20v-8M22 20H2"/>',
fuel :'<path d="M4.5 20V6.2c0-.9.8-1.7 1.7-1.7h5.6c1 0 1.7.8 1.7 1.7V20"/><path d="M3 20h12.5"/><path d="M4.5 11h10.5"/><path d="M17 20v-8.5a2 2 0 0 0-2-2"/><path d="M17 11.5V7.8l-2-2.3"/>'
};
const TABS = [
{id:"home", label:"Übersicht", eyebrow:"Fahrzeug", title:"Übersicht"},
{id:"audi", label:"Mein Audi", eyebrow:"Fahrzeug", title:CONFIG.fahrzeugtitel},
{id:"trips",label:"Fahrten", eyebrow:"Fahrtenbuch",title:"Fahrten"},
{id:"stat", label:"Statistik", eyebrow:"Auswertung", title:"Statistik"},
{id:"fuel", label:"Tanken", eyebrow:"Kraftstoff", title:"Tanken"}
];
let route = {name:"home"};
const ZURUECK = {trip:"trips", fill:"fuel", service:"audi", reifen:"audi", ident:"audi",
vers:"audi", kosten:"audi", schutz:"vers",
werkstatt:"service", sbuch:"service", einst:"home"};
/* ---------- Grafik ---------- */
function badge(){
return `<div class="badge"><?xml version="1.0" encoding="UTF-8"?><svg aria-label="RS 4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 425 100"><polygon points="140 0 103.603 100 0 100 36.397 0 140 0" style="fill:#f50537;"/><path d="M279.9435,15c13.89,0,23.0062,9.5991,18.3107,22.5h-16.5c2.1994-6.0428-2.4854-9.5-6.5423-9.5h-48.5c-10,0-10.9525,2.617-12.6388,7.25-1.327,3.646-1.046,7.25,7.3612,7.25h48.5c12.7976,0,24.4649,5.5913,18.7656,21.25-5.1069,14.031-8.473,21.25-34.2344,21.25h-48.5c-22.238,0-20.8261-15.589-17.9467-23.5h16.5c-1.5172,4.1686-2.3153,10.5,6.1783,10.5h48.5c9.0063,0,11.2814-3.5205,13.0028-8.25,2.3539-6.4674-.7024-8.25-6.9972-8.25h-48.5c-16.0991,0-23.0423-9.5-19.1296-20.25,5.1394-14.1202,7.854-20.25,33.8704-20.25h48.5Z" style="fill:currentColor;"/><path d="M165.478,15h-70l-25.478,70h16.5l9.4633-26h59.5518c4.7471,0,6.8294,4.4041,4.2185,25.9165h16.9999v-8.9007c0-5.2722,0-17.0158-5.796-23.4287,6.8742-3.3009,10.0555-7.4061,12.8643-15.1234,4.6956-12.9009-4.4339-22.4637-18.3239-22.4637ZM100.6949,46l6.5515-18h53.5c4.0569,0,8.7549,3.4209,6.5555,9.4637-2.1993,6.0427-5.3154,8.5363-13.1069,8.5363h-53.5Z" style="fill:currentColor;"/><path d="M408.4969,59l16.0201-44h-24.75l-80.2974,39.2816-6.4489,17.7184h74.25l-4.7316,13h16.5s4.7316-13,4.7316-13h16.4977l4.7316-13h-16.5031ZM392.0022,59h-53.6829l64.966-31h0l-11.2831,31Z" style="fill:currentColor;"/></svg><span class="zusatz">${esc(CONFIG.fahrzeugzusatz)}</span></div>`;
}
const BILDER = [{name:"Seitenansicht",src:"bilder/seitenansicht.webp"},{name:"Front schräg",src:"bilder/front-schraeg.webp"},{name:"Frontansicht",src:"bilder/frontansicht.webp"},{name:"Heckansicht",src:"bilder/heckansicht.webp"},{name:"Cockpit",src:"bilder/cockpit.webp"},{name:"Scheinwerfer",src:"bilder/scheinwerfer.webp"},{name:"Sitze",src:"bilder/sitze.webp"}];
let bild = 0;
/* modus "fest": ein festes Bild, kein Umschalten (Übersicht).
modus "galerie": durchschaltbar per Antippen (Mein Audi).
Die Bildfläche hat in beiden Fällen dieselbe Höhe, damit Front- und
Seitenansicht gleich groß wirken. */
function startIndex(){
const i = BILDER.findIndex(b => b.name === CONFIG.startbild);
return i < 0 ? 0 : i;
}
/* Für die Seitenansicht liegt eine zweite Fassung mit montierten Winterrädern
bereit. Nur diese Perspektive zeigt die Räder groß genug, dass sich der
Austausch lohnt — die übrigen Ansichten bleiben unverändert. */
const SEITE_WINTER = "bilder/seitenansicht-winter.webp";
function bildSrc(i){
const b = BILDER[i];
return (b.name === "Seitenansicht" && CAR.reifen.aktiv === "Winter") ? SEITE_WINTER : b.src;
}
function carImg(modus){
if(modus === "fest"){
const b = BILDER[startIndex()];
return `<img class="carfix klein" src="${bildSrc(startIndex())}" alt="${esc(CONFIG.fahrzeugtitel)}">`;
}
return `<img id="carimg" class="carfix" src="${bildSrc(bild)}"
alt="${esc(CONFIG.fahrzeugtitel)}">
<div class="dots" id="dots">${BILDER.map((_,i)=>
`<i class="${i===bild?"on":""}"></i>`).join("")}</div>`;
}
/* Antippen schaltet weiter. Nur die betroffenen Knoten werden getauscht,
damit die Scrollposition erhalten bleibt. */
/* Bildmarke des Anbieters. Geschützte Zeichen werden nicht nachgezeichnet —
hier steht ein Platz, in den die Originaldatei eingesetzt wird. */
function markenlogo(){
if(!CAR.smartdeal.aktiv) return "";
return CONFIG.markenlogo
? `<img src="${esc(CONFIG.markenlogo)}" alt="${esc(CONFIG.markenname)}">`
: `<span class="ph">Logo</span>`;
}
/* Cockpit, Sitze und der Scheinwerfer-Ausschnitt zeigen keine Fahrbahn —
eine verschneite Straße hinter einem Innenraumfoto wäre Unsinn. */
const OHNE_SZENE = ["Cockpit","Sitze","Scheinwerfer"];
function szeneKlasse(i){
if(!bodenAn) return "";
if(OHNE_SZENE.includes(BILDER[i].name)) return "";
return CAR.reifen.aktiv === "Winter" ? "winter" : "strasse";
}
function bildWeiter(){
bild = (bild + 1) % BILDER.length;
const img=document.getElementById("carimg");
if(!img) return;
img.src = bildSrc(bild);
const sz=document.getElementById("szene");
if(sz) sz.className = "szene " + szeneKlasse(bild);
[...document.getElementById("dots").children].forEach((d,i)=>
d.classList.toggle("on", i===bild));
}
/* ---------- Termine und Vorhersage ---------- */
const heute = new Date(2026,7,3);
const dTag = 86400000;
const mmjj = d => String(d.getMonth()+1).padStart(2,"0")+"/"+String(d.getFullYear()).slice(2);
const dedat = d => d.toLocaleDateString("de-DE",{day:"2-digit",month:"2-digit",year:"numeric"});
/* Aus der durchschnittlichen Tagesleistung ableiten, wann ein Kilometerstand
erreicht ist. Grundlage ist die Statistik, nicht eine Annahme. */
/* Die Tagesleistung wird aus dem ältesten Servicebuch-Eintrag und dem
aktuellen Kilometerstand berechnet — sie wächst also mit jedem gefahrenen
Kilometer mit, statt ein fester Wert zu bleiben. */
function dat(s){ const [d,m,j]=s.split(".").map(Number); return new Date(j,m-1,d); }
/* Zwei Zeiträume, gewichtet gemischt:
- langfristig: der gesamte bekannte Verlauf seit dem ältesten Eintrag
- aktuell: seit dem letzten Service, also seit dem Zurücksetzen des Zählers
Direkt nach einem Service ist der aktuelle Zeitraum zu kurz für eine
belastbare Aussage, deshalb überwiegt zunächst der Langzeitwert. Mit jedem
Tag verschiebt sich das Gewicht, nach etwa einem halben Jahr zählt allein
der aktuelle Abschnitt. Die Vorhersage wird also genauer, je näher das Ziel
rückt — und startet nach jedem Service neu. */
const MISCHDAUER = 180;
function tagesleistung(){
const b=CAR.service.buch;
if(!b.length) return {wert:CAR.kmProTag, quelle:"Vorgabe", tage:0, km:0};
const alt = b[b.length-1];
const tageGesamt = Math.max(1, (heute - dat(alt.datum))/dTag);
const langfristig = (CAR.odo - alt.km)/tageGesamt;
const letzter = b[0];
const tageSeit = (heute - dat(letzter.datum))/dTag;
const kmSeit = CAR.odo - letzter.km;
if(tageSeit < 14 || kmSeit <= 0)
return {wert:langfristig, quelle:"gesamter Verlauf", tage:Math.round(tageGesamt), km:CAR.odo-alt.km};
const aktuell = kmSeit/tageSeit;
const g = Math.min(1, tageSeit/MISCHDAUER);
return {
wert: langfristig*(1-g) + aktuell*g,
quelle: g>=1 ? "seit dem letzten Service" : "gemischt, "+Math.round(g*100)+" % aktueller Abschnitt",
tage: Math.round(tageSeit), km: kmSeit
};
}
function kmProTag(){ return tagesleistung().wert; }
function prognose(zielKm){
const rest = zielKm - CAR.odo;
if(rest <= 0) return {tage:0, datum:heute};
const tage = Math.round(rest / kmProTag());
return {tage, datum:new Date(heute.getTime() + tage*dTag)};
}
/* Kalendereintrag als ICS. iOS öffnet die Datei direkt in der Kalender-App. */
function ics(titel, datum, ort, notiz){
const tag = datum.replace(/-/g,"");
const naechster = new Date(new Date(datum).getTime()+dTag)
.toISOString().slice(0,10).replace(/-/g,"");
const text = [
"BEGIN:VCALENDAR","VERSION:2.0","PRODID:-//RS4 Dashboard//DE","BEGIN:VEVENT",
"UID:"+Date.now()+"@rs4.local",
"DTSTAMP:"+new Date().toISOString().replace(/[-:]/g,"").split(".")[0]+"Z",
"DTSTART;VALUE=DATE:"+tag, "DTEND;VALUE=DATE:"+naechster,
"SUMMARY:"+titel, "LOCATION:"+(ort||""), "DESCRIPTION:"+(notiz||""),
"BEGIN:VALARM","TRIGGER:-P2D","ACTION:DISPLAY","DESCRIPTION:"+titel,"END:VALARM",
"END:VEVENT","END:VCALENDAR"].join("\r\n");
const a=document.createElement("a");
a.href="data:text/calendar;charset=utf-8,"+encodeURIComponent(text);
a.download=titel.replace(/[^\wäöüÄÖÜß ]/g,"").replace(/\s+/g,"-")+".ics";
document.body.appendChild(a); a.click(); a.remove();
}
function ring(pct){
const r=64,c=2*Math.PI*r,on=c*pct/100;
return `<div class="ringwrap">
<svg width="150" height="150" viewBox="0 0 150 150">
<circle cx="75" cy="75" r="${r}" fill="none" stroke="var(--line)" stroke-width="2"/>
<circle cx="75" cy="75" r="${r}" fill="none" stroke="var(--red)" stroke-width="2"
stroke-linecap="round" stroke-dasharray="${on} ${c}" transform="rotate(-90 75 75)"/>
</svg>
<div class="mid">
<div class="fig" style="font-size:40px">${pct}<span class="unit">%</span></div>
<span class="label" style="margin-top:8px">${de(CONFIG.tankvolumen*pct/100,1)} Liter</span>
</div></div>`;
}
let MAP=null, TILE=null;
const TILES={
nacht:"https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
tag :"https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png"
};
const ATTR='&copy; OpenStreetMap &middot; CARTO';
function mapBox(){ return `<div class="mapbox"><div id="map"></div></div>`; }
/* Aus Start und Ziel einen plausiblen Streckenverlauf erzeugen.
Im Betrieb steht hier der tatsaechlich aufgezeichnete Track aus §4. */
function fakeTrack(a,b,n=13){
const pts=[]; let seed=Math.round((a[0]+b[1])*1000);
const rnd=()=>{ seed=(seed*1103515245+12345)&0x7fffffff; return seed/0x7fffffff-0.5; };
for(let i=0;i<=n;i++){
const t=i/n, k=Math.sin(t*Math.PI);
pts.push([ a[0]+(b[0]-a[0])*t + rnd()*0.05*k, a[1]+(b[1]-a[1])*t + rnd()*0.05*k ]);
}
pts[0]=a; pts[n]=b; return pts;
}
function tiles(){
if(!MAP) return;
const url=TILES[document.documentElement.dataset.theme];
if(TILE) MAP.removeLayer(TILE);
TILE=L.tileLayer(url,{maxZoom:19,attribution:ATTR}).addTo(MAP);
}
function initMap(){
const el=document.getElementById("map");
if(!el || typeof L==="undefined") return;
MAP=L.map(el,{zoomControl:true,attributionControl:true,scrollWheelZoom:false});
TILE=null; tiles();
const rot=getComputedStyle(document.documentElement).getPropertyValue("--red").trim()||"#F50537";
if(route.name==="trip"){
const t=TRIPS.find(x=>x.id===route.id);
const track=fakeTrack(t.a,t.b);
const line=L.polyline(track,{color:rot,weight:2.5,opacity:.9}).addTo(MAP);
/* Stützpunkte sichtbar machen — der Verlauf ist eine Naeherung, keine luekenlose Spur */
track.slice(1,-1).forEach(pt=>L.circleMarker(pt,
{radius:2.5,color:rot,weight:0,fillColor:rot,fillOpacity:.85}).addTo(MAP));
L.circleMarker(t.a,{radius:6,color:"#fff",weight:2,fillColor:"#000",fillOpacity:1}).addTo(MAP)
.bindPopup("Start · "+t.von);
L.circleMarker(t.b,{radius:6,color:rot,weight:2,fillColor:rot,fillOpacity:1}).addTo(MAP)
.bindPopup("Ziel · "+t.nach);
MAP.fitBounds(line.getBounds(),{padding:[26,26]});
} else if(route.name==="fill"){
const f=FILLS.find(x=>x.id===route.id);
MAP.setView(f.pos,14);
L.circleMarker(f.pos,{radius:7,color:rot,weight:2,fillColor:rot,fillOpacity:.85}).addTo(MAP)
.bindPopup(f.station+"<br>"+f.adresse);
}
setTimeout(()=>MAP.invalidateSize(),60);
}
/* ---------- Ansichten ---------- */
function teaser(){
const t=TRIPS[0], f=FILLS[0];
return `<div class="tile"><span class="label">Zuletzt</span>
<button class="leaf" style="padding-left:0" data-go="trip:${t.id}">
<span class="k">Letzte Fahrt<small>${t.tag} · ${esc(t.von.split(",")[0])}${esc(t.nach.split(",")[0])}</small></span>
<span class="v">${de(t.dist)} km<small>${t.dauer}</small></span>
<svg class="chev" viewBox="0 0 6 10"><polyline points="1,1 5,5 1,9"/></svg></button>
<button class="leaf" style="padding-left:0;border-bottom:0" data-go="fill:${f.id}">
<span class="k">Letzter Tankvorgang<small>${f.datum} · ${esc(f.station)}</small></span>
<span class="v">${de(f.liter,2)} l<small>${eur(f.summe)} €</small></span>
<svg class="chev" viewBox="0 0 6 10"><polyline points="1,1 5,5 1,9"/></svg></button></div>`;
}
/* Der zeitlich nächste aller Termine — nicht einfach der erste in der Liste. */
function naechsterTermin(){
return termine().slice().sort((a,b)=>a.ziel-b.ziel)[0];
}
/* Einheitliche Beschreibung eines Termins für alle Ansichten */
/* Zwei Sichtweisen auf denselben Termin: das in den Einstellungen gewählte
Intervall und die Vorgabe des Herstellers. Beide werden nebeneinander
gezeigt, keine ist verbindlich. */
function intervalle(t){
const oel=CAR.oel, b=t.basis;
if(!b) return null;
const bauen=(km, monate) => ({
km: km ? b.km + km : null,
datum: monatePlus(b.datum, monate)
});
if(t.art==="Hauptuntersuchung"){
const eig = bauen(null, 24);
return {hersteller:null, eigen:eig, prognose:eig.datum};
}
const eKm = t.art==="Ölwechsel"
? (oel.modus==="hersteller" ? oel.herstellerKm : Math.min(oel.km, oel.herstellerKm))
: 30000;
const eM = t.art==="Ölwechsel"
? (oel.modus==="hersteller" ? oel.herstellerMonate : Math.min(oel.monate, oel.herstellerMonate))
: 24;
const eig = bauen(eKm, eM);
const her = t.art==="Ölwechsel" ? bauen(oel.herstellerKm, oel.herstellerMonate) : bauen(30000, 24);
/* Voraussichtlich: wann der eigene Zielkilometerstand nach der gemessenen
Fahrleistung erreicht ist — oder das Zeitintervall, falls es früher greift. */
const perKm = prognose(eig.km).datum;
return {hersteller:her, eigen:eig, prognose: perKm < eig.datum ? perKm : eig.datum};
}
function terminText(t){
const restKm = t.km!==null ? t.km-CAR.odo : null;
const haupt = t.zuerst==="km" && restKm!==null ? "in "+de(restKm)+" km" : dedat(t.datum);
const neben = t.zuerst==="km"
? "voraussichtlich "+dedat(t.kmDatum)+" · oder "+dedat(t.datum)
: (t.km!==null ? "oder in "+de(restKm)+" km" : "aus dem Servicebuch fortgeschrieben");
return {haupt, neben, restKm};
}
function vHome(){
const g = CAR.gesichert;
return `
<div class="szene ${szeneKlasse(startIndex())}"><div class="carbox">${carImg("fest")}</div></div>
<div class="tile flat" style="margin-bottom:22px">
${badge()}
<span class="label" style="margin-top:12px">${esc(CONFIG.kennzeichen)} · ${esc(CONFIG.fahrzeuguntertitel)}</span>
<div class="status">
<span class="dot ${g?"":"bad"}"></span>
<div><div class="t">${g?"Sicher abgestellt":"Nicht sicher abgestellt"}</div>
<div class="s">${g?"Verriegelt · Türen zu · Fenster zu":"Beifahrerfenster offen"}</div></div>
</div>
</div>
<div class="tile flat" style="margin-bottom:26px">
<div class="tankzeile">
<div class="fig" style="font-size:60px">418<span class="unit">km</span></div>
<span class="pct">${CAR.tankPct} %</span>
</div>
<div class="balken"><i style="width:${CAR.tankPct}%"></i></div>
<span class="label" style="margin-top:12px">Reichweite</span>
</div>
<div class="duo">
<div class="tile"><span class="label">Kilometerstand</span>
<div class="fig" style="font-size:29px;margin-top:14px">${de(CAR.odo)}<span class="unit">km</span></div></div>
${(()=>{const t=naechsterTermin();
return `<div class="tile"><span class="label">Nächster ${esc(t.art)}</span>
<div class="zweizeiler">
<span class="fig" style="font-size:29px">${t.zuerst==="km"?de(t.km-CAR.odo):mmjj(t.datum)}<span class="unit">${t.zuerst==="km"?"km":""}</span></span>
<span class="nebenwert">${t.zuerst==="km"?mmjj(t.kmDatum):"fällig"}</span>
</div></div>`;})()}
</div>
${teaser()}`;
}
function vAudi(){
const r=CAR.reifen, a=r[r.aktiv.toLowerCase()], sv=CAR.service;
return `
<div class="szene ${szeneKlasse(bild)}" id="szene"><div class="carbox">${carImg("galerie")}</div></div>
<div class="tile flat" style="margin:14px 0 16px">
${badge()}
<span class="label" style="margin-top:12px">${esc(CONFIG.kennzeichen)}</span>
</div>
<button class="tile tilebtn" data-go="ident:x">
<span class="label">Identität</span>
<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>Fahrgestellnummer</dt><dd>${CAR.fin}</dd></div>
<div class="row"><dt>Details</dt><dd>${CAR.details}</dd></div>
<div class="row"><dt>Erstzulassung</dt><dd>${CAR.erstzulassung}</dd></div>
<div class="row"><dt>Ausführung</dt><dd>competition</dd></div>
<div class="row" style="border-bottom:0"><dt>Ausstattung</dt>
<dd>${CAR.ausstattung.reduce((n,g)=>n+g.sonder.length,0)} Positionen</dd></div>
</dl></button>
<div class="tile"><span class="label">Zustand</span><dl class="rows">
<div class="row"><dt>Kilometerstand</dt><dd>${de(CAR.odo)} km</dd></div>
<div class="row"><dt>Tankfüllung</dt><dd>${de(CONFIG.tankvolumen*CAR.tankPct/100,1)} l<small>${CAR.tankPct} % von ${CONFIG.tankvolumen} l</small></dd></div>
<div class="row"><dt>Batteriespannung</dt><dd>${de(CAR.spannung,1)} V</dd></div></dl></div>
<button class="tile tilebtn" data-go="service:x">
<span class="label">Service</span>
<svg class="go" viewBox="0 0 6 10"><polyline points="1,1 5,5 1,9"/></svg>
<dl class="rows" style="margin-top:12px">
${termine().map((t,i,arr)=>{const x=terminText(t);
return `<div class="row" ${i===arr.length-1?'style="border-bottom:0"':""}>
<dt>${t.art}</dt><dd>${x.haupt}<small>${x.neben}</small></dd></div>`;}).join("")}
</dl></button>
<button class="tile tilebtn" data-go="kosten:x">
<span class="label">Kosten</span>
<svg class="go" viewBox="0 0 6 10"><polyline points="1,1 5,5 1,9"/></svg>
${(()=>{const k=kosten(kostenJahr);
const teile=[k.kraftstoff,k.service,k.versicherung,k.steuer].filter(x=>x!==null);
const su=teile.reduce((a,b)=>a+b,0);
return `<div class="fig" style="font-size:34px;margin-top:12px">${eur(su)}<span class="unit">€</span></div>
<span class="label" style="margin-top:10px">${kostenJahr} · ${teile.length} von 4 Posten erfasst</span>`;})()}
</button>
<button class="tile tilebtn" data-go="vers:x">
<span class="label">Versicherung und Steuer</span>
<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>
</dl></button>
<button class="tile tilebtn" data-go="reifen:x">
<span class="label">Reifen · ${r.aktiv} montiert</span>
<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>${a.marke} ${a.modell}</dt><dd>${a.mass}</dd></div>
<div class="row"><dt>Laufleistung</dt><dd>${de(a.km)} km</dd></div>
<div class="row" style="border-bottom:0"><dt>Wechseltermin</dt>
<dd>${dedat(new Date(r.wechsel.datum))}<small>${r.wechsel.vereinbart?"vereinbart":"offen"}</small></dd></div>
</dl></button>`;
}
/* ---------- Service ---------- */
let svAuswahl = 0; // welcher Termin gerade bearbeitet wird
function vService(){
const sv=CAR.service;
return `
<div class="tile"><span class="label">Anstehende Termine</span>
<dl class="rows" style="margin-top:10px">
${termine().map((t,i,arr)=>{
const iv = intervalle(t);
if(!iv) return `<div class="row" ${i===arr.length-1?'style="border-bottom:0"':""}>
<dt>${t.art}</dt><dd style="color:var(--fg3)">kein Eintrag im Servicebuch</dd></div>`;
const anzeige = iv.hersteller || iv.eigen;
return `<div class="row" ${i===arr.length-1?'style="border-bottom:0"':""}>
<dt>${t.art}
${t.vereinbart ? `<br><span style="color:var(--red);font-size:11px">Werkstatt am ${dedat(new Date(t.vereinbart))}</span>` : ""}
</dt>
<dd>
${iv.hersteller ? `<span class="label" style="margin-bottom:6px">Herstellervorgabe</span>` : ""}
<span class="werte">${anzeige.km!==null?de(anzeige.km)+" km · ":""}${dedat(anzeige.datum)}</span>
<small>Voraussichtlich: ${dedat(iv.prognose)}${iv.eigen.km!==null?" / "+de(iv.eigen.km)+" km":""}</small>
</dd>
</div>`;}).join("")}
</dl>
${(()=>{const t=tagesleistung(); return `
<dl class="rows" style="margin-top:16px">
<div class="row"><dt>Fahrleistung</dt><dd>${de(t.wert,1)} km je Tag</dd></div>
<div class="row" style="border-bottom:0"><dt>Grundlage</dt><dd>${t.quelle}</dd></div>
</dl>
<span class="label" style="margin-top:14px">Nach jedem Service beginnt die Messung neu</span>`;})()}
</div>
<div class="tile"><span class="label">Termin vereinbaren</span>
${(()=>{const ts=termine(), t=ts[Math.min(svAuswahl,ts.length-1)];
const vorschlag = CAR.service.vereinbart[t.art]
|| (t.ziel ? t.ziel.toISOString().slice(0,10) : "");
return `
<div class="feld"><label for="svArt">Wofür</label>
<select id="svArt" data-svsel>${ts.map((x,i)=>
`<option value="${i}" ${i===svAuswahl?"selected":""}>${x.art}</option>`).join("")}</select></div>
<div class="feld" style="border-bottom:0"><label for="svDat">Werkstatttermin am</label>
<input id="svDat" type="date" value="${vorschlag}" data-vereinbart="${esc(t.art)}"></div>
<span class="label" style="margin-top:14px">Fälligkeit und Intervall kommen aus Servicebuch und
Einstellungen und lassen sich hier nicht überschreiben</span>
<button class="aktion" data-ics="service">In den Kalender übernehmen</button>
${CAR.service.vereinbart[t.art]?`<button class="aktion" data-loeschen="${esc(t.art)}">Termin verwerfen</button>`:""}`;})()}
</div>
<div class="tile">
<span class="label">Autohaus</span>
<button class="zahnrad" data-go="werkstatt:x" aria-label="Angaben ändern">
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/>
<path d="M19.1 14.6a1.5 1.5 0 0 0 .3 1.7l.1.1a1.8 1.8 0 1 1-2.6 2.6l-.1-.1a1.5 1.5 0 0 0-1.7-.3 1.5 1.5 0 0 0-.9 1.4v.2a1.8 1.8 0 1 1-3.6 0V20a1.5 1.5 0 0 0-1-1.4 1.5 1.5 0 0 0-1.7.3l-.1.1a1.8 1.8 0 1 1-2.6-2.6l.1-.1a1.5 1.5 0 0 0 .3-1.7 1.5 1.5 0 0 0-1.4-.9H4a1.8 1.8 0 1 1 0-3.6h.2a1.5 1.5 0 0 0 1.4-1 1.5 1.5 0 0 0-.3-1.7l-.1-.1a1.8 1.8 0 1 1 2.6-2.6l.1.1a1.5 1.5 0 0 0 1.7.3H9.8a1.5 1.5 0 0 0 .9-1.4V4a1.8 1.8 0 1 1 3.6 0v.2a1.5 1.5 0 0 0 .9 1.4 1.5 1.5 0 0 0 1.7-.3l.1-.1a1.8 1.8 0 1 1 2.6 2.6l-.1.1a1.5 1.5 0 0 0-.3 1.7v.1a1.5 1.5 0 0 0 1.4.9h.2a1.8 1.8 0 1 1 0 3.6H20a1.5 1.5 0 0 0-1.4.9z"/></svg>
</button>
<div style="font-size:15px;margin-top:12px">${esc(sv.autohaus.name)}</div>
<span class="label" style="margin-top:8px">${esc(sv.autohaus.adresse)}</span>
<a class="aktion" href="tel:${esc(sv.autohaus.tel.replace(/\s/g,""))}"
style="display:block;text-decoration:none;text-align:center;margin-top:16px">Anrufen · ${esc(sv.autohaus.tel)}</a>
<a class="aktion" target="_blank" rel="noopener"
href="https://maps.google.com/?q=${sv.autohaus.pos?sv.autohaus.pos.join(","):encodeURIComponent(sv.autohaus.adresse)}"
style="display:block;text-decoration:none;text-align:center">In Karten öffnen</a>
</div>
<div class="tile"><span class="label">Servicebuch</span>
${sv.buch.map((e,i)=>`<button class="leaf" style="padding-left:0" data-go="sbuch:${i}">
<span class="k">${esc(e.art)}<small>${esc(e.werkstatt)}</small></span>
<span class="v">${e.datum}<small>${de(e.km)} km${e.kosten!=null?" · "+eur(e.kosten)+" €":""}</small></span>
<svg class="chev" viewBox="0 0 6 10"><polyline points="1,1 5,5 1,9"/></svg></button>`).join("")}
<button class="aktion" data-sbneu>Eintrag hinzufügen</button>
</div>`;
}
/* ---------- Identität und Ausstattung ---------- */
function vIdent(){
return `
<div class="tile"><span class="label">Fahrzeug</span>
<dl class="rows" style="margin-top:10px">
<div class="row"><dt>Modell</dt><dd>${esc(CONFIG.fahrzeugtitel)}</dd></div>
<div class="row"><dt>Ausführung</dt><dd>competition</dd></div>
<div class="row"><dt>Fahrgestellnummer</dt><dd>${CAR.fin}</dd></div>
<div class="row"><dt>Motor und Leistung</dt><dd>${CAR.details}</dd></div>
<div class="row"><dt>Erstzulassung</dt><dd>${CAR.erstzulassung}</dd></div>
<div class="row"><dt>Kennzeichen</dt><dd>${esc(CONFIG.kennzeichen)}</dd></div>
<div class="row" style="border-bottom:0"><dt>Zulassung</dt><dd>Deutschland</dd></div>
</dl></div>
${CAR.technik.map(g=>`<div class="tile"><span class="label">${g.gruppe}</span>
<dl class="rows" style="margin-top:8px">
${g.posten.map((pp,i)=>`<div class="row" ${i===g.posten.length-1?'style="border-bottom:0"':""}>
<dt>${esc(pp[0])}</dt>
<dd style="${pp[1]?"":"color:var(--fg3)"}">${pp[1]?esc(pp[1]):"noch offen"}</dd></div>`).join("")}
</dl></div>`).join("")}
${CAR.ausstattung.map(g=>`<div class="tile"><span class="label">${g.gruppe}</span>
<dl class="rows" style="margin-top:8px">
${g.sonder.map((x,i)=>`<div class="row" ${i===g.sonder.length-1?'style="border-bottom:0"':""}>
<dt style="color:var(--fg)">${esc(x)}</dt><dd></dd></div>`).join("")}
</dl></div>`).join("")}
<button class="aktion">Daten bearbeiten</button>`;
}
/* Wird ein Service eingetragen, rückt der zugehörige Termin um ein Intervall
weiter — der Zähler beginnt damit an derselben Stelle neu, an der die Arbeit
tatsächlich gemacht wurde. */
/* Fälligkeiten aus dem letzten Eintrag der jeweiligen Art plus Intervall.
Kilometer und Zeit gelten parallel — fällig ist, was zuerst eintritt. */
function monatePlus(datum, monate){
const d = dat(datum); d.setMonth(d.getMonth()+monate); return d;
}
function letzterEintrag(stichwort){
return CAR.service.buch.find(e => e.art.toLowerCase().includes(stichwort)) || null;
}
function termine(){
const oel = CAR.oel;
/* Eigenes Intervall darf die Herstellervorgabe nicht überschreiten */
const oelKm = oel.modus==="hersteller" ? oel.herstellerKm : Math.min(oel.km, oel.herstellerKm);
const oelM = oel.modus==="hersteller" ? oel.herstellerMonate : Math.min(oel.monate, oel.herstellerMonate);
const bauen = (art, basis, kmIntervall, monate, ersatzDatum) => {
const kmZiel = basis && kmIntervall ? basis.km + kmIntervall : null;
const datZiel = basis ? monatePlus(basis.datum, monate)
: (ersatzDatum ? monatePlus(ersatzDatum, monate) : null);
const kmDatum = kmZiel!==null ? prognose(kmZiel).datum : null;
/* Fällig ist, was zuerst eintritt */
const zuerst = (kmDatum && datZiel) ? (kmDatum < datZiel ? "km" : "zeit")
: (kmDatum ? "km" : "zeit");
return {art, km:kmZiel, datum:datZiel, kmDatum, zuerst, basis,
ziel: zuerst==="km" ? kmDatum : datZiel,
vereinbart: CAR.service.vereinbart[art] || null};
};
return [
bauen("Ölwechsel", letzterEintrag("öl"), oelKm, oelM),
bauen("Inspektion", letzterEintrag("inspektion"), 30000, 24),
bauen("Hauptuntersuchung", letzterEintrag("hauptuntersuchung"), null, 24, "01.08.2023")
];
}
/* ---------- Werkstatt ---------- */
function vWerkstatt(){
const a=CAR.service.autohaus;
return `
<div class="tile"><span class="label">Angaben zum Autohaus</span>
<div class="feld"><label>Name</label><input value="${esc(a.name)}" data-ah="name"></div>
<div class="feld"><label>Adresse</label><input value="${esc(a.adresse)}" data-ah="adresse"></div>
<div class="feld"><label>Telefon</label><input type="tel" value="${esc(a.tel)}" data-ah="tel"></div>
<div class="feld"><label>E-Mail</label>
<input type="email" value="${esc(a.mail||"")}" data-ah="mail" placeholder="noch offen"></div>
<div class="feld" style="border-bottom:0"><label>Koordinaten</label>
<input value="${a.pos?a.pos.join(", "):""}" data-ah="pos" placeholder="Breite, Länge"></div>
<span class="label" style="margin-top:14px">Die Koordinaten steuern die Kartenschaltfläche.
Ohne sie wird die Adresse gesucht</span>
</div>`;
}
/* ---------- Servicebuch-Eintrag ---------- */
function vSbuch(){
const i=parseInt(route.id,10), e=CAR.service.buch[i];
if(!e) return `<div class="tile">Eintrag nicht gefunden</div>`;
return `
<div class="tile"><span class="label">${esc(e.art)}</span>
<div class="fig" style="font-size:40px;margin-top:12px">${de(e.km)}<span class="unit">km</span></div>
<span class="label" style="margin-top:12px">${e.datum} · ${esc(e.werkstatt)}</span>
</div>
<div class="tile"><span class="label">Eintrag</span>
<div class="feld"><label>Datum</label><input value="${esc(e.datum)}" data-sb="${i}|datum"></div>
<div class="feld"><label>Kilometerstand</label>
<span class="mitEinheit"><input type="number" value="${e.km}" data-sb="${i}|km"><span>km</span></span></div>
<div class="feld"><label>Art</label><input value="${esc(e.art)}" data-sb="${i}|art"></div>
<div class="feld"><label>Werkstatt</label><input value="${esc(e.werkstatt)}" data-sb="${i}|werkstatt"></div>
<div class="feld" style="border-bottom:0"><label>Kosten</label>
<span class="mitEinheit"><input type="number" step="0.01" value="${e.kosten ?? ""}"
data-sb="${i}|kosten" placeholder="noch offen"><span>€</span></span></div>
<span class="label" style="margin-top:14px">Kosten fließen in die Jahresübersicht ein</span>
</div>
<div class="tile"><span class="label">Durchgeführte Arbeiten</span>
<textarea class="notiz" data-sb="${i}|arbeiten" rows="7"
placeholder="Was wurde gemacht, welche Teile wurden getauscht, was ist aufgefallen">${esc(e.arbeiten||"")}</textarea>
<span class="label" style="margin-top:12px">Beim Verkauf ist diese Liste mehr wert als die Rechnung —
sie zeigt, dass gepflegt wurde</span>
</div>`;
}
/* ---------- Kosten ---------- */
const KM_JAHR = {2026:6680, 2025:6900};
let kostenJahr = 2026;
function kosten(j){
const zahl = x => { const n=parseFloat(String(x).replace(",",".")); return isNaN(n)?null:n; };
const kraftstoff = sum(FILLS.filter(f=>f.jahr===j), f=>f.summe);
const service = sum(CAR.service.buch.filter(e=>e.datum.endsWith(String(j)) && e.kosten!=null), e=>e.kosten);
return {
kraftstoff, service,
versicherung: zahl(CAR.versicherung.beitrag),
steuer: zahl(CAR.steuer.betrag),
km: KM_JAHR[j] || null
};
}
function vKosten(){
const j=kostenJahr, k=kosten(j);
const posten=[
["Kraftstoff", k.kraftstoff, "aus den erfassten Tankvorgängen"],
["Service und Wartung", k.service, "aus dem Servicebuch"],
["Versicherung", k.versicherung, "Jahresbeitrag"],
["Kfz-Steuer", k.steuer, "Jahresbetrag"]
];
const bekannt = posten.filter(p=>p[1]!==null && p[1]!==undefined);
const summe = sum(bekannt, p=>p[1]);
const fehlt = posten.length - bekannt.length;
return `
<div class="tile"><span class="label">Gesamtkosten ${j}</span>
<div class="fig" style="font-size:48px;margin-top:12px">${eur(summe)}<span class="unit">€</span></div>
${k.km?`<span class="label" style="margin-top:14px">${de(k.km)} km · ${de(summe/k.km*100,2)} € je 100 km</span>`:""}
${fehlt?`<div style="margin-top:16px;border-left:2px solid var(--warn);padding-left:14px;
font-size:12.5px;color:var(--fg2);line-height:1.55">
${fehlt===1?"Ein Posten fehlt noch":fehlt+" Posten fehlen noch"} — die Summe ist bis dahin
unvollständig und nicht als Jahresbilanz zu lesen.</div>`:""}
<div class="seg" style="margin-top:18px">
${Object.keys(KM_JAHR).sort((a,b)=>b-a).map(y=>
`<button data-kjahr="${y}" class="${+y===j?"on":""}">${y}</button>`).join("")}
</div>
</div>
<div class="tile"><span class="label">Aufteilung</span>
<dl class="rows" style="margin-top:8px">
${posten.map(([bez,wert,quelle],i)=>`<div class="row" ${i===posten.length-1?'style="border-bottom:0"':""}>
<dt>${bez}<br><span style="color:var(--fg3);font-size:11px">${quelle}</span></dt>
<dd style="${wert===null?"color:var(--fg3)":""}">${wert===null?"noch offen":eur(wert)+" €"}
${wert!==null&&summe?`<small>${de(wert/summe*100,0)} %</small>`:""}</dd></div>`).join("")}
</dl>
<div class="bar" style="margin-top:20px">
${bekannt.map(([bez,wert],i)=>`<i style="flex:${wert};background:${
["var(--red)","var(--fg)","var(--fg2)","var(--fg3)"][i]}"></i>`).join("")}
</div>
<div class="legend">${bekannt.map(([bez],i)=>`<span><i style="background:${
["var(--red)","var(--fg)","var(--fg2)","var(--fg3)"][i]}"></i>${bez}</span>`).join("")}</div>
</div>
<div class="tile"><span class="label">Je Kilometer</span>
<dl class="rows" style="margin-top:8px">
${bekannt.map(([bez,wert],i)=>`<div class="row" ${i===bekannt.length-1?'style="border-bottom:0"':""}>
<dt>${bez}</dt><dd>${k.km?de(wert/k.km*100,2)+" € / 100 km":"—"}</dd></div>`).join("")}
</dl></div>`;
}
/* ---------- Versicherung und Steuer ---------- */
function feldZeile(bez, wert, id, typ){
return `<div class="feld"><label for="${id}">${bez}</label>
<input id="${id}" type="${typ||"text"}" value="${esc(wert||"")}" placeholder="noch offen"></div>`;
}
function vVers(){
const v=CAR.versicherung;
return `
<div class="tile"><span class="label">Jahresbeitrag ab ${dedat(new Date(v.gueltigAb))}</span>
<div class="fig" style="font-size:46px;margin-top:12px">${eur(v.beitrag)}<span class="unit">€</span></div>
<span class="label" style="margin-top:14px">${v.zahlweise} · enthält ${eur(v.steueranteil)} € Versicherungsteuer (${v.steuersatz})</span>
<dl class="rows" style="margin-top:16px">
${v.teile.map((t,i)=>`<div class="row" ${i===v.teile.length-1?'style="border-bottom:0"':""}>
<dt>${esc(t.bez)}<br><span style="color:var(--fg3);font-size:11px">${t.sf} · Beitragssatz ${t.satz}</span></dt>
<dd>${eur(t.betrag)} €<small>${de(t.betrag/v.beitrag*100,0)} %</small></dd></div>`).join("")}
</dl>
<div class="bar" style="margin-top:18px">
${v.teile.map((t,i)=>`<i style="flex:${t.betrag};background:${i?"var(--fg2)":"var(--red)"}"></i>`).join("")}
</div>
</div>
<div class="tile"><span class="label">Beitrag anpassen</span>
<div class="feld" style="border-bottom:0"><label for="vBeitrag">Jahresbeitrag</label>
<span class="mitEinheit"><input id="vBeitrag" type="number" step="0.01" value="${v.beitrag}"
data-vbeitrag><span>€</span></span></div>
<span class="label" style="margin-top:14px">Bei einer Beitragsanpassung hier ändern —
die Jahreskosten rechnen sofort neu</span>
</div>
<div class="tile"><span class="label">Vertrag</span>
<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>
<div class="row"><dt>Vertragsnummer</dt><dd>${esc(v.nummer)}</dd></div>
${v.selbst.map(([b,w])=>`<div class="row"><dt>Selbstbeteiligung ${b}</dt><dd>${w}</dd></div>`).join("")}
<div class="row" style="border-bottom:0"><dt>Schadenfreiheitsklasse</dt>
<dd>${v.teile.map(t=>t.sf).join(" / ")}<small>zuvor ${v.teile.map(t=>t.sfAlt).join(" / ")}</small></dd></div>
</dl></div>
<div class="tile"><span class="label">Schaden-Notruf · rund um die Uhr</span>
<a class="aktion" href="tel:${esc(v.service.replace(/\s/g,""))}"
style="display:block;text-decoration:none;margin-top:14px;text-align:center">
Inland · ${esc(v.service)}</a>
<a class="aktion" href="tel:${esc(v.notfall.replace(/\s/g,""))}"
style="display:block;text-decoration:none;text-align:center">
Ausland · ${esc(v.notfall)}</a>
<span class="label" style="margin-top:16px">Inland kostenfrei. Beide Nummern gehören zusätzlich in
die Kontakte des iPhones — im Pannenfall ist oft kein Netz für das Dashboard da</span>
</div>
<button class="tile tilebtn" data-go="schutz:x">
<span class="label">Schutzbrief Mobilität</span>
<svg class="go" viewBox="0 0 6 10"><polyline points="1,1 5,5 1,9"/></svg>
<div style="font-size:14px;margin-top:12px">Panne, Unfall, Diebstahl, Fahrerausfall</div>
<span class="label" style="margin-top:10px">Nummern und Leistungen für den Ernstfall</span>
</button>
${v.leistungen.map(g=>`<div class="tile"><span class="label">${g.gruppe}</span>
<dl class="rows" style="margin-top:8px">
${g.posten.map((x,i)=>`<div class="row" ${i===g.posten.length-1?'style="border-bottom:0"':""}>
<dt style="color:var(--fg)">${esc(x)}</dt><dd></dd></div>`).join("")}
</dl></div>`).join("")}
${vSteuer()}`;
}
/* Für den Ernstfall gebaut: oben die Nummer, dann in einem Blick, was der
Versicherer übernimmt und wo eigene Kosten entstehen können. Keine langen
Absätze — wer an der Leitplanke steht, liest keine Fließtexte. */
function vSchutz(){
const v=CAR.versicherung, sb=v.schutzbrief;
return `
<div class="tile">
<span class="label">Zuerst anrufen</span>
<a class="aktion" href="tel:${esc(v.service.replace(/\s/g,""))}"
style="display:block;text-decoration:none;margin-top:14px;text-align:center;
border-color:var(--red);color:var(--fg)">Inland · ${esc(v.service)}</a>
<a class="aktion" href="tel:${esc(v.notfall.replace(/\s/g,""))}"
style="display:block;text-decoration:none;text-align:center">Ausland · ${esc(v.notfall)}</a>
<div style="margin-top:16px;border-left:2px solid var(--warn);padding-left:14px;
font-size:13px;color:var(--fg2);line-height:1.6">
<b style="color:var(--fg);font-weight:400">Weisung einholen ist Pflicht.</b> Vor Inanspruchnahme
einer Leistung musst du dich melden, soweit die Umstände es zulassen. Selbst beauftragte
Abschleppdienste, Hotels oder Mietwagen können sonst unbezahlt bleiben.
</div>
</div>
<div class="tile"><span class="label">Die Entscheidung am Schadenort</span>
<div style="font-size:13px;color:var(--fg2);line-height:1.6;margin-top:10px">
Diese drei Leistungen schließen einander aus. Wer eine nimmt, verliert den Anspruch auf die
anderen beiden — das ist die einzige Entscheidung, die vor Ort wirklich Geld kostet.</div>
<dl class="rows" style="margin-top:14px">
${sb.entweder.map((x,i)=>`<div class="row" ${i===sb.entweder.length-1?'style="border-bottom:0"':""}>
<dt style="color:var(--fg)">${esc(x.bez)}</dt>
<dd>${esc(x.grenze)}${x.zusatz?`<small>${esc(x.zusatz)}</small>`:""}</dd></div>`).join("")}
</dl>
<span class="label" style="margin-top:16px">Mobilität wird binnen 60 Minuten organisiert</span>
</div>
<div class="tile"><span class="label">Wann der Schutzbrief greift</span>
<dl class="rows" style="margin-top:8px">
${sb.ausloeser.map((a,i)=>`<div class="row" ${i===sb.ausloeser.length-1?'style="border-bottom:0"':""}>
<dt style="color:var(--fg)">${esc(a)}</dt><dd></dd></div>`).join("")}
</dl>
<span class="label" style="margin-top:16px">Gilt in ${esc(sb.gilt)}</span>
<span class="label" style="margin-top:8px">Versichert: ${esc(sb.versichert)}</span>
</div>
${sb.gruppen.map(g=>`<div class="tile"><span class="label">${g.titel}</span>
<dl class="rows" style="margin-top:8px">
${g.posten.map((pp,i)=>`<div class="row" ${i===g.posten.length-1?'style="border-bottom:0"':""}>
<dt style="color:var(--fg)">${esc(pp[0])}${pp[2]?`<br><span style="color:var(--fg3);font-size:11px">${esc(pp[2])}</span>`:""}</dt>
<dd>${esc(pp[1])}</dd></div>`).join("")}
</dl></div>`).join("")}
<div class="tile"><span class="label">Nicht versichert</span>
<dl class="rows" style="margin-top:8px">
${sb.nicht.map((n,i)=>`<div class="row" ${i===sb.nicht.length-1?'style="border-bottom:0"':""}>
<dt style="color:var(--fg)">${esc(n[0])}<br>
<span style="color:var(--fg3);font-size:11px">${esc(n[1])}</span></dt><dd></dd></div>`).join("")}
</dl></div>
<div class="tile"><span class="label">Deine Pflichten</span>
<dl class="rows" style="margin-top:8px">
${sb.pflichten.map((x,i)=>`<div class="row" ${i===sb.pflichten.length-1?'style="border-bottom:0"':""}>
<dt style="color:var(--fg)">${esc(x)}</dt><dd></dd></div>`).join("")}
</dl>
<div style="margin-top:16px;font-size:12.5px;color:var(--fg2);line-height:1.6">${esc(sb.rang)}</div>
<span class="label" style="margin-top:14px">${esc(sb.stand)}</span>
</div>`;
}
function vSteuer(){
const t=CAR.steuer;
return `
<div class="tile" style="margin-top:26px"><span class="label">Kfz-Steuer</span>
<div class="feld"><label for="stBetrag">Betrag</label>
<span class="mitEinheit"><input id="stBetrag" type="number" step="1" value="${t.betrag}"
data-steuer><span>€</span></span></div>
<div class="feld"><label for="stZeit">Zeitraum</label>
<select id="stZeit"><option>jährlich</option><option>halbjährlich</option></select></div>
<div class="feld"><label for="stFaellig">Nächste Fälligkeit</label>
<input id="stFaellig" type="date" value="${t.faellig}"></div>
<div class="feld" style="border-bottom:0"><label for="stLast">Lastschrift erteilt</label>
<input id="stLast" type="checkbox" ${t.lastschrift?"checked":""}></div>
</div>
`;
}
/* ---------- Einstellungen ---------- */
let beschriftung = true;
let bodenAn = true;
function csvDatei(name, kopf, zeilen){
const txt = [kopf.join(";")].concat(zeilen.map(r=>r.join(";"))).join("\r\n");
const a=document.createElement("a");
a.href="data:text/csv;charset=utf-8,"+encodeURIComponent("\ufeff"+txt);
a.download=name; document.body.appendChild(a); a.click(); a.remove();
}
function vEinst(){
return `
<div class="tile"><span class="label">Darstellung</span>
<div class="seg">
<button data-mode="nacht" class="${document.documentElement.dataset.theme==="nacht"?"on":""}">Nacht</button>
<button data-mode="tag" class="${document.documentElement.dataset.theme==="tag"?"on":""}">Tag</button>
</div>
<div class="feld" style="margin-top:16px;border-bottom:0">
<label for="schrift">Beschriftung in der Menüleiste</label>
<input id="schrift" type="checkbox" data-schrift ${beschriftung?"checked":""}></div>
<span class="label" style="margin-top:14px">Aus zeigt nur die Symbole und gibt etwas Höhe frei</span>
<div class="feld" style="margin-top:16px;border-bottom:0">
<label for="boden">Fahrbahn unter dem Fahrzeug</label>
<input id="boden" type="checkbox" data-boden ${bodenAn?"checked":""}></div>
<span class="label" style="margin-top:14px">Angedeutete Fahrbahn mit Schatten, nur bei Außenansichten</span>
</div>
<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>
<img class="carfix" style="margin-top:16px" src="${BILDER[startIndex()].src}" alt="">
</div>
<div class="tile"><span class="label">Kraftstoff-Rabatt</span>
<div class="feld"><label for="sdAktiv">Shell SmartDeal nutzen</label>
<input id="sdAktiv" type="checkbox" data-sd ${CAR.smartdeal.aktiv?"checked":""}></div>
<div class="feld" style="border-bottom:0"><label for="sdBis">Läuft ab am</label>
<input id="sdBis" type="date" value="${CAR.smartdeal.laeuftAb}" ${CAR.smartdeal.aktiv?"":"disabled"}></div>
${CAR.smartdeal.aktiv?`<span class="label" style="margin-top:14px">Nach diesem Datum wird der Rabatt
nicht mehr erwartet — bleibt er auf dem Beleg aus, ist das dann kein Fehler</span>`:
`<span class="label" style="margin-top:14px">Ersparnis und Bildmarke werden ausgeblendet</span>`}
</div>
<div class="tile"><span class="label">Fahrten zusammenfassen</span>
<div class="feld" style="border-bottom:0"><label for="pause">Pause bis</label>
<span class="mitEinheit"><input id="pause" type="number" step="5" min="0"
value="${CONFIG.pauseMin}" data-pause><span>Minuten</span></span></div>
<span class="label" style="margin-top:14px">Steigst du kürzer als diese Zeit aus — etwa zum Tanken —,
bleibt es eine zusammenhängende Fahrt statt zweier</span>
</div>
<div class="tile"><span class="label">Ölwechsel-Intervall</span>
<div class="seg">
<button data-oel="hersteller" class="${CAR.oel.modus==="hersteller"?"on":""}">Herstellervorgabe</button>
<button data-oel="eigen" class="${CAR.oel.modus==="eigen"?"on":""}">Eigenes</button>
</div>
${CAR.oel.modus==="hersteller"
? `<dl class="rows" style="margin-top:16px">
<div class="row"><dt>Laufleistung</dt><dd>${de(CAR.oel.herstellerKm)} km</dd></div>
<div class="row" style="border-bottom:0"><dt>Zeit</dt><dd>${CAR.oel.herstellerMonate} Monate</dd></div>
</dl>
<span class="label" style="margin-top:14px">Aus dem Fahrzeug gelesen</span>`
: `<div class="feld" style="margin-top:6px"><label for="oelKm">Nach Laufleistung</label>
<select id="oelKm" data-oelkm>${[5000,10000,15000,20000].map(k=>
`<option value="${k}" ${k===CAR.oel.km?"selected":""}>${de(k)} km</option>`).join("")}</select></div>
<div class="feld" style="border-bottom:0"><label for="oelM">Nach Zeit</label>
<select id="oelM" data-oelm>${[12,24].map(m=>
`<option value="${m}" ${m===CAR.oel.monate?"selected":""}>${m===12?"1 Jahr":"2 Jahre"}</option>`).join("")}</select></div>
<span class="label" style="margin-top:14px">Fällig wird, was zuerst eintritt</span>`}
</div>
<div class="tile"><span class="label">Fahrzeugprofil</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">
Alles Fahrzeugspezifische liegt in einer einzigen Datei: Stammdaten, technische Daten,
Ausstattung, Reifen, Versicherung, Steuer und Werkstatt. Für ein anderes Fahrzeug wird nur
diese Datei getauscht — die App selbst bleibt unverändert.</span>
<button class="aktion" data-profil="export">Profil sichern</button>
<label class="aktion" style="display:block;text-align:center;cursor:pointer">
Profil laden<input type="file" accept="application/json" data-profil="import" hidden></label>
<dl class="rows" style="margin-top:16px">
<div class="row"><dt>Datei</dt><dd>fahrzeug.json</dd></div>
<div class="row" style="border-bottom:0"><dt>Bearbeitbar mit</dt>
<dd>jedem Texteditor<small>auch im Datei-Editor von Home Assistant</small></dd></div>
</dl>
</div>
<div class="tile"><span class="label">Daten ausgeben</span>
<span class="label" style="margin-top:10px;color:var(--fg2);letter-spacing:0;text-transform:none;font-size:12.5px">
Semikolon als Trennzeichen und deutsches Zahlenformat, damit die Dateien ohne Umweg in
Tabellenprogrammen aufgehen.</span>
<button class="aktion" data-csv="fahrten">Fahrten als CSV</button>
<button class="aktion" data-csv="tanken">Tankvorgänge als CSV</button>
<button class="aktion" data-csv="service">Servicebuch als CSV</button>
</div>
<div class="tile"><span class="label">Sicherung</span>
<dl class="rows">
<div class="row"><dt>Letzte Sicherung</dt><dd>03.08.2026<small>04:00 Uhr · 2,4 MB</small></dd></div>
<div class="row" style="border-bottom:0"><dt>Umfang</dt>
<dd>Fahrten, Tankvorgänge<small>Servicebuch, Stammdaten, Belege</small></dd></div>
</dl>
<div class="feld" style="margin-top:6px"><label for="bkAuto">Automatisch sichern</label>
<input id="bkAuto" type="checkbox" checked></div>
<div class="feld" style="border-bottom:0"><label for="bkInt">Rhythmus</label>
<select id="bkInt">
<option>täglich</option><option selected>wöchentlich</option><option>monatlich</option>
</select></div>
<button class="aktion">Jetzt sichern</button>
</div>
<div class="tile"><span class="label">Version</span>
<dl class="rows">
<div class="row"><dt>Dashboard</dt><dd>${CONFIG.version}</dd></div>
<div class="row"><dt>Fahrzeugdaten</dt><dd>EU Data Act<small>Abruf alle 15 Minuten</small></dd></div>
<div class="row"><dt>Letzter Abruf</dt><dd>${CAR.standAlter}</dd></div>
<div class="row" style="border-bottom:0"><dt>Position</dt><dd>iPhone<small>Companion App</small></dd></div>
</dl></div>`;
}
/* ---------- Reifen ---------- */
function vReifen(){
const r=CAR.reifen;
/* Jedes Feld schreibt beim Verlassen direkt in den Datensatz zurück.
Die Laufleistung ist ebenfalls änderbar — beim Wechsel auf einen bereits
gefahrenen Satz muss der Startwert von Hand gesetzt werden können. */
const feld = (k, schluessel, bez, typ) => {
const t = r[k];
return `<div class="feld"><label>${bez}</label>
<input type="${typ||"text"}" value="${esc(t[schluessel] ?? "")}"
data-rf="${k}|${schluessel}" placeholder="noch offen"></div>`;
};
const satz = k => {
const t=r[k], aktiv = r.aktiv.toLowerCase()===k;
return `<div class="tile">
${t.bild ? `<img class="radbild" src="${esc(t.bild)}" alt="${esc(t.marke)} ${esc(t.modell)}">`
: `<div class="radph"></div>`}
<div class="radkopf">
<span class="label">${k==="sommer"?"Sommer":"Winter"}${aktiv?" · montiert":""}</span>
<div class="fig" style="font-size:32px;margin-top:14px">${de(t.km)}<span class="unit">km</span></div>
</div>
<div style="margin-top:22px">
${feld(k,"marke","Hersteller")}
${feld(k,"modell","Modell")}
${feld(k,"mass","Größe")}
${feld(k,"dot","DOT")}
${feld(k,"druck","Solldruck")}
${feld(k,"km","Laufleistung in km","number")}
${feld(k,"kauf","Gekauft")}
${feld(k,"kommentar","Kommentar")}
</div>
<span class="label" style="margin-top:16px">Änderungen wirken sofort</span>
</div>`;
};
return `
<div class="tile"><span class="label">Montiert</span>
<div class="seg">
<button data-satz="Sommer" class="${r.aktiv==="Sommer"?"on":""}">Sommer</button>
<button data-satz="Winter" class="${r.aktiv==="Winter"?"on":""}">Winter</button>
</div>
<span class="label" style="margin-top:14px">Das Umschalten leitet die gefahrenen Kilometer auf den gewählten Satz um</span>
</div>
<div class="tile"><span class="label">Beim Wechsel</span>
<button class="zahnrad" data-nmauf aria-label="Anzugsmoment ändern">
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/>
<path d="M19.1 14.6a1.5 1.5 0 0 0 .3 1.7l.1.1a1.8 1.8 0 1 1-2.6 2.6l-.1-.1a1.5 1.5 0 0 0-1.7-.3 1.5 1.5 0 0 0-.9 1.4v.2a1.8 1.8 0 1 1-3.6 0V20a1.5 1.5 0 0 0-1-1.4 1.5 1.5 0 0 0-1.7.3l-.1.1a1.8 1.8 0 1 1-2.6-2.6l.1-.1a1.5 1.5 0 0 0 .3-1.7 1.5 1.5 0 0 0-1.4-.9H4a1.8 1.8 0 1 1 0-3.6h.2a1.5 1.5 0 0 0 1.4-1 1.5 1.5 0 0 0-.3-1.7l-.1-.1a1.8 1.8 0 1 1 2.6-2.6l.1.1a1.5 1.5 0 0 0 1.7.3H9.8a1.5 1.5 0 0 0 .9-1.4V4a1.8 1.8 0 1 1 3.6 0v.2a1.5 1.5 0 0 0 .9 1.4 1.5 1.5 0 0 0 1.7-.3l.1-.1a1.8 1.8 0 1 1 2.6 2.6l-.1.1a1.5 1.5 0 0 0-.3 1.7v.1a1.5 1.5 0 0 0 1.4.9h.2a1.8 1.8 0 1 1 0 3.6H20a1.5 1.5 0 0 0-1.4.9z"/></svg>
</button>
<div class="fig" style="font-size:34px;margin-top:12px">${de(r.anzugsmoment)}<span class="unit">Nm</span></div>
<span class="label" style="margin-top:10px">Anzugsmoment der Radschrauben</span>
${nmOffen?`
<div style="margin-top:18px;border-top:1px solid var(--line);padding-top:16px">
<div class="feld" style="border-bottom:0"><label for="nm">Neuer Wert</label>
<span class="mitEinheit"><input id="nm" type="number" step="5" min="0"
value="${r.anzugsmoment}"><span>Nm</span></span></div>
<button class="aktion" data-nmspeichern>Speichern</button>
<button class="aktion" data-nmauf>Abbrechen</button>
</div>`:""}
</div>
<div class="tile"><span class="label">Wechseltermin</span>
<div class="feld"><label for="rfDat">Geplant am</label>
<input id="rfDat" type="date" value="${r.wechsel.datum}"></div>
<div class="feld" style="border-bottom:0"><label for="rfOk">Termin vereinbart</label>
<input id="rfOk" type="checkbox" ${r.wechsel.vereinbart?"checked":""}></div>
<button class="aktion" data-ics="reifen">In den Kalender übernehmen</button>
</div>
${satz("sommer")}
${satz("winter")}`;
}
function vTrips(){
const jahre=[...new Set(TRIPS.map(t=>t.jahr))].sort((a,b)=>b-a);
let h=`<div class="tile">`;
jahre.forEach((j,ji)=>{
const tj=TRIPS.filter(t=>t.jahr===j);
h+=`<button class="acc-h" aria-expanded="${ji===0}" data-acc="y${j}"><span class="mark"></span>
<span class="k">${j}</span><span class="v">${de(sum(tj,t=>t.dist))} km<br>${tj.length} Fahrten</span></button>
<div class="acc-b ${ji===0?"on":""}" id="y${j}">`;
[...new Set(tj.map(t=>t.monat))].forEach((m,mi)=>{
const tm=tj.filter(t=>t.monat===m);
h+=`<div class="lvl2"><button class="acc-h" aria-expanded="${mi===0}" data-acc="m${j}${m}">
<span class="mark"></span><span class="k">${m}</span>
<span class="v">${de(sum(tm,t=>t.dist))} km</span></button>
<div class="acc-b ${mi===0?"on":""}" id="m${j}${m}">`;
tm.forEach(t=>{ h+=`<button class="leaf" data-go="trip:${t.id}">
<span class="k">${t.tag} ${esc(t.von.split(",")[0])}${esc(t.nach.split(",")[0])}
<small>${t.art} · ${t.dauer}${t.nacht?" · Nacht":""}</small></span>
<span class="v">${de(t.dist)} km<small>${eur(t.kosten)} €</small></span>
<svg class="chev" viewBox="0 0 6 10"><polyline points="1,1 5,5 1,9"/></svg></button>`; });
h+=`</div></div>`;
});
h+=`</div>`;
});
return h + `</div>
${fahrtOffen?`<div class="tile"><span class="label">Neue Fahrt</span>
<div class="feld"><label>Datum</label><input type="date" value="2026-08-03"></div>
<div class="feld"><label>Startzeit</label><input type="time" value="08:00"></div>
<div class="feld"><label>Dauer in Minuten</label><input type="number" placeholder="0"></div>
<div class="feld"><label>Startort</label><input placeholder="Ort oder Adresse"></div>
<div class="feld"><label>Zielort</label><input placeholder="Ort oder Adresse"></div>
<div class="feld"><label>Kilometerstand Start</label><input type="number" value="${CAR.odo}"></div>
<div class="feld"><label>Kilometerstand Ende</label><input type="number" placeholder="${CAR.odo}"></div>
<div class="feld" style="border-bottom:0"><label>Art der Fahrt</label>
<select><option>Privat</option><option>Arbeitsweg</option></select></div>
<button class="aktion">Speichern</button></div>`:""}
<button class="aktion" data-fahrt>${fahrtOffen?"Abbrechen":"Fahrt erfassen"}</button>`;
}
function vTrip(id){
const t=TRIPS.find(x=>x.id===id);
return `
${mapBox()}
<div class="tile flat" style="margin:18px 0 14px">
<span class="label">Distanz</span>
<div class="fig" style="font-size:52px;margin-top:10px">${de(t.dist)}<span class="unit">km</span></div>
<div style="margin-top:15px">
<button class="pill ${t.art==="Arbeitsweg"?"work":""}" data-art="${t.id}"
style="cursor:pointer;font-family:inherit">${t.art}</button>
${t.nacht?'<span class="pill" style="margin-left:8px">Nachtfahrt</span>':""}</div>
<span class="label" style="margin-top:12px">Vorbelegung privat · tippen zum Umschalten</span>
</div>
<div class="tile"><dl class="rows">
<div class="row"><dt>Startort</dt><dd>${esc(t.von)}<small>${t.tag} ${t.zeit} Uhr</small></dd></div>
<div class="row"><dt>Zielort</dt><dd>${esc(t.nach)}</dd></div>
<div class="row"><dt>Startkilometer</dt><dd>${de(t.kmA)} km</dd></div>
<div class="row"><dt>Endkilometer</dt><dd>${de(t.kmE)} km</dd></div>
<div class="row"><dt>Dauer</dt><dd>${t.dauer}</dd></div>
<div class="row"><dt>Ø Geschwindigkeit</dt><dd>${de(t.schnitt)} km/h</dd></div>
<div class="row"><dt>Kraftstoffkosten</dt><dd>${eur(t.kosten)} €<small>${de(t.kosten/t.dist*100,2)} € je 100 km</small></dd></div>
</dl></div>`;
}
function quad(t,v){return `<span class="label" style="margin-top:20px">${t}</span>
<div class="quad">${v.map(x=>`<div><div class="n">${x[0]}</div><div class="l">${x[1]}</div></div>`).join("")}</div>`;}
function statTile(id,label,fig,unit,extra,body){
return `<div class="tile"><button class="tile-h" aria-expanded="false" data-acc="${id}">
<span class="label">${label}</span>
<div style="display:flex;align-items:flex-end;justify-content:space-between;gap:14px;margin-top:12px">
<div class="fig" style="font-size:34px">${fig}<span class="unit">${unit}</span></div>
<span class="label" style="padding-bottom:5px">${extra}</span></div>
</button><div class="tile-b" id="${id}">${body}</div></div>`;
}
/* Beispielzahlen, abgeleitet aus der tatsächlichen Fahrleistung von
18,3 km je Tag. Formatierung durchgehend über de(), damit überall
derselbe Tausenderpunkt steht. */
const ST = {
kmJahr:6680, kmMonat:557, kmWoche:128, kmTag:18,
hJahr:121, hMonat:10, hWoche:2.3, hTag:0.3,
lJahr:534, lMonat:45, lWoche:10, lTag:0,
eJahr:1127, eMonat:94, eWoche:21, eTag:0,
tagKm:5210, nachtKm:1470, arbeitKm:4275, privatKm:2405,
fahrtenArbeit:96, fahrtenPrivat:44
};
function vStat(){
return `
${statTile("s1","Distanz und Fahrzeit 2026",de(ST.kmJahr),"km",de(ST.hJahr)+" h",
quad("Gefahrene Distanz",[[de(ST.kmJahr),"Jahr"],[de(ST.kmMonat),"Monat"],
[de(ST.kmWoche),"Woche"],[de(ST.kmTag),"Tag"]])+
quad("Fahrzeit",[[de(ST.hJahr),"Jahr h"],[de(ST.hMonat),"Monat h"],
[de(ST.hWoche,1),"Woche h"],[de(ST.hTag,1),"Tag h"]]))}
${statTile("s2","Getankte Menge und Kosten 2026",de(ST.lJahr),"l",de(ST.eJahr)+" €",
quad("Getankte Liter",[[de(ST.lJahr),"Jahr"],[de(ST.lMonat),"Monat"],
[de(ST.lWoche),"Woche"],[de(ST.lTag),"Tag"]])+
quad("Kraftstoffkosten",[[de(ST.eJahr),"Jahr €"],[de(ST.eMonat),"Monat €"],
[de(ST.eWoche),"Woche €"],[eur(0),"Tag €"]]))}
${statTile("s3","Durchschnittsverbrauch","8,0","l/100 km","2026",
quad("Je Zeitraum",[["8,0","Jahr"],["7,6","Monat"],["7,4","Woche"],["","Tag"]]))}
${statTile("s4","Tag und Nacht","78","% bei Tag",de(ST.tagKm)+" km",
`<div class="bar"><i style="flex:78;background:var(--fg)"></i><i style="flex:22;background:var(--fg3)"></i></div>
<div class="legend"><span><i style="background:var(--fg)"></i>Tag · ${de(ST.tagKm)} km</span>
<span><i style="background:var(--fg3)"></i>Nacht · ${de(ST.nachtKm)} km</span></div>
<span class="label" style="margin-top:16px">Nacht = ${CONFIG.nachtVon} bis ${CONFIG.nachtBis} Uhr</span>`)}
${statTile("s5","Art der Fahrten","64","% Arbeitsweg",de(ST.arbeitKm)+" km",
`<div class="bar"><i style="flex:64;background:var(--red)"></i><i style="flex:36;background:var(--fg3)"></i></div>
<div class="legend"><span><i style="background:var(--red)"></i>Arbeitsweg · ${de(ST.arbeitKm)} km</span>
<span><i style="background:var(--fg3)"></i>Privat · ${de(ST.privatKm)} km</span></div>
<dl class="rows" style="margin-top:18px">
<div class="row"><dt>Fahrten Arbeitsweg</dt><dd>${de(ST.fahrtenArbeit)}</dd></div>
<div class="row" style="border-bottom:0"><dt>Fahrten privat</dt><dd>${de(ST.fahrtenPrivat)}</dd></div></dl>`)}`;
}
let neuOffen = false;
let nmOffen = false;
let fahrtOffen = false;
function vFuel(){
const jahre=[...new Set(FILLS.map(f=>f.jahr))].sort((a,b)=>b-a);
let h=`<div class="tile">`;
jahre.forEach((j,ji)=>{
const fj=FILLS.filter(f=>f.jahr===j);
h+=`<button class="acc-h" aria-expanded="${ji===0}" data-acc="fy${j}"><span class="mark"></span>
<span class="k">${j}</span><span class="v">Ø ${de(schnittpreis(fj),3)} €/l<br>${de(sum(fj,f=>f.seit))} km · ${eur(sum(fj,f=>f.summe))} €<br>
<span class="marke" style="justify-content:flex-end">${markenlogo()} ${eur(sum(fj,f=>f.rabatt))} €</span></span></button>
<div class="acc-b ${ji===0?"on":""}" id="fy${j}">`;
[...new Set(fj.map(f=>f.monat))].forEach((m,mi)=>{
const fm=fj.filter(f=>f.monat===m);
h+=`<div class="lvl2"><button class="acc-h" aria-expanded="${mi===0}" data-acc="fm${j}${m}">
<span class="mark"></span><span class="k">${m}</span>
<span class="v">Ø ${de(schnittpreis(fm),3)} €/l<br>${de(sum(fm,f=>f.seit))} km · ${eur(sum(fm,f=>f.summe))} €</span></button>
<div class="acc-b ${mi===0?"on":""}" id="fm${j}${m}">`;
fm.forEach(f=>{ h+=`<button class="leaf" data-go="fill:${f.id}">
<span class="k">${f.datum}<small>${esc(f.station)}</small></span>
<span class="v">${de(f.liter,2)} l<small>${de(f.summe/f.liter,3)} €/l · ${eur(f.summe)} €</small></span>
<svg class="chev" viewBox="0 0 6 10"><polyline points="1,1 5,5 1,9"/></svg></button>`; });
h+=`</div></div>`;
});
h+=`</div>`;
});
return h + `</div>
${neuOffen?`<div class="tile"><span class="label">Neuer Tankvorgang</span>
<div class="feld"><label>Datum</label><input type="date" value="2026-08-03"></div>
<div class="feld"><label>Uhrzeit</label><input type="time" value="16:05"></div>
<div class="feld"><label>Kraftstoff</label>
<select>${["V-Power Racing","Super Plus","Super (95)"].map(k=>`<option>${k}</option>`).join("")}</select></div>
<div class="feld"><label>Getankte Liter</label><input type="number" step="0.01" placeholder="0,00"></div>
<div class="feld"><label>Kosten in Euro</label><input type="number" step="0.01" placeholder="0,00"></div>
<div class="feld"><label>Kilometerstand</label><input type="number" value="${CAR.odo}"></div>
<div class="feld" style="border-bottom:0"><label>Tankstelle</label><input placeholder="Name und Ort"></div>
<button class="aktion" data-beleg>Beleg hochladen und auswerten</button>
<button class="aktion">Speichern</button></div>`:""}
<button class="aktion" data-neu>${neuOffen?"Abbrechen":"Tankvorgang erfassen"}</button>`;
}
/* Volltankung wird nicht abgefragt, sondern aus dem Füllstand nach dem Tanken
abgeleitet. Ab 97 Prozent gilt die Füllung als voll — darunter liegt die
Auflösung der Fahrzeugmeldung. */
function istVoll(f){ return f.pctNach >= 97; }
function vFill(id){
const f=FILLS.find(x=>x.id===id);
const voll=istVoll(f);
const preis=f.summe/f.liter, listenpreis=(f.summe+f.rabatt)/f.liter;
return `
${mapBox()}
<div class="tile flat" style="margin:18px 0 14px">
<span class="label">Getankt</span>
<div class="fig" style="font-size:52px;margin-top:10px">${de(f.liter,2)}<span class="unit">l</span></div>
</div>
<div class="tile"><dl class="rows">
<div class="row"><dt>Zeitpunkt</dt><dd>${f.datum}<small>${f.zeit} Uhr</small></dd></div>
<div class="row"><dt>Kilometerstand</dt><dd>${de(f.odo)} km</dd></div>
<div class="row"><dt>Gefahrene Distanz</dt><dd>${de(f.seit)} km<small>seit der letzten Füllung</small></dd></div>
<div class="row"><dt>Getankte Liter</dt><dd>${de(f.liter,2)} l</dd></div>
<div class="row"><dt>Kosten</dt><dd>${eur(f.summe)} €</dd></div>
<div class="row"><dt>Preis je Liter</dt><dd>${de(preis,3)} €</dd></div>
<div class="row"><dt><span class="marke">${markenlogo()} SmartDeal</span></dt><dd> ${eur(f.rabatt)} €<small>Listenpreis ${de(listenpreis,3)} €/l</small></dd></div>
<div class="row"><dt>Volltankung</dt>
<dd>${voll?"ja":"nein"}<small>Füllstand danach ${f.pctNach} %, davor ${f.pctVor} %</small></dd></div>
<div class="row"><dt>Verbrauch</dt>
<dd>${voll?de(f.liter/f.seit*100,1)+" l/100 km":"—"}<small>${voll?"zwischen zwei Volltankungen":"nur bei Volltankung belastbar"}</small></dd></div>
<div class="row"><dt>Tankstelle</dt><dd>${esc(f.station)}<small>${esc(f.adresse)}</small></dd></div>
<div class="row" style="border-bottom:0"><dt>Beleg</dt>
<dd>${f.beleg?"hinterlegt":"fehlt"}<small>${f.beleg?"Werte aus dem Beleg übernommen":"Kosten bisher geschätzt"}</small></dd></div>
</dl>
<button class="aktion" data-beleg>${f.beleg?"Beleg ersetzen":"Beleg hochladen und auswerten"}</button>
</div>`;
}
/* ---------- Steuerung ---------- */
/* Bleibt die Ansicht dieselbe und wird nur neu aufgebaut — etwa weil ein
Schalter umgelegt wurde —, behält die Seite ihre Scrollposition. Nur beim
echten Wechsel der Ansicht wird nach oben gesprungen. */
let letzteAnsicht = null;
function render(){
const v=$("#view"), b=$("#back");
const merkeScroll = v.scrollTop;
const gleicheAnsicht = letzteAnsicht === route.name + "|" + (route.id || "");
let head;
if(route.name==="home"){ head=["Fahrzeug","Übersicht"]; v.innerHTML=vHome(); }
else if(route.name==="trip"){ head=["Fahrt","Einzelfahrt"]; v.innerHTML=vTrip(route.id); }
else if(route.name==="fill"){ head=["Tankvorgang","Einzelbeleg"]; v.innerHTML=vFill(route.id); }
else if(route.name==="service"){ head=["Wartung","Service"]; v.innerHTML=vService(); }
else if(route.name==="reifen"){ head=["Fahrzeug","Reifen"]; v.innerHTML=vReifen(); }
else if(route.name==="einst"){ head=["App","Einstellungen"]; v.innerHTML=vEinst(); }
else if(route.name==="ident"){ head=["Fahrzeug","Identität und Technik"]; v.innerHTML=vIdent(); }
else if(route.name==="vers"){ head=["Fahrzeug","Versicherung und Steuer"]; v.innerHTML=vVers(); }
else if(route.name==="kosten"){ head=["Fahrzeug","Kosten"]; v.innerHTML=vKosten(); }
else if(route.name==="schutz"){ head=["Im Ernstfall","Schutzbrief"]; v.innerHTML=vSchutz(); }
else if(route.name==="werkstatt"){ head=["Service","Autohaus"]; v.innerHTML=vWerkstatt(); }
else if(route.name==="sbuch"){ head=["Servicebuch","Eintrag"]; v.innerHTML=vSbuch(); }
else { const t=TABS.find(x=>x.id===route.name); head=[t.eyebrow,t.title];
v.innerHTML={audi:vAudi,trips:vTrips,stat:vStat,fuel:vFuel}[route.name](); }
$("#eyebrow").textContent=head[0]; $("#title").textContent=head[1];
const sy=$("#sync");
sy.style.display = route.name==="home" ? "flex" : "none";
sy.querySelector("span").textContent = "Aktualisiert " + CAR.standAlter;
b.classList.toggle("on", !!ZURUECK[route.name]);
v.scrollTop = gleicheAnsicht ? merkeScroll : 0;
letzteAnsicht = route.name + "|" + (route.id || "");
if(MAP){ MAP.remove(); MAP=null; TILE=null; }
if(route.name==="trip"||route.name==="fill") initMap();
document.querySelectorAll(".tab").forEach(el=>el.classList.toggle("on",el.dataset.tab===route.name));
}
const go=(name,id)=>{route={name,id};render();};
$("#tabbar").innerHTML = TABS.map(t=>
`<button class="tab" data-tab="${t.id}">
<svg viewBox="0 0 24 24" aria-hidden="true">${ICONS[t.id]}</svg><span>${t.label}</span>
</button>`).join("");
$("#tabbar").addEventListener("click",e=>{const b=e.target.closest(".tab"); if(b) go(b.dataset.tab);});
$("#back").addEventListener("click",()=>go(ZURUECK[route.name]||"home"));
const ICON = {
sonne:'<circle cx="10" cy="10" r="4"/><path d="M10 1v2M10 17v2M1 10h2M17 10h2M3.9 3.9l1.4 1.4M14.7 14.7l1.4 1.4M16.1 3.9l-1.4 1.4M5.3 14.7l-1.4 1.4"/>',
mond :'<path d="M16.5 12.4A7 7 0 1 1 7.6 3.5a5.6 5.6 0 0 0 8.9 8.9z"/>'
};
function themeIcon(){ $("#themeicon").innerHTML = document.documentElement.dataset.theme==="nacht" ? ICON.sonne : ICON.mond; }
$("#ringsbtn").addEventListener("click",()=>go("einst"));
$("#theme").addEventListener("click",()=>{
const el=document.documentElement;
el.dataset.theme = el.dataset.theme==="nacht" ? "tag" : "nacht";
themeIcon(); tiles();
});
document.addEventListener("change",e=>{
if(e.target.dataset.profil==="import"){
const datei=e.target.files[0];
if(!datei) return;
const leser=new FileReader();
leser.onload=()=>{
try{
const p=JSON.parse(leser.result);
if(p.config) Object.assign(CONFIG,p.config);
if(p.fahrzeug) Object.assign(CAR,p.fahrzeug);
bild=0; render();
}catch(err){ alert("Die Datei ließ sich nicht lesen: "+err.message); }
};
leser.readAsText(datei);
return;
}
const vb=e.target.dataset.vereinbart;
if(vb){ CAR.service.vereinbart[vb]=e.target.value; render(); return; }
const ah=e.target.dataset.ah;
if(ah){
CAR.service.autohaus[ah] = ah==="pos"
? (e.target.value.split(",").map(x=>parseFloat(x.trim())).filter(x=>!isNaN(x)).slice(0,2) || null)
: e.target.value;
render(); return;
}
const sb=e.target.dataset.sb;
if(sb){
const [i,feld]=sb.split("|");
const eintrag=CAR.service.buch[+i];
eintrag[feld] = (feld==="km") ? (parseInt(e.target.value,10)||0)
: (feld==="kosten") ? (e.target.value===""?null:parseFloat(e.target.value))
: e.target.value;
render(); return;
}
const rf=e.target.dataset.rf;
if(rf){
const [k,schluessel]=rf.split("|");
const wert=e.target.value;
CAR.reifen[k][schluessel] = (schluessel==="km") ? (parseInt(wert,10)||0) : wert;
render();
return;
}
if(e.target.dataset.schrift!==undefined){
beschriftung = e.target.checked;
$("#tabbar").classList.toggle("ohne", !beschriftung);
return; }
if(e.target.dataset.steuer!==undefined){ CAR.steuer.betrag=parseFloat(e.target.value)||0; render(); return; }
if(e.target.dataset.vbeitrag!==undefined){ CAR.versicherung.beitrag=parseFloat(e.target.value)||0; render(); return; }
if(e.target.dataset.pause!==undefined){ CONFIG.pauseMin=parseInt(e.target.value,10)||0; return; }
if(e.target.dataset.sd!==undefined){ CAR.smartdeal.aktiv=e.target.checked; render(); return; }
if(e.target.dataset.oelkm!==undefined){ CAR.oel.km=parseInt(e.target.value,10); return; }
if(e.target.dataset.oelm!==undefined){ CAR.oel.monate=parseInt(e.target.value,10); return; }
if(e.target.dataset.boden!==undefined){ bodenAn=e.target.checked; render(); return; }
if(e.target.dataset.startbild!==undefined){ CONFIG.startbild=e.target.value; render(); return; }
if(e.target.dataset.svsel!==undefined){ svAuswahl=parseInt(e.target.value,10); render(); return; }
});
document.addEventListener("click",e=>{
if(e.target.id==="carimg"){ bildWeiter(); return; }
if(e.target.closest("[data-nmauf]")){ nmOffen=!nmOffen; render(); return; }
if(e.target.closest("[data-nmspeichern]")){
const wert=parseInt($("#nm").value,10);
if(!isNaN(wert) && wert>0) CAR.reifen.anzugsmoment=wert;
nmOffen=false; render(); return;
}
if(e.target.closest("[data-sbneu]")){
CAR.service.buch.unshift({datum:"04.08.2026", km:CAR.odo, art:"Neuer Eintrag",
werkstatt:CAR.service.autohaus.name, kosten:null, arbeiten:""});
go("sbuch","0"); return;
}
if(e.target.closest("[data-neu]")){ neuOffen=!neuOffen; render(); return; }
if(e.target.closest("[data-fahrt]")){ fahrtOffen=!fahrtOffen; render(); return; }
if(e.target.closest("[data-beleg]")){
alert("Hier öffnet sich die Dateiauswahl. Der Parser liest Menge, Preis, "
+ "Rabatt und Tankstelle aus dem Beleg und trägt sie ein.");
return; }
const del=e.target.closest("[data-loeschen]");
if(del){ delete CAR.service.vereinbart[del.dataset.loeschen]; render(); return; }
const kj=e.target.closest("[data-kjahr]");
if(kj){ kostenJahr=parseInt(kj.dataset.kjahr,10); render(); return; }
const oel=e.target.closest("[data-oel]");
if(oel){ CAR.oel.modus=oel.dataset.oel; render(); return; }
const mode=e.target.closest("[data-mode]");
if(mode){ document.documentElement.dataset.theme=mode.dataset.mode; themeIcon(); tiles(); render(); return; }
const pr=e.target.closest("[data-profil]");
if(pr && pr.dataset.profil==="export"){
const profil={config:CONFIG, fahrzeug:CAR};
const a=document.createElement("a");
a.href="data:application/json;charset=utf-8,"+
encodeURIComponent(JSON.stringify(profil,null,2));
a.download="fahrzeug.json"; document.body.appendChild(a); a.click(); a.remove();
return;
}
const cs=e.target.closest("[data-csv]");
if(cs){
const w=cs.dataset.csv;
if(w==="fahrten") csvDatei("fahrten.csv",
["Datum","Start","Ziel","km","Dauer","Ø km/h","Kosten €","Art"],
TRIPS.map(t=>[t.tag,t.von,t.nach,de(t.dist),t.dauer,de(t.schnitt),eur(t.kosten),t.art]));
else if(w==="tanken") csvDatei("tankvorgaenge.csv",
["Datum","Uhrzeit","Station","Liter","€/l","Kosten €","SmartDeal €","km"],
FILLS.map(f=>[f.datum,f.zeit,f.station,de(f.liter,2),de(f.summe/f.liter,3),
eur(f.summe),eur(f.rabatt),de(f.odo)]));
else csvDatei("servicebuch.csv",["Datum","km","Art","Werkstatt","Kosten €"],
CAR.service.buch.map(e2=>[e2.datum,de(e2.km),e2.art,e2.werkstatt,e2.kosten!=null?eur(e2.kosten):""]));
return; }
const satz=e.target.closest("[data-satz]");
if(satz){ CAR.reifen.aktiv=satz.dataset.satz; render(); return; }
const k=e.target.closest("[data-ics]");
if(k){
if(k.dataset.ics==="service"){
const ts=termine(), t=ts[Math.min(svAuswahl,ts.length-1)];
const datum=$("#svDat").value;
CAR.service.vereinbart[t.art]=datum;
ics(`${CONFIG.fahrzeugtitel}: ${t.art}`, datum, CAR.service.autohaus.name,
t.km!==null ? `Fällig bei ${de(t.km)} km · ${CAR.service.autohaus.adresse}`
: CAR.service.autohaus.adresse);
render();
} else {
const dat=$("#rfDat").value;
CAR.reifen.wechsel.datum=dat;
CAR.reifen.wechsel.vereinbart=$("#rfOk").checked;
const ziel = CAR.reifen.aktiv==="Sommer" ? "Winter" : "Sommer";
ics(`${CONFIG.fahrzeugtitel}: Reifenwechsel auf ${ziel}`, dat,
CAR.service.autohaus.name, `Umstellung des Zählers auf den ${ziel}satz nicht vergessen`);
}
return;
}
const a=e.target.closest("[data-acc]");
if(a){ const b=document.getElementById(a.dataset.acc);
a.setAttribute("aria-expanded", b.classList.toggle("on")); return; }
const art=e.target.closest("[data-art]");
if(art){ const tr=TRIPS.find(x=>x.id===art.dataset.art);
tr.art = tr.art==="Arbeitsweg" ? "Privat" : "Arbeitsweg"; render(); return; }
const g=e.target.closest("[data-go]");
if(g){ const [n,i]=g.dataset.go.split(":"); go(n,i); }
});
themeIcon();
render();
</script>
</body>
</html>