Compare commits
26 Commits
8279e8a2b5
...
v13.4.14-1
| Author | SHA1 | Date | |
|---|---|---|---|
| 9d4fad0889 | |||
| 9720b9328e | |||
| 177d79ceb1 | |||
| b6ba7f24fe | |||
| 080bf9e186 | |||
| 71d06aabd6 | |||
| b65377dee4 | |||
| c552021c35 | |||
| 1cd8e30a16 | |||
| 6c602a4838 | |||
| 37300492dc | |||
| c4d01f2a47 | |||
| f36e0d7f72 | |||
| e3c7a18505 | |||
| 5effa2d89c | |||
| c2da399a32 | |||
| f5dd861ef1 | |||
| 4a0628e25d | |||
| f1e73d57f6 | |||
| af9b157622 | |||
| 2e0980ca7e | |||
| 592a76737b | |||
| 3fddfdff67 | |||
| edc2cf7634 | |||
| 030053adc3 | |||
| 21586fbc78 |
@@ -16,7 +16,10 @@ web_environment:
|
|||||||
corepack_enable: false
|
corepack_enable: false
|
||||||
nodejs_version: "18"
|
nodejs_version: "18"
|
||||||
|
|
||||||
|
additional_services:
|
||||||
|
- mailpit
|
||||||
hooks:
|
hooks:
|
||||||
post-start:
|
post-start:
|
||||||
- exec: "npm install"
|
- exec-host: |
|
||||||
- exec: "npm run dev:css"
|
ddev npm install
|
||||||
|
ddev npm run dev:css -- --watch &
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
version: '3.6'
|
|
||||||
services:
|
|
||||||
web:
|
|
||||||
# Install needed dependencies and run webpack in watch mode
|
|
||||||
command: /bin/sh -c "npm install && npm run build:css -- --watch"
|
|
||||||
volumes:
|
|
||||||
- ../packages/base:/var/www/html/packages/base
|
|
||||||
environment:
|
|
||||||
- NODE_ENV=development
|
|
||||||
@@ -68,8 +68,8 @@ jobs:
|
|||||||
rm typo3.tar.gz
|
rm typo3.tar.gz
|
||||||
- name: Install ssh agent and rsync
|
- name: Install ssh agent and rsync
|
||||||
run: |
|
run: |
|
||||||
apt update
|
apt-get update
|
||||||
apt install -y openssh-client rsync
|
apt-get install -y openssh-client rsync
|
||||||
- name: Upload release
|
- name: Upload release
|
||||||
uses: deployphp/action@v1
|
uses: deployphp/action@v1
|
||||||
with:
|
with:
|
||||||
@@ -93,8 +93,8 @@ jobs:
|
|||||||
rm typo3.tar.gz
|
rm typo3.tar.gz
|
||||||
- name: Install ssh agent and rsync
|
- name: Install ssh agent and rsync
|
||||||
run: |
|
run: |
|
||||||
apt update
|
apt-get update
|
||||||
apt install -y openssh-client rsync
|
apt-get install -y openssh-client rsync
|
||||||
- name: Switch to release
|
- name: Switch to release
|
||||||
uses: deployphp/action@v1
|
uses: deployphp/action@v1
|
||||||
with:
|
with:
|
||||||
@@ -102,28 +102,28 @@ jobs:
|
|||||||
dep: --file=./build/deploy.php release:switch stage
|
dep: --file=./build/deploy.php release:switch stage
|
||||||
private-key: ${{secrets.STAGE_KEY}}
|
private-key: ${{secrets.STAGE_KEY}}
|
||||||
|
|
||||||
# deploy-production:
|
deploy-production:
|
||||||
# needs: build
|
needs: build
|
||||||
# runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# steps:
|
steps:
|
||||||
# - name: Setup PHP
|
- name: Setup PHP
|
||||||
# uses: shivammathur/setup-php@7c0b4c8c8ebed23eca9ec2802474895d105b11bc
|
uses: shivammathur/setup-php@7c0b4c8c8ebed23eca9ec2802474895d105b11bc
|
||||||
# with:
|
with:
|
||||||
# php-version: ${{ env.PHP_VERSION }}
|
php-version: ${{ env.PHP_VERSION }}
|
||||||
# - uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
# with:
|
with:
|
||||||
# name: typo3
|
name: typo3
|
||||||
# - name: Extract artifact
|
- name: Extract artifact
|
||||||
# run: |
|
run: |
|
||||||
# tar xf typo3.tar.gz
|
tar xf typo3.tar.gz
|
||||||
# rm typo3.tar.gz
|
rm typo3.tar.gz
|
||||||
# - name: Install ssh agent and rsync
|
- name: Install ssh agent and rsync
|
||||||
# run: |
|
run: |
|
||||||
# apt update
|
apt-get update
|
||||||
# apt install -y openssh-client rsync
|
apt-get install -y openssh-client rsync
|
||||||
# - name: Deploy
|
- name: Deploy
|
||||||
# uses: deployphp/action@v1
|
uses: deployphp/action@v1
|
||||||
# with:
|
with:
|
||||||
# deployer-binary: "./bin/dep"
|
deployer-binary: "./bin/dep"
|
||||||
# dep: --file=./build/deploy.php release:create production
|
dep: --file=./build/deploy.php release:create production
|
||||||
# private-key: ${{secrets.PROD_KEY}}
|
private-key: ${{secrets.PROD_KEY}}
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ jobs:
|
|||||||
composer validate --no-check-publish && composer install --prefer-dist --no-progress --ignore-platform-reqs
|
composer validate --no-check-publish && composer install --prefer-dist --no-progress --ignore-platform-reqs
|
||||||
- name: Install ssh agent, rsync
|
- name: Install ssh agent, rsync
|
||||||
run: |
|
run: |
|
||||||
apt update
|
apt-get update
|
||||||
apt install -y openssh-client rsync
|
apt-get install -y openssh-client rsync
|
||||||
- name: Switch to release
|
- name: Switch to release
|
||||||
uses: deployphp/action@v1
|
uses: deployphp/action@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
163
.roo/rules/rules.md
Normal file
163
.roo/rules/rules.md
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
# TYPO3 Project Rules for LLM Assistance
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
This project is a TYPO3 installation with a custom site-package extension located in [`packages/base`](packages/base), providing layout, templates, and modular ContentBlocks for pages. The LLM should dynamically determine the TYPO3 version and related dependencies by examining project files.
|
||||||
|
|
||||||
|
## Technology Stack
|
||||||
|
- PHP (version defined in [`composer.json`](composer.json))
|
||||||
|
- TYPO3 (version defined in [`composer.json`](composer.json))
|
||||||
|
- Composer ([`composer.json`](composer.json))
|
||||||
|
- Deployer ([`build/deploy.php`](build/deploy.php), [`build/servers.yaml`](build/servers.yaml))
|
||||||
|
- Webpack ([`webpack.config.js`](webpack.config.js))
|
||||||
|
- PostCSS ([`postcss.config.js`](postcss.config.js)) with Tailwind CSS (version defined in [`package.json`](package.json)) and Autoprefixer
|
||||||
|
- SCSS (`packages/base/Resources/Public/Scss/`)
|
||||||
|
- JavaScript bundling (`packages/base/Resources/Public/JavaScript/`)
|
||||||
|
- PHPStan, Rector (`phpstan.neon`, `rector.php`)
|
||||||
|
- YAML and TypoScript for configuration
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
- [`config/`](config/): Global TYPO3 config and environment overrides
|
||||||
|
- [`data/`](data/): Database dumps and test fixtures
|
||||||
|
- [`packages/base/`](packages/base/): Site-package extension with design assets, Fluid templates, TypoScript, ContentBlocks
|
||||||
|
- [`public/`](public/): Document root
|
||||||
|
- Build files: [`webpack.config.js`](webpack.config.js), [`postcss.config.js`](postcss.config.js)
|
||||||
|
- Dependency manifests: [`package.json`](package.json), [`composer.json`](composer.json)
|
||||||
|
|
||||||
|
## Development Guidelines
|
||||||
|
- Use DDEV for local environment management: `ddev start`, `ddev restart`, `ddev stop`, etc.
|
||||||
|
- Check versions in [`composer.json`](composer.json) and [`package.json`](package.json) before referencing dependencies; the LLM should examine these files to determine actual versions
|
||||||
|
- Manage PHP dependencies via Composer within DDEV: `ddev exec composer install`, `ddev exec composer update`
|
||||||
|
- Manage JS/CSS via npm within DDEV: `ddev exec npm install`, `ddev exec npm run dev` / `ddev exec npm run build`
|
||||||
|
- Follow TYPO3 extension conventions in [`packages/base`](packages/base): `ext_localconf.php`, `ext_tables.php`, `ext_emconf.php`
|
||||||
|
- Organize TypoScript under [`packages/base/Configuration/Sets/SitePackage/TypoScript/`](packages/base/Configuration/Sets/SitePackage/TypoScript/)
|
||||||
|
- Enforce static analysis and automated refactoring with PHPStan and Rector
|
||||||
|
|
||||||
|
## Default Workflow
|
||||||
|
When handling any task, LLMs should follow this structured approach:
|
||||||
|
|
||||||
|
1. **Information Gathering**
|
||||||
|
- Read the necessary code from the project using available tools
|
||||||
|
- Examine [`composer.json`](composer.json) and [`package.json`](package.json) to understand current dependencies and versions
|
||||||
|
- Use MCP servers to read documentation about libraries that are used and should be used
|
||||||
|
- Review relevant project files to understand the current implementation
|
||||||
|
- Gather context about the specific area of the codebase that will be affected
|
||||||
|
|
||||||
|
2. **Planning**
|
||||||
|
- Analyze the gathered information to understand the task requirements
|
||||||
|
- Plan how the task should be implemented within the existing project structure
|
||||||
|
- Consider potential impacts on other parts of the codebase
|
||||||
|
- Identify which files need to be created, modified, or reviewed
|
||||||
|
- Determine the best approach that follows project conventions and best practices
|
||||||
|
|
||||||
|
3. **Implementation**
|
||||||
|
- Execute the planned task using appropriate tools
|
||||||
|
- Follow the project's coding standards and conventions
|
||||||
|
- Test the implementation where possible
|
||||||
|
- Ensure all changes work within the existing project structure
|
||||||
|
|
||||||
|
4. **Documentation Updates**
|
||||||
|
- Update project documentation (README files) if the task affects user-facing functionality
|
||||||
|
- Update these rules ([`.roo/rules/rules.md`](.roo/rules/rules.md)) if the task introduces new patterns, conventions, or important information that future LLMs should know
|
||||||
|
- Ensure any new features or changes are properly documented for future reference
|
||||||
|
|
||||||
|
This workflow ensures thorough understanding, proper planning, clean implementation, and maintained documentation for all project changes.
|
||||||
|
|
||||||
|
## ContentBlocks Usage
|
||||||
|
- Defined under [`packages/base/ContentBlocks/ContentElements/`](packages/base/ContentBlocks/ContentElements/)
|
||||||
|
- Element folder contains:
|
||||||
|
- `config.yaml` (block definition)
|
||||||
|
- `templates/frontend.html` (frontend rendering)
|
||||||
|
- `templates/backend-preview.html` (backend preview)
|
||||||
|
- `language/labels.xlf` (translations)
|
||||||
|
- To add a new block:
|
||||||
|
1. Create a folder under `ContentElements/`
|
||||||
|
2. Define `config.yaml` and labels
|
||||||
|
3. Add Fluid templates in `templates/`
|
||||||
|
4. Clear caches and verify in TYPO3 backend (`ddev exec vendor/bin/typo3cms cache:flush`)
|
||||||
|
- Content element restrictions:
|
||||||
|
- ContentBlocks are automatically registered via their YAML config files
|
||||||
|
- Availability is controlled through PageTSconfig using `TCEFORM.tt_content.CType.keepItems`
|
||||||
|
- The `keepItems` list in [`packages/base/Configuration/Sets/SitePackage/page.tsconfig`](packages/base/Configuration/Sets/SitePackage/page.tsconfig) determines which content elements editors can use
|
||||||
|
- To enable a new ContentBlock, add its CType to the `keepItems` list
|
||||||
|
- Clear caches after changes
|
||||||
|
|
||||||
|
## Styling Guidelines
|
||||||
|
- All design work lives in the [`packages/base`](packages/base) extension
|
||||||
|
- SCSS structure in `Resources/Public/Scss/`:
|
||||||
|
- `abstracts/` (variables, mixins, functions)
|
||||||
|
- `base/` (resets, global styles)
|
||||||
|
- `components/` (UI modules: buttons, cards, nav, etc.)
|
||||||
|
- `layouts/` (page-specific styles)
|
||||||
|
- Include Tailwind directives in `main.scss`:
|
||||||
|
```scss
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
```
|
||||||
|
- Customize Tailwind in [`tailwind.config.js`](tailwind.config.js)
|
||||||
|
|
||||||
|
## Build Process
|
||||||
|
1. Compile SCSS → PostCSS (Tailwind + Autoprefixer) → CSS in `Resources/Public/Css/` (within DDEV: `ddev exec npm run build:css`)
|
||||||
|
2. Bundle JS via Webpack → `Resources/Public/JavaScript/` (within DDEV: `ddev exec npm run build:js`)
|
||||||
|
3. Run dev mode: `ddev exec npm run dev`
|
||||||
|
4. Run production build: `ddev exec npm run build`
|
||||||
|
5. Deploy via Deployer: `ddev exec vendor/bin/dep deploy`
|
||||||
|
|
||||||
|
## File Editing Guidelines
|
||||||
|
- TypoScript: `packages/base/Configuration/Sets/SitePackage/TypoScript/`
|
||||||
|
- YAML: `packages/base/Configuration/**/*.yaml`
|
||||||
|
- Fluid templates: `packages/base/Resources/Private/**/*.html`
|
||||||
|
- SCSS: `packages/base/Resources/Public/Scss/**/*.scss`
|
||||||
|
- JavaScript: `packages/base/Resources/Public/JavaScript/**/*.js`
|
||||||
|
- Never read or commit the environment file: [`.env`](.env)
|
||||||
|
|
||||||
|
## MCP Server Usage
|
||||||
|
- Use `brave_web_search` for general web searches via `use_mcp_tool`
|
||||||
|
- Use `resolve-library-id` + `get-library-docs` for official API docs:
|
||||||
|
- `/typo3/docs` for TYPO3 reference
|
||||||
|
- `/tailwindcss` for Tailwind CSS docs
|
||||||
|
- For NixOS/Home Manager queries: use `nixos_search`, `home_manager_search`
|
||||||
|
|
||||||
|
## Version Management
|
||||||
|
- Always inspect [`composer.json`](composer.json) for PHP dependencies and TYPO3 version
|
||||||
|
- Always inspect [`package.json`](package.json) for frontend dependencies
|
||||||
|
- Use MCP servers (e.g., `resolve-library-id`, `get-library-docs`) to fetch documentation matching the exact versions found
|
||||||
|
- Never assume specific dependency versions in code examples; dynamically reference versions as discovered
|
||||||
|
|
||||||
|
## Common Tasks
|
||||||
|
1. **Initial Setup**
|
||||||
|
```bash
|
||||||
|
ddev start
|
||||||
|
ddev composer install
|
||||||
|
ddev npm install
|
||||||
|
```
|
||||||
|
2. **Development Build**
|
||||||
|
```bash
|
||||||
|
ddev npm run dev
|
||||||
|
```
|
||||||
|
3. **Production Build**
|
||||||
|
```bash
|
||||||
|
ddev npm run build
|
||||||
|
```
|
||||||
|
4. **Clear TYPO3 Cache**
|
||||||
|
```bash
|
||||||
|
ddev typo3cms cache:flush
|
||||||
|
```
|
||||||
|
5. **Add a ContentBlock**
|
||||||
|
- Create folder, config, templates, translations
|
||||||
|
- Add the new ContentBlock's CType to the `keepItems` list in [`packages/base/Configuration/Sets/SitePackage/page.tsconfig`](packages/base/Configuration/Sets/SitePackage/page.tsconfig)
|
||||||
|
- Clear caches and verify in backend
|
||||||
|
6. **DDEV Environment Management**
|
||||||
|
- Restart environment: `ddev restart`
|
||||||
|
- Stop environment: `ddev stop`
|
||||||
|
7. **Deploy**
|
||||||
|
```bash
|
||||||
|
ddev exec vendor/bin/dep deploy production
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
- **Blank CSS/JS**: confirm build pipeline ran; check [`webpack.config.js`](webpack.config.js)
|
||||||
|
- **YAML Syntax Errors**: validate `config.yaml` with a linter
|
||||||
|
- **Fluid Rendering Issues**: clear caches; verify template paths
|
||||||
|
- **TypoScript Not Loading**: ensure correct path under `Configuration/Sets`
|
||||||
|
- **Cache Problems**: always flush caches after changes
|
||||||
6
ToDo.md
Normal file
6
ToDo.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[x] hero element needs a possibility to set the anchor link for down arrow
|
||||||
|
[x] unordered list design
|
||||||
|
[x] check if marker design of ul and ol use em instead of rem for sizing
|
||||||
|
[x] navbar should be sticky on mobile
|
||||||
|
[ ] disable social media icons
|
||||||
|
[ ] footer links zu datenschutz und impressum
|
||||||
@@ -55,16 +55,16 @@ set('rsync', [
|
|||||||
'timeout' => 300
|
'timeout' => 300
|
||||||
]);
|
]);
|
||||||
|
|
||||||
task('typo3:extension:setup', function () {
|
|
||||||
cd('{{release_path}}');
|
|
||||||
run('{{bin/php}} bin/typo3 extension:setup');
|
|
||||||
});
|
|
||||||
|
|
||||||
task('typo3:cache:flush', function() {
|
task('typo3:cache:flush', function() {
|
||||||
cd('current');
|
cd('current');
|
||||||
run('{{bin/php}} bin/typo3 cache:flush');
|
run('{{bin/php}} bin/typo3 cache:flush');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
task('typo3:extension:setup', function () {
|
||||||
|
cd('{{release_path}}');
|
||||||
|
run('{{bin/php}} bin/typo3 extension:setup');
|
||||||
|
});
|
||||||
|
|
||||||
task('typo3:cache:warmup', function() {
|
task('typo3:cache:warmup', function() {
|
||||||
cd('current');
|
cd('current');
|
||||||
run('{{bin/php}} bin/typo3 cache:warmup');
|
run('{{bin/php}} bin/typo3 cache:warmup');
|
||||||
@@ -94,6 +94,7 @@ task('release:create', [
|
|||||||
'deploy:vendors',
|
'deploy:vendors',
|
||||||
'deploy:shared',
|
'deploy:shared',
|
||||||
'deploy:writable',
|
'deploy:writable',
|
||||||
|
'typo3:cache:flush',
|
||||||
'typo3:extension:setup',
|
'typo3:extension:setup',
|
||||||
'deploy:unlock',
|
'deploy:unlock',
|
||||||
'deploy:success'
|
'deploy:success'
|
||||||
@@ -117,6 +118,7 @@ task('deploy', [
|
|||||||
'deploy:vendors',
|
'deploy:vendors',
|
||||||
'deploy:shared',
|
'deploy:shared',
|
||||||
'deploy:writable',
|
'deploy:writable',
|
||||||
|
'typo3:cache:flush',
|
||||||
'typo3:extension:setup',
|
'typo3:extension:setup',
|
||||||
'deploy:symlink',
|
'deploy:symlink',
|
||||||
'php:reload',
|
'php:reload',
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ $customChanges = [
|
|||||||
'transport_smtp_encrypt' => $_ENV['TYPO3_MAIL_SMTP_ENCRYPT'],
|
'transport_smtp_encrypt' => $_ENV['TYPO3_MAIL_SMTP_ENCRYPT'],
|
||||||
'transport_smtp_username' => $_ENV['TYPO3_MAIL_SMTP_USER'],
|
'transport_smtp_username' => $_ENV['TYPO3_MAIL_SMTP_USER'],
|
||||||
'transport_smtp_password' => $_ENV['TYPO3_MAIL_SMTP_PASSWORD'],
|
'transport_smtp_password' => $_ENV['TYPO3_MAIL_SMTP_PASSWORD'],
|
||||||
|
'transport_sendmail_command' => $_ENV['TYPO3_MAIL_SENDMAIL_COMMAND'],
|
||||||
],
|
],
|
||||||
'SYS' => [
|
'SYS' => [
|
||||||
'caching' => [
|
'caching' => [
|
||||||
|
|||||||
@@ -112,11 +112,14 @@ return [
|
|||||||
'processor_path' => '/run/current-system/sw/bin/',
|
'processor_path' => '/run/current-system/sw/bin/',
|
||||||
],
|
],
|
||||||
'MAIL' => [
|
'MAIL' => [
|
||||||
'defaultMailFromAddress' => 'no-reply@example.com',
|
'defaultMailFromAddress' => $_ENV['TYPO3_MAIL_FROM'],
|
||||||
'transport_smtp_encrypt' => false,
|
'transport' => $_ENV['TYPO3_MAIL_TRANSPORT'],
|
||||||
'transport_smtp_password' => '',
|
'transport_smtp_server' => $_ENV['TYPO3_MAIL_SMTP_SERVER'],
|
||||||
'transport_smtp_server' => '',
|
'transport_smtp_encrypt' => $_ENV['TYPO3_MAIL_SMTP_ENCRYPT'],
|
||||||
'transport_smtp_username' => '',
|
'transport_smtp_username' => $_ENV['TYPO3_MAIL_SMTP_USER'],
|
||||||
|
'transport_smtp_password' => $_ENV['TYPO3_MAIL_SMTP_PASSWORD'],
|
||||||
|
'transport_sendmail_command' => $_ENV['TYPO3_MAIL_SENDMAIL_COMMAND'],
|
||||||
|
'transport_sendmail_command' => $_ENV['TYPO3_MAIL_SENDMAIL_COMMAND'],
|
||||||
],
|
],
|
||||||
'SYS' => [
|
'SYS' => [
|
||||||
'caching' => [
|
'caching' => [
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:css": "NODE_ENV=production webpack --config webpack.config.js --mode production",
|
"build:css": "NODE_ENV=production webpack --config webpack.config.js --mode production",
|
||||||
"dev:css": "webpack --config webpack.config.js --mode development"
|
"dev:css": "webpack --config webpack.config.js --mode development --watch"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer": "^10.4.21",
|
"autoprefixer": "^10.4.21",
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ RTE {
|
|||||||
TCEFORM {
|
TCEFORM {
|
||||||
tt_content {
|
tt_content {
|
||||||
CType {
|
CType {
|
||||||
keepItems = cloonar_text,cloonar_textimage,cloonar_hero,cloonar_cards,form_formframework
|
keepItems = cloonar_text,cloonar_textimage,cloonar_hero,cloonar_cards,cloonar_imagegallery,form_formframework
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,33 @@
|
|||||||
<div class="card-front absolute w-full h-full backface-hidden overflow-hidden shadow-lg">
|
<div class="card-front absolute w-full h-full backface-hidden overflow-hidden shadow-lg">
|
||||||
<f:if condition="{card.images}">
|
<f:if condition="{card.images}">
|
||||||
<f:then>
|
<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" />
|
<picture class="w-full h-full object-cover transition-all duration-500">
|
||||||
|
<!-- WEBP source -->
|
||||||
|
<source
|
||||||
|
type="image/webp"
|
||||||
|
srcset="
|
||||||
|
{f:uri.image(image:card.images.0, width:'320c', cropVariant:'default', fileExtension:'webp')} 320w,
|
||||||
|
{f:uri.image(image:card.images.0, width:'768c', cropVariant:'default', fileExtension:'webp')} 768w,
|
||||||
|
{f:uri.image(image:card.images.0, width:'1024c', cropVariant:'default', fileExtension:'webp')} 1024w"
|
||||||
|
sizes="(max-width: 767px) 90vw,
|
||||||
|
{f:if(condition: '{data.imagesize} == 1', then: '(min-width: 768px) 40vw', else: '(min-width: 768px) 50vw')}" />
|
||||||
|
<!-- Fallback source -->
|
||||||
|
<source
|
||||||
|
srcset="
|
||||||
|
{f:uri.image(image:card.images.0, width:'320c', cropVariant:'default')} 320w,
|
||||||
|
{f:uri.image(image:card.images.0, width:'400c', cropVariant:'default')} 768w,
|
||||||
|
{f:uri.image(image:card.images.0, width:'538c', cropVariant:'default')} 1024w"
|
||||||
|
sizes="(max-width: 767px) 90vw,
|
||||||
|
{f:if(condition: '{data.imagesize} == 1', then: '(min-width: 768px) 40vw', else: '(min-width: 768px) 50vw')}" />
|
||||||
|
<f:image
|
||||||
|
image="{card.images.0}"
|
||||||
|
treatIdAsReference="1"
|
||||||
|
cropVariant="default"
|
||||||
|
width="538c"
|
||||||
|
alt="{card.images.0.alternative}"
|
||||||
|
class="w-full h-full object-cover"
|
||||||
|
/>
|
||||||
|
</picture>
|
||||||
</f:then>
|
</f:then>
|
||||||
<f:else>
|
<f:else>
|
||||||
<div class="w-full h-full bg-gray-300 flex items-center justify-center">
|
<div class="w-full h-full bg-gray-300 flex items-center justify-center">
|
||||||
@@ -33,9 +59,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</f:else>
|
</f:else>
|
||||||
</f:if>
|
</f:if>
|
||||||
<div class="absolute inset-0 bg-black bg-opacity-40 flex flex-col items-center justify-center">
|
<div class="absolute inset-0 bg-white bg-opacity-80 flex flex-col items-center justify-center">
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<h3 class="text-white text-xl font-bold text-center px-4">{card.header}</h3>
|
<h3 class="text-black text-xl font-bold text-center px-4">{card.header}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full text-center">
|
<div class="w-full text-center">
|
||||||
<div class="w-6 h-6 bg-primary text-white rounded-full inline-flex items-center justify-center">
|
<div class="w-6 h-6 bg-primary text-white rounded-full inline-flex items-center justify-center">
|
||||||
@@ -46,7 +72,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-back absolute w-full h-full backface-hidden rotate-y-180 bg-light-grey border border-dark-grey p-6">
|
<div class="card-back absolute w-full h-full backface-hidden rotate-y-180 bg-light-grey border border-dark-grey p-6">
|
||||||
<h4>{card.header}</h4>
|
<h4 class="text-center">{card.header}</h4>
|
||||||
<div class="text-sm">
|
<div class="text-sm">
|
||||||
<f:format.html>{card.bodytext}</f:format.html>
|
<f:format.html>{card.bodytext}</f:format.html>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -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 md:mb-16">
|
<section class="bg-white md:bg-hero-gradient md:mb-16 -mt-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">
|
||||||
|
|
||||||
@@ -78,18 +78,20 @@
|
|||||||
<f:format.html>{data.bodytext}</f:format.html>
|
<f:format.html>{data.bodytext}</f:format.html>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<f:comment>
|
||||||
<!-- Social icons -->
|
<!-- Social icons -->
|
||||||
<div class="space-x-3">
|
<div class="space-x-3">
|
||||||
<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 hover:bg-primary-dark hover:text-white">
|
<a href="#" aria-label="LinkedIn" class="w-6 h-6 md:w-10 md:h-10 bg-primary text-white rounded-full inline-flex items-center justify-center hover:bg-primary-dark hover:text-white">
|
||||||
<i class="ci ci-linkedin"></i>
|
<i class="ci ci-linkedin"></i>
|
||||||
</a>
|
</a>
|
||||||
<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 hover:bg-primary-dark hover:text-white">
|
<a href="#" aria-label="Instagram" class="w-6 h-6 md:w-10 md:h-10 bg-primary text-white rounded-full inline-flex items-center justify-center hover:bg-primary-dark hover:text-white">
|
||||||
<i class="ci ci-instagram"></i>
|
<i class="ci ci-instagram"></i>
|
||||||
</a>
|
</a>
|
||||||
<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 hover:bg-primary-dark hover:text-white">
|
<a href="#" aria-label="Facebook" class="w-6 h-6 md:w-10 md:h-10 bg-primary text-white rounded-full inline-flex items-center justify-center hover:bg-primary-dark hover:text-white">
|
||||||
<i class="ci ci-facebook"></i>
|
<i class="ci ci-facebook"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
</f:comment>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
name: cloonar/imagegallery
|
||||||
|
typeName: cloonar_imagegallery
|
||||||
|
group: default
|
||||||
|
prefixFields: false
|
||||||
|
fields:
|
||||||
|
- identifier: header
|
||||||
|
useExistingField: true
|
||||||
|
- identifier: image
|
||||||
|
type: File
|
||||||
|
properties:
|
||||||
|
allowed: [jpg, jpeg, png, gif, webp]
|
||||||
|
multiple: true
|
||||||
|
useExistingField: true
|
||||||
|
- identifier: columns
|
||||||
|
type: Select
|
||||||
|
renderType: selectSingle
|
||||||
|
default: 1
|
||||||
|
items:
|
||||||
|
- label: LLL:EXT:base/ContentBlocks/ContentElements/imagegallery/language/labels.xlf:columns.1
|
||||||
|
value: 1
|
||||||
|
- label: LLL:EXT:base/ContentBlocks/ContentElements/imagegallery/language/labels.xlf:columns.2
|
||||||
|
value: 2
|
||||||
|
- label: LLL:EXT:base/ContentBlocks/ContentElements/imagegallery/language/labels.xlf:columns.3
|
||||||
|
value: 3
|
||||||
|
- label: LLL:EXT:base/ContentBlocks/ContentElements/imagegallery/language/labels.xlf:columns.5
|
||||||
|
value: 5
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?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" product-name="cloonar/imagegallery">
|
||||||
|
<header/>
|
||||||
|
<body>
|
||||||
|
<trans-unit id="title">
|
||||||
|
<source>Image Gallery</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="description">
|
||||||
|
<source>A gallery of images with configurable columns</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="columns.1">
|
||||||
|
<source>1 Column</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="columns.2">
|
||||||
|
<source>2 Columns</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="columns.3">
|
||||||
|
<source>3 Columns</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="columns.5">
|
||||||
|
<source>5 Columns</source>
|
||||||
|
</trans-unit>
|
||||||
|
</body>
|
||||||
|
</file>
|
||||||
|
</xliff>
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<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.image}">
|
||||||
|
<div class="row">
|
||||||
|
<f:for each="{data.image}" as="image" iteration="iterator">
|
||||||
|
<f:if condition="{iterator.index} < 3">
|
||||||
|
<div class="col-4">
|
||||||
|
<f:image image="{image}" width="100" height="auto" treatIdAsReference="1" alt="Preview image" />
|
||||||
|
</div>
|
||||||
|
</f:if>
|
||||||
|
</f:for>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
<f:switch expression="{data.columns}">
|
||||||
|
<f:case value="2">2 Columns</f:case>
|
||||||
|
<f:case value="3">3 Columns</f:case>
|
||||||
|
<f:case value="5">5 Columns</f:case>
|
||||||
|
<f:defaultCase>1 Column</f:defaultCase>
|
||||||
|
</f:switch>
|
||||||
|
</p>
|
||||||
|
</f:if>
|
||||||
|
</f:section>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<f:layout name="Default" />
|
||||||
|
<f:section name="Header"></f:section>
|
||||||
|
<f:section name="Main">
|
||||||
|
<f:if condition="{data.header}">
|
||||||
|
<h2 class="text-center mb-8">{data.header}</h2>
|
||||||
|
</f:if>
|
||||||
|
|
||||||
|
<f:if condition="{data.image}">
|
||||||
|
<f:variable name="columnClass">
|
||||||
|
<f:switch expression="{data.columns}">
|
||||||
|
<f:case value="2">md:grid-cols-2</f:case>
|
||||||
|
<f:case value="3">md:grid-cols-3</f:case>
|
||||||
|
<f:case value="5">md:grid-cols-5</f:case>
|
||||||
|
<f:defaultCase>md:grid-cols-1</f:defaultCase>
|
||||||
|
</f:switch>
|
||||||
|
</f:variable>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 {columnClass} gap-6 md:gap-8">
|
||||||
|
<f:for each="{data.image}" as="image">
|
||||||
|
<div class="relative">
|
||||||
|
<f:if condition="{image.link}">
|
||||||
|
<f:then>
|
||||||
|
<f:link.typolink parameter="{image.link}" class="block w-full h-full">
|
||||||
|
<picture class="block w-full h-full">
|
||||||
|
<source
|
||||||
|
type="image/webp"
|
||||||
|
srcset="{f:uri.image(image:image, width:'320', cropVariant:'default', fileExtension:'webp')} 320w,
|
||||||
|
{f:uri.image(image:image, width:'768', cropVariant:'default', fileExtension:'webp')} 768w"
|
||||||
|
sizes="(max-width: 767px) 90vw, 33vw" />
|
||||||
|
<img
|
||||||
|
src="{f:uri.image(image:image, width:'768', cropVariant:'default')}"
|
||||||
|
srcset="{f:uri.image(image:image, width:'320', cropVariant:'default')} 320w,
|
||||||
|
{f:uri.image(image:image, width:'768', cropVariant:'default')} 768w"
|
||||||
|
sizes="(max-width: 767px) 90vw, 33vw"
|
||||||
|
alt="{image.alternative}"
|
||||||
|
class="w-full h-full object-cover"
|
||||||
|
/>
|
||||||
|
</picture>
|
||||||
|
</f:link.typolink>
|
||||||
|
</f:then>
|
||||||
|
<f:else>
|
||||||
|
<picture class="block w-full h-full">
|
||||||
|
<source
|
||||||
|
type="image/webp"
|
||||||
|
srcset="{f:uri.image(image:image, width:'320', cropVariant:'default', fileExtension:'webp')} 320w,
|
||||||
|
{f:uri.image(image:image, width:'768', cropVariant:'default', fileExtension:'webp')} 768w"
|
||||||
|
sizes="(max-width: 767px) 90vw, 33vw" />
|
||||||
|
<img
|
||||||
|
src="{f:uri.image(image:image, width:'768', cropVariant:'default')}"
|
||||||
|
srcset="{f:uri.image(image:image, width:'320', cropVariant:'default')} 320w,
|
||||||
|
{f:uri.image(image:image, width:'768', cropVariant:'default')} 768w"
|
||||||
|
sizes="(max-width: 767px) 90vw, 33vw"
|
||||||
|
alt="{image.alternative}"
|
||||||
|
class="w-full h-full object-cover"
|
||||||
|
/>
|
||||||
|
</picture>
|
||||||
|
</f:else>
|
||||||
|
</f:if>
|
||||||
|
</div>
|
||||||
|
</f:for>
|
||||||
|
</div>
|
||||||
|
</f:if>
|
||||||
|
</f:section>
|
||||||
@@ -21,9 +21,11 @@ fields:
|
|||||||
- identifier: imagesize
|
- identifier: imagesize
|
||||||
type: Select
|
type: Select
|
||||||
renderType: selectSingle
|
renderType: selectSingle
|
||||||
default: 2
|
default: 3
|
||||||
items:
|
items:
|
||||||
- label: 25%
|
- label: 25%
|
||||||
value: 1
|
value: 1
|
||||||
- label: 50%
|
- label: 33%
|
||||||
value: 2
|
value: 2
|
||||||
|
- label: 50%
|
||||||
|
value: 3
|
||||||
@@ -5,10 +5,16 @@
|
|||||||
<f:variable name="textSizeClass" value="md:w-1/2" />
|
<f:variable name="textSizeClass" value="md:w-1/2" />
|
||||||
<f:variable name="gapClass" value="gap-8 md:gap-16" />
|
<f:variable name="gapClass" value="gap-8 md:gap-16" />
|
||||||
|
|
||||||
<f:if condition="{data.imagesize} == 1"> <!-- Size 25% -> map to 40% for layout -->
|
<f:if condition="{data.imagesize} == 1"> <!-- Size 25% -->
|
||||||
<f:variable name="imageSizeClass" value="md:w-2/5" />
|
<f:variable name="imageSizeClass" value="md:w-1/4" />
|
||||||
<f:variable name="textSizeClass" value="md:w-3/5" />
|
<f:variable name="textSizeClass" value="md:w-3/4" />
|
||||||
<f:variable name="gapClass" value="gap-8 md:gap-16 lg:gap-32" />
|
<f:variable name="gapClass" value="gap-6 md:gap-12" />
|
||||||
|
</f:if>
|
||||||
|
|
||||||
|
<f:if condition="{data.imagesize} == 2"> <!-- Size 33% -->
|
||||||
|
<f:variable name="imageSizeClass" value="md:w-1/3" />
|
||||||
|
<f:variable name="textSizeClass" value="md:w-2/3" />
|
||||||
|
<f:variable name="gapClass" value="gap-8 md:gap-16" />
|
||||||
</f:if>
|
</f:if>
|
||||||
|
|
||||||
<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 flex-col {gapClass} fade-in-on-scroll {f:if(condition: '{data.imageorient} == 26', then: 'md:flex-row-reverse', else: 'md:flex-row')}">
|
||||||
@@ -24,7 +30,11 @@
|
|||||||
{f:uri.image(image:data.image.0, width:'768c', cropVariant:'default', fileExtension:'webp')} 768w,
|
{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"
|
{f:uri.image(image:data.image.0, width:'1024c', cropVariant:'default', fileExtension:'webp')} 1024w"
|
||||||
sizes="(max-width: 767px) 90vw,
|
sizes="(max-width: 767px) 90vw,
|
||||||
{f:if(condition: '{data.imagesize} == 1', then: '(min-width: 768px) 40vw', else: '(min-width: 768px) 50vw')}" />
|
{f:if(condition: '{data.imagesize} == 1',
|
||||||
|
then: '(min-width: 768px) 25vw',
|
||||||
|
else: f:if(condition: '{data.imagesize} == 2',
|
||||||
|
then: '(min-width: 768px) 33vw',
|
||||||
|
else: '(min-width: 768px) 50vw'))}" />
|
||||||
<!-- Fallback source -->
|
<!-- Fallback source -->
|
||||||
<source
|
<source
|
||||||
srcset="
|
srcset="
|
||||||
@@ -32,7 +42,11 @@
|
|||||||
{f:uri.image(image:data.image.0, width:'400c', cropVariant:'default')} 768w,
|
{f:uri.image(image:data.image.0, width:'400c', cropVariant:'default')} 768w,
|
||||||
{f:uri.image(image:data.image.0, width:'538c', cropVariant:'default')} 1024w"
|
{f:uri.image(image:data.image.0, width:'538c', cropVariant:'default')} 1024w"
|
||||||
sizes="(max-width: 767px) 90vw,
|
sizes="(max-width: 767px) 90vw,
|
||||||
{f:if(condition: '{data.imagesize} == 1', then: '(min-width: 768px) 40vw', else: '(min-width: 768px) 50vw')}" />
|
{f:if(condition: '{data.imagesize} == 1',
|
||||||
|
then: '(min-width: 768px) 25vw',
|
||||||
|
else: f:if(condition: '{data.imagesize} == 2',
|
||||||
|
then: '(min-width: 768px) 33vw',
|
||||||
|
else: '(min-width: 768px) 50vw'))}" />
|
||||||
<f:image
|
<f:image
|
||||||
image="{data.image.0}"
|
image="{data.image.0}"
|
||||||
treatIdAsReference="1"
|
treatIdAsReference="1"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<header>
|
<header class="sticky top-0 left-0 right-0 z-50 bg-primary text-white">
|
||||||
<!-- Main Navigation -->
|
<!-- Main Navigation -->
|
||||||
<f:render partial="Navigation/Main" arguments="{_all}" />
|
<f:render partial="Navigation/Main" arguments="{_all}" />
|
||||||
</header>
|
</header>
|
||||||
@@ -22,26 +22,27 @@
|
|||||||
|
|
||||||
<!-- Kontaktiere uns -->
|
<!-- Kontaktiere uns -->
|
||||||
<div>
|
<div>
|
||||||
<h5 class="text-white">Kontaktiere uns</h5>
|
<h3 class="text-white text-sm">Kontaktiere uns</h3>
|
||||||
<ul class="space-y-4">
|
<ul class="space-y-4">
|
||||||
<li class="flex items-center">
|
<li class="flex items-center pl-0">
|
||||||
<!-- mail -->
|
<!-- mail -->
|
||||||
<a href="mailto:inquiry@dialogrelations.com" class="hover:text-white text-white">
|
<a href="mailto:office@dialog-relations.at" class="hover:text-white text-white">
|
||||||
inquiry@dialogrelations.com
|
office@dialog-relations.at
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="flex items-center">
|
<li class="flex items-center pl-0">
|
||||||
<!-- phone -->
|
<!-- phone -->
|
||||||
<a href="tel:+4312313435" class="hover:text-white text-white">
|
<a href="tel:+436763533669" class="hover:text-white text-white">
|
||||||
+43 1231 3435
|
+43 676 3533669
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<f:comment>
|
||||||
<!-- Folge uns -->
|
<!-- Folge uns -->
|
||||||
<div class="flex flex-col items-start md:items-end">
|
<div class="flex flex-col items-start md:items-end">
|
||||||
<h5 class="text-white">Folge uns</h5>
|
<h3 class="text-white text-sm">Folge uns</h3>
|
||||||
<div class="flex space-x-4">
|
<div class="flex space-x-4">
|
||||||
<!-- Social buttons -->
|
<!-- Social buttons -->
|
||||||
|
|
||||||
@@ -56,6 +57,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</f:comment>
|
||||||
|
|
||||||
</div><!-- /Row 1 -->
|
</div><!-- /Row 1 -->
|
||||||
|
|
||||||
@@ -70,9 +72,9 @@
|
|||||||
|
|
||||||
<!-- Privacy links -->
|
<!-- Privacy links -->
|
||||||
<p>
|
<p>
|
||||||
<a href="#" class="hover:text-white text-white">Privacy Policy</a>
|
<a href="/datenschutz" class="hover:text-white text-white">Datenschutz</a>
|
||||||
<span class="mx-1">|</span>
|
<span class="mx-1">|</span>
|
||||||
<a href="#" class="hover:text-white text-white">Terms and Conditions</a>
|
<a href="/impressum" class="hover:text-white text-white">Impressum</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
</div><!-- /Row 2 -->
|
</div><!-- /Row 2 -->
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<nav class="py-1 main-nav group sticky top-0 z-50 bg-repeat" id="mainNav">
|
<nav class="py-1 main-nav group" id="mainNav">
|
||||||
<div class="container flex items-center h-full mx-auto px-4">
|
<div class="container flex items-center h-full mx-auto px-4">
|
||||||
<a href="/" class="nav-logo">
|
<a href="/" class="nav-logo">
|
||||||
<f:image src="EXT:base/Resources/Public/Images/logo.svg" alt="Logo" class="block max-h-[50px] h-auto w-auto" />
|
<f:image src="EXT:base/Resources/Public/Images/logo.svg" alt="Logo" class="block max-h-[50px] h-auto w-auto" />
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
absolute top-full left-0 right-0 flex-col max-h-0 overflow-hidden bg-white transition-max-height duration-400 ease-in-out group-[.open]:max-h-[500px]" id="navLinks">
|
absolute top-full left-0 right-0 flex-col max-h-0 overflow-hidden bg-white transition-max-height duration-400 ease-in-out group-[.open]:max-h-[500px]" id="navLinks">
|
||||||
<f:for each="{mainnavigation}" as="mainnavigationItem">
|
<f:for each="{mainnavigation}" as="mainnavigationItem">
|
||||||
<li class="nav-item lg:mx-4 lg:my-0 lg:p-0 lg:border-0 mx-0 my-0 p-4 border-t border-black/10 first:border-t-0 {f:if(condition: mainnavigationItem.active, then:' active')}">
|
<li class="nav-item lg:mx-4 lg:my-0 lg:p-0 lg:border-0 mx-0 my-0 p-4 border-t border-black/10 first:border-t-0 {f:if(condition: mainnavigationItem.active, then:' active')}">
|
||||||
<a href="{mainnavigationItem.link}" title="{mainnavigationItem.title}" class="nav-link block lg:inline-block no-underline text-primary lg:text-white font-bold uppercase tracking-[0.05em] text-sm transition-colors duration-300 hover:text-primary lg:hover:text-white">
|
<a href="{mainnavigationItem.link}" title="{mainnavigationItem.title}" class="nav-link block lg:inline-block no-underline text-primary lg:text-white font-bold uppercase tracking-[0.05em] text-sm md:text-base transition-colors duration-300 hover:text-primary lg:hover:text-white">
|
||||||
{mainnavigationItem.title}
|
{mainnavigationItem.title}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
3
packages/base/Resources/Public/Icons/check.svg
Normal file
3
packages/base/Resources/Public/Icons/check.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M20 6L9 17L4 12" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 210 B |
@@ -17,26 +17,28 @@
|
|||||||
margin-top: 0.125em;
|
margin-top: 0.125em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.ci-instagram::before {
|
.ci-instagram::before {
|
||||||
mask-image: url(../Icons/instagram.svg);
|
mask-image: url(../Icons/instagram.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ci-linkedin::before {
|
.ci-linkedin::before {
|
||||||
mask-image: url(../Icons/linkedin.svg);
|
mask-image: url(../Icons/linkedin.svg);
|
||||||
width: 0.9em;
|
width: 0.9em;
|
||||||
height: 0.9em;
|
height: 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ci-facebook::before {
|
.ci-facebook::before {
|
||||||
mask-image: url(../Icons/facebook.svg);
|
mask-image: url(../Icons/facebook.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ci-arrow-down::before {
|
.ci-arrow-down::before {
|
||||||
mask-image: url(../Icons/arrow-down.svg);
|
mask-image: url(../Icons/arrow-down.svg);
|
||||||
}
|
}
|
||||||
.ci-arrow-up-right::before {
|
.ci-arrow-up-right::before {
|
||||||
mask-image: url(../Icons/arrow-up-right.svg);
|
mask-image: url(../Icons/arrow-up-right.svg);
|
||||||
}
|
}
|
||||||
|
.ci-check::before {
|
||||||
|
mask-image: url(../Icons/check.svg);
|
||||||
|
}
|
||||||
.ci-email::before {
|
.ci-email::before {
|
||||||
mask-image: url(../Icons/email.svg);
|
mask-image: url(../Icons/email.svg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,4 +2,10 @@
|
|||||||
.container {
|
.container {
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
::before {
|
||||||
|
@apply hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
$marker-size: 1.5rem;
|
$marker-size: 1.5em;
|
||||||
$gap-y: 2rem;
|
$gap-y: 2em;
|
||||||
|
|
||||||
ol {
|
ol {
|
||||||
@apply list-none m-0 p-0;
|
@apply list-none m-0 p-0;
|
||||||
@@ -7,7 +7,7 @@ ol {
|
|||||||
|
|
||||||
> li {
|
> li {
|
||||||
@apply relative;
|
@apply relative;
|
||||||
padding-left: calc(#{$marker-size} + .5rem);
|
padding-left: calc(#{$marker-size} + .5em);
|
||||||
margin-bottom: $gap-y;
|
margin-bottom: $gap-y;
|
||||||
counter-increment: step;
|
counter-increment: step;
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ ol {
|
|||||||
&::before {
|
&::before {
|
||||||
content: counter(step, decimal-leading-zero);
|
content: counter(step, decimal-leading-zero);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: .2rem;
|
top: .2em;
|
||||||
left: 0;
|
left: 0;
|
||||||
@apply text-primary font-bold text-2xl leading-none;
|
@apply text-primary font-bold text-2xl leading-none;
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ ol {
|
|||||||
&::after {
|
&::after {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: calc(#{$marker-size} + .5rem);
|
top: calc(#{$marker-size} + .5em);
|
||||||
bottom: -$gap-y; // extend past the li’s bottom margin
|
bottom: -$gap-y; // extend past the li’s bottom margin
|
||||||
left: calc(#{$marker-size} / 2);
|
left: calc(#{$marker-size} / 2);
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
@@ -41,3 +41,18 @@ ol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
@apply list-none m-0 p-0;
|
||||||
|
|
||||||
|
> li {
|
||||||
|
@apply relative pl-8 mb-4; // Adjust padding-left based on icon size + desired gap
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
@extend .ci; // Inherit base icon styles
|
||||||
|
@extend .ci-check; // Use the check icon
|
||||||
|
@apply absolute left-0 top-1 text-primary; // Position and color the icon
|
||||||
|
// Adjust 'top' value as needed for vertical alignment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,24 +2,11 @@
|
|||||||
|
|
||||||
.backendlayout-home_page {
|
.backendlayout-home_page {
|
||||||
|
|
||||||
// --- Target the header element ---
|
|
||||||
header {
|
header {
|
||||||
// --- Mobile First: Always Primary Background ---
|
|
||||||
@apply bg-primary text-white;
|
|
||||||
|
|
||||||
// Mobile link/icon colors (on primary background)
|
|
||||||
#mainNav .nav-link { // Target links within #mainNav
|
|
||||||
@apply text-primary lg:text-white lg:hover:text-gray-200;
|
|
||||||
}
|
|
||||||
// Adjust mobile submenu link colors if needed (depends on dropdown background)
|
|
||||||
#mainNav .sub-menu .nav-link {
|
|
||||||
@apply text-gray-700 hover:text-black; // Assuming light dropdown background
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Desktop Styles ---
|
// --- Desktop Styles ---
|
||||||
@screen lg {
|
@screen lg {
|
||||||
// Initial state: Transparent background, fixed position
|
// Initial state: Transparent background, fixed position
|
||||||
@apply fixed top-0 left-0 right-0 z-50 bg-transparent transition-colors duration-300 ease-in-out;
|
@apply bg-transparent transition-colors duration-300 ease-in-out;
|
||||||
|
|
||||||
// Initial link colors and background for transparent header (desktop)
|
// Initial link colors and background for transparent header (desktop)
|
||||||
#mainNav .nav-link {
|
#mainNav .nav-link {
|
||||||
@@ -49,11 +36,3 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Default styles for header on NON-home pages ---
|
|
||||||
// Ensures header has a background and correct colors on other pages
|
|
||||||
body:not(.backendlayout-home_page) {
|
|
||||||
header {
|
|
||||||
@apply bg-primary text-white; // Or your desired default background/text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user