@kitconcept/volto-light-theme 8.0.0-alpha.2 → 8.0.0-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/.changelog.draft +3 -4
  2. package/CHANGELOG.md +232 -0
  3. package/locales/de/LC_MESSAGES/volto.po +30 -115
  4. package/locales/en/LC_MESSAGES/volto.po +30 -115
  5. package/locales/es/LC_MESSAGES/volto.po +31 -116
  6. package/locales/eu/LC_MESSAGES/volto.po +58 -124
  7. package/locales/pt_BR/LC_MESSAGES/volto.po +38 -123
  8. package/locales/volto.pot +31 -116
  9. package/package.json +7 -4
  10. package/src/__mocks__/semantic-ui-react.ts +31 -0
  11. package/src/components/Blocks/Block/Edit.jsx +14 -6
  12. package/src/components/Blocks/Block/EditBlockWrapper.jsx +9 -3
  13. package/src/components/Blocks/Block/ErrorBoundary.test.tsx +55 -0
  14. package/src/components/Blocks/Block/ErrorBoundary.tsx +92 -0
  15. package/src/components/Blocks/Block/ErrorBoundaryMessage.tsx +66 -0
  16. package/src/components/Blocks/EventCalendar/Search/components/EventTemplate.tsx +1 -1
  17. package/src/components/Blocks/Image/Edit.jsx +1 -0
  18. package/src/components/Blocks/Listing/DefaultTemplate.jsx +12 -6
  19. package/src/components/Blocks/Listing/GridTemplate.jsx +16 -7
  20. package/src/components/Blocks/Listing/ListingBody.jsx +4 -1
  21. package/src/components/Blocks/Listing/SummaryTemplate.jsx +16 -7
  22. package/src/components/Blocks/Teaser/DefaultBody.tsx +25 -5
  23. package/src/components/Blocks/schema.ts +69 -0
  24. package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +128 -0
  25. package/src/components/Breadcrumbs/Breadcrumbs.tsx +117 -0
  26. package/src/components/Caption/Caption.test.tsx +31 -0
  27. package/src/components/Caption/{Caption.jsx → Caption.tsx} +14 -21
  28. package/src/components/Footer/ColumnLinks.tsx +2 -2
  29. package/src/components/Footer/slots/Colophon.tsx +13 -1
  30. package/src/components/Footer/slots/CoreFooter.tsx +4 -2
  31. package/src/components/Header/Header.tsx +3 -3
  32. package/src/components/LanguageSelector/LanguageSelector.tsx +91 -0
  33. package/src/components/MobileNavigation/MobileNavigation.jsx +11 -9
  34. package/src/components/Navigation/Navigation.test.tsx +176 -0
  35. package/src/components/Navigation/{Navigation.jsx → Navigation.tsx} +77 -37
  36. package/src/components/StickyMenu/MobileCarouselArrowButton.tsx +81 -0
  37. package/src/components/StickyMenu/MobileStickyMenu.tsx +76 -0
  38. package/src/components/Summary/DefaultSummary.tsx +10 -3
  39. package/src/components/Summary/EventSummary.tsx +10 -3
  40. package/src/components/Summary/FileSummary.tsx +10 -3
  41. package/src/components/Summary/NewsItemSummary.tsx +10 -3
  42. package/src/components/Summary/PersonSummary.tsx +10 -3
  43. package/src/components/Summary/Summary.stories.tsx +46 -30
  44. package/src/components/Tags/Tags.test.tsx +71 -0
  45. package/src/components/Tags/{Tags.jsx → Tags.tsx} +9 -25
  46. package/src/components/Theme/EventView.jsx +4 -4
  47. package/src/components/Theme/NewsItemView.jsx +4 -4
  48. package/src/components/Theme/RenderBlocks.jsx +45 -37
  49. package/src/components/Theme/RenderBlocksV2.jsx +51 -20
  50. package/src/components/Widgets/ColorSwatch.stories.tsx +197 -0
  51. package/src/components/Widgets/ColorSwatch.test.tsx +188 -0
  52. package/src/components/Widgets/ColorSwatch.tsx +77 -39
  53. package/src/components/Widgets/SoftTextWidget.tsx +129 -0
  54. package/src/components/Widgets/SoftTextareaWidget.tsx +118 -0
  55. package/src/components/Widgets/ThemeColorSwatch.tsx +5 -9
  56. package/src/config/blocks.tsx +21 -29
  57. package/src/config/slots.ts +7 -0
  58. package/src/config/widgets.ts +5 -9
  59. package/src/customizations/volto/components/manage/DragDropList/DragDropList.jsx +263 -0
  60. package/src/customizations/volto/components/theme/LanguageSelector/LanguageSelector.tsx +10 -0
  61. package/src/helpers/styleDefinitions.test.tsx +30 -0
  62. package/src/helpers/styleDefinitions.ts +49 -0
  63. package/src/internalChecks.test.ts +94 -0
  64. package/src/primitives/Card/Card.stories.tsx +4 -1
  65. package/src/primitives/Card/Card.test.tsx +11 -33
  66. package/src/primitives/Card/Card.tsx +33 -43
  67. package/src/primitives/IconLinkList.tsx +53 -52
  68. package/src/theme/_bgcolor-blocks-layout.scss +43 -45
  69. package/src/theme/_content.scss +12 -13
  70. package/src/theme/_export_import.scss +94 -0
  71. package/src/theme/_footer.scss +64 -19
  72. package/src/theme/_header.scss +21 -4
  73. package/src/theme/_insets.scss +1 -1
  74. package/src/theme/_layout.scss +34 -15
  75. package/src/theme/_mobile-sticky-menu.scss +92 -0
  76. package/src/theme/_search-page.scss +249 -0
  77. package/src/theme/_typo-custom.scss +16 -5
  78. package/src/theme/_variables.scss +19 -4
  79. package/src/theme/_widgets.scss +15 -27
  80. package/src/theme/blocks/_accordion.scss +11 -4
  81. package/src/theme/blocks/_grid.scss +9 -77
  82. package/src/theme/blocks/_listing.scss +60 -126
  83. package/src/theme/blocks/_search.scss +3 -4
  84. package/src/theme/blocks/_table.scss +1 -0
  85. package/src/theme/blocks/_teaser.scss +7 -117
  86. package/src/theme/blocks/error-boundary.scss +11 -0
  87. package/src/theme/card.scss +107 -70
  88. package/src/theme/main.scss +5 -0
  89. package/src/theme/notfound.scss +27 -0
  90. package/src/theme/person.scss +28 -12
  91. package/src/theme/sticky-menu.scss +7 -5
  92. package/src/types.d.ts +1 -0
  93. package/vitest.config.mjs +4 -0
  94. package/razzle.extend.js +0 -38
  95. package/src/components/Blocks/schema.js +0 -44
  96. package/src/components/Breadcrumbs/Breadcrumbs.jsx +0 -118
  97. package/src/components/Widgets/AlignWidget.tsx +0 -84
  98. package/src/components/Widgets/BlockAlignment.tsx +0 -88
  99. package/src/components/Widgets/BlockWidth.tsx +0 -101
  100. package/src/components/Widgets/Buttons.tsx +0 -144
  101. package/src/components/Widgets/Size.tsx +0 -78
@@ -0,0 +1,94 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { describe, expect, it } from 'vitest';
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+
9
+ const recommendedAddonsPath = path.resolve(
10
+ __dirname,
11
+ '../../../..',
12
+ 'recommendedAddons.json',
13
+ );
14
+ const mrsDeveloperPath = path.resolve(
15
+ __dirname,
16
+ '../../..',
17
+ 'mrs.developer.json',
18
+ );
19
+
20
+ const readJSON = <T>(filePath: string): T =>
21
+ JSON.parse(fs.readFileSync(filePath, 'utf-8'));
22
+
23
+ const normalizeVersion = (version: unknown) =>
24
+ typeof version === 'string' ? version.replace(/^[\\^~]/, '') : version;
25
+
26
+ const excludedPackages = new Set(['@eeacms/volto-accordion-block']);
27
+
28
+ describe('internal checks', () => {
29
+ it('keeps recommended add-ons in sync with mrs.developer.json', () => {
30
+ const recommendedAddons = readJSON<Record<string, string>>(
31
+ recommendedAddonsPath,
32
+ );
33
+ const mrsDeveloper = readJSON<Record<string, unknown>>(mrsDeveloperPath);
34
+
35
+ const mrsByPackage = Object.entries(mrsDeveloper).reduce<
36
+ Record<string, Record<string, unknown> & { configKey: string }>
37
+ >((acc, [configKey, configValue]) => {
38
+ if (
39
+ configValue &&
40
+ typeof configValue === 'object' &&
41
+ 'package' in configValue
42
+ ) {
43
+ acc[String((configValue as Record<string, unknown>).package)] = {
44
+ ...(configValue as Record<string, unknown>),
45
+ configKey,
46
+ };
47
+ }
48
+ return acc;
49
+ }, {});
50
+
51
+ const issues: string[] = [];
52
+
53
+ Object.entries(recommendedAddons).forEach(
54
+ ([packageName, recommendedVersion]) => {
55
+ if (excludedPackages.has(packageName)) return;
56
+
57
+ const mrsEntry = mrsByPackage[packageName];
58
+
59
+ if (!mrsEntry) {
60
+ issues.push(
61
+ `${packageName} is listed in recommendedAddons.json but missing from frontend/mrs.developer.json.`,
62
+ );
63
+ return;
64
+ }
65
+
66
+ const mrsVersion =
67
+ (mrsEntry.tag as string | undefined) ||
68
+ (mrsEntry.branch as string | undefined) ||
69
+ (mrsEntry.version as string | undefined);
70
+
71
+ if (!mrsVersion) {
72
+ issues.push(
73
+ `${packageName} (${mrsEntry.configKey}) has no tag, branch, or version specified in frontend/mrs.developer.json.`,
74
+ );
75
+ return;
76
+ }
77
+
78
+ const normalizedRecommended = normalizeVersion(recommendedVersion);
79
+ const normalizedMrsVersion = normalizeVersion(mrsVersion);
80
+
81
+ if (
82
+ recommendedVersion !== mrsVersion &&
83
+ normalizedRecommended !== normalizedMrsVersion
84
+ ) {
85
+ issues.push(
86
+ `${packageName} differs: recommendedAddons.json=${recommendedVersion} vs frontend/mrs.developer.json(${mrsEntry.configKey})=${mrsVersion}.`,
87
+ );
88
+ }
89
+ },
90
+ );
91
+
92
+ expect(issues).toEqual([]);
93
+ });
94
+ });
@@ -165,7 +165,10 @@ export const CustomImage: Story = {
165
165
  render: (args) => (
166
166
  <div
167
167
  className="card-listing"
168
- style={{ width: 'var(--default-container-width)' }}
168
+ style={{
169
+ width: 'var(--default-container-width)',
170
+ '--theme-high-contrast-color': '#ecebeb',
171
+ }}
169
172
  >
170
173
  <Card href={args.href}>
171
174
  <Card.Image>
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { describe, it, expect, vi } from 'vitest';
3
- import { render, fireEvent } from '@testing-library/react';
3
+ import { render } from '@testing-library/react';
4
4
  import Card from './Card';
5
5
 
6
6
  vi.mock(
@@ -43,10 +43,16 @@ vi.mock(
43
43
 
44
44
  type SummaryProps = {
45
45
  a11yLabelId?: string;
46
+ LinkToItem?: React.ElementType;
46
47
  };
47
48
 
48
- const SummaryContent = ({ a11yLabelId }: SummaryProps) => (
49
- <h3 id={a11yLabelId}>Card title</h3>
49
+ const SummaryContent = ({
50
+ a11yLabelId,
51
+ LinkToItem = React.Fragment,
52
+ }: SummaryProps) => (
53
+ <h3 id={a11yLabelId}>
54
+ <LinkToItem>Card title</LinkToItem>
55
+ </h3>
50
56
  );
51
57
 
52
58
  const BodyContent = () => <div>Body content</div>;
@@ -64,26 +70,20 @@ describe('Card', () => {
64
70
 
65
71
  it('is interactive when an href is provided', () => {
66
72
  const { container } = renderCard({ href: '/target', className: 'custom' });
67
- const card = container.querySelector('.card') as HTMLElement;
68
-
69
- expect(card).toHaveAttribute('role', 'link');
70
- expect(card).toHaveAttribute('tabindex', '0');
71
73
 
72
74
  const anchor = container.querySelector('a');
73
75
  expect(anchor).not.toBeNull();
74
76
  expect(anchor).toHaveAttribute('href', '/target');
77
+ expect(anchor).toHaveClass('card-primary-link');
75
78
  });
76
79
 
77
80
  it('is interactive when an item is provided', () => {
78
81
  const { container } = renderCard({ item: { '@id': '/item-target' } });
79
- const card = container.querySelector('.card') as HTMLElement;
80
-
81
- expect(card).toHaveAttribute('role', 'link');
82
- expect(card).toHaveAttribute('tabindex', '0');
83
82
 
84
83
  const anchor = container.querySelector('a');
85
84
  expect(anchor).not.toBeNull();
86
85
  expect(anchor).toHaveAttribute('href', '/item-target');
86
+ expect(anchor).toHaveClass('card-primary-link');
87
87
  });
88
88
 
89
89
  it('is not interactive when neither href nor item is provided', () => {
@@ -112,26 +112,4 @@ describe('Card', () => {
112
112
  expect(card).not.toHaveAttribute('tabindex');
113
113
  expect(container.querySelector('a')).toBeNull();
114
114
  });
115
-
116
- it('triggers navigation handlers when interactive', () => {
117
- const clickSpy = vi
118
- .spyOn(HTMLAnchorElement.prototype, 'click')
119
- .mockImplementation(() => {});
120
- const selectionSpy = vi
121
- .spyOn(window, 'getSelection')
122
- .mockReturnValue({ toString: () => '' } as unknown as Selection);
123
-
124
- const { container } = renderCard({ href: '/target' });
125
- const card = container.querySelector('.card') as HTMLElement;
126
-
127
- fireEvent.click(card);
128
- fireEvent.keyDown(card, { key: 'Enter' });
129
- fireEvent.keyDown(card, { key: ' ' });
130
- fireEvent.keyDown(card, { key: 'Escape' });
131
-
132
- expect(clickSpy).toHaveBeenCalledTimes(3);
133
-
134
- clickSpy.mockRestore();
135
- selectionSpy.mockRestore();
136
- });
137
115
  });
@@ -52,49 +52,32 @@ const Card = (props: CardProps) => {
52
52
  const { className, openLinkInNewTab } = props;
53
53
 
54
54
  const a11yLabelId = React.useId();
55
- const linkRef = React.useRef<HTMLAnchorElement>(null);
56
-
57
- const triggerNavigation = () => {
58
- // Only navigate if there is *no* text selection
59
- const hasSelection = !!window.getSelection()?.toString();
60
- if (!hasSelection) {
61
- linkRef.current?.click();
62
- }
63
- };
64
-
65
55
  const isInteractive = !!props.href || !!props.item;
66
56
 
67
- const onClick: React.MouseEventHandler<HTMLDivElement> = () => {
68
- if (isInteractive) triggerNavigation();
69
- };
70
-
71
- const onKeyDown: React.KeyboardEventHandler<HTMLDivElement> = (e) => {
72
- if (!isInteractive) return;
73
- if (e.key === 'Enter' || e.key === ' ') {
74
- e.preventDefault();
75
- triggerNavigation();
76
- }
77
- };
57
+ const LinkToItem = React.useCallback(
58
+ ({ children }: { children: React.ReactNode }) => {
59
+ return (
60
+ <ConditionalLink
61
+ className="card-primary-link"
62
+ condition={isInteractive}
63
+ href={href}
64
+ item={item}
65
+ openLinkInNewTab={openLinkInNewTab}
66
+ >
67
+ {children}
68
+ </ConditionalLink>
69
+ );
70
+ },
71
+ [href, item, isInteractive, openLinkInNewTab],
72
+ );
78
73
 
79
74
  return (
80
- <div
81
- className={cx('card', className)}
82
- onClick={isInteractive ? onClick : undefined}
83
- onKeyDown={isInteractive ? onKeyDown : undefined}
84
- role={isInteractive ? 'link' : undefined}
85
- tabIndex={isInteractive ? 0 : undefined}
86
- >
87
- {/* @ts-expect-error since this has no children, should fail */}
88
- <ConditionalLink
89
- aria-labelledby={a11yLabelId}
90
- condition={isInteractive}
91
- href={href}
92
- item={item}
93
- openLinkInNewTab={openLinkInNewTab}
94
- ref={linkRef}
95
- />
75
+ <div className={cx('card', className)}>
96
76
  <div className="card-inner">
97
- {childrenWithProps(props.children, { a11yLabelId })}
77
+ {childrenWithProps(props.children, {
78
+ a11yLabelId,
79
+ LinkToItem,
80
+ })}
98
81
  </div>
99
82
  </div>
100
83
  );
@@ -144,14 +127,21 @@ const CardImage = (props: CardImageProps) => {
144
127
  type CardSummaryProps = {
145
128
  /** The ID of the element that labels the card. */
146
129
  a11yLabelId?: string;
130
+ LinkToItem?: React.ElementType;
147
131
  children?: React.ReactNode;
148
132
  };
149
133
 
150
- const CardSummary = (props: CardSummaryProps) => (
151
- <div className="card-summary">
152
- {childrenWithProps(props.children, { a11yLabelId: props.a11yLabelId })}
153
- </div>
154
- );
134
+ const CardSummary = (props: CardSummaryProps) => {
135
+ const { a11yLabelId, LinkToItem } = props;
136
+ return (
137
+ <div className="card-summary">
138
+ {childrenWithProps(props.children, {
139
+ a11yLabelId,
140
+ LinkToItem,
141
+ })}
142
+ </div>
143
+ );
144
+ };
155
145
 
156
146
  const CardActions = (props: any) => (
157
147
  <div className="actions-wrapper">{props.children}</div>
@@ -6,6 +6,58 @@ type IconLinkListProps = {
6
6
  iconLinks: Array<iconLink>;
7
7
  };
8
8
 
9
+ export const IconLinkListTemplate = ({ item }) => {
10
+ const itemInfo: {
11
+ title: string;
12
+ hrefTitle: string;
13
+ href: string;
14
+ itemHref: string;
15
+ src: string;
16
+ srcAlt: string;
17
+ } = {
18
+ title: '',
19
+ hrefTitle: '',
20
+ href: '',
21
+ itemHref: '',
22
+ src: '',
23
+ srcAlt: '',
24
+ };
25
+
26
+ // If the item has title, always set it
27
+ itemInfo.title = item ? item?.title || item?.href?.[0]?.['title'] || '' : '';
28
+ if (item?.href?.length > 0) {
29
+ itemInfo.title = item.title || item.href[0]['title'];
30
+ itemInfo.href = flattenToAppURL(item.href[0]['@id']);
31
+ }
32
+ if (item?.icon && item.icon[0]?.image_scales) {
33
+ itemInfo.itemHref = item.icon[0]['@id'];
34
+ itemInfo.srcAlt = item['alt'];
35
+ itemInfo.src = `${flattenToAppURL(itemInfo.itemHref)}/${item.icon[0].image_scales[item.icon[0].image_field][0].download}`;
36
+ } else if (item?.icon && item.icon[0]) {
37
+ itemInfo.itemHref = item.icon[0]['@id'];
38
+ itemInfo.srcAlt = item['alt'];
39
+ itemInfo.src = `${flattenToAppURL(itemInfo.itemHref)}/@@images/image`;
40
+ }
41
+
42
+ if (!itemInfo.src) return null;
43
+ return (
44
+ <li className="item" key={item['@id']}>
45
+ {/* @ts-ignore */}
46
+ <ConditionalLink
47
+ condition={itemInfo.href}
48
+ to={itemInfo.href}
49
+ title={itemInfo.hrefTitle || itemInfo.srcAlt}
50
+ openLinkInNewTab={item.openInNewTab}
51
+ >
52
+ <div className="image-wrapper">
53
+ <img src={itemInfo.src} alt={itemInfo.srcAlt || ''} />
54
+ </div>
55
+ <span className="title">{itemInfo.title}</span>
56
+ </ConditionalLink>
57
+ </li>
58
+ );
59
+ };
60
+
9
61
  const IconLinkList = (props: IconLinkListProps) => {
10
62
  const { iconLinks } = props;
11
63
 
@@ -13,58 +65,7 @@ const IconLinkList = (props: IconLinkListProps) => {
13
65
  <ul>
14
66
  {iconLinks && Array.isArray(iconLinks)
15
67
  ? iconLinks.map((item) => {
16
- const itemInfo: {
17
- title: string;
18
- hrefTitle: string;
19
- href: string;
20
- itemHref: string;
21
- src: string;
22
- srcAlt: string;
23
- } = {
24
- title: '',
25
- hrefTitle: '',
26
- href: '',
27
- itemHref: '',
28
- src: '',
29
- srcAlt: '',
30
- };
31
-
32
- // If the item has title, always set it
33
- itemInfo.title = item
34
- ? item?.title || item?.href?.[0]?.['title'] || ''
35
- : '';
36
- if (item?.href?.length > 0) {
37
- itemInfo.title = item.title || item.href[0]['title'];
38
- itemInfo.href = flattenToAppURL(item.href[0]['@id']);
39
- }
40
- if (item?.icon && item.icon[0]?.image_scales) {
41
- itemInfo.itemHref = item.icon[0]['@id'];
42
- itemInfo.srcAlt = item['alt'];
43
- itemInfo.src = `${flattenToAppURL(itemInfo.itemHref)}/${item.icon[0].image_scales[item.icon[0].image_field][0].download}`;
44
- } else if (item?.icon && item.icon[0]) {
45
- itemInfo.itemHref = item.icon[0]['@id'];
46
- itemInfo.srcAlt = item['alt'];
47
- itemInfo.src = `${flattenToAppURL(itemInfo.itemHref)}/@@images/image`;
48
- }
49
-
50
- if (!itemInfo.src) return null;
51
-
52
- return (
53
- <li className="item" key={item['@id']}>
54
- {/* @ts-ignore */}
55
- <ConditionalLink
56
- condition={itemInfo.href}
57
- to={itemInfo.href}
58
- title={itemInfo.hrefTitle || itemInfo.srcAlt}
59
- openLinkInNewTab={item.openInNewTab}
60
- >
61
- <div className="image-wrapper">
62
- <img src={itemInfo.src} alt={itemInfo.srcAlt || ''} />
63
- </div>
64
- <span>{itemInfo.title}</span>
65
- </ConditionalLink>
66
- </li>
67
- );
68
+ return <IconLinkListTemplate item={item} key={item['@id']} />;
68
69
  })
69
70
  : null}
70
71
  </ul>
@@ -17,7 +17,7 @@
17
17
  & > strong,
18
18
  & > em,
19
19
  & > figcaption,
20
- & > a:not(.item),
20
+ & > a,
21
21
  & > blockquote,
22
22
  & > h2,
23
23
  & > h3,
@@ -25,16 +25,6 @@
25
25
  color: var(--theme-foreground-color);
26
26
  }
27
27
 
28
- :not(.teaser-item)
29
- > a:not(.item):not(
30
- :has(> .teaser-item),
31
- :has(> .listing-body),
32
- :has(> .card-container)
33
- ) {
34
- color: var(--link-foreground-color, --theme-foreground-color);
35
- text-decoration: underline;
36
- }
37
-
38
28
  &:first-child:has(> .documentFirstHeading) {
39
29
  padding-top: 0;
40
30
  }
@@ -407,6 +397,14 @@
407
397
  }
408
398
  }
409
399
 
400
+ // Banner block, if next block has different bgcolor it snaps to the bottom
401
+ #page-document
402
+ .blocks-group-wrapper:has(
403
+ :last-child.banner.next--has--different--backgroundColor
404
+ ) {
405
+ padding-bottom: 0;
406
+ }
407
+
410
408
  // Color map
411
409
  @mixin use-theme-colors() {
412
410
  #page-document {
@@ -439,7 +437,8 @@
439
437
  &.__button {
440
438
  & > .button.container,
441
439
  & > .block-inner-container {
442
- & button {
440
+ & button,
441
+ a {
443
442
  border-color: var(--theme-foreground-color);
444
443
  background-color: var(--theme-color);
445
444
 
@@ -494,7 +493,8 @@
494
493
  &.listing,
495
494
  &.search,
496
495
  &.rssBlock {
497
- h2.headline {
496
+ h2.headline,
497
+ h2.block-title {
498
498
  color: var(--theme-foreground-color);
499
499
  }
500
500
 
@@ -505,40 +505,26 @@
505
505
  .listing-item {
506
506
  border-bottom-color: var(--theme-foreground-color) !important;
507
507
 
508
- a > .listing-body {
509
- .headline,
510
- h3,
511
- h2,
512
- a,
513
- p,
514
- span {
515
- color: var(--theme-foreground-color);
516
- }
508
+ .headline,
509
+ h3,
510
+ h2,
511
+ a,
512
+ p,
513
+ span {
514
+ color: var(--theme-foreground-color);
517
515
  }
518
516
 
519
517
  .head-title span,
520
518
  .head-title {
521
519
  color: var(--theme-foreground-color);
522
520
  }
523
-
524
- .card-container {
525
- background-color: var(--theme-high-contrast-color);
526
-
527
- .content,
528
- .content p {
529
- color: var(--theme-foreground-color);
530
- }
531
- }
532
521
  }
533
- /* I have removed the .card-container className that's why I have to write this css
534
- * I will remove all the .card-container className from repo.
535
- */
536
522
  &.grid .card,
537
523
  & .grid-variation .card {
538
524
  background-color: var(--theme-high-contrast-color);
539
525
 
540
- .content,
541
- .content p {
526
+ .card-summary,
527
+ .card-summary p {
542
528
  color: var(--theme-foreground-color);
543
529
  }
544
530
  }
@@ -1122,19 +1108,28 @@
1122
1108
  }
1123
1109
  }
1124
1110
 
1125
- table.ui.table.slate-table-block {
1126
- border-color: var(--theme-low-contrast-foreground-color);
1111
+ table.ui.celled.table.slate-table-block {
1112
+ border-color: color-mix(
1113
+ in srgb,
1114
+ var(--theme-color) 75%,
1115
+ var(--theme-foreground-color)
1116
+ );
1127
1117
 
1128
1118
  tr td,
1129
1119
  th {
1130
- border-color: var(--theme-low-contrast-foreground-color);
1120
+ border-color: color-mix(
1121
+ in srgb,
1122
+ var(--theme-color) 75%,
1123
+ var(--theme-foreground-color)
1124
+ );
1131
1125
  }
1132
1126
 
1133
1127
  th {
1134
1128
  background-color: var(--theme-high-contrast-color) !important;
1129
+ color: var(--theme-low-contrast-foreground-color);
1135
1130
 
1136
- p {
1137
- color: var(--theme-low-contrast-foreground-color) !important;
1131
+ * {
1132
+ color: inherit;
1138
1133
  }
1139
1134
  }
1140
1135
 
@@ -1269,12 +1264,15 @@
1269
1264
  color: var(--header-foreground);
1270
1265
  }
1271
1266
  }
1267
+ .language-selector a {
1268
+ color: var(--header-foreground);
1269
+ }
1272
1270
  }
1273
1271
 
1274
1272
  // Navigation
1275
1273
  nav.navigation {
1276
- button.item {
1277
- color: var(--header-foreground);
1274
+ .item {
1275
+ color: var(--header-foreground, var(--primary-foreground-color));
1278
1276
  }
1279
1277
  .submenu-wrapper {
1280
1278
  .submenu.active {
@@ -1426,12 +1424,12 @@
1426
1424
  }
1427
1425
 
1428
1426
  a.section {
1429
- color: var(--link-foreground-color, --breadcrumbs-foreground);
1427
+ color: var(--breadcrumbs-foreground, --link-foreground-color);
1430
1428
  }
1431
1429
 
1432
1430
  a.home {
1433
1431
  svg {
1434
- fill: var(--link-foreground-color, --breadcrumbs-foreground) !important;
1432
+ fill: var(--breadcrumbs-foreground, --link-foreground-color) !important;
1435
1433
  }
1436
1434
  }
1437
1435
  }
@@ -1,3 +1,12 @@
1
+ @mixin day-with-head-title-separator {
2
+ .day:has(+ .head-title) {
3
+ &::after {
4
+ margin-left: 8px;
5
+ content: '|';
6
+ }
7
+ }
8
+ }
9
+
1
10
  .ui.basic.segment.content-area {
2
11
  // We cancel the padding and margin from the segment
3
12
  // allowing the content elements to be the ones that push for
@@ -18,6 +27,8 @@
18
27
  #page-document .dates {
19
28
  @include default-container-width();
20
29
  @include adjustMarginsToContainer($default-container-width);
30
+ @include day-with-head-title-separator();
31
+
21
32
  margin-top: $spacing-medium;
22
33
  margin-bottom: $spacing-medium;
23
34
  color: var(--primary-foreground-color);
@@ -27,13 +38,6 @@
27
38
  text-transform: uppercase;
28
39
  }
29
40
 
30
- .head-title:has(+ .day) {
31
- &::after {
32
- margin-left: 8px;
33
- content: '|';
34
- }
35
- }
36
-
37
41
  @container (max-width: #{$tablet-breakpoint} ) {
38
42
  .day,
39
43
  .head-title {
@@ -91,6 +95,7 @@
91
95
  }
92
96
  }
93
97
  .dates {
98
+ @include day-with-head-title-separator();
94
99
  margin-top: $spacing-medium;
95
100
  margin-bottom: $spacing-medium;
96
101
  color: var(--primary-foreground-color);
@@ -103,12 +108,6 @@
103
108
  letter-spacing: 1px;
104
109
  text-transform: uppercase;
105
110
  }
106
- .head-title {
107
- &::after {
108
- margin-left: 8px;
109
- content: '|';
110
- }
111
- }
112
111
  @container (max-width: #{$tablet-breakpoint} ) {
113
112
  .day,
114
113
  .head-title {