@redsift/products 12.5.8 → 12.5.9-muiv6

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.
@@ -3024,8 +3024,8 @@ function useCollapseController(_ref) {
3024
3024
  */
3025
3025
 
3026
3026
  // Default fallback values - use DS CSS variables with hardcoded ultimate fallbacks
3027
- const DS_FONT_BODY$9 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
3028
- const DS_TEXT_COLOR$5 = 'var(--redsift-color-neutral-x-dark-grey, #3B3A58)';
3027
+ const DS_FONT_BODY$8 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
3028
+ const DS_TEXT_COLOR$4 = 'var(--redsift-color-neutral-x-dark-grey, #3B3A58)';
3029
3029
 
3030
3030
  /**
3031
3031
  * Intro text container for signal cards.
@@ -3037,8 +3037,8 @@ const StyledIntroText = styled.div`
3037
3037
  margin-bottom: 0.75rem;
3038
3038
  font-size: 14px;
3039
3039
  line-height: 1.5;
3040
- font-family: var(--sc-font-body, ${DS_FONT_BODY$9});
3041
- color: var(--sc-text-color, ${DS_TEXT_COLOR$5});
3040
+ font-family: var(--sc-font-body, ${DS_FONT_BODY$8});
3041
+ color: var(--sc-text-color, ${DS_TEXT_COLOR$4});
3042
3042
 
3043
3043
  strong {
3044
3044
  font-weight: 600;
@@ -3080,18 +3080,18 @@ const StyledCardFooter = styled.div`
3080
3080
  // ============================================================================
3081
3081
 
3082
3082
  // Default fallback values - use DS CSS variables with hardcoded ultimate fallbacks
3083
- const DS_FONT_BODY$8 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
3084
- const DS_TEXT_COLOR$4 = 'var(--redsift-color-neutral-x-dark-grey, #3B3A58)';
3083
+ const DS_FONT_BODY$7 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
3084
+ const DS_TEXT_COLOR$3 = 'var(--redsift-color-neutral-x-dark-grey, #3B3A58)';
3085
3085
  const DS_LINK_COLOR$1 = 'var(--redsift-color-notifications-info-primary, #4285f4)';
3086
3086
  const DescriptionContainer = styled.div`
3087
3087
  display: flex;
3088
3088
  flex-direction: column;
3089
3089
  `;
3090
3090
  const DescriptionText = styled.div`
3091
- font-family: var(--sc-font-body, ${DS_FONT_BODY$8});
3091
+ font-family: var(--sc-font-body, ${DS_FONT_BODY$7});
3092
3092
  font-size: 14px;
3093
3093
  line-height: 1.5;
3094
- color: var(--sc-text-color, ${DS_TEXT_COLOR$4});
3094
+ color: var(--sc-text-color, ${DS_TEXT_COLOR$3});
3095
3095
 
3096
3096
  p {
3097
3097
  margin: 0 0 1rem;
@@ -3384,7 +3384,7 @@ ExpandableDescription.displayName = 'ExpandableDescription';
3384
3384
  // these will be overridden with Investigate-specific fonts.
3385
3385
 
3386
3386
  // Default fallback values - use DS CSS variables with hardcoded ultimate fallbacks
3387
- const DS_FONT_BODY$7 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
3387
+ const DS_FONT_BODY$6 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
3388
3388
  const StyledContainer$1 = styled.div`
3389
3389
  display: ${_ref => {
3390
3390
  let {
@@ -3407,14 +3407,14 @@ const StyledContainer$1 = styled.div`
3407
3407
  } = _ref3;
3408
3408
  return $borderBottom && $marginBottom === 0 ? '0.5rem' : `${$marginBottom}px`;
3409
3409
  }};
3410
- font-family: var(--sc-font-body, ${DS_FONT_BODY$7});
3410
+ font-family: var(--sc-font-body, ${DS_FONT_BODY$6});
3411
3411
 
3412
3412
  &:first-child {
3413
3413
  margin-top: 0;
3414
3414
  }
3415
3415
 
3416
3416
  > h2 {
3417
- font-family: var(--sc-font-body, ${DS_FONT_BODY$7});
3417
+ font-family: var(--sc-font-body, ${DS_FONT_BODY$6});
3418
3418
  font-size: 1.35rem;
3419
3419
  font-weight: 600;
3420
3420
  margin: 0 0 0.25rem;
@@ -3452,9 +3452,9 @@ var SignalCardSection$1 = SignalCardSection;
3452
3452
  // ============================================================================
3453
3453
 
3454
3454
  // Default fallback values - use DS CSS variables with hardcoded ultimate fallbacks
3455
- const DS_FONT_BODY$6 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
3455
+ const DS_FONT_BODY$5 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
3456
3456
  const DS_FONT_CODE$2 = "var(--redsift-typography-font-family-source-code-pro, 'Source Code Pro', monospace)";
3457
- const DS_TEXT_COLOR$3 = 'var(--redsift-color-neutral-x-dark-grey, #3B3A58)';
3457
+ const DS_TEXT_COLOR$2 = 'var(--redsift-color-neutral-x-dark-grey, #3B3A58)';
3458
3458
  const DS_BG_LIGHT$2 = 'var(--redsift-color-neutral-x-light-grey, #EAEAED)';
3459
3459
  const InfoItemContainer = styled.div`
3460
3460
  padding: ${_ref => {
@@ -3474,10 +3474,10 @@ const InfoItemRow = styled.div`
3474
3474
  }};
3475
3475
  gap: 0.75rem;
3476
3476
  flex-wrap: wrap;
3477
- font-family: var(--sc-font-body, ${DS_FONT_BODY$6});
3477
+ font-family: var(--sc-font-body, ${DS_FONT_BODY$5});
3478
3478
  font-size: 14px;
3479
3479
  line-height: 1.5;
3480
- color: var(--sc-text-color, ${DS_TEXT_COLOR$3});
3480
+ color: var(--sc-text-color, ${DS_TEXT_COLOR$2});
3481
3481
  `;
3482
3482
  const InfoItemIcon = styled.span`
3483
3483
  display: inline-flex;
@@ -3540,10 +3540,10 @@ const InfoItemLabel = styled.span`
3540
3540
  `;
3541
3541
  const InfoItemSubtexts = styled.div`
3542
3542
  margin: 0;
3543
- font-family: var(--sc-font-body, ${DS_FONT_BODY$6});
3543
+ font-family: var(--sc-font-body, ${DS_FONT_BODY$5});
3544
3544
  font-size: 14px;
3545
3545
  line-height: 1.5;
3546
- color: var(--sc-text-color, ${DS_TEXT_COLOR$3});
3546
+ color: var(--sc-text-color, ${DS_TEXT_COLOR$2});
3547
3547
 
3548
3548
  ${_ref6 => {
3549
3549
  let {
@@ -3568,7 +3568,7 @@ const InfoItemSubtexts = styled.div`
3568
3568
  code {
3569
3569
  background-color: var(--sc-code-bg, ${DS_BG_LIGHT$2});
3570
3570
  font-family: var(--sc-font-code, ${DS_FONT_CODE$2});
3571
- color: var(--sc-text-color, ${DS_TEXT_COLOR$3});
3571
+ color: var(--sc-text-color, ${DS_TEXT_COLOR$2});
3572
3572
  padding: 0.2em 0.5em;
3573
3573
  border-radius: 3px;
3574
3574
  white-space: pre-wrap;
@@ -3593,7 +3593,7 @@ const InfoItemList = styled.ul`
3593
3593
  code {
3594
3594
  background-color: var(--sc-code-bg, ${DS_BG_LIGHT$2});
3595
3595
  font-family: var(--sc-font-code, ${DS_FONT_CODE$2});
3596
- color: var(--sc-text-color, ${DS_TEXT_COLOR$3});
3596
+ color: var(--sc-text-color, ${DS_TEXT_COLOR$2});
3597
3597
  padding: 0.2em 0.5em;
3598
3598
  border-radius: 3px;
3599
3599
  white-space: pre-wrap;
@@ -3610,7 +3610,7 @@ const InfoItemList = styled.ul`
3610
3610
  const InfoItemCodeBlock = styled.pre`
3611
3611
  background-color: var(--sc-code-bg, ${DS_BG_LIGHT$2});
3612
3612
  font-family: var(--sc-font-code, ${DS_FONT_CODE$2});
3613
- color: var(--sc-text-color, ${DS_TEXT_COLOR$3});
3613
+ color: var(--sc-text-color, ${DS_TEXT_COLOR$2});
3614
3614
  font-size: 14px;
3615
3615
  padding: 0.5em;
3616
3616
  border-radius: 4px;
@@ -3653,10 +3653,10 @@ InfoItemsWrapper.displayName = 'InfoItemsWrapper';
3653
3653
  // these will be overridden with Investigate-specific fonts.
3654
3654
 
3655
3655
  // Default fallback values - use DS CSS variables with hardcoded ultimate fallbacks
3656
- const DS_FONT_BODY$5 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
3656
+ const DS_FONT_BODY$4 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
3657
3657
  const StyledContainer = styled.div`
3658
3658
  border-radius: 4px;
3659
- font-family: var(--sc-font-body, ${DS_FONT_BODY$5});
3659
+ font-family: var(--sc-font-body, ${DS_FONT_BODY$4});
3660
3660
  > div {
3661
3661
  display: grid;
3662
3662
  padding: 0;
@@ -3697,7 +3697,7 @@ var SignalCardInfoBox$1 = SignalCardInfoBox;
3697
3697
  // these will be overridden with Investigate-specific fonts.
3698
3698
 
3699
3699
  // Default fallback values - use DS CSS variables with hardcoded ultimate fallbacks
3700
- const DS_FONT_BODY$4 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
3700
+ const DS_FONT_BODY$3 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
3701
3701
  const DEFAULT_PALETTE = {
3702
3702
  base: '#e5e5e5',
3703
3703
  hover: '#d6d6d6'
@@ -3766,7 +3766,7 @@ const StyledGlossaryTag = styled.a`
3766
3766
  user-select: none;
3767
3767
  font-size: 14px;
3768
3768
  font-weight: 400;
3769
- font-family: var(--sc-font-body, ${DS_FONT_BODY$4});
3769
+ font-family: var(--sc-font-body, ${DS_FONT_BODY$3});
3770
3770
  white-space: nowrap;
3771
3771
  line-height: 1.3;
3772
3772
  color: ${COLOR.grey.darkest} !important;
@@ -4671,26 +4671,26 @@ const EXTRACTION_CAPTION_KEYS = {
4671
4671
  // ============================================================================
4672
4672
 
4673
4673
  // Default fallback values - use DS CSS variables with hardcoded ultimate fallbacks
4674
- const DS_FONT_BODY$3 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
4674
+ const DS_FONT_BODY$2 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
4675
4675
  const DS_FONT_CODE$1 = "var(--redsift-typography-font-family-source-code-pro, 'Source Code Pro', monospace)";
4676
- const DS_TEXT_COLOR$2 = 'var(--redsift-color-neutral-x-dark-grey, #3B3A58)';
4676
+ const DS_TEXT_COLOR$1 = 'var(--redsift-color-neutral-x-dark-grey, #3B3A58)';
4677
4677
  const DS_BG_LIGHT$1 = 'var(--redsift-color-neutral-x-light-grey, #EAEAED)';
4678
4678
  styled.div`
4679
4679
  padding: 0;
4680
4680
  margin-bottom: 0.25rem;
4681
- font-family: var(--sc-font-body, ${DS_FONT_BODY$3});
4681
+ font-family: var(--sc-font-body, ${DS_FONT_BODY$2});
4682
4682
  line-height: normal;
4683
4683
  `;
4684
4684
  styled.span`
4685
4685
  margin: 0;
4686
4686
  margin-right: 0.5rem;
4687
- font-family: var(--sc-font-body, ${DS_FONT_BODY$3});
4687
+ font-family: var(--sc-font-body, ${DS_FONT_BODY$2});
4688
4688
  font-size: 16px;
4689
4689
  font-weight: 600;
4690
- color: var(--sc-text-color, ${DS_TEXT_COLOR$2});
4690
+ color: var(--sc-text-color, ${DS_TEXT_COLOR$1});
4691
4691
  `;
4692
4692
  styled.span`
4693
- font-family: var(--sc-font-body, ${DS_FONT_BODY$3});
4693
+ font-family: var(--sc-font-body, ${DS_FONT_BODY$2});
4694
4694
  font-size: 12px;
4695
4695
  font-weight: 400;
4696
4696
  color: ${COLOR.grey.medium};
@@ -4745,10 +4745,10 @@ const InfoItemsGrid = styled.div`
4745
4745
  word-break: break-word;
4746
4746
  border-radius: ${props => props.$insideCollapsible ? '0' : '4px'};
4747
4747
  margin: ${props => props.$insideCollapsible ? '0' : 'initial'};
4748
- font-family: var(--sc-font-body, ${DS_FONT_BODY$3});
4748
+ font-family: var(--sc-font-body, ${DS_FONT_BODY$2});
4749
4749
  font-size: 14px;
4750
4750
  line-height: 1.5;
4751
- color: var(--sc-text-color, ${DS_TEXT_COLOR$2});
4751
+ color: var(--sc-text-color, ${DS_TEXT_COLOR$1});
4752
4752
  `;
4753
4753
  const GridLabel = styled.div`
4754
4754
  display: flex;
@@ -4768,10 +4768,10 @@ const GridLabel = styled.div`
4768
4768
  const GridValue = styled.div`
4769
4769
  display: flex;
4770
4770
  align-items: center;
4771
- font-family: var(--sc-font-body, ${DS_FONT_BODY$3});
4771
+ font-family: var(--sc-font-body, ${DS_FONT_BODY$2});
4772
4772
  font-size: 14px;
4773
4773
  font-weight: 600;
4774
- color: var(--sc-text-color, ${DS_TEXT_COLOR$2});
4774
+ color: var(--sc-text-color, ${DS_TEXT_COLOR$1});
4775
4775
  word-break: break-all;
4776
4776
 
4777
4777
  p {
@@ -4796,7 +4796,7 @@ const GridValue = styled.div`
4796
4796
  const CodeBlock = styled.div`
4797
4797
  font-family: var(--sc-font-code, ${DS_FONT_CODE$1});
4798
4798
  font-size: 14px;
4799
- color: var(--sc-text-color, ${DS_TEXT_COLOR$2});
4799
+ color: var(--sc-text-color, ${DS_TEXT_COLOR$1});
4800
4800
  border-radius: 4px;
4801
4801
  width: 100%;
4802
4802
  word-break: break-all;
@@ -4823,9 +4823,9 @@ InfoItemsHighlight.displayName = 'InfoItemsHighlight';
4823
4823
  // these will be overridden with Investigate-specific fonts.
4824
4824
 
4825
4825
  // Default fallback values - use DS CSS variables with hardcoded ultimate fallbacks
4826
- const DS_FONT_BODY$2 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
4826
+ const DS_FONT_BODY$1 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
4827
4827
  const DS_FONT_CODE = "var(--redsift-typography-font-family-source-code-pro, 'Source Code Pro', monospace)";
4828
- const DS_TEXT_COLOR$1 = 'var(--redsift-color-neutral-x-dark-grey, #3B3A58)';
4828
+ const DS_TEXT_COLOR = 'var(--redsift-color-neutral-x-dark-grey, #3B3A58)';
4829
4829
  const DS_LINK_COLOR = 'var(--redsift-color-notifications-info-primary, #4285f4)';
4830
4830
  const DS_BG_LIGHT = 'var(--redsift-color-neutral-x-light-grey, #EAEAED)';
4831
4831
  const StyledChecklistContainer = styled.div`
@@ -4895,7 +4895,7 @@ const StyledItemText = styled.div`
4895
4895
  } = _ref8;
4896
4896
  return $compact ? '0.5rem' : '0.75rem';
4897
4897
  }};
4898
- font-family: var(--sc-font-body, ${DS_FONT_BODY$2});
4898
+ font-family: var(--sc-font-body, ${DS_FONT_BODY$1});
4899
4899
  font-size: 0.875rem;
4900
4900
  line-height: ${_ref9 => {
4901
4901
  let {
@@ -4903,7 +4903,7 @@ const StyledItemText = styled.div`
4903
4903
  } = _ref9;
4904
4904
  return $compact ? '1.4' : '2';
4905
4905
  }};
4906
- color: var(--sc-text-color, ${DS_TEXT_COLOR$1});
4906
+ color: var(--sc-text-color, ${DS_TEXT_COLOR});
4907
4907
  min-width: 0; /* Allow flex container to shrink */
4908
4908
 
4909
4909
  @media (max-width: 480px) {
@@ -4960,7 +4960,7 @@ const StyledContent = styled.span`
4960
4960
 
4961
4961
  code {
4962
4962
  background-color: var(--sc-code-bg, ${DS_BG_LIGHT});
4963
- color: var(--sc-text-color, ${DS_TEXT_COLOR$1});
4963
+ color: var(--sc-text-color, ${DS_TEXT_COLOR});
4964
4964
  border-radius: 4px;
4965
4965
  padding: 0 0.25rem;
4966
4966
  word-break: break-word;
@@ -4968,10 +4968,10 @@ const StyledContent = styled.span`
4968
4968
  `;
4969
4969
  const StyledSubtexts = styled.div`
4970
4970
  margin: 0.5em 0 0.5em 0;
4971
- font-family: var(--sc-font-body, ${DS_FONT_BODY$2});
4971
+ font-family: var(--sc-font-body, ${DS_FONT_BODY$1});
4972
4972
  font-size: 0.875rem;
4973
4973
  line-height: 2;
4974
- color: var(--sc-text-color, ${DS_TEXT_COLOR$1});
4974
+ color: var(--sc-text-color, ${DS_TEXT_COLOR});
4975
4975
 
4976
4976
  display: flex;
4977
4977
  flex-direction: column;
@@ -4996,7 +4996,7 @@ const StyledSubtexts = styled.div`
4996
4996
  code {
4997
4997
  background-color: var(--sc-code-bg, ${DS_BG_LIGHT});
4998
4998
  font-family: var(--sc-font-code, ${DS_FONT_CODE});
4999
- color: var(--sc-text-color, ${DS_TEXT_COLOR$1});
4999
+ color: var(--sc-text-color, ${DS_TEXT_COLOR});
5000
5000
  padding: 0.2em 0.5em;
5001
5001
  border-radius: 3px;
5002
5002
  white-space: pre-wrap;
@@ -5472,7 +5472,7 @@ const Slider = styled.span`
5472
5472
  }};
5473
5473
  }
5474
5474
  `;
5475
- const StyledLabel$1 = styled.label`
5475
+ const StyledLabel = styled.label`
5476
5476
  display: inline-flex;
5477
5477
  align-items: center;
5478
5478
  ${_ref21 => {
@@ -5553,7 +5553,7 @@ const CheckBox = _ref22 => {
5553
5553
  $selected: selected,
5554
5554
  $accentColor: accentColor,
5555
5555
  $disabled: disabled
5556
- }) : null)), id && /*#__PURE__*/React__default.createElement(StyledLabel$1, {
5556
+ }) : null)), id && /*#__PURE__*/React__default.createElement(StyledLabel, {
5557
5557
  htmlFor: id,
5558
5558
  $alignLabel: alignLabel,
5559
5559
  $hasChildren: Boolean(children)
@@ -6468,7 +6468,7 @@ const _excluded$4 = ["isOpen", "parentRef", "ContentComponent", "placement", "st
6468
6468
  // these will be overridden with Investigate-specific fonts.
6469
6469
 
6470
6470
  // Default fallback values - use DS CSS variables with hardcoded ultimate fallbacks
6471
- const DS_FONT_BODY$1 = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
6471
+ const DS_FONT_BODY = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
6472
6472
 
6473
6473
  /**
6474
6474
  * TooltipInPortal Component
@@ -6511,7 +6511,7 @@ const TooltipStyled = styled(Tooltip$1)`
6511
6511
  & .tooltip__content {
6512
6512
  padding: 8px;
6513
6513
  font-size: 13px;
6514
- font-family: var(--sc-font-body, ${DS_FONT_BODY$1});
6514
+ font-family: var(--sc-font-body, ${DS_FONT_BODY});
6515
6515
  min-width: 260px;
6516
6516
  max-width: 320px;
6517
6517
  }
@@ -7281,16 +7281,7 @@ const BIMI_KEY_TO_TESTID = {
7281
7281
  'card.bimi.vmc-not-vmc-title_md': 'vmc-validity-invalid',
7282
7282
  'card.bimi.pemErrors.cert-not-found_md': 'vmc-cert-not-found',
7283
7283
  'card.bimi.vmc.expired-date_md': 'vmc-expiration-expired',
7284
- 'card.bimi.vmc.expiry-date_md': 'vmc-expiration-valid',
7285
- // Legacy VMC rows superseded by the DS-93 published-certificate sections.
7286
- // Stamped with stable testids so SignalCardBimi can suppress them by testid
7287
- // rather than by fragile label-text matching (see SignalCardBimi vmcSection).
7288
- 'card.bimi.vmc.issuer_md': 'vmc-issuer',
7289
- 'card.bimi.vmc.valid-for-domain_md': 'vmc-valid-for-domains',
7290
- 'card.bimi.vmc.trademarkAuthority_md': 'vmc-trademark-authority',
7291
- // Legacy "Assertion Mark:" row — duplicated by Mark evidence › "Mark type:"
7292
- // (both render the trademark mark class, e.g. "Registered Mark").
7293
- 'card.bimi.vmc.assertionMark_md': 'vmc-assertion-mark'
7284
+ 'card.bimi.vmc.expiry-date_md': 'vmc-expiration-valid'
7294
7285
  };
7295
7286
 
7296
7287
  // =============================================================================
@@ -8054,438 +8045,6 @@ const uncompressLogo = svgUrl => {
8054
8045
 
8055
8046
  var SVGLogo$1 = SVGLogo;
8056
8047
 
8057
- const DAY_MS = 24 * 60 * 60 * 1000;
8058
-
8059
- /**
8060
- * Amber-warning window: certificates within this many days of expiry surface an
8061
- * amber status pill rather than green, giving operators a heads-up before it
8062
- * lapses. Anything past expiry is red.
8063
- */
8064
- const EXPIRY_WARNING_DAYS = 30;
8065
- const DS_FONT_BODY = "var(--redsift-typography-body-font-family, 'Poppins', sans-serif)";
8066
- const DS_TEXT_COLOR = 'var(--redsift-color-neutral-x-dark-grey, #3B3A58)';
8067
- const DS_TEXT_MUTED = 'var(--redsift-color-neutral-dark-grey, #6E6D83)';
8068
- const DS_BORDER = 'var(--redsift-color-neutral-light-grey, #D9D8DE)';
8069
- const DS_GREEN = 'var(--redsift-color-notifications-success-primary, #2e7d32)';
8070
- const DS_AMBER = 'var(--redsift-color-notifications-warning-primary, #f5a623)';
8071
- const DS_RED = 'var(--redsift-color-notifications-error-primary, #d32f2f)';
8072
-
8073
- /**
8074
- * Parse an ISO date/datetime string to a Date. Accepts both bare `YYYY-MM-DD`
8075
- * and full ISO datetimes (`2025-07-29T00:00:00Z`) — the IPForensics
8076
- * publishedCertificate emits the latter. Returns null when the input is missing
8077
- * or unparseable so callers can degrade gracefully.
8078
- */
8079
- const parseCertDate = value => {
8080
- if (!value) return null;
8081
- // A bare YYYY-MM-DD is interpreted as UTC midnight; a full ISO datetime is
8082
- // parsed as-is (it carries its own offset). Anchoring the date-only form to
8083
- // UTC keeps the whole-day arithmetic stable regardless of the viewer's zone.
8084
- const normalized = /^\d{4}-\d{2}-\d{2}$/.test(value) ? `${value}T00:00:00Z` : value;
8085
- const parsed = new Date(normalized);
8086
- return Number.isNaN(parsed.getTime()) ? null : parsed;
8087
- };
8088
-
8089
- /** Whole-day difference between two dates (b - a), truncated toward zero. */
8090
- const diffInDays = (a, b) => Math.trunc((b.getTime() - a.getTime()) / DAY_MS);
8091
-
8092
- /**
8093
- * Format a parsed certificate date as a locale-aware, human-readable day
8094
- * (e.g. "29 Jul 2025") in UTC. UTC keeps the displayed day matching the
8095
- * certificate's own boundary, independent of the viewer's timezone.
8096
- */
8097
- const formatDay = date => new Intl.DateTimeFormat(undefined, {
8098
- day: '2-digit',
8099
- month: 'short',
8100
- year: 'numeric',
8101
- timeZone: 'UTC'
8102
- }).format(date);
8103
- const StyledWidget = styled.div`
8104
- display: flex;
8105
- flex-wrap: wrap;
8106
- align-items: stretch;
8107
- gap: 1px;
8108
- border: 1px solid var(--sc-border-color, ${DS_BORDER});
8109
- border-radius: 8px;
8110
- overflow: hidden;
8111
- /* The 1px flex gaps reveal this divider colour between cells; cells sit on a
8112
- lighter surface (below) so the columns read as distinct, not one slab. */
8113
- background: var(--sc-border-color, ${DS_BORDER});
8114
- font-family: var(--sc-font-body, ${DS_FONT_BODY});
8115
- `;
8116
- const StyledCell = styled.div`
8117
- flex: 1 1 33%;
8118
- min-width: 120px;
8119
- display: flex;
8120
- flex-direction: column;
8121
- gap: 0.25rem;
8122
- padding: 0.75rem 1rem;
8123
- /* Section surface — x-light-grey (#f4f4f6) matches the other card sections.
8124
- It is lighter than the divider (light-grey) so the 1px gaps still read as
8125
- hairlines between cells. */
8126
- background: var(--redsift-color-neutral-x-light-grey, #f4f4f6);
8127
- `;
8128
- const StyledLabel = styled.span`
8129
- font-size: 0.6875rem;
8130
- font-weight: 600;
8131
- letter-spacing: 0.05em;
8132
- text-transform: uppercase;
8133
- color: var(--sc-text-muted, ${DS_TEXT_MUTED});
8134
- `;
8135
- const StyledValue = styled.span`
8136
- font-size: 0.9375rem;
8137
- font-weight: 600;
8138
- color: var(--sc-text-color, ${DS_TEXT_COLOR});
8139
- `;
8140
- const statusColor = status => {
8141
- switch (status) {
8142
- case 'valid':
8143
- return DS_GREEN;
8144
- case 'expiring':
8145
- return DS_AMBER;
8146
- case 'expired':
8147
- case 'not-yet-active':
8148
- return DS_RED;
8149
- }
8150
- };
8151
- const StyledPill = styled.span`
8152
- display: inline-flex;
8153
- align-items: center;
8154
- gap: 0.4rem;
8155
- align-self: flex-start;
8156
- padding: 0.125rem 0;
8157
- font-size: 0.9375rem;
8158
- font-weight: 600;
8159
- color: ${_ref => {
8160
- let {
8161
- $status
8162
- } = _ref;
8163
- return statusColor($status);
8164
- }};
8165
-
8166
- &::before {
8167
- content: '';
8168
- width: 0.5rem;
8169
- height: 0.5rem;
8170
- border-radius: 50%;
8171
- background: currentColor;
8172
- flex-shrink: 0;
8173
- }
8174
- `;
8175
- /**
8176
- * A glanceable three-part certificate-validity widget: the issue date, the
8177
- * expiry date, and a color-coded status pill counting down (or up, once
8178
- * expired) the days to expiry. Replaces the previous prose validity rows so the
8179
- * issue date and remaining validity are legible at a glance (DS-93 feedback).
8180
- *
8181
- * All copy routes through `t` and stays translatable; the humanized durations
8182
- * are a render-layer concern (the API returns only the raw dates). Renders
8183
- * nothing when neither date is parseable.
8184
- */
8185
- const CertificateValidityWidget = _ref2 => {
8186
- let {
8187
- validFrom,
8188
- expiry,
8189
- t,
8190
- now,
8191
- 'data-testid': testId
8192
- } = _ref2;
8193
- const from = parseCertDate(validFrom);
8194
- const to = parseCertDate(expiry);
8195
- if (!from && !to) return null;
8196
-
8197
- // Days remaining until expiry (negative once past). The expiry boundary day
8198
- // itself is treated as "expires today" — not remaining validity.
8199
- const daysToExpiry = to ? diffInDays(now, to) : null;
8200
- // Not-yet-active takes precedence: a future start date means the cert isn't in
8201
- // force yet, whatever the expiry says.
8202
- const notYetActive = from ? diffInDays(now, from) > 0 : false;
8203
- let status;
8204
- let statusLabel;
8205
- if (notYetActive) {
8206
- status = 'not-yet-active';
8207
- statusLabel = t('card.bimi.vmc.cert-status-not-yet-active');
8208
- } else if (daysToExpiry === null) {
8209
- // No expiry date but an active start — treat as valid with no countdown.
8210
- status = 'valid';
8211
- statusLabel = t('card.bimi.vmc.cert-status-valid');
8212
- } else if (daysToExpiry < 0) {
8213
- status = 'expired';
8214
- statusLabel = t('card.bimi.vmc.cert-status-expired', {
8215
- count: Math.abs(daysToExpiry)
8216
- });
8217
- } else if (daysToExpiry === 0) {
8218
- status = 'expiring';
8219
- statusLabel = t('card.bimi.vmc.cert-status-expires-today');
8220
- } else {
8221
- status = daysToExpiry <= EXPIRY_WARNING_DAYS ? 'expiring' : 'valid';
8222
- statusLabel = t('card.bimi.vmc.cert-status-days-left', {
8223
- count: daysToExpiry
8224
- });
8225
- }
8226
- return /*#__PURE__*/React__default.createElement(StyledWidget, {
8227
- "data-testid": testId
8228
- }, from && /*#__PURE__*/React__default.createElement(StyledCell, {
8229
- "data-testid": "bimi-cert-validity-issued"
8230
- }, /*#__PURE__*/React__default.createElement(StyledLabel, null, t('card.bimi.vmc.cert-issued-label')), /*#__PURE__*/React__default.createElement(StyledValue, null, formatDay(from))), to && /*#__PURE__*/React__default.createElement(StyledCell, {
8231
- "data-testid": "bimi-cert-validity-expires"
8232
- }, /*#__PURE__*/React__default.createElement(StyledLabel, null, t('card.bimi.vmc.cert-expires-label')), /*#__PURE__*/React__default.createElement(StyledValue, null, formatDay(to))), /*#__PURE__*/React__default.createElement(StyledCell, {
8233
- "data-testid": "bimi-cert-validity-status"
8234
- }, /*#__PURE__*/React__default.createElement(StyledLabel, null, t('card.bimi.vmc.cert-status-label')), /*#__PURE__*/React__default.createElement(StyledPill, {
8235
- $status: status,
8236
- "data-testid": `bimi-cert-validity-pill-${status}`
8237
- }, statusLabel)));
8238
- };
8239
- CertificateValidityWidget.displayName = 'CertificateValidityWidget';
8240
-
8241
- /**
8242
- * A rendered published-certificate section: a titled group of Checklist items.
8243
- */
8244
-
8245
- /**
8246
- * Reference URL for the BIMI certificate-type explainer, used by the VMC/CMC
8247
- * type badge. Follows the existing external-link convention in the card.
8248
- */
8249
- const CERT_TYPE_REFERENCE_URL = 'https://bimigroup.org/verified-mark-certificates-vmc-and-bimi/';
8250
-
8251
- /** Join defined, non-empty parts with a separator; undefined when nothing remains. */
8252
- const joinParts = function (parts) {
8253
- let sep = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ', ';
8254
- const filtered = parts.map(p => p === null || p === void 0 ? void 0 : p.trim()).filter(p => !!p);
8255
- return filtered.length ? filtered.join(sep) : undefined;
8256
- };
8257
-
8258
- /**
8259
- * Build a single info ChecklistItem when its value is present. Returns null so
8260
- * callers can filter absent fields out and only render populated rows.
8261
- */
8262
- const infoRow = (t, key, params, testId, value) => {
8263
- if (!value) return null;
8264
- // 'no-icon' renders the label/value with no leading icon — these dense
8265
- // metadata rows read as a plain key/value list, so an info dot per row is
8266
- // just noise.
8267
- return {
8268
- type: 'no-icon',
8269
- text: t(key, params),
8270
- 'data-testid': testId
8271
- };
8272
- };
8273
-
8274
- /** External-link anchor rendered inline inside a Checklist item. */
8275
- const ExternalLink = _ref => {
8276
- let {
8277
- href,
8278
- children,
8279
- 'data-testid': testId
8280
- } = _ref;
8281
- return /*#__PURE__*/React__default.createElement("a", {
8282
- href: href,
8283
- target: "_blank",
8284
- rel: "noopener noreferrer",
8285
- "data-testid": testId
8286
- }, children);
8287
- };
8288
-
8289
- /**
8290
- * Build the five published-certificate sections (Validity, Certificate, Subject
8291
- * identity, Mark evidence, Verification issues) from IPForensics
8292
- * VmcPublishedCertificate + VmcPemEvidence data.
8293
- *
8294
- * `assertionMarkType` ('VMC' | 'CMC') is the certificate type and lives on the
8295
- * parent `vmc` object, NOT inside the published certificate — the certificate's
8296
- * own `markType` field is the trademark mark *class* ("Registered Mark" etc.),
8297
- * which is rendered separately under Mark evidence. The "Certificate type:" row
8298
- * must use `assertionMarkType`.
8299
- *
8300
- * All labels come from @redsift/signal-logic BIMI_KEYS via `t` so they remain
8301
- * translatable. `now` is injected for deterministic humanized durations in
8302
- * tests and stories.
8303
- */
8304
- const buildPublishedCertificateSections = (cert, pem, t, now, assertionMarkType) => {
8305
- var _cert$certifiedDomain, _cert$certifiedDomain2, _pem$errors;
8306
- const sections = [];
8307
-
8308
- // --- Validity ---
8309
- // Rendered as a single glanceable widget (issued · expires · days-to-expiry
8310
- // status pill) rather than prose rows, so the issue date and remaining
8311
- // validity read at a glance (DS-93 feedback). The widget returns null when
8312
- // neither date is parseable; only add the section when it has something to
8313
- // show. It is carried as an 'image'-type Checklist item so it escapes the
8314
- // key/value row layout and spans the section width (same slot SVGLogo uses).
8315
- const hasValidityDates = !!parseCertDate(cert.validFrom) || !!parseCertDate(cert.expiry);
8316
- if (hasValidityDates) {
8317
- sections.push({
8318
- id: 'bimi-cert-validity',
8319
- title: t('card.bimi.vmc.cert-section-validity'),
8320
- items: [{
8321
- type: 'image',
8322
- 'data-testid': 'bimi-cert-validity-widget-item',
8323
- text: /*#__PURE__*/React__default.createElement(CertificateValidityWidget, {
8324
- validFrom: cert.validFrom,
8325
- expiry: cert.expiry,
8326
- t: t,
8327
- now: now,
8328
- "data-testid": "bimi-cert-validity-widget"
8329
- })
8330
- }],
8331
- testId: 'bimi-cert-validity-section'
8332
- });
8333
- }
8334
-
8335
- // --- Certificate ---
8336
- const certItems = [];
8337
- const issuerCommon = infoRow(t, 'card.bimi.vmc.cert-issuer-common-name_md', {
8338
- issuerCommonName: cert.issuerCommonName
8339
- }, 'bimi-cert-issuer-common-name', cert.issuerCommonName);
8340
- if (issuerCommon) certItems.push(issuerCommon);
8341
- const issuerOrg = infoRow(t, 'card.bimi.vmc.cert-issuer-organization_md', {
8342
- issuerOrganization: cert.issuerOrganization
8343
- }, 'bimi-cert-issuer-organization', cert.issuerOrganization);
8344
- if (issuerOrg) certItems.push(issuerOrg);
8345
- const issuerCountry = infoRow(t, 'card.bimi.vmc.cert-issuer-country_md', {
8346
- issuerCountry: cert.issuerCountry
8347
- }, 'bimi-cert-issuer-country', cert.issuerCountry);
8348
- if (issuerCountry) certItems.push(issuerCountry);
8349
-
8350
- // Certificate type row: a bold "Certificate type:" label (which itself
8351
- // contains spaces, e.g. "Certificate type:" / FR "Type de certificat :")
8352
- // with the VMC/CMC value as an external-link badge. We interpolate a NUL
8353
- // sentinel for the value so the label markdown (**…**) parses correctly, then
8354
- // split the template at that exact sentinel and splice the linked badge in
8355
- // where the value goes — only the value links, not the label. Splitting on
8356
- // the sentinel (never a bare space) is what keeps multi-word labels intact.
8357
- //
8358
- // Value is `assertionMarkType` ('VMC'/'CMC') from the parent vmc object — NOT
8359
- // the certificate's own `markType`, which is the trademark mark class and is
8360
- // rendered under Mark evidence instead.
8361
- if (assertionMarkType) {
8362
- const VALUE_TOKEN = '';
8363
- const template = t('card.bimi.vmc.cert-type_md', {
8364
- assertionMarkType: VALUE_TOKEN
8365
- });
8366
- const tokenIndex = template.indexOf(VALUE_TOKEN);
8367
- // If the placeholder is somehow absent, keep the whole label before the
8368
- // badge rather than dropping any text.
8369
- const before = tokenIndex === -1 ? template : template.slice(0, tokenIndex);
8370
- const after = tokenIndex === -1 ? '' : template.slice(tokenIndex + VALUE_TOKEN.length);
8371
- certItems.push({
8372
- type: 'no-icon',
8373
- 'data-testid': 'bimi-cert-type',
8374
- text: /*#__PURE__*/React__default.createElement("span", null, parseGlossaryMarkdown(before), /*#__PURE__*/React__default.createElement(ExternalLink, {
8375
- href: CERT_TYPE_REFERENCE_URL,
8376
- "data-testid": "bimi-cert-type-link"
8377
- }, assertionMarkType), after && parseGlossaryMarkdown(after))
8378
- });
8379
- }
8380
-
8381
- // Certified domains as chips with external links, comma-separated.
8382
- const certifiedDomains = (_cert$certifiedDomain = (_cert$certifiedDomain2 = cert.certifiedDomains) === null || _cert$certifiedDomain2 === void 0 ? void 0 : _cert$certifiedDomain2.filter(d => !!d)) !== null && _cert$certifiedDomain !== void 0 ? _cert$certifiedDomain : [];
8383
- if (certifiedDomains.length) {
8384
- certItems.push({
8385
- type: 'no-icon',
8386
- 'data-testid': 'bimi-cert-certified-domains',
8387
- text: /*#__PURE__*/React__default.createElement("span", {
8388
- "data-testid": "bimi-cert-certified-domains-chips"
8389
- }, certifiedDomains.map((domain, idx) => /*#__PURE__*/React__default.createElement(React__default.Fragment, {
8390
- key: domain
8391
- }, idx > 0 && ', ', domain.includes('*') ? domain : /*#__PURE__*/React__default.createElement(ExternalLink, {
8392
- href: `https://${domain}`
8393
- }, domain))))
8394
- });
8395
- }
8396
- if (certItems.length) {
8397
- sections.push({
8398
- id: 'bimi-cert-certificate',
8399
- title: t('card.bimi.vmc.cert-section-certificate'),
8400
- items: certItems,
8401
- testId: 'bimi-cert-certificate-section'
8402
- });
8403
- }
8404
-
8405
- // --- Subject identity ---
8406
- const jurisdiction = joinParts([cert.jurisdictionLocality, cert.jurisdictionStateOrProvince, cert.jurisdictionCountry]);
8407
- const address = joinParts([cert.streetAddress, cert.locality, cert.stateOrProvince, cert.country]);
8408
- const organizationIdentifier = cert.organizationIdentifier ? cert.organizationIdentifierScheme ? `${cert.organizationIdentifier} (${cert.organizationIdentifierScheme})` : cert.organizationIdentifier : undefined;
8409
- const subjectItems = [infoRow(t, 'card.bimi.vmc.cert-serial-number_md', {
8410
- serialNumber: cert.serialNumber
8411
- }, 'bimi-cert-serial-number', cert.serialNumber), infoRow(t, 'card.bimi.vmc.cert-organization_md', {
8412
- organization: cert.organization
8413
- }, 'bimi-cert-organization', cert.organization), infoRow(t, 'card.bimi.vmc.cert-common-name_md', {
8414
- commonName: cert.commonName
8415
- }, 'bimi-cert-common-name', cert.commonName), infoRow(t, 'card.bimi.vmc.cert-business-category_md', {
8416
- businessCategory: cert.businessCategory
8417
- }, 'bimi-cert-business-category', cert.businessCategory), infoRow(t, 'card.bimi.vmc.cert-organization-identifier_md', {
8418
- organizationIdentifier
8419
- }, 'bimi-cert-organization-identifier', organizationIdentifier), infoRow(t, 'card.bimi.vmc.cert-legal-entity-identifier_md', {
8420
- legalEntityIdentifier: cert.legalEntityIdentifier
8421
- }, 'bimi-cert-legal-entity-identifier', cert.legalEntityIdentifier), infoRow(t, 'card.bimi.vmc.cert-jurisdiction_md', {
8422
- jurisdiction
8423
- }, 'bimi-cert-jurisdiction', jurisdiction), infoRow(t, 'card.bimi.vmc.cert-address_md', {
8424
- address
8425
- }, 'bimi-cert-address', address)].filter(i => i !== null);
8426
- if (subjectItems.length) {
8427
- sections.push({
8428
- id: 'bimi-cert-subject-identity',
8429
- title: t('card.bimi.vmc.cert-section-subject-identity'),
8430
- items: subjectItems,
8431
- testId: 'bimi-cert-subject-identity-section'
8432
- });
8433
- }
8434
-
8435
- // --- Mark evidence ---
8436
- const markItems = [infoRow(t, 'card.bimi.vmc.cert-trademark-registration_md', {
8437
- trademarkRegistration: cert.trademarkRegistration
8438
- }, 'bimi-cert-trademark-registration', cert.trademarkRegistration), infoRow(t, 'card.bimi.vmc.cert-trademark-office_md', {
8439
- trademarkOfficeName: cert.trademarkOfficeName
8440
- }, 'bimi-cert-trademark-office', cert.trademarkOfficeName), infoRow(t, 'card.bimi.vmc.cert-mark-type_md', {
8441
- markType: cert.markType
8442
- }, 'bimi-cert-mark-type', cert.markType), infoRow(t, 'card.bimi.vmc.cert-trademark-country_md', {
8443
- trademarkCountryOrRegion: cert.trademarkCountryOrRegion
8444
- }, 'bimi-cert-trademark-country', cert.trademarkCountryOrRegion)].filter(i => i !== null);
8445
- if (markItems.length) {
8446
- sections.push({
8447
- id: 'bimi-cert-mark-evidence',
8448
- title: t('card.bimi.vmc.cert-section-mark-evidence'),
8449
- items: markItems,
8450
- testId: 'bimi-cert-mark-evidence-section'
8451
- });
8452
- }
8453
-
8454
- // --- Verification issues ---
8455
- // Sourced from PEM evidence errors plus an ambiguous leaf-selection signal.
8456
- const errorMessages = ((_pem$errors = pem === null || pem === void 0 ? void 0 : pem.errors) !== null && _pem$errors !== void 0 ? _pem$errors : []).map(e => typeof e === 'string' ? e : e === null || e === void 0 ? void 0 : e.message).filter(m => !!m);
8457
- const isAmbiguous = (pem === null || pem === void 0 ? void 0 : pem.leafSelectionMethod) === 'AMBIGUOUS';
8458
- const issueItems = [];
8459
- if (isAmbiguous) {
8460
- issueItems.push({
8461
- type: 'warning',
8462
- text: t('card.bimi.vmc.cert-ambiguous-leaf_md'),
8463
- 'data-testid': 'bimi-cert-issue-ambiguous'
8464
- });
8465
- }
8466
- errorMessages.forEach((message, idx) => {
8467
- issueItems.push({
8468
- type: 'warning',
8469
- text: message,
8470
- 'data-testid': `bimi-cert-issue-${idx}`
8471
- });
8472
- });
8473
- if (!issueItems.length) {
8474
- issueItems.push({
8475
- type: 'good',
8476
- text: t('card.bimi.vmc.cert-no-issues-reported_md'),
8477
- 'data-testid': 'bimi-cert-no-issues'
8478
- });
8479
- }
8480
- sections.push({
8481
- id: 'bimi-cert-verification-issues',
8482
- title: t('card.bimi.vmc.cert-section-verification-issues'),
8483
- items: issueItems,
8484
- testId: 'bimi-cert-verification-issues-section'
8485
- });
8486
- return sections;
8487
- };
8488
-
8489
8048
  const _excluded$2 = ["jmap", "onHeightChange", "useInvestigateColors", "isCollapsible", "areAllCollapsed", "onCollapseAll", "className"];
8490
8049
  const COMPONENT_NAME$2 = 'SignalCardBimi';
8491
8050
  const CLASSNAME$2 = 'redsift-signal-card-bimi';
@@ -8495,7 +8054,6 @@ const CLASSNAME$2 = 'redsift-signal-card-bimi';
8495
8054
  * BIMI record validation, VMC certificate details, and SVG logo validation.
8496
8055
  */
8497
8056
  const SignalCardBimi = /*#__PURE__*/forwardRef((props, ref) => {
8498
- var _bimi$vmc;
8499
8057
  const {
8500
8058
  t
8501
8059
  } = useSignalCardTranslation('investigate');
@@ -8554,76 +8112,31 @@ const SignalCardBimi = /*#__PURE__*/forwardRef((props, ref) => {
8554
8112
  items
8555
8113
  });
8556
8114
  }, [adapterResult === null || adapterResult === void 0 ? void 0 : adapterResult.svgSection, bimi, isDeclinationToPublish]);
8557
- const hasPublishedCertificate = !!(bimi !== null && bimi !== void 0 && (_bimi$vmc = bimi.vmc) !== null && _bimi$vmc !== void 0 && _bimi$vmc.publishedCertificate);
8558
8115
 
8559
8116
  // Inject SVGLogo into VMC section (React-specific)
8560
8117
  const vmcSection = useMemo(() => {
8561
- var _bimi$vmc2;
8118
+ var _bimi$vmc;
8562
8119
  if (isDeclinationToPublish || !(adapterResult !== null && adapterResult !== void 0 && adapterResult.vmcSection)) return null;
8563
- let items = [...adapterResult.vmcSection.items];
8564
-
8565
- // When the full published certificate is present, the new metadata sections
8566
- // (below) supersede several legacy VMC rows with richer equivalents, so drop
8567
- // the duplicated legacy rows to avoid showing each field twice (DS-93):
8568
- // issuer → Certificate Issuer
8569
- // expiry → Validity › Expiry (matched by testid)
8570
- // valid-for-domains → Certificate › Certified domains
8571
- // trademark authority → Mark evidence › Trademark office
8572
- // assertion mark → Mark evidence › Mark type (both are the mark class)
8573
- // The legacy VMC validity-status row has no equivalent in the new sections
8574
- // and is kept.
8575
- if (hasPublishedCertificate) {
8576
- // Suppress by stable data-testid (stamped in the extractor adapter's
8577
- // BIMI_KEY_TO_TESTID map) rather than by label text. Matching on wording
8578
- // is fragile — a copy change in signal-logic would silently stop matching
8579
- // and reintroduce the duplicated rows. The adapter owns these testids:
8580
- // issuer → vmc-issuer (Certificate › Issuer)
8581
- // valid-for-domains → vmc-valid-for-domains (Certificate › Certified domains)
8582
- // trademark authority → vmc-trademark-authority (Mark evidence › Trademark office)
8583
- // expiry → vmc-expiration-* (Validity › Expiry)
8584
- const suppressedTestIds = new Set(['vmc-issuer', 'vmc-valid-for-domains', 'vmc-trademark-authority', 'vmc-assertion-mark', 'vmc-expiration-valid', 'vmc-expiration-expired']);
8585
- items = items.filter(item => {
8586
- const testId = item['data-testid'];
8587
- return !(testId && suppressedTestIds.has(testId));
8588
- });
8589
- }
8590
- const logoSrc = bimi === null || bimi === void 0 ? void 0 : (_bimi$vmc2 = bimi.vmc) === null || _bimi$vmc2 === void 0 ? void 0 : _bimi$vmc2.logoSrc;
8591
- if (logoSrc) {
8592
- // Insert logo before the first 'no-icon' item (matching original helpers behavior)
8593
- const noIconIdx = items.findIndex(item => item.type === 'no-icon');
8594
- const svgItem = {
8595
- text: /*#__PURE__*/React__default.createElement(SVGLogo$1, {
8596
- svgUrl: logoSrc
8597
- }),
8598
- type: 'image'
8599
- };
8600
- if (noIconIdx >= 0) {
8601
- items.splice(noIconIdx, 0, svgItem);
8602
- } else {
8603
- items.push(svgItem);
8604
- }
8120
+ const logoSrc = bimi === null || bimi === void 0 ? void 0 : (_bimi$vmc = bimi.vmc) === null || _bimi$vmc === void 0 ? void 0 : _bimi$vmc.logoSrc;
8121
+ if (!logoSrc) return adapterResult.vmcSection;
8122
+ const items = [...adapterResult.vmcSection.items];
8123
+ // Insert logo before the first 'no-icon' item (matching original helpers behavior)
8124
+ const noIconIdx = items.findIndex(item => item.type === 'no-icon');
8125
+ const svgItem = {
8126
+ text: /*#__PURE__*/React__default.createElement(SVGLogo$1, {
8127
+ svgUrl: logoSrc
8128
+ }),
8129
+ type: 'image'
8130
+ };
8131
+ if (noIconIdx >= 0) {
8132
+ items.splice(noIconIdx, 0, svgItem);
8133
+ } else {
8134
+ items.push(svgItem);
8605
8135
  }
8606
8136
  return _objectSpread2(_objectSpread2({}, adapterResult.vmcSection), {}, {
8607
8137
  items
8608
8138
  });
8609
- }, [adapterResult === null || adapterResult === void 0 ? void 0 : adapterResult.vmcSection, bimi, isDeclinationToPublish, hasPublishedCertificate]);
8610
-
8611
- // Build the published-certificate metadata sections (VMC/CMC leaf identity,
8612
- // mark evidence, verification issues). Only present when IPForensics resolved
8613
- // a unique leaf; otherwise this is empty and the card degrades to the legacy
8614
- // VMC section above (DS-93). `now` drives the humanized validity durations.
8615
- const publishedCertSections = useMemo(() => {
8616
- var _bimi$vmc3, _bimi$vmc4, _bimi$vmc5;
8617
- if (isDeclinationToPublish) return [];
8618
- const cert = bimi === null || bimi === void 0 ? void 0 : (_bimi$vmc3 = bimi.vmc) === null || _bimi$vmc3 === void 0 ? void 0 : _bimi$vmc3.publishedCertificate;
8619
- if (!cert) return [];
8620
- const pem = bimi === null || bimi === void 0 ? void 0 : (_bimi$vmc4 = bimi.vmc) === null || _bimi$vmc4 === void 0 ? void 0 : _bimi$vmc4.pem;
8621
- // assertionMarkType ('VMC'/'CMC') is a sibling of publishedCertificate on
8622
- // vmc, not a field of the certificate itself — pass it through for the
8623
- // "Certificate type:" row (cert.markType is the trademark mark class).
8624
- const assertionMarkType = bimi === null || bimi === void 0 ? void 0 : (_bimi$vmc5 = bimi.vmc) === null || _bimi$vmc5 === void 0 ? void 0 : _bimi$vmc5.assertionMarkType;
8625
- return buildPublishedCertificateSections(cert, pem, t, new Date(), assertionMarkType);
8626
- }, [bimi, t, isDeclinationToPublish]);
8139
+ }, [adapterResult === null || adapterResult === void 0 ? void 0 : adapterResult.vmcSection, bimi, isDeclinationToPublish]);
8627
8140
  const getTranslatedCaption = useCallback(caption => {
8628
8141
  if (!caption) return undefined;
8629
8142
  return t(EXTRACTION_CAPTION_KEYS[caption]);
@@ -8681,20 +8194,6 @@ const SignalCardBimi = /*#__PURE__*/forwardRef((props, ref) => {
8681
8194
  testId: 'bimi-vmc-section'
8682
8195
  });
8683
8196
  }
8684
-
8685
- // Full published-certificate metadata sections (DS-93). Rendered only when
8686
- // vmc.publishedCertificate is present; otherwise the card keeps its legacy
8687
- // VMC rendering above.
8688
- publishedCertSections.forEach(section => {
8689
- sections.push({
8690
- id: section.id,
8691
- title: section.title,
8692
- content: /*#__PURE__*/React__default.createElement(Checklist$1, {
8693
- items: section.items
8694
- }),
8695
- testId: section.testId
8696
- });
8697
- });
8698
8197
  if (svgSection) {
8699
8198
  sections.push({
8700
8199
  id: 'safeSVG',