title: Pianeta Web · le 5 migliorative — prompt di handoff per sessione fresca date: 2026-06-07 owner: Gregorio (decisioni) · Claude (esecuzione) status: pronto. Base = #307 watermark + #311 hero-CTA + #321 footer/sezioni page-locale-aware (tutti MERGED + verificati live) related: ops/pianeta-web-program-handoff-2026-06-06.md · execution/logo-ufficiale-task-2026-06-06.md · canon/12-design-system-orbi-logos.md · memory reference_live_verify_behind_auth_chrome_mcp
Pianeta Web · le 5 migliorative (handoff)
Raccolta delle migliorie "best-practice / tech più moderna" emerse chiudendo il design-pass del Pianeta Web. NON sono blocker del gate: sono qualità e debito sano. Sotto, prima un breve contesto, poi il PROMPT pronto da incollare in una sessione fresca.
Le 5 migliorative in breve
- Booking i18n — l'ultima stringa hardcoded IT ("Prenotazioni online in arrivo") + audit dell'intera famiglia Booking.
- Smooth-scroll sugli anchor (Lenis sugli hash) + cleanup dipendenze morte in
sites-runtime. - Consolidare la i18n del runtime in un meccanismo unico, tipizzato e moderno (oggi è sparsa in switch per-componente).
- Logo SVG ufficiale + watermark background-adaptive (oggi raster: su tenant scuro la sfera nera sparisce). Founder-gated (identità di marca).
PROMPT (incolla in una sessione fresca)
Sei un senior staff full-stack + design engineer (livello big-tech) che alza la qualità del Pianeta Web di MULTIVERBE. MULTIVERBE è il SaaS che dà a una PMI (CH/UE) tutta la presenza digitale (sito, prenotazioni, contenuti, CRM, vendite) coordinata da un'AI centrale. Il "BOS"/bos.multiverbe.com è lo strumento interno, NON il prodotto.
Standard di lavoro (Engineering Charter — memory
operating_charter, non negoziabile)Un task è "fatto" SOLO se: verificato dal vivo con metodo esplicito · piccolo e coeso (no refactor misti a feature) · zero hardcoded customer-facing (ogni stringa vale per QUALSIASI tenant; tutto via token
--tenant-*) · sicuro multi-tenant (filtraworkspace_idin query/cache/storage + RLS, valida ownership al data-layer) · advisor Supabase 0 errori · niente regressioni · fix alla radice (mai declassare warning) · merge SOLO a CI verde (squash +--adminè il pattern del repo). UI/copy in italiano; eccezione: il wordmark del watermark è inglese ("Powered by Multiverbe"), monolingua per tutti i tenant. Pseudonimizza PII prima di Anthropic. Mai DeepSeek/OpenRouter. Plan-first per lavori non banali; proponi la scelta migliore con trade-off; verifica lo stato reale (DB/prod/CI) prima di agire; chiedi prima solo per schema-prod, pricing/canon, sicurezza, hard-to-revert, e per scelte di identità di marca (logo). Cost-mode CI/infra: verifica in LOCALE prima di pushare (la PR nasce verde), batcha i commit, 1 PR per unità coerente, non ri-triggerare la CI a vuoto; i gate non si toccano. Per ogni scelta di stack/libreria valida sul web l'ultimo livello 2026 (versioni, best practice, deprecazioni) — non fidarti solo del training. Chiudi la sessione con un blocco 🔴 DA FARE in 3 categorie a tabella (🔄 Continuative · ⚡ Migliorative · 🗓️ Sessioni future) e persisti il pending in memoria/BOS (memoryfeedback_persist_pending_on_session_close).Verità architetturale (tienila)
Non esiste codice per-sito. UNA runtime condivisa (
sites-runtime, Next.js 16 + React 19, Vercel projectmultiverbe-sites) serve tutti i*.multiverbe.appvia routing per subdomain (sites-runtime/proxy.ts) + ISR. Il sito = DATI in Supabase (sites/site_subdomains/site_pages/site_blocks/site_block_translations/site_assets/site_constitutions). Modificare i dati = UPDATE righe +/api/revalidate(REVALIDATE_SECRET) → live, no deploy. Progetto Supabaseyqhixdqipojvgzfadufo(eu-central-1). Unico sito pubblicato =trattoria-bellinzona-demo(tier business, tema CHIARO: bg#FAF5EC, testo#241C17; locale it/de/fr/en presenti). Le route[subdomain]/...sono dinamiche (ƒ), con data-cache viaunstable_cache+revalidate.Base già fatta e verificata live (NON rifarla)
- #307 — watermark "Powered by Multiverbe": logo brand + wordmark EN monolingua + micro-press stile Apple (
active:scale(.96), reduced-motion safe) + UTM, gating per-tier (Starter/Pro lo mostrano, Business no). Asset =sites-runtime/public/brand/multiverbe-mark.png(raster 128px right-sized dalla sfera-occhio).- #311 — la CTA sticky mobile dell'hero si ritrae quando il footer entra in vista.
- #321 — footer/cookie/legali page-locale-aware (il middleware inoltra
x-multiverbe-localecome request header →app/[subdomain]/layout.tsxlo legge viaheaders(), narrowing aSiteLocale) + cornice sezioni localizzata viasites-runtime/lib/sections/i18n.ts(it/de/fr/en) conlocalethreadato daSectionRenderer(components/sections/index.tsx) a Events + Menu (3 varianti + primitive). Verificato SSR su prod:/de→Cookie-Einstellungen/Sitzplätze/Allergene:, zero IT residuo.Missione: le 5 migliorative, in quest'ordine
⚡ M1 — Chiudi la i18n: "Prenotazioni online in arrivo" + audit Booking (quick win, mecc.)
Unica stringa di cornice ancora hardcoded IT:
sites-runtime/components/sections/Booking/_BookingForm.tsx(~riga 169, fallback CTA quando il booking online è disattivo). La famiglia Booking NON riceve ancoralocale: incomponents/sections/index.tsxilcase 'booking'rende<Booking content=... />senzalocale. Cosa fare: passalocaleda SectionRenderer →Booking/index.tsx(dispatcher) → varianti (InlineForm/SlideOver/StickyMobile) →_BookingForm.tsx; aggiungi la chiave alib/sections/i18n.ts(4 lingue). Prima, fai un audit completo:grepsucomponents/sections/**per ogni stringa IT hardcoded rimasta (Contact, SocialProof, About, ServicesPricing, Faq, Gallery, Booking — label fisse,aria-label, empty-state) e localizzale tutte nello stesso giro. Done: zero stringhe IT hardcoded nelle sezioni; verifica SSR su/dedel demo.⚡ M2 — Smooth-scroll anchor (Lenis) + cleanup dipendenze morte
(a) I CTA puntano a
#prenota/#menuma lo scroll è il jump nativo: Lenis (sites-runtime/components/effects/SmoothScroll.tsx) non è agganciato agli hash. Aggancia i click su linka[href^="#"]allo scroll smooth di Lenis (rispettaprefers-reduced-motion→ niente smooth; mantieni il fallback no-JS; aggiorna l'hash + focus del target per a11y). (b)sites-runtime/package.jsondichiara@react-three/fiber,@react-three/drei,threeora inutilizzati (l'hero WebGL è stato rimosso). Primanpx depcheck(verifica anchegsap/mapbox-gl/framer-motion/lenisreali usi: es. il Contact usa una mappa?); rimuovi solo ciò che è davvero morto. ⚠️ NON editarepnpm-lock.yamla mano: usapnpm removee rigenera il lock dove pnpm funziona (la junctionnode_modulesnei worktree è solo per build/typecheck, non per mutare il lock). Done: smooth-scroll verificato (con e senza reduced-motion),next buildverde, lockfile coerente, bundle più snello.⚡ M3 — Consolida la i18n del runtime (architetturale · plan-first)
Oggi la i18n del runtime è sparsa:
lib/sections/i18n.ts(nuova), lo switchcookieLabelincomponents/layout/SiteFooter.tsx, le stringhe incomponents/Compliance/CookieBanner.tsx, le locale inproxy.ts, e (citato in memoria)booking/_lib/i18n.tslato app. Obiettivo: un meccanismo unico, tipizzato, moderno. Valida sul web (2026)next-intlper App Router vs un piccolo dizionario tipizzato in-house. ⚠️ Vincolo: il runtime ha già il proprio routing locale (subdomain +[locale]+x-multiverbe-locale) → se usinext-intl, usane il core (getTranslations/useTranslations) senza il suo middleware di routing (evita conflitti conproxy.ts). Confine corretto: le label di cornice/UI stanno nel codice (i18n tipizzata); il contenuto del tenant resta data-driven insite_block_translations(già così — non spostarlo nel codice né viceversa). Plan-first: presenta la scelta (libreria vs in-house) con trade-off + raccomandazione, poi consolida le isole sopra inlib/i18n/con chiavi tipizzate. M1 può confluire qui. Done: una sola fonte di verità i18n per il runtime, tipizzata,tscverde, render SSR identico nelle 4 lingue.🎨 M4 — Logo SVG ufficiale + watermark background-adaptive (FOUNDER-GATED)
Il watermark usa un raster (sfera nera + occhio ciano): su un tenant a tema scuro la sfera si fonde con lo sfondo. Il canon (
canon/12-design-system-orbi-logos.md§"Logo di Multiverbe") conferma che non esiste un SVG pulito; colori canon#0EA5E9base ·#22D3EEluci ciano ·#4ADE80verde acceso; servono master SVG + 3 varianti (completo/monogramma/ritaglio) + light/dark + export. Task aperto:execution/logo-ufficiale-task-2026-06-06.md. ⚠️ Il logo è identità di marca = territorio founder (come i pianeti 3D, memoryfeedback_do_not_touch_3d_planets): non ridisegnare unilateralmente. Cosa fare: (1) proponi 2-3 opzioni di mark monocromo inline SVGcurrentColor(riproduzione fedele della sfera-occhio esistente, NON un redesign) che legga su QUALSIASI sfondo — riferimento di partenza l'SVG infrontend/multiverbe-app/src/components/auth/SolarSystemPattern.tsx; (2) ottieni l'OK del founder sul mark; (3) wiralo insites-runtime/components/layout/SiteFooter.tsx(inline SVG che ereditacurrentColoral posto dell'<img>raster), mantenendo press Apple + gating + UTM + il raster come fallback. Verifica leggibilità su CHIARO e SCURO: il demo è chiaro → per il test scuro, flippa temporaneamente idesign_tokensdel demo a un set scuro in DB (poi ripristina) oppure monta il footer in una pagina di prova locale con sfondo scuro. Done: il watermark resta nitido e leggibile su un tenant chiaro E uno scuro, verificato a vivo; founder ha approvato il mark.Metodo di verifica LOCALE (sites-runtime) — memory
reference_live_verify_behind_auth_chrome_mcp§sites-runtimeI siti sono pubblici → verificabili in locale a quality-bar. Setup: pnpm è rotto nei worktree → crea una junction
sites-runtime/node_modulesverso il checkout main (cmd /c mklink /J) + copianext-env.d.ts; così giranotsc --noEmit,node scripts/check-cwv-budget.mjs,next build. Per renderizzare un tenant: il proxy supporta*.localtest.me→http://<slug>.localtest.me:3001/legge i dati reali di prod (build con la anon key VERA via Supabase MCPget_publishable_keys, è inlinata a build-time). L'idratazione NON parte innext devsotto localtest.me → usa build di produzione +next start; maoutput:'standalone'impedisce al middleware di girare sottonext start→ commenta temporaneamenteoutput:'standalone'innext.config.mjs, builda, testa, RIPRISTINA (verificagit diff). Verifica gli stati: SSR via curl +grep(le stringhe i18n sono SSR → ground truth: es./dedeve contenereCookie-Einstellungen,/Preferenze cookie) oppure Playwright per l'interattività; misura viagetComputedStyle/ARIA dopo il settle delle transizioni. Feature tier-gated (watermark): dopo il merge, flippa il tier del demo in DB su prod → poll ISR (~16-60s) → ripristina. Pulizia: rimuovi la junction concmd /c rmdir(toglie solo il link); MAIRemove-Item *.pngalla radice (lì viveClosed-Sphere-NoBackground.pngtracciato).CI / merge (cost-mode)
Sul PR (solo
sites-runtime/**) girano security-audit (Semgrep + Trivy/secret/CVE) + Vercelmultiverbe-sites(=npm run build: CWV prebuild + next build + typecheck) = il gate type/build.frontend-ci/planet-system-ci/e2e-smokeNON triggerano su sites-runtime. Merge:gh pr merge <n> --squash --admina check verdi (mergeStateStatus BLOCKED= branch protection, si supera con--admin). Messaggi multi-riga:git commit -F <file>egh pr ... --body-file <file>(l'inline PowerShell con"si rompe). Chiudi il commit conCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>e il body PR con la riga Claude Code.Primo passo concreto
Inizia da M1 (chiusura i18n Booking + audit): è veloce, mecc., e chiude al 100% la classe "stringhe hardcoded". Apri
components/sections/index.tsx(case 'booking'),components/sections/Booking/_BookingForm.tsx,lib/sections/i18n.ts; fai prima ilgrepdi audit su tutte le sezioni. Done dell'unità = differenza verificata a vivo (SSR/de) + CI verde + PR squash-merged, senza regressioni né hardcoded. Poi M2 → M3 (plan-first) → M4 (founder-gated). Una slice coesa per PR.Leggi prima le memory
operating_charter,reference_live_verify_behind_auth_chrome_mcp,project_pianeta_web_trattoria_impeccabile_2026_06_06,project_pianeta_web_program_2026_06_06, e questo doc. Poi dichiara il piano del giorno (3 categorie) e procedi a qualità massima.