# EasyForma — Design System del sito pubblico

Documento per chi implementa: landing `/`, `/prezzi`, `/privacy`, `/termini`, checklist di onboarding nella dashboard.
Stack: Laravel + Inertia React 19 + Tailwind 4 + shadcn. Font caricati via Bunny Fonts in `vite.config.ts`.

---

## 1. Concept

La materia prima di EasyForma non è "la formazione online", è **il registro presenze**: il documento su cui l'ente
vive o muore in un audit Forma.Temp. Tutto il resto — aula virtuale, docente, discenti, orari — esiste in funzione
di produrre quel documento senza errori umani. La cosa memorabile del sito è quindi **il registro che si scrive da
solo, in diretta**: nell'hero, invece di uno stat gigante o di un'illustrazione astratta, mostriamo un vero foglio
presenze in formato tabellare che si compila riga per riga davanti all'utente — nome, orario di entrata che appare,
un puntino che diventa "presente", poi l'orario di uscita e la durata calcolata. È la prova del prodotto, non una
metafora. Da questo oggetto (tabella + timestamp + stato) derivano palette, tipografia dei dati e persino il modo
in cui differenziamo il pacchetto Pro (un timbro, non un badge). L'unico altro momento di audacia concesso è questo;
tutto il resto della pagina resta un impaginato quieto, quasi da modulo compilato bene.

**Elemento hero — "Il registro che si scrive da solo"**
Un pannello leggermente ruotato (-1.2°, come un foglio vero appoggiato sul tavolo) con intestazione
`Aula · Sicurezza sul lavoro — modulo 3` e ora corrente. Sotto, una tabella a 4 colonne (Partecipante, Entrata,
Uscita, Durata). Al caricamento della pagina, 4 righe compaiono in sequenza (intervallo ~550ms): il nome sfuma in
vista, poi la cella "Entrata" si scrive con un timestamp in monospace (senza effetto macchina da scrivere carattere
per carattere — troppo gimmick — un semplice fade veloce basta), un pallino accanto al nome pulsa una volta in verde
("in aula"). Dopo una pausa, l'ultima riga completa anche "Uscita" e "Durata" e il pallino diventa un piccolo segno
di spunta dentro un cerchio, come un timbro leggero. L'animazione parte una sola volta, non fa loop infinito: a
sequenza conclusa il pannello resta fermo, statico e leggibile — è un documento, non un widget che deve intrattenere.
Con `prefers-reduced-motion` il pannello appare già nello stato finale, senza alcuna transizione.

---

## 2. Token colore

Sei colori, ruoli fissi. Contrasto verificato (WCAG, formula relative luminance) — vedi valori a fianco.

| Ruolo              | Nome variabile          | Hex       | Uso                                                           | Contrasto verificato                       |
| ------------------ | ----------------------- | --------- | ------------------------------------------------------------- | ------------------------------------------ |
| Sfondo             | `--marketing-bg`        | `#F3F6F4` | sfondo pagina — carta fredda, non crema                       | —                                          |
| Testo              | `--marketing-ink`       | `#142420` | testo principale, titoli                                      | 14.8:1 su `--marketing-bg`                 |
| Accento primario   | `--marketing-primary`   | `#0F6B4F` | CTA primarie, link, stato "presente/verificato"               | 5.96:1 su bg testo · 6.49:1 bianco su fill |
| Accento secondario | `--marketing-secondary` | `#95590F` | stato "in corso", evidenze secondarie, hover su elementi dati | 5.2:1 su bg testo · 5.65:1 bianco su fill  |
| Superficie         | `--marketing-surface`   | `#FFFFFF` | card, pannello del registro, header sticky                    | 16.1:1 testo ink su superficie             |
| Segnale di stato   | `--marketing-signal`    | `#9B2C2C` | avvisi, "non conforme", errori form                           | 6.92:1 su bg testo · 7.53:1 bianco su fill |

Tutte le coppie testo/sfondo usate nella pagina superano AA (≥4.5:1 per testo normale). L'ambra secondaria è stata
scurita rispetto al primo tentativo (`#B5701F`, 3.6:1 — solo AA-large) proprio per poterla usare anche in badge di
testo piccolo, non solo in elementi grafici larghi.

**Superato da §2 bis**: questo paragrafo prescriveva due palette separate, quella dell'app e quella con prefisso
`--marketing-`. Oggi la palette è una sola, questa, e i token `--marketing-*` sono alias dei valori di marca. I
ruoli e i colori qui sopra restano validi; cambia solo dove vivono e chi li usa.

Per come questi valori vivono oggi in `app.css` — una sola dichiarazione `--brand-*` in oklch, referenziata
sia dai token shadcn sia dagli alias `--marketing-*` — vedi §2 bis.

**Dark mode**: le pagine pubbliche restano volutamente solo chiare. Il pubblico target (responsabili
formazione/amministrativi che leggono moduli, non sviluppatori) associa il chiaro a "documento ufficiale
leggibile"; introdurre un dark mode marketing sarebbe uno sforzo di token/QA non richiesto dal brief. La checklist
di onboarding, invece, vive _dentro_ l'app e **deve** seguire il tema dell'utente: per quella non si usano i token
`--marketing-*`, si riusano i token shadcn esistenti (vedi §5).

---

## 2 bis. Palette unica

Aggiornamento: **il prodotto usa una palette sola, questa.** I token `--marketing-*` descritti sopra non sono
più una palette a parte — sono alias degli stessi valori che alimentano l'app. Gli esadecimali vivono una volta
sola in `resources/css/app.css`, come variabili `--brand-*` scritte in oklch con l'esadecimale di riferimento nel
commento a fianco; da lì li referenziano sia i token shadcn (`:root` e `.dark`) sia i token `--marketing-*`.
Nessun colore letterale va scritto altrove, né in CSS né in una classe Tailwind della tavolozza di default
(`text-green-600`, `bg-neutral-100`, `text-amber-700`, ...).

I ruoli di §2 restano: carta fredda di fondo, inchiostro verde-nero, verde "presente/verificato", ambra
"in corso", rosso "non conforme". Il raggio scende a **0.5rem** anche nell'app (era 0.625rem), così i bordi
dell'interfaccia e quelli della vetrina sono gli stessi.

### Cosa mappa dove

| Token shadcn                 | Chiaro                            | Scuro                       |
| ---------------------------- | --------------------------------- | --------------------------- |
| `--background`               | `#F3F6F4` carta fredda            | `#0F1A16` verde-notte       |
| `--foreground`               | `#142420`                         | `#F3F6F4`                   |
| `--card` / `--popover`       | `#FFFFFF` / `#FFFFFF`             | `#16231E` / `#1A2922`       |
| `--primary`                  | `#0F6B4F`                         | `#46A883`                   |
| `--primary-foreground`       | `#FFFFFF`                         | `#0B1512`                   |
| `--secondary` / `--muted`    | `#E7EDE9`                         | `#1E2E27`                   |
| `--muted-foreground`         | `#556A62`                         | `#93A9A0`                   |
| `--accent`                   | `#E1EBE5`                         | `#22332B`                   |
| `--warning` (nuovo)          | `#95590F`                         | `#D9973C`                   |
| `--warning-foreground`       | `#FFFFFF`                         | `#0B1512`                   |
| `--destructive` (e `-fore.`) | `#9B2C2C`                         | `#E98B86`                   |
| `--border`                   | `#DBE5E0`                         | `#27382F`                   |
| `--input`                    | `#839089`                         | `#62706A`                   |
| `--ring`                     | `#0F6B4F`                         | `#46A883`                   |
| `--sidebar`                  | `#E9EFEB` (carta un tono più giù) | `#0B1512` (notte più fonda) |
| `--sidebar-primary`          | `#0F6B4F` (voce attiva)           | `#46A883`                   |
| `--sidebar-accent`           | `#DCE8E1`                         | `#1D2D26`                   |
| `--sidebar-border`           | `#CBDAD2`                         | `#27382F`                   |
| `--radius`                   | `0.5rem`                          | `0.5rem`                    |

Tre scelte da non rileggere come sviste:

- **`--secondary` non è l'ambra.** In shadcn `secondary` è una superficie quieta — il bottone "Annulla", il badge
  neutro — e va tenuta tale, altrimenti mezza interfaccia diventa arancione. L'ambra vive nella coppia
  **`--warning` / `--warning-foreground`**, aggiunta apposta: `text-warning` per il testo su fondo pagina,
  `bg-warning text-warning-foreground` per un riempimento.
- **`--destructive` e `--destructive-foreground` sono lo stesso rosso.** Le varianti shadcn usano il primo come
  riempimento (con `text-white` imposto dalla variante) e il secondo come testo su fondo pagina: un unico valore
  regge entrambi i ruoli in AA, in tutti e due i temi.
- **Le pagine pubbliche restano solo chiare**, come deciso in §2. Non basta che i token `--marketing-*` puntino
  ai valori chiari: dentro la vetrina finiscono anche componenti che leggono `--card`, `--border` e compagni. Per
  questo il contenitore di `MarketingLayout` porta la classe **`.marketing-scope`**, che ridichiara sul proprio
  sottoalbero sia i token semantici sia gli alias `--color-*` del blocco `@theme` — Tailwind 4 risolve
  quell'indirezione su `:root`, quindi ridichiarare solo i primi non avrebbe alcun effetto. Le pagine di accesso
  invece stanno dentro l'app e seguono il tema dell'utente, quindi sono costruite sui token semantici, che in
  tema chiaro _sono_ i valori della vetrina.

### Contrasti verificati (WCAG 2.1, relative luminance)

Ogni coppia usata per del testo supera AA (≥4.5:1). I bordi dei campi superano i 3:1 richiesti agli elementi
d'interfaccia.

| Coppia                                            | Chiaro  | Scuro    |
| ------------------------------------------------- | ------- | -------- |
| `foreground` su `background`                      | 14.81:1 | 16.36:1  |
| `foreground` su `card`                            | 16.12:1 | 14.92:1  |
| `foreground` su `popover`                         | 16.12:1 | 13.94:1  |
| `muted-foreground` su `background`                | 5.33:1  | 7.14:1   |
| `muted-foreground` su `card`                      | 5.79:1  | 6.51:1   |
| `muted-foreground` su `muted`                     | 4.88:1  | 5.71:1   |
| `primary` come testo su `background`              | 5.96:1  | 6.09:1   |
| `primary` come testo su `card`                    | 6.49:1  | 5.56:1   |
| `primary-foreground` su `primary`                 | 6.49:1  | 6.36:1   |
| `warning` come testo su `background`              | 5.20:1  | 7.16:1   |
| `warning` come testo su `card`                    | 5.65:1  | 6.53:1   |
| `warning-foreground` su `warning`                 | 5.65:1  | 7.47:1   |
| `destructive-foreground` su `background`          | 6.92:1  | 7.21:1   |
| `destructive-foreground` su `card`                | 7.53:1  | 6.57:1   |
| bianco sul riempimento `destructive`              | 7.53:1  | 5.29:1\* |
| `accent-foreground` su `accent`                   | 13.21:1 | 12.24:1  |
| `sidebar-foreground` su `sidebar`                 | 13.82:1 | 17.08:1  |
| `sidebar-primary-foreground` su `sidebar-primary` | 6.49:1  | 6.36:1   |
| bordo `input` su `card` (non testo, soglia 3:1)   | 3.33:1  | 3.13:1   |
| bordo `input` su `background`                     | 3.06:1  | 3.43:1   |

\* in tema scuro le varianti shadcn riempiono con `bg-destructive/60`, quindi il valore è misurato sulla
composizione al 60% sopra il fondo.

### Le otto tinte del calendario

Servono a distinguere le aule nel calendario e le serie nei grafici (`--chart-1…5` sono le prime cinque). Stessa
chiarezza, tonalità a 45° l'una dall'altra: nessuna aula urla più delle altre e tutte restano ≥3:1 sui due fondi,
soglia giusta perché sono elementi grafici — pallini, barre, bordi — mai testo. Il testo dentro le chip del
calendario usa sempre i token del tema.

| #   | Hex       | su `#F3F6F4` | su `#0F1A16` |
| --- | --------- | ------------ | ------------ |
| 1   | `#009160` | 3.70:1       | 4.42:1       |
| 2   | `#008DA1` | 3.62:1       | 4.51:1       |
| 3   | `#347BC5` | 4.03:1       | 4.06:1       |
| 4   | `#8265BE` | 4.24:1       | 3.86:1       |
| 5   | `#AD558F` | 4.31:1       | 3.79:1       |
| 6   | `#BB544C` | 4.30:1       | 3.80:1       |
| 7   | `#A96900` | 4.10:1       | 3.99:1       |
| 8   | `#748200` | 3.91:1       | 4.18:1       |

La lista vive in tre posti che vanno cambiati insieme: `Classroom::COLORS` (la sorgente, il colore dell'aula si
calcola dal suo uuid), `--brand-hue-*` in `app.css` e il fallback in `resources/js/lib/classroom-color.ts`.

### Pagine di accesso

Login, registrazione, password dimenticata, reimpostazione, verifica email, secondo fattore e conferma password
passano tutte dallo stesso layout (`resources/js/layouts/auth/auth-split-layout.tsx`, unico template dietro
`auth-layout.tsx`). Da `lg` la pagina si divide in due: a sinistra, su carta, il lockup che torna al sito, la
promessa in Archivo, il pannello del registro **già chiuso** e i link legali; a destra, su superficie bianca, il
form. Sotto `lg` le due metà si impilano con il form per primo, perché è lui l'attore, e il registro chiude la
pagina come promemoria.

Il pannello del registro è lo stesso componente della vetrina
(`resources/js/components/marketing/attendance-panel.tsx`), con `animate={false}`: una dimostrazione che si
riavvia a ogni tentativo di login sarebbe un fastidio, non una prova. Archivo e IBM Plex Mono sono già caricati
per tutta l'applicazione da `vite.config.ts`, quindi le pagine di accesso non aggiungono nessun font.

Quando si arriva da `/prezzi` con `?package=`, la registrazione mostra il piano scelto per nome, prezzo e crediti
(risolto lato server da `FortifyServiceProvider`, che ignora uno slug sconosciuto) e lo passa comunque al form nel
campo nascosto, come prima.

---

## 3. Tipografia

Due famiglie per la prosa, più una terza **solo funzionale** per i dati tabellari (timestamp, durate, prezzi) —
coerente con il concept: i numeri del registro sono un elemento di design, non testo qualunque.

- **Archivo** (700/600) — titoli e display. Grottesca con presenza da segnaletica istituzionale: comunica
  "ente accreditato" senza scadere nel bancario né nell'editoriale. Disponibile su Bunny Fonts.
- **Instrument Sans** (400/500) — corpo testo, lead, small. È già caricata nell'app: nessun font nuovo da
  aggiungere per il body, un solo file in più (Archivo) per i titoli.
- **IBM Plex Mono** (500) — _solo_ per timestamp, durate, prezzi e cifre nella tabella del registro e nei pacchetti.
  Numeri tabulari (`font-variant-numeric: tabular-nums`). Mai usata per label, eyebrow o corpo testo.

Fallback: `Archivo, 'Helvetica Neue', Arial, sans-serif` · `'Instrument Sans', ui-sans-serif, system-ui, sans-serif`
· `'IBM Plex Mono', ui-monospace, 'SFMono-Regular', monospace`.

| Ruolo                           | Font            | Dimensione                               | Peso    | Line-height | Note                                  |
| ------------------------------- | --------------- | ---------------------------------------- | ------- | ----------- | ------------------------------------- |
| Display (hero)                  | Archivo         | 3.25rem / 2rem mobile                    | 700     | 1.08        | letter-spacing -0.01em, max 2 righe   |
| H1 (titolo sezione)             | Archivo         | 2.25rem / 1.75rem mobile                 | 700     | 1.15        | letter-spacing -0.005em               |
| H2 (sottosezione)               | Archivo         | 1.5rem                                   | 600     | 1.25        | —                                     |
| H3 (card, domanda FAQ)          | Archivo         | 1.125rem                                 | 600     | 1.35        | —                                     |
| Lead (sottotitolo hero/sezione) | Instrument Sans | 1.25rem                                  | 400     | 1.55        | max-width 38rem                       |
| Body                            | Instrument Sans | 1rem                                     | 400     | 1.6         | max-width 34–38rem (~70–75 caratteri) |
| Small (didascalie, legal)       | Instrument Sans | 0.875rem                                 | 400/500 | 1.5         | —                                     |
| Dati/mono (timestamp, prezzi)   | IBM Plex Mono   | 0.9375rem (0.8125rem in tabella stretta) | 500     | 1.4         | tabular-nums                          |

Regole vincolanti:

- Nessuna eyebrow maiuscola sopra i titoli (niente "COME FUNZIONA" tracciato sopra "Tre passi, un solo login").
  Il titolo stesso porta l'informazione.
- Nessuna singola parola colorata o in corsivo dentro un titolo per creare enfasi finta.
- Nei titoli, l'unico corsivo tabulare ammesso è quello reale del monospace sui numeri (es. il prezzo dentro la
  card pacchetto), perché lì il cambio di font è funzionale, non decorativo.
- Le maiuscole sono ammesse in un solo punto, esplicitamente eccezionale: il testo dentro il timbro grafico del
  pacchetto Pro (§5), perché imita un vero timbro a inchiostro, non un'etichetta tipografica.

---

## 4. Layout

**Allineamento**: testo a sinistra come default su tutta la pagina, non centrato. Il pubblico legge moduli e tabelle
tutto il giorno: un impaginato "a modulo", con margine sinistro costante e titoli che iniziano dallo stesso filo,
comunica ordine meglio di un hero centrato da landing page generica. Uniche eccezioni centrate: la riga dei 3 pacchetti
(gruppo di card, centrata come blocco — il testo dentro ogni card resta a sinistra) e il toggle mensile/pacchetto
singolo in `/prezzi`.

**Griglia**: 12 colonne, gutter 1.5rem. Contenitore largo max 72rem (1152px) per hero/sezioni full-bleed, testo
vincolato a max 38rem dentro quel contenitore. Ritmo verticale: 6rem tra sezioni su desktop, 3.5rem su mobile;
padding interno sezione 5rem verticale desktop, 3rem mobile. Raggio: `--marketing-radius` 0.5rem su card e pannello
registro, `--marketing-radius-sm` 0.25rem su bottoni e input — più squadrato del raggio 0.625rem già in uso
nell'app, per un tono da modulo compilato piuttosto che da bottone "morbido" da app consumer.

### Landing — desktop (≥1024px)

```
┌───────────────────────────────────────────────────────────────────────┐
│ EasyForma   Come funziona  Conformità  Prezzi  FAQ        Accedi  [Crea account] │ ← sticky, bordo 1px sotto
├───────────────────────────────────────────────────────────────────────┤
│  HERO                                                                   │
│  Le aule finanziate da Forma.Temp,        ┌─────────────────────────┐ │
│  con il registro già pronto per l'audit.  │ Aula · Sicurezza sul    │ │
│                                            │ lavoro — modulo 3  09:14│ │
│  Lead: crea l'aula, invita i discenti,    │ ───────────────────────│ │
│  il registro si compila da solo mentre    │ Nome      Entr.  Usc.  │ │
│  la lezione va avanti.                    │ M. Rossi  09:03  ●     │ │
│                                            │ A. Bianchi 09:04  ●     │ │
│  [Crea il tuo account]  [Vedi i prezzi]   │ L. Verdi  09:05  09:47 │ │
│                                            └─────────────────────────┘ │
├───────────────────────────────────────────────────────────────────────┤
│  IL PROBLEMA (testo, 2 col: problema / conseguenza — max 38rem)        │
├───────────────────────────────────────────────────────────────────────┤
│  COME FUNZIONA IN 3 PASSI (sequenza reale → numerata)                  │
│  1 Crea l'aula        2 Invita chi partecipa     3 Il registro si fa   │
│  e imposta orario     (docente + discenti,       da solo: entrate,     │
│  e durata massima     un link personale a testa) uscite, export CSV    │
├───────────────────────────────────────────────────────────────────────┤
│  CONFORMITÀ FAD SINCRONA — 5 requisiti (lista appaiata, non card)      │
│  Requisito vademecum          ─────           Come lo copre EasyForma   │
│  Identità reale del discente  ─────           Link personale per...    │
│  Timestamp entrata/uscita     ─────           Ogni intervallo user-... │
│  ... (5 righe, hairline tra le righe)                                  │
├───────────────────────────────────────────────────────────────────────┤
│  FUNZIONALITÀ (lista a righe, 2 colonne, divisori hairline — no card)  │
├───────────────────────────────────────────────────────────────────────┤
│  PER CHI È — Ente accreditato | Agenzia per il lavoro (2 col, testo)   │
├───────────────────────────────────────────────────────────────────────┤
│  ANTEPRIMA PACCHETTI — 3 card centrate come gruppo, Pro con timbro     │
│  [Starter]        [Pro ● timbro]        [Enterprise]                   │
│                    Vedi tutti i dettagli →/prezzi (link testo)         │
├───────────────────────────────────────────────────────────────────────┤
│  FAQ — accordion, domande a sinistra, max-width 38rem                  │
├───────────────────────────────────────────────────────────────────────┤
│  CTA FINALE — titolo + bottone primario, sfondo --marketing-surface    │
├───────────────────────────────────────────────────────────────────────┤
│  FOOTER — colonne: Prodotto / Risorse / Legale, poi riga P.IVA+© a sx  │
└───────────────────────────────────────────────────────────────────────┘
```

### Landing — mobile (<640px)

```
┌──────────────────────────┐
│ EasyForma         [☰]     │  ← hamburger: Come funziona, Conformità,
├──────────────────────────┤     Prezzi, FAQ, Accedi, Crea account
│ Le aule finanziate da    │
│ Forma.Temp, con il       │
│ registro già pronto      │
│ per l'audit.             │
│                          │
│ Lead in 2 righe.         │
│                          │
│ [Crea il tuo account]    │
│ [Vedi i prezzi]          │
│                          │
│ ┌──────────────────────┐│  ← pannello registro sotto il testo,
│ │ Aula · Sicurezza...   ││     stessa larghezza del contenuto,
│ │ Nome   Entr.   Usc.   ││     non ritagliato
│ │ Rossi  09:03   ●      ││
│ └──────────────────────┘│
├──────────────────────────┤
│ Problema (1 colonna)     │
├──────────────────────────┤
│ 1 Crea l'aula            │
│ 2 Invita chi partecipa   │
│ 3 Il registro si fa solo │
├──────────────────────────┤
│ Conformità: 5 righe       │
│ impilate (requisito sopra,│
│ copertura sotto, hairline)│
├──────────────────────────┤
│ Funzionalità (1 colonna) │
├──────────────────────────┤
│ Per chi è (impilato)     │
├──────────────────────────┤
│ Pacchetti (card impilate,│
│ Pro al centro con timbro)│
├──────────────────────────┤
│ FAQ (accordion)          │
├──────────────────────────┤
│ CTA finale               │
├──────────────────────────┤
│ Footer (colonne impilate)│
└──────────────────────────┘
```

### `/prezzi`

```
┌───────────────────────────────────────────────────────────┐
│ Header (identico alla landing)                              │
├───────────────────────────────────────────────────────────┤
│  Titolo H1 a sinistra: "Un pacchetto di aule, senza         │
│  abbonamenti nascosti"  + lead                               │
│  [Abbonamento mensile ○──●]  (toggle centrato sotto il lead) │
├───────────────────────────────────────────────────────────┤
│  [ Starter 149€ ]   [ Pro 599€ ● timbro ]   [ Enterprise ]   │
│  (3 card centrate come gruppo, stessa altezza, Pro al centro)│
├───────────────────────────────────────────────────────────┤
│  Tabella comparativa dettagliata (aule incluse, discenti     │
│  max, ore max per aula, export, supporto) — righe hairline,  │
│  cifre in IBM Plex Mono                                      │
├───────────────────────────────────────────────────────────┤
│  FAQ prezzi (sottoinsieme, 4-5 domande specifiche fatturazione)│
├───────────────────────────────────────────────────────────┤
│  CTA finale + Footer                                          │
└───────────────────────────────────────────────────────────┘
```

### `/privacy`, `/termini`

Colonna singola, max-width 38rem, allineata a sinistra (mai centrata: è testo lungo, non marketing). Header
identico ma senza il bottone "Crea account" enfatizzato (resta ghost). Sommario cliccabile in cima solo se il
documento supera ~6 sezioni, come lista di link `Small`, non come sidebar. Titoli di sezione in H2, non H1, per
non competere con l'H1 di pagina ("Termini di servizio" / "Privacy policy").

---

## 5. Componenti

**Header di navigazione** — sticky, sfondo `--marketing-surface`, bordo inferiore 1px `--marketing-border` (niente
ombra). Logo a sinistra come wordmark in Archivo 600. Voci di nav (`Come funziona`, `Conformità`, `Prezzi`, `FAQ`)
in Instrument Sans 0.9375rem, peso 500, colore ink 80% opacità, hover a ink pieno con sottolineatura 1px offset
0.25em (niente background pillola sull'hover). A destra: `Accedi` come link testo, `Crea account` come bottone
primario. Sotto 1024px collassa in hamburger con pannello a tutta larghezza.

**Bottone primario** — sfondo `--marketing-primary`, testo `--marketing-primary-foreground`, radius
`--marketing-radius-sm`, padding 0.75rem 1.25rem, Instrument Sans 500. Nessuna icona freccia. Hover: sfondo
scurito dell'8% (non un'ombra). Testo dei bottoni = azione diretta e concreta: "Crea il tuo account",
"Acquista pacchetto Pro" — mai "Inizia ora" generico o "Scopri di più".

**Bottone secondario** — bordo 1px `--marketing-ink` 25% opacità, testo ink, sfondo trasparente. Hover: sfondo
`--marketing-ink` al 5%.

**Card pacchetto** — bordo 1px `--marketing-border`, radius `--marketing-radius`, sfondo `--marketing-surface`,
nessuna ombra. Contenuto: nome pacchetto (H3), prezzo in IBM Plex Mono grande (es. `599 €`) con unità "una
tantum" o "/mese" in Small accanto, poi lista di ciò che include in body/small, bottone in fondo.
_Differenziazione del Pro senza badge_: nessun ribbon "CONSIGLIATO" in alto a destra. Invece, un **timbro
circolare** (diametro ~3.5rem, tratto singolo 1.5px, colore `--marketing-primary`, ruotato -5°, sovrapposto
all'angolo del blocco prezzo) con testo interno maiuscolo piccolo `SCELTA PIÙ FREQUENTE` (l'unica maiuscola
concessa nel sistema, motivata in §3). È un dispositivo coerente con un pubblico che nei propri moduli reali
riceve e appone timbri — non un elemento SaaS generico. In aggiunta, solo la card Pro ha bordo `--marketing-primary`
1.5px invece del bordo neutro; Starter ed Enterprise restano piatte.

**Blocco requisito → copertura** (sezione Conformità) — non è una griglia di card con icone. È una lista di 5
righe appaiate, separate da hairline `--marketing-border`: colonna sinistra "Requisito richiesto" (Body, ink),
un connettore centrale minimo (un trattino 1.5rem, non una freccia), colonna destra "Come lo copre EasyForma"
(Body) con eventuali riferimenti tecnici in IBM Plex Mono piccolo (es. `webhook + polling ogni 3 min`). Il
dispositivo grafico (righe appaiate) codifica l'informazione reale: ogni riga è una promessa e la sua prova.

**FAQ** — accordion, non lista sempre aperta. Motivazione: il pubblico arriva con una domanda precisa
(fatturazione, requisiti tecnici, cosa succede se manca un webhook) e scansiona i titoli delle domande più che
legge in ordine; un accordion collassato riduce il rumore su una pagina già densa di sezioni informative. Domanda
in H3 su riga cliccabile a tutta larghezza, indicatore `+`/`–` a destra (non un chevron che ruota — un
plus che si trasforma in trattino, coerente con l'estetica "modulo/timbro" più che "app"). Risposta in Body,
transizione di altezza 200ms ease-out; con `prefers-reduced-motion` il toggle è istantaneo.

**Footer** — sfondo `--marketing-bg`, bordo superiore 1px. Tre colonne a sinistra (Prodotto, Risorse, Legale) in
Small, poi riga finale con ragione sociale/P.IVA placeholder e copyright, sempre a sinistra. Nessuna icona social
se non esistono profili reali da collegare.

**Checklist onboarding (dashboard)** — vive dentro una `Card` shadcn esistente, non introduce token `--marketing-*`.
Header della card: titolo "Configurazione dell'account" + contatore `3 di 5 completati` con una barra segmentata
a 5 blocchi (blocco pieno = `--color-chart-2`, il verde-teal già definito nella palette chart dell'app; blocco
vuoto = `--muted`) — 5 segmenti reali per 5 step reali, non un progress bar continuo generico. Ogni riga step:
cerchio indicatore 1.5rem (vuoto, bordo `--border` = da fare; pieno `--color-chart-2` con spunta bianca = fatto),
collegato al successivo da una linea verticale 1px `--border`, testo dello step in `--foreground`/`--muted-foreground`
a seconda dello stato, azione a destra (link o bottone `outline` shadcn). I 5 step, dedotti dal modello dati
reale del prodotto: completa il profilo azienda, collega le credenziali Forma.Temp, acquista un pacchetto aule,
crea la prima aula, carica i discenti e invita il docente. Nessun colore nuovo: riusa `--chart-2` proprio perché
è già verde-successo nel set esistente, così l'onboarding non introduce una seconda identità cromatica nella
dashboard.

---

## 6. Motion

Un solo momento orchestrato: l'animazione del pannello registro in hero, descritta in §1 (4 righe che compaiono in
sequenza con intervallo ~550ms, un pallino che pulsa una volta da "in aula" a spunta, sequenza che parte una volta
sola al mount e poi resta ferma). Nessun'altra sezione ha ingressi fade/slide-up al reveal, nessun hover-lift sulle
card pacchetto: gli hover si limitano a un cambio di colore/bordo, mai un movimento o un'ombra che appare.
L'accordion FAQ è motion "risposta a un'azione dell'utente" (si apre perché l'utente clicca), quindi ammesso di
default anche con `prefers-reduced-motion`, ma senza transizione di altezza (toggle istantaneo).

Regola `prefers-reduced-motion: reduce`: il pannello registro in hero renderizza direttamente lo stato finale (le
4 righe già compilate, incluso l'ultima con uscita/durata), senza alcun fade o pulse; l'accordion apre/chiude
senza transizione di altezza.

---

## 7. Autocritica

1. **Prima idea di palette**: sfondo crema + serif alto contrasto + accento terracotta — il default esatto da
   evitare. L'ho sostituita con una carta fredda verde-grigia, un grottesco istituzionale (Archivo) e un
   verde-verifica/ambra derivati dal linguaggio degli stati di presenza (verificato/in corso), non da un'estetica
   editoriale generica.
2. **Prima idea di hero**: un numero grande ("-40% tempo di rendicontazione") con sottotitolo e un blob sfumato
   decorativo dietro — il default da stat-hero. L'ho sostituita con il pannello del registro che si compila in
   diretta, perché è letteralmente il prodotto e risponde all'ansia specifica del pubblico (l'audit), non una
   promessa astratta.
3. **Prima idea per il pacchetto Pro**: un ribbon "CONSIGLIATO" in alto a destra sulla card, il badge SaaS più
   comune in assoluto. L'ho sostituito con un timbro circolare ruotato, coerente con il fatto che questo pubblico
   riceve e appone timbri su documenti reali tutti i giorni — differenzia la card senza il linguaggio da e-commerce.
