Hero
A Hero is often used at the top of a Landing page layout, such as a homepage, campaign page or section index page.
A Hero does have the capability of carouseling multiple slide. However, analytics have shown that engagement significantly decreases after the first slide, so only carousel if necessary.
Examples
Default
<section class="bux-hero bux-hero--card-left bux-hero--3x2">
<div class="bux-hero__items">
<div
id="bux-hero__carousel-1399966637-tab-1"
class="bux-hero__container bux-hero__container--showing"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--3x2"
src="/images/placeholders/osu-bux-5.jpg"
alt="Graduates performing the O-H-I-O pose"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline lorem ipsum</h2>
<div class="bux-hero__subheader">
<span>Subhead lorem ipsum dolor met</span>
</div>
<a class="bux-button bux-button--alt" href="#" rel="noopener">
<span class="bux-button__text bux-button--alt__text">
Call to Action
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Scarlet Left 3:2
<section class="bux-hero bux-hero--scarlet bux-hero--card-left bux-hero--3x2">
<div class="bux-hero__items">
<div
id="bux-hero__carousel-312728168-tab-1"
class="bux-hero__container bux-hero__container--showing"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--3x2"
src="/images/placeholders/osu-bux-5.jpg"
alt="Graduates performing the O-H-I-O pose"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline lorem ipsum</h2>
<div class="bux-hero__subheader">
<span>Subhead lorem ipsum dolor met</span>
</div>
<a class="bux-button bux-button--alt" href="#" rel="noopener">
<span class="bux-button__text bux-button--alt__text">
Call to Action
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Scarlet Right 3:2
<section class="bux-hero bux-hero--scarlet bux-hero--card-right bux-hero--3x2">
<div class="bux-hero__items">
<div
id="bux-hero__carousel-613486924-tab-1"
class="bux-hero__container bux-hero__container--showing"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--3x2"
src="/images/placeholders/osu-bux-5.jpg"
alt="Graduates performing the O-H-I-O pose"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline lorem ipsum</h2>
<div class="bux-hero__subheader">
<span>Subhead lorem ipsum dolor met</span>
</div>
<a class="bux-button bux-button--alt" href="#" rel="noopener">
<span class="bux-button__text bux-button--alt__text">
Call to Action
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Gray Left 3:2
<section class="bux-hero bux-hero--card-left bux-hero--3x2">
<div class="bux-hero__items">
<div
id="bux-hero__carousel-271986773-tab-1"
class="bux-hero__container bux-hero__container--showing"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--3x2"
src="/images/placeholders/osu-bux-5.jpg"
alt="Graduates performing the O-H-I-O pose"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline lorem ipsum</h2>
<div class="bux-hero__subheader">
<span>Subhead lorem ipsum dolor met</span>
</div>
<a class="bux-button bux-button--alt" href="#" rel="noopener">
<span class="bux-button__text bux-button--alt__text">
Call to Action
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Gray Right 3:2
<section class="bux-hero bux-hero--card-right bux-hero--3x2">
<div class="bux-hero__items">
<div
id="bux-hero__carousel-915313785-tab-1"
class="bux-hero__container bux-hero__container--showing"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--3x2"
src="/images/placeholders/osu-bux-5.jpg"
alt="Graduates performing the O-H-I-O pose"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline lorem ipsum</h2>
<div class="bux-hero__subheader">
<span>Subhead lorem ipsum dolor met</span>
</div>
<a class="bux-button bux-button--alt" href="#" rel="noopener">
<span class="bux-button__text bux-button--alt__text">
Call to Action
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Scarlet Left 16:9
<section class="bux-hero bux-hero--scarlet bux-hero--card-left bux-hero--16x9">
<div class="bux-hero__items">
<div
id="bux-hero__carousel-1386469300-tab-1"
class="bux-hero__container bux-hero__container--showing"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--16x9"
src="/images/placeholders/osu-bux-5.jpg"
alt="Graduates performing the O-H-I-O pose"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline lorem ipsum</h2>
<div class="bux-hero__subheader">
<span>Subhead lorem ipsum dolor met</span>
</div>
<a class="bux-button bux-button--alt" href="#" rel="noopener">
<span class="bux-button__text bux-button--alt__text">
Call to Action
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Scarlet Right 16:9
<section class="bux-hero bux-hero--scarlet bux-hero--card-right bux-hero--16x9">
<div class="bux-hero__items">
<div
id="bux-hero__carousel-1992861975-tab-1"
class="bux-hero__container bux-hero__container--showing"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--16x9"
src="/images/placeholders/osu-bux-5.jpg"
alt="Graduates performing the O-H-I-O pose"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline lorem ipsum</h2>
<div class="bux-hero__subheader">
<span>Subhead lorem ipsum dolor met</span>
</div>
<a class="bux-button bux-button--alt" href="#" rel="noopener">
<span class="bux-button__text bux-button--alt__text">
Call to Action
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Gray Left 16:9
<section class="bux-hero bux-hero--card-left bux-hero--16x9">
<div class="bux-hero__items">
<div
id="bux-hero__carousel-656967714-tab-1"
class="bux-hero__container bux-hero__container--showing"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--16x9"
src="/images/placeholders/osu-bux-5.jpg"
alt="Graduates performing the O-H-I-O pose"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline lorem ipsum</h2>
<div class="bux-hero__subheader">
<span>Subhead lorem ipsum dolor met</span>
</div>
<a class="bux-button bux-button--alt" href="#" rel="noopener">
<span class="bux-button__text bux-button--alt__text">
Call to Action
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Gray Right 16:9
<section class="bux-hero bux-hero--card-right bux-hero--16x9">
<div class="bux-hero__items">
<div
id="bux-hero__carousel-800433496-tab-1"
class="bux-hero__container bux-hero__container--showing"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--16x9"
src="/images/placeholders/osu-bux-5.jpg"
alt="Graduates performing the O-H-I-O pose"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline lorem ipsum</h2>
<div class="bux-hero__subheader">
<span>Subhead lorem ipsum dolor met</span>
</div>
<a class="bux-button bux-button--alt" href="#" rel="noopener">
<span class="bux-button__text bux-button--alt__text">
Call to Action
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Carousel
If necessary, the hero component can display multiple slides as a carousel.
<section
class="bux-hero bux-hero--gray bux-hero--card-left bux-hero--carousel bux-hero--3x2"
aria-roledescription="carousel"
aria-label="Highlighted stories"
>
<div class="visually-hidden">
Carousel of 3 slides. Use the Previous and Next buttons to navigate the
slides.
</div>
<div class="bux-carousel-controls" aria-label="Slide navigation" role="group">
<button
class="bux-carousel-controls__previous bux-carousel-controls__btn"
type="button"
aria-label="Previous Slide"
>
<span class="icon icon-chevron-left" aria-hidden="true"></span>
</button>
<button
class="bux-carousel-controls__next bux-carousel-controls__btn"
type="button"
aria-label="Next Slide"
>
<span class="icon icon-chevron-right" aria-hidden="true"></span>
</button>
</div>
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
<button
id="bux-hero__carousel-2143723703-tabbutton-1"
class="bux-hero__tab bux-hero__tab--active"
type="button"
role="tab"
aria-label="Slide 1 of 3"
aria-controls="bux-hero__carousel-2143723703-tab-1"
aria-selected="true"
tabindex="0"
>
<span class="visually-hidden">Slide 1</span>
</button>
<button
id="bux-hero__carousel-2143723703-tabbutton-2"
class="bux-hero__tab"
type="button"
role="tab"
aria-label="Slide 2 of 3"
aria-controls="bux-hero__carousel-2143723703-tab-2"
aria-selected="false"
tabindex="-1"
>
<span class="visually-hidden">Slide 2</span>
</button>
<button
id="bux-hero__carousel-2143723703-tabbutton-3"
class="bux-hero__tab"
type="button"
role="tab"
aria-label="Slide 3 of 3"
aria-controls="bux-hero__carousel-2143723703-tab-3"
aria-selected="false"
tabindex="-1"
>
<span class="visually-hidden">Slide 3</span>
</button>
</div>
<div
id="bux-hero__carousel-2143723703-items"
class="bux-hero__items bux-hero__carousel-items"
>
<div
id="bux-hero__carousel-2143723703-tab-1"
class="bux-hero__container bux-hero__container--showing"
role="tabpanel"
aria-labelledby="bux-hero__carousel-2143723703-tabbutton-1"
tabindex="0"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--3x2"
src="/images/placeholders/osu-bux-5.jpg"
alt="Graduates performing the O-H-I-O pose"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline 1 lorem ipsum</h2>
<div class="bux-hero__subheader">
<span>Subhead lorem ipsum dolor met</span>
</div>
<a class="bux-button bux-button--alt" href="#" rel="noopener">
<span class="bux-button__text bux-button--alt__text">
Call to Action
</span>
</a>
</div>
</div>
<div
id="bux-hero__carousel-2143723703-tab-2"
class="bux-hero__container"
role="tabpanel"
aria-labelledby="bux-hero__carousel-2143723703-tabbutton-2"
tabindex="-1"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--3x2"
src="/images/placeholders/osu-bux-2.jpg"
alt="A marching band member high-fives a crowd"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline 2 lorem ipsum</h2>
<div class="bux-hero__subheader">
<span>Subhead lorem ipsum dolor met</span>
</div>
<a class="bux-button bux-button--alt" href="#" rel="noopener">
<span class="bux-button__text bux-button--alt__text">
Call to Action
</span>
</a>
</div>
</div>
<div
id="bux-hero__carousel-2143723703-tab-3"
class="bux-hero__container"
role="tabpanel"
aria-labelledby="bux-hero__carousel-2143723703-tabbutton-3"
tabindex="-1"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--3x2"
src="/images/placeholders/osu-bux-4.jpg"
alt="A person in a scarlet shirt poses for a photo"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline 3 lorem ipsum</h2>
<div class="bux-hero__subheader">
<span>Subhead lorem ipsum dolor met</span>
</div>
<a class="bux-button bux-button--alt" href="#" rel="noopener">
<span class="bux-button__text bux-button--alt__text">
Call to Action
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Statistic at Start
A statistic Hero leads with a large number, followed by the text that gives it context. Add bux-hero-text-content--statistic to the text content and wrap the number in header__statistic, with the supporting copy in header__text-after-stat. In Twig, set hero_text_variant to statistic and supply a statistic_text object.
<section class="bux-hero bux-hero--gray bux-hero--card-left bux-hero--3x2">
<div class="bux-hero__items">
<div
id="bux-hero__carousel-1069769561-tab-1"
class="bux-hero__container bux-hero__container--showing"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--3x2"
src="/images/placeholders/osu-bux-5.jpg"
alt="Graduates performing the O-H-I-O pose"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content bux-hero-text-content--statistic">
<h2 class="bux-heading bux-hero__header">
<span class="header__statistic">50%</span>
<span class="header__text-after-stat">
of students graduate with no debt.
</span>
</h2>
<div class="bux-hero__subheader">
<span></span>
</div>
<a class="bux-button bux-button--alt" href="#" rel="noopener">
<span class="bux-button__text bux-button--alt__text">
Call to Action
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Statistic in Middle
The statistic can also sit between two pieces of copy. Add the leading text in header__text-before-stat and the rest in header__text-after-stat. Keep the statistic short so the headline stays readable at mobile widths.
<section class="bux-hero bux-hero--gray bux-hero--card-left bux-hero--3x2">
<div class="bux-hero__items">
<div
id="bux-hero__carousel-1047578846-tab-1"
class="bux-hero__container bux-hero__container--showing"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--3x2"
src="/images/placeholders/osu-bux-5.jpg"
alt="Graduates performing the O-H-I-O pose"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content bux-hero-text-content--statistic">
<h2 class="bux-heading bux-hero__header">
<span class="header__text-before-stat">Ohio State is the</span>
<span class="header__statistic">#15</span>
<span class="header__text-after-stat">
public research university.
</span>
</h2>
<div class="bux-hero__subheader">
<span></span>
</div>
<a class="bux-button bux-button--alt" href="#" rel="noopener">
<span class="bux-button__text bux-button--alt__text">
Call to Action
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Image with Gray Text Box
Headline lorem ipsum
Subhead lorem ipsum dolor met<section class="bux-hero bux-hero--gray bux-hero--card-full bux-hero--16x9">
<div class="bux-hero__items">
<div
id="bux-hero__carousel-809205362-tab-1"
class="bux-hero__container bux-hero__container--showing"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--16x9"
src="/images/placeholders/osu-bux-5.jpg"
alt="Graduates performing the O-H-I-O pose"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline lorem ipsum</h2>
<a class="bux-hero__subheader bux-text-link" href="#" rel="noopener">
<span class="bux-hero__subheader__text bux-text-link__text">
Subhead lorem ipsum dolor met
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Image with White Text Box
Headline lorem ipsum
Subhead lorem ipsum dolor met<section class="bux-hero bux-hero--white bux-hero--card-full bux-hero--16x9">
<div class="bux-hero__items">
<div
id="bux-hero__carousel-1882170495-tab-1"
class="bux-hero__container bux-hero__container--showing"
>
<div class="bux-hero__image-container">
<figure class="bux-image">
<img
class="bux-image--16x9"
src="/images/placeholders/osu-bux-5.jpg"
alt="Graduates performing the O-H-I-O pose"
height=""
width=""
/>
</figure>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline lorem ipsum</h2>
<a class="bux-hero__subheader bux-text-link" href="#" rel="noopener">
<span class="bux-hero__subheader__text bux-text-link__text">
Subhead lorem ipsum dolor met
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Video with Gray Text Box
Headline lorem ipsum
Subhead lorem ipsum dolor met<section class="bux-hero bux-hero--gray bux-hero--card-full bux-hero--16x9">
<div class="bux-hero__items">
<div
id="bux-hero__carousel-2083251832-tab-1"
class="bux-hero__container bux-hero__container--showing"
>
<div class="bux-hero__image-container">
<div class="bux-hero__image">
<video
aria-label="Background Video"
tabindex="-1"
loop
autoplay
playsinline
muted
class="bux-hero__video"
>
<source
src="/images/placeholders/hero-video-clip.mp4"
type="video/mp4"
/>
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div
class="bux-hero__video-button-icon bux-hero__video-button-icon--play"
aria-hidden="true"
>
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div
class="bux-hero__video-button-icon bux-hero__video-button-icon--pause"
aria-hidden="true"
>
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline lorem ipsum</h2>
<a class="bux-hero__subheader bux-text-link" rel="noopener">
<span class="bux-hero__subheader__text bux-text-link__text">
Subhead lorem ipsum dolor met
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Video with White Text Box
Headline lorem ipsum
Subhead lorem ipsum dolor met<section class="bux-hero bux-hero--white bux-hero--card-full bux-hero--16x9">
<div class="bux-hero__items">
<div
id="bux-hero__carousel-761585474-tab-1"
class="bux-hero__container bux-hero__container--showing"
>
<div class="bux-hero__image-container">
<div class="bux-hero__image">
<video
aria-label="Background Video"
tabindex="-1"
loop
autoplay
playsinline
muted
class="bux-hero__video"
>
<source
src="/images/placeholders/hero-video-clip.mp4"
type="video/mp4"
/>
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div
class="bux-hero__video-button-icon bux-hero__video-button-icon--play"
aria-hidden="true"
>
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div
class="bux-hero__video-button-icon bux-hero__video-button-icon--pause"
aria-hidden="true"
>
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
</div>
<div class="bux-hero-text-content">
<h2 class="bux-heading bux-hero__header">Headline lorem ipsum</h2>
<a class="bux-hero__subheader bux-text-link" rel="noopener">
<span class="bux-hero__subheader__text bux-text-link__text">
Subhead lorem ipsum dolor met
</span>
</a>
</div>
</div>
</div>
</section>
{#
Buckeye UX - version 1.7.0
Copyright (C) 2026 The Ohio State University
#}
{#
Hero
Available Variables:
- background: Optional. Sets the Hero background color: gray, scarlet, or white
- card_orientation: Sets the card orientation: card-left, card-right, card-full.
- ratio: Optional. Sets the hero's image ratio: 16x9 or 3x2
- hero_heading_level: Integer. Sets the heading level of the header.
- cards: Array containing the cards for the hero carousel: hero_header, hero_subheader, hero_image, hero_image_alt, button_text, button_url, hero_video_mp4, hero_aria_label.
- carousel_aria_label: Optional. String for the carousel aria-label.
- carousel_id: Optional. Unique ID for the carousel.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 10-01-2026 11:01:36
#}
{% import '@bux/_macros/attributes.twig' as Attributes %}
{% set random_seed = random() %}
{% set carousel_uniqueid = carousel_id ~ '-' ~ random_seed %}
{% set hero_heading_level = hero_heading_level|default(2) %}
{% set section_classes =
[
'bux-hero',
background ? 'bux-hero--' ~ background : '',
'bux-hero--' ~ card_orientation,
(cards|length) > 1 ? 'bux-hero--carousel' : '',
ratio ? 'bux-hero--' ~ ratio : ''
]
|join(' ')
|trim
%}
{% set section_attributes =
{
class: section_classes,
'aria-roledescription': (cards|length) > 1 ? 'carousel' : null,
'aria-label': (cards|length) > 1 ? carousel_aria_label : null
}|filter(v => v is not null)
%}
<section {{ Attributes.render(section_attributes) }}>
{% if (cards|length) > 1 %}
<div class="visually-hidden">
Carousel of {{ cards|length }} slides. Use the Previous and Next buttons to navigate the slides.
</div>
{% include '@bux/carousel-controls/carousel-controls.twig' with {
previous_label: 'Previous Slide',
next_label: 'Next Slide',
group_aria_label: 'Slide navigation'
} only %}
{% endif %}
{% if (cards|length) > 1 %}
<div class="bux-hero__tabs" role="tablist" aria-label="Slides">
{% for card in cards %}
{% set tab_attributes = {
id: carousel_uniqueid ~ '-tabbutton-' ~ loop.index,
class: 'bux-hero__tab' ~ (loop.index == 1 ? ' bux-hero__tab--active' : ''),
type: 'button',
role: 'tab',
'aria-label': 'Slide ' ~ loop.index ~ ' of ' ~ (cards|length),
'aria-controls': carousel_uniqueid ~ '-tab-' ~ loop.index,
'aria-selected': loop.index == 1 ? 'true' : 'false',
tabindex: loop.index == 1 ? '0' : '-1'
} %}
<button {{ Attributes.render(tab_attributes) }}>
<span class="visually-hidden">Slide {{ loop.index }}</span>
</button>
{% endfor %}
</div>
{% endif %}
{% set items_attributes =
{
id: (cards|length) > 1 ? "#{carousel_uniqueid}-items" : null,
class: 'bux-hero__items' ~ ((cards|length) > 1 ? ' bux-hero__carousel-items' : '')
}|filter(v => v is not null)
%}
<div {{ Attributes.render(items_attributes) }}>
{% for card in cards %}
{% set panel_attributes =
{
id: carousel_uniqueid ~ '-tab-' ~ loop.index,
class: 'bux-hero__container' ~ (loop.index == 1 ? ' bux-hero__container--showing' : ''),
role: (cards|length) > 1 ? 'tabpanel' : null,
'aria-labelledby': (cards|length) > 1 ? carousel_uniqueid ~ '-tabbutton-' ~ loop.index : null,
tabindex: (cards|length) > 1 ? loop.index == 1 ? '0' : '-1' : null
}|filter(v => v is not null)
%}
<div {{ Attributes.render(panel_attributes) }}>
<div class="bux-hero__image-container">
{% if card.hero_image %}
{% include '@bux/image/image.twig' with {
image_url: card.hero_image,
image_alt_text: card.hero_image_alt,
image_ratio: ratio
} only %}
{% elseif card.hero_video_mp4 %}
<div class="bux-hero__image">
{% set video_attributes = {
'aria-label': card.hero_aria_label,
tabindex: '-1',
loop: true,
autoplay: true,
playsinline: true,
muted: true,
class: 'bux-hero__video'
} %}
<video {{ Attributes.render(video_attributes) }}>
<source src="{{ card.hero_video_mp4 }}" type="video/mp4" />
</video>
<button type="button" class="bux-hero__video-button">
<span class="visually-hidden">Pause video</span>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--play" aria-hidden="true">
<span class="bux-icon icon-play-fill" aria-hidden="true"></span>
</div>
<div class="bux-hero__video-button-icon bux-hero__video-button-icon--pause" aria-hidden="true">
<span class="bux-icon icon-pause-fill" aria-hidden="true"></span>
</div>
</button>
</div>
{% endif %}
</div>
{% include '@bux/hero-text-content/hero-text-content.twig' with {
card_orientation: card_orientation,
hero_text_variant: card.hero_text_variant,
statistic_text: card.statistic_text,
heading: {
text: card.hero_header,
level: hero_heading_level
},
subheading: {
text: card.hero_subheader
},
cta: {
url: card.button_url,
text: card.button_text
}
} %}
</div>
{% endfor %}
</div>
</section>
Usage
Dos
- Use to call attention to the highest-priority among all content, such as a campaign, story or other call-to-action
- Limit to one per page
- Include a high-quality image
- Strongly consider using the included Button as a call-to-action
- Use the variant with scarlet background to convey a bold and energetic feel for a less formal audience
- Use the variant with image on the right if the subject of the image faces left
- Use the variant with image on the left if the subject of the image faces right
Don’ts
- Don’t autoplay the slides when using a Carousel
- Don’t use a Hero on a page that is not the homepage; If a high visual emphasis is needed, consider a Featured Card instead
Accessibility
- Make sure to write quality alternative text for the image in the Hero component