@bytebrand/fe-ui-core-autobahn 1.0.60 → 1.0.62

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.
@@ -329,24 +329,35 @@ const FinanceCalculator: React.FunctionComponent<FinanceCalculatorProps> = ({
329
329
  }) => {
330
330
  // Pure view state only — whether the adjust/details expander is open.
331
331
  const [adjust, setAdjust] = useState(false);
332
+ // whether the "UVP-Rate" footnote popover (fin/leasing) is open — same widget as CarCard's.
333
+ const [uvpTooltipOpen, setUvpTooltipOpen] = useState(false);
332
334
  const isCash = mode === 'cash';
333
335
  const terms = termOptions && termOptions.length ? termOptions : range(termMin, termMax, termStep);
334
336
  const showStrike = listPrice != null && listPrice > price;
335
337
  // price-evaluation tier from the rating label (defaults to 'Guter Preis' tier when unmapped).
336
338
  const tierIdx = TIER_LABELS.indexOf(ratingLabel as (typeof TIER_LABELS)[number]);
337
339
  const evalTier = tierIdx >= 0 ? tierIdx : 1;
338
- const evalTierLabel = t('autobahn:tier.' + TIER_KEYS[evalTier]);
339
- // condition summary (current selection) — the auto.de-ID lives with the details link, not here.
340
+ // both green tiers ('top' and 'good') collapse onto one "Top-Preis" claim (same convention as
341
+ // CarCard's PriceEvalCol) — footnote 4 carries the disclaimer text.
342
+ const isGoodTier = TIER_KEYS[evalTier] === 'good';
343
+ const evalTierLabel = isGoodTier ? t('autobahn:tier.top') : t('autobahn:tier.' + TIER_KEYS[evalTier]);
344
+ const evalPillColor = isGoodTier ? TIER_COLORS[0] : TIER_COLORS[evalTier];
345
+ // condition summary (current selection) + its own details link — financing: "0 € Anzahlung ·
346
+ // 60 Monate · Finanzierungsdetails"; leasing: "25.000 € Sonderzahlung · 60 Mon. · 10.000
347
+ // km/Jahr · Details" (same wording/order as CarCard's own PriceTerms leaseTerms).
340
348
  const condParts: string[] = [];
341
- if (!isCash) {
349
+ if (mode === 'leasing') {
342
350
  condParts.push(
343
- mode === 'leasing' && annualMileage != null
344
- ? t('autobahn:finance.kmPerYear', { value: eur(annualMileage) })
345
- : t('autobahn:finance.downPaymentLabel', { value: eur(down) }),
351
+ ...t('autobahn:card.price.leaseTerms', {
352
+ firstInstallment: eur(down),
353
+ months: term,
354
+ mileage: annualMileage != null ? eur(annualMileage) : '',
355
+ }).split(' · '),
346
356
  );
357
+ } else if (!isCash) {
358
+ condParts.push(t('autobahn:finance.downPaymentLabel', { value: eur(down) }));
347
359
  condParts.push(t('autobahn:finance.monthsLabel', { months: term, count: term }));
348
360
  }
349
- const condLine = condParts.length ? `${t('autobahn:finance.exampleLabel')} ${condParts.join(' · ')}` : '';
350
361
 
351
362
  return (
352
363
  <div className="mcard mcard--elevated fin-calc-card" style={{ padding: 20 }}>
@@ -410,10 +421,48 @@ const FinanceCalculator: React.FunctionComponent<FinanceCalculatorProps> = ({
410
421
  {/* mobile Kaufen (Figma round 14): struck list price ABOVE the price, right-aligned,
411
422
  tight to the figure — replaces the Festpreis + UVP lines, which stay desktop-only */}
412
423
  {isCash && showStrike && (
413
- <div className="show-mobile" style={{ justifyContent: 'flex-end', lineHeight: 1, marginTop: 7 }}>
414
- <s className="num fin-rate-old fin-rate-old-list">
415
- {eur(listPrice as number)} €<sup>2</sup>
416
- </s>
424
+ <div className="show-mobile" style={{ justifyContent: 'flex-end', alignItems: 'baseline', gap: 4, lineHeight: 1, marginTop: 7 }}>
425
+ <span style={{ fontSize: 13, color: 'var(--md-on-surface-variant)' }}>{t('autobahn:finance.uvp')}</span>
426
+ <span
427
+ className={`num pp-hero-old${
428
+ String(Math.round(listPrice as number)).length === 5
429
+ ? ' pp-hero-old--len5'
430
+ : String(Math.round(listPrice as number)).length === 4
431
+ ? ' pp-hero-old--len4'
432
+ : ''
433
+ }`}
434
+ >
435
+ {eur(Math.round(listPrice as number))} €
436
+ <span
437
+ className="pp-eyebrow-badge"
438
+ role="button"
439
+ tabIndex={0}
440
+ onClick={(e) => {
441
+ e.stopPropagation();
442
+ setUvpTooltipOpen((v) => !v);
443
+ }}
444
+ >
445
+ 2
446
+ </span>
447
+ {uvpTooltipOpen && (
448
+ <div className="pp-uvp-tooltip" onClick={(e) => e.stopPropagation()}>
449
+ <button
450
+ type="button"
451
+ className="pp-uvp-tooltip-close"
452
+ aria-label={t('autobahn:modal.close')}
453
+ onClick={(e) => {
454
+ e.stopPropagation();
455
+ setUvpTooltipOpen(false);
456
+ }}
457
+ >
458
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
459
+ <path d="M5 5L15 15M15 5L5 15" stroke="white" strokeWidth={2.4} strokeLinecap="round" />
460
+ </svg>
461
+ </button>
462
+ <div className="pp-uvp-tooltip-body">{t('autobahn:card.price.uvpListTooltipBody')}</div>
463
+ </div>
464
+ )}
465
+ </span>
417
466
  </div>
418
467
  )}
419
468
  <div style={{ display: 'flex', alignItems: 'center', gap: 7 }}>
@@ -463,7 +512,44 @@ const FinanceCalculator: React.FunctionComponent<FinanceCalculatorProps> = ({
463
512
  {/* struck old rate (REAL oldMonthlyInstallment; SRP strikes the same source) */}
464
513
  {oldMonthly != null && (
465
514
  <>
466
- <span className="fin-rate-example-label">{t('autobahn:finance.exampleLabel')}</span>
515
+ <span className="pp-eyebrow">
516
+ {t('autobahn:card.price.uvpRateLabel')}
517
+ <span
518
+ className="pp-eyebrow-badge"
519
+ role="button"
520
+ tabIndex={0}
521
+ onClick={(e) => {
522
+ e.stopPropagation();
523
+ setUvpTooltipOpen((v) => !v);
524
+ }}
525
+ >
526
+ 3
527
+ </span>
528
+ {uvpTooltipOpen && (
529
+ <div className="pp-uvp-tooltip" onClick={(e) => e.stopPropagation()}>
530
+ <button
531
+ type="button"
532
+ className="pp-uvp-tooltip-close"
533
+ aria-label={t('autobahn:modal.close')}
534
+ onClick={(e) => {
535
+ e.stopPropagation();
536
+ setUvpTooltipOpen(false);
537
+ }}
538
+ >
539
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
540
+ <path d="M5 5L15 15M15 5L5 15" stroke="white" strokeWidth={2.4} strokeLinecap="round" />
541
+ </svg>
542
+ </button>
543
+ <div className="pp-uvp-tooltip-body">
544
+ {t(
545
+ mode === 'leasing'
546
+ ? 'autobahn:card.price.uvpRateTooltipBodyLeasing'
547
+ : 'autobahn:card.price.uvpRateTooltipBody',
548
+ )}
549
+ </div>
550
+ </div>
551
+ )}
552
+ </span>
467
553
  <s
468
554
  className={`num fin-rate-old fin-rate-example-price${
469
555
  String(Math.round(oldMonthly)).length >= 5
@@ -473,12 +559,12 @@ const FinanceCalculator: React.FunctionComponent<FinanceCalculatorProps> = ({
473
559
  : ''
474
560
  }`}
475
561
  >
476
- {eur(Math.round(oldMonthly))} €<sup>2</sup>
562
+ {eur(Math.round(oldMonthly))} €
477
563
  </s>
478
564
  </>
479
565
  )}
480
566
  <span className="fin-rate-example-suffix">
481
- {t('autobahn:finance.perMonth')}<sup>3</sup>
567
+ {t('autobahn:finance.perMonth')}
482
568
  </span>
483
569
  </span>
484
570
  </>
@@ -499,19 +585,38 @@ const FinanceCalculator: React.FunctionComponent<FinanceCalculatorProps> = ({
499
585
  <div className="fin-eval-pill-cell">
500
586
  {ratingLabel && (
501
587
  <span
502
- className={`fin-eval-pill${TIER_KEYS[evalTier] === 'good' ? ' fin-eval-pill--good' : ''}`}
503
- style={{ color: TIER_COLORS[evalTier], background: `color-mix(in srgb, ${TIER_COLORS[evalTier]} 16%, transparent)` }}
588
+ className={`fin-eval-pill${isGoodTier ? ' fin-eval-pill--good' : ''}`}
589
+ style={{ color: evalPillColor, background: `color-mix(in srgb, ${evalPillColor} 16%, transparent)` }}
504
590
  aria-label={t('autobahn:finance.priceRatingAria', { rating: evalTierLabel })}
505
591
  >
506
592
  {evalTierLabel}
593
+ {isGoodTier && <sup>4</sup>}
507
594
  </span>
508
595
  )}
509
596
  </div>
510
597
  {/* segmented evaluation bar (Figma: discrete tiers, not a gradient) */}
511
598
  <div className="fin-eval-bar-cell">{ratingLabel && <EvalBar tier={evalTier} />}</div>
512
599
  </div>
513
- {/* col 1 row 2: condition line */}
514
- <div className="fin-cond">{condLine}</div>
600
+ {/* col 1 row 2: condition line — financing "0 € Anzahlung · 60 Monate · Finanzierungsdetails",
601
+ leasing "25.000 € Sonderzahlung · 60 Mon. · 10.000 km/Jahr · Details" */}
602
+ <div className="fin-cond">
603
+ {!isCash &&
604
+ condParts.map((part, i) => (
605
+ <React.Fragment key={i}>
606
+ {i > 0 && <span className="cc-terms-dot"> · </span>}
607
+ {part}
608
+ </React.Fragment>
609
+ ))}
610
+ {!isCash && onShowDetails && (
611
+ <>
612
+ <span className="cc-terms-dot"> · </span>
613
+ {/* plain underlined text link, same onShowDetails handler as .fin-info used to open. */}
614
+ <button type="button" className="cc-terms-link" onClick={onShowDetails}>
615
+ {mode === 'leasing' ? t('autobahn:card.price.detailsLink') : t('autobahn:finance.financingDetails')}
616
+ </button>
617
+ </>
618
+ )}
619
+ </div>
515
620
  </div>
516
621
 
517
622
  {/* ============================== DESKTOP (≥601px) — unchanged ============================== */}
@@ -642,84 +747,10 @@ const FinanceCalculator: React.FunctionComponent<FinanceCalculatorProps> = ({
642
747
  </div>
643
748
  </div>
644
749
 
645
- {/* Persönliche Beratung (left) · divider · Finanzierungs-/Leasingdetails or hint (right) */}
646
- <div className="fin-info">
647
- <div className="fin-info-main" style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0, flex: 1 }}>
648
- <Icon name="user" size={26} color="var(--md-on-surface-variant)" style={{ flex: 'none' }} />
649
- <div style={{ minWidth: 0 }}>
650
- <div className="md-label-sm" style={{ fontWeight: 700, color: 'var(--md-on-surface)' }}>
651
- {t('autobahn:finance.personalConsultation')}
652
- </div>
653
- <div className="md-label-sm fin-info-sub">{t('autobahn:finance.personalConsultationSub')}</div>
654
- </div>
655
- </div>
656
- <span
657
- style={{
658
- width: 1,
659
- alignSelf: 'stretch',
660
- background: 'var(--md-outline-variant)',
661
- flex: 'none',
662
- marginLeft: 13,
663
- marginRight: 13,
664
- }}
665
- />
666
- {!isCash && onShowDetails ? (
667
- <button
668
- type="button"
669
- className="fin-info-details-btn"
670
- onClick={onShowDetails}
671
- style={{
672
- display: 'flex',
673
- alignItems: 'center',
674
- gap: 8,
675
- background: 'none',
676
- border: 0,
677
- padding: 0,
678
- cursor: 'pointer',
679
- font: 'inherit',
680
- color: 'var(--md-on-surface)',
681
- textAlign: 'left',
682
- }}
683
- >
684
- <Icon name="info" size={24} color="var(--md-on-surface-variant)" style={{ flex: 'none' }} />
685
- {/* no max-width: "Finanzierungsdetails" is one unbreakable word — capping the
686
- span clipped it mid-word instead of wrapping */}
687
- <span className="md-label-sm fin-info-details-label">
688
- {mode === 'leasing' ? (
689
- t('autobahn:finance.leasingDetails')
690
- ) : (
691
- <>
692
- Finanzierungs-
693
- <br />
694
- Details
695
- </>
696
- )}
697
- </span>
698
- </button>
699
- ) : (
700
- <div style={{ display: 'flex', alignItems: 'center', gap: 6, color: 'var(--md-on-surface-variant)' }}>
701
- <Icon name="info" size={24} />
702
- <span className="md-label-sm fin-financing-leasing-note">
703
- {(() => {
704
- // hard break right after "&" (not a soft wrap-if-needed hint) — always
705
- // two lines: "Finanzierung &" / "Leasing möglich"; derived from the
706
- // translated string itself so it works for either locale.
707
- const raw = t('autobahn:finance.financingLeasingPossible');
708
- const splitAt = raw.indexOf(' & ');
709
- if (splitAt === -1) return raw;
710
- const before = raw.slice(0, splitAt).split(' ').join(' ');
711
- const after = raw.slice(splitAt + 3).split(' ').join(' ');
712
- return (
713
- <>
714
- {before} &
715
- <br />
716
- {after}
717
- </>
718
- );
719
- })()}
720
- </span>
721
- </div>
722
- )}
750
+ {/* Persönliche Beratung — icon + one line (the details link now lives in .fin-cond above) */}
751
+ <div className="fin-info" style={{ justifyContent: 'flex-start', paddingLeft: 15 }}>
752
+ <Icon name="user" size={26} color="var(--md-on-surface-variant)" style={{ flex: 'none', marginRight: 20 }} />
753
+ <span className="fin-info-line">{t('autobahn:finance.personalConsultationLine')}</span>
723
754
  </div>
724
755
 
725
756
  {/* "Rate anpassen" / "Details anzeigen" — opens the full bottom sheet (not an inline expander) */}
@@ -28,7 +28,7 @@ import { Button, Dropdown, DropdownOption, Icon, Spec, StatChip, Stars, Switch }
28
28
  import { CO2_CLASSES, CO2_COLORS, TIER_LABELS, TIER_KEYS, TIER_COLORS, TIER_BACKGROUNDS } from '../constants';
29
29
  import { defaultVdpSpecs, EquipmentGroups, PriceRatingBands, VehicleDetail, VdpSpec, VdpReview } from './types';
30
30
  import { CalcRow, DocCheckIcon, EvalBar, expanderBtnStyle, FinanceMode, Slider, TermChips } from './FinanceCalculator';
31
- import { formatEur as eur, formatPct as pct, buildFinanceExampleLine } from '../utils/financeFormat';
31
+ import { formatEur as eur, formatPct as pct } from '../utils/financeFormat';
32
32
 
33
33
  /** Figma "check with open arc" glyph (modern lucide circle-check-big; the bundled lucide
34
34
  * 0.288 only ships the closed-circle variant, so the two paths are inlined). */
@@ -1957,54 +1957,76 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
1957
1957
  // total, so Schlussrate + Gesamtbetrag come from the config and are omitted when unavailable —
1958
1958
  // never a fabricated/misleading total.
1959
1959
  const netto = netLoanAmount != null ? netLoanAmount : Math.max(0, price - down);
1960
- const rows: Array<[string, string]> = [
1960
+ // "Rundum-Sorglos-Paket" one-time fee only counts toward the breakdown when the customer
1961
+ // actually has it switched on (cash mode forces it on upstream) AND a real cost is known.
1962
+ const hasAddServices = !!withAddServices && addServicesCost != null && addServicesCost > 0;
1963
+ // Grand total (Figma "Gesamtbelastung inkl. Anzahlung & Paket") — down payment + the config's
1964
+ // real Gesamtbetrag + the package fee. Only shown when Gesamtbetrag is known (never fabricated).
1965
+ const totalCost = grossAmount != null && grossAmount > 0 ? down + grossAmount + (hasAddServices ? (addServicesCost as number) : 0) : undefined;
1966
+ const rows: Array<[string, string, boolean?]> = [
1961
1967
  [t('autobahn:modal.vehiclePrice'), `${eur(price)} €`],
1962
- [isLease ? t('autobahn:modal.leasingAmount') : t('autobahn:modal.netLoanAmount'), `${eur(netto)} €`],
1968
+ [t('autobahn:modal.term'), t('autobahn:modal.months', { months: term, count: term })],
1963
1969
  [t('autobahn:modal.downPayment'), `${eur(down)} €`],
1964
1970
  ...(isLease && annualMileage != null ? ([[t('autobahn:modal.annualMileage'), `${eur(annualMileage)} km`]] as Array<[string, string]>) : []),
1965
- [t('autobahn:modal.term'), t('autobahn:modal.months', { months: term, count: term })],
1971
+ [
1972
+ isLease ? t('autobahn:modal.leasingRateCount', { count: term }) : t('autobahn:modal.monthlyRateCount', { count: term }),
1973
+ `${eur(monthly)} €`,
1974
+ ],
1975
+ ...(finalInstallment != null && finalInstallment > 0 ? ([[t('autobahn:modal.finalInstallment'), `${eur(finalInstallment)} €`]] as Array<[string, string]>) : []),
1976
+ ...(hasAddServices ? ([[t('autobahn:modal.addServicesRow'), `${eur(addServicesCost as number)} €`]] as Array<[string, string]>) : []),
1966
1977
  ...(nominalRate != null && nominalRate > 0 ? ([[t('autobahn:modal.nominalRate'), pct(nominalRate)]] as Array<[string, string]>) : []),
1967
1978
  [t('autobahn:modal.effectiveRate'), pct(apr)],
1968
- ...(finalInstallment != null && finalInstallment > 0 ? ([[t('autobahn:modal.finalInstallment'), `${eur(finalInstallment)} €`]] as Array<[string, string]>) : []),
1969
- [isLease ? t('autobahn:modal.leasingRate') : t('autobahn:modal.monthlyRate'), t('autobahn:modal.ratePerMonth', { amount: eur(monthly) })],
1979
+ [isLease ? t('autobahn:modal.leasingAmount') : t('autobahn:modal.netLoanAmount'), `${eur(netto)} €`],
1970
1980
  ...(grossAmount != null && grossAmount > 0 ? ([[isLease ? t('autobahn:modal.totalAmount') : t('autobahn:modal.totalRepayment'), `${eur(grossAmount)} €`]] as Array<[string, string]>) : []),
1981
+ ...(totalCost != null
1982
+ ? ([[hasAddServices ? t('autobahn:modal.totalCostWithPackage') : t('autobahn:modal.totalCost'), `${eur(totalCost)} €`, true]] as Array<
1983
+ [string, string, boolean]
1984
+ >)
1985
+ : []),
1986
+ ...(listPrice != null && listPrice > 0 ? ([[t('autobahn:modal.listPrice'), `${eur(listPrice)} €`]] as Array<[string, string]>) : []),
1971
1987
  ];
1972
- const breakdownRows = rows.map(([l, v], i) => (
1988
+ const breakdownRows = rows.map(([l, v, bold], i) => (
1973
1989
  <div
1974
1990
  key={l}
1975
1991
  style={{
1976
1992
  display: 'flex',
1977
- justifyContent: 'space-between',
1978
- gap: 12,
1979
- padding: '9px 0',
1980
- borderBottom: i < rows.length - 1 ? '1px solid var(--md-outline-variant)' : 0,
1993
+ alignItems: 'baseline',
1994
+ gap: 8,
1995
+ padding: '7px 0',
1996
+ borderTop: '1px solid rgba(212, 221, 231, 0.95)',
1981
1997
  }}
1982
1998
  >
1983
- <span className="md-label-sm">{l}</span>
1984
- <span className="num" style={{ fontSize: 13.5, fontWeight: 600 }}>
1999
+ <span
2000
+ style={{
2001
+ fontFamily: 'Arial, Helvetica, sans-serif',
2002
+ fontStyle: 'normal',
2003
+ fontWeight: bold ? 700 : 400,
2004
+ fontSize: 13,
2005
+ lineHeight: '13px',
2006
+ color: '#0e2238',
2007
+ whiteSpace: 'nowrap',
2008
+ }}
2009
+ >
2010
+ {l}
2011
+ </span>
2012
+ <span
2013
+ className="num"
2014
+ style={{
2015
+ fontFamily: 'Arial, Helvetica, sans-serif',
2016
+ fontStyle: 'normal',
2017
+ fontWeight: bold ? 700 : 400,
2018
+ fontSize: 13,
2019
+ lineHeight: '13px',
2020
+ color: '#0e2238',
2021
+ whiteSpace: 'nowrap',
2022
+ marginLeft: 'auto',
2023
+ }}
2024
+ >
1985
2025
  {v}
1986
2026
  </span>
1987
2027
  </div>
1988
2028
  ));
1989
2029
 
1990
- // mobile sheet footnote — the Figma representative example: real figures inline
1991
- // ("³ Fahrzeugpreis: … €; Effektiver Jahreszins: … %; …") followed by the PangV sentence.
1992
- // Only REAL config figures are included; absent ones are simply omitted — shared logic with
1993
- // the Meta AIA marketing-image renderer, see ../utils/financeFormat.ts.
1994
- const exampleLine = buildFinanceExampleLine(
1995
- { price, apr, down, netLoanAmount, nominalRate, finalInstallment, grossAmount },
1996
- {
1997
- vehiclePrice: t('autobahn:modal.exampleVehiclePrice'),
1998
- priceSuffix: t('autobahn:modal.examplePriceSuffix'),
1999
- apr: t('autobahn:modal.exampleApr'),
2000
- nominal: t('autobahn:modal.exampleNominal'),
2001
- net: t('autobahn:modal.exampleNet'),
2002
- down: t('autobahn:modal.exampleDown'),
2003
- final: t('autobahn:modal.exampleFinal'),
2004
- gross: t('autobahn:modal.exampleGross'),
2005
- },
2006
- );
2007
-
2008
2030
  return (
2009
2031
  <div className="fin-modal-scrim" onClick={onClose}>
2010
2032
  <div
@@ -2408,7 +2430,7 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
2408
2430
  </div>
2409
2431
 
2410
2432
  {/* centered ⓘ details toggle (mockup shows no chevron) */}
2411
- <button type="button" onClick={() => setShowBreakdown((v) => !v)} style={{ ...expanderBtnStyle, justifyContent: 'center', padding: '2px 0' }}>
2433
+ <button type="button" onClick={() => setShowBreakdown((v) => !v)} style={{ ...expanderBtnStyle, justifyContent: 'center', padding: '2px 0 20px' }}>
2412
2434
  <span
2413
2435
  style={{
2414
2436
  display: 'inline-flex',
@@ -2425,27 +2447,180 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
2425
2447
  {isLease ? t('autobahn:modal.leasingDetails') : t('autobahn:modal.financingDetails')}
2426
2448
  </span>
2427
2449
  </button>
2428
- {/* mobile mockup shows NO row-by-row breakdown table (round 9 review) — the Figma
2429
- footnote: real figures inline, then the PangV sentence (round 12). */}
2450
+ {/* mobile "Finanzierungsdetails" toggle reveals the same row-by-row breakdown
2451
+ table as desktop (breakdownRows, built once above) instead of the old
2452
+ condensed footnote line. */}
2430
2453
  {showBreakdown && (
2431
- <div>
2454
+ <>
2455
+ <div style={{ marginBottom: 5 }}>
2456
+ <p
2457
+ style={{
2458
+ fontFamily: 'Arial, Helvetica, sans-serif',
2459
+ fontWeight: 700,
2460
+ fontSize: 16,
2461
+ lineHeight: '18px',
2462
+ color: '#0E2238',
2463
+ margin: 0,
2464
+ marginBottom: 5,
2465
+ paddingTop: 10,
2466
+ borderTop: '1px solid rgba(212, 221, 231, 0.95)',
2467
+ }}
2468
+ >
2469
+ {t('autobahn:modal.representativeExample')}
2470
+ </p>
2471
+ <p
2472
+ style={{
2473
+ fontFamily: 'Arial, Helvetica, sans-serif',
2474
+ fontWeight: 700,
2475
+ fontSize: 9,
2476
+ lineHeight: '12px',
2477
+ color: '#5B6B7F',
2478
+ marginBottom: 5,
2479
+ }}
2480
+ >
2481
+ {t('autobahn:modal.vatDisclaimer')}
2482
+ </p>
2483
+ {breakdownRows}
2484
+ </div>
2485
+ <div
2486
+ style={{
2487
+ display: 'flex',
2488
+ alignItems: 'flex-start',
2489
+ gap: 10,
2490
+ background: '#FAFBFD',
2491
+ border: '1px solid #D4DDE7',
2492
+ borderRadius: 6,
2493
+ padding: 10,
2494
+ marginBottom: 10,
2495
+ }}
2496
+ >
2497
+ <svg width="27" height="27" viewBox="0 0 27 27" fill="none" xmlns="http://www.w3.org/2000/svg" style={{ flex: 'none' }}>
2498
+ <path d="M2.7002 9.00001L13.5002 3.60001L24.3002 9.00001H2.7002Z" stroke="#0E2238" strokeWidth="1.6" strokeLinejoin="round" />
2499
+ <path d="M4.49961 10.8H22.4996M5.39961 21.6H21.5996M3.59961 24.3H23.3996" stroke="#0E2238" strokeWidth="1.6" strokeLinecap="round" />
2500
+ <path d="M7.2002 10.8V21.6M11.7002 10.8V21.6M15.3002 10.8V21.6M19.8002 10.8V21.6" stroke="#0E2238" strokeWidth="1.6" />
2501
+ </svg>
2502
+ <div>
2503
+ <p
2504
+ style={{
2505
+ fontFamily: 'Arial, Helvetica, sans-serif',
2506
+ fontWeight: 700,
2507
+ fontSize: 14,
2508
+ lineHeight: '13px',
2509
+ color: '#0E2238',
2510
+ margin: 0,
2511
+ marginBottom: 3,
2512
+ }}
2513
+ >
2514
+ {t('autobahn:modal.lenderLabel')}
2515
+ </p>
2516
+ <p
2517
+ style={{
2518
+ fontFamily: 'Arial, Helvetica, sans-serif',
2519
+ fontWeight: 400,
2520
+ fontSize: 12,
2521
+ lineHeight: '13px',
2522
+ color: '#0E2238',
2523
+ margin: 0,
2524
+ }}
2525
+ >
2526
+ {t('autobahn:modal.lenderName')}
2527
+ </p>
2528
+ </div>
2529
+ </div>
2432
2530
  <p
2433
- className="md-label-sm"
2434
2531
  style={{
2532
+ fontFamily: 'Arial, Helvetica, sans-serif',
2533
+ fontWeight: 700,
2534
+ fontSize: 13.3,
2535
+ lineHeight: '17px',
2536
+ color: '#0E2238',
2435
2537
  margin: 0,
2436
- paddingTop: 12.5,
2538
+ marginBottom: 7,
2539
+ }}
2540
+ >
2541
+ {t('autobahn:modal.legalNoticesTitle')}
2542
+ </p>
2543
+ <ul style={{ margin: 0, marginBottom: 3, paddingLeft: 16, display: 'flex', flexDirection: 'column', gap: 3 }}>
2544
+ {[
2545
+ t('autobahn:modal.legalNoticeCreditworthiness'),
2546
+ t('autobahn:modal.legalNoticeExample'),
2547
+ t('autobahn:modal.legalNoticeTwoThirds'),
2548
+ t('autobahn:modal.legalNoticeVat'),
2549
+ t('autobahn:modal.legalNoticeAddServices'),
2550
+ ].map((notice) => (
2551
+ <li
2552
+ key={notice}
2553
+ style={{
2554
+ fontFamily: 'Arial, Helvetica, sans-serif',
2555
+ fontWeight: 400,
2556
+ fontSize: 12,
2557
+ lineHeight: '12px',
2558
+ color: '#0E2238',
2559
+ }}
2560
+ >
2561
+ {notice}
2562
+ </li>
2563
+ ))}
2564
+ </ul>
2565
+ <p
2566
+ style={{
2437
2567
  fontFamily: 'Arial, Helvetica, sans-serif',
2438
2568
  fontWeight: 400,
2439
- fontSize: 10,
2440
- lineHeight: '10px',
2441
- color: '#000000',
2569
+ fontSize: 12,
2570
+ lineHeight: '12px',
2571
+ color: '#0E2238',
2572
+ margin: 0,
2573
+ paddingBottom: 10,
2574
+ borderBottom: '1px solid rgba(212, 221, 231, 0.95)',
2442
2575
  }}
2443
2576
  >
2444
- {exampleLine}
2445
- <br />
2446
- {isLease ? t('autobahn:modal.legalLeasing') : t('autobahn:modal.legalFinancing')}
2577
+ {t('autobahn:modal.listPriceFootnote')}
2447
2578
  </p>
2448
- </div>
2579
+ <div className="fin-sheet-cta-row" style={{ display: 'flex', gap: 7, paddingBottom: 15 }}>
2580
+ <Button
2581
+ variant="filled"
2582
+ size="lg"
2583
+ style={{
2584
+ width: 286,
2585
+ height: 50,
2586
+ background: '#005CFF',
2587
+ borderRadius: 16,
2588
+ justifyContent: 'flex-start',
2589
+ paddingLeft: 47,
2590
+ paddingRight: 47,
2591
+ fontFamily: 'Arial, Helvetica, sans-serif',
2592
+ fontWeight: 700,
2593
+ fontSize: 14,
2594
+ lineHeight: '16px',
2595
+ textAlign: 'center',
2596
+ color: '#FFFFFF',
2597
+ }}
2598
+ onClick={onSecure}
2599
+ >
2600
+ <span style={{ display: 'inline-flex', marginRight: 18 }}>
2601
+ <DocCheckIcon size={23} />
2602
+ </span>
2603
+ {t('autobahn:finance.requestRate')}
2604
+ </Button>
2605
+ {/* padding:0 — mbtn--lg's 30px side padding left no room for the icon at width 52 */}
2606
+ <Button
2607
+ variant="outlined"
2608
+ size="lg"
2609
+ icon="phone"
2610
+ className="fin-sheet-call-btn"
2611
+ style={{
2612
+ width: 50,
2613
+ height: 50,
2614
+ flex: 'none',
2615
+ padding: 0,
2616
+ background: '#FFFFFF',
2617
+ border: '1.6px solid #005CFF',
2618
+ borderRadius: 16,
2619
+ }}
2620
+ onClick={onCall}
2621
+ />
2622
+ </div>
2623
+ </>
2449
2624
  )}
2450
2625
  </>
2451
2626
  )}