@bytebrand/fe-ui-core-autobahn 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (621) hide show
  1. package/assets/autode-logo.svg +6 -6
  2. package/cards/CarCard.tsx +174 -174
  3. package/cards/CarRow.tsx +186 -182
  4. package/cards/cardParts.tsx +529 -489
  5. package/cards/index.ts +37 -35
  6. package/cards/types.ts +124 -114
  7. package/chrome/Footer.tsx +189 -189
  8. package/chrome/TopBar.tsx +405 -405
  9. package/chrome/index.ts +20 -20
  10. package/chrome/svg.d.ts +11 -11
  11. package/compat/AccardionSection/AccardionSection.styl +45 -45
  12. package/compat/AccardionSection/AccardionSection.tsx +56 -56
  13. package/compat/AccordionWidget/AccordionWidget.styl +220 -220
  14. package/compat/AccordionWidget/AccordionWidget.tsx +257 -257
  15. package/compat/AccordionWrapper/AccordionItem/AccordionItem.styl +34 -34
  16. package/compat/AccordionWrapper/AccordionItem/AccordionItem.tsx +64 -64
  17. package/compat/AccordionWrapper/AccordionWrapper.tsx +34 -34
  18. package/compat/AdvantageItem/AdvantageItem.styl +47 -47
  19. package/compat/AdvantageItem/AdvantageItem.tsx +26 -26
  20. package/compat/Alternative/DealerInfo.styl +116 -116
  21. package/compat/Alternative/DealerInfo.tsx +171 -171
  22. package/compat/Badge/Badge.styl +44 -44
  23. package/compat/Badge/Badge.tsx +25 -25
  24. package/compat/BodyTypeIcons/Audi.tsx +9 -9
  25. package/compat/BodyTypeIcons/Bmw.tsx +860 -860
  26. package/compat/BodyTypeIcons/Ford.tsx +31 -31
  27. package/compat/BodyTypeIcons/IconsConfig.tsx +44 -44
  28. package/compat/BodyTypeIcons/IconsConfigCompact.tsx +30 -30
  29. package/compat/BodyTypeIcons/Mazda.tsx +44 -44
  30. package/compat/BodyTypeIcons/MercedesBenz.tsx +38 -38
  31. package/compat/BodyTypeIcons/Opel.tsx +19 -19
  32. package/compat/BodyTypeIcons/Search.tsx +19 -19
  33. package/compat/BodyTypeIcons/SelectorCategoryCombi.tsx +68 -68
  34. package/compat/BodyTypeIcons/SelectorCategoryCompact.tsx +20 -20
  35. package/compat/BodyTypeIcons/SelectorCategoryConvertible.tsx +68 -68
  36. package/compat/BodyTypeIcons/SelectorCategoryCoupe.tsx +60 -60
  37. package/compat/BodyTypeIcons/SelectorCategoryMinibus.tsx +64 -64
  38. package/compat/BodyTypeIcons/SelectorCategorySedan.tsx +69 -69
  39. package/compat/BodyTypeIcons/SelectorCategorySuv.tsx +77 -77
  40. package/compat/BodyTypeIcons/SelectorCategoryTransporter.tsx +68 -68
  41. package/compat/BodyTypeIcons/SelectorCategoryVan.tsx +72 -72
  42. package/compat/BodyTypeIcons/Volkswagen.tsx +330 -330
  43. package/compat/BodyTypeIcons/index.ts +17 -17
  44. package/compat/Button/Button.tsx +65 -65
  45. package/compat/ButtonOld/Button.styl +65 -65
  46. package/compat/ButtonOld/Button.tsx +84 -84
  47. package/compat/Checkbox/Checkbox.styl +119 -119
  48. package/compat/Checkbox/Checkbox.tsx +151 -151
  49. package/compat/Checkbox/FormCheckbox.styl +22 -22
  50. package/compat/Checkbox/FormCheckbox.tsx +86 -86
  51. package/compat/Co2Widget/CO2Efficiency.styl +219 -219
  52. package/compat/Co2Widget/CO2Efficiency.tsx +93 -93
  53. package/compat/ContactInfo/ContactInfo.styl +22 -22
  54. package/compat/ContactInfo/ContactInfo.tsx +161 -161
  55. package/compat/ContactInfo/TemporaryTranslation.ts +11 -11
  56. package/compat/CookieModal/CookieModal.tsx +49 -49
  57. package/compat/CookieModal/Modal.tsx +43 -43
  58. package/compat/CookieModal/ModalsConfig.tsx +23 -23
  59. package/compat/CookieModal/modals/ManageCookieModal/ManageCookieModal.styl +86 -86
  60. package/compat/CookieModal/modals/ManageCookieModal/ManageCookieModal.tsx +184 -184
  61. package/compat/CookieModal/modals/PreviewCookieModal/PreviewCookieModal.styl +66 -66
  62. package/compat/CookieModal/modals/PreviewCookieModal/PreviewCookieModal.tsx +51 -51
  63. package/compat/CookieModal/modals/TestModal.tsx +7 -7
  64. package/compat/CookieModal/useModal.ts +13 -13
  65. package/compat/CustomerQuote/CustomerQuote.styl +79 -79
  66. package/compat/CustomerQuote/CustomerQuote.tsx +68 -68
  67. package/compat/CustomerQuotesSlider/CustomerQuotesSlider.styl +46 -46
  68. package/compat/CustomerQuotesSlider/CustomerQuotesSlider.tsx +79 -79
  69. package/compat/CustomerQuotesSlider/SliderArrow.tsx +20 -20
  70. package/compat/CustomerQuotesSlider/slider.global.styl +2 -2
  71. package/compat/ExpansionPanel/ExpansionPanel.tsx +68 -68
  72. package/compat/FirstInfoBlock/FirstInfoBlock.styl +33 -33
  73. package/compat/FirstInfoBlock/FirstInfoBlock.tsx +49 -49
  74. package/compat/FirstInfoBlock/FirstInfoBlockItem/FirstInfoBlockItem.styl +66 -66
  75. package/compat/FirstInfoBlock/FirstInfoBlockItem/FirstInfoBlockItem.tsx +21 -21
  76. package/compat/FormattedNumber/FormattedNumber.styl +1 -1
  77. package/compat/FormattedNumber/FormattedNumber.tsx +90 -90
  78. package/compat/IconContainer/IconContainer.styl +23 -23
  79. package/compat/IconContainer/IconContainer.tsx +34 -34
  80. package/compat/Image/Image.styl +109 -109
  81. package/compat/Image/Image.tsx +302 -302
  82. package/compat/ImageSettings/EditableOptionsTable/CustomCheckbox/CustomCheckbox.styl +7 -7
  83. package/compat/ImageSettings/EditableOptionsTable/CustomCheckbox/CustomCheckbox.tsx +30 -30
  84. package/compat/ImageSettings/EditableOptionsTable/EditableOptionsTable.styl +122 -122
  85. package/compat/ImageSettings/EditableOptionsTable/EditableOptionsTable.tsx +199 -199
  86. package/compat/ImageSettings/EditableOptionsTable/ImageIcon/ImageIcon.styl +3 -3
  87. package/compat/ImageSettings/EditableOptionsTable/ImageIcon/ImageIcon.tsx +15 -15
  88. package/compat/ImageSettings/OptionsTable/OptionsTable.styl +47 -47
  89. package/compat/ImageSettings/OptionsTable/OptionsTable.tsx +122 -122
  90. package/compat/ImageSettings/PricePlan/PricePlan.styl +63 -63
  91. package/compat/ImageSettings/PricePlan/PricePlan.tsx +32 -32
  92. package/compat/ImageSettings/index.ts +42 -42
  93. package/compat/ImagesSet/ImagesSet.styl +27 -27
  94. package/compat/ImagesSet/ImagesSet.tsx +76 -76
  95. package/compat/InfoBlockWrapper/InfoBlockWrapper.styl +41 -41
  96. package/compat/InfoBlockWrapper/InfoBlockWrapper.tsx +46 -46
  97. package/compat/Loader/Loader.styl +39 -39
  98. package/compat/Loader/Loader.tsx +32 -32
  99. package/compat/MagnifyGlass/MagnifyGlass.styl +33 -33
  100. package/compat/MagnifyGlass/MagnifyGlass.tsx +213 -213
  101. package/compat/MdAccordionGroup/MdAccordionGroup.tsx +53 -53
  102. package/compat/MdCheckbox/MdCheckbox.tsx +69 -69
  103. package/compat/MdField/MdField.tsx +100 -100
  104. package/compat/MdSelect/MdSelect.tsx +103 -103
  105. package/compat/MdSwitch/MdSwitch.tsx +29 -29
  106. package/compat/MdTabs/MdTabs.tsx +47 -47
  107. package/compat/MdTooltip/MdTooltip.tsx +31 -31
  108. package/compat/OfferDetailedSection/OfferDetailedSection.styl +31 -31
  109. package/compat/OfferDetailedSection/OfferDetailedSection.tsx +100 -100
  110. package/compat/OfferDetailedSection/partials/PanelConfig.styl +131 -131
  111. package/compat/OfferDetailedSection/partials/PanelConfig.tsx +121 -121
  112. package/compat/OfferPanel/AboAccordion/AboAccordion.styl +24 -24
  113. package/compat/OfferPanel/AboAccordion/AboAccordion.tsx +128 -128
  114. package/compat/OfferPanel/AboAccordion/AboColorOptions/AboColorOptions.styl +11 -11
  115. package/compat/OfferPanel/AboAccordion/AboColorOptions/AboColorOptions.tsx +35 -35
  116. package/compat/OfferPanel/AboAccordion/AboFaq/AboFaq.styl +20 -20
  117. package/compat/OfferPanel/AboAccordion/AboFaq/AboFaq.tsx +25 -25
  118. package/compat/OfferPanel/AboAccordion/AboIncludedServices/AboIncludedServices.styl +13 -13
  119. package/compat/OfferPanel/AboAccordion/AboIncludedServices/AboIncludedServices.tsx +39 -39
  120. package/compat/OfferPanel/MuiOfferPeriod/MuiOfferPeriod.tsx +42 -42
  121. package/compat/OfferPanel/OfferCheckboxGroup/CheckboxContainer.tsx +140 -140
  122. package/compat/OfferPanel/OfferCheckboxGroup/OfferCheckboxGroup.styl +144 -144
  123. package/compat/OfferPanel/OfferCheckboxGroup/OfferCheckboxGroup.tsx +23 -23
  124. package/compat/OfferPanel/OfferPanel.styl +193 -193
  125. package/compat/OfferPanel/OfferPanel.tsx +81 -81
  126. package/compat/OfferPanel/OfferPeriod/OfferPeriod.styl +24 -24
  127. package/compat/OfferPanel/OfferPeriod/OfferPeriod.tsx +45 -45
  128. package/compat/OfferPanel/RangeGroup/RangeGroup.tsx +39 -39
  129. package/compat/OfferRequestButtonWrapper/OfferRequestButtonWrapper.styl +119 -119
  130. package/compat/OfferRequestButtonWrapper/OfferRequestButtonWrapper.styled.tsx +33 -33
  131. package/compat/OfferRequestButtonWrapper/OfferRequestButtonWrapper.tsx +122 -122
  132. package/compat/PriceRating/PriceRating.styl +47 -47
  133. package/compat/PriceRating/PriceRating.tsx +64 -64
  134. package/compat/PriceRatingDetailed/PriceRatingDetailed.styl +120 -120
  135. package/compat/PriceRatingDetailed/PriceRatingDetailed.tsx +191 -191
  136. package/compat/PricingToolBlock/PricingTool.styl +6 -6
  137. package/compat/PricingToolBlock/PricingTool.tsx +29 -29
  138. package/compat/Radio/Radio.styl +115 -115
  139. package/compat/Radio/Radio.tsx +141 -141
  140. package/compat/Radio/RadioGroup.styl +5 -5
  141. package/compat/Radio/RadioGroup.tsx +65 -65
  142. package/compat/Range/Range.tsx +79 -79
  143. package/compat/RateSearchValue/RateSearchValue.styl +22 -22
  144. package/compat/RateSearchValue/RateSearchValue.tsx +55 -55
  145. package/compat/RateSearchWidget/RateSearchWidget.styl +106 -106
  146. package/compat/RateSearchWidget/RateSearchWidget.tsx +163 -163
  147. package/compat/ServiceBlockItem/ServiceBlockItem.styl +47 -47
  148. package/compat/ServiceBlockItem/ServiceBlockItem.tsx +25 -25
  149. package/compat/SkeletonItem/SkeletonItem.styl +80 -80
  150. package/compat/SkeletonItem/SkeletonItem.tsx +80 -80
  151. package/compat/StarButton/StarButton.styl +39 -39
  152. package/compat/StarButton/StarButton.tsx +31 -31
  153. package/compat/TabPanel/TabPanel.tsx +28 -28
  154. package/compat/TimePicker/TimePicker.styl +22 -22
  155. package/compat/TimePicker/TimePicker.tsx +156 -156
  156. package/compat/Tooltip/Tooltip.styl +117 -117
  157. package/compat/Tooltip/Tooltip.tsx +63 -63
  158. package/compat/Usp/Usp.styl +78 -78
  159. package/compat/Usp/Usp.tsx +30 -30
  160. package/compat/Usp/uspTranslate.ts +12 -12
  161. package/compat/VehicleDetailedSidebar/VehicleDetailedSidebar.styl +36 -36
  162. package/compat/VehicleDetailedSidebar/VehicleDetailedSidebar.tsx +178 -178
  163. package/compat/VehicleDetailedSidebar/partials/Price.styl +27 -27
  164. package/compat/VehicleDetailedSidebar/partials/Price.tsx +41 -41
  165. package/compat/VehicleDetailedSidebar/partials/PriceContent.styl +123 -123
  166. package/compat/VehicleDetailedSidebar/partials/PriceContent.tsx +128 -128
  167. package/compat/VehicleDetailedSidebar/partials/Properties.styl +58 -58
  168. package/compat/VehicleDetailedSidebar/partials/Properties.tsx +155 -155
  169. package/compat/VehicleDetailedSidebar/partials/Title.styl +35 -35
  170. package/compat/VehicleDetailedSidebar/partials/Title.tsx +33 -33
  171. package/compat/VehicleDetailedSlider/VehicleDetailedSlider.styl +146 -146
  172. package/compat/VehicleDetailedSlider/VehicleDetailedSlider.tsx +382 -382
  173. package/compat/VehicleDetailedSlider/partials/MobileStast.tsx +61 -61
  174. package/compat/VehicleDetailedSlider/partials/MobileStats.styl +71 -71
  175. package/compat/VehicleDetailedSlider/partials/PriceData.styl +50 -50
  176. package/compat/VehicleDetailedSlider/partials/PriceData.tsx +67 -67
  177. package/compat/VehicleDetailedSlider/partials/Stats.styl +80 -80
  178. package/compat/VehicleDetailedSlider/partials/Stats.tsx +62 -62
  179. package/compat/VehicleDetailedSlider/partials/Title.styl +44 -44
  180. package/compat/VehicleDetailedSlider/partials/Title.tsx +36 -36
  181. package/compat/VehicleFormattedPrice/VehicleFormattedPrice.styl +148 -148
  182. package/compat/VehicleFormattedPrice/VehicleFormattedPrice.tsx +163 -163
  183. package/compat/VehicleSlider/VehicleSlider.styl +62 -62
  184. package/compat/VehicleSlider/VehicleSlider.tsx +125 -125
  185. package/compat/VehicleSlider/VehicleSliderForSRL.tsx +175 -175
  186. package/compat/VehicleSmallCard/SeoText/SeoText.styl +8 -8
  187. package/compat/VehicleSmallCard/SeoText/SeoText.tsx +16 -16
  188. package/compat/VehicleSmallCard/VehicleData/VechiclePriceItem/VechiclePriceItem.styl +204 -204
  189. package/compat/VehicleSmallCard/VehicleData/VechiclePriceItem/VechiclePriceItem.tsx +199 -199
  190. package/compat/VehicleSmallCard/VehicleData/VehicleInfo/VehicleInfo.styl +273 -273
  191. package/compat/VehicleSmallCard/VehicleData/VehicleInfo/VehicleInfo.tsx +179 -179
  192. package/compat/VehicleSmallCard/VehicleData/VehiclePrice/VehiclePrice.styl +165 -165
  193. package/compat/VehicleSmallCard/VehicleData/VehiclePrice/VehiclePrice.tsx +299 -299
  194. package/compat/VehicleSmallCard/VehicleData/VehicleProperty/VehicleProperty.styl +32 -32
  195. package/compat/VehicleSmallCard/VehicleData/VehicleProperty/VehicleProperty.tsx +35 -35
  196. package/compat/VehicleSmallCard/VehicleData/VehicleTitle/VehicleTitle.styl +135 -135
  197. package/compat/VehicleSmallCard/VehicleData/VehicleTitle/VehicleTitle.tsx +91 -91
  198. package/compat/VehicleSmallCard/VehicleSmallCard.styl +309 -309
  199. package/compat/VehicleSmallCard/VehicleSmallCard.tsx +448 -448
  200. package/compat/index.ts +77 -77
  201. package/compat/legacy-theme/mixins.styl +93 -93
  202. package/compat/legacy-theme/priceReviewColors.styl +12 -12
  203. package/compat/legacy-theme/slider.global.styl +5 -5
  204. package/compat/legacy-theme/theme.styl +136 -136
  205. package/compat/withLabel/withLabel.styl +33 -33
  206. package/compat/withLabel/withLabel.tsx +44 -44
  207. package/compat/withStats/withStats.styl +174 -174
  208. package/compat/withStats/withStats.tsx +238 -238
  209. package/constants/RateSearchWidget.ts +15 -15
  210. package/constants/Search.ts +290 -290
  211. package/constants/SearchWidget.ts +108 -108
  212. package/constants/app.ts +223 -223
  213. package/constants/common.ts +127 -127
  214. package/constants/core.ts +131 -131
  215. package/constants/highlights.ts +165 -165
  216. package/constants/price.ts +9 -9
  217. package/constants/selectors.ts +38 -38
  218. package/constants.ts +91 -91
  219. package/data/DataTransformers.ts +88 -88
  220. package/data/fieldMapping.ts +364 -342
  221. package/data/toAutobahnCar.ts +455 -442
  222. package/iconsvg/IconSVG.tsx +30 -30
  223. package/iconsvg/IconSVGConfig.tsx +768 -768
  224. package/iconsvg/SVG/AboPartner.tsx +16 -16
  225. package/iconsvg/SVG/ArrowQuotes.tsx +22 -22
  226. package/iconsvg/SVG/CloseIcon.tsx +17 -17
  227. package/iconsvg/SVG/CloseIconSelect.tsx +18 -18
  228. package/iconsvg/SVG/ClosedLockIcon.tsx +18 -18
  229. package/iconsvg/SVG/DealerCheckIcon.tsx +18 -18
  230. package/iconsvg/SVG/DealerPopoverMail.tsx +21 -21
  231. package/iconsvg/SVG/DealerPopoverPhone.tsx +21 -21
  232. package/iconsvg/SVG/GrayPhoneIcon.tsx +22 -22
  233. package/iconsvg/SVG/InternetIcon.tsx +18 -18
  234. package/iconsvg/SVG/WhiteEnvelopeIcon.tsx +21 -21
  235. package/iconsvg/SVG/bodyType/Cabrio.tsx +23 -23
  236. package/iconsvg/SVG/bodyType/Coupe.tsx +22 -22
  237. package/iconsvg/SVG/bodyType/Minibus.tsx +22 -22
  238. package/iconsvg/SVG/bodyType/Other.tsx +25 -25
  239. package/iconsvg/SVG/bodyType/Sedan.tsx +22 -22
  240. package/iconsvg/SVG/bodyType/SelectorCategoryCombi.tsx +68 -68
  241. package/iconsvg/SVG/bodyType/SelectorCategoryCompact.tsx +20 -20
  242. package/iconsvg/SVG/bodyType/SelectorCategoryConvertible.tsx +68 -68
  243. package/iconsvg/SVG/bodyType/SelectorCategoryCoupe.tsx +60 -60
  244. package/iconsvg/SVG/bodyType/SelectorCategoryMinibus.tsx +64 -64
  245. package/iconsvg/SVG/bodyType/SelectorCategoryOther.tsx +60 -60
  246. package/iconsvg/SVG/bodyType/SelectorCategorySedan.tsx +69 -69
  247. package/iconsvg/SVG/bodyType/SelectorCategorySuv.tsx +77 -77
  248. package/iconsvg/SVG/bodyType/SelectorCategoryTransporter.tsx +68 -68
  249. package/iconsvg/SVG/bodyType/SelectorCategoryVan.tsx +72 -72
  250. package/iconsvg/SVG/bodyType/Small.tsx +23 -23
  251. package/iconsvg/SVG/bodyType/Suv.tsx +23 -23
  252. package/iconsvg/SVG/bodyType/Van.tsx +23 -23
  253. package/iconsvg/SVG/bodyType/Wagon.tsx +23 -23
  254. package/iconsvg/SVG/common/AddIcon.tsx +16 -16
  255. package/iconsvg/SVG/common/AddPlus.tsx +16 -16
  256. package/iconsvg/SVG/common/AddressDashboard.tsx +29 -29
  257. package/iconsvg/SVG/common/AddressIcon.tsx +20 -20
  258. package/iconsvg/SVG/common/ArrowDetailedAccordionBlue.tsx +26 -26
  259. package/iconsvg/SVG/common/ArrowDownBlue.tsx +21 -21
  260. package/iconsvg/SVG/common/ArrowSelect.tsx +23 -23
  261. package/iconsvg/SVG/common/ArrowStepDown.tsx +18 -18
  262. package/iconsvg/SVG/common/Autocheck.tsx +19 -19
  263. package/iconsvg/SVG/common/AutodeLogo.tsx +36 -36
  264. package/iconsvg/SVG/common/Avatar.tsx +17 -17
  265. package/iconsvg/SVG/common/BellGray.tsx +19 -19
  266. package/iconsvg/SVG/common/BigInfoTransparent.tsx +13 -13
  267. package/iconsvg/SVG/common/Browse.tsx +20 -20
  268. package/iconsvg/SVG/common/Calendar.tsx +24 -24
  269. package/iconsvg/SVG/common/CallbackDashboard.tsx +30 -30
  270. package/iconsvg/SVG/common/Camera.tsx +17 -17
  271. package/iconsvg/SVG/common/Car.tsx +16 -16
  272. package/iconsvg/SVG/common/CarBody.tsx +19 -19
  273. package/iconsvg/SVG/common/CarFront.tsx +43 -43
  274. package/iconsvg/SVG/common/CarInspectionCheck.tsx +21 -21
  275. package/iconsvg/SVG/common/CarInspectionScheme0.tsx +32 -32
  276. package/iconsvg/SVG/common/CarInspectionScheme1.tsx +53 -53
  277. package/iconsvg/SVG/common/CarInspectionScheme2.tsx +52 -52
  278. package/iconsvg/SVG/common/CarInspectionScheme3.tsx +32 -32
  279. package/iconsvg/SVG/common/CarInspectionScheme4.tsx +32 -32
  280. package/iconsvg/SVG/common/CarInspectionScheme5.tsx +32 -32
  281. package/iconsvg/SVG/common/CarInspectionScheme6.tsx +32 -32
  282. package/iconsvg/SVG/common/CarInspectionSchemeGeneral copy.tsx +24 -24
  283. package/iconsvg/SVG/common/CarInspectionSchemeGeneral.tsx +24 -24
  284. package/iconsvg/SVG/common/CheckBlue.tsx +18 -18
  285. package/iconsvg/SVG/common/CheckGreen.tsx +22 -22
  286. package/iconsvg/SVG/common/CheckMark.tsx +16 -16
  287. package/iconsvg/SVG/common/CheckWhite.tsx +19 -19
  288. package/iconsvg/SVG/common/Chevron.tsx +17 -17
  289. package/iconsvg/SVG/common/CircledCheckmark.tsx +25 -25
  290. package/iconsvg/SVG/common/Clock.tsx +18 -18
  291. package/iconsvg/SVG/common/Close.tsx +19 -19
  292. package/iconsvg/SVG/common/CloseGrey.tsx +22 -22
  293. package/iconsvg/SVG/common/ContactEmail.tsx +21 -21
  294. package/iconsvg/SVG/common/ContactPhone.tsx +28 -28
  295. package/iconsvg/SVG/common/CopyIcon copy.tsx +22 -22
  296. package/iconsvg/SVG/common/CopyIcon.tsx +22 -22
  297. package/iconsvg/SVG/common/CopyIconForDealer.tsx +21 -21
  298. package/iconsvg/SVG/common/DashboardIcon.tsx +20 -20
  299. package/iconsvg/SVG/common/DashboardQuestionMark.tsx +20 -20
  300. package/iconsvg/SVG/common/DealersIcon.tsx +20 -20
  301. package/iconsvg/SVG/common/DeleteCircle.tsx +31 -31
  302. package/iconsvg/SVG/common/DeleteV1Icon.tsx +18 -18
  303. package/iconsvg/SVG/common/DeliveryDashboard.tsx +25 -25
  304. package/iconsvg/SVG/common/DeliveryMail.tsx +24 -24
  305. package/iconsvg/SVG/common/Discount100De.tsx +18 -18
  306. package/iconsvg/SVG/common/Discount100En.tsx +19 -19
  307. package/iconsvg/SVG/common/Discount66De.tsx +28 -28
  308. package/iconsvg/SVG/common/Discount66En.tsx +20 -20
  309. package/iconsvg/SVG/common/DoneIcon.tsx +18 -18
  310. package/iconsvg/SVG/common/EditCircle.tsx +32 -32
  311. package/iconsvg/SVG/common/EditPriceIcon.tsx +20 -20
  312. package/iconsvg/SVG/common/EuroCurrency.tsx +18 -18
  313. package/iconsvg/SVG/common/Export.tsx +20 -20
  314. package/iconsvg/SVG/common/Eye.tsx +17 -17
  315. package/iconsvg/SVG/common/EyeCatch.tsx +19 -19
  316. package/iconsvg/SVG/common/FavoritesIcon.tsx +20 -20
  317. package/iconsvg/SVG/common/FilterRange.tsx +16 -16
  318. package/iconsvg/SVG/common/FilterToolBlack.tsx +23 -23
  319. package/iconsvg/SVG/common/FlagDe.tsx +21 -21
  320. package/iconsvg/SVG/common/FlagEn.tsx +43 -43
  321. package/iconsvg/SVG/common/GrayEnvelopeIcon.tsx +19 -19
  322. package/iconsvg/SVG/common/HamburgerMenuIcon.tsx +18 -18
  323. package/iconsvg/SVG/common/HandingOverDashboard.tsx +32 -32
  324. package/iconsvg/SVG/common/ImageSettingsIcon.tsx +20 -20
  325. package/iconsvg/SVG/common/Info.tsx +16 -16
  326. package/iconsvg/SVG/common/InfoIcon.tsx +17 -17
  327. package/iconsvg/SVG/common/InfoTransparent.tsx +18 -18
  328. package/iconsvg/SVG/common/LogoutIcon.tsx +20 -20
  329. package/iconsvg/SVG/common/MagnifyingGlass.tsx +31 -31
  330. package/iconsvg/SVG/common/MenuArrow.tsx +16 -16
  331. package/iconsvg/SVG/common/MenuGrey.tsx +22 -22
  332. package/iconsvg/SVG/common/MobileDeLogo.tsx +108 -108
  333. package/iconsvg/SVG/common/MyOrderIcon.tsx +20 -20
  334. package/iconsvg/SVG/common/MyVehiclesIcon.tsx +20 -20
  335. package/iconsvg/SVG/common/NewFlagDe.tsx +25 -25
  336. package/iconsvg/SVG/common/NewFlagEn.tsx +34 -34
  337. package/iconsvg/SVG/common/OrderReceivedDashboard.tsx +27 -27
  338. package/iconsvg/SVG/common/Package.tsx +30 -30
  339. package/iconsvg/SVG/common/Phone.tsx +18 -18
  340. package/iconsvg/SVG/common/PhoneGrey.tsx +22 -22
  341. package/iconsvg/SVG/common/PickupDashboard.tsx +30 -30
  342. package/iconsvg/SVG/common/Picture.tsx +24 -24
  343. package/iconsvg/SVG/common/Pictures.tsx +32 -32
  344. package/iconsvg/SVG/common/Plus.tsx +16 -16
  345. package/iconsvg/SVG/common/PlusNew.tsx +16 -16
  346. package/iconsvg/SVG/common/PreparationDashboard.tsx +29 -29
  347. package/iconsvg/SVG/common/ProfileDashboard.tsx +24 -24
  348. package/iconsvg/SVG/common/ProfileIcon.tsx +17 -17
  349. package/iconsvg/SVG/common/Question.tsx +19 -19
  350. package/iconsvg/SVG/common/QuestionBold.tsx +25 -25
  351. package/iconsvg/SVG/common/RegistrationDashboard.tsx +31 -31
  352. package/iconsvg/SVG/common/SavedSearchsIcon.tsx +20 -20
  353. package/iconsvg/SVG/common/Search.tsx +19 -19
  354. package/iconsvg/SVG/common/SearchGrey.tsx +22 -22
  355. package/iconsvg/SVG/common/SettingPenIcon.tsx +20 -20
  356. package/iconsvg/SVG/common/Share.tsx +16 -16
  357. package/iconsvg/SVG/common/ShoppingCart.tsx +18 -18
  358. package/iconsvg/SVG/common/SliderArrow.tsx +21 -21
  359. package/iconsvg/SVG/common/SliderEye.tsx +17 -17
  360. package/iconsvg/SVG/common/SortUpDownArrows.tsx +18 -18
  361. package/iconsvg/SVG/common/Speedometer.tsx +23 -23
  362. package/iconsvg/SVG/common/Star.tsx +20 -20
  363. package/iconsvg/SVG/common/StarNew.tsx +16 -16
  364. package/iconsvg/SVG/common/StarOutline.tsx +20 -20
  365. package/iconsvg/SVG/common/StarRoundedCorners.tsx +18 -18
  366. package/iconsvg/SVG/common/Stats.tsx +17 -17
  367. package/iconsvg/SVG/common/Step1.tsx +21 -21
  368. package/iconsvg/SVG/common/Step2.tsx +20 -20
  369. package/iconsvg/SVG/common/Step3.tsx +21 -21
  370. package/iconsvg/SVG/common/SupportCallbackIcon.tsx +20 -20
  371. package/iconsvg/SVG/common/Telephone.tsx +22 -22
  372. package/iconsvg/SVG/common/Time.tsx +17 -17
  373. package/iconsvg/SVG/common/Timetable.tsx +18 -18
  374. package/iconsvg/SVG/common/Trash.tsx +22 -22
  375. package/iconsvg/SVG/common/TrashRed.tsx +23 -23
  376. package/iconsvg/SVG/common/Upload.tsx +17 -17
  377. package/iconsvg/SVG/common/UserGrey.tsx +22 -22
  378. package/iconsvg/SVG/common/UserProfileIcon.tsx +20 -20
  379. package/iconsvg/SVG/common/ValidateFailure.tsx +21 -21
  380. package/iconsvg/SVG/common/ValidateSuccess.tsx +21 -21
  381. package/iconsvg/SVG/common/WarningTriangle.tsx +20 -20
  382. package/iconsvg/SVG/common/WhiteArrowUp.tsx +21 -21
  383. package/iconsvg/SVG/common/WhiteKey.tsx +21 -21
  384. package/iconsvg/SVG/common/WhitePeople.tsx +23 -23
  385. package/iconsvg/SVG/common/WhiteTick.tsx +19 -19
  386. package/iconsvg/SVG/flags/AT.tsx +19 -19
  387. package/iconsvg/SVG/flags/BE.tsx +20 -20
  388. package/iconsvg/SVG/flags/BG.tsx +20 -20
  389. package/iconsvg/SVG/flags/CH.tsx +22 -22
  390. package/iconsvg/SVG/flags/CZ.tsx +18 -18
  391. package/iconsvg/SVG/flags/DE.tsx +18 -18
  392. package/iconsvg/SVG/flags/DK.tsx +18 -18
  393. package/iconsvg/SVG/flags/ES.tsx +2585 -2585
  394. package/iconsvg/SVG/flags/FI.tsx +18 -18
  395. package/iconsvg/SVG/flags/FR.tsx +20 -20
  396. package/iconsvg/SVG/flags/GB.tsx +26 -26
  397. package/iconsvg/SVG/flags/HR.tsx +135 -135
  398. package/iconsvg/SVG/flags/HU.tsx +20 -20
  399. package/iconsvg/SVG/flags/IT.tsx +20 -20
  400. package/iconsvg/SVG/flags/LI.tsx +106 -106
  401. package/iconsvg/SVG/flags/LU.tsx +18 -18
  402. package/iconsvg/SVG/flags/NL.tsx +18 -18
  403. package/iconsvg/SVG/flags/NO.tsx +20 -20
  404. package/iconsvg/SVG/flags/PL.tsx +19 -19
  405. package/iconsvg/SVG/flags/RO.tsx +20 -20
  406. package/iconsvg/SVG/flags/RU.tsx +20 -20
  407. package/iconsvg/SVG/flags/SE.tsx +20 -20
  408. package/iconsvg/SVG/flags/SI.tsx +54 -54
  409. package/iconsvg/SVG/flags/SK.tsx +34 -34
  410. package/iconsvg/SVG/flags/UA.tsx +19 -19
  411. package/iconsvg/SVG/infoBlocks/14DaysReturnPolicy.tsx +18 -18
  412. package/iconsvg/SVG/infoBlocks/AlertInfo.tsx +19 -19
  413. package/iconsvg/SVG/infoBlocks/Autocheck.tsx +19 -19
  414. package/iconsvg/SVG/infoBlocks/CheckTheStory.tsx +22 -22
  415. package/iconsvg/SVG/infoBlocks/CustomerServiceWhite.tsx +16 -16
  416. package/iconsvg/SVG/infoBlocks/Guarantee.tsx +16 -16
  417. package/iconsvg/SVG/infoBlocks/OrderWhite.tsx +13 -13
  418. package/iconsvg/SVG/infoBlocks/PriceGuarantee.tsx +19 -19
  419. package/iconsvg/SVG/infoBlocks/PriceGuaranteeWhite.tsx +17 -17
  420. package/iconsvg/SVG/infoBlocks/TransportAndDelivery.tsx +21 -21
  421. package/iconsvg/SVG/infoBlocks/Warranty.tsx +23 -23
  422. package/iconsvg/SVG/popower/Mail.tsx +18 -18
  423. package/iconsvg/SVG/popower/Phone.tsx +19 -19
  424. package/iconsvg/SVG/popower/Schedule.tsx +18 -18
  425. package/iconsvg/SVG/searchWidgets/drive/AAllWheelDrive.tsx +26 -26
  426. package/iconsvg/SVG/searchWidgets/drive/AllWheelDrive.tsx +26 -26
  427. package/iconsvg/SVG/searchWidgets/drive/FrontWheelDrive.tsx +25 -25
  428. package/iconsvg/SVG/searchWidgets/drive/OtherWheelDrive.tsx +26 -26
  429. package/iconsvg/SVG/searchWidgets/drive/RearWheelDrive.tsx +25 -25
  430. package/iconsvg/SVG/searchWidgets/fuel/FuelDiesel.tsx +18 -18
  431. package/iconsvg/SVG/searchWidgets/fuel/FuelElectrical.tsx +19 -19
  432. package/iconsvg/SVG/searchWidgets/fuel/FuelElectricalDiesel.tsx +34 -34
  433. package/iconsvg/SVG/searchWidgets/fuel/FuelElectricalPetrol.tsx +20 -20
  434. package/iconsvg/SVG/searchWidgets/fuel/FuelEthanol.tsx +53 -53
  435. package/iconsvg/SVG/searchWidgets/fuel/FuelHydrogen.tsx +24 -24
  436. package/iconsvg/SVG/searchWidgets/fuel/FuelLpg.tsx +24 -24
  437. package/iconsvg/SVG/searchWidgets/fuel/FuelNaturalGas.tsx +23 -23
  438. package/iconsvg/SVG/searchWidgets/fuel/FuelOther.tsx +28 -28
  439. package/iconsvg/SVG/searchWidgets/fuel/FuelPetrol.tsx +18 -18
  440. package/iconsvg/SVG/settings/Account.tsx +17 -17
  441. package/iconsvg/SVG/settings/DataUsage.tsx +17 -17
  442. package/iconsvg/SVG/settings/MarketResearch.tsx +17 -17
  443. package/iconsvg/SVG/settings/Newsletter.tsx +17 -17
  444. package/iconsvg/SVG/settings/RemoveEye.tsx +17 -17
  445. package/iconsvg/SVG/settings/RemoveEyeOff.tsx +17 -17
  446. package/iconsvg/SVG/settings/Security.tsx +17 -17
  447. package/iconsvg/SVG/settings/Warning.tsx +17 -17
  448. package/iconsvg/SVG/slider/360.tsx +23 -23
  449. package/iconsvg/SVG/slider/360New.tsx +20 -20
  450. package/iconsvg/SVG/slider/Checked.tsx +19 -19
  451. package/iconsvg/SVG/slider/DiscountRibbon.tsx +51 -51
  452. package/iconsvg/SVG/slider/DiscountRibbonMobile.tsx +47 -47
  453. package/iconsvg/SVG/slider/DiscountRibbonNew.tsx +29 -29
  454. package/iconsvg/SVG/slider/Easy.tsx +19 -19
  455. package/iconsvg/SVG/slider/Fullscreen.tsx +16 -16
  456. package/iconsvg/SVG/slider/FullscreenWindow.tsx +23 -23
  457. package/iconsvg/SVG/slider/Safe.tsx +19 -19
  458. package/iconsvg/SVG/slider/ToBuy.tsx +19 -19
  459. package/iconsvg/SVG/slider/YoutubeButton.tsx +26 -26
  460. package/iconsvg/SVG/slider/ZoomIn.tsx +21 -21
  461. package/iconsvg/SVG/slider/ZoomOut.tsx +21 -21
  462. package/iconsvg/SVG/social/AndroidLogo.tsx +18 -18
  463. package/iconsvg/SVG/social/Apple.tsx +19 -19
  464. package/iconsvg/SVG/social/FacebookF.tsx +19 -19
  465. package/iconsvg/SVG/social/GooglePlusG.tsx +19 -19
  466. package/iconsvg/SVG/social/Instagram.tsx +17 -17
  467. package/iconsvg/SVG/social/Pinterest.tsx +19 -19
  468. package/iconsvg/SVG/social/SharingInterface.tsx +21 -21
  469. package/iconsvg/SVG/social/Twitter.tsx +19 -19
  470. package/iconsvg/SVG/social/Youtube.tsx +19 -19
  471. package/iconsvg/SVG/vehicle/AboIcon.tsx +11 -11
  472. package/iconsvg/SVG/vehicle/Abs.tsx +24 -24
  473. package/iconsvg/SVG/vehicle/AirCond.tsx +34 -34
  474. package/iconsvg/SVG/vehicle/Airbag.tsx +21 -21
  475. package/iconsvg/SVG/vehicle/AuxiliaryHeating.tsx +23 -23
  476. package/iconsvg/SVG/vehicle/Bluetooth.tsx +22 -22
  477. package/iconsvg/SVG/vehicle/BuyIcon.tsx +15 -15
  478. package/iconsvg/SVG/vehicle/CarAvailability.tsx +22 -22
  479. package/iconsvg/SVG/vehicle/CarInspectionCheck.tsx +21 -21
  480. package/iconsvg/SVG/vehicle/CarInspectionCross.tsx +21 -21
  481. package/iconsvg/SVG/vehicle/CheckoutChecked.tsx +15 -15
  482. package/iconsvg/SVG/vehicle/Co2.tsx +24 -24
  483. package/iconsvg/SVG/vehicle/CruiseControl.tsx +25 -25
  484. package/iconsvg/SVG/vehicle/Date.tsx +21 -21
  485. package/iconsvg/SVG/vehicle/Delivery.tsx +12 -12
  486. package/iconsvg/SVG/vehicle/Diesel.tsx +28 -28
  487. package/iconsvg/SVG/vehicle/Display.tsx +25 -25
  488. package/iconsvg/SVG/vehicle/Done.tsx +11 -11
  489. package/iconsvg/SVG/vehicle/Door.tsx +19 -19
  490. package/iconsvg/SVG/vehicle/DoubleDone.tsx +18 -18
  491. package/iconsvg/SVG/vehicle/EditIcon.tsx +11 -11
  492. package/iconsvg/SVG/vehicle/EmergencyBrakeAssistant.tsx +27 -27
  493. package/iconsvg/SVG/vehicle/Eps.tsx +24 -24
  494. package/iconsvg/SVG/vehicle/Esp.tsx +24 -24
  495. package/iconsvg/SVG/vehicle/FinancingIcon.tsx +20 -20
  496. package/iconsvg/SVG/vehicle/FuelConsumption.tsx +20 -20
  497. package/iconsvg/SVG/vehicle/Fueling.tsx +22 -22
  498. package/iconsvg/SVG/vehicle/FullDrive.tsx +24 -24
  499. package/iconsvg/SVG/vehicle/GasElectric.tsx +28 -28
  500. package/iconsvg/SVG/vehicle/HandsFreePhoneSystem.tsx +24 -24
  501. package/iconsvg/SVG/vehicle/Kw.tsx +23 -23
  502. package/iconsvg/SVG/vehicle/LastCrawledAt.tsx +22 -22
  503. package/iconsvg/SVG/vehicle/LeasingIcon.tsx +14 -14
  504. package/iconsvg/SVG/vehicle/Led.tsx +24 -24
  505. package/iconsvg/SVG/vehicle/LightSensor.tsx +22 -22
  506. package/iconsvg/SVG/vehicle/LinkAlternative.tsx +15 -15
  507. package/iconsvg/SVG/vehicle/Location.tsx +17 -17
  508. package/iconsvg/SVG/vehicle/MinusIcon.tsx +11 -11
  509. package/iconsvg/SVG/vehicle/Mirror.tsx +19 -19
  510. package/iconsvg/SVG/vehicle/Navigation.tsx +27 -27
  511. package/iconsvg/SVG/vehicle/NewCar.tsx +21 -21
  512. package/iconsvg/SVG/vehicle/NoImage.tsx +17 -17
  513. package/iconsvg/SVG/vehicle/Owner.tsx +18 -18
  514. package/iconsvg/SVG/vehicle/PanoramicRoof.tsx +23 -23
  515. package/iconsvg/SVG/vehicle/ParkingAssistants.tsx +24 -24
  516. package/iconsvg/SVG/vehicle/PickYourself.tsx +18 -18
  517. package/iconsvg/SVG/vehicle/PlusIcon.tsx +11 -11
  518. package/iconsvg/SVG/vehicle/Power.tsx +21 -21
  519. package/iconsvg/SVG/vehicle/Ps.tsx +19 -19
  520. package/iconsvg/SVG/vehicle/Question.tsx +24 -24
  521. package/iconsvg/SVG/vehicle/Seats.tsx +21 -21
  522. package/iconsvg/SVG/vehicle/SeatsHeating.tsx +26 -26
  523. package/iconsvg/SVG/vehicle/SelectorGearboxAutomatic.tsx +24 -24
  524. package/iconsvg/SVG/vehicle/SelectorGearboxManualShift.tsx +19 -19
  525. package/iconsvg/SVG/vehicle/SelectorGearboxOther.tsx +24 -24
  526. package/iconsvg/SVG/vehicle/SelectorGearboxSemiAutomatic.tsx +30 -30
  527. package/iconsvg/SVG/vehicle/SelectorInteriorTypeAlcantara.tsx +225 -225
  528. package/iconsvg/SVG/vehicle/SelectorInteriorTypeFabric.tsx +29 -29
  529. package/iconsvg/SVG/vehicle/SelectorInteriorTypeFullLeather.tsx +29 -29
  530. package/iconsvg/SVG/vehicle/SelectorInteriorTypeOther.tsx +26 -26
  531. package/iconsvg/SVG/vehicle/SelectorInteriorTypePartLeather.tsx +142 -142
  532. package/iconsvg/SVG/vehicle/SelectorInteriorTypeSyntheticLeather.tsx +27 -27
  533. package/iconsvg/SVG/vehicle/SelectorInteriorTypeVelours.tsx +39 -39
  534. package/iconsvg/SVG/vehicle/Shield.tsx +39 -39
  535. package/iconsvg/SVG/vehicle/Speedometer.tsx +17 -17
  536. package/iconsvg/SVG/vehicle/StartStopSystem.tsx +30 -30
  537. package/iconsvg/SVG/vehicle/Stop.tsx +25 -25
  538. package/iconsvg/SVG/vehicle/TickMark.tsx +21 -21
  539. package/iconsvg/SVG/vehicle/TrafficSignRecognition.tsx +29 -29
  540. package/iconsvg/SVG/vehicle/TrailerCoupling.tsx +24 -24
  541. package/iconsvg/SVG/vehicle/Transmission.tsx +27 -27
  542. package/iconsvg/SVG/vehicle/Wheel.tsx +43 -43
  543. package/iconsvg/SVG/vehicle/Wipers.tsx +22 -22
  544. package/iconsvg/SVG/vehicle/Wrench.tsx +17 -17
  545. package/iconsvg/index.ts +7 -7
  546. package/index.ts +18 -18
  547. package/locales/de/autobahn.json +676 -671
  548. package/locales/en/autobahn.json +676 -671
  549. package/locales/legacy/SearchDetailedPage.ts +205 -205
  550. package/locales/legacy/cbd.ts +719 -719
  551. package/locales/legacy/common.ts +109 -109
  552. package/locales/legacy/data.ts +1118 -1118
  553. package/locales/legacy/priceRating.ts +10 -10
  554. package/locales/legacy/sortingOptions.ts +21 -21
  555. package/media/images/raiting-stars-min.svg +7 -7
  556. package/media/images/refresh-button.svg +49 -49
  557. package/media/images/user-icon.svg +16 -16
  558. package/media/svg/infoBlocks/whyAutodeIconSet-F.svg +9 -9
  559. package/media/svg/infoBlocks/whyAutodeIconSet-G.svg +8 -8
  560. package/media/svg/infoBlocks/whyAutodeIconSet-Q.svg +6 -6
  561. package/media/svg/infoBlocks/whyAutodeIconSet-R.svg +9 -9
  562. package/media/svg/usp/icon1.svg +16 -16
  563. package/media/svg/usp/icon2.svg +13 -13
  564. package/media/svg/usp/icon3.svg +10 -10
  565. package/media/svg/usp/icon4.svg +14 -14
  566. package/package.json +30 -30
  567. package/schemes/AggregationScheme.ts +73 -73
  568. package/searchFilters/filterOptions.ts +119 -119
  569. package/searchFilters/filterProps.ts +35 -35
  570. package/searchFilters/index.ts +15 -15
  571. package/theme/autobahn.css +25 -25
  572. package/theme/colors_and_type.css +113 -113
  573. package/theme/md3.css +2045 -2034
  574. package/types/types.ts +373 -373
  575. package/types.ts +8 -8
  576. package/ui/Accordion.tsx +134 -134
  577. package/ui/Button.tsx +62 -62
  578. package/ui/CardCarousel.tsx +133 -133
  579. package/ui/Chip.tsx +29 -29
  580. package/ui/DatePicker.tsx +145 -145
  581. package/ui/Dropdown.tsx +205 -205
  582. package/ui/FileUpload.tsx +154 -154
  583. package/ui/FormCheckbox.tsx +79 -79
  584. package/ui/FormDropdown.tsx +327 -327
  585. package/ui/FormField.tsx +88 -88
  586. package/ui/FormRadio.tsx +93 -93
  587. package/ui/FormRadioGroup.tsx +106 -106
  588. package/ui/Icon.tsx +391 -391
  589. package/ui/IconButton.tsx +44 -44
  590. package/ui/Modal.tsx +187 -187
  591. package/ui/Pagination.tsx +140 -140
  592. package/ui/Price.tsx +25 -25
  593. package/ui/PriceEvalBar.tsx +48 -48
  594. package/ui/SaveChip.tsx +34 -34
  595. package/ui/Segmented.tsx +48 -48
  596. package/ui/Skeleton.tsx +75 -75
  597. package/ui/Spec.tsx +24 -24
  598. package/ui/Stars.tsx +29 -29
  599. package/ui/StatChip.tsx +21 -21
  600. package/ui/Stepper.tsx +106 -106
  601. package/ui/Switch.tsx +65 -65
  602. package/ui/Table.tsx +156 -156
  603. package/ui/Textarea.tsx +58 -58
  604. package/ui/index.ts +88 -88
  605. package/utils/CommonUtils.ts +648 -648
  606. package/utils/DateUtils.ts +101 -101
  607. package/utils/index.ts +74 -74
  608. package/utils/power.ts +11 -11
  609. package/utils/query.ts +21 -21
  610. package/vdp/FinanceCalculator.tsx +465 -465
  611. package/vdp/VdpModules.tsx +1490 -1490
  612. package/vdp/VdpViewer.tsx +209 -209
  613. package/vdp/index.ts +75 -75
  614. package/vdp/types.ts +197 -197
  615. package/vehiclesProps/cbdSelectors.ts +117 -117
  616. package/vehiclesProps/decoratedLightProps.tsx +572 -572
  617. package/vehiclesProps/decoratedProps.tsx +1746 -1746
  618. package/vehiclesProps/equipment.ts +129 -129
  619. package/vehiclesProps/vehicleDetails.ts +428 -428
  620. package/widgets/SearchBox.tsx +256 -256
  621. package/widgets/index.ts +5 -5
@@ -1,489 +1,529 @@
1
- // Autobahn (auto.de redesign) — car-card helper parts.
2
- //
3
- // Typed React 18 + TS port of the helper components from the design kit
4
- // (docs/redesign/design-source/ui_kits/website/CarCard.jsx). Pure /
5
- // presentational: every value comes from the `AutobahnCar` prop, there is no
6
- // store / API / `window` access. The design kit's `window.CO2_CLASSES` /
7
- // `window.CO2_COLORS` globals are replaced by the shared autobahn constants.
8
- //
9
- // These render correctly only inside a `<div className="md3">` subtree (the
10
- // `.pricepaths`, `.pp-*`, `.specstrip`, `.imglabel` … classes are scoped there).
11
- //
12
- // NEEDS-DATA discipline (the point of the ticket): wherever the design showed a
13
- // figure we have no real source for, these helpers render the NEEDS_DATA_LABEL
14
- // ('Daten folgt') marker instead of inventing a number — see PricePaths'
15
- // market band and PpActivity. DropChip renders nothing when there is no drop.
16
-
17
- import React from 'react';
18
- import { TranslationFunction } from '../types';
19
- import { defaultConfig } from '@bytebrand/fe-financing';
20
-
21
- import { Icon } from '../ui';
22
- import { CO2_CLASSES, CO2_COLORS, TIER_COLORS, TIER_KEYS } from '../constants';
23
- import { AutobahnCar } from './types';
24
-
25
- // Default financing/leasing terms shown under the rate (the SRP card has no per-car selector, so
26
- // these are the same default config the displayed rate is computed with — consistent, not invented).
27
- const _finCfg = (defaultConfig as any).financing || {};
28
- const _leasCfg = (defaultConfig as any).leasing || {};
29
- /** financing terms inputs (rendered via t in PricePaths), e.g. "0 € Anzahlung · 48 Monate Laufzeit". */
30
- const _finFirstInstallment = (_finCfg.firstInstallment || 0).toLocaleString('de-DE');
31
- const _finMonths = _finCfg.rawPaybackPeriod || _finCfg.paybackPeriod || 48;
32
- /** leasing terms inputs (only when the config carries mileage + period), e.g. "10.000 km/Jahr · 48 Monate". */
33
- const _leasPeriod = _leasCfg.rawPaybackPeriod || _leasCfg.paybackPeriod;
34
- const _leasMileage = _leasCfg.annualMileage || _leasCfg.mileage;
35
- const _hasLeasTerms = Boolean(_leasMileage && _leasPeriod);
36
- const _leasMileageStr = _leasMileage ? Number(_leasMileage).toLocaleString('de-DE') : '';
37
-
38
- /** mileage → 'X.XXX km' (de-DE grouping). */
39
- export function fmtKm(n: number): string {
40
- return n.toLocaleString('de-DE') + ' km';
41
- }
42
-
43
- /**
44
- * Monthly rate → de-DE integer euro string (e.g. 402.12 → "402"). Rates are shown as whole
45
- * euros like the legacy card ("271 €"); a raw float printed directly rendered as "402.12 €",
46
- * which a German reader parses as 402.120 — fixed here with rounding + de-DE grouping.
47
- */
48
- export function fmtRate(n: number): string {
49
- return Math.round(n).toLocaleString('de-DE');
50
- }
51
-
52
- /** strip a trailing parenthetical, e.g. '110 kW (150 PS)' → '110 kW'. */
53
- function stripParen(s: string): string {
54
- return s.replace(/\s*\(.*\)/, '');
55
- }
56
-
57
- // Compact spec for cards: short fuel/gear labels so all five values fit ONE line
58
- // without clipping.
59
- const FUEL_SHORT: Record<string, string> = {
60
- 'Plug-in-Hybrid': 'Hybrid',
61
- Benzin: 'Benzin',
62
- Diesel: 'Diesel',
63
- Elektro: 'Elektro',
64
- };
65
- const GEAR_SHORT: Record<string, string> = {
66
- Automatik: 'Automatik',
67
- Schaltgetriebe: 'Manuell',
68
- };
69
-
70
- /** five compact spec values for the grid card's one-line spec strip. */
71
- export function cardSpec(car: AutobahnCar): string[] {
72
- const fuel = stripParen(car.fuel);
73
- return [
74
- fmtKm(car.km),
75
- car.reg,
76
- stripParen(car.power),
77
- FUEL_SHORT[fuel] || fuel,
78
- GEAR_SHORT[car.gear] || car.gear,
79
- ];
80
- }
81
-
82
- export interface SpecLineProps {
83
- items: string[];
84
- size?: number;
85
- /** never wrap — clip overflow with ellipsis (single line). */
86
- oneLine?: boolean;
87
- }
88
-
89
- /** Compact pipe-separated spec line (AutoScout pattern). */
90
- export const SpecLine: React.FunctionComponent<SpecLineProps> = ({ items, size = 12.5, oneLine = false }) => (
91
- <div
92
- style={{
93
- display: 'flex',
94
- flexWrap: oneLine ? 'nowrap' : 'wrap',
95
- alignItems: 'center',
96
- gap: '2px 8px',
97
- fontSize: size,
98
- color: 'var(--md-on-surface-variant)',
99
- ...(oneLine ? { overflow: 'hidden', whiteSpace: 'nowrap' } : {}),
100
- }}
101
- >
102
- {items.map((v, i) => (
103
- <React.Fragment key={i}>
104
- {i > 0 && <span style={{ color: 'var(--md-outline-variant)', flex: 'none' }}>·</span>}
105
- <span style={oneLine ? { whiteSpace: 'nowrap' } : undefined}>{v}</span>
106
- </React.Fragment>
107
- ))}
108
- </div>
109
- );
110
-
111
- export interface PriceBlockProps {
112
- car: AutobahnCar;
113
- align?: 'left' | 'right';
114
- t: TranslationFunction;
115
- }
116
-
117
- /** Price block — rate-first (monthly is the lead), purchase price secondary. */
118
- export const PriceBlock: React.FunctionComponent<PriceBlockProps> = ({ car, align = 'left', t }) => {
119
- const showStrike = car.savings != null && car.savings > 600 && car.listPrice != null;
120
- return (
121
- <div style={{ textAlign: align }}>
122
- <div
123
- style={{
124
- display: 'flex',
125
- alignItems: 'baseline',
126
- gap: 5,
127
- justifyContent: align === 'right' ? 'flex-end' : 'flex-start',
128
- }}
129
- >
130
- <span
131
- className="num"
132
- style={{
133
- fontWeight: 700,
134
- fontSize: 26,
135
- color: 'var(--md-primary)',
136
- letterSpacing: '-.6px',
137
- whiteSpace: 'nowrap',
138
- }}
139
- >
140
- {fmtRate(car.monthly)} €
141
- </span>
142
- <span className="md-label-sm">{t('autobahn:card.price.perMonth')}</span>
143
- </div>
144
- <div
145
- className="md-label-sm"
146
- style={{
147
- marginTop: 1,
148
- display: 'flex',
149
- flexWrap: 'wrap',
150
- gap: '0 6px',
151
- justifyContent: align === 'right' ? 'flex-end' : 'flex-start',
152
- }}
153
- >
154
- <span style={{ whiteSpace: 'nowrap' }}>
155
- {t('autobahn:card.price.purchasePrice')}{' '}
156
- <b style={{ color: 'var(--md-on-surface)' }}>{car.price.toLocaleString('de-DE')} €</b>
157
- </span>
158
- {showStrike && (
159
- <span
160
- style={{
161
- color: 'var(--md-on-surface-variant)',
162
- textDecoration: 'line-through',
163
- whiteSpace: 'nowrap',
164
- }}
165
- >
166
- {car.listPrice!.toLocaleString('de-DE')} €
167
- </span>
168
- )}
169
- </div>
170
- </div>
171
- );
172
- };
173
-
174
- export interface DropChipProps {
175
- /** real price reduction in EUR; when undefined the chip renders nothing. */
176
- amount?: number;
177
- t: TranslationFunction;
178
- }
179
-
180
- /**
181
- * Price-drop chip — a REAL reduction on this car. White pill so it doesn't
182
- * compete with the solid green rating chip. Renders nothing when there is no
183
- * drop (we never fabricate a reduction).
184
- */
185
- export const DropChip: React.FunctionComponent<DropChipProps> = ({ amount, t }) => {
186
- if (amount == null) {
187
- return null;
188
- }
189
- return (
190
- <span
191
- style={{
192
- display: 'inline-flex',
193
- alignItems: 'center',
194
- gap: 3,
195
- height: 22,
196
- padding: '0 8px',
197
- borderRadius: 'var(--md-r-full)',
198
- background: 'rgba(255,255,255,.94)',
199
- color: 'var(--md-good)',
200
- fontSize: 10.5,
201
- fontWeight: 700,
202
- boxShadow: 'var(--md-e1)',
203
- whiteSpace: 'nowrap',
204
- }}
205
- >
206
- <Icon name="trending-down" size={12} stroke={2.4} color="var(--md-good)" />
207
- {t('autobahn:card.price.priceDropAmount', { amount: amount.toLocaleString('de-DE') })}
208
- </span>
209
- );
210
- };
211
-
212
- /** shared deal-badge pill style (NEU/drop/percent/zero-down all share the same compact shape). */
213
- const dealPill: React.CSSProperties = {
214
- display: 'inline-flex',
215
- alignItems: 'center',
216
- height: 22,
217
- padding: '0 8px',
218
- borderRadius: 'var(--md-r-full)',
219
- fontSize: 10.5,
220
- fontWeight: 700,
221
- boxShadow: 'var(--md-e1)',
222
- whiteSpace: 'nowrap',
223
- };
224
-
225
- /** Percent price-drop chip (−X%). Red pill — pairs with DropChip. Renders nothing without a real pct. */
226
- export const PercentChip: React.FunctionComponent<{ pct?: number }> = ({ pct }) => {
227
- if (pct == null || pct <= 0) return null;
228
- return <span style={{ ...dealPill, background: 'var(--md-error)', color: '#fff' }}>−{pct}%</span>;
229
- };
230
-
231
- /**
232
- * Zero-down-payment chip (offer.showDownPayment). Cyan pill. Spells out "0 € Anzahlung" where
233
- * there is room (grid cards / wide image) and uses the compact "0 € Anz." on the narrow list-card
234
- * image, so the badge row always stays on ONE line on both desktop and mobile.
235
- */
236
- export const ZeroDownChip: React.FunctionComponent<{ show?: boolean; compact?: boolean; t: TranslationFunction }> = ({
237
- show,
238
- compact,
239
- t,
240
- }) => {
241
- if (!show) return null;
242
- return (
243
- <span style={{ ...dealPill, background: 'var(--md-accent-container)', color: 'var(--md-on-accent-container)' }}>
244
- {compact ? t('autobahn:card.price.zeroDownCompact') : t('autobahn:card.price.zeroDown')}
245
- </span>
246
- );
247
- };
248
-
249
- interface InlineClsProps {
250
- /** CO₂ class letter, e.g. 'B'. */
251
- c: string;
252
- }
253
-
254
- /** Small inline colored CO₂-class letter (keeps EnVKV line a fixed height). */
255
- const InlineCls: React.FunctionComponent<InlineClsProps> = ({ c }) => {
256
- const i = Math.max(0, CO2_CLASSES.indexOf(c as (typeof CO2_CLASSES)[number]));
257
- const color = CO2_COLORS[i] || 'var(--md-outline)';
258
- return (
259
- <span
260
- style={{
261
- display: 'inline-flex',
262
- width: 14,
263
- height: 14,
264
- borderRadius: 3,
265
- background: color,
266
- color: '#fff',
267
- fontSize: 9.5,
268
- fontWeight: 800,
269
- alignItems: 'center',
270
- justifyContent: 'center',
271
- verticalAlign: '-2px',
272
- margin: '0 1px',
273
- }}
274
- >
275
- {c}
276
- </span>
277
- );
278
- };
279
-
280
- export interface EcoLineProps {
281
- car: AutobahnCar;
282
- style?: React.CSSProperties;
283
- t: TranslationFunction;
284
- }
285
-
286
- /**
287
- * Pkw-EnVKV legal line — full consumption + CO₂ + class. REQUIRED on every
288
- * German car ad and must stay visible. Quiet fine-print footnote with a fixed
289
- * min-height so all cards stay the same height. Handles the PHEV dual-figure
290
- * variant when a `phev` block is present.
291
- */
292
- export const EcoLine: React.FunctionComponent<EcoLineProps> = ({ car, style, t }) => {
293
- const wrap: React.CSSProperties = {
294
- borderTop: '1px solid var(--md-outline-variant)',
295
- paddingTop: 8,
296
- minHeight: 41,
297
- fontSize: 11,
298
- lineHeight: 1.5,
299
- color: 'var(--md-on-surface-variant)',
300
- ...style,
301
- };
302
- if (car.phev) {
303
- const p = car.phev;
304
- return (
305
- <div style={wrap}>
306
- {p.consEl}{' '}
307
- {t('autobahn:card.eco.phevConsumptionLine', {
308
- consFuel: p.consFuel,
309
- consDis: p.consDis,
310
- co2w: p.co2w,
311
- co2classW: p.co2classW,
312
- co2classD: p.co2classD,
313
- })}
314
- </div>
315
- );
316
- }
317
- return (
318
- <div style={wrap}>
319
- {t('autobahn:card.eco.consumptionLine', { cons: car.cons, co2: car.co2, co2class: car.co2class })}
320
- </div>
321
- );
322
- };
323
-
324
- export interface PricePathsProps {
325
- car: AutobahnCar;
326
- t: TranslationFunction;
327
- }
328
-
329
- /** Map the AutobahnCar rating tone → meter segment index (0 best … 4 worst). */
330
- const TONE_TO_TIER: Record<string, number> = { top: 0, good: 1, fair: 2, raised: 3, high: 4 };
331
-
332
- /**
333
- * Segmented Preisbewertung meter + label. Extracted from PricePaths so the SRP price
334
- * column (Option A layout) can pin it to the BOTTOM of the column, separate from the
335
- * grouped price figures at the top. Renders nothing when there is no rating/band
336
- * (needs-data: we never draw a fake market position).
337
- */
338
- export const PriceMeter: React.FunctionComponent<{ car: AutobahnCar; t: TranslationFunction }> = ({ car, t }) => {
339
- const hasMarket =
340
- car.marketLow != null && car.marketAvg != null && car.marketHigh != null && car.marketHigh > car.marketLow;
341
- const seg = (tier: number) => (
342
- <div className="pp-meter">
343
- {[0, 1, 2, 3, 4].map((s) => (
344
- <span key={s} className="pp-seg" style={{ background: TIER_COLORS[s], opacity: s === tier ? 1 : 0.26 }} />
345
- ))}
346
- </div>
347
- );
348
- if (hasMarket) {
349
- const delta = car.marketAvg! - car.price;
350
- const good = delta > 150;
351
- const mpos = Math.max(0, Math.min(1, (car.price - car.marketLow!) / (car.marketHigh! - car.marketLow!)));
352
- return (
353
- <div className="pp-meter-block">
354
- {seg(Math.round(mpos * 4))}
355
- <span className={'pp-mlabel' + (good ? ' pp-mlabel--good' : '')}>
356
- {good
357
- ? t('autobahn:card.pricing.belowMarket', { delta: delta.toLocaleString('de-DE') })
358
- : t('autobahn:card.pricing.marketPrice')}
359
- </span>
360
- </div>
361
- );
362
- }
363
- if (car.rating && TONE_TO_TIER[car.rating] != null) {
364
- // No market BAND yet, but the real Preisbewertung tier (same signal as the rating chip)
365
- // drives the segmented position meter. Real data, not faked.
366
- const tier = TONE_TO_TIER[car.rating];
367
- return (
368
- <div className="pp-meter-block">
369
- {seg(tier)}
370
- <span className={'pp-mlabel' + (tier <= 1 ? ' pp-mlabel--good' : '')}>
371
- {TIER_KEYS[tier] ? t('autobahn:tier.' + TIER_KEYS[tier]) : t('autobahn:card.pricing.marketPrice')}
372
- </span>
373
- </div>
374
- );
375
- }
376
- return null;
377
- };
378
-
379
- interface PpRowProps {
380
- /** payment-path label (Finanzierung / Leasing / Kaufen). */
381
- label: string;
382
- /** the figure to show — a monthly rate (money=false) or a full price (money=true). */
383
- value: number;
384
- /** small unit before the figure, e.g. 'mtl.'. */
385
- unit?: string;
386
- /** real previous price to strike through (only ever the genuine list price). */
387
- old?: number | null;
388
- /** the financing row — kept visually dominant (larger). */
389
- focus?: boolean;
390
- /** format as a full euro price (Kaufen) instead of a rounded rate. */
391
- money?: boolean;
392
- }
393
-
394
- /**
395
- * One payment-path row: label (+ a quiet info marker) on the left, the price right-aligned
396
- * with an optional struck-through previous price above it. Even row spacing reproduces the
397
- * production "Finanzierung / Leasing / Kaufen" price table the design references.
398
- */
399
- const PpRow: React.FunctionComponent<PpRowProps> = ({ label, value, unit, old, focus, money }) => (
400
- <div className={'pp-row' + (focus ? ' pp-row--focus' : '')}>
401
- <span className="pp-row-label">
402
- {label}
403
- <Icon name="info" size={13} stroke={1.9} cls="pp-row-i" />
404
- </span>
405
- <span className="pp-row-price">
406
- {old != null && <span className="pp-old">{old.toLocaleString('de-DE')} €</span>}
407
- <span className="pp-now">
408
- {unit && <span className="pp-unit">{unit}</span>}
409
- <b className="num pp-val">{money ? value.toLocaleString('de-DE') : fmtRate(value)} €</b>
410
- </span>
411
- </span>
412
- </div>
413
- );
414
-
415
- /**
416
- * Monthly-rate payment paths (SRP price column, TOP group) — modelled on the legacy design:
417
- * Finanzierung is the hero (eyebrow + big blue rate + its terms line), which both keeps the
418
- * financing focus and FILLS the upper gap with real default-config info (Anzahlung · Laufzeit).
419
- * Leasing follows as a quiet neutral row (with its own terms when the config carries them) and
420
- * is omitted entirely when leasing isn't active. The Kaufen row is rendered separately
421
- * (PriceKauf) below a divider so only the financing rate stands out — no wall of blue prices.
422
- */
423
- export const PricePaths: React.FunctionComponent<PricePathsProps> = ({ car, t }) => {
424
- const hasLease = car.lease != null;
425
- return (
426
- <div className="pricepaths">
427
- <div className="pp-hero">
428
- <div className="pp-eyebrow">{t('autobahn:card.price.financingFrom')}</div>
429
- <div className="pp-hero-rate">
430
- <b className="num pp-hero-val">{fmtRate(car.monthly)} €</b>
431
- <span className="pp-hero-unit">{t('autobahn:card.price.perMonth')}</span>
432
- </div>
433
- <div className="pp-hero-terms">
434
- {t('autobahn:card.price.financeTerms', {
435
- firstInstallment: _finFirstInstallment,
436
- months: _finMonths,
437
- count: _finMonths,
438
- })}
439
- </div>
440
- </div>
441
- {hasLease && (
442
- <div className="pp-lease-row">
443
- <PpRow label={t('autobahn:card.price.leasing')} value={car.lease as number} unit="mtl." />
444
- {_hasLeasTerms && (
445
- <div className="pp-sub-terms">
446
- {t('autobahn:card.price.leaseTerms', { mileage: _leasMileageStr, months: _leasPeriod })}
447
- </div>
448
- )}
449
- </div>
450
- )}
451
- </div>
452
- );
453
- };
454
-
455
- /**
456
- * Kaufen (outright purchase) row — the BOTTOM group, separated from the monthly-rate paths by a
457
- * divider. Quiet/neutral (not blue) and strikes the previous price only on a real list-price
458
- * saving (never a fabricated "was" price).
459
- */
460
- export const PriceKauf: React.FunctionComponent<PricePathsProps> = ({ car, t }) => {
461
- const showStrike = car.savings != null && car.savings > 600 && car.listPrice != null;
462
- return (
463
- <PpRow label={t('autobahn:card.price.buy')} value={car.price} old={showStrike ? (car.listPrice as number) : null} money />
464
- );
465
- };
466
-
467
- export interface PpActivityProps {
468
- car: AutobahnCar;
469
- t: TranslationFunction;
470
- }
471
-
472
- /**
473
- * Buyer-activity cue rendered below the CTA in the listing card.
474
- *
475
- * NEEDS-DATA: needs watchers + views. When either is missing we show the
476
- * 'Daten folgt' marker instead of inventing interest figures.
477
- */
478
- export const PpActivity: React.FunctionComponent<PpActivityProps> = ({ car, t }) => {
479
- // No real watcher/view data (no backend yet) → render nothing rather than a "Daten folgt"
480
- // placeholder that reads as perpetual loading. Wire when UserActionsAPI stats are available.
481
- if (car.watchers == null || car.views == null) return null;
482
- const hrs = 1 + (car.views % 6);
483
- return (
484
- <div className="pp-activity">
485
- <Icon name="eye" size={12} stroke={1.9} />
486
- {t('autobahn:card.activity.watchers', { watchers: car.watchers, hrs, count: car.watchers })}
487
- </div>
488
- );
489
- };
1
+ // Autobahn (auto.de redesign) — car-card helper parts.
2
+ //
3
+ // Typed React 18 + TS port of the helper components from the design kit
4
+ // (docs/redesign/design-source/ui_kits/website/CarCard.jsx). Pure /
5
+ // presentational: every value comes from the `AutobahnCar` prop, there is no
6
+ // store / API / `window` access. The design kit's `window.CO2_CLASSES` /
7
+ // `window.CO2_COLORS` globals are replaced by the shared autobahn constants.
8
+ //
9
+ // These render correctly only inside a `<div className="md3">` subtree (the
10
+ // `.pricepaths`, `.pp-*`, `.specstrip`, `.imglabel` … classes are scoped there).
11
+ //
12
+ // NEEDS-DATA discipline (the point of the ticket): wherever the design showed a
13
+ // figure we have no real source for, these helpers render the NEEDS_DATA_LABEL
14
+ // ('Daten folgt') marker instead of inventing a number — see PricePaths'
15
+ // market band and PpActivity. DropChip renders nothing when there is no drop.
16
+
17
+ import React from 'react';
18
+ import { TranslationFunction } from '../types';
19
+ import { defaultConfig } from '@bytebrand/fe-financing';
20
+
21
+ import { Icon } from '../ui';
22
+ import { CO2_CLASSES, CO2_COLORS, TIER_COLORS, TIER_KEYS } from '../constants';
23
+ import { AutobahnCar } from './types';
24
+
25
+ // Default financing/leasing terms shown under the rate (the SRP card has no per-car selector, so
26
+ // these are the same default config the displayed rate is computed with — consistent, not invented).
27
+ const _finCfg = (defaultConfig as any).financing || {};
28
+ const _leasCfg = (defaultConfig as any).leasing || {};
29
+ /** financing terms inputs (rendered via t in PricePaths), e.g. "0 € Anzahlung · 48 Monate Laufzeit". */
30
+ const _finFirstInstallment = (_finCfg.firstInstallment || 0).toLocaleString('de-DE');
31
+ const _finMonths = _finCfg.rawPaybackPeriod || _finCfg.paybackPeriod || 48;
32
+ /** leasing terms inputs (only when the config carries mileage + period), e.g. "10.000 km/Jahr · 48 Monate". */
33
+ const _leasPeriod = _leasCfg.rawPaybackPeriod || _leasCfg.paybackPeriod;
34
+ const _leasMileage = _leasCfg.annualMileage || _leasCfg.mileage;
35
+ const _hasLeasTerms = Boolean(_leasMileage && _leasPeriod);
36
+ const _leasMileageStr = _leasMileage ? Number(_leasMileage).toLocaleString('de-DE') : '';
37
+
38
+ /** mileage → 'X.XXX km' (de-DE grouping). */
39
+ export function fmtKm(n: number): string {
40
+ return n.toLocaleString('de-DE') + ' km';
41
+ }
42
+
43
+ /**
44
+ * Monthly rate → de-DE integer euro string (e.g. 402.12 → "402"). Rates are shown as whole
45
+ * euros like the legacy card ("271 €"); a raw float printed directly rendered as "402.12 €",
46
+ * which a German reader parses as 402.120 — fixed here with rounding + de-DE grouping.
47
+ */
48
+ export function fmtRate(n: number): string {
49
+ return Math.round(n).toLocaleString('de-DE');
50
+ }
51
+
52
+ /** strip a trailing parenthetical, e.g. '110 kW (150 PS)' → '110 kW'. */
53
+ function stripParen(s: string): string {
54
+ return s.replace(/\s*\(.*\)/, '');
55
+ }
56
+
57
+ // Compact spec for cards: short fuel/gear labels so all five values fit ONE line
58
+ // without clipping.
59
+ const FUEL_SHORT: Record<string, string> = {
60
+ 'Plug-in-Hybrid': 'Hybrid',
61
+ Benzin: 'Benzin',
62
+ Diesel: 'Diesel',
63
+ Elektro: 'Elektro',
64
+ };
65
+ const GEAR_SHORT: Record<string, string> = {
66
+ Automatik: 'Automatik',
67
+ Schaltgetriebe: 'Manuell',
68
+ };
69
+
70
+ /** five compact spec values for the grid card's one-line spec strip. */
71
+ export function cardSpec(car: AutobahnCar): string[] {
72
+ const fuel = stripParen(car.fuel);
73
+ return [
74
+ fmtKm(car.km),
75
+ car.reg,
76
+ stripParen(car.power),
77
+ FUEL_SHORT[fuel] || fuel,
78
+ GEAR_SHORT[car.gear] || car.gear,
79
+ ];
80
+ }
81
+
82
+ export interface SpecLineProps {
83
+ items: string[];
84
+ size?: number;
85
+ /** never wrap — clip overflow with ellipsis (single line). */
86
+ oneLine?: boolean;
87
+ }
88
+
89
+ /** Compact pipe-separated spec line (AutoScout pattern). */
90
+ export const SpecLine: React.FunctionComponent<SpecLineProps> = ({ items, size = 12.5, oneLine = false }) => (
91
+ <div
92
+ style={{
93
+ display: 'flex',
94
+ flexWrap: oneLine ? 'nowrap' : 'wrap',
95
+ alignItems: 'center',
96
+ gap: '2px 8px',
97
+ fontSize: size,
98
+ color: 'var(--md-on-surface-variant)',
99
+ ...(oneLine ? { overflow: 'hidden', whiteSpace: 'nowrap' } : {}),
100
+ }}
101
+ >
102
+ {items.map((v, i) => (
103
+ <React.Fragment key={i}>
104
+ {i > 0 && <span style={{ color: 'var(--md-outline-variant)', flex: 'none' }}>·</span>}
105
+ <span style={oneLine ? { whiteSpace: 'nowrap' } : undefined}>{v}</span>
106
+ </React.Fragment>
107
+ ))}
108
+ </div>
109
+ );
110
+
111
+ export interface PriceBlockProps {
112
+ car: AutobahnCar;
113
+ align?: 'left' | 'right';
114
+ t: TranslationFunction;
115
+ }
116
+
117
+ /** Price block — rate-first (monthly is the lead), purchase price secondary. */
118
+ export const PriceBlock: React.FunctionComponent<PriceBlockProps> = ({ car, align = 'left', t }) => {
119
+ const showStrike = car.savings != null && car.savings > 600 && car.listPrice != null;
120
+ return (
121
+ <div style={{ textAlign: align }}>
122
+ <div
123
+ style={{
124
+ display: 'flex',
125
+ alignItems: 'baseline',
126
+ gap: 5,
127
+ justifyContent: align === 'right' ? 'flex-end' : 'flex-start',
128
+ }}
129
+ >
130
+ <span
131
+ className="num"
132
+ style={{
133
+ fontWeight: 700,
134
+ fontSize: 26,
135
+ color: 'var(--md-primary)',
136
+ letterSpacing: '-.6px',
137
+ whiteSpace: 'nowrap',
138
+ }}
139
+ >
140
+ {fmtRate(car.monthly)} €
141
+ </span>
142
+ <span className="md-label-sm">{t('autobahn:card.price.perMonth')}</span>
143
+ </div>
144
+ <div
145
+ className="md-label-sm"
146
+ style={{
147
+ marginTop: 1,
148
+ display: 'flex',
149
+ flexWrap: 'wrap',
150
+ gap: '0 6px',
151
+ justifyContent: align === 'right' ? 'flex-end' : 'flex-start',
152
+ }}
153
+ >
154
+ <span style={{ whiteSpace: 'nowrap' }}>
155
+ {t('autobahn:card.price.purchasePrice')}{' '}
156
+ <b style={{ color: 'var(--md-on-surface)' }}>{car.price.toLocaleString('de-DE')} €</b>
157
+ </span>
158
+ {showStrike && (
159
+ <span
160
+ style={{
161
+ color: 'var(--md-on-surface-variant)',
162
+ textDecoration: 'line-through',
163
+ whiteSpace: 'nowrap',
164
+ }}
165
+ >
166
+ {car.listPrice!.toLocaleString('de-DE')} €
167
+ </span>
168
+ )}
169
+ </div>
170
+ </div>
171
+ );
172
+ };
173
+
174
+ export interface DropChipProps {
175
+ /** real price reduction in EUR; when undefined the chip renders nothing. */
176
+ amount?: number;
177
+ t: TranslationFunction;
178
+ }
179
+
180
+ /**
181
+ * Price-drop chip — a REAL reduction on this car. White pill so it doesn't
182
+ * compete with the solid green rating chip. Renders nothing when there is no
183
+ * drop (we never fabricate a reduction).
184
+ */
185
+ export const DropChip: React.FunctionComponent<DropChipProps> = ({ amount, t }) => {
186
+ if (amount == null) {
187
+ return null;
188
+ }
189
+ return (
190
+ <span
191
+ style={{
192
+ display: 'inline-flex',
193
+ alignItems: 'center',
194
+ gap: 3,
195
+ height: 22,
196
+ padding: '0 8px',
197
+ borderRadius: 'var(--md-r-full)',
198
+ background: 'rgba(255,255,255,.94)',
199
+ color: 'var(--md-good)',
200
+ fontSize: 10.5,
201
+ fontWeight: 700,
202
+ boxShadow: 'var(--md-e1)',
203
+ whiteSpace: 'nowrap',
204
+ }}
205
+ >
206
+ <Icon name="trending-down" size={12} stroke={2.4} color="var(--md-good)" />
207
+ {t('autobahn:card.price.priceDropAmount', { amount: amount.toLocaleString('de-DE') })}
208
+ </span>
209
+ );
210
+ };
211
+
212
+ /** shared deal-badge pill style (NEU/drop/percent/zero-down all share the same compact shape). */
213
+ const dealPill: React.CSSProperties = {
214
+ display: 'inline-flex',
215
+ alignItems: 'center',
216
+ height: 22,
217
+ padding: '0 8px',
218
+ borderRadius: 'var(--md-r-full)',
219
+ fontSize: 10.5,
220
+ fontWeight: 700,
221
+ boxShadow: 'var(--md-e1)',
222
+ whiteSpace: 'nowrap',
223
+ };
224
+
225
+ /** Percent price-drop chip (−X%). Red pill — pairs with DropChip. Renders nothing without a real pct. */
226
+ export const PercentChip: React.FunctionComponent<{ pct?: number }> = ({ pct }) => {
227
+ if (pct == null || pct <= 0) return null;
228
+ return <span style={{ ...dealPill, background: 'var(--md-error)', color: '#fff' }}>−{pct}%</span>;
229
+ };
230
+
231
+ /**
232
+ * Zero-down-payment chip (offer.showDownPayment). Cyan pill. Spells out "0 € Anzahlung" where
233
+ * there is room (grid cards / wide image) and uses the compact "0 € Anz." on the narrow list-card
234
+ * image, so the badge row always stays on ONE line on both desktop and mobile.
235
+ */
236
+ export const ZeroDownChip: React.FunctionComponent<{ show?: boolean; compact?: boolean; t: TranslationFunction }> = ({
237
+ show,
238
+ compact,
239
+ t,
240
+ }) => {
241
+ if (!show) return null;
242
+ return (
243
+ <span style={{ ...dealPill, background: 'var(--md-accent-container)', color: 'var(--md-on-accent-container)' }}>
244
+ {compact ? t('autobahn:card.price.zeroDownCompact') : t('autobahn:card.price.zeroDown')}
245
+ </span>
246
+ );
247
+ };
248
+
249
+ interface InlineClsProps {
250
+ /** CO₂ class letter, e.g. 'B'. */
251
+ c: string;
252
+ }
253
+
254
+ /** Small inline colored CO₂-class letter (keeps EnVKV line a fixed height). */
255
+ const InlineCls: React.FunctionComponent<InlineClsProps> = ({ c }) => {
256
+ const i = Math.max(0, CO2_CLASSES.indexOf(c as (typeof CO2_CLASSES)[number]));
257
+ const color = CO2_COLORS[i] || 'var(--md-outline)';
258
+ return (
259
+ <span
260
+ style={{
261
+ display: 'inline-flex',
262
+ width: 14,
263
+ height: 14,
264
+ borderRadius: 3,
265
+ background: color,
266
+ color: '#fff',
267
+ fontSize: 9.5,
268
+ fontWeight: 800,
269
+ alignItems: 'center',
270
+ justifyContent: 'center',
271
+ verticalAlign: '-2px',
272
+ margin: '0 1px',
273
+ }}
274
+ >
275
+ {c}
276
+ </span>
277
+ );
278
+ };
279
+
280
+ export interface EcoLineProps {
281
+ car: AutobahnCar;
282
+ style?: React.CSSProperties;
283
+ t: TranslationFunction;
284
+ }
285
+
286
+ /**
287
+ * Pkw-EnVKV legal line — full consumption + CO₂ + class. REQUIRED on every
288
+ * German car ad and must stay visible. Quiet fine-print footnote with a fixed
289
+ * min-height so all cards stay the same height. Handles the PHEV dual-figure
290
+ * variant when a `phev` block is present.
291
+ */
292
+ export const EcoLine: React.FunctionComponent<EcoLineProps> = ({ car, style, t }) => {
293
+ const wrap: React.CSSProperties = {
294
+ borderTop: '1px solid var(--md-outline-variant)',
295
+ paddingTop: 8,
296
+ minHeight: 41,
297
+ fontSize: 11,
298
+ lineHeight: 1.5,
299
+ color: 'var(--md-on-surface-variant)',
300
+ ...style,
301
+ };
302
+ if (car.phev) {
303
+ const p = car.phev;
304
+ return (
305
+ <div style={wrap}>
306
+ {p.consEl}{' '}
307
+ {t('autobahn:card.eco.phevConsumptionLine', {
308
+ consFuel: p.consFuel,
309
+ consDis: p.consDis,
310
+ co2w: p.co2w,
311
+ co2classW: p.co2classW,
312
+ co2classD: p.co2classD,
313
+ })}
314
+ </div>
315
+ );
316
+ }
317
+ return (
318
+ <div style={wrap}>
319
+ {t('autobahn:card.eco.consumptionLine', { cons: car.cons, co2: car.co2, co2class: car.co2class })}
320
+ </div>
321
+ );
322
+ };
323
+
324
+ export interface PricePathsProps {
325
+ car: AutobahnCar;
326
+ t: TranslationFunction;
327
+ }
328
+
329
+ /** Map the AutobahnCar rating tone → meter segment index (0 best … 4 worst). */
330
+ const TONE_TO_TIER: Record<string, number> = { top: 0, good: 1, fair: 2, raised: 3, high: 4 };
331
+
332
+ /**
333
+ * Segmented Preisbewertung meter + label. Extracted from PricePaths so the SRP price
334
+ * column (Option A layout) can pin it to the BOTTOM of the column, separate from the
335
+ * grouped price figures at the top. Renders nothing when there is no rating/band
336
+ * (needs-data: we never draw a fake market position).
337
+ */
338
+ export const PriceMeter: React.FunctionComponent<{ car: AutobahnCar; t: TranslationFunction }> = ({ car, t }) => {
339
+ const hasMarket =
340
+ car.marketLow != null && car.marketAvg != null && car.marketHigh != null && car.marketHigh > car.marketLow;
341
+ const seg = (tier: number) => (
342
+ <div className="pp-meter">
343
+ {[0, 1, 2, 3, 4].map((s) => (
344
+ <span key={s} className="pp-seg" style={{ background: TIER_COLORS[s], opacity: s === tier ? 1 : 0.26 }} />
345
+ ))}
346
+ </div>
347
+ );
348
+ if (hasMarket) {
349
+ const delta = car.marketAvg! - car.price;
350
+ const good = delta > 150;
351
+ const mpos = Math.max(0, Math.min(1, (car.price - car.marketLow!) / (car.marketHigh! - car.marketLow!)));
352
+ return (
353
+ <div className="pp-meter-block">
354
+ {seg(Math.round(mpos * 4))}
355
+ <span className={'pp-mlabel' + (good ? ' pp-mlabel--good' : '')}>
356
+ {good
357
+ ? t('autobahn:card.pricing.belowMarket', { delta: delta.toLocaleString('de-DE') })
358
+ : t('autobahn:card.pricing.marketPrice')}
359
+ </span>
360
+ </div>
361
+ );
362
+ }
363
+ if (car.rating && TONE_TO_TIER[car.rating] != null) {
364
+ // No market BAND yet, but the real Preisbewertung tier (same signal as the rating chip)
365
+ // drives the segmented position meter. Real data, not faked.
366
+ const tier = TONE_TO_TIER[car.rating];
367
+ return (
368
+ <div className="pp-meter-block">
369
+ {seg(tier)}
370
+ <span className={'pp-mlabel' + (tier <= 1 ? ' pp-mlabel--good' : '')}>
371
+ {TIER_KEYS[tier] ? t('autobahn:tier.' + TIER_KEYS[tier]) : t('autobahn:card.pricing.marketPrice')}
372
+ </span>
373
+ </div>
374
+ );
375
+ }
376
+ return null;
377
+ };
378
+
379
+ interface PpRowProps {
380
+ /** payment-path label (Finanzierung / Leasing / Kaufen). */
381
+ label: string;
382
+ /** the figure to show — a monthly rate (money=false) or a full price (money=true). */
383
+ value: number;
384
+ /** small unit before the figure, e.g. 'mtl.'. */
385
+ unit?: string;
386
+ /** real previous price to strike through (only ever the genuine list price). */
387
+ old?: number | null;
388
+ /** the financing row — kept visually dominant (larger). */
389
+ focus?: boolean;
390
+ /** format as a full euro price (Kaufen) instead of a rounded rate. */
391
+ money?: boolean;
392
+ }
393
+
394
+ /**
395
+ * One payment-path row: label (+ a quiet info marker) on the left, the price right-aligned
396
+ * with an optional struck-through previous price above it. Even row spacing reproduces the
397
+ * production "Finanzierung / Leasing / Kaufen" price table the design references.
398
+ */
399
+ const PpRow: React.FunctionComponent<PpRowProps> = ({ label, value, unit, old, focus, money }) => (
400
+ <div className={'pp-row' + (focus ? ' pp-row--focus' : '')}>
401
+ <span className="pp-row-label">
402
+ {label}
403
+ <Icon name="info" size={13} stroke={1.9} cls="pp-row-i" />
404
+ </span>
405
+ <span className="pp-row-price">
406
+ {old != null && <span className="pp-old">{old.toLocaleString('de-DE')} €</span>}
407
+ <span className="pp-now">
408
+ {unit && <span className="pp-unit">{unit}</span>}
409
+ <b className="num pp-val">{money ? value.toLocaleString('de-DE') : fmtRate(value)} €</b>
410
+ </span>
411
+ </span>
412
+ </div>
413
+ );
414
+
415
+ /**
416
+ * Monthly-rate payment paths (SRP price column, TOP group) — modelled on the legacy design:
417
+ * Finanzierung is the hero (eyebrow + big blue rate + its terms line), which both keeps the
418
+ * financing focus and FILLS the upper gap with real default-config info (Anzahlung · Laufzeit).
419
+ * Leasing follows as a quiet neutral row (with its own terms when the config carries them) and
420
+ * is omitted entirely when leasing isn't active. The Kaufen row is rendered separately
421
+ * (PriceKauf) below a divider so only the financing rate stands out — no wall of blue prices.
422
+ */
423
+ export const PricePaths: React.FunctionComponent<PricePathsProps> = ({ car, t }) => {
424
+ const hasLease = car.lease != null;
425
+ return (
426
+ <div className="pricepaths">
427
+ <div className="pp-hero">
428
+ <div className="pp-eyebrow">{t('autobahn:card.price.financingFrom')}</div>
429
+ <div className="pp-hero-rate">
430
+ <b className="num pp-hero-val">{fmtRate(car.monthly)} €</b>
431
+ <span className="pp-hero-unit">{t('autobahn:card.price.perMonth')}</span>
432
+ </div>
433
+ <div className="pp-hero-terms">
434
+ {t('autobahn:card.price.financeTerms', {
435
+ firstInstallment: _finFirstInstallment,
436
+ months: _finMonths,
437
+ count: _finMonths,
438
+ })}
439
+ </div>
440
+ </div>
441
+ {hasLease && (
442
+ <div className="pp-lease-row">
443
+ <PpRow label={t('autobahn:card.price.leasing')} value={car.lease as number} unit="mtl." />
444
+ {_hasLeasTerms && (
445
+ <div className="pp-sub-terms">
446
+ {t('autobahn:card.price.leaseTerms', { mileage: _leasMileageStr, months: _leasPeriod })}
447
+ </div>
448
+ )}
449
+ </div>
450
+ )}
451
+ </div>
452
+ );
453
+ };
454
+
455
+ /**
456
+ * Kaufen (outright purchase) row — the BOTTOM group, separated from the monthly-rate paths by a
457
+ * divider. Quiet/neutral (not blue) and strikes the previous price only on a real list-price
458
+ * saving (never a fabricated "was" price).
459
+ */
460
+ export const PriceKauf: React.FunctionComponent<PricePathsProps> = ({ car, t }) => {
461
+ const showStrike = car.savings != null && car.savings > 600 && car.listPrice != null;
462
+ return (
463
+ <PpRow label={t('autobahn:card.price.buy')} value={car.price} old={showStrike ? (car.listPrice as number) : null} money />
464
+ );
465
+ };
466
+
467
+ export interface PpActivityProps {
468
+ car: AutobahnCar;
469
+ t: TranslationFunction;
470
+ }
471
+
472
+ /**
473
+ * Buyer-activity cue rendered below the CTA in the listing card.
474
+ *
475
+ * NEEDS-DATA: needs watchers + views. When either is missing we show the
476
+ * 'Daten folgt' marker instead of inventing interest figures.
477
+ */
478
+ export const PpActivity: React.FunctionComponent<PpActivityProps> = ({ car, t }) => {
479
+ // No real watcher/view data (no backend yet) → render nothing rather than a "Daten folgt"
480
+ // placeholder that reads as perpetual loading. Wire when UserActionsAPI stats are available.
481
+ if (car.watchers == null || car.views == null) return null;
482
+ const hrs = 1 + (car.views % 6);
483
+ return (
484
+ <div className="pp-activity">
485
+ <Icon name="eye" size={12} stroke={1.9} />
486
+ {t('autobahn:card.activity.watchers', { watchers: car.watchers, hrs, count: car.watchers })}
487
+ </div>
488
+ );
489
+ };
490
+
491
+ export interface GalleryBadgesProps {
492
+ car: AutobahnCar;
493
+ t: TranslationFunction;
494
+ }
495
+
496
+ /**
497
+ * Trust/activity pill row rendered under the gallery on the SRP list card — mirrors the mobile
498
+ * VDP gallery header (availability · views · favorites · Geprüft).
499
+ *
500
+ * PM decision (2026-07-10, Viktoriia — "this logic already exists on prod"): the row is all-or-
501
+ * nothing. A missing or zero view/favorite count is NOT shown as "0×" — the whole row (including
502
+ * the always-on availability/Geprüft pills) is hidden rather than reading as an empty/broken card.
503
+ * It only appears once BOTH counts are real and positive.
504
+ */
505
+ export const GalleryBadges: React.FunctionComponent<GalleryBadgesProps> = ({ car, t }) => {
506
+ if (!car.viewsCount || !car.favoritesCount) return null;
507
+ return (
508
+ <div className="gallery-badges">
509
+ {car.availability && (
510
+ <span className="gallery-pill">
511
+ <Icon name="circle-check" size={16} stroke={2} color="var(--md-good)" />
512
+ {car.availability}
513
+ </span>
514
+ )}
515
+ <span className="gallery-pill">
516
+ <Icon name="eye" size={16} stroke={1.9} />
517
+ {t('autobahn:card.activity.viewsCount', { count: car.viewsCount })}
518
+ </span>
519
+ <span className="gallery-pill">
520
+ <Icon name="heart" size={16} stroke={1.9} />
521
+ {t('autobahn:card.activity.favoritesCount', { count: car.favoritesCount })}
522
+ </span>
523
+ <span className="gallery-pill">
524
+ <Icon name="shield-check" size={16} stroke={1.9} />
525
+ {t('autobahn:card.trust.checked')}
526
+ </span>
527
+ </div>
528
+ );
529
+ };