feat: many changes
This commit is contained in:
@@ -9,10 +9,11 @@ RTE {
|
|||||||
TCEFORM {
|
TCEFORM {
|
||||||
tt_content {
|
tt_content {
|
||||||
CType {
|
CType {
|
||||||
keepItems = cloonar_text,cloonar_textimage,cloonar_hero,form_formframework
|
keepItems = cloonar_text,cloonar_textimage,cloonar_hero,cloonar_cards,form_formframework
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TCEMAIN {
|
TCEMAIN {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
name: cloonar/cards
|
||||||
|
typeName: cloonar_cards
|
||||||
|
group: default
|
||||||
|
prefixFields: true
|
||||||
|
prefixType: full
|
||||||
|
iconIdentifier: 'content-card-container'
|
||||||
|
fields:
|
||||||
|
-
|
||||||
|
identifier: header
|
||||||
|
useExistingField: true
|
||||||
|
-
|
||||||
|
identifier: bodytext
|
||||||
|
type: Textarea
|
||||||
|
enableRichtext: false
|
||||||
|
useExistingField: true
|
||||||
|
-
|
||||||
|
identifier: cards
|
||||||
|
type: Collection
|
||||||
|
labelField: header
|
||||||
|
fields:
|
||||||
|
-
|
||||||
|
identifier: header
|
||||||
|
type: Text
|
||||||
|
-
|
||||||
|
identifier: bodytext
|
||||||
|
type: Textarea
|
||||||
|
enableRichtext: true
|
||||||
|
rows: 15
|
||||||
|
-
|
||||||
|
identifier: images
|
||||||
|
type: File
|
||||||
|
extendedPalette: false
|
||||||
|
minitems: 1
|
||||||
|
maxitems: 1
|
||||||
|
allowed: common-image-types
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
|
<file datatype="plaintext" original="labels.xlf" source-language="en" date="2024-12-12T00:46:08+00:00" product-name="cloonar/hero">
|
||||||
|
<header/>
|
||||||
|
<body>
|
||||||
|
<trans-unit id="title">
|
||||||
|
<source>Cards</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="description">
|
||||||
|
<source>Card Element will show a list of cards</source>
|
||||||
|
</trans-unit>
|
||||||
|
</body>
|
||||||
|
</file>
|
||||||
|
</xliff>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
|
||||||
|
|
||||||
|
<f:layout name="Default" />
|
||||||
|
|
||||||
|
<f:section name="Main">
|
||||||
|
<strong>Card Container</strong>
|
||||||
|
<f:if condition="{data.header}">
|
||||||
|
<p><strong>Header:</strong> {data.header}</p>
|
||||||
|
</f:if>
|
||||||
|
</f:section>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
|
||||||
|
|
||||||
|
<f:layout name="Default" />
|
||||||
|
|
||||||
|
<f:section name="Header" />
|
||||||
|
|
||||||
|
<f:section name="Main">
|
||||||
|
<div class="card-container">
|
||||||
|
<f:if condition="{data.header}">
|
||||||
|
<h2><f:format.html parseFuncTSPath="lib.parseFunc_RTE">{data.header}</f:format.html></h2>
|
||||||
|
</f:if>
|
||||||
|
<f:if condition="{data.bodytext}">
|
||||||
|
<f:then>
|
||||||
|
<div class="max-w-3xl prose lg:prose-lg">
|
||||||
|
<p>{data.bodytext}</p>
|
||||||
|
</div>
|
||||||
|
</f:then>
|
||||||
|
</f:if>
|
||||||
|
|
||||||
|
<f:if condition="{data.cards}">
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
|
<f:for each="{data.cards}" as="card">
|
||||||
|
<div class="card-flip group perspective" tabindex="0">
|
||||||
|
<div class="card-flip-inner relative w-full h-64 preserve-3d group-hover:rotate-y-180 group-focus:rotate-y-180 duration-500">
|
||||||
|
<div class="card-front absolute w-full h-full backface-hidden overflow-hidden shadow-lg">
|
||||||
|
<f:if condition="{card.images}">
|
||||||
|
<f:then>
|
||||||
|
<f:image image="{card.images.0}" alt="{card.images.0.alternative}" class="w-full h-full object-cover grayscale group-hover:grayscale-0 transition-all duration-500" />
|
||||||
|
</f:then>
|
||||||
|
<f:else>
|
||||||
|
<div class="w-full h-full bg-gray-300 flex items-center justify-center">
|
||||||
|
<span class="text-gray-500">No Image</span>
|
||||||
|
</div>
|
||||||
|
</f:else>
|
||||||
|
</f:if>
|
||||||
|
<div class="absolute inset-0 bg-black bg-opacity-40 flex items-center justify-center">
|
||||||
|
<h3 class="text-white text-xl font-bold text-center p-4">{card.header}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-back absolute w-full h-full backface-hidden rotate-y-180 bg-gray-100 shadow-lg p-6 overflow-y-auto">
|
||||||
|
<h4 class="text-lg font-semibold mb-2">{card.header}</h4>
|
||||||
|
<div class="text-sm">
|
||||||
|
<f:format.html>{card.bodytext}</f:format.html>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</f:for>
|
||||||
|
</div>
|
||||||
|
</f:if>
|
||||||
|
</div>
|
||||||
|
</f:section>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<f:section name="Header" />
|
<f:section name="Header" />
|
||||||
|
|
||||||
<f:section name="Main">
|
<f:section name="Main">
|
||||||
<section class="bg-white md:bg-hero-gradient mb-16">
|
<section class="bg-white md:bg-hero-gradient md:mb-16">
|
||||||
<div class="container mx-auto px-6 py-12 md:py-24 bg-white md:bg-hero-inner">
|
<div class="container mx-auto px-6 py-12 md:py-24 bg-white md:bg-hero-inner">
|
||||||
<div class="md:flex md:items-center">
|
<div class="md:flex md:items-center">
|
||||||
|
|
||||||
@@ -48,9 +48,9 @@
|
|||||||
|
|
||||||
<!-- Down‑arrow, half out on the right edge -->
|
<!-- Down‑arrow, half out on the right edge -->
|
||||||
<div
|
<div
|
||||||
class="absolute top-1/2 -translate-y-1/2 right-[-2rem] z-20">
|
class="absolute top-2/3 -translate-y-1/2 right-[-3rem] z-20">
|
||||||
<a href="#next-section"
|
<a href="#next-section"
|
||||||
class="bg-primary border-4 border-white text-white rounded-full p-5 inline-flex items-center justify-center hover:bg-opacity-90">
|
class="w-24 h-24 text-5xl bg-primary border-8 border-white text-white rounded-full inline-flex items-center justify-center hover:bg-opacity-90">
|
||||||
<span class="sr-only">Scroll down</span>
|
<span class="sr-only">Scroll down</span>
|
||||||
<i class="ci ci-arrow-down"></i>
|
<i class="ci ci-arrow-down"></i>
|
||||||
</a>
|
</a>
|
||||||
@@ -80,13 +80,13 @@
|
|||||||
|
|
||||||
<!-- Social icons -->
|
<!-- Social icons -->
|
||||||
<div class="space-x-3">
|
<div class="space-x-3">
|
||||||
<a href="#" class="bg-primary text-white p-1 rounded-full inline-flex items-center justify-center">
|
<a href="#" class="w-6 h-6 md:w-10 md:h-10 bg-primary text-white rounded-full inline-flex items-center justify-center">
|
||||||
<i class="ci ci-linkedin"></i>
|
<i class="ci ci-linkedin"></i>
|
||||||
</a>
|
</a>
|
||||||
<a href="#" class="bg-primary text-white p-1 rounded-full inline-flex items-center justify-center">
|
<a href="#" class="w-6 h-6 md:w-10 md:h-10 bg-primary text-white rounded-full inline-flex items-center justify-center">
|
||||||
<i class="ci ci-instagram"></i>
|
<i class="ci ci-instagram"></i>
|
||||||
</a>
|
</a>
|
||||||
<a href="#" class="bg-primary text-white p-1 rounded-full inline-flex items-center justify-center">
|
<a href="#" class="w-6 h-6 md:w-10 md:h-10 bg-primary text-white rounded-full inline-flex items-center justify-center">
|
||||||
<i class="ci ci-facebook"></i>
|
<i class="ci ci-facebook"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<f:layout name="Default" />
|
<f:layout name="Default" />
|
||||||
<f:section name="Main">
|
<f:section name="Main">
|
||||||
<div class="fade-in-on-scroll py-16">
|
<div class="fade-in-on-scroll">
|
||||||
<f:if condition="{data.header}">
|
<f:if condition="{data.header}">
|
||||||
<f:then><h2>{data.header}</h2></f:then>
|
<f:then><h2>{data.header}</h2></f:then>
|
||||||
</f:if>
|
</f:if>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<f:variable name="gapClass" value="gap-8 md:gap-16 lg:gap-32" />
|
<f:variable name="gapClass" value="gap-8 md:gap-16 lg:gap-32" />
|
||||||
</f:if>
|
</f:if>
|
||||||
|
|
||||||
<div class="flex flex-col {gapClass} py-16 fade-in-on-scroll {f:if(condition: '{data.imageorient} == 26', then: 'md:flex-row-reverse', else: 'md:flex-row')}">
|
<div class="flex flex-col {gapClass} fade-in-on-scroll {f:if(condition: '{data.imageorient} == 26', then: 'md:flex-row-reverse', else: 'md:flex-row')}">
|
||||||
<div class="flex items-center justify-center {imageSizeClass}">
|
<div class="flex items-center justify-center {imageSizeClass}">
|
||||||
<f:if condition="{data.image}">
|
<f:if condition="{data.image}">
|
||||||
<f:then>
|
<f:then>
|
||||||
|
|||||||
@@ -45,13 +45,13 @@
|
|||||||
<div class="flex space-x-4">
|
<div class="flex space-x-4">
|
||||||
<!-- Social buttons -->
|
<!-- Social buttons -->
|
||||||
|
|
||||||
<a href="#" aria-label="LinkedIn" class="text-2xl bg-white text-primary p-3 rounded-full inline-flex items-center justify-center">
|
<a href="#" aria-label="LinkedIn" class="w-10 h-10 text-2xl bg-white text-primary rounded-full inline-flex items-center justify-center">
|
||||||
<i class="ci ci-linkedin"></i>
|
<i class="ci ci-linkedin"></i>
|
||||||
</a>
|
</a>
|
||||||
<a href="#" aria-label="Instagram" class="text-2xl bg-white text-primary p-3 rounded-full inline-flex items-center justify-center">
|
<a href="#" aria-label="Instagram" class="w-10 h-10 text-2xl bg-white text-primary rounded-full inline-flex items-center justify-center">
|
||||||
<i class="ci ci-instagram"></i>
|
<i class="ci ci-instagram"></i>
|
||||||
</a>
|
</a>
|
||||||
<a href="#" aria-label="Facebook" class="text-2xl bg-white text-primary p-3 rounded-full inline-flex items-center justify-center">
|
<a href="#" aria-label="Facebook" class="w-10 h-10 text-2xl bg-white text-primary rounded-full inline-flex items-center justify-center">
|
||||||
<i class="ci ci-facebook"></i>
|
<i class="ci ci-facebook"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
.container {
|
.container {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
/* padding: 3rem 1rem; */
|
/* padding: 3rem 1rem; */
|
||||||
|
@apply px-4 py-6 md:py-12;
|
||||||
|
|
||||||
@include respond($breakpoint-sm) {
|
@include respond($breakpoint-sm) {
|
||||||
max-width: 540px;
|
max-width: 540px;
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
.card-container {
|
||||||
|
// Container styles if needed
|
||||||
|
}
|
||||||
|
|
||||||
|
.perspective {
|
||||||
|
perspective: 1000px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preserve-3d {
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rotate-y-180 {
|
||||||
|
transform: rotateX(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.backface-hidden {
|
||||||
|
backface-visibility: hidden;
|
||||||
|
-webkit-backface-visibility: hidden; /* Safari */
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the back is initially hidden and rotated
|
||||||
|
.card-back {
|
||||||
|
transform: rotateX(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flip on hover/focus-within the group
|
||||||
|
.group:hover .card-flip-inner,
|
||||||
|
.group:focus-within .card-flip-inner {
|
||||||
|
transform: rotateX(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Style the front overlay and title
|
||||||
|
.card-front {
|
||||||
|
.absolute { // The overlay div
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fade out overlay slightly on hover to reveal image more
|
||||||
|
.group:hover .card-front .absolute {
|
||||||
|
background-color: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional: Hide front title on hover if desired
|
||||||
|
// .group:hover .card-front h3 {
|
||||||
|
// opacity: 0;
|
||||||
|
// }
|
||||||
@@ -1,153 +1,5 @@
|
|||||||
// Define a fixed height for the navigation and apply that as padding-top on the body
|
|
||||||
// so that when it becomes sticky, the content doesn't jump.
|
|
||||||
$nav-height: 60px; // Adjust as needed
|
|
||||||
|
|
||||||
// Use an absolute path to the extension’s public folder to avoid rewriting of URLs by the build process.
|
|
||||||
// Ensure this path is correct for your TYPO3 installation.
|
|
||||||
// Typically: /typo3conf/ext/<extension_key>/Resources/Public/Images/...
|
|
||||||
|
|
||||||
body > header {
|
|
||||||
width: 100%;
|
|
||||||
line-height: $nav-height;
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-nav {
|
.main-nav {
|
||||||
.container {
|
.container {
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin: 0 auto;
|
|
||||||
height: 100%;
|
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-logo {
|
|
||||||
img {
|
|
||||||
display: block;
|
|
||||||
max-height: 50px;
|
|
||||||
height: auto;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-toggle {
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
display: none; // hidden by default on desktop
|
|
||||||
position: relative;
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
|
|
||||||
.nav-toggle-icon {
|
|
||||||
width: 100%;
|
|
||||||
height: 2px;
|
|
||||||
background: $primary-color;
|
|
||||||
display: block;
|
|
||||||
position: relative;
|
|
||||||
@include transition(all, 0.3s);
|
|
||||||
|
|
||||||
&::before,
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
width: 100%;
|
|
||||||
height: 2px;
|
|
||||||
background: $primary-color;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
@include transition(all, 0.3s);
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
top: -8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
top: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active .nav-toggle-icon {
|
|
||||||
background: transparent;
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
transform: rotate(45deg) translate(5px, 5px);
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
transform: rotate(-45deg) translate(5px, -5px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-links {
|
|
||||||
display: flex;
|
|
||||||
list-style: none;
|
|
||||||
align-items: center;
|
|
||||||
margin: auto;
|
|
||||||
|
|
||||||
font-family: 'Hajime Sans', sans-serif;
|
|
||||||
font-size: 1.75rem;
|
|
||||||
|
|
||||||
a {
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item {
|
|
||||||
margin: 0 1rem;
|
|
||||||
|
|
||||||
.nav-link {
|
|
||||||
text-decoration: none;
|
|
||||||
color: $primary-color;
|
|
||||||
font-weight: 700;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.05em;
|
|
||||||
font-size: 1rem;
|
|
||||||
@include transition(color);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $brand-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: $breakpoint-lg) {
|
|
||||||
.nav-toggle {
|
|
||||||
display: block;
|
|
||||||
margin-left: auto; // move toggle to the right on mobile
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-links {
|
|
||||||
position: absolute;
|
|
||||||
top: 100%;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
flex-direction: column;
|
|
||||||
max-height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
background: #fff; // Add white background for mobile dropdown
|
|
||||||
@include transition(max-height, 0.4s);
|
|
||||||
|
|
||||||
.nav-item {
|
|
||||||
margin: 0;
|
|
||||||
padding: 1rem;
|
|
||||||
border-top: 1px solid rgba(0,0,0,0.1);
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
border-top: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.open .nav-links {
|
|
||||||
max-height: 500px; // Adjust to fit all items
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
.frame-type-form_formframework {
|
.frame-type-form_formframework {
|
||||||
@apply py-16;
|
@apply py-6 md:py-12;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
@import 'abstracts/icons';
|
@import 'abstracts/icons';
|
||||||
@import 'abstracts/fade-in';
|
@import 'abstracts/fade-in';
|
||||||
@import 'base/base';
|
@import 'base/base';
|
||||||
/* @import 'components/navigation'; */
|
@import 'components/navigation';
|
||||||
/* @import 'components/images'; */
|
/* @import 'components/images'; */
|
||||||
/* @import 'components/news'; */
|
/* @import 'components/news'; */
|
||||||
/* @import "components/news_detail"; */
|
/* @import "components/news_detail"; */
|
||||||
@@ -17,5 +17,6 @@
|
|||||||
@import 'components/text';
|
@import 'components/text';
|
||||||
@import 'components/buttons';
|
@import 'components/buttons';
|
||||||
@import 'components/form';
|
@import 'components/form';
|
||||||
|
@import 'components/card-container';
|
||||||
@import 'layouts/home-page';
|
@import 'layouts/home-page';
|
||||||
|
|
||||||
|
|||||||
@@ -4,3 +4,18 @@ defined('TYPO3') or die('Access denied.');
|
|||||||
|
|
||||||
// Add default RTE configuration
|
// Add default RTE configuration
|
||||||
$GLOBALS['TYPO3_CONF_VARS']['RTE']['Presets']['base'] = 'EXT:base/Configuration/RTE/Default.yaml';
|
$GLOBALS['TYPO3_CONF_VARS']['RTE']['Presets']['base'] = 'EXT:base/Configuration/RTE/Default.yaml';
|
||||||
|
|
||||||
|
// Register Icon for Content Element "Card Container"
|
||||||
|
$iconRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Imaging\IconRegistry::class);
|
||||||
|
$iconRegistry->registerIcon(
|
||||||
|
'content-card-container', // Icon Identifier
|
||||||
|
\TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class,
|
||||||
|
['source' => 'EXT:base/Resources/Public/Icons/content-card-container.svg']
|
||||||
|
);
|
||||||
|
|
||||||
|
// Register Icon for Card RecordType
|
||||||
|
$iconRegistry->registerIcon(
|
||||||
|
'content-card', // Icon Identifier
|
||||||
|
\TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class,
|
||||||
|
['source' => 'EXT:base/Resources/Public/Icons/content-card.svg']
|
||||||
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user