feat: add section content editing, animation selection and HTML5 drag & drop in live editor
All checks were successful
Production Build & Deploy / build-and-deploy (push) Successful in 1m0s
All checks were successful
Production Build & Deploy / build-and-deploy (push) Successful in 1m0s
This commit is contained in:
@@ -8,7 +8,7 @@ interface Props {
|
|||||||
const { config } = Astro.props;
|
const { config } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<section id="services" class="py-20 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto relative">
|
<section id="services" class={`py-20 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto relative ${config.animation ? `anim-${config.animation}` : ''}`}>
|
||||||
<div class="text-center max-w-3xl mx-auto mb-16 space-y-3">
|
<div class="text-center max-w-3xl mx-auto mb-16 space-y-3">
|
||||||
<h2 class="text-3xl font-extrabold text-white tracking-tight uppercase">{config.sectionTitle}</h2>
|
<h2 class="text-3xl font-extrabold text-white tracking-tight uppercase">{config.sectionTitle}</h2>
|
||||||
<p class="text-slate-400 text-xs sm:text-sm">{config.sectionSubtitle}</p>
|
<p class="text-slate-400 text-xs sm:text-sm">{config.sectionSubtitle}</p>
|
||||||
@@ -16,7 +16,7 @@ const { config } = Astro.props;
|
|||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||||
{config.cards.map((card) => (
|
{config.cards.map((card) => (
|
||||||
<div class={`relative glass-panel glass-panel-hover rounded-2xl p-8 flex flex-col justify-between overflow-hidden group ${card.colSpan === 2 ? 'md:col-span-2' : 'md:col-span-1'}`}>
|
<div class={`relative glass-panel glass-panel-hover rounded-2xl p-8 flex flex-col justify-between overflow-hidden group ${card.colSpan === 2 ? 'md:col-span-2' : 'md:col-span-1'} ${card.animation ? `anim-${card.animation}` : ''}`}>
|
||||||
<div class="space-y-4 relative z-10">
|
<div class="space-y-4 relative z-10">
|
||||||
{card.badge && (
|
{card.badge && (
|
||||||
<span class="inline-block text-[10px] font-mono uppercase tracking-wider text-sky-400 bg-sky-400/10 px-2.5 py-1 rounded border border-sky-400/20">
|
<span class="inline-block text-[10px] font-mono uppercase tracking-wider text-sky-400 bg-sky-400/10 px-2.5 py-1 rounded border border-sky-400/20">
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const actionElements = elements.filter((el: UIComponent) => el.slotId === 'hero-
|
|||||||
const customElements = elements.filter((el: UIComponent) => !el.slotId || el.slotId === 'hero-custom-slot');
|
const customElements = elements.filter((el: UIComponent) => !el.slotId || el.slotId === 'hero-custom-slot');
|
||||||
---
|
---
|
||||||
|
|
||||||
<section class="relative py-24 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto overflow-hidden">
|
<section class={`relative py-24 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto overflow-hidden ${config.animation ? `anim-${config.animation}` : ''}`}>
|
||||||
<span class="aurora-glow aurora-glow-sky w-[500px] h-[500px] -top-32 -left-32"></span>
|
<span class="aurora-glow aurora-glow-sky w-[500px] h-[500px] -top-32 -left-32"></span>
|
||||||
<span class="aurora-glow aurora-glow-indigo w-[400px] h-[400px] bottom-0 right-0"></span>
|
<span class="aurora-glow aurora-glow-indigo w-[400px] h-[400px] bottom-0 right-0"></span>
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ const customElements = elements.filter((el: UIComponent) => !el.slotId || el.slo
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{badgeElements.map(el => (
|
{badgeElements.map(el => (
|
||||||
<span class="inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full border border-sky-400/30 bg-sky-400/20 text-sky-300 text-xs font-mono">
|
<span class={`inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full border border-sky-400/30 bg-sky-400/20 text-sky-300 text-xs font-mono ${el.animation0 ? `anim-${el.animation0}` : ''}`}>
|
||||||
{el.content}
|
{el.content}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
@@ -54,7 +54,7 @@ const customElements = elements.filter((el: UIComponent) => !el.slotId || el.slo
|
|||||||
</a>
|
</a>
|
||||||
)}
|
)}
|
||||||
{actionElements.map(el => (
|
{actionElements.map(el => (
|
||||||
<a href={el.link || '#'} class={`px-8 py-3.5 rounded-xl font-bold text-xs transition-all active:scale-95 ${el.style === 'glass' ? 'glass-panel text-white' : 'bg-sky-400 text-slate-950 hover:bg-white'}`}>
|
<a href={el.link || '#'} class={`px-8 py-3.5 rounded-xl font-bold text-xs transition-all active:scale-95 ${el.style === 'glass' ? 'glass-panel text-white' : 'bg-sky-400 text-slate-950 hover:bg-white'} ${el.animation0 ? `anim-${el.animation0}` : ''}`}>
|
||||||
{el.content}
|
{el.content}
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -83,16 +83,16 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Sektionen Re-Order -->
|
<!-- Sektionen Re-Order mit HTML5 Drag & Drop -->
|
||||||
<div class="glass-panel rounded-xl p-4 space-y-3">
|
<div class="glass-panel rounded-xl p-4 space-y-3">
|
||||||
<h3 class="text-xs font-bold text-sky-400 uppercase tracking-wider flex items-center justify-between">
|
<h3 class="text-xs font-bold text-sky-400 uppercase tracking-wider flex items-center justify-between">
|
||||||
<span>Sektionen Reihenfolge (Layout)</span>
|
<span>Sektionen Reihenfolge (Layout)</span>
|
||||||
<span class="text-[10px] text-slate-500 font-mono">Drag & Drop</span>
|
<span class="text-[10px] text-slate-400 font-mono">Drag & Drop</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div id="sections-list" class="space-y-2">
|
<div id="sections-list" class="space-y-2">
|
||||||
{siteConfig.sectionsOrder.map((sec, idx) => (
|
{siteConfig.sectionsOrder.map((sec, idx) => (
|
||||||
<div data-section={sec} draggable="true" class="section-item flex items-center justify-between p-3 rounded-lg bg-slate-900/60 border border-white/5 hover:border-white/20 transition-all group cursor-grab">
|
<div data-section={sec} draggable="true" class="section-item flex items-center justify-between p-3 rounded-lg bg-slate-900/60 border border-white/5 hover:border-sky-400/40 transition-all group cursor-grab active:cursor-grabbing">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<span class="text-slate-500 font-mono text-xs">#{idx + 1}</span>
|
<span class="text-slate-500 font-mono text-xs">#{idx + 1}</span>
|
||||||
<span class="text-xs font-semibold capitalize text-white">{sec}</span>
|
<span class="text-xs font-semibold capitalize text-white">{sec}</span>
|
||||||
@@ -107,6 +107,63 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Sektions-Inhalte & Animationen Bearbeiten -->
|
||||||
|
<div class="glass-panel rounded-xl p-4 space-y-4">
|
||||||
|
<h3 class="text-xs font-bold text-sky-400 uppercase tracking-wider">
|
||||||
|
Hero Sektion: Inhalt & Animation
|
||||||
|
</h3>
|
||||||
|
<div class="space-y-3 text-xs">
|
||||||
|
<div>
|
||||||
|
<label class="block text-[10px] font-bold text-slate-400 uppercase mb-1">Hero Title</label>
|
||||||
|
<input type="text" id="hero-title-input" value={siteConfig.hero.title} class="w-full glass-panel bg-slate-900 rounded-lg p-2 text-xs text-white focus:outline-none focus:border-sky-400" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-[10px] font-bold text-slate-400 uppercase mb-1">Hero Subtitle</label>
|
||||||
|
<textarea id="hero-subtitle-input" class="w-full h-16 glass-panel bg-slate-900 rounded-lg p-2 text-xs text-white focus:outline-none focus:border-sky-400">{siteConfig.hero.subtitle}</textarea>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-[10px] font-bold text-slate-400 uppercase mb-1">Hero Badge Text</label>
|
||||||
|
<input type="text" id="hero-badge-input" value={siteConfig.hero.badge} class="w-full glass-panel bg-slate-900 rounded-lg p-2 text-xs text-white focus:outline-none focus:border-sky-400" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-[10px] font-bold text-slate-400 uppercase mb-1">Hero Sektion Animation</label>
|
||||||
|
<select id="hero-anim-select" class="w-full glass-panel bg-slate-900 rounded-lg p-2 text-xs text-white focus:outline-none focus:border-sky-400">
|
||||||
|
<option value="" selected={!siteConfig.hero.animation}>Keine Animation</option>
|
||||||
|
<option value="spring-fade" selected={siteConfig.hero.animation === 'spring-fade'}>Spring Fade (Federleicht)</option>
|
||||||
|
<option value="slide-up" selected={siteConfig.hero.animation === 'slide-up'}>Slide Up (Eingleiten)</option>
|
||||||
|
<option value="zoom-in" selected={siteConfig.hero.animation === 'zoom-in'}>Zoom In (Heranzoomen)</option>
|
||||||
|
<option value="pulse-glow" selected={siteConfig.hero.animation === 'pulse-glow'}>Pulse Glow (Leuchten)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Bento Grid: Inhalt & Animation -->
|
||||||
|
<div class="glass-panel rounded-xl p-4 space-y-4">
|
||||||
|
<h3 class="text-xs font-bold text-sky-400 uppercase tracking-wider">
|
||||||
|
Bento Grid: Inhalt & Animation
|
||||||
|
</h3>
|
||||||
|
<div class="space-y-3 text-xs">
|
||||||
|
<div>
|
||||||
|
<label class="block text-[10px] font-bold text-slate-400 uppercase mb-1">Sektions-Titel</label>
|
||||||
|
<input type="text" id="bento-title-input" value={siteConfig.bento.sectionTitle} class="w-full glass-panel bg-slate-900 rounded-lg p-2 text-xs text-white focus:outline-none focus:border-sky-400" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-[10px] font-bold text-slate-400 uppercase mb-1">Sektions-Untertitel</label>
|
||||||
|
<input type="text" id="bento-subtitle-input" value={siteConfig.bento.sectionSubtitle} class="w-full glass-panel bg-slate-900 rounded-lg p-2 text-xs text-white focus:outline-none focus:border-sky-400" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-[10px] font-bold text-slate-400 uppercase mb-1">Bento Grid Animation</label>
|
||||||
|
<select id="bento-anim-select" class="w-full glass-panel bg-slate-900 rounded-lg p-2 text-xs text-white focus:outline-none focus:border-sky-400">
|
||||||
|
<option value="" selected={!siteConfig.bento.animation}>Keine Animation</option>
|
||||||
|
<option value="slide-up" selected={siteConfig.bento.animation === 'slide-up'}>Slide Up</option>
|
||||||
|
<option value="spring-fade" selected={siteConfig.bento.animation === 'spring-fade'}>Spring Fade</option>
|
||||||
|
<option value="zoom-in" selected={siteConfig.bento.animation === 'zoom-in'}>Zoom In</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Dynamische UIKomponente Hinzufuegen per Sektion -->
|
<!-- Dynamische UIKomponente Hinzufuegen per Sektion -->
|
||||||
<div class="glass-panel rounded-xl p-4 space-y-4">
|
<div class="glass-panel rounded-xl p-4 space-y-4">
|
||||||
<h3 class="text-xs font-bold text-sky-400 uppercase tracking-wider">
|
<h3 class="text-xs font-bold text-sky-400 uppercase tracking-wider">
|
||||||
@@ -150,6 +207,18 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-[10px] font-bold text-slate-400 uppercase mb-1">Element Animation</label>
|
||||||
|
<select id="new-el-anim" class="w-full glass-panel bg-slate-900 rounded-lg p-2 text-xs text-white focus:outline-none focus:border-sky-400">
|
||||||
|
<option value="">Keine Animation</option>
|
||||||
|
<option value="spring-fade">Spring Fade</option>
|
||||||
|
<option value="hover-bounce">Hover Bounce</option>
|
||||||
|
<option value="pulse-glow">Pulse Glow</option>
|
||||||
|
<option value="slide-up">Slide Up</option>
|
||||||
|
<option value="zoom-in">Zoom In</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[10px] font-bold text-slate-400 uppercase mb-1">Inhalt / Label</label>
|
<label class="block text-[10px] font-bold text-slate-400 uppercase mb-1">Inhalt / Label</label>
|
||||||
<input type="text" id="new-el-content" placeholder="z.B. Jetzt Anfragen" class="w-full glass-panel bg-slate-900 rounded-lg p-2 text-xs text-white focus:outline-none focus:border-sky-400" />
|
<input type="text" id="new-el-content" placeholder="z.B. Jetzt Anfragen" class="w-full glass-panel bg-slate-900 rounded-lg p-2 text-xs text-white focus:outline-none focus:border-sky-400" />
|
||||||
@@ -180,7 +249,7 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u
|
|||||||
|
|
||||||
<div id="elements-container" class="space-y-2 max-h-80 overflow-y-auto pr-1 custom-scroll">
|
<div id="elements-container" class="space-y-2 max-h-80 overflow-y-auto pr-1 custom-scroll">
|
||||||
{((siteConfig.hero.elements || [])).map((el, idx) => (
|
{((siteConfig.hero.elements || [])).map((el, idx) => (
|
||||||
<div data-id={el.id} class="p-3 rounded-lg bg-slate-900/70 border border-white/10 space-y-2 text-xs group">
|
<div data-id={el.id} draggable="true" class="element-item p-3 rounded-lg bg-slate-900/70 border border-white/10 space-y-2 text-xs group cursor-grab active:cursor-grabbing">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<span class="font-bold text-sky-400 uppercase text-[10px] block">{el.type} (Slot: {el.slotId})</span>
|
<span class="font-bold text-sky-400 uppercase text-[10px] block">{el.type} (Slot: {el.slotId})</span>
|
||||||
@@ -404,11 +473,48 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u
|
|||||||
renderSectionsList();
|
renderSectionsList();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// --- Drag & Drop for Section Items ---
|
||||||
|
let draggedSecIndex = -1;
|
||||||
|
|
||||||
|
function initSectionDragAndDrop() {
|
||||||
|
const listContainer = document.getElementById('sections-list');
|
||||||
|
if (!listContainer) return;
|
||||||
|
|
||||||
|
const items = listContainer.querySelectorAll('.section-item');
|
||||||
|
items.forEach((item, index) => {
|
||||||
|
item.addEventListener('dragstart', (e) => {
|
||||||
|
draggedSecIndex = index;
|
||||||
|
e.dataTransfer.effectAllowed = 'move';
|
||||||
|
item.classList.add('opacity-40');
|
||||||
|
});
|
||||||
|
|
||||||
|
item.addEventListener('dragend', () => {
|
||||||
|
item.classList.remove('opacity-40');
|
||||||
|
draggedSecIndex = -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
item.addEventListener('dragover', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.dataTransfer.dropEffect = 'move';
|
||||||
|
});
|
||||||
|
|
||||||
|
item.addEventListener('drop', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (draggedSecIndex !== -1 && draggedSecIndex !== index) {
|
||||||
|
const arr = siteConfigState.sectionsOrder;
|
||||||
|
const movedItem = arr.splice(draggedSecIndex, 1)[0];
|
||||||
|
arr.splice(index, 0, movedItem);
|
||||||
|
renderSectionsList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function renderSectionsList() {
|
function renderSectionsList() {
|
||||||
const listContainer = document.getElementById('sections-list');
|
const listContainer = document.getElementById('sections-list');
|
||||||
if (!listContainer) return;
|
if (!listContainer) return;
|
||||||
listContainer.innerHTML = siteConfigState.sectionsOrder.map((sec, idx) => (
|
listContainer.innerHTML = siteConfigState.sectionsOrder.map((sec, idx) => (
|
||||||
'<div data-section="' + sec + '" draggable="true" class="section-item flex items-center justify-between p-3 rounded-lg bg-slate-900/60 border border-white/5 hover:border-white/20 transition-all group cursor-grab">' +
|
'<div data-section="' + sec + '" draggable="true" class="section-item flex items-center justify-between p-3 rounded-lg bg-slate-900/60 border border-white/5 hover:border-sky-400/40 transition-all group cursor-grab active:cursor-grabbing">' +
|
||||||
'<div class="flex items-center gap-2">' +
|
'<div class="flex items-center gap-2">' +
|
||||||
'<span class="text-slate-500 font-mono text-xs">#' + (idx + 1) + '</span>' +
|
'<span class="text-slate-500 font-mono text-xs">#' + (idx + 1) + '</span>' +
|
||||||
'<span class="text-xs font-semibold capitalize text-white">' + sec + '</span>' +
|
'<span class="text-xs font-semibold capitalize text-white">' + sec + '</span>' +
|
||||||
@@ -420,8 +526,13 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u
|
|||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>'
|
'</div>'
|
||||||
)).join('');
|
)).join('');
|
||||||
|
|
||||||
|
initSectionDragAndDrop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initial call for drag and drop setup
|
||||||
|
initSectionDragAndDrop();
|
||||||
|
|
||||||
function updateSectionSelectors() {
|
function updateSectionSelectors() {
|
||||||
const newElSec = document.getElementById('new-el-section');
|
const newElSec = document.getElementById('new-el-section');
|
||||||
const filterSec = document.getElementById('filter-section-select');
|
const filterSec = document.getElementById('filter-section-select');
|
||||||
@@ -443,6 +554,7 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u
|
|||||||
const section = document.getElementById('new-el-section').value;
|
const section = document.getElementById('new-el-section').value;
|
||||||
const slotId = document.getElementById('new-el-slot').value;
|
const slotId = document.getElementById('new-el-slot').value;
|
||||||
const type = document.getElementById('new-el-type').value;
|
const type = document.getElementById('new-el-type').value;
|
||||||
|
const anim = document.getElementById('new-el-anim').value;
|
||||||
const content = document.getElementById('new-el-content').value || 'Neues Element';
|
const content = document.getElementById('new-el-content').value || 'Neues Element';
|
||||||
|
|
||||||
const newComp = {
|
const newComp = {
|
||||||
@@ -450,6 +562,7 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u
|
|||||||
slotId: section + '-' + slotId,
|
slotId: section + '-' + slotId,
|
||||||
type,
|
type,
|
||||||
content,
|
content,
|
||||||
|
animation0: anim || undefined,
|
||||||
style: 'primary'
|
style: 'primary'
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -509,7 +622,7 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u
|
|||||||
if (countEl) countEl.textContent = els.length;
|
if (countEl) countEl.textContent = els.length;
|
||||||
|
|
||||||
container.innerHTML = els.map((el, idx) => (
|
container.innerHTML = els.map((el, idx) => (
|
||||||
'<div data-id="' + el.id + '" class="p-3 rounded-lg bg-slate-900/70 border border-white/10 space-y-2 text-xs group">' +
|
'<div data-id="' + el.id + '" draggable="true" class="element-item p-3 rounded-lg bg-slate-900/70 border border-white/10 space-y-2 text-xs group cursor-grab active:cursor-grabbing">' +
|
||||||
'<div class="flex items-center justify-between">' +
|
'<div class="flex items-center justify-between">' +
|
||||||
'<div>' +
|
'<div>' +
|
||||||
'<span class="font-bold text-sky-400 uppercase text-[10px] block">' + el.type + ' (Slot: ' + el.slotId + ')</span>' +
|
'<span class="font-bold text-sky-400 uppercase text-[10px] block">' + el.type + ' (Slot: ' + el.slotId + ')</span>' +
|
||||||
@@ -544,6 +657,28 @@ const { siteConfig, themeConfig } = loadWaasConfigs(Astro.request.headers.get('u
|
|||||||
saveBtn.disabled = true;
|
saveBtn.disabled = true;
|
||||||
saveBtn.textContent = 'Wird gespeichert...';
|
saveBtn.textContent = 'Wird gespeichert...';
|
||||||
|
|
||||||
|
// Collect Hero Section Inputs & Animation
|
||||||
|
const heroTitle = document.getElementById('hero-title-input')?.value;
|
||||||
|
const heroSubtitle = document.getElementById('hero-subtitle-input')?.value;
|
||||||
|
const heroBadge = document.getElementById('hero-badge-input')?.value;
|
||||||
|
const heroAnim = document.getElementById('hero-anim-select')?.value;
|
||||||
|
|
||||||
|
if (!siteConfigState.hero) siteConfigState.hero = {};
|
||||||
|
if (heroTitle !== undefined) siteConfigState.hero.title = heroTitle;
|
||||||
|
if (heroSubtitle !== undefined) siteConfigState.hero.subtitle = heroSubtitle;
|
||||||
|
if (heroBadge !== undefined) siteConfigState.hero.badge = heroBadge;
|
||||||
|
siteConfigState.hero.animation = heroAnim || undefined;
|
||||||
|
|
||||||
|
// Collect Bento Section Inputs & Animation
|
||||||
|
const bentoTitle = document.getElementById('bento-title-input')?.value;
|
||||||
|
const bentoSubtitle = document.getElementById('bento-subtitle-input')?.value;
|
||||||
|
const bentoAnim = document.getElementById('bento-anim-select')?.value;
|
||||||
|
|
||||||
|
if (!siteConfigState.bento) siteConfigState.bento = {};
|
||||||
|
if (bentoTitle !== undefined) siteConfigState.bento.sectionTitle = bentoTitle;
|
||||||
|
if (bentoSubtitle !== undefined) siteConfigState.bento.sectionSubtitle = bentoSubtitle;
|
||||||
|
siteConfigState.bento.animation = bentoAnim || undefined;
|
||||||
|
|
||||||
// Collect Header Inputs
|
// Collect Header Inputs
|
||||||
const brandName = document.getElementById('header-brand-name')?.value;
|
const brandName = document.getElementById('header-brand-name')?.value;
|
||||||
const brandHighlight = document.getElementById('header-brand-highlight')?.value;
|
const brandHighlight = document.getElementById('header-brand-highlight')?.value;
|
||||||
|
|||||||
@@ -46,3 +46,37 @@ body {
|
|||||||
background: radial-gradient(circle, var(--theme-accent) 0%, transparent 70%);
|
background: radial-gradient(circle, var(--theme-accent) 0%, transparent 70%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Preset Animations */
|
||||||
|
.anim-spring-fade {
|
||||||
|
animation: springFade 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
|
||||||
|
}
|
||||||
|
.anim-hover-bounce:hover {
|
||||||
|
transform: translateY(-6px);
|
||||||
|
transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||||
|
}
|
||||||
|
.anim-pulse-glow {
|
||||||
|
animation: pulseGlow 3s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
.anim-slide-up {
|
||||||
|
animation: slideUp 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
.anim-zoom-in {
|
||||||
|
animation: zoomIn 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes springFade {
|
||||||
|
0% { opacity: 0; transform: translateY(20px) scale(0.95); }
|
||||||
|
100% { opacity: 1; transform: translateY(0) scale(1); }
|
||||||
|
}
|
||||||
|
@keyframes pulseGlow {
|
||||||
|
0%, 100% { box-shadow: 0 0 15px -3px var(--theme-accent); }
|
||||||
|
50% { box-shadow: 0 0 35px 5px var(--theme-accent); }
|
||||||
|
}
|
||||||
|
@keyframes slideUp {
|
||||||
|
0% { opacity: 0; transform: translateY(30px); }
|
||||||
|
100% { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
@keyframes zoomIn {
|
||||||
|
0% { opacity: 0; transform: scale(0.85); }
|
||||||
|
100% { opacity: 1; transform: scale(1); }
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export interface SectionConfig {
|
|||||||
title?: string;
|
title?: string;
|
||||||
subtitle?: string;
|
subtitle?: string;
|
||||||
badge?: string;
|
badge?: string;
|
||||||
|
animation?: string;
|
||||||
elements?: UIComponent[];
|
elements?: UIComponent[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,11 +46,13 @@ export interface SiteConfig {
|
|||||||
ctaPrimaryLink: string;
|
ctaPrimaryLink: string;
|
||||||
ctaSecondaryText: string;
|
ctaSecondaryText: string;
|
||||||
ctaSecondaryLink: string;
|
ctaSecondaryLink: string;
|
||||||
|
animation?: string;
|
||||||
elements?: UIComponent[];
|
elements?: UIComponent[];
|
||||||
};
|
};
|
||||||
bento: {
|
bento: {
|
||||||
sectionTitle: string;
|
sectionTitle: string;
|
||||||
sectionSubtitle: string;
|
sectionSubtitle: string;
|
||||||
|
animation?: string;
|
||||||
cards: Array<{
|
cards: Array<{
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
@@ -57,6 +60,7 @@ export interface SiteConfig {
|
|||||||
colSpan?: number;
|
colSpan?: number;
|
||||||
badge?: string;
|
badge?: string;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
|
animation?: string;
|
||||||
}>;
|
}>;
|
||||||
};
|
};
|
||||||
contact: {
|
contact: {
|
||||||
|
|||||||
Reference in New Issue
Block a user