diff --git a/composer.json b/composer.json
index e0726563d7c3fb6811831052ef7328512b378238..1ce48248e48bb2fa5f29ad63d7c232fed67199b6 100644
--- a/composer.json
+++ b/composer.json
@@ -11,7 +11,7 @@
         "drupal/core": "^9.2",
         "drupal/twig_field_value": "^2.0",
         "openeuropa/composer-artifacts": "^1.0.0-alpha1",
-        "openeuropa/oe_bootstrap_theme": "1.0.0-beta2"
+        "openeuropa/oe_bootstrap_theme": "0.1.202206231430"
     },
     "require-dev": {
         "composer/installers": "^1.11",
diff --git a/modules/oe_whitelabel_list_pages/tests/src/Functional/ListPagesTest.php b/modules/oe_whitelabel_list_pages/tests/src/Functional/ListPagesTest.php
index 678be23701c28ac427ea8afe25840b71e1c1e1a3..477b6f07a458bee120555c288486c036344487ab 100644
--- a/modules/oe_whitelabel_list_pages/tests/src/Functional/ListPagesTest.php
+++ b/modules/oe_whitelabel_list_pages/tests/src/Functional/ListPagesTest.php
@@ -54,7 +54,7 @@ class ListPagesTest extends WhitelabelBrowserTestBase {
 
     // Assert offcanvas.
     $offcanvas = $left_column->find('css', 'div.bcl-offcanvas');
-    $title = $offcanvas->find('css', 'h4.offcanvas-title');
+    $title = $offcanvas->find('css', 'h3.offcanvas-title');
     $this->assertSame('Filter options', $title->getText());
     $offcanvas->hasField('Title');
     $offcanvas->hasButton('Search');
@@ -166,7 +166,7 @@ class ListPagesTest extends WhitelabelBrowserTestBase {
    */
   protected function assertListing(int $expected_count, ElementInterface $container): void {
     $listing = $container->find('css', 'div.bcl-listing');
-    $this->assertSession()->elementsCount('css', 'div.listing-item', $expected_count, $listing);
+    $this->assertSession()->elementsCount('css', 'article.listing-item', $expected_count, $listing);
   }
 
   /**
diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ContentRowTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ContentRowTest.php
index bbd451ed3a54f536926ac0a4379219d92ccc3eda..6c5734deeead0a3493aae07d6d3cdeb416107110 100644
--- a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ContentRowTest.php
+++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ContentRowTest.php
@@ -147,8 +147,8 @@ class ContentRowTest extends ParagraphsTestBase {
     $left = $crawler->filter('div.col-md-3.d-none.d-md-block');
     $nav = $left->filter('nav.bcl-inpage-navigation');
     $this->assertCount(1, $nav);
-    $h5 = $nav->filter('h5');
-    $this->assertSame('Page content', $h5->text());
+    $h3 = $nav->filter('h3');
+    $this->assertSame('Page content', $h3->text());
     $ul = $left->filter('ul.nav.nav-pills.flex-column');
     $this->assertCount(1, $ul);
     $links = $ul->filter('li.nav-item a.nav-link');
@@ -159,17 +159,17 @@ class ContentRowTest extends ParagraphsTestBase {
     // Assert the paragraphs where added into the right side column.
     $content = $crawler->filter('div.col-md-9');
     $this->assertCount(1, $content);
-    $rich_text_title = $content->filter('h4.fw-bold.mb-4');
+    $rich_text_title = $content->filter('h2.bcl-heading')->eq(0);
     $this->assertSame('Title rich text test 1', trim($rich_text_title->text()));
-    $links_block_title = $content->filter('h2.fw-bold.pb-3.mb-3.border-bottom');
+    $links_block_title = $content->filter('h2.bcl-heading')->eq(1);
     $this->assertSame('Links block test', $links_block_title->text());
     $facts_figures = $content->filter('div.bcl-fact-figures--default');
-    $this->assertStringContainsString('Facts and Figures test', $facts_figures->filter('h2.fw-bold')->text());
+    $this->assertStringContainsString('Facts and Figures test', $facts_figures->filter('h2.bcl-heading')->text());
     $blockquote_blockquote = $content->filter('blockquote.blockquote');
     $this->assertStringContainsString('Maecenas id urna eleifend', $blockquote_blockquote->text());
     $blockquote_footer = $content->filter('figcaption.blockquote-footer');
     $this->assertSame('Quote 1', trim($blockquote_footer->text()));
-    $social_media_title = $content->filter('h2.fw-bold.pb-3.mb-3.border-bottom')->eq(1);
+    $social_media_title = $content->filter('h2.bcl-heading')->eq(3);
     $this->assertStringContainsString('Social media block', $social_media_title->text());
     $accordion_items = $content->filter('.accordion-item');
     $this->assertStringContainsString('Accordion item 1', $accordion_items->eq(0)->text());
diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/DescriptionListTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/DescriptionListTest.php
index b1b1280adf2ab51a889bd33c3f4fdc21e3e9d53c..162a3ed679d06b5b82a61941d2639b8f134661bc 100644
--- a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/DescriptionListTest.php
+++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/DescriptionListTest.php
@@ -69,12 +69,12 @@ class DescriptionListTest extends ParagraphsTestBase {
     $html = $this->renderParagraph($paragraph);
     $crawler = new Crawler($html);
 
-    $this->assertCount(1, $crawler->filter('h4'));
+    $this->assertCount(1, $crawler->filter('h2.bcl-heading'));
     $this->assertCount(1, $crawler->filter('dl.d-md-grid.grid-3-9'));
     $this->assertCount(2, $crawler->filter('dd'));
     $this->assertCount(2, $crawler->filter('dt'));
 
-    $title = $crawler->filter('h4.fw-bold.mb-4');
+    $title = $crawler->filter('h2.bcl-heading');
     $this->assertEquals('Description list paragraph', $title->text());
 
     $term_1 = $crawler->filter('dl > div:nth-child(1) > dt');
@@ -100,7 +100,7 @@ class DescriptionListTest extends ParagraphsTestBase {
     $html = $this->renderParagraph($paragraph);
     $crawler = new Crawler($html);
 
-    $title = $crawler->filter('h4.fw-bold.mb-4');
+    $title = $crawler->filter('h2.bcl-heading');
     $this->assertEquals('Description list paragraph', $title->text());
 
     $term_1 = $crawler->filter('dl > dt:nth-child(1)');
diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/FactsFiguresTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/FactsFiguresTest.php
index 23633bad9dd45c4a7f2d8ad93965115ad1cb1021..49daf942cba5653dfaebe18bd3786d4a538bf809 100644
--- a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/FactsFiguresTest.php
+++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/FactsFiguresTest.php
@@ -80,11 +80,11 @@ class FactsFiguresTest extends ParagraphsTestBase {
     $crawler = new Crawler($html);
 
     $this->assertCount(1, $crawler->filter('div.bcl-fact-figures.bcl-fact-figures--default'));
-    $this->assertCount(1, $crawler->filter('h2.fw-bold'));
+    $this->assertCount(1, $crawler->filter('h2.bcl-heading'));
     $this->assertCount(1, $crawler->filter('div.row-cols-md-3.row'));
     $this->assertCount(6, $crawler->filter('svg.bi.icon--l'));
-    $this->assertCount(6, $crawler->filter('h4.fw-bold'));
-    $this->assertCount(6, $crawler->filter('h5.fw-bold'));
+    $this->assertCount(6, $crawler->filter('div.fs-3'));
+    $this->assertCount(6, $crawler->filter('div.fs-5'));
     $this->assertCount(6, $crawler->filter('div.col'));
 
     $link = $crawler->filter('a[href="https://www.readmore.com"]');
@@ -93,12 +93,12 @@ class FactsFiguresTest extends ParagraphsTestBase {
       $link->html()
     );
 
-    $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(1) > h4.text-capitalize.fw-bold');
+    $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(1) > div.fs-3');
     $this->assertStringContainsString(
       '1529 JIRA Ticket',
       $title_fact->html()
     );
-    $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(1) >  h5.fw-bold');
+    $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(1) >  div.fs-5');
     $this->assertStringContainsString(
       'Jira Tickets',
       $subtitle_fact->html()
@@ -109,12 +109,12 @@ class FactsFiguresTest extends ParagraphsTestBase {
       $description_fact->html()
     );
 
-    $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(2) > h4.text-capitalize.fw-bold');
+    $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(2) > div.fs-3');
     $this->assertStringContainsString(
       '337 Features',
       $title_fact->html()
     );
-    $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(2) >  h5.fw-bold');
+    $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(2) >  div.fs-5');
     $this->assertStringContainsString(
       'Feature tickets',
       $subtitle_fact->html()
@@ -125,12 +125,12 @@ class FactsFiguresTest extends ParagraphsTestBase {
       $description_fact->html()
     );
 
-    $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(3) > h4.text-capitalize.fw-bold');
+    $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(3) > div.fs-3');
     $this->assertStringContainsString(
       '107 Tests',
       $title_fact->html()
     );
-    $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(3) >  h5.fw-bold');
+    $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(3) >  div.fs-5');
     $this->assertStringContainsString(
       'Test tickets',
       $subtitle_fact->html()
@@ -141,12 +141,12 @@ class FactsFiguresTest extends ParagraphsTestBase {
       $description_fact->html()
     );
 
-    $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(4) > h4.text-capitalize.fw-bold');
+    $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(4) > div.fs-3');
     $this->assertStringContainsString(
       '5670 Variants',
       $title_fact->html()
     );
-    $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(4) >  h5.fw-bold');
+    $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(4) > div.fs-5');
     $this->assertStringContainsString(
       'Test variants',
       $subtitle_fact->html()
@@ -157,12 +157,12 @@ class FactsFiguresTest extends ParagraphsTestBase {
       $description_fact->html()
     );
 
-    $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(5) > h4.text-capitalize.fw-bold');
+    $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(5) > div.fs-3');
     $this->assertStringContainsString(
       '345 Dev Ticket',
       $title_fact->html()
     );
-    $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(5) >  h5.fw-bold');
+    $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(5) > div.fs-5');
     $this->assertStringContainsString(
       'Jira ticket',
       $subtitle_fact->html()
@@ -173,12 +173,12 @@ class FactsFiguresTest extends ParagraphsTestBase {
       $description_fact->html()
     );
 
-    $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(6) > h4.text-capitalize.fw-bold');
+    $title_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(6) > div.fs-3');
     $this->assertStringContainsString(
       '43 Components',
       $title_fact->html()
     );
-    $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(6) >  h5.fw-bold');
+    $subtitle_fact = $crawler->filter('div.row-cols-md-3.row > div.col:nth-child(6) > div.fs-5');
     $this->assertStringContainsString(
       'Figma components',
       $subtitle_fact->html()
diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ListingParagraphsTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ListingParagraphsTest.php
index 2fe6ab379fddbf50e35a73265d5e1ffc9277e747..f0e291872077d55b102f7bf0f2118f5600c9ce8c 100644
--- a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ListingParagraphsTest.php
+++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/ListingParagraphsTest.php
@@ -132,7 +132,7 @@ class ListingParagraphsTest extends ParagraphsTestBase {
     $assert->assertHighlightListingRendering($crawler, $image_file);
     $this->assertCount(1, $crawler->filter('div.bcl-listing--highlight-2-col'));
     $this->assertCount(1, $crawler->filter('div.row.row-cols-1.row-cols-md-2'));
-    $this->assertCount(6, $crawler->filter('div.listing-item--highlight'));
+    $this->assertCount(6, $crawler->filter('article.listing-item--highlight'));
     $this->assertCount(6, $crawler->filter('div.card-body'));
 
     // Testing Highlight 3 col.
@@ -146,7 +146,7 @@ class ListingParagraphsTest extends ParagraphsTestBase {
     $assert->assertHighlightListingRendering($crawler, $image_file);
     $this->assertCount(1, $crawler->filter('div.bcl-listing--highlight-3-col'));
     $this->assertCount(1, $crawler->filter('div.row.row-cols-1.row-cols-md-3'));
-    $this->assertCount(6, $crawler->filter('div.listing-item--highlight'));
+    $this->assertCount(6, $crawler->filter('article.listing-item--highlight'));
     $this->assertCount(6, $crawler->filter('div.card-body'));
   }
 
diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/MediaParagraphsTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/MediaParagraphsTest.php
index b434cda9af393e61c16a8b5cb6f70e31e2e6bd3c..225bfe9acbed2b3ff0d4f137eab21ad11d048b06 100644
--- a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/MediaParagraphsTest.php
+++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/MediaParagraphsTest.php
@@ -73,7 +73,7 @@ class MediaParagraphsTest extends ParagraphsTestBase {
 
     $this->assertCount(1, $crawler->filter('div.row'));
     $this->assertCount(1, $crawler->filter('div.col-12.col-md-4'));
-    $this->assertCount(0, $crawler->filter('h3'));
+    $this->assertCount(0, $crawler->filter('h2'));
     $this->assertCount(0, $crawler->filter('div.col-12.col-md-6.order-md-1'));
     $this->assertCount(0, $crawler->filter('div.col-12.col-md-6.order-md-2'));
     $figure = $crawler->filter('figure');
@@ -95,7 +95,7 @@ class MediaParagraphsTest extends ParagraphsTestBase {
 
     $this->assertCount(1, $crawler->filter('div.row'));
     $this->assertCount(0, $crawler->filter('div.col-12.col-md-4'));
-    $this->assertCount(1, $crawler->filter('h3'));
+    $this->assertCount(1, $crawler->filter('h2'));
     $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-1'));
     $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-2'));
     $figure = $crawler->filter('figure');
@@ -119,7 +119,7 @@ class MediaParagraphsTest extends ParagraphsTestBase {
 
     $this->assertCount(1, $crawler->filter('div.row'));
     $this->assertCount(0, $crawler->filter('div.col-12.col-md-4'));
-    $this->assertCount(1, $crawler->filter('h3'));
+    $this->assertCount(1, $crawler->filter('h2'));
     $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-1'));
     $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-2'));
     $figure = $crawler->filter('figure');
@@ -162,7 +162,7 @@ class MediaParagraphsTest extends ParagraphsTestBase {
 
     $this->assertCount(1, $crawler->filter('div.row'));
     $this->assertCount(1, $crawler->filter('div.col-12.col-md-4'));
-    $this->assertCount(0, $crawler->filter('h3'));
+    $this->assertCount(0, $crawler->filter('h2'));
     $this->assertCount(0, $crawler->filter('div.col-12.col-md-6.order-md-1'));
     $this->assertCount(0, $crawler->filter('div.col-12.col-md-6.order-md-2'));
     $this->assertCount(1, $crawler->filter('div.ratio.ratio-16x9'));
@@ -189,7 +189,7 @@ class MediaParagraphsTest extends ParagraphsTestBase {
 
     $this->assertCount(1, $crawler->filter('div.row'));
     $this->assertCount(0, $crawler->filter('div.col-12.col-md-4'));
-    $this->assertCount(1, $crawler->filter('h3'));
+    $this->assertCount(1, $crawler->filter('h2'));
     $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-1'));
     $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-2'));
     $this->assertCount(1, $crawler->filter('div.ratio.ratio-16x9'));
@@ -218,7 +218,7 @@ class MediaParagraphsTest extends ParagraphsTestBase {
 
     $this->assertCount(1, $crawler->filter('div.row'));
     $this->assertCount(0, $crawler->filter('div.col-12.col-md-4'));
-    $this->assertCount(1, $crawler->filter('h3'));
+    $this->assertCount(1, $crawler->filter('h2'));
     $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-1'));
     $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-2'));
     $this->assertCount(1, $crawler->filter('div.ratio.ratio-16x9'));
@@ -252,7 +252,7 @@ class MediaParagraphsTest extends ParagraphsTestBase {
 
     $this->assertCount(1, $crawler->filter('div.row'));
     $this->assertCount(0, $crawler->filter('div.col-12.col-md-4'));
-    $this->assertCount(1, $crawler->filter('h3'));
+    $this->assertCount(1, $crawler->filter('h2'));
     $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-1'));
     $this->assertCount(1, $crawler->filter('div.col-12.col-md-6.order-md-2'));
     $this->assertCount(1, $crawler->filter('div.ratio.ratio-16x9'));
diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/RichTextTest.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/RichTextTest.php
index 609a5bb08702ba6a5e04f611ec3345dff883696d..e195b7b49cca35b48264beecc53b8d0dd26acebd 100644
--- a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/RichTextTest.php
+++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/Paragraphs/RichTextTest.php
@@ -45,7 +45,7 @@ class RichTextTest extends ParagraphsTestBase {
     $html = $this->renderParagraph($paragraph);
     $crawler = new Crawler($html);
 
-    $title = $crawler->filter('h4');
+    $title = $crawler->filter('h2');
     $this->assertCount(1, $title);
     $this->assertStringContainsString(
       'Rich text example',
diff --git a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/PatternAssertions/ListingAssertion.php b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/PatternAssertions/ListingAssertion.php
index f032eb90a05f6f61b793fd97b477b28c7ee90232..5217906dccbbf3b197e78ef4ab718862cee60ac9 100644
--- a/modules/oe_whitelabel_paragraphs/tests/src/Kernel/PatternAssertions/ListingAssertion.php
+++ b/modules/oe_whitelabel_paragraphs/tests/src/Kernel/PatternAssertions/ListingAssertion.php
@@ -23,7 +23,7 @@ class ListingAssertion extends Assert {
    *   Image file added to the list item.
    */
   public function assertDefaultListingRendering(Crawler $crawler, File $file): void {
-    $this->assertCount(6, $crawler->filter('div.listing-item.border-bottom.border-md-0.border-0.card'));
+    $this->assertCount(6, $crawler->filter('article.listing-item.border-bottom.border-md-0.border-0.card'));
     $this->assertCount(6, $crawler->filter('div.mw-listing-img'));
     $this->assertCount(6, $crawler->filter('div.card-body.p-0.pb-md-0.pb-3'));
     $text_element = $crawler->filter('div.card-text');
@@ -40,7 +40,7 @@ class ListingAssertion extends Assert {
    *   Image file added to the list item.
    */
   public function assertHighlightListingRendering(Crawler $crawler, File $file): void {
-    $this->assertCount(6, $crawler->filter('div.listing-item--highlight.border-0.bg-lighter.card'));
+    $this->assertCount(6, $crawler->filter('article.listing-item--highlight.border-0.bg-lighter.card'));
     $text_element = $crawler->filter('div.card-text');
     $this->assertCount(6, $text_element);
     $this->assertImageRendering($crawler, $file);
@@ -57,8 +57,8 @@ class ListingAssertion extends Assert {
   public function assertListingRendering(Crawler $crawler, int $nid): void {
     $this->assertCount(1, $crawler->filter('div.bcl-listing'));
     $this->assertCount(6, $crawler->filter('div.row-cols-1.g-4 > div.col'));
-    $this->assertStringContainsString('Listing item block title', trim($crawler->filter('h2.fw-bold')->text()));
-    $this->assertCount(6, $crawler->filter('h5.card-title'));
+    $this->assertStringContainsString('Listing item block title', trim($crawler->filter('h2.bcl-heading')->text()));
+    $this->assertCount(6, $crawler->filter('h1.card-title'));
     $link_element = $crawler->filter('a.text-underline-hover');
     $this->assertCount(6, $link_element);
     $this->assertStringContainsString(
@@ -66,7 +66,7 @@ class ListingAssertion extends Assert {
       $link_element->attr('href')
     );
     $text_element = $crawler->filter('div.card-text');
-    $this->assertStringContainsString('Item title 1', trim($crawler->filter('h5.card-title > a.text-underline-hover')->text()));
+    $this->assertStringContainsString('Item title 1', trim($crawler->filter('h1.card-title > a.text-underline-hover')->text()));
     $this->assertStringContainsString('Label 1 - 1', trim($crawler->filter('span.badge')->eq(0)->text()));
     $this->assertStringContainsString('Label 2 - 1', trim($crawler->filter('span.badge')->eq(1)->text()));
     $this->assertStringContainsString(
diff --git a/templates/content/field--node--body--oe-sc-event.html.twig b/templates/content/field--node--body--oe-sc-event.html.twig
index 71643d71882c5884589414ad20d85b2644b05c85..ba689deb71dd7639369c268d638d43e30660b46a 100644
--- a/templates/content/field--node--body--oe-sc-event.html.twig
+++ b/templates/content/field--node--body--oe-sc-event.html.twig
@@ -1,7 +1,7 @@
 {#
 /**
  * @file
- * Default template for a field.
+ * Template for event body field.
  */
 #}
 {%
@@ -13,7 +13,6 @@
 {%
   set title_classes = [
   'field__label',
-  'fw-bold',
   label_display == 'visually_hidden' ? 'visually-hidden',
 ]
 %}
@@ -32,9 +31,13 @@
   {% endif %}
 {% else %}
   <div{{ attributes.addClass(classes) }}>
-    <h3{{ title_attributes.addClass(title_classes) }}>
-      {{ label }}{% if label_display == 'inline' %}<span class="me-1">:</span>{% endif %}
-    </h3>
+    {%- set _label -%}
+      {{- label -}}{%- if label_display == 'inline' -%}<span class="me-1">:</span>{%- endif -%}
+    {%- endset -%}
+    {% include '@oe-bcl/bcl-heading/heading.html.twig' with {
+      title: _label,
+      attributes: create_attribute().addClass(title_classes)
+    } only %}
     {% if multiple %}
     <div class="field__items">
       {% endif %}
diff --git a/templates/content/field--node--oe-documents--oe-sc-event.html.twig b/templates/content/field--node--oe-documents--oe-sc-event.html.twig
index 71643d71882c5884589414ad20d85b2644b05c85..f5074979d6e27a9d85a567e36f422adbe86cf2fd 100644
--- a/templates/content/field--node--oe-documents--oe-sc-event.html.twig
+++ b/templates/content/field--node--oe-documents--oe-sc-event.html.twig
@@ -1,7 +1,7 @@
 {#
 /**
  * @file
- * Default template for a field.
+ * Template for event documents field.
  */
 #}
 {%
@@ -13,7 +13,6 @@
 {%
   set title_classes = [
   'field__label',
-  'fw-bold',
   label_display == 'visually_hidden' ? 'visually-hidden',
 ]
 %}
@@ -32,9 +31,13 @@
   {% endif %}
 {% else %}
   <div{{ attributes.addClass(classes) }}>
-    <h3{{ title_attributes.addClass(title_classes) }}>
-      {{ label }}{% if label_display == 'inline' %}<span class="me-1">:</span>{% endif %}
-    </h3>
+    {%- set _label -%}
+      {{- label -}}{%- if label_display == 'inline' -%}<span class="me-1">:</span>{%- endif -%}
+    {%- endset -%}
+    {% include '@oe-bcl/bcl-heading/heading.html.twig' with {
+      title: _label,
+      attributes: create_attribute().addClass(title_classes)
+    } only %}
     {% if multiple %}
     <div class="field__items">
       {% endif %}
diff --git a/templates/content/node--oe-sc-event--teaser.html.twig b/templates/content/node--oe-sc-event--teaser.html.twig
index debd2d3e66aeea1f0a426429d06d96d414a98d6a..cb24a700a21ad79f3cd617a042f902ba1e4efa2a 100755
--- a/templates/content/node--oe-sc-event--teaser.html.twig
+++ b/templates/content/node--oe-sc-event--teaser.html.twig
@@ -8,15 +8,14 @@
   <a class="standalone" href="{{ url }}">{{ label }}</a>
 {% endset %}
 {% block content %}
-<article{{attributes}}>
-  {{ pattern('card', {
-    variant: 'search',
-    title: _title,
-    text: content.oe_summary,
-    image: image,
-    meta: [
-      content.oe_sc_event_dates|field_value,
-    ],
-  }) }}
-</article>
+{{ pattern('card', {
+  variant: 'search',
+  title: _title,
+  text: content.oe_summary,
+  image: image,
+  meta: [
+    content.oe_sc_event_dates|field_value,
+  ],
+  attributes: attributes,
+}) }}
 {% endblock %}
diff --git a/templates/content/node--oe-sc-news--teaser.html.twig b/templates/content/node--oe-sc-news--teaser.html.twig
index 3556131abc328427f187875f05328342354caba2..9ba22fce17e92288c4ca851d3485a3db3b697ea8 100644
--- a/templates/content/node--oe-sc-news--teaser.html.twig
+++ b/templates/content/node--oe-sc-news--teaser.html.twig
@@ -8,15 +8,14 @@
   <a class="standalone" href="{{ url }}">{{ label }}</a>
 {% endset %}
 {% block content %}
-<article{{attributes}}>
-  {{ pattern('card', {
-    variant: 'search',
-    title: _title,
-    text: content.oe_summary,
-    image: image,
-    meta: [
-      content.oe_publication_date|field_value
-    ],
-  }) }}
-</article>
+{{ pattern('card', {
+  variant: 'search',
+  title: _title,
+  text: content.oe_summary,
+  image: image,
+  meta: [
+    content.oe_publication_date|field_value
+  ],
+  attributes: attributes,
+}) }}
 {% endblock %}
diff --git a/templates/list_pages/oe-list-pages-selected-facet.html.twig b/templates/list_pages/oe-list-pages-selected-facet.html.twig
index ed4102d685950add8966c517ddae92a53e7b5e97..20cfe2c4a3c74b2619db5087f63b4eb8afc9bb50 100644
--- a/templates/list_pages/oe-list-pages-selected-facet.html.twig
+++ b/templates/list_pages/oe-list-pages-selected-facet.html.twig
@@ -2,7 +2,7 @@
   {{ pattern('badge', {
     'background': 'light',
     'label': item.label,
-    'url': item.url,
+    'url': item.url.toString(),
     'dismissible': true,
     'attributes': create_attribute({'class': ['me-2', 'fs-6']}),
   }) }}
diff --git a/templates/paragraphs/paragraph--oe-description-list.html.twig b/templates/paragraphs/paragraph--oe-description-list.html.twig
index a78c5d6e4fdb5aa33b7c19fb0e75022ab2ebb7bb..d10b468d7353241c8c5d04d8c01fd6784a720541 100644
--- a/templates/paragraphs/paragraph--oe-description-list.html.twig
+++ b/templates/paragraphs/paragraph--oe-description-list.html.twig
@@ -8,7 +8,9 @@
 #}
 
 {% if title is not empty %}
-  <h4 class="fw-bold mb-4">{{ title }}</h4>
+  {% include '@oe-bcl/bcl-heading/heading.html.twig' with {
+    title: title,
+  } only %}
 {% endif %}
 
 {{ pattern('description_list', {
diff --git a/templates/paragraphs/paragraph--oe-rich-text.html.twig b/templates/paragraphs/paragraph--oe-rich-text.html.twig
index 8024655618529752a8a8f7b5c77c4af940ce6248..3547defacd64d2b718f545b4243984ba9396ec03 100644
--- a/templates/paragraphs/paragraph--oe-rich-text.html.twig
+++ b/templates/paragraphs/paragraph--oe-rich-text.html.twig
@@ -6,5 +6,7 @@
  * @see ./modules/contrib/paragraphs/templates/paragraph.html.twig
  */
 #}
-<h4 class="fw-bold mb-4">{{ content.field_oe_title }}</h4>
+{% include '@oe-bcl/bcl-heading/heading.html.twig' with {
+  title: content.field_oe_title,
+} only %}
 {{ content|without('field_oe_title') }}
diff --git a/tests/src/Functional/ContentEventRenderTest.php b/tests/src/Functional/ContentEventRenderTest.php
index 7f7d10b299d892400f3bd6e6546ce9a5661437e7..4160c7349de9fa7bf04c0b2264fe92a9bd858ca6 100644
--- a/tests/src/Functional/ContentEventRenderTest.php
+++ b/tests/src/Functional/ContentEventRenderTest.php
@@ -133,7 +133,7 @@ class ContentEventRenderTest extends WhitelabelBrowserTestBase {
     // Assert in-page navigation title.
     $this->assertEquals(
       'Page content',
-      trim($crawler->filter('nav.bcl-inpage-navigation > h5')->text())
+      trim($crawler->filter('nav.bcl-inpage-navigation > h3')->text())
     );
 
     // Assert in-page navigation links.
@@ -175,11 +175,14 @@ class ContentEventRenderTest extends WhitelabelBrowserTestBase {
     $render = $this->container->get('renderer')->renderRoot($build);
     $crawler = new Crawler((string) $render);
 
+    $article = $crawler->filter('article');
+    $this->assertCount(1, $article);
+
     $this->assertEquals(
       'Test event node',
-      trim($crawler->filter('h5.card-title')->text())
+      trim($article->filter('h1.card-title')->text())
     );
-    $image = $crawler->filter('img');
+    $image = $article->filter('img');
     $this->assertCount(1, $image);
     $this->assertCount(1, $image->filter('.card-img-top'));
     $this->assertStringContainsString(
diff --git a/tests/src/Functional/ContentNewsRenderTest.php b/tests/src/Functional/ContentNewsRenderTest.php
index ae0eef5d42b529206a30fcdf84e4be8322f9ebac..56a2ba94f2fb09ec33b87aae2e514896422f7345 100644
--- a/tests/src/Functional/ContentNewsRenderTest.php
+++ b/tests/src/Functional/ContentNewsRenderTest.php
@@ -129,11 +129,14 @@ class ContentNewsRenderTest extends WhitelabelBrowserTestBase {
     $render = $this->container->get('renderer')->renderRoot($build);
     $crawler = new Crawler((string) $render);
 
+    $article = $crawler->filter('article');
+    $this->assertCount(1, $article);
+
     $this->assertEquals(
       'Test news node',
-      trim($crawler->filter('h5.card-title')->text())
+      trim($article->filter('h1.card-title')->text())
     );
-    $image = $crawler->filter('img');
+    $image = $article->filter('img');
     $this->assertCount(1, $image);
     $this->assertCount(1, $image->filter('.card-img-top'));
     $this->assertStringContainsString(
@@ -142,11 +145,11 @@ class ContentNewsRenderTest extends WhitelabelBrowserTestBase {
     );
     $this->assertEquals(
       'https://www.example.org is a web page',
-      trim($crawler->filter('div.card-text')->text())
+      trim($article->filter('div.card-text')->text())
     );
     $this->assertEquals(
       '09 February 2022',
-      trim($crawler->filter('div.card-body > div > span.text-muted')->text())
+      trim($article->filter('div.card-body > div > span.text-muted')->text())
     );
   }
 
diff --git a/tests/src/Kernel/FacetsFormTest.php b/tests/src/Kernel/FacetsFormTest.php
index 6b98be66c324fbea83346377ca6fdc4b87d6ea45..9ccfea9a5c93d3e6cd5b361d1b4057c569b1029e 100644
--- a/tests/src/Kernel/FacetsFormTest.php
+++ b/tests/src/Kernel/FacetsFormTest.php
@@ -96,7 +96,7 @@ class FacetsFormTest extends KernelTestBase {
     $offcanvas = $crawler->filter('div#bcl-offcanvas');
     $header = $offcanvas->filter('div.offcanvas-header');
     $this->assertCount(1, $header);
-    $title = $header->filter('h4.offcanvas-title');
+    $title = $header->filter('h3.offcanvas-title');
     $this->assertSame('Facets form', $title->text());
     $button = $header->filter('button');
     $this->assertSame('offcanvas', $button->attr('data-bs-dismiss'));
diff --git a/tests/src/PatternAssertions/CardAssert.php b/tests/src/PatternAssertions/CardAssert.php
index 00afdb6cb0f3052d70289b6f7ac7660195f140a0..e2e7eff3d05d29dd30c1cba0d0983ad85b01f22d 100644
--- a/tests/src/PatternAssertions/CardAssert.php
+++ b/tests/src/PatternAssertions/CardAssert.php
@@ -33,7 +33,7 @@ class CardAssert extends BasePatternAssert {
       ],
       'description' => [
         [$this, 'assertElementText'],
-        '.card-text',
+        '.card-text p',
       ],
       'badges' => [
         [$this, 'assertBadgesElements'],
@@ -56,13 +56,13 @@ class CardAssert extends BasePatternAssert {
    *   The DomCrawler where to check the element.
    */
   protected function assertCardImage($expected_image, string $variant, Crawler $crawler): void {
-    if ($variant == 'search') {
-      $image_div = $crawler->filter('.row .col-md-3.mw-listing-img img.card-img-top');
+    if ($variant === 'search') {
+      $image_div = $crawler->filter('.row .col-md-3 img.card-img-top');
       self::assertEquals($expected_image['alt'], $image_div->attr('alt'));
       self::assertStringContainsString($expected_image['src'], $image_div->attr('src'));
     }
     else {
-      $image_div = $crawler->filter('div.card img');
+      $image_div = $crawler->filter('article.card img');
       self::assertEquals($expected_image['alt'], $image_div->attr('alt'));
       self::assertStringContainsString($expected_image['src'], $image_div->attr('src'));
     }
@@ -82,7 +82,7 @@ class CardAssert extends BasePatternAssert {
     // There's no wrapping element in content that can be targeted,
     // so we are checking that the expected items are present.
     foreach ($expected_items as $expected_item) {
-      if ($variant == 'search') {
+      if ($variant === 'search') {
         self::assertStringContainsString($expected_item, $crawler->filter('.row .col-md-9')->html());
       }
       else {
@@ -112,10 +112,10 @@ class CardAssert extends BasePatternAssert {
   protected function getBaseItemClass(string $variant): string {
     switch ($variant) {
       case 'search':
-        return 'div.listing-item.card';
+        return 'article.listing-item.card';
 
       default:
-        return 'div.card';
+        return 'article.card';
     }
   }
 
@@ -124,7 +124,7 @@ class CardAssert extends BasePatternAssert {
    */
   protected function getPatternVariant(string $html): string {
     $crawler = new Crawler($html);
-    if ($crawler->filter('div.listing-item')->count() > 0) {
+    if ($crawler->filter('article.listing-item')->count() > 0) {
       return 'search';
     }
     return 'default';
diff --git a/tests/src/PatternAssertions/InPageNavigationAssert.php b/tests/src/PatternAssertions/InPageNavigationAssert.php
index b2d9bdf9be26042549046f5412dc692e210eb391..a367f48953b917d2869a25c6034163083e47b5db 100644
--- a/tests/src/PatternAssertions/InPageNavigationAssert.php
+++ b/tests/src/PatternAssertions/InPageNavigationAssert.php
@@ -18,7 +18,7 @@ class InPageNavigationAssert extends BasePatternAssert {
     return [
       'title' => [
         [$this, 'assertElementText'],
-        'h5',
+        'h3',
       ],
       'links' => [
         [$this, 'assertList'],