feat: tag contenuti home hero, info, feature, quote

This commit is contained in:
2026-07-05 16:04:27 +02:00
parent f4c350ad64
commit 3f01721a99
6 changed files with 75 additions and 32 deletions
+10 -11
View File
@@ -1,26 +1,25 @@
--- ---
import { Image } from 'astro:assets';
import featPerformance from '../../assets/img/feature-performance.jpg'; import featPerformance from '../../assets/img/feature-performance.jpg';
import featBalance from '../../assets/img/feature-balance.jpg'; import featBalance from '../../assets/img/feature-balance.jpg';
import featLongevity from '../../assets/img/feature-longevity.jpg'; import featLongevity from '../../assets/img/feature-longevity.jpg';
import T from '../content/T.astro';
import TImg from '../content/TImg.astro';
import { t } from '../../lib/content';
const blocks = [ const blocks = [
{ title: 'PERFORMANCE', image: featPerformance, reverse: false, { key: 'performance', image: featPerformance, reverse: false },
text: 'Allenamenti progettati su misura per adattarsi ai tuoi obiettivi e al tuo livello. Programmi mirati che sviluppano forza, resistenza e funzionalità in modo equilibrato. Un metodo efficace per migliorare le performance e ottenere risultati concreti e duraturi.' }, { key: 'balance', image: featBalance, reverse: true },
{ title: 'BALANCE', image: featBalance, reverse: true, { key: 'longevity', image: featLongevity, reverse: false },
text: 'Lequilibrio tra corpo e mente è la base di ogni performance duratura. Attraverso movimento, recupero e gestione dello stress, costruiamo stabilità e controllo. Un approccio integrato che sostiene benessere, energia e continuità nel tempo.' },
{ title: 'LONGEVITY', image: featLongevity, reverse: false,
text: 'Benessere completo tra movimento, nutrizione e stile di vita. Un percorso personalizzato che unisce prevenzione, recupero ed equilibrio. Investi nella tua salute e qualità della vita nel tempo.' },
]; ];
--- ---
<section class="section"> <section class="section">
<div class="container"> <div class="container">
{blocks.map((b) => ( {blocks.map((b) => (
<div class:list={['feat', { 'feat--reverse': b.reverse }]}> <div class:list={['feat', { 'feat--reverse': b.reverse }]}>
<Image src={b.image} alt={b.title} class="feat__img" widths={[500, 900]} sizes="(max-width: 767px) 100vw, 45vw" data-reveal={b.reverse ? 'right' : 'left'} /> <TImg tag={`home.feature.${b.key}.image`} src={b.image} alt={t(`home.feature.${b.key}.title`)} class="feat__img" widths={[500, 900]} sizes="(max-width: 767px) 100vw, 45vw" data-reveal={b.reverse ? 'right' : 'left'} />
<div class="feat__text" data-reveal={b.reverse ? 'left' : 'right'}> <div class="feat__text" data-reveal={b.reverse ? 'left' : 'right'}>
<h2>{b.title}</h2> <T tag={`home.feature.${b.key}.title`} as="h2" />
<p>{b.text}</p> <T tag={`home.feature.${b.key}.body`} as="p" />
<a class="btn" href="/programs">Scopri</a> <a class="btn" href="/programs">{t(`home.feature.${b.key}.cta`)}</a>
</div> </div>
</div> </div>
))} ))}
+7 -5
View File
@@ -1,8 +1,10 @@
--- ---
import { Image } from 'astro:assets';
import hero1 from '../../assets/img/hero-1.png'; import hero1 from '../../assets/img/hero-1.png';
import T from '../content/T.astro';
import TImg from '../content/TImg.astro';
import { t } from '../../lib/content';
const slides = [ const slides = [
{ title: ['PERFORMANCE.', 'BALANCE.', 'LONGEVITY.'], image: hero1, alt: 'Atleti InsanityLab' }, { titleTags: ['home.hero.title-line-1', 'home.hero.title-line-2', 'home.hero.title-line-3'], image: hero1, alt: 'Atleti InsanityLab' },
]; ];
--- ---
<section class="hero" aria-label="presentazione"> <section class="hero" aria-label="presentazione">
@@ -10,10 +12,10 @@ const slides = [
<div class:list={['hero__slide', { 'is-active': i === 0 }]}> <div class:list={['hero__slide', { 'is-active': i === 0 }]}>
<div class="container hero__in"> <div class="container hero__in">
<div class="hero__text"> <div class="hero__text">
<h1>{s.title.map((line) => <span class="hero__line">{line}</span>)}</h1> <h1>{s.titleTags.map((tag) => <T tag={tag} as="span" class="hero__line" />)}</h1>
<a class="btn" href="/programs">Scopri</a> <a class="btn" href="/programs">{t('home.hero.cta')}</a>
</div> </div>
<Image src={s.image} alt={s.alt} class="hero__img" widths={[600, 1000, 1400]} sizes="(max-width: 991px) 100vw, 60vw" loading="eager" /> <TImg tag="home.hero.image" src={s.image} alt={s.alt} class="hero__img" widths={[600, 1000, 1400]} sizes="(max-width: 991px) 100vw, 60vw" loading="eager" />
</div> </div>
</div> </div>
))} ))}
+8 -6
View File
@@ -3,18 +3,20 @@ import { getImage } from 'astro:assets';
import infoPerformance from '../../assets/img/info-performance.jpg'; import infoPerformance from '../../assets/img/info-performance.jpg';
import infoBalance from '../../assets/img/info-balance.jpg'; import infoBalance from '../../assets/img/info-balance.jpg';
import infoLongevity from '../../assets/img/info-longevity.jpg'; import infoLongevity from '../../assets/img/info-longevity.jpg';
import T from '../content/T.astro';
import { contentImageUrl } from '../../lib/content';
// getImage garantisce l'emissione dell'asset anche quando il file è byte-identico // getImage garantisce l'emissione dell'asset anche quando il file è byte-identico
// ad altri import (Astro dedupa e non emette l'originale usato solo come background). // ad altri import (Astro dedupa e non emette l'originale usato solo come background).
const cols = await Promise.all([ const cols = await Promise.all([
{ title: 'PERFORMANCE.', image: infoPerformance }, { titleTag: 'home.info.col1.title', imageTag: 'home.info.col1.image', image: infoPerformance },
{ title: 'BALANCE.', image: infoBalance }, { titleTag: 'home.info.col2.title', imageTag: 'home.info.col2.image', image: infoBalance },
{ title: 'LONGEVITY.', image: infoLongevity }, { titleTag: 'home.info.col3.title', imageTag: 'home.info.col3.image', image: infoLongevity },
].map(async (c) => ({ ...c, bg: (await getImage({ src: c.image, width: 1200 })).src }))); ].map(async (c) => ({ ...c, bg: contentImageUrl(c.imageTag, (await getImage({ src: c.image, width: 1200 })).src) })));
--- ---
<section class="info" aria-label="pilastri"> <section class="info" aria-label="pilastri">
{cols.map((c, i) => ( {cols.map((c, i) => (
<a class="info__col" href="/programs" style={`background-image:url(${c.bg});--reveal-delay:${i * 0.15}s`} data-reveal="fade"> <a class="info__col" href="/programs" style={`background-image:url(${c.bg});--reveal-delay:${i * 0.15}s`} data-reveal="fade" data-tag={c.imageTag}>
<span class="info__title">{c.title}</span> <T tag={c.titleTag} as="span" class="info__title" />
</a> </a>
))} ))}
</section> </section>
+6 -7
View File
@@ -1,22 +1,21 @@
--- ---
import { getImage } from 'astro:assets'; import { getImage } from 'astro:assets';
import quoteBgSrc from '../../assets/img/quote-bg.jpg'; import quoteBgSrc from '../../assets/img/quote-bg.jpg';
const quoteBg = await getImage({ src: quoteBgSrc, width: 1920 }); import { t, contentImageUrl } from '../../lib/content';
const quote = 'PERFORMANCE È SPINGERE OLTRE I PROPRI LIMITI, BALANCE È SAPERLI ASCOLTARE, LONGEVITY È COSTRUIRE NEL TEMPO CIÒ CHE DAVVERO CONTA.'; const quoteBg = contentImageUrl('home.quote.image', (await getImage({ src: quoteBgSrc, width: 1920 })).src);
const quoteHtml = quote.replace(/(PERFORMANCE|BALANCE|LONGEVITY)/g, '<strong>$1</strong>');
--- ---
<section class="quote" data-parallax> <section class="quote" data-parallax>
<div class="quote__bg" style={`background-image:url(${quoteBg.src})`}></div> <div class="quote__bg" style={`background-image:url(${quoteBg})`} data-tag="home.quote.image"></div>
<div class="quote__in"> <div class="quote__in">
<p class="quote__mark">“</p> <p class="quote__mark">“</p>
<blockquote> <blockquote>
<div class="quote__marquee"> <div class="quote__marquee">
<p class="quote__track"> <p class="quote__track">
<span class="quote__seg" set:html={quoteHtml} /> <span class="quote__seg" data-tag="home.quote.text" set:html={t('home.quote.text')} />
<span class="quote__seg" aria-hidden="true" set:html={quoteHtml} /> <span class="quote__seg" aria-hidden="true" data-tag="home.quote.text" set:html={t('home.quote.text')} />
</p> </p>
</div> </div>
<cite>Insanitylab</cite> <cite data-tag="home.quote.cite">{t('home.quote.cite')}</cite>
</blockquote> </blockquote>
</div> </div>
</section> </section>
+39
View File
@@ -58,6 +58,45 @@ export const contentSeed: SeedEntry[] = [
T('form.msg.success', 'Messaggio inviato, ti ricontatteremo al più presto.', []), T('form.msg.success', 'Messaggio inviato, ti ricontatteremo al più presto.', []),
T('form.msg.error-generic', 'Errore di invio, riprova più tardi.', []), T('form.msg.error-generic', 'Errore di invio, riprova più tardi.', []),
T('form.msg.error-network', 'Errore di rete, riprova più tardi.', []), T('form.msg.error-network', 'Errore di rete, riprova più tardi.', []),
// --- Home: meta, training heading ---
T('home.meta.title', 'Performance. Balance. Longevity.', []),
T('home.training.title', 'Training'),
T('home.training.subtitle', 'Porta i tuoi allenamenti al livello successivo: trova il percorso più adatto alle tue esigenze.'),
// --- Home: hero ---
T('home.hero.title-line-1', 'PERFORMANCE.'),
T('home.hero.title-line-2', 'BALANCE.'),
T('home.hero.title-line-3', 'LONGEVITY.'),
T('home.hero.cta', 'Scopri'),
I('home.hero.image'),
// --- Home: info columns ---
T('home.info.col1.title', 'PERFORMANCE.'),
T('home.info.col2.title', 'BALANCE.'),
T('home.info.col3.title', 'LONGEVITY.'),
I('home.info.col1.image'),
I('home.info.col2.image'),
I('home.info.col3.image'),
// --- Home: feature blocks ---
T('home.feature.performance.title', 'PERFORMANCE'),
T('home.feature.performance.body', 'Allenamenti progettati su misura per adattarsi ai tuoi obiettivi e al tuo livello. Programmi mirati che sviluppano forza, resistenza e funzionalità in modo equilibrato. Un metodo efficace per migliorare le performance e ottenere risultati concreti e duraturi.'),
T('home.feature.performance.cta', 'Scopri'),
T('home.feature.balance.title', 'BALANCE'),
T('home.feature.balance.body', 'Lequilibrio tra corpo e mente è la base di ogni performance duratura. Attraverso movimento, recupero e gestione dello stress, costruiamo stabilità e controllo. Un approccio integrato che sostiene benessere, energia e continuità nel tempo.'),
T('home.feature.balance.cta', 'Scopri'),
T('home.feature.longevity.title', 'LONGEVITY'),
T('home.feature.longevity.body', 'Benessere completo tra movimento, nutrizione e stile di vita. Un percorso personalizzato che unisce prevenzione, recupero ed equilibrio. Investi nella tua salute e qualità della vita nel tempo.'),
T('home.feature.longevity.cta', 'Scopri'),
I('home.feature.performance.image'),
I('home.feature.balance.image'),
I('home.feature.longevity.image'),
// --- Home: quote banner ---
H('home.quote.text', '<strong>PERFORMANCE</strong> È SPINGERE OLTRE I PROPRI LIMITI, <strong>BALANCE</strong> È SAPERLI ASCOLTARE, <strong>LONGEVITY</strong> È COSTRUIRE NEL TEMPO CIÒ CHE DAVVERO CONTA.'),
T('home.quote.cite', 'Insanitylab', []),
I('home.quote.image'),
// I task di estrazione aggiungono qui le entry di header/footer/pagine/data file. // I task di estrazione aggiungono qui le entry di header/footer/pagine/data file.
]; ];
+5 -3
View File
@@ -10,17 +10,19 @@ import Agenda from '../components/Agenda.astro';
import TeamSection from '../components/home/TeamSection.astro'; import TeamSection from '../components/home/TeamSection.astro';
import MethodSteps from '../components/home/MethodSteps.astro'; import MethodSteps from '../components/home/MethodSteps.astro';
import PartnersStrip from '../components/home/PartnersStrip.astro'; import PartnersStrip from '../components/home/PartnersStrip.astro';
import T from '../components/content/T.astro';
import { t } from '../lib/content';
export const prerender = true; export const prerender = true;
--- ---
<Base title="Performance. Balance. Longevity."> <Base title={t('home.meta.title')}>
<HeroSlider /> <HeroSlider />
<InfoColumns /> <InfoColumns />
<FeatureBlocks /> <FeatureBlocks />
<QuoteBanner /> <QuoteBanner />
<section class="section" style="padding-bottom:0"> <section class="section" style="padding-bottom:0">
<div class="section-heading"> <div class="section-heading">
<h2>Training</h2> <T tag="home.training.title" as="h2" />
<p>Porta i tuoi allenamenti al livello successivo: trova il percorso più adatto alle tue esigenze.</p> <T tag="home.training.subtitle" as="p" />
</div> </div>
</section> </section>
<TrainingCards /> <TrainingCards />