@bytebrand/fe-ui-core-autobahn 1.0.147 → 1.0.149

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/CarCard.tsx CHANGED
@@ -157,6 +157,8 @@ const CarCard: React.FunctionComponent<CarCardProps> = ({
157
157
  // active that's already 3, so NEU is dropped rather than causing a 4th to overflow.
158
158
  const activeDealChips = [showDrop || showSave, showPct, !!car.zeroDown].filter(Boolean).length;
159
159
  const showNeu = asGoodAsNew && car.isNew && activeDealChips < 3;
160
+ // tabs the price block can switch to (PriceTabs shows Leasing only when the car has a lease rate)
161
+ const paymentModes: PaymentMode[] = car.lease != null ? ['financing', 'leasing', 'buy'] : ['financing', 'buy'];
160
162
  return (
161
163
  <article
162
164
  className="mcard mcard--interactive cc-card"
@@ -277,7 +279,21 @@ const CarCard: React.FunctionComponent<CarCardProps> = ({
277
279
  <div className="cc-price" style={{ marginTop: 0, borderTop: '1px solid var(--md-outline-variant)' }}>
278
280
  <PriceTabs car={car} mode={mode} onModeChange={setMode} t={t} />
279
281
  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8, marginTop: 10 }}>
280
- <PriceHero car={car} mode={mode} t={t} alwaysShowUnit />
282
+ {/* every tab's hero stacked in one grid cell (.cc-hero-stack), only the active one
283
+ visible, bottom-aligned — Kaufen's struck list price sits on its own line above
284
+ the price, so without this the row (and the card) grew/shrank by that line on
285
+ every tab switch. Same trick as .cc-terms-stack below. */}
286
+ <div className="cc-hero-stack">
287
+ {paymentModes.map((m) => (
288
+ <div
289
+ key={m}
290
+ className={'cc-hero-slot' + (m === mode ? '' : ' cc-hero-slot--hidden')}
291
+ aria-hidden={m === mode ? undefined : true}
292
+ >
293
+ <PriceHero car={car} mode={m} t={t} alwaysShowUnit />
294
+ </div>
295
+ ))}
296
+ </div>
281
297
  <PriceEvalCol car={car} t={t} />
282
298
  </div>
283
299
  {/* same fallback CardCtaRow already uses below: pages that haven't wired a real
@@ -287,23 +303,21 @@ const CarCard: React.FunctionComponent<CarCardProps> = ({
287
303
  card keeps one height across Finanzierung/Leasing/Kaufen (Leasing's longer line
288
304
  wraps to 2 lines on narrow phones). No change to the visible line itself. */}
289
305
  <div className="cc-terms-stack">
290
- {(['financing', 'leasing', 'buy'] as PaymentMode[])
291
- .filter((m) => m !== 'leasing' || car.lease != null)
292
- .map((m) => (
293
- <div
294
- key={m}
295
- className={'cc-terms-slot' + (m === mode ? '' : ' cc-terms-slot--hidden')}
296
- aria-hidden={m === mode ? undefined : true}
297
- >
298
- <PriceTerms
299
- car={car}
300
- mode={m}
301
- onOpenRateAdjust={onOpenRateAdjust || (() => onOpen(car))}
302
- onShowDetails={onShowFinancingDetails ? () => onShowFinancingDetails(car, m) : undefined}
303
- t={t}
304
- />
305
- </div>
306
- ))}
306
+ {paymentModes.map((m) => (
307
+ <div
308
+ key={m}
309
+ className={'cc-terms-slot' + (m === mode ? '' : ' cc-terms-slot--hidden')}
310
+ aria-hidden={m === mode ? undefined : true}
311
+ >
312
+ <PriceTerms
313
+ car={car}
314
+ mode={m}
315
+ onOpenRateAdjust={onOpenRateAdjust || (() => onOpen(car))}
316
+ onShowDetails={onShowFinancingDetails ? () => onShowFinancingDetails(car, m) : undefined}
317
+ t={t}
318
+ />
319
+ </div>
320
+ ))}
307
321
  </div>
308
322
  </div>
309
323
  {/* Mobile-only row (CardCtaRow itself carries the show-mobile class) — always
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytebrand/fe-ui-core-autobahn",
3
- "version": "1.0.147",
3
+ "version": "1.0.149",
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",
package/theme/md3.css CHANGED
@@ -5446,6 +5446,24 @@ line-height: 31px;
5446
5446
  order: -1;
5447
5447
  align-self: flex-end;
5448
5448
  }
5449
+ /* ...but without adding a line to the price row: the struck UVP overlays the empty space
5450
+ above the (52px on a 58px line) Kaufen figure, right-aligned over it — so Kaufen's hero is
5451
+ exactly as tall as the Finanzierung/Leasing one (15px Figma gap from the tab underline to
5452
+ the figure on every tab, nothing below it moves on a tab switch; see .cc-hero-stack). */
5453
+ .md3 .cc-price .pp-hero--buy .pp-hero-rate {
5454
+ position: relative;
5455
+ }
5456
+ .md3 .cc-price .pp-hero--buy .pp-hero-unit-group {
5457
+ position: absolute;
5458
+ right: 0;
5459
+ bottom: calc(100% - 11px);
5460
+ }
5461
+ /* nudge the Kaufen figure 3px down (visual only, layout untouched) so the overlaid struck UVP
5462
+ line clears its glyph tops */
5463
+ .md3 .cc-price .pp-hero--buy .pp-hero-val {
5464
+ position: relative;
5465
+ top: 3px;
5466
+ }
5449
5467
  /* Kaufen hero price on mobile — was falling through to the generic (rate-sized) .pp-hero-val
5450
5468
  above (65px, shrinking only via the rate-digit len4/5/6 classes cardParts.tsx never applies
5451
5469
  in Kaufen mode), so real purchase prices had no digit-based shrink at all here and could
@@ -5556,6 +5574,21 @@ line-height: 31px;
5556
5574
  /* financing/leasing terms line + "Finanzierungsdetails"/"Leasingdetails" link (PriceTerms in
5557
5575
  cardParts.tsx), full-width under the price/rating row. Same quiet typography as .pp-hero-terms
5558
5576
  (PricePaths); the link resets button chrome and reuses the primary color so it reads as tappable. */
5577
+ /* CarCard: all tabs' price heroes stacked in one grid cell, only the active one visible,
5578
+ bottom-aligned (the price figure stays put) — Kaufen's struck list price adds a line above the
5579
+ price, which otherwise grew/shrank the price row on every tab switch. The cell is as wide as
5580
+ the WIDEST hero (no min-width: 0 — same auto min-width the lone hero had), so the "Guter
5581
+ Preis" column next to it also keeps one position on every tab. */
5582
+ .md3 .cc-hero-stack {
5583
+ display: grid;
5584
+ }
5585
+ .md3 .cc-hero-slot {
5586
+ grid-area: 1 / 1;
5587
+ align-self: end;
5588
+ }
5589
+ .md3 .cc-hero-slot--hidden {
5590
+ visibility: hidden;
5591
+ }
5559
5592
  /* CarCard: all tabs' terms lines stacked in one grid cell, only the active one visible — the
5560
5593
  cell takes the tallest line's height so switching tabs never changes the card's height. */
5561
5594
  .md3 .cc-terms-stack {
@@ -6575,8 +6608,13 @@ line-height: 31px;
6575
6608
  Both capped to the fixed inset:0 scrim's CURRENT visible height (%, not vh — on iOS Safari
6576
6609
  100vh > the visible area while the toolbar shows, which pushed the sheet's top off-screen). */
6577
6610
  .md3 .fin-modal {
6611
+ /* room under the fold for whatever overlays the bottom of the screen: the home-indicator
6612
+ inset, and on iOS (WebKit only: -webkit-touch-callout) Safari's floating bottom toolbar,
6613
+ which sits ON TOP of fixed content — without it the "Finanzierungs-Details" link ended up
6614
+ hidden behind the toolbar. */
6615
+ --fin-sheet-bottom-gap: env(safe-area-inset-bottom, 0px);
6578
6616
  max-width: none;
6579
- height: min(var(--fin-sheet-fold, 85vh), calc(100% - 24px));
6617
+ height: min(calc(var(--fin-sheet-fold, 85vh) + var(--fin-sheet-bottom-gap)), calc(100% - 24px));
6580
6618
  max-height: none;
6581
6619
  background: #FFFFFF;
6582
6620
  box-shadow: 0px -4px 18px rgba(0, 0, 0, 0.13);
@@ -6586,6 +6624,14 @@ line-height: 31px;
6586
6624
  .md3 .fin-modal.fin-modal--expanded {
6587
6625
  height: calc(100% - 24px);
6588
6626
  }
6627
+ .md3 .fin-modal .fin-modal-body {
6628
+ padding-bottom: calc(13px + var(--fin-sheet-bottom-gap));
6629
+ }
6630
+ @supports (-webkit-touch-callout: none) {
6631
+ .md3 .fin-modal {
6632
+ --fin-sheet-bottom-gap: max(env(safe-area-inset-bottom, 0px), 64px);
6633
+ }
6634
+ }
6589
6635
  /* set from the frame after the first fold measure (not on open — no 85vh -> fold shrink) */
6590
6636
  .md3 .fin-modal.fin-modal--animated {
6591
6637
  transition: height 0.35s var(--ease-standard, ease);