diff --git a/config/sync/core.entity_form_display.node.report_summary.default.yml b/config/sync/core.entity_form_display.node.report_summary.default.yml new file mode 100644 index 000000000..18e30fe78 --- /dev/null +++ b/config/sync/core.entity_form_display.node.report_summary.default.yml @@ -0,0 +1,146 @@ +uuid: 3c4d5e6f-7a8b-9c0d-1e2f-3a4b5c6d7e8f +langcode: en +status: true +dependencies: + config: + - field.field.node.report_summary.field_authors + - field.field.node.report_summary.field_emphasized_title_text + - field.field.node.report_summary.field_published_date + - field.field.node.report_summary.field_report_files + - field.field.node.report_summary.field_report_state + - field.field.node.report_summary.field_report_topic + - field.field.node.report_summary.field_representative_image + - field.field.node.report_summary.field_sections + - node.type.report_summary + module: + - address + - datetime + - media_library + - media_library_edit + - paragraphs + - path +id: node.report_summary.default +targetEntityType: node +bundle: report_summary +mode: default +content: + created: + type: datetime_timestamp + weight: 12 + region: content + settings: { } + third_party_settings: { } + field_authors: + type: entity_reference_autocomplete + weight: 9 + region: content + settings: + match_operator: CONTAINS + match_limit: 10 + size: 60 + placeholder: '' + third_party_settings: { } + field_emphasized_title_text: + type: string_textfield + weight: 2 + region: content + settings: + size: 60 + placeholder: '' + third_party_settings: { } + field_published_date: + type: datetime_default + weight: 10 + region: content + settings: { } + third_party_settings: { } + field_report_files: + type: media_library_widget + weight: 8 + region: content + settings: + media_types: { } + third_party_settings: + media_library_edit: + show_edit: '1' + field_report_state: + type: address_default + weight: 4 + region: content + settings: { } + third_party_settings: { } + field_report_topic: + type: options_select + weight: 3 + region: content + settings: { } + third_party_settings: { } + field_representative_image: + type: media_library_widget + weight: 5 + region: content + settings: + media_types: { } + third_party_settings: + media_library_edit: + show_edit: '1' + field_sections: + type: paragraphs + weight: 11 + region: content + settings: + title: Section + title_plural: Sections + edit_mode: closed + closed_mode: summary + autocollapse: all + closed_mode_threshold: 2 + add_mode: dropdown + form_display_mode: default + default_paragraph_type: section + features: + add_above: '0' + collapse_edit_all: collapse_edit_all + duplicate: '0' + third_party_settings: { } + langcode: + type: language_select + weight: 1 + region: content + settings: + include_locked: true + third_party_settings: { } + path: + type: path + weight: 6 + region: content + settings: { } + third_party_settings: { } + status: + type: boolean_checkbox + weight: 11 + region: content + settings: + display_label: true + third_party_settings: { } + title: + type: string_textfield + weight: 0 + region: content + settings: + size: 60 + placeholder: '' + third_party_settings: { } + uid: + type: entity_reference_autocomplete + weight: 13 + region: content + settings: + match_operator: CONTAINS + match_limit: 10 + size: 60 + placeholder: '' + third_party_settings: { } +hidden: + promote: true + sticky: true diff --git a/config/sync/core.entity_view_display.node.report_summary.default.yml b/config/sync/core.entity_view_display.node.report_summary.default.yml new file mode 100644 index 000000000..dc8659eaa --- /dev/null +++ b/config/sync/core.entity_view_display.node.report_summary.default.yml @@ -0,0 +1,80 @@ +uuid: 4d5e6f7a-8b9c-0d1e-2f3a-4b5c6d7e8f9a +langcode: en +status: true +dependencies: + config: + - core.entity_view_mode.node.full + - field.field.node.report_summary.field_authors + - field.field.node.report_summary.field_emphasized_title_text + - field.field.node.report_summary.field_published_date + - field.field.node.report_summary.field_report_files + - field.field.node.report_summary.field_report_state + - field.field.node.report_summary.field_report_topic + - field.field.node.report_summary.field_representative_image + - field.field.node.report_summary.field_sections + - node.type.report_summary + module: + - address + - datetime + - entity_reference_revisions + - layout_builder + - media + - user +third_party_settings: + layout_builder: + enabled: true + allow_custom: true +id: node.report_summary.default +targetEntityType: node +bundle: report_summary +mode: default +content: + field_report_files: + type: entity_reference_entity_view + label: above + settings: + view_mode: default + link: false + third_party_settings: { } + weight: 4 + region: content + field_report_state: + type: address_default + label: above + settings: { } + third_party_settings: { } + weight: 2 + region: content + field_report_topic: + type: entity_reference_label + label: above + settings: + link: true + third_party_settings: { } + weight: 1 + region: content + field_representative_image: + type: entity_reference_entity_view + label: hidden + settings: + view_mode: default + link: false + third_party_settings: { } + weight: 0 + region: content + field_sections: + type: entity_reference_revisions_entity_view + label: hidden + settings: + view_mode: default + link: '' + third_party_settings: { } + weight: 5 + region: content +hidden: + field_authors: true + field_emphasized_title_text: true + field_published_date: true + langcode: true + links: true + search_api_excerpt: true diff --git a/config/sync/field.field.node.report_summary.field_authors.yml b/config/sync/field.field.node.report_summary.field_authors.yml new file mode 100644 index 000000000..9f7bc6771 --- /dev/null +++ b/config/sync/field.field.node.report_summary.field_authors.yml @@ -0,0 +1,28 @@ +uuid: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_authors + - node.type.report_summary + - person.persona_type.author +id: node.report_summary.field_authors +field_name: field_authors +entity_type: node +bundle: report_summary +label: Author(s) +description: '' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:persona' + handler_settings: + target_bundles: + author: author + sort: + field: _none + auto_create: false + auto_create_bundle: '' +field_type: entity_reference diff --git a/config/sync/field.field.node.report_summary.field_emphasized_title_text.yml b/config/sync/field.field.node.report_summary.field_emphasized_title_text.yml new file mode 100644 index 000000000..cf82090d0 --- /dev/null +++ b/config/sync/field.field.node.report_summary.field_emphasized_title_text.yml @@ -0,0 +1,19 @@ +uuid: 2b3c4d5e-6f7a-8b9c-0d1e-2f3a4b5c6d7e +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_emphasized_title_text + - node.type.report_summary +id: node.report_summary.field_emphasized_title_text +field_name: field_emphasized_title_text +entity_type: node +bundle: report_summary +label: 'Emphasized title text' +description: 'If this text matches a portion of the title, it will be wrapped in bold when displayed in report listings/carousels.' +required: false +translatable: true +default_value: { } +default_value_callback: '' +settings: { } +field_type: string diff --git a/config/sync/field.field.node.report_summary.field_published_date.yml b/config/sync/field.field.node.report_summary.field_published_date.yml new file mode 100644 index 000000000..e10ea51b7 --- /dev/null +++ b/config/sync/field.field.node.report_summary.field_published_date.yml @@ -0,0 +1,24 @@ +uuid: 8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_published_date + - node.type.report_summary + module: + - datetime +id: node.report_summary.field_published_date +field_name: field_published_date +entity_type: node +bundle: report_summary +label: 'Published Date' +description: 'The published date for this report.' +required: true +translatable: false +default_value: + - + default_date_type: now + default_date: now +default_value_callback: '' +settings: { } +field_type: datetime diff --git a/config/sync/field.field.node.report_summary.field_report_files.yml b/config/sync/field.field.node.report_summary.field_report_files.yml new file mode 100644 index 000000000..f1fe8800b --- /dev/null +++ b/config/sync/field.field.node.report_summary.field_report_files.yml @@ -0,0 +1,29 @@ +uuid: 1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_report_files + - media.type.file + - node.type.report_summary +id: node.report_summary.field_report_files +field_name: field_report_files +entity_type: node +bundle: report_summary +label: 'Report files' +description: 'Upload one or more PDF files for this report.' +required: false +translatable: true +default_value: { } +default_value_callback: '' +settings: + handler: 'default:media' + handler_settings: + target_bundles: + file: file + sort: + field: _none + direction: ASC + auto_create: false + auto_create_bundle: file +field_type: entity_reference diff --git a/config/sync/field.field.node.report_summary.field_report_state.yml b/config/sync/field.field.node.report_summary.field_report_state.yml new file mode 100644 index 000000000..4b09b9305 --- /dev/null +++ b/config/sync/field.field.node.report_summary.field_report_state.yml @@ -0,0 +1,60 @@ +uuid: 8d9e0f1a-2b3c-4d5e-6f7a-8b9c0d1e2f3a +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_report_state + - node.type.report_summary + module: + - address +id: node.report_summary.field_report_state +field_name: field_report_state +entity_type: node +bundle: report_summary +label: State +description: 'Select one or more US states associated with this report.' +required: false +translatable: false +default_value: + - + langcode: '' + country_code: US + administrative_area: '' + locality: null + dependent_locality: null + postal_code: null + sorting_code: null + address_line1: null + address_line2: null + organization: null + given_name: null + additional_name: null + family_name: null +default_value_callback: '' +settings: + available_countries: + US: US + langcode_override: '' + field_overrides: + givenName: + override: hidden + additionalName: + override: hidden + familyName: + override: hidden + organization: + override: hidden + addressLine1: + override: hidden + addressLine2: + override: hidden + postalCode: + override: hidden + sortingCode: + override: hidden + dependentLocality: + override: hidden + locality: + override: hidden + fields: { } +field_type: address diff --git a/config/sync/field.field.node.report_summary.field_report_topic.yml b/config/sync/field.field.node.report_summary.field_report_topic.yml new file mode 100644 index 000000000..d49379728 --- /dev/null +++ b/config/sync/field.field.node.report_summary.field_report_topic.yml @@ -0,0 +1,29 @@ +uuid: 9e0f1a2b-3c4d-5e6f-7a8b-9c0d1e2f3a4b +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_report_topic + - node.type.report_summary + - taxonomy.vocabulary.report_topics +id: node.report_summary.field_report_topic +field_name: field_report_topic +entity_type: node +bundle: report_summary +label: Topic +description: 'Select the topic for this report.' +required: false +translatable: true +default_value: { } +default_value_callback: '' +settings: + handler: 'default:taxonomy_term' + handler_settings: + target_bundles: + report_topics: report_topics + sort: + field: name + direction: asc + auto_create: false + auto_create_bundle: '' +field_type: entity_reference diff --git a/config/sync/field.field.node.report_summary.field_representative_image.yml b/config/sync/field.field.node.report_summary.field_representative_image.yml new file mode 100644 index 000000000..7e898eb29 --- /dev/null +++ b/config/sync/field.field.node.report_summary.field_representative_image.yml @@ -0,0 +1,29 @@ +uuid: 0f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_representative_image + - media.type.image + - node.type.report_summary +id: node.report_summary.field_representative_image +field_name: field_representative_image +entity_type: node +bundle: report_summary +label: 'Representative image' +description: 'This image is used when displaying this report in listings and carousels.' +required: false +translatable: true +default_value: { } +default_value_callback: '' +settings: + handler: 'default:media' + handler_settings: + target_bundles: + image: image + sort: + field: _none + direction: ASC + auto_create: false + auto_create_bundle: image +field_type: entity_reference diff --git a/config/sync/field.field.node.report_summary.field_sections.yml b/config/sync/field.field.node.report_summary.field_sections.yml new file mode 100644 index 000000000..868bcd384 --- /dev/null +++ b/config/sync/field.field.node.report_summary.field_sections.yml @@ -0,0 +1,31 @@ +uuid: 7c8d9e0f-1a2b-3c4d-5e6f-7a8b9c0d1e2f +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_sections + - node.type.report_summary + - paragraphs.paragraphs_type.section + module: + - entity_reference_revisions +id: node.report_summary.field_sections +field_name: field_sections +entity_type: node +bundle: report_summary +label: Sections +description: '' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:paragraph' + handler_settings: + target_bundles: + section: section + negate: 0 + target_bundles_drag_drop: + section: + weight: 0 + enabled: true +field_type: entity_reference_revisions diff --git a/config/sync/field.storage.node.field_emphasized_title_text.yml b/config/sync/field.storage.node.field_emphasized_title_text.yml new file mode 100644 index 000000000..3aa4dc3f6 --- /dev/null +++ b/config/sync/field.storage.node.field_emphasized_title_text.yml @@ -0,0 +1,21 @@ +uuid: 6b7c8d9e-0f1a-2b3c-4d5e-6f7a8b9c0d1e +langcode: en +status: true +dependencies: + module: + - node +id: node.field_emphasized_title_text +field_name: field_emphasized_title_text +entity_type: node +type: string +settings: + max_length: 255 + is_ascii: false + case_sensitive: false +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/sync/field.storage.node.field_report_files.yml b/config/sync/field.storage.node.field_report_files.yml new file mode 100644 index 000000000..fc02fb15e --- /dev/null +++ b/config/sync/field.storage.node.field_report_files.yml @@ -0,0 +1,20 @@ +uuid: 5a6b7c8d-9e0f-1a2b-3c4d-5e6f7a8b9c0d +langcode: en +status: true +dependencies: + module: + - media + - node +id: node.field_report_files +field_name: field_report_files +entity_type: node +type: entity_reference +settings: + target_type: media +module: core +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/sync/field.storage.node.field_report_state.yml b/config/sync/field.storage.node.field_report_state.yml new file mode 100644 index 000000000..ca9ba05c8 --- /dev/null +++ b/config/sync/field.storage.node.field_report_state.yml @@ -0,0 +1,19 @@ +uuid: 3e4f5a6b-7c8d-9e0f-1a2b-3c4d5e6f7a8b +langcode: en +status: true +dependencies: + module: + - address + - node +id: node.field_report_state +field_name: field_report_state +entity_type: node +type: address +settings: { } +module: address +locked: false +cardinality: -1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/sync/field.storage.node.field_report_topic.yml b/config/sync/field.storage.node.field_report_topic.yml new file mode 100644 index 000000000..fd02f51c9 --- /dev/null +++ b/config/sync/field.storage.node.field_report_topic.yml @@ -0,0 +1,20 @@ +uuid: 4f5a6b7c-8d9e-0f1a-2b3c-4d5e6f7a8b9c +langcode: en +status: true +dependencies: + module: + - node + - taxonomy +id: node.field_report_topic +field_name: field_report_topic +entity_type: node +type: entity_reference +settings: + target_type: taxonomy_term +module: core +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/config/sync/language.content_settings.node.report_summary.yml b/config/sync/language.content_settings.node.report_summary.yml new file mode 100644 index 000000000..72b6436b5 --- /dev/null +++ b/config/sync/language.content_settings.node.report_summary.yml @@ -0,0 +1,11 @@ +uuid: 0d1e2f3a-4b5c-6d7e-8f9a-0b1c2d3e4f5a +langcode: en +status: true +dependencies: + config: + - node.type.report_summary +id: node.report_summary +target_entity_type_id: node +target_bundle: report_summary +default_langcode: site_default +language_alterable: false diff --git a/config/sync/node.type.report_summary.yml b/config/sync/node.type.report_summary.yml new file mode 100644 index 000000000..99e3c80f1 --- /dev/null +++ b/config/sync/node.type.report_summary.yml @@ -0,0 +1,17 @@ +uuid: 2d3e4f5a-6b7c-8d9e-0f1a-2b3c4d5e6f7a +langcode: en +status: true +dependencies: + module: + - menu_ui +third_party_settings: + menu_ui: + available_menus: { } + parent: '' +name: 'Report summary' +type: report_summary +description: 'A summary of a report with associated PDF files.' +help: null +new_revision: true +preview_mode: 1 +display_submitted: false diff --git a/config/sync/taxonomy.vocabulary.report_topics.yml b/config/sync/taxonomy.vocabulary.report_topics.yml new file mode 100644 index 000000000..057308fea --- /dev/null +++ b/config/sync/taxonomy.vocabulary.report_topics.yml @@ -0,0 +1,9 @@ +uuid: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d +langcode: en +status: true +dependencies: { } +name: 'Report topics' +vid: report_topics +description: 'Topics for categorizing report summaries.' +weight: 0 +new_revision: false diff --git a/web/modules/custom/ilr_section_navigation/src/Plugin/ExtraField/Display/SectionNavigation.php b/web/modules/custom/ilr_section_navigation/src/Plugin/ExtraField/Display/SectionNavigation.php index 06f6a8d8d..c5cf13d16 100644 --- a/web/modules/custom/ilr_section_navigation/src/Plugin/ExtraField/Display/SectionNavigation.php +++ b/web/modules/custom/ilr_section_navigation/src/Plugin/ExtraField/Display/SectionNavigation.php @@ -20,6 +20,7 @@ * "collection.subsite_blog", * "collection.content_section", * "node.page", + * "node.report_summary", * "taxonomy_term.*", * }, * visible = true diff --git a/web/themes/custom/union_marketing/js/jump-links-mobile.js b/web/themes/custom/union_marketing/js/jump-links-mobile.js new file mode 100644 index 000000000..c4dca97aa --- /dev/null +++ b/web/themes/custom/union_marketing/js/jump-links-mobile.js @@ -0,0 +1,68 @@ +(function (Drupal) { + 'use strict'; + + Drupal.behaviors.jumpLinksMobile = { + attach: function (context, settings) { + // Find the jump links navigation block + const navBlock = context.querySelector('.block-extra-field-block--node--report-summary--extra-field-ilr-section-navigation'); + + if (!navBlock || navBlock.querySelector('.jump-links-mobile')) { + return; + } + + // Get all navigation links + const navLinks = navBlock.querySelectorAll('.cu-page-nav__link'); + + if (navLinks.length === 0) { + return; + } + + // Create mobile dropdown container + const mobileContainer = document.createElement('div'); + mobileContainer.className = 'jump-links-mobile'; + + // Create label + const label = document.createElement('div'); + label.className = 'jump-links-label'; + label.textContent = 'JUMP TO:'; + mobileContainer.appendChild(label); + + // Create select element + const select = document.createElement('select'); + select.className = 'jump-links-select'; + + // Add default option + const defaultOption = document.createElement('option'); + defaultOption.value = ''; + defaultOption.textContent = 'Select a section'; + select.appendChild(defaultOption); + + // Add options from navigation links + navLinks.forEach(function (link) { + const option = document.createElement('option'); + option.value = link.getAttribute('href'); + const heading = link.querySelector('.cu-heading'); + option.textContent = heading ? heading.textContent.trim() : link.textContent.trim(); + select.appendChild(option); + }); + + // Handle select change + select.addEventListener('change', function () { + if (this.value) { + window.location.href = this.value; + } + }); + + mobileContainer.appendChild(select); + + // Insert mobile dropdown at the beginning of the nav block + const cuPageNav = navBlock.querySelector('.cu-page-nav'); + if (cuPageNav) { + navBlock.insertBefore(mobileContainer, cuPageNav); + } else { + navBlock.insertBefore(mobileContainer, navBlock.firstChild); + } + } + }; + +})(Drupal); diff --git a/web/themes/custom/union_marketing/scss/components/_report-summary.scss b/web/themes/custom/union_marketing/scss/components/_report-summary.scss new file mode 100644 index 000000000..1c6135f60 --- /dev/null +++ b/web/themes/custom/union_marketing/scss/components/_report-summary.scss @@ -0,0 +1,361 @@ +/** + * Report Summary Banner and Layout Styles + */ + +.report-summary-banner { + position: relative; + background-size: cover; + background-position: center; + min-height: 600px; + display: flex; + align-items: center; + + &__overlay { + position: absolute; + inset: 0; + background: + linear-gradient(270deg, rgba(34, 34, 34, 0) 0%, #222 100%), + linear-gradient(0deg, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.3) 100%); + } + + &__container { + position: relative; + z-index: 1; + width: 100%; + max-width: 1440px; + margin: 0 auto; + padding: 60px 103px; + } + + &__breadcrumbs { + position: absolute; + top: 0; + left: 0; + z-index: 2; + padding: 20px 103px; + + .cu-breadcrumb__item { + color: #fff; + opacity: 0.7; + font-family: 'Replica Std', sans-serif; + font-size: 12px; + font-weight: 700; + letter-spacing: 1.2px; + text-transform: uppercase; + + a { + color: inherit; + text-decoration: none; + } + + &:not(:last-child)::after { + content: ''; + display: inline-block; + width: 4px; + height: 8px; + margin: 0 12px; + background-image: url("data:image/svg+xml,%3Csvg width='4' height='8' viewBox='0 0 4 8' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0.5 0.5L3.5 4L0.5 7.5' stroke='%23C1B7B1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: center; + vertical-align: middle; + } + } + } + + &__content { + position: relative; + max-width: calc(100% - 410px); // Leave space for sidebar (350px + 60px gap) + } + + &__main { + color: #fff; + } + + &__eyebrow { + margin-bottom: 20px; + + .cu-eyebrow { + color: #fff; + font-family: 'Replica Std', sans-serif; + font-size: 12px; + font-weight: 700; + letter-spacing: 1.2px; + text-transform: uppercase; + } + } + + &__title { + color: #fff; + font-family: 'FuturaBT', sans-serif; + font-size: 50px; + font-weight: 900; + line-height: 56px; + margin-bottom: 30px; + + strong { + display: block; + font-weight: 900; + } + } + + &__topics { + display: flex; + gap: 12px; + flex-wrap: wrap; + margin-top: 24px; + + .field__item { + border-radius: 100px; + border: 1px solid var(--Light-Iron, #BABABA); + background: rgba(0, 0, 0, 0.50); + padding: 8px 20px; + + a { + color: #fff; + text-decoration: none; + } + } + } + + &__sidebar { + position: absolute; + bottom: 16px; + right: 16px; + width: 350px; + background: #fff; + padding: 40px 30px; + border-radius: 0; + box-shadow: 0px 0px 24px 0px rgba(0, 0, 0, 0.14); + z-index: 2; + } +} + +.report-summary-metadata { + &__item { + margin-bottom: 24px; + + &:last-child { + margin-bottom: 0; + } + } + + &__label { + font-family: 'Replica Std', sans-serif; + font-size: 16px; + font-weight: 700; + color: #222; + margin: 0 0 8px 0; + line-height: 1.5; + } + + &__value { + font-family: 'Replica Std', sans-serif; + font-size: 16px; + font-weight: 400; + color: #222; + line-height: 1.5; + + .field__item { + margin-bottom: 2px; + + &:last-child { + margin-bottom: 0; + } + + a { + color: #000; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 24px; + letter-spacing: 0.32px; + text-decoration: none; + + } + } + } +} + +// Read the Report button styling +a.cu-button.cu-button--red.report-summary-cta { + display: inline-block; + background: #b31b1b; + color: #fff; + font-family: 'Replica Std', sans-serif; + font-size: 16px; + font-weight: 700; + line-height: 24px; + padding: 12px 24px; + text-decoration: none; + border: none; + border-radius: 0; + transition: background-color 0.2s ease; + + &:hover { + background: #8b1515; + color: #fff; + text-decoration: none; + } + + &:focus { + outline: 2px solid #b31b1b; + outline-offset: 2px; + } +} + +// Jump links navigation styling for Report Summary +// Target the block directly using its unique class +div.block-extra-field-block--node--report-summary--extra-field-ilr-section-navigation { + background: #f7f6f6; + padding: 16px 0; + + // Mobile dropdown styles + .jump-links-mobile { + display: block; + max-width: 1440px; + margin: 0 auto; + padding: 0 20px; + + .jump-links-label { + font-family: 'Replica Std', sans-serif; + font-size: 11px; + font-weight: 700; + letter-spacing: 1.2px; + text-transform: uppercase; + color: #767676; + margin-bottom: 8px; + } + + .jump-links-select { + width: 100%; + padding: 12px 40px 12px 16px; + font-family: 'Replica Std', sans-serif; + font-size: 14px; + color: #222; + background: #fff; + border: 1px solid #ccc; + border-radius: 0; + appearance: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23767676' d='M6 8L1 3h10z'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 16px center; + cursor: pointer; + + &:focus { + outline: 2px solid #b31b1b; + outline-offset: 2px; + } + } + } + + // Desktop list styles - hidden on mobile + div.cu-page-nav ul.cu-page-nav__list { + display: none; + } + + // Desktop breakpoint + @media (min-width: 768px) { + .jump-links-mobile { + display: none; + } + + div.cu-page-nav ul.cu-page-nav__list { + max-width: 1440px; + margin: 0 auto; + padding: 0 40px; + display: flex; + gap: 50px; + list-style: none; + + li.cu-page-nav__item { + position: relative; + + a.cu-page-nav__link { + color: #767676; + text-decoration: none; + display: inline-flex; + align-items: center; + gap: 6px; + position: relative; + padding-bottom: 4px; + + h4.cu-heading { + font-family: 'Replica Std', sans-serif; + font-size: 12px; + font-weight: normal; + letter-spacing: 1.2px; + text-transform: uppercase; + color: #767676; + margin: 0; + line-height: 20px; + color: var(--Iron, #222); + + &::after { + display: none; + } + } + + &::after { + content: '↓'; + font-size: 20px; + color: #767676; + } + } + } + } + } +} + +// Responsive adjustments +@media (max-width: 1024px) { + .report-summary-banner { + &__container { + padding: 0 40px 40px; + } + + &__content { + max-width: 100%; + } + + &__sidebar { + position: static; + width: 100%; + margin-top: 40px; + } + + &__title { + font-size: 67px; + line-height: 76px; + } + } + + .node--type-report-summary .cu-page-nav__list { + padding: 0 40px; + gap: 40px; + } +} + +@media (max-width: 768px) { + .report-summary-banner { + min-height: 400px; + + &__container { + padding: 0 20px 30px; + } + + &__sidebar { + padding: 30px 20px; + } + + &__title { + font-size: 50px; + line-height: 56px; + } + } + + .node--type-report-summary .cu-page-nav__list { + padding: 0 20px; + flex-direction: column; + gap: 20px; + } +} diff --git a/web/themes/custom/union_marketing/scss/style.scss b/web/themes/custom/union_marketing/scss/style.scss index 9feea11dd..b6b63b3c6 100644 --- a/web/themes/custom/union_marketing/scss/style.scss +++ b/web/themes/custom/union_marketing/scss/style.scss @@ -30,6 +30,7 @@ @import "components/profile"; @import "components/projects"; @import "components/publication"; +@import "components/report-summary"; @import "components/stats"; @import "components/stories"; @import "components/tables"; diff --git a/web/themes/custom/union_marketing/templates/content/node--report-summary.html.twig b/web/themes/custom/union_marketing/templates/content/node--report-summary.html.twig new file mode 100644 index 000000000..864a6722e --- /dev/null +++ b/web/themes/custom/union_marketing/templates/content/node--report-summary.html.twig @@ -0,0 +1,146 @@ +{# +/** + * @file + * Theme override for Report Summary nodes. + * + * This template provides a custom banner/header for Report Summary pages + * with emphasized title, breadcrumbs, metadata, and jump links. + * + * Available variables: + * - node: The node entity. + * - label: The title of the node. + * - content: All node items. + * - url: Direct URL of the current node. + * - emphasized_title: Title with emphasized text wrapped in tags. + * - breadcrumbs: Breadcrumb navigation. + * - page: Flag for full page state. + */ +#} +{% + set classes = [ + 'node', + 'node--type-' ~ node.bundle|clean_class, + not node.isPublished() ? 'node--unpublished', + view_mode ? 'node--view-mode-' ~ view_mode|clean_class, + ] +%} + + + + {% if page %} + {# Report Summary Banner/Header #} + {% set banner_style = '' %} + {% if representative_image_url %} + {% set banner_style = 'background-image: url(' ~ representative_image_url ~ ');' %} + {% elseif node.field_representative_image.entity %} + {# Fallback: Get image URL directly from field if preprocessing failed #} + {% set media = node.field_representative_image.entity %} + {% if media.field_media_image.entity %} + {% set image_uri = media.field_media_image.entity.uri.value %} + {% set banner_style = 'background-image: url(' ~ file_url(image_uri) ~ ');' %} + {% endif %} + {% endif %} +
+
+ + {# Breadcrumbs - positioned at top of banner #} + {% if breadcrumbs %} + + {% endif %} + +
+
+
+ {# Eyebrow #} +
+ Report +
+ + {# Title with emphasized text #} + {{ title_prefix }} +

+ {{ emphasized_title|raw }} +

+ {{ title_suffix }} + + {# Topic Tags #} + {% if node.field_report_topic|length > 0 %} +
+ {% for topic in node.field_report_topic %} + {% if topic.entity %} + + + {{ topic.entity.label }} + + + {% endif %} + {% endfor %} +
+ {% endif %} +
+
+
+
+ + {# Metadata Sidebar - positioned absolutely relative to banner #} + + + + {# Jump Links Navigation #} + {% if content.ilr_section_navigation|render %} + + {% endif %} + {% endif %} + + {# Main Content (Layout Builder sections) #} + + {{ content|without('field_emphasized_title_text', 'field_published_date', 'field_authors', 'field_report_files', 'field_report_topic', 'field_representative_image', 'ilr_section_navigation') }} + + + diff --git a/web/themes/custom/union_marketing/templates/field/field--field-report-files--report-summary.html.twig b/web/themes/custom/union_marketing/templates/field/field--field-report-files--report-summary.html.twig new file mode 100644 index 000000000..7a02ebf8b --- /dev/null +++ b/web/themes/custom/union_marketing/templates/field/field--field-report-files--report-summary.html.twig @@ -0,0 +1,17 @@ +{# +/** + * @file + * Theme override for the Report files field on Report Summary nodes. + * + * Displays the first PDF file as a red "Read the Report" button. + */ +#} +{% if items %} + {% set file = items[0].content['#media'] %} + {% if file and file.field_media_file.entity %} + {% set file_url = file_url(file.field_media_file.entity.uri.value) %} + + Read the Report + + {% endif %} +{% endif %} diff --git a/web/themes/custom/union_marketing/union_marketing.libraries.yml b/web/themes/custom/union_marketing/union_marketing.libraries.yml index 1848d6dfd..293d1cb0c 100644 --- a/web/themes/custom/union_marketing/union_marketing.libraries.yml +++ b/web/themes/custom/union_marketing/union_marketing.libraries.yml @@ -6,6 +6,7 @@ global: js: js/union_marketing.js: {} js/union_marketing_responsive_tables.js: {} + js/jump-links-mobile.js: {} dependencies: - core/drupal - core/jquery diff --git a/web/themes/custom/union_marketing/union_marketing.theme b/web/themes/custom/union_marketing/union_marketing.theme index 80053f129..732ae6a78 100644 --- a/web/themes/custom/union_marketing/union_marketing.theme +++ b/web/themes/custom/union_marketing/union_marketing.theme @@ -149,6 +149,62 @@ function union_marketing_preprocess_node(&$variables) { 'classes' => ['ui-dialog' => 'cu-modal'], ])); } + + // Report Summary specific preprocessing. + if ($variables['node']->bundle() === 'report_summary' && $variables['view_mode'] === 'full') { + $node = $variables['node']; + + // Process emphasized title text. + $title = $node->label(); + $emphasized_text = ''; + + if ($node->hasField('field_emphasized_title_text') && !$node->field_emphasized_title_text->isEmpty()) { + $emphasized_text = $node->field_emphasized_title_text->value; + } + + // Wrap emphasized text in tags if it exists in the title. + if (!empty($emphasized_text) && strpos($title, $emphasized_text) !== FALSE) { + $variables['emphasized_title'] = str_replace( + Html::escape($emphasized_text), + '' . Html::escape($emphasized_text) . '', + Html::escape($title) + ); + } + else { + $variables['emphasized_title'] = Html::escape($title); + } + + // Get representative image URL for banner background. + $variables['representative_image_url'] = ''; + try { + if ($node->hasField('field_representative_image') && !$node->field_representative_image->isEmpty()) { + $media = $node->field_representative_image->entity; + if ($media && $media->hasField('field_media_image') && !$media->field_media_image->isEmpty()) { + $file = $media->field_media_image->entity; + if ($file) { + $image_uri = $file->getFileUri(); + $image_style = ImageStyle::load('large'); + if ($image_style) { + $variables['representative_image_url'] = $image_style->buildUrl($image_uri); + } + } + } + } + } + catch (\Exception $e) { + // Silently fail if image cannot be loaded + \Drupal::logger('union_marketing')->warning('Could not load representative image for report summary @nid: @message', [ + '@nid' => $node->id(), + '@message' => $e->getMessage(), + ]); + } + + // Add breadcrumbs. + $breadcrumb_manager = \Drupal::service('breadcrumb'); + $route_match = \Drupal::routeMatch(); + $breadcrumb = $breadcrumb_manager->build($route_match); + $variables['breadcrumbs'] = $breadcrumb->toRenderable(); + } } /**