@bytebrand/fe-ui-core-autobahn 1.0.107 → 1.0.108

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.
package/cards/CarRow.tsx CHANGED
@@ -250,7 +250,6 @@ const CarRow: React.FunctionComponent<CarRowProps> = ({
250
250
  {car.rating && (
251
251
  <StatChip tone={ratingTone(car.rating)} icon={ratingTone(car.rating) === 'good' ? 'check' : 'minus'}>
252
252
  {t('autobahn:tier.' + car.rating)}
253
- {ratingTone(car.rating) === 'good' && <sup>4</sup>}
254
253
  </StatChip>
255
254
  )}
256
255
  </div>
@@ -297,7 +296,6 @@ const CarRow: React.FunctionComponent<CarRowProps> = ({
297
296
  {car.rating && (
298
297
  <StatChip tone={ratingTone(car.rating)} icon={ratingTone(car.rating) === 'good' ? 'check' : 'minus'}>
299
298
  {t('autobahn:tier.' + car.rating)}
300
- {ratingTone(car.rating) === 'good' && <sup>4</sup>}
301
299
  </StatChip>
302
300
  )}
303
301
  <div style={{ flex: 1 }}>
@@ -600,7 +600,7 @@ export const PriceHero: React.FunctionComponent<PriceHeroProps> = ({ car, mode,
600
600
  <div className={'pp-hero' + (isMoney ? ' pp-hero--buy' : '')}>
601
601
  <div className="pp-hero-rate">
602
602
  <b className={'num pp-hero-val' + rateLenClass + buyLen6Class}>
603
- {isMoney ? value.toLocaleString('de-DE') : fmtRate(value)} €{isMoney && <sup>1</sup>}
603
+ {isMoney ? value.toLocaleString('de-DE') : fmtRate(value)} €
604
604
  </b>
605
605
  {/* z.B./old-rate/unit grouped in one stacked column beside the hero figure — mirrors
606
606
  the VDP finance-calculator's .fin-rate-unit layout (FinanceCalculator.tsx) exactly.
@@ -900,60 +900,28 @@ interface PpRowProps {
900
900
  focus?: boolean;
901
901
  /** format as a full euro price (Kaufen) instead of a rounded rate. */
902
902
  money?: boolean;
903
- t: TranslationFunction;
904
903
  }
905
904
 
906
905
  /**
907
906
  * One payment-path row: label (+ a quiet info marker) on the left, the price right-aligned
908
907
  * with an optional struck-through previous price above it. Even row spacing reproduces the
909
- * production "Finanzierung / Leasing / Kaufen" price table the design references. The struck
910
- * `old` price gets the same "²" UvpBadge + click-to-open popover as PriceHero's own Kaufen
911
- * old-price (same n, same body/close copy) — one-to-one, not a re-styled variant.
908
+ * production "Finanzierung / Leasing / Kaufen" price table the design references.
912
909
  */
913
- const PpRow: React.FunctionComponent<PpRowProps> = ({ label, value, unit, old, focus, money, t }) => {
914
- const [uvpTooltipOpen, setUvpTooltipOpen] = useState(false);
915
- // 5-plus-digit prices (e.g. 60.248 €) shrink to keep the row from crowding — 4-digit values
916
- // stay at the base size. Same digit-length technique as PriceHero's buyLen6Class.
917
- const valDigits = String(Math.round(value)).length;
918
- const valLenClass = valDigits >= 5 ? ' pp-val--len5' : '';
919
- return (
920
- <div className={'pp-row' + (focus ? ' pp-row--focus' : '')}>
921
- <span className="pp-row-label">
922
- {label}
923
- <Icon name="info" size={13} stroke={1.9} cls="pp-row-i" />
924
- </span>
925
- <span className="pp-row-price">
926
- {old != null && (
927
- <span
928
- className="pp-old"
929
- role="button"
930
- tabIndex={0}
931
- onClick={(e) => {
932
- e.stopPropagation();
933
- setUvpTooltipOpen((v) => !v);
934
- }}
935
- >
936
- {old.toLocaleString('de-DE')} €
937
- <UvpBadge
938
- n={2}
939
- open={uvpTooltipOpen}
940
- onToggle={() => setUvpTooltipOpen((v) => !v)}
941
- onClose={() => setUvpTooltipOpen(false)}
942
- closeLabel={t('autobahn:modal.close')}
943
- body={t('autobahn:card.price.uvpListTooltipBody')}
944
- />
945
- </span>
946
- )}
947
- <span className="pp-now">
948
- {unit && <span className="pp-unit">{unit}</span>}
949
- <b className={'num pp-val' + valLenClass}>
950
- {money ? value.toLocaleString('de-DE') : fmtRate(value)} €{money && <sup>1</sup>}
951
- </b>
952
- </span>
910
+ const PpRow: React.FunctionComponent<PpRowProps> = ({ label, value, unit, old, focus, money }) => (
911
+ <div className={'pp-row' + (focus ? ' pp-row--focus' : '')}>
912
+ <span className="pp-row-label">
913
+ {label}
914
+ <Icon name="info" size={13} stroke={1.9} cls="pp-row-i" />
915
+ </span>
916
+ <span className="pp-row-price">
917
+ {old != null && <span className="pp-old">{old.toLocaleString('de-DE')} €</span>}
918
+ <span className="pp-now">
919
+ {unit && <span className="pp-unit">{unit}</span>}
920
+ <b className="num pp-val">{money ? value.toLocaleString('de-DE') : fmtRate(value)} €</b>
953
921
  </span>
954
- </div>
955
- );
956
- };
922
+ </span>
923
+ </div>
924
+ );
957
925
 
958
926
  /**
959
927
  * Monthly-rate payment paths (SRP price column, TOP group) — modelled on the legacy design:
@@ -1010,7 +978,7 @@ export const PricePaths: React.FunctionComponent<PricePathsProps> = ({ car, t, c
1010
978
  </div>
1011
979
  {hasLease && (
1012
980
  <div className="pp-lease-row">
1013
- <PpRow label={t('autobahn:card.price.leasing')} value={car.lease as number} unit="mtl." t={t} />
981
+ <PpRow label={t('autobahn:card.price.leasing')} value={car.lease as number} unit="mtl." />
1014
982
  {hasLeasTerms && (
1015
983
  <div className="pp-sub-terms">
1016
984
  {/* dedicated keys (not a rework of leaseTerms) so mobile/VDP's own reviewed
@@ -1041,7 +1009,7 @@ export const PricePaths: React.FunctionComponent<PricePathsProps> = ({ car, t, c
1041
1009
  export const PriceKauf: React.FunctionComponent<PricePathsProps> = ({ car, t }) => {
1042
1010
  const showStrike = car.savings != null && car.savings > 600 && car.listPrice != null;
1043
1011
  return (
1044
- <PpRow label={t('autobahn:card.price.buy')} value={car.price} old={showStrike ? (car.listPrice as number) : null} money t={t} />
1012
+ <PpRow label={t('autobahn:card.price.buy')} value={car.price} old={showStrike ? (car.listPrice as number) : null} money />
1045
1013
  );
1046
1014
  };
1047
1015
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytebrand/fe-ui-core-autobahn",
3
- "version": "1.0.107",
3
+ "version": "1.0.108",
4
4
  "description": "auto.de md3 (Autobahn) design system — UI primitives, cards, chrome, VDP modules, theme CSS and locales. Ships raw TypeScript source (like fe-ui-core before it); each consumer's bundler compiles it.",
5
5
  "main": "index.ts",
6
6
  "license": "UNLICENSED",
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@bytebrand/car-schema-selectors": "^2.0.7",
13
- "@bytebrand/fe-financing": "^5.14.16",
13
+ "@bytebrand/fe-financing": "^5.14.17",
14
14
  "classnames": "2.2.6",
15
15
  "clsx": "^2.1.1",
16
16
  "d3-format": "1.4.5",
package/theme/md3.css CHANGED
@@ -55,12 +55,10 @@
55
55
  --md-secondary-container: #e7e9f1;
56
56
  --md-on-secondary-container: #3a4150;
57
57
 
58
- /* price-rating + deal accent (green) — same "good" tier green (TIER_COLORS[0], #168A45) and
59
- 16%-tint background as .fin-eval-pill--good (FinanceCalculator/VdpModules), so the
60
- search-list/VDP-header StatChip and the finance-card rating pill read as the same color. */
58
+ /* price-rating + deal accent (green) */
61
59
  --md-good: #0f7b43;
62
- --md-good-container: color-mix(in srgb, #168a45 16%, transparent);
63
- --md-on-good-container: #168a45;
60
+ --md-good-container: #c8efcf;
61
+ --md-on-good-container: #04391f;
64
62
  --md-warn-container: #fce3b4;
65
63
  --md-on-warn-container: #4a3204;
66
64
  --md-error: #ba1a1a;
@@ -439,16 +437,6 @@ line-height: 31px;
439
437
  background: var(--md-warn-container);
440
438
  color: var(--md-on-warn-container);
441
439
  }
442
- /* "4" footnote (VDP header's "Guter Preis" chip) — .statchip is a flex container like
443
- .fin-eval-pill, so the same position:relative/top lift technique applies, just re-tuned for
444
- this chip's smaller 12px text. */
445
- .md3 .statchip sup {
446
- position: relative;
447
- top: -3px;
448
- left: -3px;
449
- font-size: 8px;
450
- line-height: 8px;
451
- }
452
440
  .md3 .statchip .lucide {
453
441
  width: 14px;
454
442
  height: 14px;
@@ -4515,15 +4503,11 @@ line-height: 31px;
4515
4503
  top: -7px;
4516
4504
  right: -7px;
4517
4505
  }
4518
- /* positioned against .pp-eyebrow (line ~4476) — a tiny (8px text) span, so stretching between
4519
- left/right offsets alone (as this used to do) computed a near-zero box width and forced the
4520
- body text into a tall, narrow, wrapped column. Explicit width, same as the .cc-price/
4521
- .fin-calc-card/.listcard-price .pp-old tooltip elsewhere, fixes that. */
4522
4506
  .md3 .listcard-price .pricepaths .pp-uvp-tooltip {
4523
4507
  position: absolute;
4524
- top: 9px;
4525
- right: -35px;
4526
- width: 281px;
4508
+ top: 6px;
4509
+ right: -18px;
4510
+ left: -18px;
4527
4511
  z-index: 20;
4528
4512
  padding: 10px 12px;
4529
4513
  border-radius: 15px;
@@ -4624,7 +4608,7 @@ line-height: 31px;
4624
4608
  display: flex;
4625
4609
  flex-direction: row;
4626
4610
  align-items: baseline;
4627
- gap: 13px;
4611
+ gap: 8px;
4628
4612
  line-height: 1.08;
4629
4613
  min-width: 0;
4630
4614
  }
@@ -4650,27 +4634,6 @@ line-height: 31px;
4650
4634
  letter-spacing: -0.4px;
4651
4635
  white-space: nowrap;
4652
4636
  }
4653
- /* 5-plus-digit price (e.g. 60.248 €) shrinks so it doesn't crowd the row — 4-digit values keep
4654
- the base 19px above untouched, same digit-length technique as .pp-hero-val--buy-len6/7. */
4655
- .md3 .pp-val.pp-val--len5 {
4656
- font-size: 16px;
4657
- }
4658
- /* Kaufen row's "1" price footnote marker (desktop .pricepaths stacked rows, PpRow money=true
4659
- only) — same small/quiet sup treatment as the card's other footnote markers (.fin-eval-pill
4660
- sup, .fin-rate-main sup, etc.): vertical-align:super does the actual lift, position:relative
4661
- top just fine-tunes it for this specific 19px price size. */
4662
- .md3 .pp-val sup {
4663
- position: relative;
4664
- top: 4px;
4665
- left: 1px;
4666
- vertical-align: super;
4667
- font-family: 'Arial', Helvetica, sans-serif;
4668
- font-style: normal;
4669
- font-weight: 400;
4670
- font-size: 8px;
4671
- line-height: 9px;
4672
- color: #111820;
4673
- }
4674
4637
  /* financing is the ONLY blue, dominant figure — big hero rate */
4675
4638
  .md3 .pp-row--focus .pp-row-label {
4676
4639
  color: var(--md-on-surface);
@@ -4891,22 +4854,13 @@ line-height: 31px;
4891
4854
  color: #0e2238;
4892
4855
  margin-bottom: 2px;
4893
4856
  }
4894
- /* .pp-old itself needs to be the positioned ancestor for its badge below (same reasoning as
4895
- .cc-price/.fin-calc-card's own scoped `.pp-hero-old { position: relative }` override) —
4896
- the base .pp-old rule has no position, so without this the badge would anchor to whatever
4897
- positioned ancestor happens to be further up instead of sitting on the price text itself. */
4898
- .md3 .listcard-price .pp-old {
4899
- position: relative;
4900
- }
4901
4857
  /* footnote badge (small bordered circle, not a plain <sup>) pinned to the eyebrow's top-right
4902
4858
  corner — absolute against .pp-eyebrow's own position:relative above. Shared by the CarCard
4903
- hero (.cc-price), the VDP FinanceCalculator's own rate example (.fin-calc-card), and
4904
- CarRow's desktop stacked Kaufen row (.listcard-price .pp-old, PpRow's "2" badge). */
4859
+ hero (.cc-price) and the VDP FinanceCalculator's own rate example (.fin-calc-card). */
4905
4860
  .md3 .cc-price .pp-eyebrow-badge,
4906
4861
  .md3 .fin-calc-card .pp-eyebrow-badge,
4907
4862
  .md3 .vdp-bottom-bar .pp-eyebrow-badge,
4908
- .md3 .fin-modal .pp-eyebrow-badge,
4909
- .md3 .listcard-price .pp-old .pp-eyebrow-badge {
4863
+ .md3 .fin-modal .pp-eyebrow-badge {
4910
4864
  display: inline-flex;
4911
4865
  align-items: center;
4912
4866
  justify-content: center;
@@ -4927,11 +4881,6 @@ line-height: 31px;
4927
4881
  color: #0e2238;
4928
4882
  cursor: pointer;
4929
4883
  }
4930
- /* CarRow's desktop stacked Kaufen row sits closer to the price text than the card contexts
4931
- above, so the shared -8px offset sits a touch too far right. */
4932
- .md3 .listcard-price .pp-old .pp-eyebrow-badge {
4933
- right: -10px;
4934
- }
4935
4884
  /* mobile-only nudge: same badge, tucked slightly closer to the eyebrow text on narrow cards. */
4936
4885
  @media (max-width: 1024px) {
4937
4886
  .md3 .cc-price .pp-eyebrow-badge,
@@ -4950,14 +4899,11 @@ line-height: 31px;
4950
4899
  top: -7px;
4951
4900
  right: -12px;
4952
4901
  }
4953
- /* "3" footnote popover — click the badge above to open, the × or an outside click to close.
4954
- Also covers CarRow's desktop stacked Kaufen row (.listcard-price .pp-old, PpRow's "2"
4955
- badge) — same popover, reused rather than re-styled. */
4902
+ /* "3" footnote popover — click the badge above to open, the × or an outside click to close. */
4956
4903
  .md3 .cc-price .pp-uvp-tooltip,
4957
4904
  .md3 .fin-calc-card .pp-uvp-tooltip,
4958
4905
  .md3 .vdp-bottom-bar .pp-uvp-tooltip,
4959
- .md3 .fin-modal .pp-uvp-tooltip,
4960
- .md3 .listcard-price .pp-old .pp-uvp-tooltip {
4906
+ .md3 .fin-modal .pp-uvp-tooltip {
4961
4907
  position: absolute;
4962
4908
  top: 6px;
4963
4909
  right: -84px;
@@ -4976,12 +4922,6 @@ line-height: 31px;
4976
4922
  top: -20px;
4977
4923
  right: -110px;
4978
4924
  }
4979
- /* CarRow's desktop stacked Kaufen row is narrower still (.pp-old sits inline in the price
4980
- row, not a full-width card), so the shared -84px offset overhangs it — pull it in closer. */
4981
- .md3 .listcard-price .pp-old .pp-uvp-tooltip {
4982
- top: 6px;
4983
- right: -40px;
4984
- }
4985
4925
  /* .fin-calc-card is narrower than .cc-price / .fin-modal, so the shared -84px offset lets
4986
4926
  the popover overhang the card's right edge — this rule itself is unscoped (applies at
4987
4927
  every width, see the file-wide note above), so the max-width:600px block right below
@@ -5010,8 +4950,7 @@ line-height: 31px;
5010
4950
  .md3 .cc-price .pp-uvp-tooltip-close,
5011
4951
  .md3 .fin-calc-card .pp-uvp-tooltip-close,
5012
4952
  .md3 .vdp-bottom-bar .pp-uvp-tooltip-close,
5013
- .md3 .fin-modal .pp-uvp-tooltip-close,
5014
- .md3 .listcard-price .pp-old .pp-uvp-tooltip-close {
4953
+ .md3 .fin-modal .pp-uvp-tooltip-close {
5015
4954
  position: absolute;
5016
4955
  top: -38px;
5017
4956
  right: -35px;
@@ -5029,8 +4968,7 @@ line-height: 31px;
5029
4968
  .md3 .cc-price .pp-uvp-tooltip-body,
5030
4969
  .md3 .fin-calc-card .pp-uvp-tooltip-body,
5031
4970
  .md3 .vdp-bottom-bar .pp-uvp-tooltip-body,
5032
- .md3 .fin-modal .pp-uvp-tooltip-body,
5033
- .md3 .listcard-price .pp-old .pp-uvp-tooltip-body {
4971
+ .md3 .fin-modal .pp-uvp-tooltip-body {
5034
4972
  font-family: Arial, Helvetica, sans-serif;
5035
4973
  font-weight: 400;
5036
4974
  font-size: 11px;
@@ -5137,21 +5075,6 @@ line-height: 31px;
5137
5075
  font-size: 43px;
5138
5076
  line-height: 47px;
5139
5077
  }
5140
- /* CarCard Kaufen hero "1" price footnote marker — same treatment as
5141
- .fin-rate-main .num.hide-mobile sup (see the desktop .cc-price .pp-hero--buy .pp-hero-val
5142
- block below for the matching rule at that breakpoint). */
5143
- .md3 .cc-price .pp-hero--buy .pp-hero-val sup {
5144
- position: relative;
5145
- top: 2px;
5146
- left: 3px;
5147
- vertical-align: super;
5148
- font-family: Arial, Helvetica, sans-serif;
5149
- font-style: normal;
5150
- font-weight: 400;
5151
- font-size: 8px;
5152
- line-height: 9px;
5153
- color: #111820;
5154
- }
5155
5078
  /* Preisbewertung pill + segmented tier bar, grouped in one column exactly like the VDP
5156
5079
  finance-calculator's MOBILE .fin-eval-col (FinanceCalculator.tsx) — replaces the old
5157
5080
  StatChip pill + full-width gradient .pp-bar (see PriceEvalCol in cardParts.tsx). No
@@ -10509,21 +10432,6 @@ color: #005CFF;
10509
10432
  font-size: 43px;
10510
10433
  line-height: 47px;
10511
10434
  }
10512
- /* CarCard Kaufen hero "1" price footnote marker — same treatment as
10513
- .fin-rate-main .num.hide-mobile sup, not scoped to a media query since the same offset
10514
- reads fine against both the mobile and desktop .pp-hero--buy .pp-hero-val sizes above. */
10515
- .md3 .cc-price .pp-hero--buy .pp-hero-val sup {
10516
- position: relative;
10517
- top: 2px;
10518
- left: 3px;
10519
- vertical-align: super;
10520
- font-family: Arial, Helvetica, sans-serif;
10521
- font-style: normal;
10522
- font-weight: 400;
10523
- font-size: 8px;
10524
- line-height: 9px;
10525
- color: #111820;
10526
- }
10527
10435
 
10528
10436
  /* Finanzierung/Leasing/Kaufen tabs — Figma: only the ACTIVE tab is bold + Deep Navy #0e2238
10529
10437
  inactive text (the shared .fin-tab rule bolds both and uses #111820, since the VDP
@@ -100,7 +100,6 @@ export const VdpHeaderSummary: React.FunctionComponent<VdpHeaderCardProps> = ({
100
100
  icon={vehicle.rating === 'fair' ? 'minus' : 'check'}
101
101
  >
102
102
  {t('autobahn:tier.' + vehicle.rating)}
103
- {vehicle.rating !== 'fair' && <sup>4</sup>}
104
103
  </StatChip>
105
104
  )}
106
105
  </div>
@@ -3079,6 +3078,7 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
3079
3078
  <div className="fin-sheet-terms">
3080
3079
  <div className="md-title-sm" style={{ display: 'flex', alignItems: 'center', gap: 5 }}>
3081
3080
  {t('autobahn:finance.termSelectionMonths')}
3081
+ <Icon name="info" size={13} color="var(--md-on-surface-variant)" />
3082
3082
  </div>
3083
3083
  <TermChips
3084
3084
  options={termVals.filter((v) => v !== 12 && v !== 96)}