Compare commits
50 Commits
de23d5214c
...
v12.4.24-1
| Author | SHA1 | Date | |
|---|---|---|---|
| 7cc28d1e4e | |||
| f2599fb2ac | |||
| f8f7d70325 | |||
| bf43f52046 | |||
| 3cddcd8c5d | |||
| 5b332a1675 | |||
| c227b17d7f | |||
| defc44df99 | |||
| ced2d8279b | |||
| 2e07c498cd | |||
| 57966ea7b3 | |||
| ebe2905547 | |||
| f07354da68 | |||
| 911c228322 | |||
| 6f9ed95263 | |||
| baa233dd98 | |||
| 8df5bff3c8 | |||
| 2604436c7c | |||
| 2ae28cbd87 | |||
| 003cb2221d | |||
| d2025948cf | |||
| 63055bcd65 | |||
| 06d2dddb1b | |||
| b03f3340b9 | |||
| ec7ae2bba3 | |||
| 7883ec8b02 | |||
| 9b11327380 | |||
| 43344b8868 | |||
| 8905c5731d | |||
| 696881e4f8 | |||
| 1076fe6447 | |||
| 4a7153568f | |||
| 2b51545c6d | |||
| 30e30f7d24 | |||
| 745d922159 | |||
| cb459a03da | |||
| 1a20c0e7a3 | |||
| 5dbee89bd7 | |||
| da341badd9 | |||
| af66646775 | |||
| a967366a9b | |||
| ad04647359 | |||
| f77e921b81 | |||
| 147f53775f | |||
| 1da5ce2a77 | |||
| bed54e120b | |||
| ee73d44aaf | |||
| 78bffc5b46 | |||
| 58d041c473 | |||
| ba359c07a5 |
@@ -2,5 +2,6 @@ project_name: "lena-schilling-website"
|
||||
default_prompt_blocks:
|
||||
- "basic-prompt"
|
||||
- "typo3-development"
|
||||
directories:
|
||||
- "packages"
|
||||
initial_files:
|
||||
- composer.json
|
||||
- package.json
|
||||
|
||||
@@ -24,14 +24,7 @@ jobs:
|
||||
with:
|
||||
php-version: ${{ env.PHP_VERSION }}
|
||||
|
||||
- name: Check if composer.json exists
|
||||
id: check_files
|
||||
uses: andstor/file-existence-action@87d74d4732ddb824259d80c8a508c0124bf1c673
|
||||
with:
|
||||
files: 'composer.json'
|
||||
|
||||
- name: Run composer install if composer.json exists
|
||||
if: steps.check_files.outputs.files_exists == 'true'
|
||||
run: |
|
||||
rm composer.lock
|
||||
composer validate --no-check-publish
|
||||
|
||||
@@ -28,14 +28,7 @@ jobs:
|
||||
with:
|
||||
php-version: ${{ env.PHP_VERSION }}
|
||||
|
||||
- name: Check if composer.json exists
|
||||
id: check_files
|
||||
uses: andstor/file-existence-action@87d74d4732ddb824259d80c8a508c0124bf1c673
|
||||
with:
|
||||
files: 'composer.json'
|
||||
|
||||
- name: Run composer install if composer.json exists
|
||||
if: steps.check_files.outputs.files_exists == 'true'
|
||||
run: |
|
||||
composer validate --no-check-publish && composer install --prefer-dist --no-progress --ignore-platform-reqs
|
||||
|
||||
@@ -109,28 +102,28 @@ jobs:
|
||||
dep: --file=./build/deploy.php release:switch stage
|
||||
private-key: ${{secrets.STAGE_KEY}}
|
||||
|
||||
# deploy-production:
|
||||
# needs: build
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - name: Setup PHP
|
||||
# uses: shivammathur/setup-php@7c0b4c8c8ebed23eca9ec2802474895d105b11bc
|
||||
# with:
|
||||
# php-version: ${{ env.PHP_VERSION }}
|
||||
# - uses: actions/download-artifact@v3
|
||||
# with:
|
||||
# name: typo3
|
||||
# - name: Extract artifact
|
||||
# run: |
|
||||
# tar xf typo3.tar.gz
|
||||
# rm typo3.tar.gz
|
||||
# - name: Install ssh agent and rsync
|
||||
# run: |
|
||||
# apt update
|
||||
# apt install -y openssh-client rsync
|
||||
# - name: Deploy
|
||||
# uses: deployphp/action@v1
|
||||
# with:
|
||||
# deployer-binary: "./bin/dep"
|
||||
# dep: --file=./build/deploy.php release:create production
|
||||
# private-key: ${{secrets.PROD_KEY}}
|
||||
deploy-production:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@7c0b4c8c8ebed23eca9ec2802474895d105b11bc
|
||||
with:
|
||||
php-version: ${{ env.PHP_VERSION }}
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: typo3
|
||||
- name: Extract artifact
|
||||
run: |
|
||||
tar xf typo3.tar.gz
|
||||
rm typo3.tar.gz
|
||||
- name: Install ssh agent and rsync
|
||||
run: |
|
||||
apt update
|
||||
apt install -y openssh-client rsync
|
||||
- name: Deploy
|
||||
uses: deployphp/action@v1
|
||||
with:
|
||||
deployer-binary: "./bin/dep"
|
||||
dep: --file=./build/deploy.php release:create production
|
||||
private-key: ${{secrets.PROD_KEY}}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*' # Adjust this pattern based on your tagging
|
||||
|
||||
env:
|
||||
PHP_VERSION: '8.3' # set this to the PHP version to use
|
||||
@@ -20,13 +21,7 @@ jobs:
|
||||
uses: shivammathur/setup-php@7c0b4c8c8ebed23eca9ec2802474895d105b11bc
|
||||
with:
|
||||
php-version: ${{ env.PHP_VERSION }}
|
||||
- name: Check if composer.json exists
|
||||
id: check_files
|
||||
uses: andstor/file-existence-action@87d74d4732ddb824259d80c8a508c0124bf1c673
|
||||
with:
|
||||
files: 'composer.json'
|
||||
- name: Run composer install if composer.json exists
|
||||
if: steps.check_files.outputs.files_exists == 'true'
|
||||
- name: Run composer install
|
||||
run: |
|
||||
composer validate --no-check-publish && composer install --prefer-dist --no-progress --ignore-platform-reqs
|
||||
- name: Install ssh agent, rsync
|
||||
|
||||
2
.gitignore
vendored
@@ -2,7 +2,7 @@
|
||||
.idea
|
||||
mbox
|
||||
nbproject
|
||||
/var/*
|
||||
/var
|
||||
!/var/labels
|
||||
/vendor
|
||||
/public/_assets
|
||||
|
||||
@@ -130,10 +130,10 @@ task('deploy', [
|
||||
]);
|
||||
|
||||
host('stage')
|
||||
->set('cachetool', '/var/run/phpfpm/gbv-aktuell.cloonar.dev.sock');
|
||||
->set('cachetool', '/var/run/phpfpm/lena-schilling.cloonar.dev.sock');
|
||||
|
||||
host('production')
|
||||
->set('cachetool', '/var/run/phpfpm/gbv-aktuell.at.sock');
|
||||
->set('cachetool', '/var/run/phpfpm/lena-schilling.at.sock');
|
||||
|
||||
after('deploy:symlink', 'cachetool:clear:opcache');
|
||||
// unlock after failure
|
||||
|
||||
@@ -2,7 +2,7 @@ hosts:
|
||||
production:
|
||||
stage: production
|
||||
hostname: web-arm.cloonar.com
|
||||
remote_user: gbv_aktuell_at
|
||||
remote_user: lena_schilling_at
|
||||
writable_mode: chmod
|
||||
forward_agent: true
|
||||
deploy_path: ~/
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
base: /
|
||||
base: https://lena-schilling.at
|
||||
baseVariants:
|
||||
- base: https://lena-schilling.ddev.site
|
||||
condition: 'applicationContext == "Development/Ddev"'
|
||||
- base: https://lena-schilling.cloonar.dev
|
||||
condition: 'applicationContext == "Production/Staging"'
|
||||
dependencies:
|
||||
- georgringer/news
|
||||
- typo3/redirects
|
||||
@@ -19,3 +24,13 @@ languages:
|
||||
websiteTitle: ''
|
||||
rootPageId: 1
|
||||
websiteTitle: ''
|
||||
favicons:
|
||||
full_name: 'Lena Schilling'
|
||||
short_name: 'Lena Schilling'
|
||||
theme_color: '#233600'
|
||||
favicon_path: 'EXT:base/Resources/Public/Images/Favicons/'
|
||||
favicon_svg: favicon.svg
|
||||
favicon_png: favicon-96x96.png
|
||||
apple_touch_icon: apple-touch-icon.png
|
||||
android_192: web-app-manifest-192x192.png
|
||||
android_512: web-app-manifest-512x512.png
|
||||
|
||||
@@ -109,6 +109,7 @@ return [
|
||||
],
|
||||
'GFX' => [
|
||||
'jpg_quality' => '80',
|
||||
'processor_path' => '/run/current-system/sw/bin/',
|
||||
],
|
||||
'MAIL' => [
|
||||
'defaultMailFromAddress' => 'no-reply@example.com',
|
||||
|
||||
@@ -12,6 +12,8 @@ editor:
|
||||
- { name: "Small", element: "p", attributes: { 'class': 'small' } }
|
||||
- { name: "Big Number", element: "span", attributes: { 'class': 'big-number' } }
|
||||
|
||||
- { name: "Button", element: "a", attributes: { 'class': 'btn' } }
|
||||
|
||||
toolbarGroups:
|
||||
- { name: styles, groups: [ format, styles ] }
|
||||
- { name: basicstyles, groups: [ basicstyles ] }
|
||||
@@ -24,7 +26,7 @@ editor:
|
||||
- { name: tools, groups: [ table, specialchar ] }
|
||||
- { name: document, groups: [ mode ] }
|
||||
|
||||
format_tags: "p;h1;h2;h3;h4;h5;pre"
|
||||
format_tags: "p;h3;h4;h5;pre"
|
||||
|
||||
justifyClasses:
|
||||
- text-left
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# Define the footer menu PID as a constant to make it easily configurable
|
||||
page {
|
||||
footerMenuPid = 7
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
# Include existing configuration
|
||||
<INCLUDE_TYPOSCRIPT: source="DIR:EXT:base/ContentBlocks" extensions="typoscript">
|
||||
# Include constants
|
||||
#<INCLUDE_TYPOSCRIPT: source="FILE:EXT:base/Configuration/Sets/SitePackage/TypoScript/constants.typoscript">
|
||||
|
||||
page = PAGE
|
||||
page {
|
||||
typeNum = 0
|
||||
shortcutIcon = EXT:base/Resources/Public/Icons/favicon.ico
|
||||
shortcutIcon = EXT:base/Resources/Public/Favicons/favicon-96x96.png
|
||||
10 = PAGEVIEW
|
||||
10 {
|
||||
paths {
|
||||
@@ -23,6 +25,12 @@ page {
|
||||
as = mainnavigation
|
||||
}
|
||||
30 = page-content
|
||||
40 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
|
||||
40 {
|
||||
special = directory
|
||||
special.value = 7
|
||||
as = metanavigation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,15 +47,47 @@ page {
|
||||
|
||||
includeCSS {
|
||||
main = EXT:base/Resources/Public/Css/main.css
|
||||
fancybox = EXT:base/Resources/Public/Vendor/fancybox/fancybox.css
|
||||
}
|
||||
|
||||
includeJSLibs {
|
||||
navigation = EXT:base/Resources/Public/JavaScript/navigation.js
|
||||
fadein = EXT:base/Resources/Public/JavaScript/fade-in.js
|
||||
fancybox = EXT:base/Resources/Public/Vendor/fancybox/fancybox.umd.js
|
||||
}
|
||||
|
||||
includeJSFooter {
|
||||
test_scripts = EXT:base/Resources/Public/JavaScript/main.js
|
||||
}
|
||||
|
||||
# Use includeAssets to properly preload fonts with TYPO3 v13 asset handling.
|
||||
includeAssets {
|
||||
hajimeSansTtf {
|
||||
path = EXT:base/Resources/Public/Fonts/Hajime-Sans.woff2
|
||||
type = font
|
||||
resourceType = font
|
||||
preload = 1
|
||||
as = font
|
||||
attributes {
|
||||
type = font/woff2
|
||||
crossorigin = anonymous
|
||||
}
|
||||
}
|
||||
|
||||
interVariable {
|
||||
path = EXT:base/Resources/Public/Fonts/Inter.woff2
|
||||
type = font
|
||||
resourceType = font
|
||||
preload = 1
|
||||
as = font
|
||||
attributes {
|
||||
type = font/woff2
|
||||
crossorigin = anonymous
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footerMenuPid = {$footerMenuPid}
|
||||
}
|
||||
|
||||
lib.contentElement {
|
||||
@@ -73,3 +113,16 @@ lib.parseFunc_RTE {
|
||||
}
|
||||
}
|
||||
|
||||
# Define the footer menu to show subpages of the configured footerMenuPid
|
||||
# special = directory will list all direct subpages of the given pid, not the page itself
|
||||
lib.footerMenu = HMENU
|
||||
lib.footerMenu {
|
||||
special = directory
|
||||
special.value = {$footerMenuPid}
|
||||
1 = TMENU
|
||||
1 {
|
||||
wrap = <ul>|</ul>
|
||||
NO = 1
|
||||
NO.wrapItemAndSub = <li>|</li>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,15 +7,12 @@ RTE {
|
||||
}
|
||||
|
||||
TCEFORM {
|
||||
pages {
|
||||
|
||||
}
|
||||
tt_content {
|
||||
|
||||
tt_content {
|
||||
CType {
|
||||
keepItems = cloonar_header,cloonar_text,cloonar_textimage,news_newsliststicky,news_pi1,cloonar_hero,cloonar_stats
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TCEMAIN {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -16,17 +16,3 @@ plugin.tx_news {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Define footerMenu here
|
||||
lib.footerMenu = HMENU
|
||||
lib.footerMenu {
|
||||
special = directory
|
||||
special.value = {$page.footerMenuPid}
|
||||
1 = TMENU
|
||||
1 {
|
||||
NO {
|
||||
wrapItemAndSub = <li>|</li>
|
||||
stdWrap.noTrimWrap = | | |
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,4 +9,5 @@ $GLOBALS['TCA']['tt_content']['columns']['imageorient']['config'] = [
|
||||
['LLL:EXT:base/Resources/Private/Language/locallang_db.xlf:imageorient.25', 25],
|
||||
['LLL:EXT:base/Resources/Private/Language/locallang_db.xlf:imageorient.26', 26],
|
||||
],
|
||||
'default' => 25,
|
||||
];
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
defined('TYPO3') or die('Access denied.');
|
||||
|
||||
// Restrict cropping aspect ratio for images in news entries to 16:9
|
||||
$GLOBALS['TCA']['tx_news_domain_model_news']['columns']['fal_media']['config']['overrideChildTca']['columns']['crop']['config'] = [
|
||||
'cropVariants' => [
|
||||
'default' => [
|
||||
'title' => 'Default',
|
||||
'allowedAspectRatios' => [
|
||||
'16-9' => [
|
||||
'title' => '16:9',
|
||||
'value' => 16 / 9
|
||||
],
|
||||
],
|
||||
'selectedRatio' => '16-9',
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1 @@
|
||||
/* CSS for header content element */
|
||||
@@ -0,0 +1,10 @@
|
||||
name: cloonar/header
|
||||
typeName: cloonar_header
|
||||
group: default
|
||||
prefixFields: true
|
||||
prefixType: full
|
||||
label: LLL:EXT:base/ContentBlocks/ContentElements/header/language/labels.xlf:header.title
|
||||
description: LLL:EXT:base/ContentBlocks/ContentElements/header/language/labels.xlf:header.description
|
||||
fields:
|
||||
- identifier: header
|
||||
useExistingField: true
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff version="1.0">
|
||||
<file source-language="en" datatype="plaintext" original="messages">
|
||||
<body>
|
||||
<trans-unit id="title">
|
||||
<source>Header</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="description">
|
||||
<source>A simple content element that displays a header as an H1.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,15 @@
|
||||
<html
|
||||
xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
|
||||
data-namespace-typo3-fluid="true"
|
||||
>
|
||||
<f:layout name="Preview"/>
|
||||
<f:section name="Header">
|
||||
<be:link.editRecord uid="{data.uid}" table="{data.mainType}">
|
||||
<f:if condition="{data.header}">
|
||||
<f:then><strong>{data.header}</strong></f:then>
|
||||
</f:if>
|
||||
</be:link.editRecord>
|
||||
</f:section>
|
||||
<f:section name="Content">
|
||||
</f:section>
|
||||
</html>
|
||||
@@ -0,0 +1,4 @@
|
||||
<f:layout name="Default" />
|
||||
<f:section name="Main">
|
||||
<h1><span class="tapered">{data.header}</span></h1>
|
||||
</f:section>
|
||||
@@ -7,9 +7,8 @@
|
||||
background: url('../../../Images/background.jpg') repeat;
|
||||
}
|
||||
|
||||
|
||||
.frame-type-cloonar_hero + .frame {
|
||||
margin-top: -10rem;
|
||||
margin-top: -10.4rem;
|
||||
}
|
||||
.frame-type-cloonar_hero .container {
|
||||
padding-bottom: 3rem;
|
||||
@@ -59,29 +58,24 @@
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
}
|
||||
|
||||
/* Smaller icons on mobile */
|
||||
.frame-type-cloonar_hero .social-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--bs-primary);
|
||||
color: var(--bs-yellow);
|
||||
font-size: 1.5rem;
|
||||
padding: 2.375rem;
|
||||
font-size: 1rem;
|
||||
padding: 1rem;
|
||||
text-decoration: none;
|
||||
border-radius: 50%;
|
||||
transition: background 0.3s;
|
||||
}
|
||||
|
||||
.frame-type-cloonar_hero .social-icon:hover {
|
||||
background: #1e3810;
|
||||
}
|
||||
|
||||
.frame-type-cloonar_hero .hero-image-wrapper {
|
||||
margin-top: 1rem;
|
||||
align-self: flex-end;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.frame-type-cloonar_hero .hero-image {
|
||||
@@ -115,6 +109,7 @@
|
||||
width: 2.5rem;
|
||||
height: 2rem;
|
||||
font-size: 2rem;
|
||||
padding: 2.375rem;
|
||||
}
|
||||
|
||||
.frame-type-cloonar_hero .hero-image {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<source>Hero</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="description">
|
||||
<source>Description for Content Element cloonar/hero</source>
|
||||
<source>Hero Element should always be the first Element of the page</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@@ -2,20 +2,27 @@
|
||||
xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
|
||||
data-namespace-typo3-fluid="true"
|
||||
>
|
||||
|
||||
<f:layout name="Preview"/>
|
||||
|
||||
<f:section name="Header">
|
||||
<be:link.editRecord uid="{data.uid}" table="{data.mainType}">{data.header}</be:link.editRecord>
|
||||
<be:link.editRecord uid="{data.uid}" table="{data.mainType}">
|
||||
<f:if condition="{data.header}">
|
||||
<f:then><strong>{data.header}</strong></f:then>
|
||||
</f:if>
|
||||
</be:link.editRecord>
|
||||
</f:section>
|
||||
|
||||
<f:section name="Content">
|
||||
Preview for Content Block: cloonar/hero
|
||||
</f:section>
|
||||
<f:if condition="{data.image}">
|
||||
<f:image image="{data.image.0}" width="100" height="auto" treatIdAsReference="1" alt="Preview image" />
|
||||
</f:if>
|
||||
|
||||
<f:comment>
|
||||
<!-- Uncomment to override preview footer -->
|
||||
<f:section name="Footer">
|
||||
My custom Footer
|
||||
<f:if condition="{data.bodytext}">
|
||||
<p>
|
||||
<f:format.crop maxCharacters="80">
|
||||
<f:format.stripTags>{data.bodytext}</f:format.stripTags>
|
||||
</f:format.crop>
|
||||
</p>
|
||||
</f:if>
|
||||
</f:section>
|
||||
</f:comment>
|
||||
</html>
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
<f:asset.css identifier="CBHero" href="{cb:assetPath()}/frontend.css" />
|
||||
|
||||
<div class="hero-inner">
|
||||
<!-- Inline style with f:uri.resource to ensure correct path -->
|
||||
<div class="hero">
|
||||
<h2 class="hero-subheader">{data.subheader}</h2>
|
||||
<h1 class="hero-title">{data.header}</h1>
|
||||
@@ -15,13 +14,43 @@
|
||||
<f:format.html>{data.bodytext}</f:format.html>
|
||||
</div>
|
||||
<div class="hero-social-icons">
|
||||
<a href="https://instagram.com" class="social-icon"><i class="ci ci-instagram"></i></a>
|
||||
<a href="https://tiktok.com" class="social-icon"><i class="ci ci-tiktok"></i></a>
|
||||
<a href="https://www.instagram.com/lena.ats/" target="_blank" aria-label="Lena Schillings Instagram" class="btn social-icon"><i class="ci ci-instagram"></i></a>
|
||||
<a href="https://www.tiktok.com/@dieschilling" target="_blank" aria-label="Lena Schillings TikTok" class="btn social-icon"><i class="ci ci-tiktok"></i></a>
|
||||
</div>
|
||||
<div class="hero-image-wrapper">
|
||||
<f:if condition="{data.image}">
|
||||
<f:then>
|
||||
<f:image image="{data.image.0}" alt="Hero Image" class="hero-image" />
|
||||
<figure>
|
||||
<!-- WEBP source -->
|
||||
<source
|
||||
type="image/webp"
|
||||
srcset="
|
||||
{f:uri.image(image:data.image.0, width:'320c', cropVariant:'default', fileExtension:'webp')} 320w,
|
||||
{f:uri.image(image:data.image.0, width:'768c', cropVariant:'default', fileExtension:'webp')} 768w,
|
||||
{f:uri.image(image:data.image.0, width:'430c', cropVariant:'default', fileExtension:'webp')} 1024w"
|
||||
sizes="(max-width: 320px) 80vw,
|
||||
(max-width: 768px) 80px,
|
||||
430px" />
|
||||
|
||||
<!-- Fallback source -->
|
||||
<source
|
||||
srcset="
|
||||
{f:uri.image(image:data.image.0, width:'320c', cropVariant:'default')} 320w,
|
||||
{f:uri.image(image:data.image.0, width:'600c', cropVariant:'default')} 600w,
|
||||
{f:uri.image(image:data.image.0, width:'430c', cropVariant:'default')} 1024w"
|
||||
sizes="(max-width: 320px) 80vw,
|
||||
(max-width: 768px) 80vw,
|
||||
430px" />
|
||||
<f:image
|
||||
image="{data.image.0}"
|
||||
treatIdAsReference="1"
|
||||
fetchpriority="high"
|
||||
cropVariant="default"
|
||||
width="430c"
|
||||
alt="Hero Image"
|
||||
loading="lazy"
|
||||
class="hero-image" />
|
||||
</figure>
|
||||
</f:then>
|
||||
<f:else>
|
||||
<p>No image available</p>
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
.frame-type-cloonar_stats .stats-wrapper {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
justify-content: space-between;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
position: relative;
|
||||
z-index: 10; /* Ensure it's on top of the hero container */
|
||||
z-index: 10;
|
||||
background: #fff;
|
||||
padding: 2rem 1rem;
|
||||
padding: 1rem;
|
||||
max-width: 1140px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
gap: 1rem; /* maintain gap on mobile */
|
||||
}
|
||||
|
||||
/* Each paragraph is treated as a column */
|
||||
/* Two columns on mobile */
|
||||
.frame-type-cloonar_stats .stats-wrapper p {
|
||||
flex: 1 1 100%;
|
||||
box-sizing: border-box;
|
||||
flex: 0 0 calc((100% - 1rem) / 2);
|
||||
max-width: calc((100% - 1rem) / 2);
|
||||
text-align: center;
|
||||
margin-bottom: 1rem;
|
||||
text-transform: uppercase;
|
||||
color: var(--bs-primary);
|
||||
}
|
||||
|
||||
/* Lead paragraphs have larger text for numbers */
|
||||
.frame-type-cloonar_stats .stats-wrapper span.big-number {
|
||||
font-size: 4rem;
|
||||
font-family: 'Hajime Sans', sans-serif;
|
||||
@@ -31,11 +32,13 @@
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.frame-type-cloonar_stats .stats-wrapper {
|
||||
gap: 2rem;
|
||||
padding: 3rem 1rem;
|
||||
}
|
||||
.frame-type-cloonar_stats .stats-wrapper p {
|
||||
flex: 1 1 calc(25% - 2rem);
|
||||
gap: 2rem; /* increase gap on desktop */
|
||||
}
|
||||
|
||||
/* Four columns on desktop */
|
||||
.frame-type-cloonar_stats .stats-wrapper p {
|
||||
flex: 0 0 calc((100% - 6rem) / 4); /* 3 gaps * 2rem = 6rem total gap */
|
||||
max-width: calc((100% - 6rem) / 4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
<f:layout name="Preview"/>
|
||||
|
||||
<f:section name="Header">
|
||||
<be:link.editRecord uid="{data.uid}" table="{data.mainType}">
|
||||
Statistics Preview
|
||||
</be:link.editRecord>
|
||||
</f:section>
|
||||
|
||||
<f:section name="Content">
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/* CSS for text content element */
|
||||
.frame-type-cloonar_text .text-bodytext {
|
||||
max-width: 750px;
|
||||
}
|
||||
14
packages/base/ContentBlocks/ContentElements/text/config.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
name: cloonar/text
|
||||
typeName: cloonar_text
|
||||
group: default
|
||||
prefixFields: true
|
||||
prefixType: full
|
||||
label: LLL:EXT:base/ContentBlocks/ContentElements/text/language/labels.xlf:text.title
|
||||
description: LLL:EXT:base/ContentBlocks/ContentElements/text/language/labels.xlf:text.description
|
||||
fields:
|
||||
- identifier: header
|
||||
useExistingField: true
|
||||
- identifier: bodytext
|
||||
type: Textarea
|
||||
enableRichtext: true
|
||||
useExistingField: true
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff version="1.0">
|
||||
<file source-language="en" datatype="plaintext" original="messages">
|
||||
<body>
|
||||
<trans-unit id="title">
|
||||
<source>Text</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="description">
|
||||
<source>A text element featuring a headline (H2) and a rich-text body field.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,22 @@
|
||||
<html
|
||||
xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
|
||||
data-namespace-typo3-fluid="true"
|
||||
>
|
||||
<f:layout name="Preview"/>
|
||||
<f:section name="Header">
|
||||
<be:link.editRecord uid="{data.uid}" table="{data.mainType}">
|
||||
<f:if condition="{data.header}">
|
||||
<f:then><strong>{data.header}</strong></f:then>
|
||||
</f:if>
|
||||
</be:link.editRecord>
|
||||
</f:section>
|
||||
<f:section name="Content">
|
||||
<f:if condition="{data.bodytext}">
|
||||
<p>
|
||||
<f:format.crop maxCharacters="80">
|
||||
<f:format.stripTags>{data.bodytext}</f:format.stripTags>
|
||||
</f:format.crop>
|
||||
</p>
|
||||
</f:if>
|
||||
</f:section>
|
||||
</html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<f:layout name="Default" />
|
||||
<f:section name="Main">
|
||||
<f:asset.css identifier="CBText" href="{cb:assetPath()}/frontend.css" />
|
||||
<div class="fade-in-on-scroll">
|
||||
<f:if condition="{data.header}">
|
||||
<f:then><h2>{data.header}</h2></f:then>
|
||||
</f:if>
|
||||
<f:if condition="{data.bodytext}">
|
||||
<f:then>
|
||||
<div class="text-bodytext"><f:format.html>{data.bodytext}</f:format.html></div>
|
||||
</f:then>
|
||||
</f:if>
|
||||
</div>
|
||||
</f:section>
|
||||
@@ -1,45 +1,52 @@
|
||||
.frame-type-cloonar_textimage {
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
/* Mobile-first: column layout by default */
|
||||
.textimage-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2rem;
|
||||
--gap: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--gap);
|
||||
}
|
||||
|
||||
.textimage-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.textimage-header {
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.textimage-text {
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.textimage-image-wrapper {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.textimage-picture {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.textimage-image {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
border-radius: 0.5rem;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Image positions: 25 = left, 26 = right
|
||||
On larger screens, adjust the layout */
|
||||
/* Image positions: 25 = left, 26 = right */
|
||||
.textimage-container.image-pos-25 {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.textimage-container.image-pos-26 {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* On larger screens, arrange horizontally for image position settings */
|
||||
@media (min-width: 768px) {
|
||||
.textimage-container.size-25 {
|
||||
--gap: 8rem;
|
||||
}
|
||||
|
||||
.textimage-container.image-pos-25 {
|
||||
flex-direction: row;
|
||||
}
|
||||
@@ -48,8 +55,21 @@
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.textimage-wrapper,
|
||||
.textimage-image-wrapper {
|
||||
flex: 1 1 50%;
|
||||
}
|
||||
.textimage-image-wrapper.size-25 {
|
||||
flex: 0 0 calc(40% - (var(--gap) / 2));
|
||||
max-width: calc(40% - (var(--gap) / 2));
|
||||
}
|
||||
.textimage-wrapper.size-25 {
|
||||
flex: 0 0 calc(40% - (var(--gap) / 2));
|
||||
max-width: calc(40% - (var(--gap) / 2));
|
||||
}
|
||||
|
||||
.textimage-image-wrapper.size-50 {
|
||||
flex: 0 0 calc(50% - (var(--gap) / 2));
|
||||
max-width: calc(50% - (var(--gap) / 2));
|
||||
}
|
||||
|
||||
.textimage-wrapper {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
name: cloonar/textimage
|
||||
typeName: cloonar_textimage
|
||||
group: default
|
||||
prefixFields: true
|
||||
prefixType: full
|
||||
prefixFields: false
|
||||
fields:
|
||||
- identifier: header
|
||||
useExistingField: true
|
||||
- identifier: subheader
|
||||
useExistingField: true
|
||||
- identifier: bodytext
|
||||
type: Textarea
|
||||
enableRichtext: true
|
||||
@@ -13,7 +14,16 @@ fields:
|
||||
- identifier: image
|
||||
type: File
|
||||
properties:
|
||||
allowed: [jpg, jpeg, png, gif]
|
||||
allowed: [jpg, jpeg, png, gif, webp]
|
||||
useExistingField: true
|
||||
- identifier: imageorient
|
||||
useExistingField: true
|
||||
- identifier: imagesize
|
||||
type: Select
|
||||
renderType: selectSingle
|
||||
default: 2
|
||||
items:
|
||||
- label: 25%
|
||||
value: 1
|
||||
- label: 50%
|
||||
value: 2
|
||||
@@ -7,20 +7,22 @@
|
||||
<f:section name="Header">
|
||||
<be:link.editRecord uid="{data.uid}" table="{data.mainType}">
|
||||
<f:if condition="{data.header}">
|
||||
<f:then>{data.header}</f:then>
|
||||
<f:else>Text/Image Element</f:else>
|
||||
<f:then><strong>{data.header}</strong></f:then>
|
||||
</f:if>
|
||||
</be:link.editRecord>
|
||||
</f:section>
|
||||
|
||||
<f:section name="Content">
|
||||
<f:if condition="{data.bodytext}">
|
||||
<f:then>
|
||||
<p>Preview: <f:format.crop maxCharacters="50">{data.bodytext}</f:format.crop></p>
|
||||
</f:then>
|
||||
<f:else>
|
||||
<p>No text available</p>
|
||||
</f:else>
|
||||
</f:if>
|
||||
<f:if condition="{data.image}">
|
||||
<f:image image="{data.image.0}" width="100" height="auto" treatIdAsReference="1" alt="Preview image" />
|
||||
</f:if>
|
||||
|
||||
<f:if condition="{data.bodytext}">
|
||||
<p>
|
||||
<f:format.crop maxCharacters="80">
|
||||
<f:format.stripTags>{data.bodytext}</f:format.stripTags>
|
||||
</f:format.crop>
|
||||
</p>
|
||||
</f:if>
|
||||
</f:section>
|
||||
</html>
|
||||
|
||||
@@ -1,13 +1,63 @@
|
||||
<f:layout name="Default" />
|
||||
|
||||
<f:section name="Header" />
|
||||
<f:section name="Header"></f:section>
|
||||
<f:section name="Main">
|
||||
<f:asset.css identifier="CBTextImage" href="{cb:assetPath()}/frontend.css" />
|
||||
|
||||
<div class="textimage-container image-pos-{data.imageorient}">
|
||||
<div class="textimage-wrapper">
|
||||
<!-- Determine size class based on imagesize field -->
|
||||
<f:variable name="sizeClass" value="" />
|
||||
<f:if condition="{data.imagesize} == 1">
|
||||
<f:then><f:variable name="sizeClass" value="size-25" /></f:then>
|
||||
</f:if>
|
||||
<f:if condition="{data.imagesize} == 2">
|
||||
<f:then><f:variable name="sizeClass" value="size-50" /></f:then>
|
||||
</f:if>
|
||||
|
||||
<div class="textimage-container image-pos-{data.imageorient} {sizeClass} fade-in-on-scroll">
|
||||
<div class="textimage-image-wrapper {sizeClass}">
|
||||
<f:if condition="{data.image}">
|
||||
<f:then>
|
||||
<figure class="textimage-picture">
|
||||
<!-- WEBP source -->
|
||||
<source
|
||||
type="image/webp"
|
||||
srcset="
|
||||
{f:uri.image(image:data.image.0, width:'320c', cropVariant:'default', fileExtension:'webp')} 320w,
|
||||
{f:uri.image(image:data.image.0, width:'768c', cropVariant:'default', fileExtension:'webp')} 768w,
|
||||
{f:uri.image(image:data.image.0, width:'1024c', cropVariant:'default', fileExtension:'webp')} 1024w"
|
||||
sizes="(max-width: 320px) 90vw,
|
||||
(max-width: 768px) 600px,
|
||||
600px" />
|
||||
|
||||
<!-- Fallback source -->
|
||||
<source
|
||||
srcset="
|
||||
{f:uri.image(image:data.image.0, width:'320c', cropVariant:'default')} 320w,
|
||||
{f:uri.image(image:data.image.0, width:'400c', cropVariant:'default')} 768w,
|
||||
{f:uri.image(image:data.image.0, width:'538c', cropVariant:'default')} 1024w"
|
||||
sizes="(max-width: 320px) 90vw,
|
||||
(max-width: 768px) 600px,
|
||||
600px" />
|
||||
|
||||
<f:image
|
||||
image="{data.image.0}"
|
||||
treatIdAsReference="1"
|
||||
cropVariant="default"
|
||||
width="538c"
|
||||
alt="{data.image.0.alternative}"
|
||||
class="textimage-image"
|
||||
/>
|
||||
</figure>
|
||||
</f:then>
|
||||
<f:else>
|
||||
<p>No image available</p>
|
||||
</f:else>
|
||||
</f:if>
|
||||
</div>
|
||||
<div class="textimage-wrapper {sizeClass}">
|
||||
<f:if condition="{data.header}">
|
||||
<h2 class="textimage-header">{data.header}</h2>
|
||||
<h3 class="textimage-subheader">{data.subheader}</h3>
|
||||
</f:if>
|
||||
<f:if condition="{data.bodytext}">
|
||||
<div class="textimage-text">
|
||||
@@ -15,15 +65,5 @@
|
||||
</div>
|
||||
</f:if>
|
||||
</div>
|
||||
<div class="textimage-image-wrapper">
|
||||
<f:if condition="{data.image}">
|
||||
<f:then>
|
||||
<f:image image="{data.image.0}" alt="{data.header}" class="textimage-image" />
|
||||
</f:then>
|
||||
<f:else>
|
||||
<p>No image available</p>
|
||||
</f:else>
|
||||
</f:if>
|
||||
</div>
|
||||
</div>
|
||||
</f:section>
|
||||
|
||||
@@ -1,12 +1,42 @@
|
||||
<div class="news-list-item {f:if(condition: '{big}', then: ' news-list-item-big')}">
|
||||
<div class="news-list-item fade-in-on-scroll{f:if(condition: '{big}', then: ' news-list-item-big')}">
|
||||
<f:link.page pageUid="{settings.detailPid}" class="news-item-link" additionalParams="{tx_news_pi1: {news: newsItem.uid, action: 'detail', controller: 'News'}}">
|
||||
<f:if condition="{newsItem.media}">
|
||||
<f:image image="{newsItem.media.0}" class="news-item-grid-image" alt="{newsItem.title}" />
|
||||
<f:then>
|
||||
<picture>
|
||||
<!-- WEBP source -->
|
||||
<source
|
||||
type="image/webp"
|
||||
srcset="
|
||||
{f:uri.image(image:newsItem.media.0, width:'320c', cropVariant:'default', fileExtension:'webp')} 320w,
|
||||
{f:uri.image(image:newsItem.media.0, width:'768c', cropVariant:'default', fileExtension:'webp')} 768w,
|
||||
{f:uri.image(image:newsItem.media.0, width:'1024c', cropVariant:'default', fileExtension:'webp')} 1024w"
|
||||
sizes="(max-width: 320px) 100vw,
|
||||
(max-width: 768px) 50px,
|
||||
400px" />
|
||||
|
||||
<!-- Fallback source -->
|
||||
<source
|
||||
srcset="
|
||||
{f:uri.image(image:newsItem.media.0, width:'320c', cropVariant:'default')} 320w,
|
||||
{f:uri.image(image:newsItem.media.0, width:'768c', cropVariant:'default')} 768w,
|
||||
{f:uri.image(image:newsItem.media.0, width:'1024c', cropVariant:'default')} 1024w"
|
||||
sizes="(max-width: 320px) 100vw,
|
||||
(max-width: 768px) 50vw,
|
||||
400px" />
|
||||
<f:image
|
||||
image="{newsItem.media.0}"
|
||||
treatIdAsReference="1"
|
||||
cropVariant="default"
|
||||
width="1024c"
|
||||
alt="{newsItem.title}"
|
||||
class="news-item-grid-image" />
|
||||
</picture>
|
||||
</f:then>
|
||||
</f:if>
|
||||
<div class="news-item-content">
|
||||
<f:if condition="{newsItem.firstCategory}">
|
||||
<div class="news-item-category">{newsItem.firstCategory.title}</div>
|
||||
</f:if>
|
||||
<time itemprop="datePublished" 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>
|
||||
<h3 class="news-item-title">{newsItem.title}</h3>
|
||||
</div>
|
||||
</f:link.page>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<f:if condition="{pagination.allPageNumbers -> f:count()} > 1">
|
||||
<ul class="f3-widget-paginator">
|
||||
<f:if condition="{pagination.previousPageNumber} && {pagination.previousPageNumber} >= {pagination.firstPageNumber}">
|
||||
<li class="previous">
|
||||
@@ -19,7 +20,7 @@
|
||||
</li>
|
||||
</f:if>
|
||||
<f:for each="{pagination.allPageNumbers}" as="page">
|
||||
<li class="{f:if(condition: page == paginator.currentPageNumber, then:'current')}">
|
||||
<li class="{f:if(condition: '{page} == {paginator.currentPageNumber}', then:'current')}">
|
||||
<a href="{f:uri.action(action:actionName, arguments:{currentPage: page},addQueryString:'untrusted')}">{page}</a>
|
||||
</li>
|
||||
</f:for>
|
||||
@@ -43,3 +44,4 @@
|
||||
</li>
|
||||
</f:if>
|
||||
</ul>
|
||||
</f:if>
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
<f:layout name="General" />
|
||||
|
||||
<f:section name="content">
|
||||
<script>
|
||||
// Initialize Fancybox for elements with data-fancybox="gallery"
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
Fancybox.bind("[data-fancybox='gallery']", {});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- First image if present -->
|
||||
<f:if condition="{newsItem.media}">
|
||||
<div class="news-detail__main-image">
|
||||
<figure>
|
||||
<picture>
|
||||
<source
|
||||
type="image/webp"
|
||||
srcset="{f:uri.image(image: newsItem.media.0.originalResource, width:'320', fileExtension:'webp')} 320w,
|
||||
{f:uri.image(image: newsItem.media.0.originalResource, width:'640', fileExtension:'webp')} 640w,
|
||||
{f:uri.image(image: newsItem.media.0.originalResource, width:'1024', fileExtension:'webp')} 1024w"
|
||||
sizes="(max-width: 320px) 320px, (max-width: 640px) 640px, 1024px"
|
||||
/>
|
||||
<source
|
||||
type="image/jpeg"
|
||||
srcset="{f:uri.image(image: newsItem.media.0.originalResource, width:'320')} 320w,
|
||||
{f:uri.image(image: newsItem.media.0.originalResource, width:'640')} 640w,
|
||||
{f:uri.image(image: newsItem.media.0.originalResource, width:'1024')} 1024w"
|
||||
sizes="(max-width: 320px) 320px, (max-width: 640px) 640px, 1024px"
|
||||
/>
|
||||
<img
|
||||
src="{f:uri.image(image: newsItem.media.0.originalResource, width:'1024')}"
|
||||
alt="{newsItem.media.0.originalResource.alternative}"
|
||||
title="{newsItem.media.0.originalResource.title}"
|
||||
loading="lazy"
|
||||
/>
|
||||
</picture>
|
||||
</figure>
|
||||
</div>
|
||||
</f:if>
|
||||
|
||||
<!-- News title -->
|
||||
<h1 class="news-detail__title">{newsItem.title}</h1>
|
||||
<time class="news-detail__time" itemprop="datePublished" 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>
|
||||
|
||||
|
||||
<!-- Teaser text -->
|
||||
<f:if condition="{newsItem.teaser}">
|
||||
<div class="news-detail__teaser">
|
||||
{newsItem.teaser}
|
||||
</div>
|
||||
</f:if>
|
||||
|
||||
<!-- Bodytext -->
|
||||
<div class="news-detail__bodytext">
|
||||
<f:format.html>
|
||||
{newsItem.bodytext}
|
||||
</f:format.html>
|
||||
</div>
|
||||
|
||||
<!-- Content elements if present -->
|
||||
<f:if condition="{newsItem.contentElements}">
|
||||
<div class="news-detail__content-elements">
|
||||
<f:cObject typoscriptObjectPath="lib.tx_news.contentElementRendering">{newsItem.contentElementIdList}</f:cObject>
|
||||
</div>
|
||||
</f:if>
|
||||
|
||||
<!-- Gallery if more than one picture -->
|
||||
<f:if condition="{f:count(subject: newsItem.media)} > 1">
|
||||
<div class="news-detail__gallery news-detail__gallery--grid">
|
||||
<f:for each="{newsItem.media}" as="mediaItem">
|
||||
<a href="{f:uri.image(image: mediaItem.originalResource)}"
|
||||
data-fancybox="gallery"
|
||||
data-caption="{mediaItem.originalResource.title}"
|
||||
class="news-detail__gallery-link">
|
||||
<figure class="news-detail__gallery-item">
|
||||
<picture>
|
||||
<source
|
||||
type="image/webp"
|
||||
srcset="{f:uri.image(image: mediaItem.originalResource, width:'320', fileExtension:'webp')} 320w,
|
||||
{f:uri.image(image: mediaItem.originalResource, width:'640', fileExtension:'webp')} 640w,
|
||||
{f:uri.image(image: mediaItem.originalResource, width:'1024', fileExtension:'webp')} 1024w"
|
||||
sizes="(max-width: 320px) 320px, (max-width: 640px) 640px, 1024px"
|
||||
/>
|
||||
<source
|
||||
type="image/jpeg"
|
||||
srcset="{f:uri.image(image: mediaItem.originalResource, width:'320')} 320w,
|
||||
{f:uri.image(image: mediaItem.originalResource, width:'640')} 640w,
|
||||
{f:uri.image(image: mediaItem.originalResource, width:'1024')} 1024w"
|
||||
sizes="(max-width: 320px) 320px, (max-width: 640px) 640px, 1024px"
|
||||
/>
|
||||
<img
|
||||
src="{f:uri.image(image: mediaItem.originalResource, width:'1024')}"
|
||||
alt="{mediaItem.originalResource.alternative}"
|
||||
title="{mediaItem.originalResource.title}"
|
||||
loading="lazy"
|
||||
/>
|
||||
</picture>
|
||||
</figure>
|
||||
</a>
|
||||
</f:for>
|
||||
</div>
|
||||
</f:if>
|
||||
</f:section>
|
||||
@@ -25,17 +25,20 @@
|
||||
</f:section>
|
||||
|
||||
<f:section name="content">
|
||||
<div class="header">
|
||||
<div class="title">
|
||||
<h2>{contentObjectData.header}</h2>
|
||||
</div>
|
||||
<f:if condition="{settings.listPid}">
|
||||
<f:then>
|
||||
<f:if condition="{settings.listPid}">
|
||||
<f:then>
|
||||
<div class="header">
|
||||
<div class="title">
|
||||
<h2>{contentObjectData.header}</h2>
|
||||
</div>
|
||||
<!-- Desktop button -->
|
||||
<f:link.page title="Alle Artikel" pageUid="{settings.listPid}" class="btn header-btn">Alle Artikel</f:link.page>
|
||||
</f:then>
|
||||
</f:if>
|
||||
</div>
|
||||
</div>
|
||||
</f:then>
|
||||
<f:else>
|
||||
<h1><span class="tapered">{contentObjectData.header}</span></h1>
|
||||
</f:else>
|
||||
</f:if>
|
||||
<!--TYPO3SEARCH_end-->
|
||||
<f:if condition="{news}">
|
||||
<f:then>
|
||||
|
||||
@@ -9,25 +9,48 @@
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="site-footer__top">
|
||||
<div class="container site-footer__grid">
|
||||
<div class="site-footer__left">
|
||||
<f:cObject typoscriptObjectPath="lib.dynamicContentSlide" data="{pageUid: '{data.uid}', colPos: '90'}" />
|
||||
</div>
|
||||
<div class="site-footer__right">
|
||||
<f:cObject typoscriptObjectPath="lib.dynamicContentSlide" data="{pageUid: '{data.uid}', colPos: '91'}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="site-footer__top">
|
||||
<div class="site-footer__grid">
|
||||
<div class="site-footer__left">
|
||||
<div class="frame site-footer__logo">
|
||||
<div class="container">
|
||||
<f:image src="EXT:base/Resources/Public/Images/greens-efa-logo.png" alt="Greens EFA Logo" />
|
||||
<f:image src="EXT:base/Resources/Public/Images/logo.png" alt="Lena Schilling Logo" />
|
||||
</div>
|
||||
</div>
|
||||
<f:cObject typoscriptObjectPath="lib.dynamicContentSlide" data="{pageUid: '{data.uid}', colPos: '90'}" />
|
||||
</div>
|
||||
<div class="site-footer__right">
|
||||
<f:cObject typoscriptObjectPath="lib.dynamicContentSlide" data="{pageUid: '{data.uid}', colPos: '91'}" />
|
||||
<div class="frame site-footer__social">
|
||||
<div class="container">
|
||||
<a href="https://www.instagram.com/lena.ats/" target="_blank" rel="noopener noreferrer" title="Instagram">
|
||||
<i class="ci ci-instagram"></i>
|
||||
</a>
|
||||
<a href="https://www.tiktok.com/@dieschilling" target="_blank" rel="noopener noreferrer" title="TikTok">
|
||||
<i class="ci ci-tiktok"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="site-footer__divider" />
|
||||
<hr class="site-footer__divider" />
|
||||
|
||||
<div class="site-footer__bottom">
|
||||
<div class="container site-footer__bottom-grid">
|
||||
<ul class="site-footer__legal">
|
||||
<f:cObject typoscriptObjectPath="lib.footerMenu" />
|
||||
</ul>
|
||||
<p class="site-footer__copyright">© All Right Reserved</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="site-footer__bottom">
|
||||
<div class="site-footer__bottom-grid">
|
||||
<ul class="site-footer__legal">
|
||||
<f:for each="{metanavigation}" as="item">
|
||||
<li{f:if(condition: item.active, then:' class="active"')}>
|
||||
<a href="{item.link}"{f:if(condition: '{item.target}', then: ' target="{item.target}"')}{f:if(condition: '{item.target} == "_blank"', then: ' rel="noopener noreferrer"')} title="{item.title}">
|
||||
<span>{item.title}</span>
|
||||
</a>
|
||||
</li>
|
||||
</f:for>
|
||||
</ul>
|
||||
<p class="site-footer__copyright">© All Right Reserved</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
BIN
packages/base/Resources/Public/Favicons/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
packages/base/Resources/Public/Favicons/favicon-96x96.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
packages/base/Resources/Public/Favicons/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
3
packages/base/Resources/Public/Favicons/favicon.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" width="137" height="133"><svg id="SvgjsSvg1005" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 137 133"><defs><style>.cls-1{fill:#f4ad07;}.cls-1,.cls-2{stroke-width:0px;}.cls-2{fill:#233600;}</style></defs><circle class="cls-1" cx="68" cy="66" r="60"></circle><path class="cls-2" d="m98.01,102.96c-.33.17-.65.38-.99.52-.33.13-.68.24-1.03.29-.44.06-2,.22-2.35.3-.17.04-.34.1-.52.12-.96.15-1.92.28-2.88.42-.14.02-2.98.14-3.3.17-.96.08-1.92.18-2.88.22-1.48.06-2.97.08-4.46.1-.44,0-3.01.04-3.84.21-.66.14-1.34.09-2.01.1-1.51.02-10,.11-10.29.08-.73-.06-1.46-.08-2.18-.2,0,0-7.46-.25-7.76-.27-.29-.02-.58-.03-.88-.02h-.01s-.07,0-.11,0c-1.02.04-4.35.03-4.39-.03-.59-.04-1.18-.12-1.76-.26-.55-.13-1.12-.21-1.67-.32-.05-.27-.13-.54-.14-.82-.06-1.75-.19-3.49-.14-5.24.1-3.73-.1-7.47.18-11.2.23-3.05.19-6.11.28-9.17.04-1.41.12-2.81.13-4.22.05-4.66-.24-9.31-.3-13.97-.04-2.77.04-5.54.06-8.3,0-.19.03-.39.02-.58-.1-2.67.24-5.32.24-7.99,0-2.66.07-5.33.11-7.99.01-.87.04-1.74.03-2.61-.04-2.37-.2-4.73-.43-7.08-.05-.48-.05-.97-.09-1.45-.05-.73.02-1.41.33-2.02.19-.37.4-.59.47-.66.31-.31.62-.45.77-.52,1.86-.84,4.8-.72,4.8-.72.4.02,1.08.08,2.44.21.72.07,1.45.18,2.17.22,1.09.06,7.85.87,8.23.94.3.18.75.51,1.08,1.06.23.38.31.82.51,1.65.14.56.25,1.14.3,1.71.07.73.22,3.33.3,3.9.04.29.09.57.12.86.14,1.59.28,3.19.42,4.79.02.24.14,4.96.17,5.49.08,1.6.18,3.2.22,4.8.06,2.47.05,8.87.06,9.6,0,1.41.35,6.44.36,7.55.02,2.51.11,16.64.08,17.12-.06,1.09-.08,2.19-.17,3.28,2.72.03,16.7.02,18.3.01,1.6,0,3.2.07,4.8.11.52.01,1.05.04,1.57.03,1.43-.04,7.11.45,7.3.51.39.13.41.43.46.8.11.72.07,1.41-.07,2.12-.15.79-.16,1.61-.21,2.41-.05.81-.08,1.63-.12,2.44-.04.72-.11,1.45-.13,2.17-.04,1.08-.04,2.17-.07,3.26-.02.98-.78,5.87-1.13,6.05Z"></path></svg><style>@media (prefers-color-scheme: light) { :root { filter: none; } }
|
||||
@media (prefers-color-scheme: dark) { :root { filter: none; } }
|
||||
</style></svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 23 KiB |
BIN
packages/base/Resources/Public/Fonts/Hajime-Sans.woff2
Normal file
BIN
packages/base/Resources/Public/Fonts/Inter.woff2
Normal file
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 52 KiB |
BIN
packages/base/Resources/Public/Images/greens-efa-logo.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 15 KiB |
44
packages/base/Resources/Public/JavaScript/fade-in.js
Normal file
@@ -0,0 +1,44 @@
|
||||
(function() {
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Elements that should fade in when in view
|
||||
var fadeInElements = document.querySelectorAll('.fade-in-on-scroll');
|
||||
|
||||
// If IntersectionObserver is supported, use it for better performance
|
||||
if ('IntersectionObserver' in window) {
|
||||
// Adjusted options to help large elements fade in
|
||||
var observer = new IntersectionObserver(function(entries, observer) {
|
||||
entries.forEach(function(entry) {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('fade-in-visible');
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, {
|
||||
threshold: 0.0,
|
||||
rootMargin: '0px 0px -10% 0px'
|
||||
});
|
||||
|
||||
fadeInElements.forEach(function(el) {
|
||||
el.classList.add('fade-in-hidden');
|
||||
observer.observe(el);
|
||||
});
|
||||
} else {
|
||||
// Fallback if IntersectionObserver is not supported
|
||||
fadeInElements.forEach(function(el) {
|
||||
el.classList.add('fade-in-hidden');
|
||||
});
|
||||
|
||||
var checkVisibility = function() {
|
||||
var windowBottom = window.innerHeight + window.scrollY;
|
||||
fadeInElements.forEach(function(el) {
|
||||
if ((el.getBoundingClientRect().top + window.scrollY) < windowBottom - (el.offsetHeight * 0.1)) {
|
||||
el.classList.add('fade-in-visible');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', checkVisibility);
|
||||
checkVisibility();
|
||||
}
|
||||
});
|
||||
})();
|
||||
19
packages/base/Resources/Public/Scss/abstracts/_fade-in.scss
Normal file
@@ -0,0 +1,19 @@
|
||||
.fade-in-hidden {
|
||||
opacity: 0;
|
||||
transform: translateY(1.5rem);
|
||||
transition: opacity 0.5s ease-out, transform 0.5s ease-out;
|
||||
}
|
||||
.fade-in-visible {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* Respect prefers-reduced-motion: reduce (for accessibility).
|
||||
If user prefers reduced motion, override transitions. */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.fade-in-hidden {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +1,87 @@
|
||||
// The fonts available are OTF and TTF. Modern browsers prefer WOFF/WOFF2,
|
||||
// but we'll use TTF/OTF here.
|
||||
// We assume main.css is compiled into Resources/Public/Css, so to reach Fonts: ../Fonts/
|
||||
// Make sure filenames match exactly (case-sensitive) and spaces are escaped or handled properly.
|
||||
|
||||
// Hajime Sans (no weight variations provided other than normal)
|
||||
// Update font file names and ensure no spaces for better compatibility.
|
||||
@font-face {
|
||||
font-family: 'Hajime Sans';
|
||||
src: url('../Fonts/Hajime Sans.ttf') format('truetype'),
|
||||
url('../Fonts/Hajime Sans.otf') format('opentype');
|
||||
src: url('../Fonts/Hajime-Sans.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
// Inter as a variable font:
|
||||
// The Inter variable fonts likely contain multiple weights.
|
||||
// We'll define one face for normal and one for italic using the variable font files.
|
||||
// Define the weight range if needed (e.g., font-weight: 100 900 for variable range).
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
src: url('../Fonts/Inter-VariableFont_opsz,wght.ttf') format('truetype');
|
||||
src: url('../Fonts/Inter.woff2') format('woff2');
|
||||
font-weight: 100 900; // Adjust as needed for variable font range
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
src: url('../Fonts/Inter-Italic-VariableFont_opsz,wght.ttf') format('truetype');
|
||||
font-weight: 100 900;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
// Use Inter for body text
|
||||
body {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
// Use Hajime Sans for headlines
|
||||
h1, h2, h3 {
|
||||
h1, h2 {
|
||||
font-family: 'Hajime Sans', sans-serif;
|
||||
color: var(--bs-primary);
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: 3rem;
|
||||
|
||||
@media (min-width: $breakpoint-md) {
|
||||
font-size: 4.5rem;
|
||||
}
|
||||
}
|
||||
h1 span.tapered {
|
||||
background-size: 100% 15%;
|
||||
background-repeat: repeat-x;
|
||||
background-position: left 0% bottom 15%;
|
||||
background-image: linear-gradient(179deg,var(--bs-yellow) 0%, var(--bs-yellow) 50%,transparent 54%, transparent 100%);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 4rem;
|
||||
font-size: 2rem;
|
||||
|
||||
@media (min-width: $breakpoint-md) {
|
||||
font-size: 3rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
|
||||
@media (min-width: $breakpoint-md) {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.5rem;
|
||||
font-size: 1.125rem;
|
||||
font-weight: 600;
|
||||
|
||||
@media (min-width: $breakpoint-md) {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--cl-primary);
|
||||
color: var(--bs-primary);
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
|
||||
&:hover {
|
||||
color: var(--bs-primary-light)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Use Hajime Sans for buttons as well
|
||||
button, .btn {
|
||||
font-family: 'Hajime Sans', sans-serif;
|
||||
font-weight: 400;
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
.ci,
|
||||
a[href*="instagram.com"],
|
||||
a[href*="tiktok.com"],
|
||||
a[href*="linkedin.com"],
|
||||
a[href*="twitter.com"],
|
||||
a[href*="x.com"] {
|
||||
.ci {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ci::before,
|
||||
a[href*="instagram.com*"]::before,
|
||||
a[href*="tiktok.com"]::before,
|
||||
a[href*="linkedin.com"]::before,
|
||||
a[href*="x.com"]::before {
|
||||
.ci::before {
|
||||
display: inline-block;
|
||||
content: ' ';
|
||||
width: 1em;
|
||||
@@ -48,22 +39,6 @@ a[href*="x.com"]::before {
|
||||
.ci-phone::before {
|
||||
mask-image: url(../Icons/phone.svg);
|
||||
}
|
||||
|
||||
a[href*="instagram.com*"]::before {
|
||||
mask-image: url(../Icons/instagram.svg);
|
||||
}
|
||||
a[href*="tiktok.com"]::before {
|
||||
mask-image: url(../Icons/tiktok.svg);
|
||||
width: 0.9em;
|
||||
height: 0.9em;
|
||||
}
|
||||
a[href*="linkedin.com"]::before {
|
||||
mask-image: url(../Icons/linkedin.svg);
|
||||
}
|
||||
a[href*="x.com"]::before {
|
||||
mask-image: url(../Icons/x.svg);
|
||||
}
|
||||
|
||||
.ci-angle-right::before {
|
||||
mask-image: url(../Icons/angle-right.svg);
|
||||
}
|
||||
|
||||
@@ -24,8 +24,12 @@ $xl: 1200px;
|
||||
--breakpoint-xl: 1200px;
|
||||
|
||||
--bs-primary: #233600;
|
||||
--bs-primary-dark: #1C2B00;
|
||||
--bs-yellow: #F5AE07;
|
||||
--bs-primary-light: #4E5E32;
|
||||
--bs-light-green: #F4F6EC;
|
||||
--cl-primary: #233600;
|
||||
|
||||
}
|
||||
|
||||
// Additional global variables can be added here
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
body {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
a[href^="tel:"]::before {
|
||||
@extend .ci;
|
||||
@extend .ci-phone;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
a[href^="mailto:"]::before {
|
||||
@extend .ci;
|
||||
@extend .ci-email;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
16
packages/base/Resources/Public/Scss/components/_buttons.scss
Normal file
@@ -0,0 +1,16 @@
|
||||
.btn {
|
||||
background-color: var(--bs-primary);
|
||||
color: var(--bs-yellow);
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-weight: 700;
|
||||
border-radius: .5rem;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--bs-primary-dark);
|
||||
color: var(--bs-yellow);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
.content-element {
|
||||
margin: 2rem auto;
|
||||
padding: 2rem;
|
||||
background-color: #f5f5f5; // default background
|
||||
|
||||
// Apply responsive widths at breakpoints using the respond mixin
|
||||
|
||||
&--blue {
|
||||
background-color: #cceeff;
|
||||
}
|
||||
|
||||
&--gray {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
&--image {
|
||||
background: url('EXT:my_sitepackage/Resources/Public/Images/background-image.jpg') no-repeat center/cover;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
.site-footer {
|
||||
background: #f8f8ea;
|
||||
color: #4b4b4b;
|
||||
font-size: 0.9rem;
|
||||
padding: 2rem 0;
|
||||
|
||||
&__top {
|
||||
padding-bottom: 2rem;
|
||||
> .container {
|
||||
background: var(--bs-light-green);
|
||||
border-top-left-radius: 2rem;
|
||||
border-top-right-radius: 2rem;
|
||||
}
|
||||
|
||||
&__grid {
|
||||
@@ -16,6 +15,26 @@
|
||||
|
||||
&__left, &__right {
|
||||
flex: 1 1 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
> div:first-child {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: .5rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__logo img {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
&__social {
|
||||
a {
|
||||
margin-right: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
|
||||
20
packages/base/Resources/Public/Scss/components/_images.scss
Normal file
@@ -0,0 +1,20 @@
|
||||
a {
|
||||
img {
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
&:hover img {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
|
||||
figure {
|
||||
border-radius: 1rem;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
@@ -6,17 +6,16 @@ $nav-height: 60px; // Adjust as needed
|
||||
// Ensure this path is correct for your TYPO3 installation.
|
||||
// Typically: /typo3conf/ext/<extension_key>/Resources/Public/Images/...
|
||||
|
||||
header {
|
||||
body > header {
|
||||
width: 100%;
|
||||
height: $nav-height;
|
||||
line-height: $nav-height;
|
||||
background: url('../Images/background.jpg') repeat;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.main-nav {
|
||||
background: url('../Images/background.jpg') repeat;
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
@@ -120,6 +119,7 @@ header {
|
||||
@media (max-width: $breakpoint-lg) {
|
||||
.nav-toggle {
|
||||
display: block;
|
||||
margin-left: auto; // move toggle to the right on mobile
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
@@ -130,6 +130,7 @@ header {
|
||||
flex-direction: column;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
background: #fff; // Add white background for mobile dropdown
|
||||
@include transition(max-height, 0.4s);
|
||||
|
||||
.nav-item {
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
.frame-type-news_pi1 h1 {
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
.news-list-view {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
gap: 1rem;
|
||||
grid-auto-rows: auto;
|
||||
margin-bottom: 1rem; /* Ensure space below the news list */
|
||||
|
||||
.news-list-item {
|
||||
grid-column: span 6;
|
||||
@@ -25,7 +29,6 @@
|
||||
grid-column: 5 / span 2;
|
||||
grid-row: 2;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,9 +49,10 @@
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
&.current a {
|
||||
background: lighten($primary-color, 20%);
|
||||
color: $secondary-color;
|
||||
&.current a, a:hover {
|
||||
background: var(--bs-primary);
|
||||
color: var(--bs-yellow);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a {
|
||||
@@ -57,16 +61,10 @@
|
||||
height: 2.5rem;
|
||||
line-height: 2.5rem;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
background: $primary-color;
|
||||
color: $secondary-color;
|
||||
font-weight: bold;
|
||||
border-radius: 0.5rem;
|
||||
background: transparent;
|
||||
text-decoration: none;
|
||||
transition: background 0.3s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
background: lighten($primary-color, 10%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,7 +80,6 @@
|
||||
height: auto;
|
||||
}
|
||||
|
||||
|
||||
a {
|
||||
position: relative;
|
||||
display: flex;
|
||||
@@ -100,21 +97,60 @@
|
||||
color: #fff;
|
||||
border-top-right-radius: 1rem;
|
||||
padding: 1rem;
|
||||
padding-right: 3rem;
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
right: 1.625rem;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
font-size: 1.5rem;
|
||||
display: block;
|
||||
content: ' ';
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
background-color: currentColor;
|
||||
/* vertical-align: middle; */
|
||||
mask-image: url(../Icons/angle-right.svg);
|
||||
}
|
||||
}
|
||||
|
||||
time {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 400;
|
||||
|
||||
@media (min-width: $breakpoint-md) {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.news-list-item-big {
|
||||
picture {
|
||||
@media (min-width: $breakpoint-md) {
|
||||
padding-bottom: .8rem;
|
||||
}
|
||||
}
|
||||
a .news-item-content {
|
||||
@media (min-width: $breakpoint-md) {
|
||||
padding: 2.875rem;
|
||||
padding-right: 5rem;
|
||||
|
||||
&:after {
|
||||
right: 3.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,6 +159,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
/* Show header button only on desktop */
|
||||
@@ -133,10 +170,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Show mobile button only below desktop breakpoint */
|
||||
/* Show mobile button only below desktop breakpoint, inline-block and margin-top */
|
||||
.mobile-btn {
|
||||
display: block;
|
||||
margin-top: 1rem;
|
||||
display: inline-block;
|
||||
@media (min-width: $breakpoint-lg) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
.news-detail__title {
|
||||
max-width: 900px;
|
||||
margin: auto;
|
||||
margin-bottom: 0rem !important;
|
||||
font-size: 3rem;
|
||||
text-align: left;
|
||||
|
||||
@media (min-width: $breakpoint-md) {
|
||||
font-size: 4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.news-detail__time {
|
||||
display: block;
|
||||
max-width: 900px;
|
||||
margin: auto;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.news-detail__main-image {
|
||||
max-width: 900px;
|
||||
margin: auto;
|
||||
margin-bottom: 2rem;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.news-detail__teaser {
|
||||
max-width: 900px;
|
||||
margin: auto;
|
||||
margin-bottom: 2rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.news-detail__bodytext {
|
||||
max-width: 900px;
|
||||
margin: auto;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.news-detail__content-elements {
|
||||
max-width: 900px;
|
||||
margin: auto;
|
||||
|
||||
margin-bottom: 2rem;
|
||||
|
||||
.container {
|
||||
padding: 0;
|
||||
}
|
||||
> * {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.news-detail__gallery {
|
||||
margin-top: 2rem;
|
||||
|
||||
&--grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 1rem;
|
||||
|
||||
.news-detail__gallery-item {
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.news-detail__gallery--grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.news-detail__gallery--grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,11 @@
|
||||
@import 'abstracts/mixins';
|
||||
@import 'abstracts/fonts';
|
||||
@import 'abstracts/icons';
|
||||
@import 'abstracts/fade-in';
|
||||
@import 'base/base';
|
||||
@import 'components/navigation';
|
||||
@import 'components/contentElements';
|
||||
@import 'components/images';
|
||||
@import 'components/news';
|
||||
@import "components/news_detail";
|
||||
@import 'components/footer';
|
||||
@import 'components/buttons';
|
||||
|
||||
1
packages/base/Resources/Public/Vendor/fancybox/fancybox.css
vendored
Normal file
2
packages/base/Resources/Public/Vendor/fancybox/fancybox.umd.js
vendored
Normal file
21
packages/base/Resources/Public/site.webmanifest
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "MyWebSite",
|
||||
"short_name": "MySite",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/web-app-manifest-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "/web-app-manifest-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
||||