<section class="rtds-hero rtds-hero--gradient-bg rtds-hero--centered">
<div class="rtds-container rtds-py-16 rtds-grid rtds-gap-y-10">
<div class="rtds-hero__inner">
<div class="rtds-hero__content">
<h1 class="rtds-hero__title">
Questo è un esempio di titolo per la Hero
</h1>
<p class="rtds-hero__description">
Questo è un tempo di esempio per descrizione o sottotitolo. Dovrebbe dare informazioni aggiuntive sulla pagina in cui ci troviamo. Potrebbe avere circa 300 caratteri.
</p>
<div class="rtds-hero__search">
<div class="rtds-search-bar" data-search-bar data-all-results-href="/search?q=" data-all-results-label="Tutti i risultati">
<form class="rtds-search-bar__form" role="search" action="/search" method="get">
<div class="rtds-search-bar__wrapper">
<label for="heroSearchDefault" class="rtds-search-bar__label rtds-sr-only">
Cerca
</label>
<div class="rtds-search-bar__input-wrapper">
<div class="rtds-search-bar__autocomplete" id="heroSearchDefaultContainer" data-placeholder="Search"></div>
<button type="button" class="rtds-btn rtds-btn--icon rtds-btn--l rtds-search-bar__clear rtds-border-0 rtds-hidden hover:rtds-background-secondary hover:rtds-text-white" data-search-clear>
<span class="rtds-sr-only">Cancella ricerca</span>
<svg class="rtds-icon rtds-fill-current rtds-w-6 rtds-h-6" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#outline--x-circle" />
</svg>
</button>
<button type="submit" class="rtds-btn
r rtds-btn--icon rtds-btn--icon-square rtds-btn--primary rtds-search-bar__submit rtds-btn--l"><svg class="rtds-icon rtds-fill-current rtds-w-6 rtds-h-6" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--magnifying-glass" />
</svg>
<span class="rtds-sr-only">
Cerca
</span>
</button>
</div>
</div>
</form>
</div>
</div>
<div class="rtds-hero__buttons">
<a href="#" class="rtds-btn
rtds-btn--icon-right rtds-group/button rtds-btn--outlined rtds-btn--s">
Button
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 group-hover/button:rtds-translate-x-1" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--chevron-right" />
</svg>
</a>
<a href="#" class="rtds-btn
rtds-btn--icon-right rtds-group/button rtds-btn--primary rtds-btn--s">
CTA Button
<svg class="rtds-icon rtds-fill-current rtds-w-4 rtds-h-4 md:rtds-w-5 md:rtds-h-5 lg:rtds-w-6 lg:rtds-h-6 group-hover/button:rtds-translate-x-1" aria-hidden="true" focusable="false" role="img">
<use href="../../icons.svg#mini--chevron-right" />
</svg>
</a>
</div>
</div>
</div>
<div class="rtds-hero__additional">
Container di contenuto aggiuntivo (loghi, KPI, testo aggiuntivo...)
</div>
</div>
</section>
<section class="rtds-hero{% if background %} rtds-hero--{{ background }}{% endif %}{% if alignment == 'left' %} rtds-hero--left{% else %} rtds-hero--centered{% endif %}{% if image %} rtds-hero--has-image{% endif %}{% if classes %} {{ classes }}{% endif %}"{% if bgImage %} style="--hero-bg-image: url({{ bgImage | path }});"{% endif %}>
{% if background == 'image-bg' %}
<div class="rtds-hero__overlay" aria-hidden="true"></div>
{% endif %}
<div class="rtds-container rtds-py-16 rtds-grid rtds-gap-y-10">
<div class="rtds-hero__inner">
<div class="rtds-hero__content">
{# Title #}
<h1 class="rtds-hero__title">
{{ title | safe }}
</h1>
{# Description/Subtitle #}
{% if description %}
<p class="rtds-hero__description">
{{ description | safe }}
</p>
{% endif %}
{# Search bar #}
{% if showSearch %}
<div class="rtds-hero__search">
{% render '@search-bar', searchBar, true %}
</div>
{% endif %}
{# Button group #}
{% if buttons %}
<div class="rtds-hero__buttons">
{% for btn in buttons %}
{% render '@button' ~ btn.variant, btn.context, true %}
{% endfor %}
</div>
{% endif %}
</div>
{# Right image #}
{% if image %}
<figure class="rtds-hero__image">
<img src="{{ image.src | path }}" alt="{{ image.alt | default('') }}">
</figure>
{% endif %}
</div>
{# Additional content container #}
{% if additionalContent %}
<div class="rtds-hero__additional">
{{ additionalContent | safe }}
</div>
{% endif %}
</div>
</section>
{
"title": "Questo è un esempio di titolo per la Hero",
"description": "Questo è un tempo di esempio per descrizione o sottotitolo. Dovrebbe dare informazioni aggiuntive sulla pagina in cui ci troviamo. Potrebbe avere circa 300 caratteri.",
"background": "gradient-bg",
"alignment": "centered",
"showSearch": true,
"searchBar": {
"label": "Cerca",
"searchId": "heroSearchDefault",
"submitLabel": "Cerca",
"showClearButton": true,
"showLabel": false,
"placeholder": "Search",
"formAction": "/search",
"formMethod": "get",
"allResultsHref": "/search?q=",
"allResultsLabel": "Tutti i risultati"
},
"buttons": [
{
"variant": "--icon-right",
"context": {
"label": "Button",
"href": "#",
"classes": "rtds-btn--outlined rtds-btn--s",
"icon": "mini--chevron-right"
}
},
{
"variant": "--icon-right",
"context": {
"label": "CTA Button",
"href": "#",
"classes": "rtds-btn--primary rtds-btn--s",
"icon": "mini--chevron-right"
}
}
],
"additionalContent": "Container di contenuto aggiuntivo (loghi, KPI, testo aggiuntivo...)"
}
/* ─── Base + Custom Properties ──────────────────────────────── */
.rtds-hero {
/* Variabili private (uso interno) ← pubbliche ← default semantico ← primitivo */
--_hero-bg: var(--hero-bg, transparent);
--_hero-gradient: var(--hero-gradient, none);
--_hero-bg-image: var(--hero-bg-image, none);
--_hero-overlay-bg: var(--hero-overlay-bg, rgba(255, 255, 255, 0.5));
--_hero-image-basis: var(--hero-image-basis, 382px);
--_hero-title-color: var(--hero-title-color, var(--color-content-01, var(--color-neutral-900)));
--_hero-description-color: var(--hero-description-color, var(--color-content-03, var(--color-neutral-800)));
--_hero-additional-bg: var(--hero-additional-bg, var(--color-background-03, var(--color-neutral-300)));
--_hero-additional-border: var(--hero-additional-border, var(--color-border-gray-02, var(--color-neutral-400)));
--_hero-additional-text: var(--hero-additional-text, var(--color-content-01, var(--color-neutral-900)));
position: relative;
width: 100%;
overflow-x: hidden;
background-color: var(--_hero-bg);
background-image: var(--_hero-gradient);
}
/* ─── Backgrounds (override variabili pubbliche) ─────────────── */
.rtds-hero--gradient-bg {
--hero-gradient: var(--gradient-04);
}
.rtds-hero--light-bg {
--hero-bg: var(--color-background-01, var(--color-neutral-50));
}
.rtds-hero--dark-bg {
--hero-bg: var(--color-background-09, var(--color-secondary-800));
--hero-title-color: var(--color-content-inverse, var(--color-neutral-50));
--hero-description-color: var(--color-content-inverse, var(--color-neutral-50));
}
.rtds-hero--image-bg {
background-size: cover;
background-position: center;
background-repeat: no-repeat;
background-image: var(--_hero-bg-image);
}
/* Semi-transparent overlay for image background */
.rtds-hero__overlay {
pointer-events: none;
position: absolute;
inset: var(--spacing-0);
z-index: 0;
background-color: var(--_hero-overlay-bg);
}
/* ─── Inner ─────────────────────────────────────────────────── */
.rtds-hero__inner {
position: relative;
z-index: 10;
flex-direction: column;
align-items: flex-start;
gap: var(--spacing-10);
display: flex;
}
/* ─── Content block ─────────────────────────────────────────── */
.rtds-hero__content {
width: 100%;
flex-direction: column;
display: flex;
gap: var(--spacing-8);
}
/* Centered: content items center */
:where(.rtds-hero--centered) .rtds-hero__content {
text-align: center;
align-items: center;
}
/* ─── Title ─────────────────────────────────────────────────── */
.rtds-hero__title {
font-family: var(--fontfamily-sans), sans-serif;
line-height: 1.25;
font-weight: 700;
font-size: var(--fontsize-text-42px);
color: var(--_hero-title-color);
}
/* ─── Description ───────────────────────────────────────────── */
.rtds-hero__description {
font-family: var(--fontfamily-sans), sans-serif;
font-size: var(--fontsize-text-lg);
line-height: 1.75rem;
font-weight: 700;
color: var(--_hero-description-color);
}
/* ─── Search ────────────────────────────────────────────────── */
.rtds-hero__search {
position: relative;
width: 100%;
z-index: 10;
}
/* Dropdown risultati allineato a sinistra (non centrato) */
.rtds-hero__search .autocomplete__menu {
text-align: left;
}
.rtds-hero__search .autocomplete__option {
justify-content: flex-start;
text-align: left;
}
/* ─── Buttons ───────────────────────────────────────────────── */
.rtds-hero__buttons {
flex-wrap: wrap;
gap: var(--spacing-3);
display: flex;
}
/* ─── Right image ───────────────────────────────────────────── */
body.rtds-hero__image .rtds-primary-navigation__backdrop,
:root.rtds-hero__image .rtds-primary-navigation__backdrop {
position: fixed;
right: var(--spacing-0);
bottom: var(--spacing-0);
left: var(--spacing-0);
z-index: 10;
}
@media (min-width: 1024px) {
body.rtds-hero__image .rtds-primary-navigation__backdrop,
:root.rtds-hero__image .rtds-primary-navigation__backdrop {
display: none;
}
}
body.rtds-hero__image .rtds-primary-navigation__backdrop,
:root.rtds-hero__image .rtds-primary-navigation__backdrop {
position: fixed;
right: var(--spacing-0);
bottom: var(--spacing-0);
left: var(--spacing-0);
z-index: 10;
}
@media (min-width: 1024px) {
body.rtds-hero__image .rtds-primary-navigation__backdrop,
:root.rtds-hero__image .rtds-primary-navigation__backdrop {
display: none;
}
}
.rtds-hero__image {
aspect-ratio: 16 / 9;
width: 100%;
border-radius: 0.5rem;
overflow: hidden;
flex: none;
}
.rtds-hero__image img {
height: 100%;
width: 100%;
-o-object-fit: cover;
object-fit: cover;
-o-object-position: center;
object-position: center;
}
/* ─── Desktop layout ─────────────────────────────────────────── */
@media (min-width: 1024px) {
:where(.rtds-hero--has-image) .rtds-hero__inner {
flex-direction: row;
gap: var(--spacing-16);
}
:where(.rtds-hero--has-image) .rtds-hero__content {
flex: 1 1 0%;
}
.rtds-hero__image {
flex: 0 1 var(--_hero-image-basis);
aspect-ratio: 1 / 1;
}
}
/* ─── Additional content container ──────────────────────────── */
.rtds-hero__additional {
display: flex;
justify-content: center;
align-items: center;
padding: var(--spacing-8);
border-radius: 0.5rem;
border-width: 1px;
font-family: var(--fontfamily-sans), sans-serif;
font-size: var(--fontsize-text-base);
background-color: var(--_hero-additional-bg);
border-color: var(--_hero-additional-border);
color: var(--_hero-additional-text);
}
@layer components {
/* ─── Base + Custom Properties ──────────────────────────────── */
.rtds-hero {
/* Variabili private (uso interno) ← pubbliche ← default semantico ← primitivo */
--_hero-bg: var(--hero-bg, transparent);
--_hero-gradient: var(--hero-gradient, none);
--_hero-bg-image: var(--hero-bg-image, none);
--_hero-overlay-bg: var(--hero-overlay-bg, rgba(255, 255, 255, 0.5));
--_hero-image-basis: var(--hero-image-basis, 382px);
--_hero-title-color: var(--hero-title-color, var(--color-content-01, var(--color-neutral-900)));
--_hero-description-color: var(--hero-description-color, var(--color-content-03, var(--color-neutral-800)));
--_hero-additional-bg: var(--hero-additional-bg, var(--color-background-03, var(--color-neutral-300)));
--_hero-additional-border: var(--hero-additional-border, var(--color-border-gray-02, var(--color-neutral-400)));
--_hero-additional-text: var(--hero-additional-text, var(--color-content-01, var(--color-neutral-900)));
@apply rtds-relative rtds-w-full;
overflow-x: hidden;
background-color: var(--_hero-bg);
background-image: var(--_hero-gradient);
}
/* ─── Backgrounds (override variabili pubbliche) ─────────────── */
.rtds-hero--gradient-bg {
--hero-gradient: var(--gradient-04);
}
.rtds-hero--light-bg {
--hero-bg: var(--color-background-01, var(--color-neutral-50));
}
.rtds-hero--dark-bg {
--hero-bg: var(--color-background-09, var(--color-secondary-800));
--hero-title-color: var(--color-content-inverse, var(--color-neutral-50));
--hero-description-color: var(--color-content-inverse, var(--color-neutral-50));
}
.rtds-hero--image-bg {
@apply rtds-bg-cover rtds-bg-center rtds-bg-no-repeat;
background-image: var(--_hero-bg-image);
}
/* Semi-transparent overlay for image background */
.rtds-hero__overlay {
@apply rtds-absolute rtds-inset-0 rtds-pointer-events-none rtds-z-0;
background-color: var(--_hero-overlay-bg);
}
/* ─── Inner ─────────────────────────────────────────────────── */
.rtds-hero__inner {
@apply rtds-relative rtds-z-10 rtds-flex rtds-flex-col rtds-items-start rtds-gap-10;
}
/* ─── Content block ─────────────────────────────────────────── */
.rtds-hero__content {
@apply rtds-flex rtds-flex-col rtds-gap-8 rtds-w-full;
}
/* Centered: content items center */
:where(.rtds-hero--centered) .rtds-hero__content {
@apply rtds-items-center rtds-text-center;
}
/* ─── Title ─────────────────────────────────────────────────── */
.rtds-hero__title {
@apply rtds-font-sans rtds-font-bold rtds-leading-tight;
font-size: var(--fontsize-text-42px);
color: var(--_hero-title-color);
}
/* ─── Description ───────────────────────────────────────────── */
.rtds-hero__description {
@apply rtds-font-sans rtds-font-bold rtds-text-lg rtds-leading-7;
color: var(--_hero-description-color);
}
/* ─── Search ────────────────────────────────────────────────── */
.rtds-hero__search {
@apply rtds-relative rtds-w-full;
z-index: 10;
}
/* Dropdown risultati allineato a sinistra (non centrato) */
.rtds-hero__search .autocomplete__menu {
@apply rtds-text-left;
}
.rtds-hero__search .autocomplete__option {
@apply rtds-text-left rtds-justify-start;
}
/* ─── Buttons ───────────────────────────────────────────────── */
.rtds-hero__buttons {
@apply rtds-flex rtds-flex-wrap rtds-gap-3;
}
/* ─── Right image ───────────────────────────────────────────── */
.rtds-hero__image {
@apply rtds-flex-none rtds-overflow-hidden rtds-rounded-lg rtds-w-full rtds-aspect-video;
}
.rtds-hero__image img {
@apply rtds-w-full rtds-h-full rtds-object-cover rtds-object-center;
}
/* ─── Desktop layout ─────────────────────────────────────────── */
@screen lg {
:where(.rtds-hero--has-image) .rtds-hero__inner {
@apply rtds-flex-row rtds-gap-16;
}
:where(.rtds-hero--has-image) .rtds-hero__content {
@apply rtds-flex-1;
}
.rtds-hero__image {
flex: 0 1 var(--_hero-image-basis);
aspect-ratio: 1 / 1;
}
}
/* ─── Additional content container ──────────────────────────── */
.rtds-hero__additional {
@apply rtds-flex rtds-items-center rtds-justify-center;
@apply rtds-border rtds-rounded-lg rtds-p-8;
@apply rtds-font-sans rtds-text-base;
background-color: var(--_hero-additional-bg);
border-color: var(--_hero-additional-border);
color: var(--_hero-additional-text);
}
}
Sezione introduttiva di pagina (above-the-fold) con titolo, descrizione, barra di ricerca, bottoni, immagine laterale e blocco di contenuto aggiuntivo. Disponibile in quattro varianti di sfondo e due allineamenti del contenuto.
Il componente Hero è progettato per la prima sezione visibile di una pagina con:
Livello AA — criteri pertinenti:
<section>, <h1> unico per pagina, <figure> per l’immagineimage.alt sempre presente sull’immagine laterale; stringa vuota se decorativa<section class="rtds-hero"> — landmark di pagina<h1> deve essere unico nella pagina — non usare il componente Hero più di una volta per pagina con un titolo H1image-bg ha aria-hidden="true" — escluso dagli screen reader<figure> — markup semanticamente corretto| Attributo | Valori | Condizione |
|---|---|---|
aria-hidden="true" sull’overlay |
— | solo nella variante image-bg |
alt su <img> |
stringa descrittiva o "" |
sempre presente sull’immagine laterale |
<h1> è il primo heading della pagina — gli screen reader lo annunciano come intestazione principale@search-bararia-hidden="true"<section class="rtds-hero rtds-hero--{background} [rtds-hero--left] [rtds-hero--has-image] [{classes}]"
[style="--hero-bg-image: url(...)"]>
<!-- Solo per variante image-bg -->
<div class="rtds-hero__overlay" aria-hidden="true"></div>
<div class="rtds-container rtds-py-16 rtds-grid rtds-gap-y-10">
<div class="rtds-hero__inner">
<div class="rtds-hero__content">
<h1 class="rtds-hero__title">[title]</h1>
<!-- opzionale -->
<p class="rtds-hero__description">[description]</p>
<!-- opzionale -->
<div class="rtds-hero__search">
<div class="rtds-search-bar" data-search-bar data-all-results-href="/search?q=" data-all-results-label="Tutti i risultati">
<form class="rtds-search-bar__form" role="search" action="/search" method="get">
<div class="rtds-search-bar__wrapper">
<label for="searchBarDefault" class="rtds-search-bar__label rtds-sr-only">
Cerca
</label>
<div class="rtds-search-bar__input-wrapper">
<div class="rtds-search-bar__autocomplete" id="searchBarDefaultContainer" data-placeholder="Search"></div>
<button
type="button"
class="rtds-btn rtds-btn--icon rtds-btn--l rtds-search-bar__clear rtds-border-0 rtds-hidden hover:rtds-background-secondary hover:rtds-text-white"
data-search-clear
>
<span class="rtds-sr-only">Cancella ricerca</span>
<svg
class="rtds-icon rtds-fill-current rtds-w-6 rtds-h-6"
aria-hidden="true"
focusable="false"
role="img"
>
<use href="../../icons.svg#outline--x-circle" />
</svg>
</button>
<button type="submit"
class="rtds-btn
r rtds-btn--icon rtds-btn--icon-square rtds-btn--primary rtds-search-bar__submit rtds-btn--l"
><svg
class="rtds-icon rtds-fill-current rtds-w-6 rtds-h-6"
aria-hidden="true"
focusable="false"
role="img"
>
<use href="../../icons.svg#mini--magnifying-glass" />
</svg>
<span class="rtds-sr-only">
Cerca
</span>
</button>
</div>
</div>
</form>
</div>
</div>
<!-- opzionale -->
<div class="rtds-hero__buttons">
</div>
</div>
<!-- opzionale: solo varianti con immagine laterale -->
<figure class="rtds-hero__image">
<img src="[image.src]" alt="[image.alt]">
</figure>
</div>
<!-- opzionale -->
<div class="rtds-hero__additional">
[additionalContent]
</div>
</div>
</section>title (stringa, obbligatorio): Titolo H1 della sezione. Supporta HTML tramite filtro safe.description (stringa, opzionale): Sottotitolo o testo descrittivo. Supporta HTML.additionalContent (stringa, opzionale): HTML libero nel blocco aggiuntivo sotto la hero (loghi, KPI, testo). null per nascondere il blocco.background (stringa, opzionale): Variante di sfondo. Valori accettati: gradient-bg (default), light-bg, dark-bg, image-bg.bgImage (stringa, opzionale): Percorso dell’immagine di sfondo per la variante image-bg. Passato come custom property CSS --hero-bg-image.alignment (stringa, opzionale): Allineamento del contenuto. Valori: centered (default), left.classes (stringa, opzionale): Classi CSS aggiuntive applicate alla <section> radice.image (oggetto, opzionale): Attiva il layout a due colonne su desktop.image.src (stringa, obbligatorio): Percorso dell’immagine.image.alt (stringa, opzionale): Testo alternativo. Default: stringa vuota.showSearch (booleano, opzionale): Mostra la barra di ricerca. Default: true.searchBar (oggetto, opzionale): Configurazione passata al componente @search-bar:searchId: ID univoco del campo inputlabel: Label del camposubmitLabel: Testo del bottone di submitplaceholder: Placeholder del camposhowLabel: Mostra/nasconde la label visivashowClearButton: Mostra il bottone cancellaformAction: URL di destinazione del formformMethod: Metodo HTTP (get / post)allResultsHref: URL della pagina risultati completiallResultsLabel: Testo del link risultati completibuttons (array, opzionale): Lista di bottoni renderizzati con @button.[].variant (stringa): Suffisso del componente bottone (es. --icon-right).[].context (oggetto): Contesto passato al componente @button:label: Testo del bottonehref: URL di destinazioneclasses: Classi CSS del bottone (variante e dimensione, es. rtds-btn--primary rtds-btn--s)icon: Nome icona (es. mini--chevron-right)Le seguenti proprietà possono essere sovrascritte dall’esterno per personalizzare l’aspetto senza modificare il CSS del componente:
--hero-bg: Colore di sfondo solido.--hero-gradient: Gradiente di sfondo.--hero-bg-image: URL dell’immagine di sfondo (impostato via style inline da Nunjucks).--hero-overlay-bg: Colore dell’overlay per la variante image-bg. Default: rgba(255, 255, 255, 0.5).--hero-image-basis: Larghezza base dell’immagine laterale su desktop. Default: 382px.--hero-title-color: Colore del titolo. Default: var(--color-content-01).--hero-description-color: Colore della descrizione. Default: var(--color-content-03).--hero-additional-bg: Sfondo del blocco additionalContent. Default: var(--color-background-03).--hero-additional-border: Bordo del blocco additionalContent. Default: var(--color-border-gray-02).--hero-additional-text: Colore testo del blocco additionalContent. Default: var(--color-content-01).Il componente include le seguenti varianti:
--color-background-01) con contenuto centrato.--color-background-09) con testi e bottoni invertiti (usa rtds-btn--text-inverted).image-bg-centered ma con contenuto allineato a sinistra.showSearch: false).additionalContent: null).Il componente è completamente responsive:
image, layout a due colonne con contenuto flex-1 e immagine fissa 382×382px.