From 063972dd7cadacecbdc036265812db60c522b385 Mon Sep 17 00:00:00 2001 From: AdrianoDev Date: Wed, 1 Jul 2026 23:11:45 +0200 Subject: [PATCH] Aggiunge design spec sito InsanityLab Co-Authored-By: Claude Fable 5 --- .../2026-07-01-insanitylab-website-design.md | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 docs/superpowers/specs/2026-07-01-insanitylab-website-design.md diff --git a/docs/superpowers/specs/2026-07-01-insanitylab-website-design.md b/docs/superpowers/specs/2026-07-01-insanitylab-website-design.md new file mode 100644 index 0000000..f0c7af1 --- /dev/null +++ b/docs/superpowers/specs/2026-07-01-insanitylab-website-design.md @@ -0,0 +1,130 @@ +# Sito web InsanityLab — Design + +**Data:** 2026-07-01 +**Dominio di destinazione:** insanitylab.tielogic.xyz (VPS Hostinger, porting in fase successiva) +**Stato:** approvato dall'operatore durante la sessione di brainstorming + +## Obiettivo + +Realizzare il sito vetrina di InsanityLab (centro di allenamento e benessere, Bologna) a partire dal design Figma fornito dal designer (`FigmaDoc/*.pdf`, `Web Insanity.fig`), che ristilizza il template WordPress "Prowess" (analizzato in `Dati/cassetta-me-analisi.md`) con una palette beige/marrone al posto del rosso originale. Il sito include un blog gestibile dal cliente tramite pannello protetto da login e un form contatti che invia email. La gestione degli acquisti online (pagina prezzi Performance Class) è rimandata a una fase successiva. + +## Stack + +| Livello | Scelta | +|---|---| +| Framework | Astro 5, output `server` con adapter Node | +| Pagine vetrina | Prerenderizzate (`prerender = true`) | +| Blog e admin | Server-rendered | +| Stile | CSS custom (palette estratta dai PDF Figma), nessun framework CSS | +| Font | Montserrat (titoli) + Open Sans (corpo), self-hosted | +| JS client | Vanilla, minimo indispensabile (slider, tab, accordion, header sticky) | +| Database | SQLite via `better-sqlite3`, file `data/insanitylab.db` | +| Editor admin | WYSIWYG TipTap, con upload immagini nel corpo articolo | +| Email | nodemailer → SMTP (credenziali via `.env`) | +| Test | vitest (logica) + smoke test su build | +| Versionamento | git dal primo commit, remote su GitLab | +| Deploy (fase 2) | Dockerfile multi-stage + compose, gestito poi via Komodo sul VPS | + +Motivazione: sito prevalentemente statico con una sola area dinamica (blog). Un'unica applicazione Node leggera evita la manutenzione di un CMS completo, mantiene ottime prestazioni e SEO, e resta estendibile (pagamenti in fase futura). + +## Route + +### Pubbliche + +| Route | Contenuto | Fonte design | +|---|---|---| +| `/` | Homepage: hero slider, 3 colonne Performance/Balance/Longevity, feature alternata, banner citazione, Training (4 card), Programmi (6 icone), Agenda con tab, Team trainer, Metodo (4 step), loghi partner (Ticket Welfare Edenred, Welbee, AON, Howden), footer con mini-form | Homepage.pdf | +| `/about` | Mission, direzione, approccio, about, timeline "Storylab" (2021-2024 aperta; +2025, +2026, +oggi ad accordion), convenzioni aziendali, team completo (9 persone), metodo, IN-SANITY STUDIOS, vision | Insanitylab.pdf | +| `/training` | 4 servizi (One to One, Small Groups, Performance Class, Fit Remote) con blocchi alternati, agenda, CTA "prenota la lezione di prova" | Training.pdf | +| `/programs` | Griglia 6 programmi con testi reali | Programmi.pdf | +| `/programs/[slug]` | Pagina dettaglio per ogni programma: `personal-training`, `performance-class`, `coaching`, `pilates-flow`, `rehab`, `nutrition` | Performance class.pdf | +| `/blog` | Blog & Edugo: intro, filtri per categoria, griglia articoli, paginazione | Blog & Edugo.pdf | +| `/blog/[slug]` | Articolo singolo con sidebar (autore, categorie, ultimi articoli, archivio) | Articolo.pdf | +| `/contact` | Form contatti (Nome, Cognome, Telefono, E-mail, Messaggio), mappa Google, recapiti | Contatti.pdf | + +Dettaglio programmi: layout unico modellato su Performance class.pdf (FAQ ad accordion, descrizione, sidebar categorie + altri programmi). Il blocco pricing compare solo dove esistono prezzi — al lancio solo `performance-class` (3 piani semestrali: 130/234/300 € al mese, con varianti trimestrale e mensile ad accordion). I bottoni "acquista" puntano per ora a `/contact`. I testi degli altri cinque programmi partono dalle descrizioni di Programmi.pdf; il cliente li integrerà. + +### Admin (richiedono sessione) + +| Route | Funzione | +|---|---| +| `/admin/login` | Login user/password | +| `/admin` | Elenco articoli (pubblicati e bozze) | +| `/admin/new` | Nuovo articolo | +| `/admin/edit/[id]` | Modifica articolo | + +### API + +| Endpoint | Funzione | +|---|---| +| `POST /api/contact` | Invio email form contatti (honeypot antispam + rate-limit) | +| `POST/PUT/DELETE /api/admin/posts*` | CRUD articoli (sessione richiesta) | +| `POST /api/admin/upload` | Upload immagini (copertina e corpo articolo, salvate in `public/uploads/`) | + +## Design system + +- **Palette** (valori esatti da campionare dai PDF in fase di implementazione): accento beige/tan ~`#b8a98a` (bottoni, etichette), marrone scuro ~`#3a2e28` (sezioni dark: agenda, banner citazione, footer, card scure), fondi chiari `#f5f3f0`/bianco. +- **Tipografia**: Montserrat uppercase con letterspacing largo per titoli e bottoni; Open Sans per il corpo. File woff2 self-hosted (niente Google Fonts CDN, conformità GDPR). +- **Componenti chiave**: header sticky (trasparente sopra l'hero, bianco con ombra allo scroll), hero slider (scroll-snap CSS + JS vanilla), card programma testo/foto alternate, agenda settimanale con tab per disciplina, accordion FAQ e pricing, form con stati di validazione. +- **Responsive**: mobile-first; il Figma è solo desktop (1366 px), il comportamento mobile si deriva dalle convenzioni del template (menu hamburger sotto i 992 px, griglie che collassano a colonna). +- **Immagini**: estratte dall'archivio `Web Insanity.fig` (è uno ZIP con cartella `images/`; i file hanno nomi hash e vanno identificati visivamente e rinominati per sezione). Fallback: asset in `Dati/` e estrazione da PDF con `pdfimages`. Ottimizzazione con `astro:assets` (webp, lazy loading, srcset). +- **SEO**: title/description per pagina, Open Graph, sitemap, robots.txt, favicon dal logo. +- **Mappa contatti**: iframe Google Maps con click-to-load (consenso prima del caricamento, GDPR). + +## Backend + +### Database + +SQLite in `data/insanitylab.db` (fuori da `src/`, montabile come volume Docker in fase 2). Schema creato da script SQL idempotente all'avvio. + +```sql +posts (id, title, slug UNIQUE, category, excerpt, body_html, + cover, published_at, draft, created_at, updated_at) +users (id, username UNIQUE, password_hash) +sessions (token PK, user_id, expires_at) +``` + +Categorie blog fisse (da Figma): Articoli tecnici & scientifici, Contenuti educativi, LinkedIn / Insight, Eventi & Presidi. + +Il corpo articolo è HTML prodotto da TipTap, sanitizzato lato server prima del salvataggio e del rendering. + +### Autenticazione + +- Password con hash bcrypt; utenti creati via script CLI (`npm run create-user`). +- Sessione: token random in cookie httpOnly, SameSite=Lax, scadenza 7 giorni, verificata da middleware su tutte le route `/admin` e `/api/admin`. +- Rate-limit sul login (protezione brute force). + +### Email + +`POST /api/contact` valida i campi, applica honeypot e rate-limit, invia via nodemailer con SMTP configurato in `.env` (host, porta, credenziali, destinatario — default `info@insanitylab.it`). Risposta JSON per feedback inline nel form. + +### Dati statici + +Agenda settimanale, prezzi, team, programmi, loghi partner: file TypeScript/JSON in `src/data/`, modificati dallo sviluppatore e versionati in git. Nessuna gestione da admin per questi contenuti al lancio. + +## Deploy + +- **Fase attuale (locale)**: `npm run dev`; build verificata con `npm run build && npm run preview`. +- **Versionamento**: repository git con remote su GitLab (namespace da confermare in fase di implementazione). +- **Fase 2 (VPS)**: Dockerfile multi-stage (build → `node:22-slim`), `compose.yaml` con volumi per `data/` e `public/uploads/`, porta interna 4321; aggancio a Komodo e reverse proxy per `insanitylab.tielogic.xyz` quando si porterà in produzione. Fuori scope di questa spec. + +## Gestione errori + +- Form contatti: validazione client + server, messaggi di errore inline, fallback se SMTP non risponde (errore esplicito all'utente, log lato server). +- Admin: redirect a `/admin/login` se sessione assente/scaduta; conferma prima dell'eliminazione articoli. +- 404 personalizzata coerente col design. +- Upload: limite dimensione (5 MB) e whitelist tipi immagine. + +## Test e verifica + +- vitest su: helper slug, validazione form, auth (hash/sessioni), query posts. +- Smoke test: build completa senza errori; fetch delle route principali con risposta 200 e contenuti attesi. +- Verifica visiva locale contro i PDF Figma pagina per pagina. + +## Fuori scope (fasi future) + +- Pagamenti online piani Performance Class (Stripe o simile). +- Gestione da admin di agenda, prezzi, team. +- Porting su VPS, DNS, TLS (fase 2 dedicata). +- Ricerca nel blog e ricerca globale (icona lente del template: omessa al lancio). +- E-commerce/carrello (icona carrello nell'header Figma: omessa al lancio, era ereditata dal template).