From 27640fee35b990b0286251b737c669db7ba99155 Mon Sep 17 00:00:00 2001 From: Tobi G Date: Tue, 11 Aug 2026 00:36:58 +0200 Subject: [PATCH] Entwurf aus Claude Design aufnehmen (Zwischenstand) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Export des Projekts "DataMetric360 App Design" nach design/ - 80 Dateien: die beiden .dc.html-Entwurfsdateien, support.js, die verwendeten Icons, Logos, Typenschilder und Schriften sowie das kompilierte Bündel des Design-Systems, damit der Entwurf für sich allein darstellbar ist. Bewusst ein Zwischenstand, nicht der Endstand: dieser Export zeigt noch "Audi RS 6 Avant" statt des tatsächlichen RS 4 Avant competition und enthält erst die Hauptbildschirme. Die 16 fehlenden Seiten (Fahrzeugstatus, Batterieverlauf, Service, Reifen, Versicherung/Steuer und weitere, siehe SPECIFICATION.md §3) sind im Design-Projekt bereits nachbeauftragt. Beides ist in design/README.md festgehalten, damit der Stand nachvollziehbar bleibt; der Ordner wird beim nächsten Export ersetzt. Co-Authored-By: Claude Opus 5 --- design/.thumbnail | Bin 0 -> 7842 bytes design/DM360.dc.html | 769 +++++++ design/DataMetric360.dc.html | 103 + design/README.md | 41 + .../README.md | 72 + .../_adherence.oxlintrc.json | 290 +++ .../_ds_bundle.css | 733 +++++++ .../_ds_bundle.js | 563 +++++ .../_ds_manifest.json | 1 + .../styles.css | 1 + design/assets/audi-rings-black.svg | 11 + design/assets/audi-rings-white.svg | 11 + design/assets/audi-sport.svg | 1 + design/assets/badge-rs6-negative.svg | 1 + design/assets/badge-rs6-positive.svg | 1 + design/assets/fonts/AudiType-Normal.ttf | Bin 0 -> 188752 bytes design/assets/fonts/AudiType-WideLight.ttf | Bin 0 -> 153764 bytes design/assets/fonts/AudiType-WideNormal.ttf | Bin 0 -> 190368 bytes design/assets/fonts/AudiTypeVF.ttf | Bin 0 -> 268160 bytes design/assets/icons.js | 1 + design/assets/icons.json | 1 + design/assets/icons/add.svg | 1 + design/assets/icons/arrow-left.svg | 1 + design/assets/icons/camera.svg | 1 + design/assets/icons/car-insurance.svg | 1 + design/assets/icons/car-settings.svg | 1 + design/assets/icons/car.svg | 1 + design/assets/icons/caution.svg | 1 + design/assets/icons/code.svg | 1 + design/assets/icons/commute.svg | 1 + design/assets/icons/compass.svg | 1 + design/assets/icons/connect-key.svg | 1 + design/assets/icons/consumption.svg | 1 + design/assets/icons/cubic-capacity.svg | 1 + design/assets/icons/dashboard.svg | 1 + design/assets/icons/document-taxation.svg | 1 + design/assets/icons/download.svg | 1 + design/assets/icons/fuel-range.svg | 1 + design/assets/icons/gas-station.svg | 1 + design/assets/icons/lock.svg | 1 + design/assets/icons/mileage.svg | 1 + design/assets/icons/over-the-air-car.svg | 1 + design/assets/icons/parking.svg | 1 + design/assets/icons/photo.svg | 1 + design/assets/icons/plan-route.svg | 1 + design/assets/icons/poi-home.svg | 1 + design/assets/icons/service-package.svg | 1 + design/assets/icons/settings.svg | 1 + design/assets/icons/time.svg | 1 + design/assets/icons/tire.svg | 1 + design/assets/icons/top-speed.svg | 1 + design/assets/shell.svg | 8 + design/support.js | 1911 +++++++++++++++++ design/uploads/AS_RGB_pos_red.svg | 1 + design/uploads/AudiType-BoldItalic_4.03.ttf | Bin 0 -> 162696 bytes design/uploads/AudiType-Bold_4.03.ttf | Bin 0 -> 160740 bytes .../AudiType-ExtendedBoldItalic_4.03.ttf | Bin 0 -> 166856 bytes design/uploads/AudiType-ExtendedBold_4.03.ttf | Bin 0 -> 166080 bytes .../uploads/AudiType-ExtendedItalic_4.03.ttf | Bin 0 -> 165484 bytes design/uploads/AudiType-Normal_4.03.ttf | Bin 0 -> 188752 bytes design/uploads/AudiType-WideBold_4.03.ttf | Bin 0 -> 159768 bytes design/uploads/AudiType-WideLight_4.03.ttf | Bin 0 -> 153764 bytes design/uploads/AudiType-WideNormal_4.03.ttf | Bin 0 -> 190368 bytes design/uploads/AudiTypeVF_4.04.ttf | Bin 0 -> 268160 bytes design/uploads/Audi_Rings_bl-RGB.svg | 11 + design/uploads/Audi_Rings_wh-RGB.svg | 11 + .../AUDI_RS_3_Badge_RGB_negative.svg | 1 + .../AUDI_RS_3_Badge_RGB_positive.svg | 1 + .../AUDI_RS_4_Badge_RGB_negative.svg | 1 + .../AUDI_RS_4_Badge_RGB_positive.svg | 1 + .../AUDI_RS_5_Badge_RGB_negative.svg | 1 + .../AUDI_RS_5_Badge_RGB_positive.svg | 1 + .../AUDI_RS_6_Badge_RGB_negative.svg | 1 + .../AUDI_RS_6_Badge_RGB_positive.svg | 1 + .../AUDI_RS_7_Badge_RGB_negative.svg | 1 + .../AUDI_RS_7_Badge_RGB_positive.svg | 1 + .../AUDI_S_3_Badge_RGB_negative.svg | 1 + .../AUDI_S_3_Badge_RGB_positive.svg | 1 + .../AUDI_S_Q7_Badge_RGB_negative.svg | 1 + .../AUDI_S_Q7_Badge_RGB_positive.svg | 1 + design/uploads/shell.svg | 8 + 81 files changed, 4594 insertions(+) create mode 100644 design/.thumbnail create mode 100644 design/DM360.dc.html create mode 100644 design/DataMetric360.dc.html create mode 100644 design/README.md create mode 100644 design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/README.md create mode 100644 design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_adherence.oxlintrc.json create mode 100644 design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_ds_bundle.css create mode 100644 design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_ds_bundle.js create mode 100644 design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_ds_manifest.json create mode 100644 design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/styles.css create mode 100644 design/assets/audi-rings-black.svg create mode 100644 design/assets/audi-rings-white.svg create mode 100644 design/assets/audi-sport.svg create mode 100644 design/assets/badge-rs6-negative.svg create mode 100644 design/assets/badge-rs6-positive.svg create mode 100644 design/assets/fonts/AudiType-Normal.ttf create mode 100644 design/assets/fonts/AudiType-WideLight.ttf create mode 100644 design/assets/fonts/AudiType-WideNormal.ttf create mode 100644 design/assets/fonts/AudiTypeVF.ttf create mode 100644 design/assets/icons.js create mode 100644 design/assets/icons.json create mode 100644 design/assets/icons/add.svg create mode 100644 design/assets/icons/arrow-left.svg create mode 100644 design/assets/icons/camera.svg create mode 100644 design/assets/icons/car-insurance.svg create mode 100644 design/assets/icons/car-settings.svg create mode 100644 design/assets/icons/car.svg create mode 100644 design/assets/icons/caution.svg create mode 100644 design/assets/icons/code.svg create mode 100644 design/assets/icons/commute.svg create mode 100644 design/assets/icons/compass.svg create mode 100644 design/assets/icons/connect-key.svg create mode 100644 design/assets/icons/consumption.svg create mode 100644 design/assets/icons/cubic-capacity.svg create mode 100644 design/assets/icons/dashboard.svg create mode 100644 design/assets/icons/document-taxation.svg create mode 100644 design/assets/icons/download.svg create mode 100644 design/assets/icons/fuel-range.svg create mode 100644 design/assets/icons/gas-station.svg create mode 100644 design/assets/icons/lock.svg create mode 100644 design/assets/icons/mileage.svg create mode 100644 design/assets/icons/over-the-air-car.svg create mode 100644 design/assets/icons/parking.svg create mode 100644 design/assets/icons/photo.svg create mode 100644 design/assets/icons/plan-route.svg create mode 100644 design/assets/icons/poi-home.svg create mode 100644 design/assets/icons/service-package.svg create mode 100644 design/assets/icons/settings.svg create mode 100644 design/assets/icons/time.svg create mode 100644 design/assets/icons/tire.svg create mode 100644 design/assets/icons/top-speed.svg create mode 100644 design/assets/shell.svg create mode 100644 design/support.js create mode 100644 design/uploads/AS_RGB_pos_red.svg create mode 100644 design/uploads/AudiType-BoldItalic_4.03.ttf create mode 100644 design/uploads/AudiType-Bold_4.03.ttf create mode 100644 design/uploads/AudiType-ExtendedBoldItalic_4.03.ttf create mode 100644 design/uploads/AudiType-ExtendedBold_4.03.ttf create mode 100644 design/uploads/AudiType-ExtendedItalic_4.03.ttf create mode 100644 design/uploads/AudiType-Normal_4.03.ttf create mode 100644 design/uploads/AudiType-WideBold_4.03.ttf create mode 100644 design/uploads/AudiType-WideLight_4.03.ttf create mode 100644 design/uploads/AudiType-WideNormal_4.03.ttf create mode 100644 design/uploads/AudiTypeVF_4.04.ttf create mode 100644 design/uploads/Audi_Rings_bl-RGB.svg create mode 100644 design/uploads/Audi_Rings_wh-RGB.svg create mode 100644 design/uploads/RS-S Badges/AUDI_RS_3_Badge_RGB_negative.svg create mode 100644 design/uploads/RS-S Badges/AUDI_RS_3_Badge_RGB_positive.svg create mode 100644 design/uploads/RS-S Badges/AUDI_RS_4_Badge_RGB_negative.svg create mode 100644 design/uploads/RS-S Badges/AUDI_RS_4_Badge_RGB_positive.svg create mode 100644 design/uploads/RS-S Badges/AUDI_RS_5_Badge_RGB_negative.svg create mode 100644 design/uploads/RS-S Badges/AUDI_RS_5_Badge_RGB_positive.svg create mode 100644 design/uploads/RS-S Badges/AUDI_RS_6_Badge_RGB_negative.svg create mode 100644 design/uploads/RS-S Badges/AUDI_RS_6_Badge_RGB_positive.svg create mode 100644 design/uploads/RS-S Badges/AUDI_RS_7_Badge_RGB_negative.svg create mode 100644 design/uploads/RS-S Badges/AUDI_RS_7_Badge_RGB_positive.svg create mode 100644 design/uploads/RS-S Badges/AUDI_S_3_Badge_RGB_negative.svg create mode 100644 design/uploads/RS-S Badges/AUDI_S_3_Badge_RGB_positive.svg create mode 100644 design/uploads/RS-S Badges/AUDI_S_Q7_Badge_RGB_negative.svg create mode 100644 design/uploads/RS-S Badges/AUDI_S_Q7_Badge_RGB_positive.svg create mode 100644 design/uploads/shell.svg diff --git a/design/.thumbnail b/design/.thumbnail new file mode 100644 index 0000000000000000000000000000000000000000..138b7266044de28771e82ca403a64388c4d26fd3 GIT binary patch literal 7842 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 Sm?pL1vNvNFBj-QAJpT)*^M!E$ literal 0 HcmV?d00001 diff --git a/design/DM360.dc.html b/design/DM360.dc.html new file mode 100644 index 0000000..8c489a4 --- /dev/null +++ b/design/DM360.dc.html @@ -0,0 +1,769 @@ + + + + + + + + + + + + + + + + +
+ + +
+
+ Audi + DataMetric360 +
Willkommen
+

Die App holt ihre Daten von deinem eigenen Server. Trag einmal die Adresse ein und füge deinen Zugangs-Token ein. Danach läuft alles von selbst.

+ + + + + + + + +
+ Verbinden + + {{ icons.code }}QR-Code scannen + +
+

Den QR-Code zeigt dir dein Server unter „DataMetric360 → Gerät verbinden“. Deine Daten bleiben auf deinem Server.

+
+
+
+ + + + + + +
+
+ + {{ icons.arrowLeft }} + +
+ {{ eyebrow }} +
{{ title }}
+
+ + + {{ icons.caution }}Offline · Stand {{ offlineTime }} + + + + {{ icons.settings }} + +
+ + +
Server nicht erreichbar. Du siehst die zuletzt geladenen Daten von {{ offlineDate }}, {{ offlineTime }} Uhr.
+
+ +
+ + + + + + {{ icons.overTheAir }} + + Fahrzeug fährt gerade + seit {{ live.dauer }} · {{ live.strecke }} km · {{ live.tempo }} km/h + + + + + +
+
+ + +
+
+
{{ modell }}
+
{{ kennzeichen }}
+
+ RS 6 +
+
+ +
+
+
+ +
+ + {{ icons.fuelRange }}Reichweite +
+ +
+ +
+ Tankfüllstand {{ tankPercentLabel }} % + {{ tankLiter }} l von 73 l +
+
+ + + +
+ +
+ + + {{ icons.planRoute }}Letzte Fahrt + {{ lastTrip.title }} + {{ lastTrip.sub }} · {{ lastTrip.value }} + + + + + {{ icons.gasStation }}Letzte Tankung + {{ lastFuel.title }} + {{ lastFuel.sub }} · {{ lastFuel.value }} + + + + + + + +
+
+
+ + +
+
+ + +
+ {{ icons.compass }} + {{ live.ort }} · aktualisiert vor {{ live.alter }} +
+
+
+
+ + {{ icons.topSpeed }}Geschwindigkeit +
+ +
+
Zündung an · {{ live.drehzahl }} 1/min
+
+ + + + + + +
+
+
+ + +
+ +
+ + +
+ RS 6 + Audi Sport +
+
+ + + +
+
+
+ + + + {{ a.icon }}{{ a.label }} + {{ a.value }} + {{ a.sub }} + + + +
+
+
+ +
+ + {{ audiDetail.icon }}{{ audiDetail.label }} +
{{ audiDetail.title }}
+ +
+ + + + + +
+
+
+
+ + + + +
+
{{ icons.planRoute }}
+
Noch keine Fahrten
+

Sobald du das erste Mal losfährst, zeichnet DataMetric360 die Fahrt automatisch auf und sortiert sie hier nach Monat ein.

+
+ Verbindung prüfen +
+
+
+
+ +
+ +
+ + + + + + + + + + + + + +
+
+ +
+ + +
+
+
{{ trip.title }}
+
{{ trip.sub }}
+
+ + {{ trip.artIcon }}{{ trip.art }} + +
+ +
+ + + +
+
+
+
+
+ + +
+ +
+ + +
+
{{ icons.consumption }}
+
Noch nichts auszuwerten
+

Nach der ersten vollständigen Fahrt siehst du hier Strecke, Fahrzeit, Verbrauch und Kosten. Für den Vergleich Tag/Nacht brauchst du etwa eine Woche Daten.

+
+
+
+ +
+
+ + {{ icons.mileage }}{{ stat.label }} +
+ +
+
+
+
+ + {{ icons.time }}Tag und Nacht +
+ +
+
+ + {{ icons.commute }}Privat und Arbeitsweg +
+ +
+
+
+
+ + Im Detail +
+ +
+
+
+
+
+
+ + + + +
+
{{ icons.gasStation }}
+
Noch keine Tankvorgänge
+

Trag deine erste Tankung ein, dann rechnet die App Verbrauch und Kosten automatisch mit. Den Beleg kannst du direkt fotografieren.

+
+ Tankung eintragen +
+
+
+
+ +
+ +
+ + + + + + + + + + + + + +
+ + {{ icons.add }}Tankung eintragen + +
+
+
+ +
+ +
+ + {{ fuel.station }} +
+
{{ fuel.title }}
+ +
+ + {{ icons.camera }}Beleg +
+ +
+ +
+ +
+
+
+
+
+
+
+
+ + +
+
+ + {{ icons.carSettings }}Fahrzeugdaten +
+ + + + + + + + + +
+
+ + Darstellung +
+ + + + + + +
+
+
+
+ + {{ icons.photo }}Fotos +
+ + + + + +
+
+ + {{ icons.add }}Foto hinzufügen + +
+
+ + {{ icons.download }}Daten +
+ Daten exportieren (CSV) + Backup erstellen + Verbindung trennen +
+
Letztes Backup: 03.08.2026, 02:00 Uhr
+
+
+
+
+ +
+ + +
+ +
+
+
+
+
+ +
+ + + diff --git a/design/DataMetric360.dc.html b/design/DataMetric360.dc.html new file mode 100644 index 0000000..b20ab80 --- /dev/null +++ b/design/DataMetric360.dc.html @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + +
+ +
+
+ Audi + DataMetric360 +
Bildschirme und Zustände
+
+
+ + + +
+
+ + + + +
+
+ +
+
+
+ Smartphone + 402 px · Tab-Leiste unten +
+
+ +
+
+ +
+
+ Großer Bildschirm + 1280 px · Navigation seitlich, Liste und Detail nebeneinander +
+
+ +
+
+
+
+ +
+ + + diff --git a/design/README.md b/design/README.md new file mode 100644 index 0000000..b4c9fe7 --- /dev/null +++ b/design/README.md @@ -0,0 +1,41 @@ +# design/ — Entwurf aus Claude Design + +Export des Claude-Design-Projekts **DataMetric360 App Design** +(https://claude.ai/design/p/c28a8d4d-ec4e-4178-9e49-ab5b90c02097). + +Das ist der **Entwurf**, nicht der lauffähige Code. Umgesetzt wird er später in +`companion-app/` auf Basis der Komponenten aus `design-system/`; die Architektur dahinter steht in +`../COMPANION_APP_ARCHITECTURE.md`, der Auftrag an den Entwurf in `../DESIGN_BRIEF_DATAMETRIC360.md`. + +## Inhalt + +| Pfad | Was | +|---|---| +| `DataMetric360.dc.html` | Einstiegsdatei des Entwurfs | +| `DM360.dc.html` | Die eigentlichen Bildschirme und Zustände | +| `support.js` | Hilfsfunktionen des Entwurfs | +| `assets/` | Icons, Logos, Typenschilder und Schriften, die der Entwurf verwendet | +| `uploads/` | Rohdateien, die ins Design-Projekt hochgeladen wurden (Schriften, Ringe, alle RS-/S-Typenschilder) | +| `_ds/` | Kompiliertes Bündel des Design-Systems `@audi-dash/ui` - erzeugt aus `../design-system/`, hier nur mitgeliefert, damit der Entwurf für sich allein darstellbar ist. **Nicht von Hand ändern**, sondern `../design-system/` anpassen und neu synchronisieren. | + +## Stand dieses Exports + +Heruntergeladen am 2026-08-11. Zwei bekannte Abweichungen, die im Design-Projekt bereits als Korrektur +beauftragt, in *diesem* Export aber noch nicht enthalten sind: + +1. **Falsches Modell:** zeigt „Audi RS 6 Avant" mit RS-6-Typenschild. Richtig ist der + **RS 4 Avant competition** (siehe `../SPECIFICATION.md` §1). +2. **Zu geringer Umfang:** enthält erst die Hauptbildschirme. Es fehlen 16 weitere Seiten, die das + bestehende HA-Panel bereits hat (Fahrzeugstatus, Fahrzeugdaten, Batterieverlauf, Service, + Werkstatt, Servicebuch, Versicherung/Steuer, Beitrag, Vertragsdetails, Schutzbrief, Notruf, + Kfz-Steuer, Reifen, Fahrt-Detail, Tankvorgang-Detail sowie deutlich umfangreichere Einstellungen) + - vollständige Liste in `../SPECIFICATION.md` §3. + +Dieser Ordner wird beim nächsten Export komplett ersetzt. + +## Markenrechtlicher Hinweis + +`assets/` und `uploads/` enthalten die Hausschrift Audi Type, die Ringe und die Typenschilder. Die +sind lizenz- beziehungsweise markenrechtlich geschützt (`../bauauftrag.md` §8/§12) und nur für diese +private Installation freigegeben. Dieses Repository ist deshalb privat zu halten. `../design-system/` +kommt bewusst ohne diese Dateien aus, weil es nach außen (Claude Design) hochgeladen wird. diff --git a/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/README.md b/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/README.md new file mode 100644 index 0000000..e073dc5 --- /dev/null +++ b/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/README.md @@ -0,0 +1,72 @@ +## Usage conventions + +- **Always wrap the tree that uses these components in `
` (or `data-theme="tag"` for the light theme).** Color tokens (`--fg`, `--canvas`, `--tile`, etc.) are defined on `:root` and work anywhere, but text `color` and page `background` are only applied via the `.ads-root` class — content rendered outside it falls back to browser-default black-on-white. +- Default theme is **Nacht** (dark) — this is what `:root` sets without any `data-theme` override. Use `data-theme="tag"` for the light variant. +- No Audi brand assets (font, rings, nameplate) are included in this bundle — it uses a neutral `Helvetica, Arial, sans-serif` fallback stack by design. +- `Popup` renders via a React portal into `document.body` by default (`position: fixed`, centers or anchors relative to the viewport) — it doesn't need to sit inside `.ads-root` itself since its own CSS sets `background`/`color` explicitly rather than inheriting them. +- `SwipeRow` is a controlled/uncontrolled swipe-to-reveal row: swiping (or setting `swiped`) slides content left to reveal a delete action on the right, clipping the row's left edge by design — this is the intended interaction, not a layout bug. + +# AudiDashUI (@audi-dash/ui@0.1.0) + +This design system is the published @audi-dash/ui React library, bundled as a single +browser global. All 20 components are the real upstream code. + +## Where things are + +- `_ds_bundle.js` — the whole-DS bundle at the project root; loads every component to `window.AudiDashUI`. First line is a `/* @ds-bundle: … */` metadata header. +- `styles.css` — the single stylesheet entry: it `@import`s the tokens, fonts, and component styles (`_ds_bundle.css`). Link this one file. +- `components///.prompt.md` (example JSX + variants), `.d.ts` (types), `.html` (variant grid). +- `tokens/*.css` — CSS custom properties, names verbatim from upstream. +- `fonts/` — `@font-face` files + `fonts.css` (when the package ships fonts). + +For a specific component, `read_file("components///.prompt.md")`. + +## Loading + +Add these two lines to your page once (React must be on the page first): + +```html + + +``` + +Components are then available at `window.AudiDashUI.*`. Mount into a dedicated child node (e.g. `
`), not the host page's own React root, so the two trees don't collide: + +```jsx +const { Accordion } = window.AudiDashUI; +ReactDOM.createRoot(document.getElementById('ds-root')).render(); +``` + +## Tokens + +23 CSS custom properties from @audi-dash/ui. Names are +preserved verbatim from upstream. They are declared inside `_ds_bundle.css` (this DS ships one compiled stylesheet rather than separate token files). + +- **typography** (1): `--font-stack` +- **other** (22): `--red`, `--r-tile`, `--r-pill`, … + +## Components + +### general +- `Accordion` +- `ActionButton` +- `Feld` +- `Fig` +- `IconButton` +- `ImagePlaceholder` +- `Pill` +- `Popup` +- `PopupMenuItem` +- `ProgressBar` +- `ProgressRing` +- `RowList` +- `Seg` +- `StatGrid` +- `StatusRow` +- `SwipeRow` +- `Switch` +- `TabBar` +- `Tile` + +### accordion +- `LeafRow` diff --git a/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_adherence.oxlintrc.json b/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_adherence.oxlintrc.json new file mode 100644 index 0000000..9f6bcc6 --- /dev/null +++ b/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_adherence.oxlintrc.json @@ -0,0 +1,290 @@ +{ + "plugins": [ + "react", + "import" + ], + "rules": { + "react/forbid-elements": [ + "warn", + { + "forbid": [] + } + ], + "no-restricted-imports": [ + "warn", + { + "patterns": [ + { + "group": [ + "components/accordion/LeafRow/**", + "components/general/Accordion/**", + "components/general/ActionButton/**", + "components/general/Feld/**", + "components/general/Fig/**", + "components/general/IconButton/**", + "components/general/ImagePlaceholder/**", + "components/general/Pill/**", + "components/general/Popup/**", + "components/general/PopupMenuItem/**", + "components/general/ProgressBar/**", + "components/general/ProgressRing/**", + "components/general/RowList/**", + "components/general/Seg/**", + "components/general/StatGrid/**", + "components/general/StatusRow/**", + "components/general/SwipeRow/**", + "components/general/Switch/**", + "components/general/TabBar/**", + "components/general/Tile/**" + ], + "message": "Import design-system components from 'index.js', not component internals." + } + ] + } + ], + "no-restricted-syntax": [ + "warn", + { + "selector": "Literal[value=/#[0-9a-fA-F]{3,8}\\b/]", + "message": "Raw hex color — use a design-system color token via var()." + }, + { + "selector": "Literal[value=/\\b\\d+px\\b/]", + "message": "Raw px value — use a design-system spacing token via var()." + }, + { + "selector": "JSXOpeningElement[name.name='Accordion'] > JSXAttribute > JSXIdentifier[name!=/^(?:title|summary|open|defaultOpen|onOpenChange|level|children|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: title, summary, open, defaultOpen, onOpenChange, level, children, className." + }, + { + "selector": "JSXOpeningElement[name.name='ActionButton'] > JSXAttribute > JSXIdentifier[name!=/^(?:children|onClick|variant|disabled|type|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: children, onClick, variant, disabled, type, className." + }, + { + "selector": "JSXOpeningElement[name.name='ActionButton'] > JSXAttribute[name.name='variant'] > Literal[value!=/^(?:default|destructive)$/]", + "message": " variant must be one of 'default' | 'destructive'." + }, + { + "selector": "JSXOpeningElement[name.name='ActionButton'] > JSXAttribute[name.name='type'] > Literal[value!=/^(?:button|submit)$/]", + "message": " type must be one of 'button' | 'submit'." + }, + { + "selector": "JSXOpeningElement[name.name='Feld'] > JSXAttribute > JSXIdentifier[name!=/^(?:label|value|children|unit|last|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: label, value, children, unit, last, className." + }, + { + "selector": "JSXOpeningElement[name.name='Fig'] > JSXAttribute > JSXIdentifier[name!=/^(?:value|unit|size|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: value, unit, size, className." + }, + { + "selector": "JSXOpeningElement[name.name='IconButton'] > JSXAttribute > JSXIdentifier[name!=/^(?:onClick|children|disabled|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: onClick, children, disabled, className." + }, + { + "selector": "JSXOpeningElement[name.name='ImagePlaceholder'] > JSXAttribute > JSXIdentifier[name!=/^(?:src|alt|label|hint|icon|size|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: src, alt, label, hint, icon, size, className." + }, + { + "selector": "JSXOpeningElement[name.name='ImagePlaceholder'] > JSXAttribute[name.name='size'] > Literal[value!=/^(?:default|mini|round)$/]", + "message": " size must be one of 'default' | 'mini' | 'round'." + }, + { + "selector": "JSXOpeningElement[name.name='LeafRow'] > JSXAttribute > JSXIdentifier[name!=/^(?:title|subTitle|value|subValue|onClick|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: title, subTitle, value, subValue, onClick, className." + }, + { + "selector": "JSXOpeningElement[name.name='Pill'] > JSXAttribute > JSXIdentifier[name!=/^(?:children|variant|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: children, variant, className." + }, + { + "selector": "JSXOpeningElement[name.name='Pill'] > JSXAttribute[name.name='variant'] > Literal[value!=/^(?:default|work)$/]", + "message": " variant must be one of 'default' | 'work'." + }, + { + "selector": "JSXOpeningElement[name.name='Popup'] > JSXAttribute > JSXIdentifier[name!=/^(?:open|onClose|variant|anchor|children|className|portalTarget|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: open, onClose, variant, anchor, children, className, portalTarget." + }, + { + "selector": "JSXOpeningElement[name.name='Popup'] > JSXAttribute[name.name='variant'] > Literal[value!=/^(?:menu|form)$/]", + "message": " variant must be one of 'menu' | 'form'." + }, + { + "selector": "JSXOpeningElement[name.name='PopupMenuItem'] > JSXAttribute > JSXIdentifier[name!=/^(?:onClick|destructive|children|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: onClick, destructive, children." + }, + { + "selector": "JSXOpeningElement[name.name='ProgressBar'] > JSXAttribute > JSXIdentifier[name!=/^(?:percent|segments|showLegend|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: percent, segments, showLegend, className." + }, + { + "selector": "JSXOpeningElement[name.name='ProgressRing'] > JSXAttribute > JSXIdentifier[name!=/^(?:percent|value|unit|label|size|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: percent, value, unit, label, size, className." + }, + { + "selector": "JSXOpeningElement[name.name='RowList'] > JSXAttribute > JSXIdentifier[name!=/^(?:items|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: items, className." + }, + { + "selector": "JSXOpeningElement[name.name='Seg'] > JSXAttribute > JSXIdentifier[name!=/^(?:options|value|onChange|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: options, value, onChange, className." + }, + { + "selector": "JSXOpeningElement[name.name='StatGrid'] > JSXAttribute > JSXIdentifier[name!=/^(?:items|columns|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: items, columns, className." + }, + { + "selector": "JSXOpeningElement[name.name='StatusRow'] > JSXAttribute > JSXIdentifier[name!=/^(?:status|title|subtitle|onClick|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: status, title, subtitle, onClick, className." + }, + { + "selector": "JSXOpeningElement[name.name='StatusRow'] > JSXAttribute[name.name='status'] > Literal[value!=/^(?:ok|warn|bad)$/]", + "message": " status must be one of 'ok' | 'warn' | 'bad'." + }, + { + "selector": "JSXOpeningElement[name.name='SwipeRow'] > JSXAttribute > JSXIdentifier[name!=/^(?:children|onDelete|deleteLabel|swiped|onSwipedChange|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: children, onDelete, deleteLabel, swiped, onSwipedChange, className." + }, + { + "selector": "JSXOpeningElement[name.name='Switch'] > JSXAttribute > JSXIdentifier[name!=/^(?:checked|onChange|disabled|id|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: checked, onChange, disabled, id, className." + }, + { + "selector": "JSXOpeningElement[name.name='TabBar'] > JSXAttribute > JSXIdentifier[name!=/^(?:items|activeKey|onChange|iconOnly|className|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: items, activeKey, onChange, iconOnly, className." + }, + { + "selector": "JSXOpeningElement[name.name='Tile'] > JSXAttribute > JSXIdentifier[name!=/^(?:variant|chevron|onClick|className|children|key|ref|className|style|children)$/]", + "message": " doesn't accept that prop. Declared props: variant, chevron, onClick, className, children." + }, + { + "selector": "JSXOpeningElement[name.name='Tile'] > JSXAttribute[name.name='variant'] > Literal[value!=/^(?:default|button|flat)$/]", + "message": " variant must be one of 'default' | 'button' | 'flat'." + } + ] + }, + "overrides": [ + { + "files": [ + "**/index.js" + ], + "rules": { + "no-restricted-imports": "off" + } + } + ], + "x-omelette": { + "components": { + "Accordion": { + "replaces": [] + }, + "ActionButton": { + "replaces": [] + }, + "Feld": { + "replaces": [] + }, + "Fig": { + "replaces": [] + }, + "IconButton": { + "replaces": [] + }, + "ImagePlaceholder": { + "replaces": [] + }, + "LeafRow": { + "replaces": [] + }, + "Pill": { + "replaces": [] + }, + "Popup": { + "replaces": [] + }, + "PopupMenuItem": { + "replaces": [] + }, + "ProgressBar": { + "replaces": [] + }, + "ProgressRing": { + "replaces": [] + }, + "RowList": { + "replaces": [] + }, + "Seg": { + "replaces": [] + }, + "StatGrid": { + "replaces": [] + }, + "StatusRow": { + "replaces": [] + }, + "SwipeRow": { + "replaces": [] + }, + "Switch": { + "replaces": [] + }, + "TabBar": { + "replaces": [] + }, + "Tile": { + "replaces": [] + } + }, + "tokens": [ + "--bad", + "--canvas", + "--fg", + "--fg2", + "--fg3", + "--font-stack", + "--line", + "--line-strong", + "--ok", + "--r-func", + "--r-pill", + "--r-tile", + "--rahmen-hg", + "--red", + "--shade", + "--sp-1", + "--sp-2", + "--sp-3", + "--sp-4", + "--sp-5", + "--tile", + "--tile-2", + "--warn" + ], + "tokenKinds": { + "--red": "color", + "--r-tile": "spacing", + "--r-pill": "spacing", + "--r-func": "spacing", + "--rahmen-hg": "color", + "--sp-1": "spacing", + "--sp-2": "spacing", + "--sp-3": "spacing", + "--sp-4": "spacing", + "--sp-5": "spacing", + "--canvas": "color", + "--tile": "color", + "--tile-2": "color", + "--line": "color", + "--line-strong": "color", + "--fg": "color", + "--fg2": "color", + "--fg3": "color", + "--ok": "color", + "--warn": "color", + "--bad": "color", + "--shade": "color", + "--font-stack": "font" + }, + "fontFamilies": [] + } +} \ No newline at end of file diff --git a/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_ds_bundle.css b/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_ds_bundle.css new file mode 100644 index 0000000..5ba5e7d --- /dev/null +++ b/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_ds_bundle.css @@ -0,0 +1,733 @@ +/* src/tokens/tokens.css */ +:root { + --red: #F50537; + --r-tile: 20px; + --r-pill: 999px; + --r-func: 8px; + --rahmen-hg: #111; + --sp-1: 4px; + --sp-2: 8px; + --sp-3: 12px; + --sp-4: 16px; + --sp-5: 22px; + --canvas: #161b23; + --tile: #1f2733; + --tile-2: #2a3341; + --line: rgba(255, 255, 255, .10); + --line-strong: rgba(255, 255, 255, .20); + --fg: #FFFFFF; + --fg2: #9aa1ad; + --fg3: #657081; + --ok: #15da15; + --warn: #ffaa00; + --bad: #fd2c4e; + --shade: rgba(255, 255, 255, .05); + --font-stack: + Helvetica, + Arial, + sans-serif; +} +[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); +} +.ads-root { + font-family: var(--font-stack); + font-variant-numeric: tabular-nums; + color: var(--fg); + background: var(--canvas); +} +.ads-eyebrow { + font-size: 10px; + letter-spacing: .2em; + text-transform: uppercase; + color: var(--fg3); + display: block; +} +.ads-title { + font-size: 23px; + letter-spacing: -.015em; + line-height: 1.15; + color: var(--fg); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.ads-label { + font-size: 10px; + letter-spacing: .2em; + text-transform: uppercase; + color: var(--fg3); + display: block; +} +.ads-sport { + font-style: italic; + letter-spacing: .005em; +} + +/* src/components/Pill/Pill.css */ +.ads-pill { + display: inline-flex; + align-items: center; + font-size: 10px; + letter-spacing: .14em; + text-transform: uppercase; + color: var(--fg2); + border: 1px solid var(--line-strong); + border-radius: var(--r-pill); + padding: 6px 12px; +} +.ads-pill--work { + color: var(--red); + border-color: var(--red); +} + +/* src/components/IconButton/IconButton.css */ +.ads-icon-button { + display: inline-flex; + align-items: center; + justify-content: center; + width: 34px; + height: 34px; + border: none; + border-radius: 50%; + background: none; + color: var(--fg3); + cursor: pointer; + padding: 0; +} +.ads-icon-button svg { + width: 18px; + height: 18px; +} +.ads-icon-button:hover:not(:disabled) { + background: var(--tile-2); + color: var(--fg); +} +.ads-icon-button:disabled { + opacity: .4; + cursor: default; +} + +/* src/components/Fig/Fig.css */ +.ads-fig { + font-weight: 300; + letter-spacing: -.02em; + line-height: .95; + color: var(--fg); +} +.ads-fig__unit { + font-size: .32em; + font-weight: 400; + letter-spacing: normal; + color: var(--fg2); + margin-left: .32em; +} + +/* src/components/StatusRow/StatusRow.css */ +.ads-status { + display: flex; + align-items: center; + gap: var(--sp-3); + width: 100%; + background: none; + border: none; + padding: 0; + text-align: left; + font-family: inherit; + cursor: default; +} +button.ads-status { + cursor: pointer; +} +.ads-dot { + width: 11px; + height: 11px; + border-radius: 50%; + flex: 0 0 auto; +} +.ads-dot--ok { + background: var(--ok); +} +.ads-dot--warn { + background: var(--warn); +} +.ads-dot--bad { + background: var(--bad); +} +.ads-status__text { + display: flex; + flex-direction: column; +} +.ads-status__t { + font-size: 14px; + color: var(--fg); +} +.ads-status__s { + font-size: 11px; + color: var(--fg3); +} + +/* src/components/ActionButton/ActionButton.css */ +.ads-action { + display: block; + width: 100%; + font-family: inherit; + font-size: 11px; + letter-spacing: .14em; + text-transform: uppercase; + color: var(--fg); + background: none; + border: 1px solid var(--line-strong); + border-radius: var(--r-pill); + padding: 14px; + cursor: pointer; +} +.ads-action:hover:not(:disabled) { + border-color: var(--red); +} +.ads-action:disabled { + opacity: .4; + cursor: default; +} +.ads-action--destructive { + color: var(--bad); + border-color: var(--bad); +} +.ads-action--destructive:hover:not(:disabled) { + background: var(--bad); + color: var(--fg); + border-color: var(--bad); +} + +/* src/components/Switch/Switch.css */ +.ads-switch { + position: relative; + display: inline-block; + flex-shrink: 0; + width: 46px; + height: 27px; +} +.ads-switch input { + position: absolute; + inset: 0; + opacity: 0; + margin: 0; + cursor: pointer; + min-width: 0; +} +.ads-switch__track { + position: absolute; + inset: 0; + background: var(--tile-2); + border: 1px solid var(--line); + border-radius: var(--r-pill); + transition: background .18s; + pointer-events: none; +} +.ads-switch__track::before { + content: ""; + position: absolute; + left: 2px; + top: 1px; + width: 23px; + height: 23px; + background: #fff; + border-radius: 50%; + transition: transform .18s; +} +.ads-switch input:checked + .ads-switch__track { + background: var(--red); + border-color: var(--red); +} +.ads-switch input:checked + .ads-switch__track::before { + transform: translateX(19px); +} +.ads-switch input:disabled + .ads-switch__track { + opacity: .4; +} + +/* src/components/Seg/Seg.css */ +.ads-seg { + display: flex; + gap: var(--sp-2); +} +.ads-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; +} +.ads-seg button.ads-seg__on { + border-color: var(--red); + color: var(--fg); +} + +/* src/components/RowList/RowList.css */ +.ads-rows { + margin: 0; +} +.ads-row { + display: flex; + justify-content: space-between; + align-items: baseline; + gap: var(--sp-3); + padding: 13px 0; + border-bottom: 1px solid var(--line); +} +.ads-row:last-child { + border-bottom: 0; +} +.ads-row dt { + font-size: 13px; + color: var(--fg2); +} +.ads-row dd { + margin: 0; + font-size: 14px; + color: var(--fg); + text-align: right; +} +.ads-row dd small { + display: block; + font-size: 11px; + color: var(--fg3); +} + +/* src/components/Accordion/LeafRow.css */ +.ads-leaf { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--sp-3); + width: 100%; + background: none; + border: none; + font-family: inherit; + text-align: left; + padding: 12px 0 12px 44px; + cursor: default; + border-bottom: 1px solid var(--line); +} +button.ads-leaf { + cursor: pointer; +} +.ads-leaf__k { + font-size: 13.5px; + color: var(--fg); + display: flex; + flex-direction: column; +} +.ads-leaf__k small { + font-size: 11px; + color: var(--fg3); +} +.ads-leaf__v { + font-size: 13px; + color: var(--fg2); + text-align: right; + display: flex; + flex-direction: column; +} +.ads-leaf__v small { + font-size: 11px; + color: var(--fg3); +} +.ads-chev { + width: 6px; + height: 10px; + color: var(--fg3); + flex: 0 0 auto; +} + +/* src/components/Tile/Tile.css */ +.ads-tile { + background: var(--tile); + border-radius: var(--r-tile); + padding: var(--sp-5); + margin-bottom: var(--sp-3); +} +.ads-tile--flat { + background: none; + padding: 0; +} +button.ads-tile--button { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + border: none; + font-family: inherit; + text-align: left; + cursor: pointer; + position: relative; +} +button.ads-tile--button:hover { + background: var(--tile-2); +} +.ads-tile__content { + flex: 1; +} +.ads-tile__go { + width: 6px; + height: 10px; + color: var(--fg3); + flex: 0 0 auto; + margin-left: var(--sp-3); +} + +/* src/components/Feld/Feld.css */ +.ads-feld { + display: flex; + justify-content: space-between; + align-items: center; + gap: var(--sp-4); + padding: 12px 0; + border-bottom: 1px solid var(--line); +} +.ads-feld--last { + border-bottom: 0; +} +.ads-feld label { + font-size: 13px; + color: var(--fg2); +} +.ads-feld input, +.ads-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: var(--r-func); + text-align: right; + min-width: 132px; +} +.ads-mit-einheit { + display: inline-flex; + align-items: center; + gap: var(--sp-2); +} +.ads-mit-einheit input { + min-width: 92px; + text-align: right; +} +.ads-mit-einheit span:last-child { + font-size: 13px; + color: var(--fg2); +} + +/* src/components/ProgressRing/ProgressRing.css */ +.ads-ring { + position: relative; + display: inline-block; +} +.ads-ring svg { + transform: rotate(-90deg); +} +.ads-ring__track { + fill: none; + stroke: var(--line); + stroke-width: 10; +} +.ads-ring__arc { + fill: none; + stroke: var(--red); + stroke-width: 10; + stroke-linecap: round; + transition: stroke-dashoffset .3s; +} +.ads-ring__mid { + position: absolute; + inset: 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; +} + +/* src/components/ProgressBar/ProgressBar.css */ +.ads-balken { + height: 4px; + border-radius: var(--r-pill); + background: var(--line); + overflow: hidden; +} +.ads-balken i { + display: block; + height: 100%; + background: var(--fg); + border-radius: var(--r-pill); +} +.ads-bar { + display: flex; + height: 4px; + border-radius: var(--r-pill); + overflow: hidden; + gap: 2px; +} +.ads-bar i { + display: block; + border-radius: var(--r-pill); +} +.ads-legend { + display: flex; + flex-wrap: wrap; + gap: var(--sp-3); + margin-top: var(--sp-2); + font-size: 11px; + color: var(--fg2); +} +.ads-legend span { + display: inline-flex; + align-items: center; + gap: 6px; +} +.ads-legend i { + width: 8px; + height: 8px; + border-radius: 50%; + display: inline-block; +} + +/* src/components/StatGrid/StatGrid.css */ +.ads-quad { + display: grid; + gap: var(--sp-4); +} +.ads-quad__n { + display: block; +} +.ads-quad__l { + display: block; + margin-top: 4px; + font-size: 9px; + letter-spacing: .12em; + text-transform: uppercase; + color: var(--fg3); +} + +/* src/components/Accordion/Accordion.css */ +.ads-acc-h { + display: flex; + align-items: center; + gap: var(--sp-2); + width: 100%; + background: none; + border: none; + font-family: inherit; + text-align: left; + padding: 12px 0; + cursor: pointer; + border-bottom: 1px solid var(--line); +} +.ads-acc-h__k { + flex: 1; + font-size: 15px; + color: var(--fg); +} +.ads-acc-h__v { + font-size: 11.5px; + color: var(--fg2); + text-align: right; +} +.ads-mark { + width: 6px; + height: 10px; + border-right: 1.4px solid var(--fg3); + border-bottom: 1.4px solid var(--fg3); + transform: rotate(-45deg) scaleY(1); + transition: transform .15s, border-color .15s; +} +.ads-acc-h[aria-expanded=true] .ads-mark { + border-color: var(--red); + transform: rotate(45deg) scaleY(1); +} +.ads-acc-b { + display: none; +} +.ads-acc-b--on { + display: block; +} +.ads-accordion--lvl2 { + margin-left: 22px; +} +.ads-accordion--lvl2 .ads-acc-h__k { + font-size: 13px; +} + +/* src/components/SwipeRow/SwipeRow.css */ +.ads-swipe-wrap { + position: relative; + overflow: hidden; +} +.ads-swipe-delete { + position: absolute; + inset: 0 0 0 auto; + width: 84px; + background: var(--bad); + color: #fff; + border: none; + font-family: inherit; + font-size: 11px; + letter-spacing: .08em; + text-transform: uppercase; + cursor: pointer; +} +.ads-swipe-content { + position: relative; + background: var(--tile); + touch-action: pan-y; + transition: transform .18s; +} + +/* src/components/TabBar/TabBar.css */ +.ads-tabbar { + display: grid; + border-top: 1px solid var(--line); +} +.ads-tab { + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; + padding: 10px 0 8px; + background: none; + border: none; + border-top: 2px solid transparent; + margin-top: -1px; + color: var(--fg3); + font-family: inherit; + cursor: pointer; +} +.ads-tab--on { + border-top-color: var(--red); + color: var(--fg); +} +.ads-tab__icon svg { + width: 21px; + height: 21px; +} +.ads-tabbar--ohne .ads-tab__icon svg { + width: 26px; + height: 26px; +} +.ads-tab__label { + font-size: 9px; + letter-spacing: .08em; + text-transform: uppercase; +} + +/* src/components/Popup/Popup.css */ +.ads-popup-catcher { + position: fixed; + inset: 0; + z-index: 1000; + background: none; + border: none; +} +.ads-popup { + position: fixed; + z-index: 1001; + background: var(--tile-2); + border-radius: 14px; + padding: var(--sp-4); +} +.ads-popup--menu { + display: flex; + flex-direction: column; + min-width: 180px; +} +.ads-popup--form { + min-width: 260px; +} +.ads-popup-item { + display: block; + width: 100%; + text-align: left; + background: none; + border: none; + color: var(--fg); + font-family: inherit; + font-size: 13.5px; + padding: 10px 4px; + cursor: pointer; +} +.ads-popup-item--destructive { + color: var(--bad); +} + +/* src/components/ImagePlaceholder/ImagePlaceholder.css */ +.ads-bildbox { + position: relative; + width: 100%; + aspect-ratio: 4 / 3; + border-radius: 12px; + overflow: hidden; +} +.ads-bildbox img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; +} +.ads-bildbox--mini { + width: 78px; + height: 78px; + aspect-ratio: auto; + border-radius: 12px; +} +.ads-bildbox--round { + border-radius: 50%; +} +.ads-platzhalter { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 6px; + border: 1px dashed var(--line-strong); + border-radius: inherit; + color: var(--fg3); + text-align: center; + padding: var(--sp-2); +} +.ads-platzhalter__icon svg { + width: 26px; + height: 26px; + color: var(--fg3); +} +.ads-platzhalter__label { + font-size: 10.5px; + letter-spacing: .02em; + color: var(--fg3); +} +.ads-platzhalter__hint { + font-family: ui-monospace, monospace; + font-size: 9px; + color: var(--fg3); +} + +/* src/styles.css */ +/*# sourceMappingURL=styles.css.map */ \ No newline at end of file diff --git a/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_ds_bundle.js b/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_ds_bundle.js new file mode 100644 index 0000000..3cc2679 --- /dev/null +++ b/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_ds_bundle.js @@ -0,0 +1,563 @@ +/* @ds-bundle: {"namespace":"AudiDashUI","components":[{"name":"Accordion","sourcePath":"components/general/Accordion/Accordion.jsx"},{"name":"ActionButton","sourcePath":"components/general/ActionButton/ActionButton.jsx"},{"name":"Feld","sourcePath":"components/general/Feld/Feld.jsx"},{"name":"Fig","sourcePath":"components/general/Fig/Fig.jsx"},{"name":"IconButton","sourcePath":"components/general/IconButton/IconButton.jsx"},{"name":"ImagePlaceholder","sourcePath":"components/general/ImagePlaceholder/ImagePlaceholder.jsx"},{"name":"LeafRow","sourcePath":"components/accordion/LeafRow/LeafRow.jsx"},{"name":"Pill","sourcePath":"components/general/Pill/Pill.jsx"},{"name":"Popup","sourcePath":"components/general/Popup/Popup.jsx"},{"name":"PopupMenuItem","sourcePath":"components/general/PopupMenuItem/PopupMenuItem.jsx"},{"name":"ProgressBar","sourcePath":"components/general/ProgressBar/ProgressBar.jsx"},{"name":"ProgressRing","sourcePath":"components/general/ProgressRing/ProgressRing.jsx"},{"name":"RowList","sourcePath":"components/general/RowList/RowList.jsx"},{"name":"Seg","sourcePath":"components/general/Seg/Seg.jsx"},{"name":"StatGrid","sourcePath":"components/general/StatGrid/StatGrid.jsx"},{"name":"StatusRow","sourcePath":"components/general/StatusRow/StatusRow.jsx"},{"name":"SwipeRow","sourcePath":"components/general/SwipeRow/SwipeRow.jsx"},{"name":"Switch","sourcePath":"components/general/Switch/Switch.jsx"},{"name":"TabBar","sourcePath":"components/general/TabBar/TabBar.jsx"},{"name":"Tile","sourcePath":"components/general/Tile/Tile.jsx"}],"sourceHashes":{"components/general/Accordion/Accordion.jsx":"e451421cbbee","components/general/Accordion/Accordion.d.ts":"0b821f95d8ec","components/general/Accordion/Accordion.prompt.md":"7b4714a7568d","components/general/ActionButton/ActionButton.jsx":"555676a71f72","components/general/ActionButton/ActionButton.d.ts":"faef681772e0","components/general/ActionButton/ActionButton.prompt.md":"1e8fad2d73f9","components/general/Feld/Feld.jsx":"fec8fe89e3b8","components/general/Feld/Feld.d.ts":"263528b0d195","components/general/Feld/Feld.prompt.md":"274cbafb13e5","components/general/Fig/Fig.jsx":"5870842c3cc9","components/general/Fig/Fig.d.ts":"a326dd89b7fd","components/general/Fig/Fig.prompt.md":"c60284795308","components/general/IconButton/IconButton.jsx":"fcd5ddfd2b26","components/general/IconButton/IconButton.d.ts":"e7a8c88afc00","components/general/IconButton/IconButton.prompt.md":"f311ce3928f4","components/general/ImagePlaceholder/ImagePlaceholder.jsx":"8ddcd8dab0a0","components/general/ImagePlaceholder/ImagePlaceholder.d.ts":"d6364f15e9c0","components/general/ImagePlaceholder/ImagePlaceholder.prompt.md":"43ca50be5f77","components/accordion/LeafRow/LeafRow.jsx":"ce900d42927c","components/accordion/LeafRow/LeafRow.d.ts":"85468f327f7a","components/accordion/LeafRow/LeafRow.prompt.md":"237acb37d8e6","components/general/Pill/Pill.jsx":"210d8cf6596a","components/general/Pill/Pill.d.ts":"530c874d26b6","components/general/Pill/Pill.prompt.md":"14374bc5a758","components/general/Popup/Popup.jsx":"bede56d5c4aa","components/general/Popup/Popup.d.ts":"469d967b7416","components/general/Popup/Popup.prompt.md":"6195801e8172","components/general/PopupMenuItem/PopupMenuItem.jsx":"0429937f4520","components/general/PopupMenuItem/PopupMenuItem.d.ts":"d98857eaf3c3","components/general/PopupMenuItem/PopupMenuItem.prompt.md":"8f18bd7e059b","components/general/ProgressBar/ProgressBar.jsx":"9ca1d1ea172a","components/general/ProgressBar/ProgressBar.d.ts":"baaa06ad6859","components/general/ProgressBar/ProgressBar.prompt.md":"039685a8659f","components/general/ProgressRing/ProgressRing.jsx":"78d41740d78b","components/general/ProgressRing/ProgressRing.d.ts":"15839d274511","components/general/ProgressRing/ProgressRing.prompt.md":"32b3e060530f","components/general/RowList/RowList.jsx":"62af0e4a633e","components/general/RowList/RowList.d.ts":"6f76bdb3711d","components/general/RowList/RowList.prompt.md":"2abce7b8d541","components/general/Seg/Seg.jsx":"0ad3d0f3e130","components/general/Seg/Seg.d.ts":"549442e8afad","components/general/Seg/Seg.prompt.md":"a1432f2825f6","components/general/StatGrid/StatGrid.jsx":"218bbd339935","components/general/StatGrid/StatGrid.d.ts":"a1b9d892b1a6","components/general/StatGrid/StatGrid.prompt.md":"0f1df1271fb0","components/general/StatusRow/StatusRow.jsx":"de77b6665985","components/general/StatusRow/StatusRow.d.ts":"3fe225d397b1","components/general/StatusRow/StatusRow.prompt.md":"cd33af1c2e77","components/general/SwipeRow/SwipeRow.jsx":"27451f62cae8","components/general/SwipeRow/SwipeRow.d.ts":"496e2058917a","components/general/SwipeRow/SwipeRow.prompt.md":"d191d8adba8c","components/general/Switch/Switch.jsx":"33ba18bc52cc","components/general/Switch/Switch.d.ts":"e5b2427866a1","components/general/Switch/Switch.prompt.md":"81f49ffeb8a6","components/general/TabBar/TabBar.jsx":"b74b7d431989","components/general/TabBar/TabBar.d.ts":"2e79e7e870c7","components/general/TabBar/TabBar.prompt.md":"dd8948507175","components/general/Tile/Tile.jsx":"b526964c5c96","components/general/Tile/Tile.d.ts":"b37ce97e2658","components/general/Tile/Tile.prompt.md":"e7cc32b1303d"},"inlinedExternals":[],"builtBy":"cc-design-sync"} */ +"use strict"; +var AudiDashUI = (() => { + var __create = Object.create; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __getProtoOf = Object.getPrototypeOf; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __esm = (fn, res, err) => function __init() { + if (err) throw err[0]; + try { + return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; + } catch (e) { + throw err = [e], e; + } + }; + var __commonJS = (cb, mod) => function __require() { + try { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + } catch (e) { + throw mod = 0, e; + } + }; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + + // + var init_define_import_meta_env = __esm({ + ""() { + } + }); + + // shim:react-shim + var require_react_shim = __commonJS({ + "shim:react-shim"(exports, module) { + init_define_import_meta_env(); + var R = window.React; + function np(p, k) { + var o = {}; + for (var x in p) if (x !== "children") o[x] = p[x]; + if (k !== void 0) o.key = k; + return o; + } + function jsx20(t, p, k) { + var c = p && p.children; + return c === void 0 ? R.createElement(t, np(p, k)) : R.createElement(t, np(p, k), c); + } + function jsxs16(t, p, k) { + return R.createElement.apply(R, [t, np(p, k)].concat(p.children)); + } + module.exports = R; + module.exports.jsx = jsx20; + module.exports.jsxs = jsxs16; + module.exports.jsxDEV = function(t, p, k, s) { + return (s ? jsxs16 : jsx20)(t, p, k); + }; + module.exports.Fragment = R.Fragment; + } + }); + + // shim:react-dom-shim + var require_react_dom_shim = __commonJS({ + "shim:react-dom-shim"(exports, module) { + init_define_import_meta_env(); + var D = window.ReactDOM; + var n = function() { + }; + module.exports = Object.assign({ preload: n, preinit: n, preconnect: n, prefetchDNS: n, preloadModule: n, preinitModule: n }, D); + } + }); + + // dist/index.js + var index_exports = {}; + __export(index_exports, { + Accordion: () => Accordion, + ActionButton: () => ActionButton, + Feld: () => Feld, + Fig: () => Fig, + IconButton: () => IconButton, + ImagePlaceholder: () => ImagePlaceholder, + LeafRow: () => LeafRow, + Pill: () => Pill, + Popup: () => Popup, + PopupMenuItem: () => PopupMenuItem, + ProgressBar: () => ProgressBar, + ProgressRing: () => ProgressRing, + RowList: () => RowList, + Seg: () => Seg, + StatGrid: () => StatGrid, + StatusRow: () => StatusRow, + SwipeRow: () => SwipeRow, + Switch: () => Switch, + TabBar: () => TabBar, + Tile: () => Tile + }); + init_define_import_meta_env(); + var import_jsx_runtime = __toESM(require_react_shim(), 1); + var import_jsx_runtime2 = __toESM(require_react_shim(), 1); + var import_jsx_runtime3 = __toESM(require_react_shim(), 1); + var import_jsx_runtime4 = __toESM(require_react_shim(), 1); + var import_jsx_runtime5 = __toESM(require_react_shim(), 1); + var import_jsx_runtime6 = __toESM(require_react_shim(), 1); + var import_jsx_runtime7 = __toESM(require_react_shim(), 1); + var import_jsx_runtime8 = __toESM(require_react_shim(), 1); + var import_jsx_runtime9 = __toESM(require_react_shim(), 1); + var import_jsx_runtime10 = __toESM(require_react_shim(), 1); + var import_jsx_runtime11 = __toESM(require_react_shim(), 1); + var import_jsx_runtime12 = __toESM(require_react_shim(), 1); + var import_jsx_runtime13 = __toESM(require_react_shim(), 1); + var React = __toESM(require_react_shim(), 1); + var import_jsx_runtime14 = __toESM(require_react_shim(), 1); + var import_jsx_runtime15 = __toESM(require_react_shim(), 1); + var React2 = __toESM(require_react_shim(), 1); + var import_jsx_runtime16 = __toESM(require_react_shim(), 1); + var import_jsx_runtime17 = __toESM(require_react_shim(), 1); + var import_react_dom = __toESM(require_react_dom_shim(), 1); + var import_jsx_runtime18 = __toESM(require_react_shim(), 1); + var React3 = __toESM(require_react_shim(), 1); + var import_jsx_runtime19 = __toESM(require_react_shim(), 1); + function Pill({ children, variant = "default", className }) { + const classes = ["ads-pill"]; + if (variant === "work") classes.push("ads-pill--work"); + if (className) classes.push(className); + return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: classes.join(" "), children }); + } + function IconButton({ + onClick, + children, + disabled, + className, + ...rest + }) { + const classes = ["ads-icon-button"]; + if (className) classes.push(className); + return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( + "button", + { + type: "button", + className: classes.join(" "), + onClick, + disabled, + ...rest, + children + } + ); + } + function Fig({ value, unit, size, className }) { + const classes = ["ads-fig"]; + if (className) classes.push(className); + const style = size !== void 0 ? { fontSize: typeof size === "number" ? `${size}px` : size } : void 0; + return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: classes.join(" "), style, children: [ + value, + unit !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "ads-fig__unit", children: unit }) + ] }); + } + function StatusRow({ status, title, subtitle, onClick, className }) { + const classes = ["ads-status"]; + if (className) classes.push(className); + const Tag = onClick ? "button" : "div"; + return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)( + Tag, + { + type: onClick ? "button" : void 0, + className: classes.join(" "), + onClick, + children: [ + /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: `ads-dot ads-dot--${status}`, "aria-hidden": true }), + /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "ads-status__text", children: [ + /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "ads-status__t", children: title }), + subtitle !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "ads-status__s", children: subtitle }) + ] }) + ] + } + ); + } + function ActionButton({ + children, + onClick, + variant = "default", + disabled, + type = "button", + className + }) { + const classes = ["ads-action"]; + if (variant === "destructive") classes.push("ads-action--destructive"); + if (className) classes.push(className); + return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type, className: classes.join(" "), onClick, disabled, children }); + } + function Switch({ + checked, + onChange, + disabled, + id, + className, + ...rest + }) { + const classes = ["ads-switch"]; + if (className) classes.push(className); + return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: classes.join(" "), children: [ + /* @__PURE__ */ (0, import_jsx_runtime6.jsx)( + "input", + { + type: "checkbox", + role: "switch", + id, + checked, + disabled, + onChange: (e) => onChange(e.target.checked), + ...rest + } + ), + /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ads-switch__track", "aria-hidden": true }) + ] }); + } + function Seg({ + options, + value, + onChange, + className + }) { + const classes = ["ads-seg"]; + if (className) classes.push(className); + return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: classes.join(" "), children: options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( + "button", + { + type: "button", + className: opt.value === value ? "ads-seg__on" : void 0, + onClick: () => onChange(opt.value), + children: opt.label + }, + opt.value + )) }); + } + function RowList({ items, className }) { + const classes = ["ads-rows"]; + if (className) classes.push(className); + return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("dl", { className: classes.join(" "), children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "ads-row", children: [ + /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("dt", { children: item.label }), + /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("dd", { children: [ + item.value, + item.subValue !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("small", { children: item.subValue }) + ] }) + ] }, item.key)) }); + } + function Tile({ variant = "default", chevron, onClick, className, children }) { + const classes = ["ads-tile"]; + if (variant === "flat") classes.push("ads-tile--flat"); + if (variant === "button") classes.push("ads-tile--button"); + if (className) classes.push(className); + if (variant === "button") { + return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("button", { type: "button", className: classes.join(" "), onClick, children: [ + /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ads-tile__content", children }), + chevron && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { className: "ads-tile__go", viewBox: "0 0 6 10", "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M1 1l4 4-4 4", fill: "none", stroke: "currentColor", strokeWidth: "1.4" }) }) + ] }); + } + return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: classes.join(" "), children }); + } + function Feld({ label, value, children, unit, last, className }) { + const classes = ["ads-feld"]; + if (last) classes.push("ads-feld--last"); + if (className) classes.push(className); + const control = children ? unit ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "ads-mit-einheit", children: [ + children, + /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: unit }) + ] }) : children : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: value }); + return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: classes.join(" "), children: [ + /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { children: label }), + control + ] }); + } + var RADIUS = 64; + var CIRCUMFERENCE = 2 * Math.PI * RADIUS; + function ProgressRing({ + percent, + value, + unit, + label, + size = 150, + className + }) { + const clamped = Math.max(0, Math.min(100, percent)); + const offset = CIRCUMFERENCE * (1 - clamped / 100); + const classes = ["ads-ring"]; + if (className) classes.push(className); + return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: classes.join(" "), style: { width: size, height: size }, children: [ + /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { viewBox: "0 0 150 150", width: size, height: size, children: [ + /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "75", cy: "75", r: RADIUS, className: "ads-ring__track" }), + /* @__PURE__ */ (0, import_jsx_runtime11.jsx)( + "circle", + { + cx: "75", + cy: "75", + r: RADIUS, + className: "ads-ring__arc", + strokeDasharray: CIRCUMFERENCE, + strokeDashoffset: offset + } + ) + ] }), + /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "ads-ring__mid", children: [ + /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Fig, { value: value ?? Math.round(clamped), unit }), + label !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ads-label", children: label }) + ] }) + ] }); + } + function ProgressBar({ percent, segments, showLegend, className }) { + const classes = ["ads-progress-bar"]; + if (className) classes.push(className); + if (segments && segments.length > 0) { + const total = segments.reduce((sum, s) => sum + s.value, 0) || 1; + const legend = showLegend ?? segments.length > 1; + return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: classes.join(" "), children: [ + /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ads-bar", children: segments.map((seg, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)( + "i", + { + style: { flex: seg.value / total, background: seg.color ?? "var(--fg)" } + }, + i + )) }), + legend && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ads-legend", children: segments.map((seg, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [ + /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("i", { style: { background: seg.color ?? "var(--fg)" } }), + seg.label + ] }, i)) }) + ] }); + } + const clamped = Math.max(0, Math.min(100, percent ?? 0)); + return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: classes.join(" "), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ads-balken", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("i", { style: { width: `${clamped}%` } }) }) }); + } + function StatGrid({ items, columns = 4, className }) { + const classes = ["ads-quad"]; + if (className) classes.push(className); + return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: classes.join(" "), style: { gridTemplateColumns: `repeat(${columns}, 1fr)` }, children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [ + /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Fig, { className: "ads-quad__n", value: item.value, unit: item.unit, size: 17 }), + /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ads-quad__l", children: item.caption }) + ] }, i)) }); + } + function Accordion({ + title, + summary, + open, + defaultOpen = false, + onOpenChange, + level = 1, + children, + className + }) { + const [internalOpen, setInternalOpen] = React.useState(defaultOpen); + const isControlled = open !== void 0; + const isOpen = isControlled ? open : internalOpen; + const toggle = () => { + const next = !isOpen; + if (!isControlled) setInternalOpen(next); + onOpenChange?.(next); + }; + const classes = ["ads-accordion"]; + if (level === 2) classes.push("ads-accordion--lvl2"); + if (className) classes.push(className); + return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: classes.join(" "), children: [ + /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("button", { type: "button", className: "ads-acc-h", onClick: toggle, "aria-expanded": isOpen, children: [ + /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ads-acc-h__k", children: title }), + summary !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ads-acc-h__v", children: summary }), + /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ads-mark", "aria-hidden": true }) + ] }), + /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: isOpen ? "ads-acc-b ads-acc-b--on" : "ads-acc-b", children }) + ] }); + } + function LeafRow({ title, subTitle, value, subValue, onClick, className }) { + const classes = ["ads-leaf"]; + if (className) classes.push(className); + const Tag = onClick ? "button" : "div"; + return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Tag, { type: onClick ? "button" : void 0, className: classes.join(" "), onClick, children: [ + /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "ads-leaf__k", children: [ + title, + subTitle !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("small", { children: subTitle }) + ] }), + /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "ads-leaf__v", children: [ + value, + subValue !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("small", { children: subValue }) + ] }), + /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("svg", { className: "ads-chev", viewBox: "0 0 6 10", "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M1 1l4 4-4 4", fill: "none", stroke: "currentColor", strokeWidth: "1.4" }) }) + ] }); + } + var SWIPE_THRESHOLD = -40; + var SWIPE_OPEN = -84; + var listeners = /* @__PURE__ */ new Set(); + function closeAllExcept(keep) { + for (const close of listeners) { + if (close !== keep) close(); + } + } + function SwipeRow({ + children, + onDelete, + deleteLabel = "Delete", + swiped, + onSwipedChange, + className + }) { + const [internalSwiped, setInternalSwiped] = React2.useState(false); + const isControlled = swiped !== void 0; + const isSwiped = isControlled ? swiped : internalSwiped; + const setSwiped = React2.useCallback( + (next) => { + if (!isControlled) setInternalSwiped(next); + onSwipedChange?.(next); + }, + [isControlled, onSwipedChange] + ); + const close = React2.useCallback(() => setSwiped(false), [setSwiped]); + React2.useEffect(() => { + listeners.add(close); + return () => { + listeners.delete(close); + }; + }, [close]); + const dragStartX = React2.useRef(null); + const onPointerDown = (e) => { + dragStartX.current = e.clientX; + }; + const onPointerMove = (e) => { + if (dragStartX.current === null) return; + const delta = e.clientX - dragStartX.current; + if (delta < SWIPE_THRESHOLD) { + closeAllExcept(close); + setSwiped(true); + dragStartX.current = null; + } else if (delta > -SWIPE_THRESHOLD) { + setSwiped(false); + } + }; + const onPointerUp = () => { + dragStartX.current = null; + }; + const classes = ["ads-swipe-wrap"]; + if (className) classes.push(className); + return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: classes.join(" "), children: [ + /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", className: "ads-swipe-delete", onClick: onDelete, children: deleteLabel }), + /* @__PURE__ */ (0, import_jsx_runtime16.jsx)( + "div", + { + className: isSwiped ? "ads-swipe-content ads-swiped" : "ads-swipe-content", + style: { transform: isSwiped ? `translateX(${SWIPE_OPEN}px)` : void 0 }, + onPointerDown, + onPointerMove, + onPointerUp, + onPointerCancel: onPointerUp, + children + } + ) + ] }); + } + function TabBar({ items, activeKey, onChange, iconOnly, className }) { + const classes = ["ads-tabbar"]; + if (iconOnly) classes.push("ads-tabbar--ohne"); + if (className) classes.push(className); + return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)( + "nav", + { + className: classes.join(" "), + style: { gridTemplateColumns: `repeat(${items.length}, 1fr)` }, + children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)( + "button", + { + type: "button", + className: item.key === activeKey ? "ads-tab ads-tab--on" : "ads-tab", + onClick: () => onChange(item.key), + children: [ + /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ads-tab__icon", children: item.icon }), + !iconOnly && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ads-tab__label", children: item.label }) + ] + }, + item.key + )) + } + ); + } + function Popup({ + open, + onClose, + variant = "menu", + anchor = "center", + children, + className, + portalTarget + }) { + if (!open) return null; + const classes = ["ads-popup", `ads-popup--${variant}`]; + if (className) classes.push(className); + const style = anchor === "center" ? { top: "50%", left: "50%", transform: "translate(-50%, -50%)" } : { ...anchor }; + const content = /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [ + /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "ads-popup-catcher", onClick: onClose }), + /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: classes.join(" "), style, children }) + ] }); + const target = portalTarget ?? (typeof document !== "undefined" ? document.body : null); + return target ? (0, import_react_dom.createPortal)(content, target) : content; + } + function PopupMenuItem({ onClick, destructive, children }) { + return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)( + "button", + { + type: "button", + className: destructive ? "ads-popup-item ads-popup-item--destructive" : "ads-popup-item", + onClick, + children + } + ); + } + var DEFAULT_ICON = /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("svg", { viewBox: "0 0 24 24", width: "26", height: "26", "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)( + "path", + { + fill: "currentColor", + fillRule: "evenodd", + d: "M4 5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V5Zm2 0v14h12V5H6Zm3 3a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3Zm-1 8 3-3 2 2 3-4 3 5H8Z", + clipRule: "evenodd" + } + ) }); + function ImagePlaceholder({ + src, + alt, + label, + hint, + icon, + size = "default", + className + }) { + const [failed, setFailed] = React3.useState(false); + const classes = ["ads-bildbox"]; + if (size === "mini") classes.push("ads-bildbox--mini"); + if (size === "round") classes.push("ads-bildbox--round"); + if (className) classes.push(className); + const showPlaceholder = !src || failed; + return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: classes.join(" "), children: [ + !showPlaceholder && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("img", { src, alt, onError: () => setFailed(true) }), + showPlaceholder && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "ads-platzhalter", children: [ + /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ads-platzhalter__icon", children: icon ?? DEFAULT_ICON }), + /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ads-platzhalter__label", children: label }), + hint !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ads-platzhalter__hint", children: hint }) + ] }) + ] }); + } + return __toCommonJS(index_exports); +})(); +window.AudiDashUI=AudiDashUI.__dsMainNs?Object.assign({},AudiDashUI,AudiDashUI.__dsMainNs,{__dsMainNs:undefined}):AudiDashUI; diff --git a/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_ds_manifest.json b/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_ds_manifest.json new file mode 100644 index 0000000..a1dedf9 --- /dev/null +++ b/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/_ds_manifest.json @@ -0,0 +1 @@ +{"namespace":"AudiDashUI","components":[{"name":"Accordion","sourcePath":"components/general/Accordion/Accordion.jsx"},{"name":"ActionButton","sourcePath":"components/general/ActionButton/ActionButton.jsx"},{"name":"Feld","sourcePath":"components/general/Feld/Feld.jsx"},{"name":"Fig","sourcePath":"components/general/Fig/Fig.jsx"},{"name":"IconButton","sourcePath":"components/general/IconButton/IconButton.jsx"},{"name":"ImagePlaceholder","sourcePath":"components/general/ImagePlaceholder/ImagePlaceholder.jsx"},{"name":"LeafRow","sourcePath":"components/accordion/LeafRow/LeafRow.jsx"},{"name":"Pill","sourcePath":"components/general/Pill/Pill.jsx"},{"name":"Popup","sourcePath":"components/general/Popup/Popup.jsx"},{"name":"PopupMenuItem","sourcePath":"components/general/PopupMenuItem/PopupMenuItem.jsx"},{"name":"ProgressBar","sourcePath":"components/general/ProgressBar/ProgressBar.jsx"},{"name":"ProgressRing","sourcePath":"components/general/ProgressRing/ProgressRing.jsx"},{"name":"RowList","sourcePath":"components/general/RowList/RowList.jsx"},{"name":"Seg","sourcePath":"components/general/Seg/Seg.jsx"},{"name":"StatGrid","sourcePath":"components/general/StatGrid/StatGrid.jsx"},{"name":"StatusRow","sourcePath":"components/general/StatusRow/StatusRow.jsx"},{"name":"SwipeRow","sourcePath":"components/general/SwipeRow/SwipeRow.jsx"},{"name":"Switch","sourcePath":"components/general/Switch/Switch.jsx"},{"name":"TabBar","sourcePath":"components/general/TabBar/TabBar.jsx"},{"name":"Tile","sourcePath":"components/general/Tile/Tile.jsx"}],"startingPoints":[],"cards":[{"path":"components/accordion/LeafRow/LeafRow.html","group":"accordion"},{"path":"components/general/Accordion/Accordion.html","group":"general","viewport":"900x700"},{"path":"components/general/ActionButton/ActionButton.html","group":"general"},{"path":"components/general/Feld/Feld.html","group":"general","viewport":"900x700"},{"path":"components/general/Fig/Fig.html","group":"general"},{"path":"components/general/IconButton/IconButton.html","group":"general"},{"path":"components/general/ImagePlaceholder/ImagePlaceholder.html","group":"general"},{"path":"components/general/Pill/Pill.html","group":"general"},{"path":"components/general/Popup/Popup.html","group":"general","viewport":"340x300"},{"path":"components/general/PopupMenuItem/PopupMenuItem.html","group":"general"},{"path":"components/general/ProgressBar/ProgressBar.html","group":"general"},{"path":"components/general/ProgressRing/ProgressRing.html","group":"general"},{"path":"components/general/RowList/RowList.html","group":"general"},{"path":"components/general/Seg/Seg.html","group":"general"},{"path":"components/general/StatGrid/StatGrid.html","group":"general","viewport":"900x700"},{"path":"components/general/StatusRow/StatusRow.html","group":"general"},{"path":"components/general/SwipeRow/SwipeRow.html","group":"general"},{"path":"components/general/Switch/Switch.html","group":"general"},{"path":"components/general/TabBar/TabBar.html","group":"general","viewport":"900x700"},{"path":"components/general/Tile/Tile.html","group":"general"}],"templates":[],"hasThumbnailHtml":false,"globalCssPaths":["_ds_bundle.css","styles.css"],"tokens":[{"name":"--red","value":"#F50537","kind":"color","definedIn":"_ds_bundle.css"},{"name":"--r-tile","value":"20px","kind":"spacing","definedIn":"_ds_bundle.css"},{"name":"--r-pill","value":"999px","kind":"spacing","definedIn":"_ds_bundle.css"},{"name":"--r-func","value":"8px","kind":"spacing","definedIn":"_ds_bundle.css"},{"name":"--rahmen-hg","value":"#111","kind":"color","definedIn":"_ds_bundle.css"},{"name":"--sp-1","value":"4px","kind":"spacing","definedIn":"_ds_bundle.css"},{"name":"--sp-2","value":"8px","kind":"spacing","definedIn":"_ds_bundle.css"},{"name":"--sp-3","value":"12px","kind":"spacing","definedIn":"_ds_bundle.css"},{"name":"--sp-4","value":"16px","kind":"spacing","definedIn":"_ds_bundle.css"},{"name":"--sp-5","value":"22px","kind":"spacing","definedIn":"_ds_bundle.css"},{"name":"--canvas","value":"#161b23","kind":"color","definedIn":"_ds_bundle.css"},{"name":"--tile","value":"#1f2733","kind":"color","definedIn":"_ds_bundle.css"},{"name":"--tile-2","value":"#2a3341","kind":"color","definedIn":"_ds_bundle.css"},{"name":"--line","value":"rgba(255, 255, 255, .10)","kind":"color","definedIn":"_ds_bundle.css"},{"name":"--line-strong","value":"rgba(255, 255, 255, .20)","kind":"color","definedIn":"_ds_bundle.css"},{"name":"--fg","value":"#FFFFFF","kind":"color","definedIn":"_ds_bundle.css"},{"name":"--fg2","value":"#9aa1ad","kind":"color","definedIn":"_ds_bundle.css"},{"name":"--fg3","value":"#657081","kind":"color","definedIn":"_ds_bundle.css"},{"name":"--ok","value":"#15da15","kind":"color","definedIn":"_ds_bundle.css"},{"name":"--warn","value":"#ffaa00","kind":"color","definedIn":"_ds_bundle.css"},{"name":"--bad","value":"#fd2c4e","kind":"color","definedIn":"_ds_bundle.css"},{"name":"--shade","value":"rgba(255, 255, 255, .05)","kind":"color","definedIn":"_ds_bundle.css"},{"name":"--font-stack","value":"Helvetica,\n Arial,\n sans-serif","kind":"font","definedIn":"_ds_bundle.css"},{"name":"--canvas","value":"#FFFFFF","kind":"color","definedIn":"_ds_bundle.css","scope":"[data-theme=tag]"},{"name":"--tile","value":"#f2f2f2","kind":"color","definedIn":"_ds_bundle.css","scope":"[data-theme=tag]"},{"name":"--tile-2","value":"#e5e5e5","kind":"color","definedIn":"_ds_bundle.css","scope":"[data-theme=tag]"},{"name":"--line","value":"rgba(0, 0, 0, .10)","kind":"color","definedIn":"_ds_bundle.css","scope":"[data-theme=tag]"},{"name":"--line-strong","value":"rgba(0, 0, 0, .22)","kind":"color","definedIn":"_ds_bundle.css","scope":"[data-theme=tag]"},{"name":"--fg","value":"#000000","kind":"color","definedIn":"_ds_bundle.css","scope":"[data-theme=tag]"},{"name":"--fg2","value":"#4c4c4c","kind":"color","definedIn":"_ds_bundle.css","scope":"[data-theme=tag]"},{"name":"--fg3","value":"#666666","kind":"color","definedIn":"_ds_bundle.css","scope":"[data-theme=tag]"},{"name":"--ok","value":"#0DA20D","kind":"color","definedIn":"_ds_bundle.css","scope":"[data-theme=tag]"},{"name":"--warn","value":"#ffaa00","kind":"color","definedIn":"_ds_bundle.css","scope":"[data-theme=tag]"},{"name":"--bad","value":"#eb0d3f","kind":"color","definedIn":"_ds_bundle.css","scope":"[data-theme=tag]"},{"name":"--shade","value":"rgba(0, 0, 0, .04)","kind":"color","definedIn":"_ds_bundle.css","scope":"[data-theme=tag]"}],"themes":[{"selector":"[data-theme=tag]","label":"Tag"}],"fonts":[],"brandFonts":[],"source":"design-sync-cli"} \ No newline at end of file diff --git a/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/styles.css b/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/styles.css new file mode 100644 index 0000000..8f6b11b --- /dev/null +++ b/design/_ds/audi-dashboard-ui-27d66fd4-ed86-43b2-b8bf-61e281a5a1a5/styles.css @@ -0,0 +1 @@ +@import "./_ds_bundle.css"; diff --git a/design/assets/audi-rings-black.svg b/design/assets/audi-rings-black.svg new file mode 100644 index 0000000..1c3b009 --- /dev/null +++ b/design/assets/audi-rings-black.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/design/assets/audi-rings-white.svg b/design/assets/audi-rings-white.svg new file mode 100644 index 0000000..83a5ca6 --- /dev/null +++ b/design/assets/audi-rings-white.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/design/assets/audi-sport.svg b/design/assets/audi-sport.svg new file mode 100644 index 0000000..07e5f71 --- /dev/null +++ b/design/assets/audi-sport.svg @@ -0,0 +1 @@ +AS_RGB_pos_red \ No newline at end of file diff --git a/design/assets/badge-rs6-negative.svg b/design/assets/badge-rs6-negative.svg new file mode 100644 index 0000000..506b1a5 --- /dev/null +++ b/design/assets/badge-rs6-negative.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/design/assets/badge-rs6-positive.svg b/design/assets/badge-rs6-positive.svg new file mode 100644 index 0000000..11142fd --- /dev/null +++ b/design/assets/badge-rs6-positive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/design/assets/fonts/AudiType-Normal.ttf b/design/assets/fonts/AudiType-Normal.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d026f3037841d2de2903cd0d00aa27aa52ad410f GIT binary patch literal 188752 zcmeFacYG98_c(m-?Ck86-JPx3WH-sS>~1y*X`4<-XrY@>lOTqk1Q0_D5ClOf2}O!X z2*^WGq=^uz5kWwti>P!30g}`b*C1qA-lkRSY+uMU zzTc*6_ZDN=DPJJsi%|&4n&fniOWgkR@*4=@Lr}j@k5--X9}K&E3?ao>gt#63hxQ%z zM5MWO^mw7&(v z>xy43FB(#C>Jx+-RU-UDe#yYT1G?9=j)l4%;rEmhD2ShJ`3bJ4z;#5)&{1PA`@Ya1 zL`1^#bB7EZ@tS^bqiu+wFTpduf3>uK-;klJ%Ha9u5t6PO+IQ?Q^52q0aQ_;(-||}D zp##?rdpZaa(L15PONW(?9M$vikq3xK?uC$k?ywO9hegSkLw_USdBjyD(2|sGu&hlV z+M93kr-f5N0YcxO9sHXAIIh{VK2P2D3H%1QrV$~O!XMnnZ+Pm4b|ydT^Q^CZg4mM( zHxUyjg%ZGb;jRTpD*ld<9Lf-(MiRJ|FqL>N{DL?STLk4z{YTmR*d^^l69gxfkOV;y zk`;)!lZz}*>YDFZmR*Xn5c2xu?x$|aRDOfxj0K@(!tZo4R|N+Pl1Of${X&W4;d5Y1 z(M$gXl>4Ec8!u(5koWI^^Wdc-^g=Zp0Milb{sW-*!+i$i{YS70>I!fj)skEAQmO(g z$t}M1R0W#V;QBFK{{-b5;JB0Af@nDY4#$K*{ikq!4eF2aU!&W?k$nj-m0Ph=y4ZJD z0O4H)pnLuWCZh_WOsRu@T=_3hf?4h#0Dl)~IUVQ(Ak=3|;h7D9X@#!-9RLj`&|Xyf zSKuf-;GY891+`brL|y(0%nsC^c@ri42TVuROatI@(PO$6UHB)U*oH1J&}Uf{y8U;+ ztU|Zzp#s{AJSx;Pi!jsYpNy>Di5Qdp0@*hIucI^KpZs^t(2`pH~$WpyHIZpn)p{>-o*L;6l6zHBl+v7 z>0g1iqAu_o`5$l#9g{Tx7{jZwP3S(o9vejYG7@#En@?;tnk;}IAK0C~0|H+O^IGBZ z9T4V0-CU-UeFx~}z5{i0Se%m}uj=L=eHqmX_2m=cKDb|)NA$O-R+tw8|8h%xtHk47 zv{K+}ZYbI>r*WJJ$Kbh}fbT?r@s#_{Fu;4VZfL&qkd;&6y_SHi z72q*es^{UQ>bp?h7WGqn9*~1qP^o+kDrLQJ9aw8rg@Rl}O9WZN48Rn<6Zm_50B*za z7|itv$o&_&aTVUpEr8sO+_H`^UjSGVPiP2%xes&RXQoSm4*;0Os6AZ+$36f

NTs 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