Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 170 additions & 13 deletions blocks/hero/hero.css
Original file line number Diff line number Diff line change
@@ -1,37 +1,194 @@
.hero-container .hero-wrapper {
div.hero-container:not(.teaser) {
margin-top: 0;
}

.hero-container:not(.teaser) .hero-wrapper {
max-width: unset;
padding: 0;
}

.hero {
display: flex;
align-items: center;
position: relative;
min-height: 300px;
padding: var(--space-l) var(--space-m);
overflow: hidden;
min-height: 350px;
border-bottom: 1px solid var(--color-border);
}

.hero h1 {
.hero > div {
display: flex;
flex: 1;
flex-direction: column;
max-width: var(--site-width);
margin-left: auto;
margin-right: auto;
color: var(--color-bg);
margin: 0 auto;
}

@media (width >= 900px) {
.hero {
color: var(--color-bg);
}

.hero::before {
content: '';
position: absolute;
inset: 0;
z-index: 1;
background: linear-gradient(to right, rgb(0 0 0 / 85%) 7%, rgb(0 0 0 / 0%) 60%);
pointer-events: none;
}

.hero[data-body="right"]::before {
background: linear-gradient(to left, rgb(0 0 0 / 85%) 7%, rgb(0 0 0 / 0%) 60%);
}
}

.hero picture {
.hero .media-wrapper {
flex-shrink: 0;
order: -1;
position: relative;
z-index: 0;
min-height: 200px;
}

.hero .media-wrapper picture {
display: block;
position: absolute;
inset: 0;
z-index: -1;
box-sizing: border-box;
}

.hero .media-wrapper img {
display: block;
height: 100%;
width: 100%;
object-fit: cover;
}

.hero img {
.hero .media-wrapper video {
position: absolute;
inset: 0;
z-index: 1;
height: 100%;
width: 100%;
object-fit: cover;
}

@media (width >= 600px) {
.hero .media-wrapper {
min-height: 285px;
}
}

@media (width >= 900px) {
.hero {
padding: var(--space-l) var(--space-l);
.hero .media-wrapper {
order: 0;
position: absolute;
inset: 0;
min-height: auto;
}
}

.hero .body-wrapper {
position: relative;
z-index: 2;
padding: var(--space-m);
}

.hero .body-wrapper h1,
.hero .body-wrapper h2,
.hero .body-wrapper h3,
.hero .body-wrapper h4,
.hero .body-wrapper h5,
.hero .body-wrapper h6,
.hero .body-wrapper p {
color: inherit;
}

.hero .body-wrapper h1::after,
.hero .body-wrapper h2::after,
.hero .body-wrapper h3::after,
.hero .body-wrapper h4::after,
.hero .body-wrapper h5::after,
.hero .body-wrapper h6::after {
content: '';
display: block;
height: 5px;
width: 40px;
margin-top: var(--space-s);
background-color: var(--color-brand);
}

@media (width >= 900px) {
.hero .body-wrapper {
max-width: 55%;
}

.hero[data-body="right"] .body-wrapper {
margin-left: auto;
}

.hero .body-wrapper h1 {
margin-bottom: 1em;
font-size: 3.375rem;
text-shadow: 0 1px 5px rgb(0 0 0 / 60%);
}

.hero .body-wrapper .button {
min-width: 200px;
}
}

/* TEASER */

.hero.teaser {
background-color: var(--color-black);
color: var(--color-bg);
}

@media (width >= 900px) {
.hero.teaser {
align-items: center;
min-height: 325px;
}

.hero.teaser::before {
background: linear-gradient(to right, var(--color-black) 7%, rgb(0 0 0 / 0%) 93%);
}

.hero.teaser[data-body="right"]::before {
background: linear-gradient(to left, var(--color-black) 7%, rgb(0 0 0 / 0%) 93%);
}
}

.hero.teaser .media-wrapper::before {
content: '';
position: absolute;
inset: 0;
z-index: 2;
background: linear-gradient(to top, var(--color-black) 7%, rgb(0 0 0 / 0%) 60%);
pointer-events: none;
}

@media (width >= 900px) {
.hero.teaser .media-wrapper::before {
content: none;
}
}

.hero.teaser .body-wrapper .button {
width: 100%;
}

@media (width >= 600px) {
.hero.teaser .body-wrapper .button {
width: unset;
min-width: 200px;
}
}

@media (width >= 900px) {
.hero.teaser .body-wrapper {
max-width: 360px;
padding: var(--space-m) var(--space-xl);
}
}
42 changes: 42 additions & 0 deletions blocks/hero/hero.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Configures ambient video and unwraps pictures.
* @param {HTMLElement} col
*/
function decorateMedia(col) {
const video = col.querySelector('video');
if (video) {
video.removeAttribute('controls');
video.muted = true;
video.autoplay = true;
video.loop = true;
}

col.querySelectorAll('p > picture').forEach((pic) => {
pic.parentElement.replaceWith(pic);
});
}

export default function decorate(block) {
const cols = [...block.querySelectorAll(':scope > div > div')];

const mediaCol = cols.find((col) => {
const els = [...col.children];
return els.length > 0 && els.every((el) => {
if (el.tagName === 'VIDEO' || el.tagName === 'PICTURE') return true;
return el.tagName === 'P' && el.children.length === 1 && el.children[0].tagName === 'PICTURE';
});
});
mediaCol.className = 'media-wrapper';
decorateMedia(mediaCol);

const bodyCol = cols.find((col) => col !== mediaCol);
bodyCol.className = 'body-wrapper';

if (cols[0] === mediaCol) block.dataset.body = 'right';

const heading = block.querySelector('h1, h2, h3, h4, h5, h6');
if (!heading || heading.tagName !== 'H1') {
block.classList.add('teaser');
block.closest('.hero-container').classList.add('teaser');
}
}
27 changes: 26 additions & 1 deletion scripts/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,30 @@ function buildWidgetAutoBlocks(main) {
});
}

/**
* Replaces standalone .mp4 links with native video elements.
* @param {Element} main The container element
*/
function decorateVideos(main) {
main.querySelectorAll('a[href$=".mp4"]').forEach((link) => {
const video = document.createElement('video');
video.src = link.href;
video.controls = true;
video.setAttribute('playsinline', '');
const p = link.closest('p');
if (
p
&& p.querySelectorAll('a[href]').length === 1
&& p.querySelector('a[href]') === link
&& p.textContent.trim() === link.textContent.trim()
) {
p.replaceWith(video);
} else {
link.replaceWith(video);
}
});
}

/**
* Builds all synthetic blocks in a container element.
* @param {Element} main The container element
Expand Down Expand Up @@ -145,11 +169,12 @@ export function decorateExternalLinks(container) {
*/
// eslint-disable-next-line import/prefer-default-export
export function decorateMain(main) {
decorateIcons(main);
buildAutoBlocks(main);
decorateIcons(main);
decorateSections(main);
decorateBlocks(main);
decorateButtons(main);
decorateVideos(main);
}

/**
Expand Down