Merge branch 'feature/a11y-improvements' into develop

This commit is contained in:
Björn Fromme
2025-06-27 18:41:59 +02:00
64 changed files with 502 additions and 431 deletions
@@ -1,3 +1,6 @@
.iconbar {
@apply hidden lg:block fixed z-100 top-[30vh] right-0 overflow-hidden;
}
.iconbar {
display: none;
@include mq($from: desktop) {
@@ -181,10 +181,5 @@ return [
'eval' => 'double2',
]
],
'sorting' => [
'config' => [
'type' => 'passthrough'
]
],
],
];
@@ -1,11 +1,10 @@
<?php
return [
'ctrl' => [
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_hotel',
'title' => 'LLL:EXT:ep_products/Resources/Private/Language/locallang.xlf:tx_epproducts_domain_model_hotel',
'default_sortby' => 'ORDER BY name',
'label' => 'name',
'label_userFunc' => \EP\EpProducts\Service\LabelService::class.'->getHotelLabel',
'label_userFunc' => \EP\EpProducts\Service\LabelService::class . '->getHotelLabel',
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'cruser_id' => 'cruser_id',
@@ -43,9 +42,10 @@ return [
'name' => ['showitem' => 'name,short_name,--linebreak--,header_title,header_subtitle,--linebreak--,headline'],
'categories' => ['showitem' => 'type,category'],
'season' => ['showitem' => 'main_season_from, main_season_to'],
'others' => ['showitem' => 'season,groups_price_tax_label, groups_price_adolescents_age'],
'others' => ['showitem' => 'season,groups_price_tax_label, groups_price_adolescents_age']
],
'columns' => [
'sys_language_uid' => [
'exclude' => 0,
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
@@ -56,7 +56,7 @@ return [
'foreign_table_where' => 'ORDER BY sys_language.title',
'items' => [
['LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.allLanguages', -1],
['LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.default_value', 0],
['LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.default_value', 0]
],
],
],
@@ -85,7 +85,7 @@ return [
'type' => 'input',
'size' => 30,
'max' => 255,
],
]
],
'hidden' => [
@@ -161,7 +161,7 @@ return [
'type' => 'input',
'size' => 30,
'renderType' => 'inputLink',
],
]
],
'name' => [
'exclude' => 0,
@@ -170,7 +170,7 @@ return [
'type' => 'text',
'cols' => 30,
'rows' => 2,
'eval' => 'trim,required',
'eval' => 'trim,required'
],
],
'short_name' => [
@@ -179,7 +179,7 @@ return [
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'eval' => 'trim'
],
],
'keywords' => [
@@ -198,7 +198,7 @@ return [
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'eval' => 'trim'
],
],
'teaser' => [
@@ -229,7 +229,7 @@ return [
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'eval' => 'trim'
],
],
'header_subtitle' => [
@@ -238,7 +238,7 @@ return [
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'eval' => 'trim'
],
],
'features' => [
@@ -281,7 +281,7 @@ return [
'teaser_images',
[
'appearance' => [
'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference',
'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference'
],
'overrideChildTca' => [
'types' => [
@@ -309,7 +309,7 @@ return [
],
],
],
'maxitems' => 10,
'maxitems' => 10
],
$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
),
@@ -321,7 +321,7 @@ return [
'header_images',
[
'appearance' => [
'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference',
'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference'
],
'overrideChildTca' => [
'types' => [
@@ -349,7 +349,7 @@ return [
],
],
],
'maxitems' => 10,
'maxitems' => 10
],
$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
),
@@ -361,7 +361,7 @@ return [
'images',
[
'appearance' => [
'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference',
'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference'
],
'overrideChildTca' => [
'types' => [
@@ -398,7 +398,7 @@ return [
],
],
],
'maxitems' => 10,
'maxitems' => 10
],
$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
),
@@ -410,7 +410,7 @@ return [
'reseller_images',
[
'appearance' => [
'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference',
'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference'
],
'overrideChildTca' => [
'types' => [
@@ -421,7 +421,7 @@ return [
],
],
],
'maxitems' => 10,
'maxitems' => 10
],
$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
),
@@ -432,7 +432,7 @@ return [
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
'eval' => 'trim'
],
],
'external_link' => [
@@ -461,7 +461,7 @@ return [
],
'size' => 1,
'minItems' => 1,
'maxItems' => 1,
'maxItems' => 1
],
],
'category' => [
@@ -480,8 +480,8 @@ return [
],
'size' => 1,
'minItems' => 1,
'maxItems' => 1,
],
'maxItems' => 1
]
],
'country' => [
'exclude' => 0,
@@ -596,8 +596,8 @@ return [
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
],
'eval' => 'trim'
]
],
'longitude' => [
'exclude' => 0,
@@ -605,8 +605,8 @@ return [
'config' => [
'type' => 'input',
'size' => 30,
'eval' => 'trim',
],
'eval' => 'trim'
]
],
'address' => [
'exclude' => 0,
@@ -321,7 +321,6 @@ CREATE TABLE tx_epproducts_domain_model_groupspriceconfig
hidden tinyint(4) unsigned DEFAULT '0' NOT NULL,
starttime int(11) unsigned DEFAULT '0' NOT NULL,
endtime int(11) unsigned DEFAULT '0' NOT NULL,
sorting int(11) DEFAULT '0' NOT NULL,
t3ver_oid int(11) DEFAULT '0' NOT NULL,
t3ver_id int(11) DEFAULT '0' NOT NULL,
@@ -3,12 +3,11 @@ lib.breadcrumb {
special = rootline
special.range = 0|-1
1 = TMENU
1.wrap = <div class="hidden md:flex container mb-8 text-sm text-zinc-400">|</div>
1.wrap = <div class="hidden md:flex container mb-8 text-sm">|</div>
1.NO {
stdWrap.htmlSpecialChars = 1
ATagParams = class="text-zinc-400"
ATagTitle.field = nav_title // title
linkWrap = |<span class="text-zinc-400 px-1">/</span>|*||*| |
linkWrap = |<span class="px-1">/</span>|*||*| |
doNotLinkIt = |*| 0 |*| 1
}
}
@@ -17,6 +17,8 @@ TYPO3:
1623227657: 'EXT:ep_theme/Resources/Private/Partials/Form/'
layoutRootPaths:
1505042810: 'EXT:ep_theme/Resources/Private/Layouts/Form/'
honeypot:
enable: false
finishersDefinition:
BpnApiFinisher:
@@ -32,6 +32,8 @@ TYPO3:
1623227657: 'EXT:ep_theme/Resources/Private/Partials/Form/'
layoutRootPaths:
1505042810: 'EXT:ep_theme/Resources/Private/Layouts/Form/'
honeypot:
enable: false
contactform:
__inheritances:
10: 'TYPO3.CMS.Form.prototypes.standard'
@@ -0,0 +1,32 @@
import { Controller } from '@hotwired/stimulus'
import { useClickOutside } from 'stimulus-use'
export default class extends Controller {
static classes = ['hidden']
static targets = ['button', 'subnav']
static values = { expanded: Boolean }
connect() {
useClickOutside(this)
}
toggle(e) {
e.preventDefault()
this.expandedValue = !this.expandedValue
}
clickOutside(e) {
this.expandedValue = false
}
expandedValueChanged(expanded) {
this.buttonTarget.setAttribute('aria-expanded', expanded)
this.subnavTarget.setAttribute('aria-hidden', !expanded)
if (true === expanded) {
this.subnavTarget.classList.remove(...this.hiddenClasses)
} else {
this.subnavTarget.classList.add(...this.hiddenClasses)
}
}
}
@@ -1,9 +1,10 @@
import { Controller } from '@hotwired/stimulus'
import { useDebounce} from 'stimulus-use'
import { useDebounce } from 'stimulus-use'
export default class extends Controller {
static debounces = [ 'toggle' ]
static classes = [ 'hidden', 'visible' ]
initialize() {
useDebounce(this)
@@ -13,10 +14,13 @@ export default class extends Controller {
window.addEventListener('scroll', () => {
this.toggle()
}, { passive: true })
this.toggle()
}
toggle() {
this.element.classList.toggle('hidden', window.scrollY < window.innerHeight / 3)
let isVisible = window.scrollY >= window.innerHeight / 3
this.element.classList.toggle(this.hiddenClass, false === isVisible)
this.element.classList.toggle(this.visibleClass, isVisible)
}
scroll() {
@@ -10,5 +10,4 @@
@import "components/misc";
@import "components/searchbar";
@import "components/teaser";
@import "components/tiles";
}
@@ -22,7 +22,7 @@ p {
}
a:not(.button):not(.rte-button):not(.rte-button--full) {
@apply text-ep-primary-light sbw:text-sbw-primary-dark;
@apply underline text-ep-primary-dark sbw:text-sbw-primary-dark;
.bg-brand-gradient & {
@apply text-white underline;
@@ -32,7 +32,7 @@ a:not(.button):not(.rte-button):not(.rte-button--full) {
a.rte-button {
@apply inline-flex items-center justify-center px-4 py-2 md:px-8;
@apply uppercase leading-none text-center;
@apply transition-colors outline-none focus:outline-none;
@apply transition-colors outline-none;
@apply bg-ep-primary-light text-white;
@apply sbw:bg-sbw-secondary;
@apply snz:bg-snz-secondary;
@@ -45,6 +45,10 @@ a.rte-button {
@apply suz:hover:bg-suz-primary-dark suz:group-hover:bg-suz-primary-dark;
@apply uch:hover:bg-uch-primary-dark uch:group-hover:bg-uch-primary-dark;
@apply ser:hover:bg-ser-primary ser:group-hover:bg-ser-primary;
@apply focus:outline focus:outline-2 focus:outline-offset-2;
@apply focus:outline-ep-primary-dark sbw:focus:outline-sbw-secondary uch:focus:outline-uch-secondary;
@apply suz:focus:outline-suz-secondary ser:focus:outline-ser-secondary snz:focus:outline-snz-secondary;
}
a.rte-button--full {
@@ -1,7 +1,10 @@
.button {
@apply inline-flex items-center justify-center space-x-2 px-4 py-2 md:px-8 cursor-pointer;
@apply uppercase leading-none text-center;
@apply transition-colors outline-none focus:outline-none;
@apply transition-colors outline-none;
@apply focus:outline focus:outline-2 focus:outline-offset-2;
@apply focus:outline-ep-primary-dark sbw:focus:outline-sbw-secondary uch:focus:outline-uch-secondary;
@apply suz:focus:outline-suz-secondary ser:focus:outline-ser-secondary snz:focus:outline-snz-secondary;
&--small {
@apply px-2 py-1 md:px-4 text-xs sm:text-sm;
@@ -12,32 +15,60 @@
}
}
.bg-button {
@apply bg-ep-primary-light text-white;
.teaser-button {
@apply w-full;
@apply bg-ep-primary-dark text-white;
@apply sbw:bg-sbw-secondary;
@apply snz:bg-snz-secondary;
@apply suz:bg-suz-secondary;
@apply uch:bg-uch-secondary;
@apply ser:bg-ser-secondary;
@apply hover:bg-ep-secondary;
@apply sbw:hover:bg-sbw-primary-dark;
@apply snz:hover:bg-snz-primary-dark;
@apply suz:hover:bg-suz-primary-dark;
@apply uch:hover:bg-uch-primary-dark;
@apply ser:hover:bg-ser-primary;
@apply hover:bg-badge-gradient hover:text-white;
@apply peer-hover:bg-badge-gradient peer-hover:text-white;
@apply sbw:hover:bg-none sbw:hover:bg-sbw-primary-dark;
@apply snz:hover:bg-none snz:hover:bg-snz-primary-dark;
@apply suz:hover:bg-none suz:hover:bg-suz-primary-dark;
@apply uch:hover:bg-none uch:hover:bg-uch-primary-dark;
@apply ser:hover:bg-none ser:hover:bg-ser-primary;
@apply sbw:peer-hover:bg-none sbw:peer-hover:bg-sbw-primary-dark;
@apply snz:peer-hover:bg-none snz:peer-hover:bg-snz-primary-dark;
@apply suz:peer-hover:bg-none suz:peer-hover:bg-suz-primary-dark;
@apply uch:peer-hover:bg-none uch:peer-hover:bg-uch-primary-dark;
@apply ser:peer-hover:bg-none ser:peer-hover:bg-ser-primary;
}
.bg-button {
@apply bg-ep-primary-dark text-white;
@apply sbw:bg-sbw-secondary;
@apply snz:bg-snz-secondary;
@apply suz:bg-suz-secondary;
@apply uch:bg-uch-secondary;
@apply ser:bg-ser-secondary;
@apply hover:bg-badge-gradient hover:text-white;
@apply sbw:hover:bg-none sbw:hover:bg-sbw-primary-dark;
@apply snz:hover:bg-none snz:hover:bg-snz-primary-dark;
@apply suz:hover:bg-none suz:hover:bg-suz-primary-dark;
@apply uch:hover:bg-none uch:hover:bg-uch-primary-dark;
@apply ser:hover:bg-none ser:hover:bg-ser-primary;
&--active,
&--secondary {
@apply bg-ep-secondary;
@apply sbw:bg-sbw-primary;
@apply snz:bg-snz-primary;
@apply suz:bg-suz-primary;
@apply uch:bg-uch-primary;
@apply ser:bg-ser-secondary;
@apply bg-badge-gradient text-white;
@apply sbw:bg-none sbw:bg-sbw-secondary;
@apply snz:bg-none snz:bg-snz-secondary;
@apply suz:bg-none suz:bg-suz-secondary;
@apply uch:bg-none uch:bg-uch-secondary;
@apply ser:bg-none ser:bg-ser-secondary;
@apply hover:bg-none hover:bg-ep-pink hover:text-white;
@apply sbw:hover:bg-none sbw:hover:bg-sbw-primary-dark;
@apply snz:hover:bg-none snz:hover:bg-snz-primary-dark;
@apply suz:hover:bg-none suz:hover:bg-suz-primary-dark;
@apply uch:hover:bg-none uch:hover:bg-uch-primary-dark;
@apply ser:hover:bg-none ser:hover:bg-ser-primary;
}
&--muted {
@apply bg-zinc-300 hover:bg-zinc-300;
@apply bg-zinc-300 text-gray-900 hover:bg-zinc-300;
}
&--dark {
@@ -49,7 +80,7 @@
&--light {
@apply bg-white border-2;
@apply font-bold;
@apply border-ep-primary-light text-ep-primary;
@apply border-ep-primary-dark text-ep-primary-dark;
@apply sbw:bg-white sbw:border-sbw-primary sbw:text-sbw-primary;
@apply snz:bg-white snz:border-snz-primary snz:text-snz-primary;
@apply suz:bg-white suz:border-suz-primary suz:text-suz-primary;
@@ -58,8 +89,7 @@
&:hover,
&.button--active {
@apply bg-white;
@apply border-ep-secondary text-ep-secondary;
@apply bg-none bg-ep-pink border-ep-pink;
@apply sbw:bg-white sbw:border-sbw-secondary sbw:text-sbw-secondary;
@apply snz:bg-white snz:border-snz-secondary snz:text-snz-secondary;
@apply suz:bg-white suz:border-suz-secondary suz:text-suz-secondary;
@@ -9,7 +9,7 @@
.contact-bar__item {
@apply flex-1 text-white py-2 bg-ep-primary-dark border-r border-white last:border-0;
@apply ser:bg-ser-primary sbw:bg-sbw-primary snz:bg-snz-primary suz:bg-suz-primary uch:bg-uch-primary;
@apply ser:bg-ser-primary sbw:bg-sbw-secondary snz:bg-snz-primary suz:bg-suz-primary uch:bg-uch-primary;
@screen md {
@apply flex flex-none items-start transition-transform duration-300 ease-in-out p-1 shadow-md focus:text-white border-0;
@@ -1,5 +1,6 @@
.form-field {
@apply border-zinc-400 focus:border-zinc-800 ring-0 focus:ring-0 mt-1 block w-full;
@apply border-zinc-400 focus:border-zinc-800 ring-0 block w-full mt-1;
@apply focus:ring-0 focus:outline focus:outline-2 focus:outline-offset-2 focus:outline-zinc-800;
&--has-error {
@apply border-red-500;
@@ -9,6 +10,7 @@
.form-checkbox,
.form-radio {
@apply border-zinc-400 focus:border-zinc-800 ring-0 focus:ring-0 text-ep-secondary sbw:text-sbw-secondary uch:text-uch-secondary h-4 w-4;
@apply focus:outline focus:outline-2 focus:outline-offset-2 focus:outline-zinc-800;
&--has-error {
@apply border-red-500;
@@ -1,47 +0,0 @@
.tiles {
@apply container lg:max-w-screen-2xl;
}
.tiles__grid {
@apply grid grid-cols-1 lg:grid-cols-12 lg:grid-rows-3 lg:grid-flow-col gap-4 lg:gap-1;
@apply lg:h-128;
@apply bg-white;
}
.tiles__tile {
@apply bg-cover bg-center h-32 lg:h-auto;
}
.tiles__link {
@apply relative w-full h-full flex items-center justify-center;
@apply leading-none text-white hover:text-white text-2xl font-bold uppercase text-shadow break-normal;
&:before {
@apply block absolute top-0 left-0 inset-0 w-full h-full z-20;
@apply border-0 border-white;
@apply transition-all;
content: "";
}
&:hover:before {
@apply mt-4 ml-4;
@apply border-2;
width: calc(100% - theme('spacing.8'));
height: calc(100% - theme('spacing.8'));
}
&:after {
@apply block absolute top-0 left-0 inset-0 w-full h-full z-10;
@apply transition-all;
content:"";
}
&:hover:after {
@apply sbw:bg-sbw-overlay/55 uch:bg-uch-overlay/55;
}
}
.tiles__label {
@apply block relative z-20;
@apply text-center;
}
@@ -13,7 +13,7 @@ table {
a.rte-button {
@apply inline-flex items-center justify-center px-4 py-2 md:px-8 cursor-pointer;
@apply uppercase leading-none text-center no-underline;
@apply bg-ep-primary-light text-white;
@apply bg-ep-primary-dark text-white;
}
a.rte-button--full {
@@ -7,7 +7,7 @@
<f:render partial="Topnav" arguments="{_all}"/>
<f:render partial="Mainnav" section="Main" arguments="{_all}"/>
</f:alias>
<main>
<main id="main-content">
<f:render section="Content"/>
<f:render section="Teasers"/>
</main>
@@ -7,7 +7,7 @@
<header>
<f:render partial="HeaderSlider" arguments="{_all}"/>
</header>
<main>
<main id="main-content">
<f:if condition="{data.tx_eptheme_hide_searchbar} || {settings.hideSearchbar}">
<f:else>
<f:cObject typoscriptObjectPath="lib.searchBar"/>
@@ -7,7 +7,7 @@
<f:render partial="EventHero" arguments="{_all}"/>
<f:render partial="EventDisturber" arguments="{headline: settings.eventDisturberHeadline, listItems: settings.eventDisturberListitems, buttonLabel: settings.eventDisturberButtonLabel, buttonLink: settings.eventDisturberButtonLink}"/>
</header>
<main>
<main id="main-content">
<f:render section="Content"/>
</main>
<footer>
@@ -2,11 +2,17 @@
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<f:render partial="Mainnav" section="Main" arguments="{_all}"/>
<f:render section="Content"/>
<f:render partial="Footer" arguments="{_all}"/>
<f:render partial="ContactBar" arguments="{_all}"/>
<f:render partial="Topnav" arguments="{_all}"/>
<f:render partial="Mobilenav" section="Main" arguments="{_all}"/>
<f:render partial="Mainnav" section="Main" arguments="{_all}"/>
<main id="main-content">
<f:render section="Content"/>
</main>
<footer>
<f:render partial="Footer" arguments="{_all}"/>
</footer>
<aside>
<f:render partial="ContactBar" arguments="{_all}"/>
<f:render partial="Mobilenav" section="Main" arguments="{_all}"/>
</aside>
<f:render partial="Config" arguments="{_all}" />
</html>
@@ -11,7 +11,7 @@
</f:else>
</f:if>
</header>
<main>
<main id="main-content">
<f:cObject typoscriptObjectPath="lib.breadcrumb"/>
<f:render section="Content"/>
<f:render section="Teasers"/>
@@ -11,7 +11,7 @@
</f:else>
</f:if>
</header>
<main>
<main id="main-content">
<f:cObject typoscriptObjectPath="lib.breadcrumb"/>
<f:render section="Header" optional="true"/>
<div class="container grid grid-cols-3 gap-8">
@@ -6,7 +6,7 @@
<header>
<f:render partial="HeaderSliderSmall" arguments="{_all}"/>
</header>
<main>
<main id="main-content">
<f:cObject typoscriptObjectPath="lib.breadcrumb"/>
<f:render section="Header" optional="true"/>
<div class="container grid grid-cols-3 gap-8">
@@ -11,7 +11,7 @@
</f:else>
</f:if>
</header>
<main>
<main id="main-content">
<f:cObject typoscriptObjectPath="lib.breadcrumb"/>
<f:render section="Header" optional="true"/>
<div class="container grid grid-cols-3 gap-8">
@@ -7,7 +7,7 @@
<f:render partial="HeaderSliderSmall" arguments="{_all}"/>
<f:cObject typoscriptObjectPath="lib.breadcrumb"/>
</header>
<main>
<main id="main-content">
<f:render section="Header" optional="true"/>
<div class="container grid grid-cols-3 gap-8">
<div class="col-span-3 lg:col-span-2">
@@ -18,7 +18,7 @@
<div class="text-lg lg:text-xl font-medium leading-none">My E&P</div>
</f:link.typolink>
</header>
<main>
<main id="main-content">
<f:render section="Content"/>
</main>
<footer>
@@ -10,15 +10,15 @@
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMinYMin meet"
class="w-full h-full">
<circle fill="currentColor" class="text-ep-primary/50" cx="100" cy="100" r="100"/>
<circle fill="currentColor" class="text-ep-primary" cx="100" cy="100" r="70"/>
<circle fill="currentColor" class="text-ep-primary-dark/50" cx="100" cy="100" r="100"/>
<circle fill="currentColor" class="text-ep-primary-dark" cx="100" cy="100" r="70"/>
</svg>
<div class="absolute top-0 left-0 inset-0 flex flex-col items-center justify-center p-8">
<span class="block text-center text-white uppercase font-bold leading-none text-xl">
<span class="block text-center text-white bg-ep-primary-dark uppercase font-bold leading-none text-xl">
{badge.title -> f:format.raw()}
</span>
<f:if condition="{badge.subtitle}">
<span class="block text-center text-white uppercase font-bold leading-none">
<span class="block text-center text-white bg-ep-primary-dark uppercase font-bold leading-none">
{badge.subtitle -> f:format.raw()}
</span>
</f:if>
@@ -4,7 +4,7 @@
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<f:section name="Teaser">
<a href="{f:uri.typolink(parameter: city.detailPage)}" class="flex flex-col">
<div class="relative flex flex-col">
<div class="relative">
{ep:icon(icon: 'flag-{city.country.code -> f:format.case(mode: \'lower\')}', class: 'w-8 h-6 absolute top-0 left-0')}
<f:alias map="{teaserImage: city.teaserImage, defaultImage: city.images.0}">
@@ -34,17 +34,19 @@
</f:if>
</f:alias>
</div>
<div class="flex-1 py-4 px-2 bg-white border-l border-r border-zinc-200">
<span class="headline--3 mb-4">
<div class="flex-1 flex flex-col pt-4 bg-white border border-t-0 border-zinc-200">
<a href="{f:uri.typolink(parameter: city.detailPage)}" class="px-2 peer headline--3 mb-4 no-underline">
{city.name}
</span>
{city.teaser -> f:format.crop(maxCharacters: settings.teaserTextMaxChars) -> f:format.html()}
<span class="absolute inset-0"></span>
</a>
<div class="flex-1 px-2 text-zinc-800" data-rte-content>
{city.teaser -> f:format.crop(maxCharacters: settings.teaserTextMaxChars) -> f:format.html()}
</div>
<div class="button teaser-button">
{f:translate(key: 'tx_eptheme.label.teaserbutton.default', extensionName: 'ep_theme')}
</div>
</div>
<button type="button"
class="button bg-button w-full">
{f:translate(key: 'tx_eptheme.label.teaserbutton.default', extensionName: 'ep_theme')}
</button>
</a>
</div>
</f:section>
</html>
@@ -5,6 +5,7 @@
<div class="contact-bar">
<a href="{f:uri.typolink(parameter: settings.watchlistPageUid)}"
tabindex="0"
class="contact-bar__item"
data-controller="watchlist-label"
data-action="watchlist-toggle:toggle@window->watchlist-label#update"
@@ -15,6 +16,7 @@
</div>
</a>
<a href="tel:{settings.phoneNumberLink}"
tabindex="0"
class="contact-bar__item"
rel="nofollow">
{ep:icon(icon: 'phone', class: 'contact-bar__icon')}
@@ -23,7 +25,8 @@
</div>
</a>
<f:link.email email="{settings.contactFormToEmail}"
class="contact-bar__item">
class="contact-bar__item"
additionalAttributes="{tabindex: 0}">
{ep:icon(icon: 'email', class: 'contact-bar__icon')}
<div class="contact-bar__label">
{settings.contactFormToEmail}
@@ -31,6 +34,7 @@
</f:link.email>
<f:if condition="{settings.whatsApp}">
<a href="{settings.whatsAppNumberLink}"
tabindex="0"
class="contact-bar__item"
target="_blank"
rel="nofollow">
@@ -41,6 +45,7 @@
</a>
</f:if>
<a href="{settings.facebookUrl}"
tabindex="0"
class="contact-bar__item"
target="_blank"
rel="nofollow">
@@ -50,6 +55,7 @@
</div>
</a>
<a href="{settings.instagramUrl}"
tabindex="0"
class="contact-bar__item"
target="_blank"
rel="nofollow">
@@ -59,6 +65,7 @@
</div>
</a>
<a href="{settings.youtubeUrl}"
tabindex="0"
class="contact-bar__item"
target="_blank"
rel="nofollow">
@@ -69,6 +76,7 @@
</a>
<f:if condition="{settings.tiktokUrl}">
<a href="{settings.tiktokUrl}"
tabindex="0"
class="contact-bar__item"
target="_blank"
rel="nofollow">
@@ -79,7 +87,9 @@
</a>
</f:if>
<f:if condition="{settings.englishPageUid}">
<f:link.typolink parameter="{settings.englishPageUid}" class="contact-bar__item">
<f:link.typolink parameter="{settings.englishPageUid}"
class="contact-bar__item"
additionalAttributes="{tabindex: 0}">
{ep:icon(icon: 'flag-gb', class: 'contact-bar__icon')}
<div class="contact-bar__label">
English
@@ -87,7 +97,9 @@
</f:link.typolink>
</f:if>
<f:if condition="{settings.germanPageUid}">
<f:link.typolink parameter="{settings.germanPageUid}" class="contact-bar__item">
<f:link.typolink parameter="{settings.germanPageUid}"
class="contact-bar__item"
additionalAttributes="{tabindex: 0}">
{ep:icon(icon: 'flag-de', class: 'contact-bar__icon')}
<div class="contact-bar__label">
Deutsch
@@ -9,7 +9,7 @@
section="Top1"
arguments="{classes: 'hidden md:block -translate-y-2 {f:if(condition: \'{data.tx_eptheme_background} == 1 || {data.tx_eptheme_background} == 3\', then: \'text-ep-primary-bg\', else: \'text-white\')}'}"/>
</f:if>
<div class="relative container grid grid-cols-2 gap-8 py-4" data-rte-content>
<div class="relative container grid grid-cols-2 gap-8 py-4">
<div class="col-span-2 md:col-span-1">
<div class="relative max-w-md mx-auto mb-8">
<f:if condition="{image}">
@@ -36,12 +36,8 @@
</div>
</div>
<div class="col-span-2 md:col-span-1">
<span class="headline--secondary font-light text-white">
{data.subheadline}
</span>
<span class="headline--secondary uppercase font-light text-white mb-4">
{data.headline}
</span>
<span class="headline--secondary font-light text-white">{data.subheadline}</span>
<span class="headline--secondary uppercase font-light text-white mb-4">{data.headline}</span>
<div class="text-white" data-rte-content>
{data.bodytext -> f:format.html()}
</div>
@@ -49,7 +45,7 @@
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 lg:gap-8">
<f:for each="{data.flexForm.buttons}" as="button">
<f:link.typolink parameter="{button.container.link}"
class="button bg-button shadow-lg">
class="button bg-button--secondary shadow-lg">
{button.container.label}
</f:link.typolink>
</f:for>
@@ -8,8 +8,12 @@
section="Top1"
arguments="{classes: 'hidden md:block -translate-y-2 {f:if(condition: \'{data.tx_eptheme_background} == 1 || {data.tx_eptheme_background} == 3\', then: \'text-ep-primary-bg\', else: \'text-white\')}'}"/>
<div class="max-w-screen-lg mx-auto" data-rte-content>
<div>{data.headline}</div>
<div>{data.text -> f:format.html()}</div>
<div>
{data.headline}
</div>
<div>
{data.text -> f:format.html()}
</div>
<div>
{data.flexForm.buttons -> v:iterator.first() -> v:variable.set(name: 'button')}
<a href="{f:uri.typolink(parameter: button.container.link)}" class="btn btn-info">
@@ -4,8 +4,10 @@
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<f:alias map="{button: data.flexForm.buttons.0}">
<div class="container-fluid ep-disturber-reminder" data-rte-content>
<div>{data.headline}</div>
<div class="container-fluid ep-disturber-reminder">
<div data-rte-content>
{data.headline}
</div>
<div class="col-md-6">
<a href="{f:uri.typolink(parameter: button.container.link)}" title="{button.container.label -> f:format.raw()}">
<f:if condition="{image}">
@@ -17,8 +19,8 @@
</f:if>
</a>
</div>
<div class="col-md-6 ">
<div>{data.text -> f:format.html()}</div>
<div class="col-md-6" data-rte-content>
{data.text -> f:format.html()}
</div>
<a href="{f:uri.typolink(parameter: button.container.link)}" class="btn btn-info">
{button.container.label -> f:format.raw()}
@@ -7,7 +7,7 @@
<f:render partial="Disrupter/Outlines"
section="Top1"
arguments="{classes: 'hidden md:block -translate-y-2 {f:if(condition: \'{background} == 1 || {background} == 3\', then: \'text-ep-primary-bg\', else: \'text-white\')}'}"/>
<div class="max-w-screen-lg mx-auto py-4" data-rte-content>
<div class="max-w-screen-lg mx-auto py-4">
<div class="md:flex md:items-start py-4">
<div class="px-16 pb-4 md:px-4 md:pb-0 md:w-1/6">
<f:if condition="{image}">
@@ -20,14 +20,12 @@
</f:if>
</div>
<div class="px-16 md:px-4 md:w-5/6 md:pl-8 text-center text-white md:text-left" data-rte-content>
<span class="headline--3 text-white uppercase">
{data.headline}
</span>
<span class="headline--3 text-white uppercase">{data.headline}</span>
{data.text -> f:format.html()}
<div class="flex flex-col space-y-4 md:flex-row md:items-center md:space-y-0 md:space-x-4">
<f:for each="{data.flexForm.buttons}" as="button" iteration="iteration">
<f:if condition="{iteration.cycle} <= 3">
<f:link.typolink parameter="{button.container.link}" class="button bg-button shadow-lg">
<f:link.typolink parameter="{button.container.link}" class="button bg-button--secondary shadow-lg">
{button.container.label}
</f:link.typolink>
</f:if>
@@ -10,7 +10,7 @@
section="Top1"
arguments="{classes: 'hidden md:block -translate-y-2 {f:if(condition: \'{background} == 1 || {background} == 3\', then: \'text-ep-primary-bg\', else: \'text-white\')}'}"/>
</f:if>
<div class="relative container grid grid-cols-2 gap-8 py-8" data-rte-content>
<div class="relative container grid grid-cols-2 gap-8 py-8">
<div class="col-span-2 md:col-span-1">
<div class="relative max-w-md mx-auto mb-8">
<f:if condition="{teaserImage}">
@@ -36,13 +36,9 @@
</a>
</div>
</div>
<div class="col-span-2 md:col-span-1">
<span class="headline--secondary font-light text-white">
{data.subheader}
</span>
<span class="headline--secondary uppercase font-light text-white mb-4">
{data.header}
</span>
<div class="col-span-2 md:col-span-1" data-rte-content>
<span class="headline--secondary font-light text-white">{data.subheader}</span>
<span class="headline--secondary uppercase font-light text-white mb-4">{data.header}</span>
<div class="text-white" data-rte-content>
{data.bodytext -> f:format.html()}
</div>
@@ -50,7 +46,7 @@
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4 lg:gap-8">
<f:for each="{data.flexForm.buttons}" as="button">
<f:link.typolink parameter="{button.container.link}"
class="button bg-button shadow-lg">
class="button bg-button--secondary shadow-lg">
{button.container.label}
</f:link.typolink>
</f:for>
@@ -3,12 +3,18 @@
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<div class="container-fluid ep-disturber-last-chance" data-rte-content>
<div>{data.header}</div>
<div>{data.bodytext -> f:format.html()}</div>
<div class="container-fluid ep-disturber-last-chance">
<div data-rte-content>
{data.header}
</div>
<div data-rte-content>
{data.bodytext -> f:format.html()}
</div>
<div>
{data.flexForm.buttons -> v:iterator.first() -> v:variable.set(name: 'button')}
<a href="{f:uri.typolink(parameter: button.container.link)}" class="btn btn-info">{button.container.label -> f:format.raw()}</a>
<a href="{f:uri.typolink(parameter: button.container.link)}" class="button bg-button--secondary">
{button.container.label -> f:format.raw()}
</a>
</div>
</div>
@@ -4,8 +4,10 @@
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<f:alias map="{button: data.flexForm.buttons.0}">
<div class="container-fluid ep-disturber-reminder" data-rte-content>
<div>{data.header}</div>
<div class="container-fluid ep-disturber-reminder">
<div data-rte-content>
{data.header}
</div>
<div class="col-md-6">
<a href="{f:uri.typolink(parameter: button.container.link)}" title="{button.container.label -> f:format.raw()}">
<f:if condition="{teaserImage}">
@@ -17,8 +19,10 @@
</f:if>
</a>
</div>
<div class="col-md-6 ">
<div>{data.bodytext -> f:format.html()}</div>
<div class="col-md-6" data-rte-content>
<div>
{data.bodytext -> f:format.html()}
</div>
</div>
<a href="{f:uri.typolink(parameter: button.container.link)}" class="btn btn-info">
{button.container.label -> f:format.raw()}
@@ -7,7 +7,7 @@
<f:render partial="Disrupter/Outlines"
section="Top1"
arguments="{classes: 'hidden md:block -translate-y-2 {f:if(condition: \'{data.tx_eptheme_background} == 1 || {data.tx_eptheme_background} == 3\', then: \'text-ep-primary-bg\', else: \'text-white\')}'}"/>
<div class="max-w-screen-lg mx-auto" data-rte-content>
<div class="max-w-screen-lg mx-auto">
<div class="md:flex md:items-start py-4">
<div class="px-16 pb-4 md:px-4 md:pb-0 md:w-1/6">
<f:if condition="{teaserImage}">
@@ -20,14 +20,12 @@
</f:if>
</div>
<div class="px-16 md:px-4 md:w-5/6 md:pl-8 text-center text-white md:text-left" data-rte-content>
<span class="headline--3 text-white uppercase">
{data.header}
</span>
<span class="headline--3 text-white uppercase">{data.header}</span>
{data.bodytext -> f:format.html()}
<div class="flex flex-col space-y-4 md:flex-row md:items-center md:space-y-0 md:space-x-4">
<f:for each="{data.flexForm.buttons}" as="button" iteration="iteration">
<f:if condition="{iteration.cycle} <= 3">
<f:link.typolink parameter="{button.container.link}" class="button bg-button shadow-lg">
<f:link.typolink parameter="{button.container.link}" class="button bg-button--secondary shadow-lg">
{button.container.label}
</f:link.typolink>
</f:if>
@@ -177,7 +177,9 @@
aria-label="zum Seitenanfang scrollen"
data-controller="scroll-top"
data-action="scroll-top#scroll"
class="hidden fixed bottom-0 right-0 mb-16 md:mb-8 mr-4 md:mr-8 z-10 h-10 w-10 flex items-center justify-center rounded bg-ep-secondary/80 ser:bg-ser-secondary">
data-scroll-top-hidden-class="hidden"
data-scroll-top-visible-class="flex"
class="hidden fixed bottom-0 right-0 mb-16 md:mb-8 mr-4 md:mr-8 z-10 h-10 w-10 items-center justify-center rounded bg-ep-pink/80 sbw:bg-sbw-secondary/80 snz:bg-snz-secondary/80 uch:bg-uch-secondary/80 ser:bg-ser-secondary/80">
{ep:icon(icon: 'chevron-up', class: 'w-8 h-8 text-white')}
</button>
@@ -14,7 +14,12 @@
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"/>
<img src="{f:uri.page(pageType:3413)}" alt="Captcha image" loading="lazy" onload="this.parentElement.classList.remove('captcha--reloading'); return false;"/>
<f:if condition="{element.properties.showRefresh}">
<button type="button" class="captcha__reload" data-url="{f:uri.page(pageType:3413)}" onclick="const div = this.parentElement; div.classList.add('captcha--reloading', 'captcha--spin'); let captchaUrl = this.dataset.url; this.previousElementSibling.setAttribute('src', captchaUrl + (/\?/.test(captchaUrl) ? '&' : '?') + 'now=' + Date.now()); setTimeout(function(){div.classList.remove('captcha--spin')},400); return false;">
<button type="button"
class="captcha__reload"
aria-label="Captcha neu laden"
data-url="{f:uri.page(pageType:3413)}"
onclick="const div = this.parentElement; div.classList.add('captcha--reloading', 'captcha--spin'); let captchaUrl = this.dataset.url; this.previousElementSibling.setAttribute('src', captchaUrl + (/\?/.test(captchaUrl) ? '&' : '?') + 'now=' + Date.now()); setTimeout(function(){div.classList.remove('captcha--spin')},400); return false;">
<span class="sr-only">Captcha neu laden</span>
<svg width="31" height="28" xmlns="http://www.w3.org/2000/svg">
<g fill="#000" fill-rule="evenodd">
<path d="M10 10.7 6.3 8.5a11 11 0 0 1 20 3l2.5-.8h.4v-.3A14 14 0 0 0 3.6 7L.3 5l1.8 8.3 8-2.6ZM31 23l-1.7-8-8 2.5 3.7 2.1a10.9 10.9 0 0 1-19.8-2.3l-2 .6-1 .3a13.9 13.9 0 0 0 17 9.3 14 14 0 0 0 8.4-6.4l3.4 2Z"/>
@@ -35,7 +35,7 @@
<f:if condition="{slide.button}">
<f:link.typolink parameter="{slide.page_uid}"
additionalAttributes="{'tabindex': '-1'}"
class="button bg-button inline-block">
class="button bg-badge-gradient hover:bg-none hover:bg-ep-pink text-white inline-block">
{slide.button}
</f:link.typolink>
</f:if>
@@ -62,13 +62,13 @@
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMinYMin meet"
class="w-full h-full">
<circle fill="currentColor" class="text-ep-primary/50" cx="100" cy="100" r="100"/>
<circle fill="currentColor" class="text-ep-primary" cx="100" cy="100" r="70"/>
<circle fill="currentColor" class="text-ep-primary-dark/50" cx="100" cy="100" r="100"/>
<circle fill="currentColor" class="text-ep-primary-dark" cx="100" cy="100" r="70"/>
</svg>
<div class="absolute top-0 left-0 inset-0 flex flex-col items-center justify-center p-8">
<span class="block text-center text-white uppercase font-bold leading-none text-xl">{badgeData.title -> f:format.raw()}</span>
<span class="block text-center text-white bg-ep-primary-dark uppercase font-bold leading-none text-xl">{badgeData.title -> f:format.raw()}</span>
<f:if condition="{badgeData.subtitle}">
<span class="block text-center text-white uppercase font-bold leading-none">{badgeData.subtitle -> f:format.raw()}</span>
<span class="block text-center text-white bg-ep-primary-dark uppercase font-bold leading-none">{badgeData.subtitle -> f:format.raw()}</span>
</f:if>
</div>
</div>
@@ -20,12 +20,12 @@
<div class="absolute bottom-0 left-0 inset-x-0 px-8 md:bottom-1/2 md:translate-y-1/2">
<div class="lg:container">
<div class="p-4 bg-ep-primary-dark/80 sbw:bg-sbw-primary/80 snz:bg-snz-primary/80 suz:bg-suz-primary/80 uch:bg-uch-primary/80 ser:bg-ser-primary/80 mb-4 md:p-8 md:max-w-2xl">
<span class="block text-xl md:text-2xl text-white uppercase">
<div class="text-xl md:text-2xl text-white uppercase">
{slide.headline}
</span>
<span class="block text-2xl md:text-3xl lg:text-4xl text-white uppercase">
</div>
<div class="text-2xl md:text-3xl lg:text-4xl text-white uppercase">
{slide.subline}
</span>
</div>
<f:if condition="{slide.button}">
<f:link.typolink parameter="{slide.page_uid}"
class="button bg-button inline-block">
@@ -53,8 +53,8 @@
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMinYMin meet"
class="w-full h-full">
<circle fill="currentColor" class="text-ep-primary/50" cx="100" cy="100" r="100"/>
<circle fill="currentColor" class="text-ep-primary" cx="100" cy="100" r="70"/>
<circle fill="currentColor" class="text-ep-primary-dark/50" cx="100" cy="100" r="100"/>
<circle fill="currentColor" class="text-ep-primary-dark" cx="100" cy="100" r="70"/>
</svg>
<div class="absolute top-0 left-0 inset-0 flex flex-col items-center justify-center p-8">
<span class="block text-center text-white uppercase font-bold leading-none text-xl">{badgeData.title -> f:format.raw()}</span>
@@ -4,7 +4,7 @@
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<f:section name="Teaser">
<a href="{f:uri.typolink(parameter: hotel.detailPage)}" class="flex flex-col">
<div class="relative flex flex-col">
<div class="relative">
{ep:icon(icon: 'flag-{hotel.country.code -> f:format.case(mode: \'lower\')}', class: 'w-8 h-6 absolute top-0 left-0')}
<f:if condition="{hotel.images.original.0}">
@@ -25,27 +25,29 @@
</f:else>
</f:if>
</div>
<div class="flex-1 py-4 px-2 bg-white border-l border-r border-zinc-200">
<span class="headline--3 mb-4">
<div class="flex-1 flex flex-col pt-4 bg-white border border-t-0 border-zinc-200">
<a href="{f:uri.typolink(parameter: hotel.detailPage)}" class="px-2 peer headline--3 mb-4 no-underline">
{hotel.name -> f:format.nl2br()}
</span>
<span class="absolute inset-0"></span>
</a>
<f:if condition="{hotel.category}">
<span class="searchresult-item__category">
<div class="px-2">
<strong>Kategorie</strong> {hotel.category}
</span>
</f:if>
{hotel.teaser -> f:format.crop(maxCharacters: settings.teaserTextMaxChars) -> f:format.html()}
<f:if condition="{hotel.available} != -1">
<span class="teaserbox__price">
<strong>{f:if(condition: '{hotel.available} > 0', then: 'ab {hotel.minPrice} €', else: 'aktuell nicht buchbar')}</strong>
</span>
</div>
</f:if>
<div class="flex-1 px-2 text-zinc-800" data-rte-content>
{hotel.teaser -> f:format.crop(maxCharacters: settings.teaserTextMaxChars) -> f:format.html()}
<f:if condition="{hotel.available} != -1">
<span class="teaserbox__price">
<strong>{f:if(condition: '{hotel.available} > 0', then: 'ab {hotel.minPrice} €', else: 'aktuell nicht buchbar')}</strong>
</span>
</f:if>
</div>
<div class="button teaser-button">
{f:translate(key: 'tx_eptheme.label.teaserbutton.default', extensionName: 'ep_theme')}
</div>
</div>
<button type="button"
class="button bg-button w-full">
{f:translate(key: 'tx_eptheme.label.teaserbutton.default', extensionName: 'ep_theme')}
</button>
</a>
</div>
</f:section>
</html>
@@ -44,13 +44,19 @@
<f:section name="FirstLevel">
<nav role="navigation" aria-label="Hauptnavigation">
<ul class="m-0 p-0 list-none flex items-center justify-end space-x-4" role="menubar">
<ul class="m-0 p-0 list-none flex items-center justify-end space-x-4"
role="menubar" >
<f:for each="{mainnav}" as="topitem">
<li class="group pb-4" role="none">
<li class="group pb-4" role="none" data-controller="nav" data-nav-hidden-class="invisible opacity-0">
<f:if condition="{topitem.children}">
<f:then>
<a href="{f:uri.typolink(parameter: topitem.data.uid)}"
role="menuitem"
id="mainnav-{topitem.data.uid}"
aria-haspopup="true"
aria-expanded="false"
data-nav-target="button"
data-action="keydown.space->nav#toggle"
class="text-zinc-800 uppercase lg:text-lg font-bold flex items-center">
<span>{topitem.title}</span>
{ep:icon(icon: 'chevron-down', class: 'ml-1 w-4 h-4 group-hover:rotate-180')}
@@ -93,7 +99,10 @@
</f:section>
<f:section name="SecondLevel">
<div class="absolute top-100 left-0 inset-x-0 pt-4 invisible opacity-0 group-hover:visible group-hover:opacity-100 transition-opacity duration-300 ease-in-out">
<div class="absolute top-100 left-0 inset-x-0 pt-4 invisible opacity-0 group-hover:visible group-hover:opacity-100 transition-opacity duration-300 ease-in-out"
aria-hidden="true"
aria-labelledby="mainnav-{topitem.data.uid}"
data-nav-target="subnav">
<div class="bg-white grid grid-cols-3 lg:grid-cols-4 gap-8 p-4 shadow-lg rounded">
<f:for each="{topitem.children}" as="subitem">
<ul class="m-0 p-0 list-none" role="menu">
@@ -6,7 +6,7 @@
<f:if condition="{images}">
<f:if condition="{images -> f:count()} == 1">
<f:then>
<f:link.typolink parameter="{images.0.originalResource.link}">
<f:link.typolink parameter="{images.0.originalResource.link}" title="{images.0.title}">
<img src="{f:uri.image(image: images.0, width: '770', height: '430c+100')}"
class="block w-full h-auto mb-4"
alt="{images.0.alternative}">
@@ -4,8 +4,8 @@
<div class="mb-8">
<n:excludeDisplayedNews newsItem="{newsItem}"/>
<div class="flex flex-col md:flex-row md:space-x-8">
<n:link newsItem="{newsItem}" settings="{settings}" title="{newsItem.title}" class="mb-4 md:w-1/2">
<div class="relative flex flex-col md:flex-row md:space-x-8">
<div class="mb-4 md:w-1/2">
<f:if condition="{newsItem.mediaPreviews}">
<f:then>
<f:if condition="{newsItem.mediaPreviews.0}">
@@ -26,13 +26,14 @@
</f:if>
</f:else>
</f:if>
</n:link>
</div>
<div class="md:flex-1">
<h3 class="blog-entry__headline">
<n:link newsItem="{newsItem}" settings="{settings}">
<a href="{f:uri.typolink(parameter: newsItem.newsLink)}" class="peer">
<h3 class="blog-entry__headline">
{newsItem.title}
</n:link>
</h3>
</h3>
<span class="absolute inset-0"></span>
</a>
<p class="text-sm italic mb-4">
<f:if condition="{newsItem.author}">{newsItem.author} am </f:if>
<time datetime="{f:format.date(date:newsItem.datetime, format:'Y-m-d')}"><f:format.date format="{f:translate(key:'dateFormat')}">{newsItem.datetime}</f:format.date></time>
@@ -57,9 +58,9 @@
</f:if>
</div>
</n:removeMediaTags>
<n:link newsItem="{newsItem}" settings="{settings}" class="button bg-button button--small">
<div class="button bg-button button--small">
<f:translate key="more-link"/>
</n:link>
</div>
</div>
</div>
</div>
@@ -16,10 +16,10 @@
<table class="min-w-full border border-zinc-200 border-collapse mb-8">
<thead>
<tr>
<th class="text-left">
<th class="text-left" scope="col">
Zimmertyp
</th>
<th class="text-left">
<th class="text-left" scope="col">
Preis/Pers.
</th>
<f:if condition="{hasIncludedServices}">
@@ -27,8 +27,8 @@
inkl.
</th>
</f:if>
<th></th>
<th class="hidden lg:table-cell"></th>
<th scope="col" aria-label="Links zu optionalen Zusatzleistungen"></th>
<th class="hidden lg:table-cell" scope="col" aria-label="Links zur Buchung"></th>
</tr>
</thead>
<tbody>
@@ -41,8 +41,8 @@
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMinYMin meet"
class="w-full h-full">
<circle fill="currentColor" class="text-ep-primary/50" cx="100" cy="100" r="100"/>
<circle fill="currentColor" class="text-ep-primary" cx="100" cy="100" r="70"/>
<circle fill="currentColor" class="text-ep-primary-dark/50" cx="100" cy="100" r="100"/>
<circle fill="currentColor" class="text-ep-primary-dark" cx="100" cy="100" r="70"/>
</svg>
<div class="absolute top-0 left-0 inset-0 flex flex-col items-center justify-center p-8">
<span class="block text-center text-white uppercase font-bold leading-none text-xl">
@@ -34,12 +34,12 @@
{ep:icon(icon: 'flag-{product.country.code -> f:format.case(mode: \'lower\')}', class: 'w-8 h-6 md:w-10 md:h-8')}
<f:if condition="{hotel}">
<f:then>
<a href="{ep:gmapsUrl(hotel: hotel)}" target="_blank" class="block bg-ep-primary-light px-2 py-1">
<a href="{ep:gmapsUrl(hotel: hotel)}" target="_blank" class="block bg-ep-primary-light px-2 py-1" title="Öffnen auf Google Maps">
{ep:icon(icon: 'location-marker', class: 'w-4 h-4 md:w-6 md:h-6 text-white')}
</a>
</f:then>
<f:else>
<a href="{ep:gmapsUrl(region: product.region)}" target="_blank" class="block bg-ep-primary-light px-2 py-1">
<a href="{ep:gmapsUrl(region: product.region)}" target="_blank" class="block bg-ep-primary-light px-2 py-1" title="Öffnen auf Google Maps">
{ep:icon(icon: 'location-marker', class: 'w-4 h-4 md:w-6 md:h-6 text-white')}
</a>
</f:else>
@@ -6,7 +6,7 @@
<f:section name="Teaser">
<f:variable name="targetUrl" value="{ep:uri.product(forceHotelUid: forceHotelUid, product: product, hotel: hotel, dateFrom: dateFrom, dateTo: dateTo, ref: referringPageUri)}"/>
<div class="product-teaser flex flex-col h-full bg-white group{f:if(condition: landscape, then: ' sm:flex-row sm:h-auto')}">
<div class="product-teaser relative flex flex-col h-full bg-white{f:if(condition: landscape, then: ' sm:flex-row sm:h-auto')}">
<f:render section="TeaserImage" arguments="{_all}"/>
<f:render section="TeaserContent" arguments="{_all}"/>
</div>
@@ -14,32 +14,24 @@
<f:section name="TeaserImage">
<div class="relative{f:if(condition: landscape, then: ' sm:w-2/5')}">
<a href="{targetUrl}"
<f:if condition="{concept.popupText} && {settings.globalConceptCode} != {concept.code}">
hx-get="{ep:uri.ajax(action: 'concept', controller: 'AjaxTeaserPopup', arguments: '{concept: concept.uid, targetUrl: targetUrl}', format: 'html', pageUid: settings.defaultAjaxUid)}"
hx-target="body"
hx-swap="beforeend"
</f:if>
>
<f:if condition="{productImage}">
<f:then>
<ep:lazyLoadImage image="{productImage}"
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
class="block w-full h-full object-cover"
width="400c"
height="300c"
alt="{product.name}" />
</f:then>
<f:else>
<f:image src="EXT:ep_theme/Resources/Public/images/lazy.png"
class="block w-full h-full object-cover"
width="400c"
height="300c"
alt="{product.name}" />
</f:else>
</f:if>
</a>
<div class="absolute top-0 left-0 z-10 inset-x-0 p-2 flex justify-between items-center {f:if(condition: concept, then: 'bg-concept-{concept.code}/70', else: 'bg-ep-primary/80')}">
<f:if condition="{productImage}">
<f:then>
<ep:lazyLoadImage image="{productImage}"
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
class="block w-full h-full object-cover"
width="400c"
height="300c"
alt="{product.name}" />
</f:then>
<f:else>
<f:image src="EXT:ep_theme/Resources/Public/images/lazy.png"
class="block w-full h-full object-cover"
width="400c"
height="300c"
alt="{product.name}" />
</f:else>
</f:if>
<div class="absolute top-0 left-0 z-20 inset-x-0 p-2 flex justify-between items-center {f:if(condition: concept, then: 'bg-concept-{concept.code}/70', else: 'bg-ep-primary/80')}">
<div class="flex items-center space-x-2">
<f:if condition="{country.code}">
{ep:icon(class: 'product-teaser__flag', icon: 'flag-{country.code -> f:format.case(mode: \'lower\')}')}
@@ -76,37 +68,38 @@
</f:section>
<f:section name="TeaserContent">
{f:variable(name: 'including', value: '{f:render(section: \'Including\', arguments: \'{_all}\') -> v:format.trim()}')}
<a href="{targetUrl}"
<f:if condition="{concept.popupText} && {settings.globalConceptCode} != {concept.code}">
hx-get="{ep:uri.ajax(action: 'concept', controller: 'AjaxTeaserPopup', arguments: '{concept: concept.uid, targetUrl: targetUrl}', format: 'html', pageUid: settings.defaultAjaxUid)}"
hx-target="body"
hx-swap="beforeend"
</f:if>
class="flex-1 flex flex-col space-y-1 px-2 py-4 md:p-4">
<div class="product-teaser__label-name">
{product.name}
</div>
<div class="product-teaser__label-region">
{region.name}
</div>
{f:variable(name: 'including', value: '{f:render(section: \'Including\', arguments: \'{_all}\') -> v:format.trim()}')}
<div class="flex-1 flex flex-col space-y-1 px-2 py-4 md:p-4">
<a href="{targetUrl}" class="peer"
<f:if condition="{concept.popupText} && {settings.globalConceptCode} != {concept.code}">
hx-get="{ep:uri.ajax(action: 'concept', controller: 'AjaxTeaserPopup', arguments: '{concept: concept.uid, targetUrl: targetUrl}', format: 'html', pageUid: settings.defaultAjaxUid)}"
hx-target="body"
hx-swap="beforeend"
</f:if>
>
<div class="product-teaser__label-name">
{product.name}
</div>
<div class="product-teaser__label-region">
{region.name}
</div>
<span class="absolute top-0 left-0 inset-0 z-10"></span>
</a>
<div class="product-teaser__label-included">
{ep:nightsOptions(options: nights, daytrip: daytrip)}{f:if(condition: including, then: ' inkl.')}
</div>
<ul class="product-teaser__list-included flex-1 list-none m-0 text-zinc-800 divide-y divide-zinc-400">
<ul class="product-teaser__list-included flex-1 list-none m-0 text-zinc-800 divide-y divide-zinc-400 pb-8">
{including -> f:format.raw()}
</ul>
<div class="pt-8">
<div class="bg-button text-white font-bold px-4 py-1 group-hover:bg-button transition-colors">
<div class="lg:inline-block">
ab <span class="product-teaser__price mx-1">{minPrice} €</span>
</div>
<div class="product-teaser__label-price">
p. P.{f:if(condition: '{season} == "w"', then: ' / inkl. Skipass')}
</div>
<div class="bg-ep-primary-dark text-white font-bold px-4 py-1 peer-hover:bg-badge-gradient peer-hover:text-white transition-colors">
<div class="lg:inline-block">
ab <span class="product-teaser__price mx-1">{minPrice} €</span>
</div>
<div class="product-teaser__label-price">
p. P.{f:if(condition: '{season} == "w"', then: ' / inkl. Skipass')}
</div>
</div>
</a>
</div>
</f:section>
<f:section name="Including">
@@ -4,7 +4,7 @@
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<f:section name="Teaser">
<a href="{f:uri.typolink(parameter: region.detailPage)}" title="{region.name}" class="flex flex-col">
<div class="relative flex flex-col">
<div class="relative">
{ep:icon(icon: 'flag-{region.country.code -> f:format.case(mode: \'lower\')}', class: 'w-8 h-6 absolute top-0 left-0')}
<f:alias map="{teaserImage: region.teaserImage, defaultImage: region.images.0}">
@@ -34,17 +34,19 @@
</f:if>
</f:alias>
</div>
<div class="flex-1 py-4 px-2 bg-white border-l border-r border-zinc-200" data-rte-content>
<span class="headline--3 mb-4">
<div class="flex-1 flex flex-col pt-4 bg-white border border-t-0 border-zinc-200">
<a href="{f:uri.typolink(parameter: region.detailPage)}" class="px-2 peer headline--3 mb-4 no-underline">
{region.name}
</span>
{region.teaser -> f:format.crop(maxCharacters: settings.teaserTextMaxChars) -> f:format.html()}
<span class="absolute inset-0"></span>
</a>
<div class="flex-1 px-2 text-zinc-800" data-rte-content>
{region.teaser -> f:format.crop(maxCharacters: settings.teaserTextMaxChars) -> f:format.html()}
</div>
<div class="button teaser-button">
{f:translate(key: 'tx_eptheme.label.teaserbutton.default', extensionName: 'ep_theme')}
</div>
</div>
<button type="button"
class="button bg-button w-full">
{f:translate(key: 'tx_eptheme.label.teaserbutton.default', extensionName: 'ep_theme')}
</button>
</a>
</div>
</f:section>
</html>
@@ -30,6 +30,7 @@
<div class="flex flex-col">
<div class="relative pb-2 md:pb-0">
<input type="text"
aria-label="Reisezeitraum"
class="border-px border-white text-white text-xl p-2 w-full bg-transparent focus:border-white focus:ring-0"
data-datepicker-target="field">
{ep:icon(icon: 'calendar', class: 'w-6 h-6 text-white absolute top-0 right-0 translate-y-1/2 mr-2')}
@@ -75,14 +76,13 @@
<ul class="mb-0 p-0 space-y-2">
<f:for each="{filterOptions.concepts}" as="concept">
<li>
<label class="flex items-center">
<label class="flex items-center" for="form-concept-{concept.uid}">
<f:form.checkbox class="mr-2 rounded-full w-5 h-5 border-white ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary"
id="form-concept-{concept.uid}"
property="conceptUids"
data="{action: '{stimulusController}#filter'}"
value="{concept.uid}"/>
<span class="block w-full py-1 px-2 bg-concept-{concept.code} text-white rounded">
{concept.name}
</span>
<span class="block w-full py-1 px-2 bg-concept-{concept.code} text-white text-lg rounded">{concept.name}</span>
</label>
</li>
</f:for>
@@ -99,7 +99,7 @@
</div>
</f:if>
<div class="px-4 divide-y py-2 px-4 hover-hover:lg:bg-white">
<div class="divide-y py-2 px-4 hover-hover:lg:bg-white">
<div class="py-2"
data-controller="collapse"
@@ -219,17 +219,19 @@
<div data-collapse-target="container">
<ul class="mb-0 p-0 pt-4 space-y-2">
<f:for each="{filterOptions.hotelTypes}" as="type">
<li>
<label class="flex items-start">
<f:form.checkbox class="w-5 h-5 border-ep-primary-light ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary"
property="hotelTypes"
data="{action: '{stimulusController}#filter'}"
value="{type}"/>
<span class="leading-none pl-2">
{hotelTypes.{type}}
</span>
</label>
</li>
<f:if condition="{hotelTypes.{type}}">
<li>
<label class="flex items-start">
<f:form.checkbox class="w-5 h-5 border-ep-primary-light ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary"
property="hotelTypes"
data="{action: '{stimulusController}#filter'}"
value="{type}"/>
<span class="leading-none pl-2">
{hotelTypes.{type}}
</span>
</label>
</li>
</f:if>
</f:for>
</ul>
</div>
@@ -287,7 +289,7 @@
{ep:icon(icon: 'arrow-right', class: 'w-6 h-6 hover-none:text-white', data: '{collapse-target: \'icon\'}')}
</button>
<div data-collapse-target="container">
<ul class="mb-0 p-0 p-0 pt-4 space-y-2">
<ul class="mb-0 p-0 pt-4 space-y-2">
<f:for each="{filterOptions.roomTypes}" as="type">
<li>
<label class="flex items-start">
@@ -3,16 +3,18 @@
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers">
<div class="flex items-center space-x-4 text-white text-lg p-4 mb-4 {f:if(condition: '{meta.organic} && {meta.total} > 0', then: 'bg-emerald-600', else: 'bg-red-600')}">
<f:if condition="{meta.organic} && {meta.total} > 0">
<f:then>
{ep:icon(icon: 'emoji-happy', class: 'w-6 h-6')}
</f:then>
<f:else>
{ep:icon(icon: 'emoji-sad', class: 'w-6 h-6')}
</f:else>
</f:if>
<span class="flex-1">
<div class="flex mb-4 border-2 rounded-sm {f:if(condition: '{meta.organic} && {meta.total} > 0', then: 'border-emerald-600', else: 'border-red-600')}">
<div class="flex flex-col items-center justify-center px-2 {f:if(condition: '{meta.organic} && {meta.total} > 0', then: 'bg-emerald-600', else: 'bg-red-600')}">
<f:if condition="{meta.organic} && {meta.total} > 0">
<f:then>
{ep:icon(icon: 'emoji-happy', class: 'w-6 h-6 text-white')}
</f:then>
<f:else>
{ep:icon(icon: 'emoji-sad', class: 'w-6 h-6 text-white')}
</f:else>
</f:if>
</div>
<div class="flex-1 px-4 py-2 bg-white text-lg">
Deine Suche
<f:if condition="{meta.organic}">
<f:then>
@@ -28,7 +30,7 @@
ergab leider keine genauen Treffer. Bitte benutze die Filter.
</f:else>
</f:if>
</span>
</div>
</div>
<button type="button"
class="lg:hidden mb-4 text-white bg-badge-gradient uppercase py-2 w-full"
@@ -48,8 +48,8 @@
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMinYMin meet"
class="w-full h-full">
<circle fill="currentColor" class="text-ep-primary/50" cx="100" cy="100" r="100"/>
<circle fill="currentColor" class="text-ep-primary" cx="100" cy="100" r="70"/>
<circle fill="currentColor" class="text-ep-primary-dark/50" cx="100" cy="100" r="100"/>
<circle fill="currentColor" class="text-ep-primary-dark" cx="100" cy="100" r="70"/>
</svg>
<div class="absolute top-0 left-0 inset-0 flex flex-col items-center justify-center p-8">
<span class="block text-center text-white uppercase font-bold leading-none text-xl">{badgeData.title -> f:format.raw()}</span>
@@ -4,31 +4,31 @@
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<f:section name="Teaser">
<a href="{f:uri.typolink(parameter: data.header_link)}" class="flex flex-col group">
<div class="relative flex flex-col">
<div class="relative">
<f:if condition="{context.country}">
{ep:icon(icon: 'flag-{context.country.code -> f:format.case(mode: \'lower\')}', class: 'w-8 h-6 absolute top-0 left-0')}
</f:if>
<ep:lazyLoadImage image="{teaserImage}"
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
class="block w-full h-full object-cover"
width="400c"
height="300c"
alt="{teaserImage.alternative}" />
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
class="block w-full h-full object-cover"
width="400c"
height="300c"
alt="{teaserImage.alternative}" />
</div>
<div class="flex-1 py-4 px-2 bg-white border-l border-r border-zinc-200" data-rte-content>
<span class="headline--3 mb-4">
<div class="flex-1 flex flex-col pt-4 bg-white border border-t-0 border-zinc-200">
<a href="{f:uri.typolink(parameter: data.header_link)}" class="px-2 peer headline--3 mb-2 no-underline">
{data.header -> f:format.nl2br()}{f:if(condition: data.subheader, then: '<br>{data.subheader}')}
</span>
<div class="text-zinc-800">
<span class="absolute inset-0"></span>
</a>
<div class="flex-1 px-2 pb-6 text-zinc-800" data-rte-content>
{data.bodytext -> f:format.html()}
</div>
<div class="button teaser-button">
{data.button -> v:or(alternative: 'Details')}
</div>
</div>
<button type="button"
class="button bg-button w-full">
{data.button -> v:or(alternative: 'Details')}
</button>
</a>
</div>
</f:section>
</html>
@@ -4,22 +4,24 @@
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<f:section name="Teaser">
<a href="{f:uri.typolink(parameter: data.header_link)}" class="teaserbox teaserbox--default group">
<div class="relative teaserbox teaserbox--default">
<div class="teasebox__image">
<f:render partial="TeaserImage" arguments="{image: teaserImage}"/>
</div>
<div class="teaserbox__main" data-rte-content>
<span class="headline headline--3 headline--teaser">
<div class="teaserbox__main">
<a href="{f:uri.typolink(parameter: data.header_link)}" class="headline headline--3 headline--teaser no-underline">
{data.header -> f:format.nl2br()}{f:if(condition: data.subheader, then: '<br>{data.subheader}')}
</span>
<span class="absolute inset-0"></span>
</a>
<hr>
{data.bodytext -> f:format.html()}
<div class="text-zinc-800" data-rte-content>
{data.bodytext -> f:format.html()}
</div>
</div>
<button type="button"
class="button bg-button button--full">
<div class="button bg-button button--full">
{data.button -> v:or(alternative: 'Details')}
</button>
</a>
</div>
</div>
</f:section>
</html>
@@ -5,61 +5,56 @@
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers">
<f:section name="Content">
<div class="tiles">
<div class="tiles__grid">
<div class="container lg:max-w-screen-2xl">
<div class="grid grid-cols-1 lg:grid-cols-12 lg:grid-rows-3 lg:grid-flow-col gap-4 lg:gap-1 lg:h-128 bg-white">
<f:if condition="{images.0}">
<div class="tiles__tile lg:col-span-2 lg:row-span-1"
style="background-image:url('{f:uri.image(image: images.0)}');">
<f:link.typolink parameter="{images.0.link}"
class="tiles__link">
<span class="tiles__label">
<div class="relative h-32 lg:h-auto lg:col-span-2 lg:row-span-1 overflow-hidden">
<f:link.typolink parameter="{images.0.link}" class="absolute inset-0 z-20 flex items-center justify-center peer">
<div class="inline-block px-4 py-2 text-center leading-none text-white hover:text-white text-2xl font-bold uppercase break-normal sbw:bg-sbw-secondary/90 uch:bg-uch-secondary/90 snz:bg-snz-secondary/90">
{images.0.title -> f:format.raw()}
</span>
</div>
</f:link.typolink>
<f:image image="{images.0}" alt="{images.0.alternative}" class="w-full h-full object-cover transition-transform duration-300 peer-hover:scale-110" />
</div>
</f:if>
<f:if condition="{images.1}">
<div class="tiles__tile lg:col-span-2 lg:row-span-1"
style="background-image:url('{f:uri.image(image: images.1)}');">
<f:link.typolink parameter="{images.1.link}"
class="tiles__link">
<span class="tiles__label">
<div class="relative h-32 lg:h-auto lg:col-span-2 lg:row-span-1 overflow-hidden">
<f:link.typolink parameter="{images.1.link}" class="absolute inset-0 z-20 flex items-center justify-center peer">
<div class="inline-block px-4 py-2 text-center leading-none text-white hover:text-white text-2xl font-bold uppercase break-normal sbw:bg-sbw-secondary/90 uch:bg-uch-secondary/90 snz:bg-snz-secondary/90">
{images.1.title -> f:format.raw()}
</span>
</div>
</f:link.typolink>
<f:image image="{images.1}" alt="{images.1.alternative}" class="w-full h-full object-cover transition-transform duration-300 peer-hover:scale-110" />
</div>
</f:if>
<f:if condition="{images.4}">
<div class="tiles__tile lg:col-span-12 lg:row-span-1"
style="background-image:url('{f:uri.image(image: images.4)}');">
<f:link.typolink parameter="{images.4.link}"
class="tiles__link">
<span class="tiles__label">
<div class="relative h-32 lg:h-auto lg:col-span-12 lg:row-span-1 overflow-hidden">
<f:link.typolink parameter="{images.4.link}" class="absolute inset-0 z-20 flex items-center justify-center peer">
<div class="inline-block px-4 py-2 text-center leading-none text-white hover:text-white text-2xl font-bold uppercase break-normal sbw:bg-sbw-secondary/90 uch:bg-uch-secondary/90 snz:bg-snz-secondary/90">
{images.4.title -> f:format.raw()}
</span>
</div>
</f:link.typolink>
<f:image image="{images.4}" alt="{images.4.alternative}" class="w-full h-full object-cover transition-transform duration-300 peer-hover:scale-110" />
</div>
</f:if>
<f:if condition="{images.2}">
<div class="tiles__tile lg:col-span-4 lg:row-span-2"
style="background-image:url('{f:uri.image(image: images.2)}');">
<f:link.typolink parameter="{images.2.link}"
class="tiles__link">
<span class="tiles__label">
<div class="relative h-32 lg:h-auto lg:col-span-4 lg:row-span-2 overflow-hidden">
<f:link.typolink parameter="{images.2.link}" class="absolute inset-0 z-20 flex items-center justify-center peer">
<div class="inline-block px-4 py-2 text-center leading-none text-white hover:text-white text-2xl font-bold uppercase break-normal sbw:bg-sbw-secondary/90 uch:bg-uch-secondary/90 snz:bg-snz-secondary/90">
{images.2.title -> f:format.raw()}
</span>
</div>
</f:link.typolink>
<f:image image="{images.2}" alt="{images.2.alternative}" class="w-full h-full object-cover transition-transform duration-300 peer-hover:scale-110" />
</div>
</f:if>
<f:if condition="{images.3}">
<div class="tiles__tile lg:col-span-6 lg:row-span-2"
style="background-image:url('{f:uri.image(image: images.3)}');">
<f:link.typolink parameter="{images.3.link}"
class="tiles__link">
<span class="tiles__label">
<div class="relative h-32 lg:h-auto lg:col-span-6 lg:row-span-2 overflow-hidden">
<f:link.typolink parameter="{images.3.link}" class="absolute inset-0 z-20 w-full h-full flex items-center justify-center peer">
<div class="inline-block px-4 py-2 text-center leading-none text-white hover:text-white text-2xl font-bold uppercase break-normal sbw:bg-sbw-secondary/90 uch:bg-uch-secondary/90 snz:bg-snz-secondary/90">
{images.3.title -> f:format.raw()}
</span>
</div>
</f:link.typolink>
<f:image image="{images.3}" alt="{images.3.alternative}" class="w-full h-full object-cover transition-transform duration-300 peer-hover:scale-110" />
</div>
</f:if>
</div>
@@ -3,6 +3,10 @@
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<a href="#main-content" class="hidden lg:block fixed left-0 top-0 bg-ep-primary-dark text-white py-1 px-4 z-50 transform focus:translate-y-12 transition">
zum Inhalt springen
</a>
<f:if condition="{settings.hideAreaNavigation}">
<f:else>
<div class="topnav">
@@ -25,7 +29,7 @@
<f:if condition="{settings.topNavPid}">
<div class="flex-1 flex items-center">
<f:for each="{topnav}" as="menuitem">
<a class="topnav__item flex-grow{f:if(condition: menuitem.data.tx_eptheme_navitemclass, then: ' {menuitem.data.tx_eptheme_navitemclass}')}{f:if(condition: '{menuitem.active} || {menuitem.data.uid} == {settings.forceActiveTopnavUid}', then: ' bg-ep-secondary')}"
<a class="topnav__item flex-grow{f:if(condition: menuitem.data.tx_eptheme_navitemclass, then: ' {menuitem.data.tx_eptheme_navitemclass}')}{f:if(condition: '{menuitem.active} || {menuitem.data.uid} == {settings.forceActiveTopnavUid}', then: ' bg-ep-secondary text-gray-900')}"
href="{menuitem.link}"{f:if(condition: '{menuitem.data.doktype} == 3', then: ' target="_blank"')}>
{menuitem.title}
</a>
@@ -33,7 +37,7 @@
</div>
</f:if>
<f:if condition="{settings.myEpPageUid}">
<f:link.typolink parameter="{settings.myEpPageUid}" class="topnav__item" title="My E&P">
<f:link.typolink parameter="{settings.myEpPageUid}" class="topnav__item" title="My E&amp;P">
{ep:icon(icon: 'user', class: 'w-5 h-5')}
</f:link.typolink>
</f:if>
@@ -29,21 +29,21 @@
<table class="w-full mb-4 bg-zinc-200">
<thead>
<tr>
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-left text-sm md:text-base">
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-left text-sm md:text-base" scope="col">
Termin
</th>
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-sm md:text-base">
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-sm md:text-base" scope="col">
Nächte
</th>
<f:if condition="{hasIncludedServices}">
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-sm md:text-base">
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-sm md:text-base" scope="col">
inklusive
</th>
</f:if>
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-sm md:text-base">
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-sm md:text-base" scope="col">
ab
</th>
<th></th>
<th scope="col" aria-label="Links zur Buchung"></th>
</tr>
</thead>
<tbody>
@@ -54,7 +54,7 @@
<f:if condition="{bookable} && {row.available} && {row.showBookingButton}">
<f:then>
<button type="button"
class="text-left text-ep-primary-light ser:text-ser-primary text-sm md:text-base"
class="text-left text-ep-primary-dark ser:text-ser-primary-dark text-sm md:text-base"
data-action="product-details#loadPrices"
data-product-details-prices-url-param="{ep:uri.ajax(
action: 'pricetable',
@@ -117,7 +117,7 @@
</f:if>
</div>
<button type="button"
class="text-ep-primary-light ser:text-ser-primary col-span-2 text-sm md:text-base text-left leading-none whitespace-nowrap p-1"
class="text-ep-primary-dark ser:text-ser-primary-dark col-span-2 text-sm md:text-base text-left leading-none whitespace-nowrap p-1"
data-action="pricetable#openModal"
data-pricetable-type-param="services"
data-pricetable-uid-param="{row.dateUid}"
@@ -146,7 +146,7 @@
<f:if condition="{row.showBookingButton}">
<f:then>
<button type="button"
class="flex space-x-1 items-center {f:if(condition: row.available, then: 'text-ep-primary-light ser:text-ser-primary', else: 'text-zinc-300')}"
class="flex space-x-1 items-center {f:if(condition: row.available, then: 'text-ep-primary-dark ser:text-ser-primary-dark', else: 'text-zinc-300')}"
data-action="product-details#loadPrices"
data-product-details-prices-url-param="{ep:uri.ajax(action: 'pricetable', controller: 'AjaxTable', arguments: '{product: product, hotel: hotel, date: row.dateUid}', format: 'html', pageUid: settings.defaultAjaxUid)}">
<svg class="w-6 h-6 hidden md:block">
@@ -160,7 +160,7 @@
<f:else>
<a href="{f:uri.typolink(parameter: settings.travelAlertPageUid)}"
title="Reisen-Alert"
class="flex space-x-1 items-center text-ep-primary-light ser:text-ser-primary">
class="flex space-x-1 items-center text-ep-primary-dark ser:text-ser-primary-dark">
<svg class="w-6 h-6 hidden md:block">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-arrow-circle-right"></use>
</svg>
@@ -181,7 +181,7 @@
<li class="py-2">
<button type="button"
data-action="pricetable#toggleSurcharge"
class="flex items-center space-x-1 focus:outline-none text-ep-primary-light ser:text-ser-primary">
class="flex items-center space-x-1 focus:outline-none text-ep-primary-dark ser:text-ser-primary-dark">
<svg class="w-6 h-6">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-arrow-circle-right"></use>
</svg>
@@ -197,7 +197,7 @@
<li class="py-2">
<button type="button"
data-action="pricetable#toggleDiscount"
class="flex items-center space-x-1 focus:outline-none text-ep-primary-light ser:text-ser-primary">
class="flex items-center space-x-1 focus:outline-none text-ep-primary-dark ser:text-ser-primary-dark">
<svg class="w-6 h-6">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-arrow-circle-right"></use>
</svg>
@@ -212,7 +212,7 @@
<f:if condition="{bookableDates -> f:count()} > 5">
<li class="py-2">
<button type="button"
class="flex items-center space-x-1 focus:outline-none text-ep-primary-light ser:text-ser-primary"
class="flex items-center space-x-1 focus:outline-none text-ep-primary-dark ser:text-ser-primary-dark"
data-action="pricetable#toggleRows">
<svg class="w-6 h-6">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-plus-circle"
@@ -228,7 +228,7 @@
<li class="py-2">
<a href="{altProductLink}"
title="{altLabel}"
class="flex items-center space-x-1 focus:outline-none text-ep-primary-light ser:text-ser-primary">
class="flex items-center space-x-1 focus:outline-none text-ep-primary-dark ser:text-ser-primary-dark">
<svg class="w-6 h-6">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-arrow-circle-right"></use>
</svg>
@@ -248,7 +248,7 @@
<div class="absolute inset-0 w-full h-full bg-black/85 z-25"
data-action="click->modal#close"></div>
<div class="absolute top-1/2 left-1/2 transform -translate-xy-1/2 w-full max-w-xl px-4">
<div class="shadow flex items-center justify-between p-4 bg-ep-primary-light ser:bg-ser-primary text-white rounded-t">
<div class="shadow flex items-center justify-between p-4 bg-ep-primary-dark ser:bg-ser-primary-dark text-white rounded-t">
<span class="text-xl font-bold">
Inklusivleistungen {hotel.name}
</span>
@@ -270,7 +270,7 @@
<tr>
<td>
<div class="flex items-center space-x-2">
<svg class="w-6 h-6 text-ep-primary">
<svg class="w-6 h-6 text-ep-primary-dark">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-check"></use>
</svg>
<span>{service}</span>
@@ -25,11 +25,11 @@
<table class="w-full mb-4 bg-zinc-200">
<thead>
<tr>
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-left text-sm md:text-base">
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-left text-sm md:text-base" scope="col">
Zimmertyp {dateRange}
</th>
<f:if condition="{hasIncludedServices}">
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-sm md:text-base">
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-sm md:text-base" scope="col">
<span class="lg:hidden">
inkl.
</span>
@@ -38,10 +38,10 @@
</span>
</th>
</f:if>
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-sm md:text-base">
<th class="border-r border-white/50 px-2 py-1 md:p-2 text-sm md:text-base" scope="col">
optional
</th>
<th class="px-2 py-1 md:p-2 text-sm md:text-base">
<th class="px-2 py-1 md:p-2 text-sm md:text-base" scope="col">
Preis/Buchen
</th>
</tr>
@@ -67,7 +67,7 @@
<li class="py-2">
<button type="button"
data-action="pricetable#toggleSurcharge"
class="flex items-center space-x-1 focus:outline-none text-ep-primary-light">
class="flex items-center space-x-1 focus:outline-none text-ep-primary-dark">
<svg class="w-6 h-6">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-arrow-circle-right"></use>
</svg>
@@ -83,7 +83,7 @@
<li class="py-2">
<button type="button"
data-action="pricetable#toggleDiscount"
class="flex items-center space-x-1 focus:outline-none text-ep-primary-light">
class="flex items-center space-x-1 focus:outline-none text-ep-primary-dark">
<svg class="w-6 h-6">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-arrow-circle-right"></use>
</svg>
@@ -99,7 +99,7 @@
<f:else>
<li class="py-2">
<button type="button"
class="flex items-center space-x-1 focus:outline-none text-ep-primary-light"
class="flex items-center space-x-1 focus:outline-none text-ep-primary-dark"
data-action="product-details#showDates">
<svg class="w-6 h-6">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-arrow-circle-left"></use>
@@ -119,7 +119,7 @@
<ul class="list-none m-0 p-0 flex-1">
<f:for each="{servicesIncluded}" as="service">
<li class="flex items-center space-x-2">
<svg class="w-6 h-6 text-ep-primary">
<svg class="w-6 h-6 text-ep-primary-dark">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-check"></use>
</svg>
<span>{service}</span>
@@ -152,7 +152,7 @@
<div class="absolute inset-0 w-full h-full bg-black/85 z-25"
data-action="click->modal#close"></div>
<div class="absolute top-1/2 left-1/2 transform -translate-xy-1/2 w-full max-w-xl px-4">
<div class="shadow flex items-center justify-between p-4 bg-ep-primary-light text-white rounded-t">
<div class="shadow flex items-center justify-between p-4 bg-ep-primary-dark text-white rounded-t">
<span class="text-xl font-bold">
Optionale Zusatzleistungen
</span>
@@ -179,7 +179,7 @@
<td class="border-r border-zinc-200 px-2 py-1 md:p-2">
<f:if condition="{row.showBookingButton} && {row.available}">
<f:then>
<a class="inline-block text-ep-primary-light text-xs sm:text-sm md:text-base leading-tight"
<a class="inline-block text-ep-primary-dark text-xs sm:text-sm md:text-base leading-tight"
href="{row.bookingUrl}"
data-controller="datalayer" data-datalayer-event-value="ZurBuchung" data-datalayer-action="trigger"
target="_blank"
@@ -241,7 +241,7 @@
<td class="border-r border-zinc-200 px-2 py-1 md:p-2 text-center">
<f:if condition="{row.hasOptionalServices} && {row.available}">
<button type="button"
class="text-ep-primary-light text-sm md:text-base text-left leading-none p-1"
class="text-ep-primary-dark text-sm md:text-base text-left leading-none p-1"
data-action="pricetable#openModal"
data-pricetable-type-param="options"
data-pricetable-uid-param="{row.roomUid}"
@@ -6,7 +6,7 @@
<f:layout name="Bare"/>
<f:section name="Main">
<a href="{f:uri.typolink(parameter: country.detailPage)}" class="flex flex-col group">
<div class="relative flex flex-col">
<div class="relative">
<svg class="w-8 h-6 absolute top-0 left-0">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-flag-{country.code -> f:format.case(mode: 'lower')}"></use>
@@ -20,17 +20,19 @@
alt="{country.name}" />
</f:if>
</div>
<div class="flex-1 py-4 px-2 bg-white border-l border-r border-zinc-200" data-rte-content>
<span class="headline--3 mb-4">
<div class="flex-1 flex flex-col pt-4 bg-white border border-t-0 border-zinc-200">
<a href="{f:uri.typolink(parameter: country.detailPage)}" class="px-2 peer headline--3 mb-4 no-underline">
{country.name}
</span>
{country.teaser -> f:format.crop(maxCharacters: settings.teaserTextMaxChars) -> f:format.html()}
<span class="absolute inset-0"></span>
</a>
<div class="flex-1 px-2 text-zinc-800" data-rte-content>
{country.teaser -> f:format.crop(maxCharacters: settings.teaserTextMaxChars) -> f:format.html()}
</div>
<div class="button teaser-button w-full">
{data.button -> v:or(alternative: 'Details')}
</div>
</div>
<button type="button"
class="button bg-button w-full">
{data.button -> v:or(alternative: 'Details')}
</button>
</a>
</div>
</f:section>
</html>
@@ -32,7 +32,7 @@
<f:if condition="{teasers}">
<p class="hidden lg:block">
<button type="button"
class="button bg-button w-full mb-8 ml-4"
class="button bg-button w-full mb-8"
data-controller="scroll-to"
data-scroll-to-target-value="teasers"
data-action="scroll-to#scroll">
@@ -15,7 +15,7 @@
</div>
<div class="fixed top-0 left-0 z-20 w-screen h-screen hidden"
data-search-target="loadingIndicator">
<div class="absolute top-1/2 left-1/2 transform -translate-xy-1/2 flex items-center space-x-4 bg-ep-secondary text-white text-lg p-4 rounded">
<div class="absolute top-1/2 left-1/2 transform -translate-xy-1/2 flex items-center space-x-4 bg-badge-gradient text-white text-lg p-4 rounded">
<svg class="w-6 h-6">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-spinner"></use>
</svg>
@@ -266,7 +266,7 @@
Detailsuche
</button>
<button type="submit"
class="w-1/3 text-white bg-badge-gradient uppercase py-2">
class="w-1/3 text-white bg-badge-gradient hover:bg-none hover:bg-ep-pink transition-colors uppercase py-2">
Alle Reisen anzeigen
</button>
</div>
+11 -9
View File
@@ -15,6 +15,7 @@ module.exports = {
'pt-8', 'pt-16', 'pb-8', 'pb-16',
'bg-red-600',
'bg-header-season-w', 'bg-header-season-s',
'bg-concept-ok', 'bg-concept-ok/70',
'bg-concept-bdg', 'bg-concept-bdg/70',
'bg-concept-skr', 'bg-concept-skr/70',
'bg-concept-evt', 'bg-concept-evt/70',
@@ -66,20 +67,21 @@ module.exports = {
epe: '#436a8a',
sfl: '#4E4E51',
ser: '#e85243',
ok: '#0173A5',
},
ep: {
primary: '#3d8ccb',
secondary: '#f9c700',
'primary-bg': '#ebf3fa',
'primary-light': '#0080ff',
'primary-light': '#0070E0',
'primary-medium': '#165883',
'primary-dark': '#18527b',
pink: '#fa1a8c',
},
sbw: {
primary: '#f0bc44',
secondary: '#ee525a',
'primary-dark': '#c7a20c',
primary: '#B3820F',
secondary: '#E91C26',
'primary-dark': '#8D7207',
overlay: '#c20000',
},
snz: {
@@ -88,14 +90,14 @@ module.exports = {
'primary-dark': '#82c3c6',
},
uch: {
primary: '#a6c62c',
primary: '#677A1A',
secondary: '#19a3dc',
'primary-dark': '#a6c62c',
overlay: '#a6c62c',
'primary-dark': '#677A1A',
overlay: '#677A1A',
},
ser: {
primary: '#006fb6',
secondary: '#e85243',
secondary: '#DE2C1B',
'primary-light': '#04A4CC',
},
suz: {
@@ -109,7 +111,7 @@ module.exports = {
'85': 0.85,
},
backgroundImage: {
'badge-gradient': 'linear-gradient(120deg, rgba(150,1,103,1) 0%, rgba(158,3,106,1) 40%, rgba(250,26,140,1) 100%)',
'badge-gradient': 'linear-gradient(120deg, #960167 0%, #9e036a 40%, #fa1a8c 100%)',
'brand-gradient': 'linear-gradient(to top right, #009fff, #165883, #18527b)',
},
height: {