From f33d29fe7b2bd4a4b02d2f1e2e9fbdc9bcf1eb9c Mon Sep 17 00:00:00 2001
From: Javaxman
Date: Fri, 24 Apr 2026 20:59:53 +0200
Subject: [PATCH 1/4] Rende operativa la pagina news e sostituisce il README
starter con un runbook di progetto.
Allinea la documentazione a setup, deploy Cloudflare e gestione contatti per supportare il go-live.
Made-with: Cursor
---
README.md | 145 +++++++++++++++++++++++--------------------
src/pages/news.astro | 31 +++++++--
2 files changed, 102 insertions(+), 74 deletions(-)
diff --git a/README.md b/README.md
index a6105e9..c256778 100644
--- a/README.md
+++ b/README.md
@@ -1,73 +1,71 @@
-# Astro Starter Kit: Minimal
+# NexStudio Website Runbook
-```sh
-npm create astro@latest -- --template minimal
-```
+Sito istituzionale NexStudio basato su Astro, con deploy su Cloudflare e form contatti protetto da Turnstile.
-> ð§âð **Seasoned astronaut?** Delete this file. Have fun!
+## Obiettivo del repository
-## ð Project Structure
+- Presentazione aziendale e servizi (homepage e pagine legali).
+- Entry point unico per richieste commerciali e supporto.
+- Base pronta per contenuti multilingua IT/EN/TH.
+- Pipeline di deploy stabile su Cloudflare.
-Inside of your Astro project, you'll see the following folders and files:
+## Stack tecnico
-```text
-/
-âââ public/
-âââ src/
-â âââ pages/
-â âââ index.astro
-âââ package.json
-```
+- Astro + Tailwind CSS
+- Adapter Cloudflare (`@astrojs/cloudflare`)
+- Sitemap (`@astrojs/sitemap`)
+- Form backend su endpoint `/api/contact`
+- Turnstile + Resend per anti-spam e invio email
-Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
+## Struttura essenziale
-There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
+- `src/pages/`: pagine pubbliche e route API (`src/pages/api/contact.ts`)
+- `src/components/`: componenti UI condivisi
+- `src/data/`: contenuti testuali e configurazioni pagine
+- `public/`: asset statici (loghi, immagini, robots)
+- `.env.example`: variabili locali di riferimento
-Any static assets, like images, can be placed in the `public/` directory.
+## Prerequisiti
-## ð§ Commands
+- Node.js 20+
+- npm 10+
+- Account Cloudflare (Pages/Workers + Turnstile)
+- Account Resend (API key + sender verificato)
-All commands are run from the root of the project, from a terminal:
+## Avvio locale
-| Command | Action |
-| :------------------------ | :----------------------------------------------- |
-| `npm install` | Installs dependencies |
-| `npm run dev` | Starts local dev server at `localhost:4321` |
-| `npm run build` | Build your production site to `./dist/` |
-| `npm run preview` | Preview your build locally, before deploying |
-| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
-| `npm run astro -- --help` | Get help using the Astro CLI |
+1. Installazione dipendenze:
+ - `npm install`
+2. Copia variabili di ambiente:
+ - copia `.env.example` in `.env`
+3. Avvio sviluppo:
+ - `npm run dev`
+4. Se Vite resta in cache incoerente:
+ - `npm run dev:fresh`
-## ð Want to learn more?
+## Comandi utili
-Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
+- `npm run dev`: sviluppo locale
+- `npm run dev:fresh`: reset cache `.vite` e `.astro` + avvio dev server
+- `npm run build`: build produzione
+- `npm run preview`: preview locale della build
+- `npm run deploy:cf`: build + deploy con wrangler su output Astro
-## Cloudflare deploy notes
+## Configurazione contatti
-If you deploy with Wrangler in CI/Cloudflare, build first and deploy using Astro's generated Worker config:
+Variabili pubbliche (frontend):
-- Build command: `npm run build`
-- Deploy command: `npm run deploy:cf`
-
-This avoids entrypoint errors like `@astrojs/cloudflare/entrypoints/server` not found.
-
-## Contact form configuration
-
-Set these variables for the website contact form.
-
-Public (frontend):
-
-- `PUBLIC_CONTACT_FORM_ACTION_URL` (default `/api/contact`)
-- `PUBLIC_CONTACT_FORM_SUCCESS_REDIRECT` (absolute URL for `_next`)
-- `PUBLIC_CONTACT_FORM_MAILTO` (fallback only if `ACTION_URL` is empty)
+- `PUBLIC_CONTACT_FORM_ACTION_URL` (default consigliato: `/api/contact`)
+- `PUBLIC_CONTACT_FORM_SUCCESS_REDIRECT` (URL assoluto della pagina post-submit)
+- `PUBLIC_CONTACT_FORM_MAILTO` (fallback se action URL non disponibile)
- `PUBLIC_CONTACT_TURNSTILE_SITE_KEY`
-Server-side (Cloudflare runtime / local `.env`):
+Variabili server (Cloudflare/local):
-- `CONTACT_FORM_MODE` (`dev` or `live`)
+- `CONTACT_FORM_MODE` (`dev` oppure `live`)
- `CONTACT_FORM_RESEND_API_KEY`
-- `CONTACT_FORM_FROM_EMAIL` (verified sender in Resend, recommended `no-reply@nexstudio.com`)
-- `CONTACT_FORM_TO_EMAIL` (default recipient inbox or alias, recommended `info@nexstudio.com`)
+- `CONTACT_FORM_FROM_EMAIL` (consigliato: `no-reply@nexstudio.ai`)
+- `CONTACT_FORM_TO_EMAIL` (default destinatario, es. `info@nexstudio.ai`)
- `CONTACT_FORM_TO_EMAIL_SUPPORT`
- `CONTACT_FORM_TO_EMAIL_PRIVACY`
- `CONTACT_FORM_TO_EMAIL_SECURITY`
@@ -76,29 +74,40 @@ Server-side (Cloudflare runtime / local `.env`):
- `CONTACT_FORM_TO_EMAIL_HR`
- `CONTACT_TURNSTILE_SECRET_KEY`
-Mode behavior:
+Comportamento:
-- `dev`: accepts form and logs payload server-side (no real email send)
-- `live`: verifies Turnstile (if secret configured) and sends via Resend API
+- `dev`: accetta submit e scrive payload nei log (senza invio reale)
+- `live`: valida Turnstile e invia email via Resend
-Department routing:
+## Deploy Cloudflare
-- the contact form includes a department selector
-- if a department-specific env is set, the email is routed to that recipient
-- otherwise it falls back to `CONTACT_FORM_TO_EMAIL`
+Impostazioni consigliate:
-Suggested operational use:
+- Build command: `npm run build`
+- Deploy command: `npm run deploy:cf`
-- `info@...` for prospects and generic clarifications (non-clients)
-- `support@...` for existing customers
-- `no-reply@...` as sender for newsletters and automated communications
+Questa configurazione evita errori tipo:
+`The entry-point file at "@astrojs/cloudflare/entrypoints/server" was not found.`
-Copy `.env.example` to `.env` for local development and configure the same keys in Cloudflare Pages/Workers for production.
+## Dominio e sicurezza
-## Production domain
-
-- Official domain: `https://nexstudio.ai`
-- Keep Turnstile widget hostnames aligned with:
+- Dominio ufficiale: `https://nexstudio.ai`
+- Hostname Turnstile da mantenere allineati:
- `nexstudio.ai`
- - `www.nexstudio.ai` (if used)
- - `localhost` (for local testing)
+ - `www.nexstudio.ai` (se usato)
+ - `localhost` (test locale)
+- Accesso pre-go-live gestito con Cloudflare Zero Trust Access
+
+## Stato operativo attuale
+
+- Issue #1 (contact form live): implementata
+- Issue #2 (anti-spam Turnstile): implementata
+- Issue #3 (SEO base): implementata (sitemap, robots, canonical/OG/Twitter)
+- Issue #4: in avanzamento (contenuti non placeholder)
+- Issue #5: da completare (localizzazione reale IT/EN/TH)
+
+## Note operative
+
+- Per modifiche non minori usare branch dedicato (`feat/*`, `fix/*`) e merge su `main` dopo verifica.
+- Evitare commit su `main` per attivita complesse.
+- Rigenerare eventuali API key esposte e aggiornare subito i secret su Cloudflare.
diff --git a/src/pages/news.astro b/src/pages/news.astro
index a1a0e1d..b01f530 100644
--- a/src/pages/news.astro
+++ b/src/pages/news.astro
@@ -6,13 +6,32 @@ import SubpageLayout from '../layouts/SubpageLayout.astro';
title="Novità â NexStudio"
description="Novità , release e articoli da NexStudio."
heading="Novità "
- lead="Hub comunicazioni: collegate qui il vostro blog CMS, oppure elencate manualmente le notizie."
+ lead="Aggiornamenti ufficiali su piattaforma, compliance, infrastruttura e contenuti editoriali."
>
-
- Quando avrete contenuti da pubblicare (release di prodotto, note di
- conformità , eventi), potete sostituire questa pagina con una raccolta
- articoli Astro, un redirect verso Medium/Substack, o un headless CMS.
+
+ Stato editoriale: canale attivo. Le prossime pubblicazioni verranno aggiornate su questa pagina con frequenza periodica.
+
+ Programma editoriale
+
+ Release tecniche: aggiornamenti su funzionalita, integrazioni e miglioramenti di stabilita.
+ Compliance: novita su policy, sicurezza applicativa e adempimenti normativi.
+ Case e risultati: note operative su adozione, scalabilita e impatti di business.
+
+
+ Canali di distribuzione
+
+ Questa pagina resta il punto di riferimento ufficiale per annunci e changelog sintetici.
+ La newsletter verra attivata appena disponibile il canale comunicazioni dedicato.
+ I contenuti long-form potranno essere pubblicati anche su canali esterni, con rimando qui.
+
+
Archivio
- Nessuna news pubblicata per il momento.
+
+ In questa fase il sito e in pre-lancio operativo. Il primo blocco di news verra pubblicato con il go-live ufficiale.
+
+
+ Per richieste stampa, partnership o approfondimenti tecnici e possibile usare il form nella sezione
+ Contatti .
+
From ddab32d3efc31e0f937326f479a6c9697d71ac76 Mon Sep 17 00:00:00 2001
From: Javaxman
Date: Fri, 24 Apr 2026 21:32:15 +0200
Subject: [PATCH 2/4] Riduce il routing del contact form pubblico a info,
privacy e careers.
Allinea backend, configurazione env e documentazione al nuovo modello vetrina con destinatari meno granulari.
Made-with: Cursor
---
.env.example | 7 ++-----
README.md | 20 +++++++++++++++-----
src/data/home/cta.ts | 12 ++++--------
src/pages/api/contact.ts | 9 +++------
4 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/.env.example b/.env.example
index aef0b21..e3ce163 100644
--- a/.env.example
+++ b/.env.example
@@ -7,10 +7,7 @@ CONTACT_FORM_MODE=dev
CONTACT_FORM_RESEND_API_KEY=
CONTACT_FORM_FROM_EMAIL=no-reply@nexstudio.com
CONTACT_FORM_TO_EMAIL=info@nexstudio.com
-CONTACT_FORM_TO_EMAIL_SUPPORT=support@nexstudio.com
+CONTACT_FORM_TO_EMAIL_INFO=info@nexstudio.com
CONTACT_FORM_TO_EMAIL_PRIVACY=
-CONTACT_FORM_TO_EMAIL_SECURITY=
-CONTACT_FORM_TO_EMAIL_ETHICS=
-CONTACT_FORM_TO_EMAIL_LEGAL=
-CONTACT_FORM_TO_EMAIL_HR=
+CONTACT_FORM_TO_EMAIL_CAREERS=
CONTACT_TURNSTILE_SECRET_KEY=
diff --git a/README.md b/README.md
index c256778..3a175f8 100644
--- a/README.md
+++ b/README.md
@@ -66,12 +66,9 @@ Variabili server (Cloudflare/local):
- `CONTACT_FORM_RESEND_API_KEY`
- `CONTACT_FORM_FROM_EMAIL` (consigliato: `no-reply@nexstudio.ai`)
- `CONTACT_FORM_TO_EMAIL` (default destinatario, es. `info@nexstudio.ai`)
-- `CONTACT_FORM_TO_EMAIL_SUPPORT`
+- `CONTACT_FORM_TO_EMAIL_INFO` (opzionale, override esplicito per area "info")
- `CONTACT_FORM_TO_EMAIL_PRIVACY`
-- `CONTACT_FORM_TO_EMAIL_SECURITY`
-- `CONTACT_FORM_TO_EMAIL_ETHICS`
-- `CONTACT_FORM_TO_EMAIL_LEGAL`
-- `CONTACT_FORM_TO_EMAIL_HR`
+- `CONTACT_FORM_TO_EMAIL_CAREERS`
- `CONTACT_TURNSTILE_SECRET_KEY`
Comportamento:
@@ -79,6 +76,19 @@ Comportamento:
- `dev`: accetta submit e scrive payload nei log (senza invio reale)
- `live`: valida Turnstile e invia email via Resend
+Routing pubblico consigliato (portale vetrina):
+
+- `info`: informazioni generali/commerciali
+- `privacy`: richieste privacy e diritti interessato
+- `careers`: candidature e collaborazioni
+
+Indirizzi consigliati portale:
+
+- `info@nexstudio.ai`
+- `privacy@nexstudio.ai`
+- `careers@nexstudio.ai`
+- `no-reply@nexstudio.ai` (solo invio comunicazioni/newsletter, non destinazione inbound)
+
## Deploy Cloudflare
Impostazioni consigliate:
diff --git a/src/data/home/cta.ts b/src/data/home/cta.ts
index 746f3a1..1ead7e6 100644
--- a/src/data/home/cta.ts
+++ b/src/data/home/cta.ts
@@ -30,7 +30,7 @@ export const cta = {
nameLabel: 'Nome',
companyLabel: 'Azienda (opzionale)',
countryLabel: 'Paese',
- departmentLabel: 'Reparto',
+ departmentLabel: 'Area',
emailLabel: 'Email',
messageLabel: 'Scrivi qui il tuo messaggio',
submitLabel: 'Invia messaggio',
@@ -54,13 +54,9 @@ export const cta = {
fieldEmail: 'email',
fieldMessage: 'message',
departmentOptions: [
- { value: 'general', label: 'Generale' },
- { value: 'support', label: 'Support' },
- { value: 'privacy', label: 'Privacy / DPO' },
- { value: 'security', label: 'Security / Incident Response' },
- { value: 'ethics', label: 'Segnalazioni confidenziali (Ethics)' },
- { value: 'legal', label: 'Legal' },
- { value: 'hr', label: 'HR' },
+ { value: 'info', label: 'Informazioni generali e commerciali' },
+ { value: 'privacy', label: 'Privacy' },
+ { value: 'careers', label: 'Careers / Collaborazioni' },
],
},
} as const;
diff --git a/src/pages/api/contact.ts b/src/pages/api/contact.ts
index f69dd38..2d86cf7 100644
--- a/src/pages/api/contact.ts
+++ b/src/pages/api/contact.ts
@@ -82,12 +82,9 @@ async function sendWithResend(apiKey: string, fromEmail: string, toEmail: string
function resolveDepartmentRecipient(runtimeEnv: RuntimeEnv, defaultRecipient: string, department: string): string {
const normalized = department.trim().toLowerCase();
const map: Record = {
- support: readEnv('CONTACT_FORM_TO_EMAIL_SUPPORT', runtimeEnv),
+ info: readEnv('CONTACT_FORM_TO_EMAIL_INFO', runtimeEnv) || defaultRecipient,
privacy: readEnv('CONTACT_FORM_TO_EMAIL_PRIVACY', runtimeEnv),
- security: readEnv('CONTACT_FORM_TO_EMAIL_SECURITY', runtimeEnv),
- ethics: readEnv('CONTACT_FORM_TO_EMAIL_ETHICS', runtimeEnv),
- legal: readEnv('CONTACT_FORM_TO_EMAIL_LEGAL', runtimeEnv),
- hr: readEnv('CONTACT_FORM_TO_EMAIL_HR', runtimeEnv),
+ careers: readEnv('CONTACT_FORM_TO_EMAIL_CAREERS', runtimeEnv),
};
return map[normalized] || defaultRecipient;
}
@@ -111,7 +108,7 @@ export const POST: APIRoute = async ({ request, locals, url }) => {
const company = required(form.get('company'));
const email = required(form.get('email'));
const country = required(form.get('country'));
- const department = required(form.get('department')) || 'general';
+ const department = required(form.get('department')) || 'info';
const message = required(form.get('message'));
if (!name || !email || !country || !message) {
From 0714ec13354d0a7c3e1d971bca30e9da3ad23a2e Mon Sep 17 00:00:00 2001
From: Javaxman
Date: Mon, 27 Apr 2026 09:12:00 +0200
Subject: [PATCH 3/4] Avvia i18n reale della home su IT EN TH.
Introduco contenuti localizzati per menu, footer e principali sezioni della homepage, includendo il form contatti e i messaggi client per mantenere coerenza UX tra le tre lingue.
Made-with: Cursor
---
src/components/ContactFormInline.astro | 20 +-
src/components/SiteFooter.astro | 18 +-
src/data/home/cta.ts | 211 +++++++++++++++-----
src/data/home/faq.ts | 191 +++++++++++++-----
src/data/home/footer.ts | 259 +++++++++++++++++--------
src/data/home/hero.ts | 110 ++++++++---
src/data/home/index.ts | 8 +
src/data/home/navigation.ts | 88 +++++++--
src/data/home/services.ts | 192 +++++++++++++-----
src/data/home/site-meta.ts | 27 ++-
src/data/home/stack.ts | 170 +++++++++++++++-
src/layouts/SubpageLayout.astro | 8 +-
src/pages/index.astro | 40 ++--
src/scripts/nx-contact-form.ts | 34 +++-
14 files changed, 1068 insertions(+), 308 deletions(-)
diff --git a/src/components/ContactFormInline.astro b/src/components/ContactFormInline.astro
index 82ed22d..54ad4f9 100644
--- a/src/components/ContactFormInline.astro
+++ b/src/components/ContactFormInline.astro
@@ -1,5 +1,10 @@
---
-import { cta } from '../data/home';
+import { getCta } from '../data/home';
+
+const path = Astro.url.pathname;
+const localeMatch = path.match(/^\/(en|th)(\/|$)/);
+const currentLocale = (localeMatch?.[1] ?? 'it') as 'it' | 'en' | 'th';
+const cta = getCta(currentLocale);
const cf = cta.contactForm;
const model = {
@@ -14,6 +19,15 @@ const model = {
fieldDepartment: cf.fieldDepartment,
fieldEmail: cf.fieldEmail,
fieldMessage: cf.fieldMessage,
+ turnstileError: cf.errors.turnstile,
+ configError: cf.errors.config,
+ mailtoFallbackSubject: cf.mailtoFallbackSubject,
+ mailtoLabelName: cf.mailtoLabels.name,
+ mailtoLabelCompany: cf.mailtoLabels.company,
+ mailtoLabelEmail: cf.mailtoLabels.email,
+ mailtoLabelCountry: cf.mailtoLabels.country,
+ mailtoLabelDepartment: cf.mailtoLabels.department,
+ mailtoDefaultDepartment: cf.mailtoLabels.defaultDepartment,
};
const hasFormspree =
typeof cf.actionUrl === 'string' && cf.actionUrl.length > 0;
@@ -203,11 +217,11 @@ const fieldClass =
class="cf-turnstile"
data-sitekey={cf.turnstileSiteKey}
data-theme="dark"
- data-language="it"
+ data-language={cf.turnstileLanguage}
data-size="normal"
>
- Verifica anti-spam: completa il controllo prima di inviare il messaggio.
+ {cf.turnstileHint}
) : null
diff --git a/src/components/SiteFooter.astro b/src/components/SiteFooter.astro
index 3e7e9b0..0df5cf8 100644
--- a/src/components/SiteFooter.astro
+++ b/src/components/SiteFooter.astro
@@ -1,5 +1,10 @@
---
-import { footer } from '../data/home';
+import { getFooter } from '../data/home';
+
+const path = Astro.url.pathname;
+const localeMatch = path.match(/^\/(en|th)(\/|$)/);
+const currentLocale = (localeMatch?.[1] ?? 'it') as 'it' | 'en' | 'th';
+const footer = getFooter(currentLocale);
const hasNewsletterAction =
typeof footer.newsletter.actionUrl === 'string' &&
@@ -17,9 +22,6 @@ const notifySubject =
const linkClass =
'text-sm text-sky-400/90 transition-colors hover:text-sky-300';
-const path = Astro.url.pathname;
-const localeMatch = path.match(/^\/(en|th)(\/|$)/);
-const currentLocale = localeMatch?.[1] ?? 'it';
const withLocale = (href: string) => {
if (currentLocale === 'it') return href;
if (href.startsWith(`/${currentLocale}`)) return href;
@@ -91,7 +93,7 @@ const withLocale = (href: string) => {
) : (
{item.label}
@@ -115,7 +117,7 @@ const withLocale = (href: string) => {
{link.label}
) : (
-
+
{link.label}
)}
@@ -131,7 +133,7 @@ const withLocale = (href: string) => {
>
- Impostazioni cookie
+ {footer.labels.cookieTitle}
{footer.cookiePreferences.hint}
@@ -204,7 +206,7 @@ const withLocale = (href: string) => {
{nl.buttonLabel}
- Iscrizione in arrivo: configura lâendpoint nel progetto per attivare il modulo.
+ {footer.labels.newsletterComingSoon}
)
diff --git a/src/data/home/cta.ts b/src/data/home/cta.ts
index 1ead7e6..43662e9 100644
--- a/src/data/home/cta.ts
+++ b/src/data/home/cta.ts
@@ -5,58 +5,165 @@ const contactSuccessRedirect = (env.PUBLIC_CONTACT_FORM_SUCCESS_REDIRECT ?? '').
const contactMailto = (env.PUBLIC_CONTACT_FORM_MAILTO ?? '').trim();
const contactTurnstileSiteKey = (env.PUBLIC_CONTACT_TURNSTILE_SITE_KEY ?? '').trim();
-export const cta = {
- /** Riga sezione (stesso ruolo di FAQ, Stack, âĶ) */
- eyebrow: 'Contatti',
+import type { SupportedLocale } from './navigation';
- /** Titolo CTA su due righe (dopo il punto) */
- titleLine1: 'Automatizza il complesso.',
- titleLine2: 'Velocizza il processo.',
- body:
- 'Dai modelli LLM alla distribuzione globale in pochi millisecondi. La directory definitiva per il LegalTech e MedTech. Utilizza il modulo contatto qui a fianco e ti forniremo tutti i chiarimenti che ti servono.',
-
- /**
- * Modulo contatti in pagina (sezione Contatti).
- *
- * **Formspree:** crea un form su https://formspree.io e incolla lâURL in `actionUrl`.
- * **Solo mailto:** lascia `actionUrl` vuoto e imposta `mailto` con lâindirizzo destinatario
- * (si apre il client di posta dellâutente).
- */
- contactForm: {
- /** Lasciare vuoti endpoint/chiavi nelle fasi di sola UI. */
- title: 'Parliamone',
- description:
- 'Lascia i tuoi dati e il messaggio: ti risponde il team NexStudio.',
- nameLabel: 'Nome',
- companyLabel: 'Azienda (opzionale)',
- countryLabel: 'Paese',
- departmentLabel: 'Area',
- emailLabel: 'Email',
- messageLabel: 'Scrivi qui il tuo messaggio',
- submitLabel: 'Invia messaggio',
- /** Formspree: `https://formspree.io/f/xxxx` â valorizzato via `PUBLIC_CONTACT_FORM_ACTION_URL` */
- actionUrl: contactActionUrl,
- /** Formspree `_next` â URL assoluta in produzione (`PUBLIC_CONTACT_FORM_SUCCESS_REDIRECT`) */
- successRedirect: contactSuccessRedirect,
- /**
- * Cloudflare Turnstile (anti-spam): inserisci qui la site key pubblica.
- * Se vuota, il CAPTCHA non viene mostrato.
- */
- turnstileSiteKey: contactTurnstileSiteKey,
- /** Formspree `_subject` e oggetto mailto */
- notifySubject: 'Richiesta contatto â sito NexStudio',
- /** Fallback se `actionUrl` e' vuoto (`PUBLIC_CONTACT_FORM_MAILTO`) */
- mailto: contactMailto,
- fieldName: 'name',
- fieldCompany: 'company',
- fieldCountry: 'country',
- fieldDepartment: 'department',
- fieldEmail: 'email',
- fieldMessage: 'message',
- departmentOptions: [
- { value: 'info', label: 'Informazioni generali e commerciali' },
- { value: 'privacy', label: 'Privacy' },
- { value: 'careers', label: 'Careers / Collaborazioni' },
- ],
+const ctaByLocale = {
+ it: {
+ eyebrow: 'Contatti',
+ titleLine1: 'Automatizza il complesso.',
+ titleLine2: 'Velocizza il processo.',
+ body:
+ 'Dai modelli LLM alla distribuzione globale in pochi millisecondi. La directory definitiva per il LegalTech e MedTech. Utilizza il modulo contatto qui a fianco e ti forniremo tutti i chiarimenti che ti servono.',
+ contactForm: {
+ title: 'Parliamone',
+ description:
+ 'Lascia i tuoi dati e il messaggio: ti risponde il team NexStudio.',
+ nameLabel: 'Nome',
+ companyLabel: 'Azienda (opzionale)',
+ countryLabel: 'Paese',
+ departmentLabel: 'Area',
+ emailLabel: 'Email',
+ messageLabel: 'Scrivi qui il tuo messaggio',
+ submitLabel: 'Invia messaggio',
+ actionUrl: contactActionUrl,
+ successRedirect: contactSuccessRedirect,
+ turnstileSiteKey: contactTurnstileSiteKey,
+ turnstileLanguage: 'it',
+ turnstileHint:
+ 'Verifica anti-spam: completa il controllo prima di inviare il messaggio.',
+ notifySubject: 'Richiesta contatto â sito NexStudio',
+ mailto: contactMailto,
+ mailtoFallbackSubject: 'Contatto sito',
+ mailtoLabels: {
+ name: 'Nome',
+ company: 'Azienda',
+ email: 'Email',
+ country: 'Paese',
+ department: 'Area',
+ defaultDepartment: 'general',
+ },
+ errors: {
+ turnstile: 'Completa il controllo anti-spam prima di inviare il messaggio.',
+ config:
+ 'Configura `contactForm.actionUrl` (Formspree) o `contactForm.mailto` in `src/data/home/cta.ts`.',
+ },
+ fieldName: 'name',
+ fieldCompany: 'company',
+ fieldCountry: 'country',
+ fieldDepartment: 'department',
+ fieldEmail: 'email',
+ fieldMessage: 'message',
+ departmentOptions: [
+ { value: 'info', label: 'Informazioni generali e commerciali' },
+ { value: 'privacy', label: 'Privacy' },
+ { value: 'careers', label: 'Careers / Collaborazioni' },
+ ],
+ },
+ },
+ en: {
+ eyebrow: 'Contacts',
+ titleLine1: 'Automate complexity.',
+ titleLine2: 'Accelerate operations.',
+ body:
+ 'From LLM models to global distribution in milliseconds. Use the contact form and our team will provide all the details you need.',
+ contactForm: {
+ title: 'Letâs talk',
+ description: 'Share your details and message: the NexStudio team will reply.',
+ nameLabel: 'Name',
+ companyLabel: 'Company (optional)',
+ countryLabel: 'Country',
+ departmentLabel: 'Area',
+ emailLabel: 'Email',
+ messageLabel: 'Write your message',
+ submitLabel: 'Send message',
+ actionUrl: contactActionUrl,
+ successRedirect: contactSuccessRedirect,
+ turnstileSiteKey: contactTurnstileSiteKey,
+ turnstileLanguage: 'en',
+ turnstileHint:
+ 'Anti-spam verification: complete the challenge before sending your message.',
+ notifySubject: 'Contact request â NexStudio website',
+ mailto: contactMailto,
+ mailtoFallbackSubject: 'Website contact',
+ mailtoLabels: {
+ name: 'Name',
+ company: 'Company',
+ email: 'Email',
+ country: 'Country',
+ department: 'Area',
+ defaultDepartment: 'general',
+ },
+ errors: {
+ turnstile: 'Complete the anti-spam check before sending your message.',
+ config:
+ 'Configure `contactForm.actionUrl` (Formspree) or `contactForm.mailto` in `src/data/home/cta.ts`.',
+ },
+ fieldName: 'name',
+ fieldCompany: 'company',
+ fieldCountry: 'country',
+ fieldDepartment: 'department',
+ fieldEmail: 'email',
+ fieldMessage: 'message',
+ departmentOptions: [
+ { value: 'info', label: 'General and commercial information' },
+ { value: 'privacy', label: 'Privacy' },
+ { value: 'careers', label: 'Careers / Collaborations' },
+ ],
+ },
+ },
+ th: {
+ eyebrow: 'āļāļīāļāļāđāļ',
+ titleLine1: 'āļāļģāļāļēāļāļāļąāļāļāđāļāļāđāļŦāđāļāļąāļāđāļāļĄāļąāļāļī',
+ titleLine2: 'āđāļĢāđāļāļāļ§āļēāļĄāđāļĢāđāļ§āļāļĢāļ°āļāļ§āļāļāļēāļĢ',
+ body:
+ 'āļāļēāļāđāļĄāđāļāļĨ LLM āļŠāļđāđāļāļēāļĢāļāļĢāļ°āļāļēāļĒāļĢāļ°āļāļāļĢāļ°āļāļąāļāđāļĨāļāļ āļēāļĒāđāļāđāļĄāđāļāļĩāđāļĄāļīāļĨāļĨāļīāļ§āļīāļāļēāļāļĩ āđāļāđāļāļāļĢāđāļĄāļāļīāļāļāđāļāļāđāļēāļāļāđāļēāļ āđāļĨāđāļ§āļāļĩāļĄ NexStudio āļāļ°āļāļāļāļāļĨāļąāļāļāļĢāđāļāļĄāļāđāļāļĄāļđāļĨāļāļĩāđāļāļļāļāļāđāļāļāļāļēāļĢ',
+ contactForm: {
+ title: 'āļāļļāļĒāļāļąāļāđāļĢāļē',
+ description: 'āļāļĢāļāļāļāđāļāļĄāļđāļĨāđāļĨāļ°āļāđāļāļāļ§āļēāļĄ āđāļĨāđāļ§āļāļĩāļĄ NexStudio āļāļ°āļāļīāļāļāđāļāļāļĨāļąāļ',
+ nameLabel: 'āļāļ·āđāļ',
+ companyLabel: 'āļāļĢāļīāļĐāļąāļ (āđāļĄāđāļāļąāļāļāļąāļ)',
+ countryLabel: 'āļāļĢāļ°āđāļāļĻ',
+ departmentLabel: 'āđāļāļāļ',
+ emailLabel: 'āļāļĩāđāļĄāļĨ',
+ messageLabel: 'āļāļīāļĄāļāđāļāđāļāļāļ§āļēāļĄāļāļāļāļāļļāļ',
+ submitLabel: 'āļŠāđāļāļāđāļāļāļ§āļēāļĄ',
+ actionUrl: contactActionUrl,
+ successRedirect: contactSuccessRedirect,
+ turnstileSiteKey: contactTurnstileSiteKey,
+ turnstileLanguage: 'th',
+ turnstileHint: 'āļāļēāļĢāļĒāļ·āļāļĒāļąāļāļāđāļāļāļāļąāļāļŠāđāļāļĄ: āļāļĢāļļāļāļēāļāļģāļāļąāđāļāļāļāļāđāļŦāđāđāļŠāļĢāđāļāļāđāļāļāļŠāđāļāļāđāļāļāļ§āļēāļĄ',
+ notifySubject: 'āļāļģāļāļāļāļīāļāļāđāļ â āđāļ§āđāļāđāļāļāđ NexStudio',
+ mailto: contactMailto,
+ mailtoFallbackSubject: 'āļāļīāļāļāđāļāļāļēāļāđāļ§āđāļāđāļāļāđ',
+ mailtoLabels: {
+ name: 'āļāļ·āđāļ',
+ company: 'āļāļĢāļīāļĐāļąāļ',
+ email: 'āļāļĩāđāļĄāļĨ',
+ country: 'āļāļĢāļ°āđāļāļĻ',
+ department: 'āđāļāļāļ',
+ defaultDepartment: 'general',
+ },
+ errors: {
+ turnstile: 'āļāļĢāļļāļāļēāļĒāļ·āļāļĒāļąāļāļāļēāļĢāļāđāļāļāļāļąāļāļŠāđāļāļĄāļāđāļāļāļŠāđāļāļāđāļāļāļ§āļēāļĄ',
+ config:
+ 'āļāļĢāļļāļāļēāļāļąāđāļāļāđāļē `contactForm.actionUrl` (Formspree) āļŦāļĢāļ·āļ `contactForm.mailto` āđāļ `src/data/home/cta.ts`',
+ },
+ fieldName: 'name',
+ fieldCompany: 'company',
+ fieldCountry: 'country',
+ fieldDepartment: 'department',
+ fieldEmail: 'email',
+ fieldMessage: 'message',
+ departmentOptions: [
+ { value: 'info', label: 'āļāđāļāļĄāļđāļĨāļāļąāđāļ§āđāļāđāļĨāļ°āđāļāļīāļāļāļēāļāļīāļāļĒāđ' },
+ { value: 'privacy', label: 'āļāļ§āļēāļĄāđāļāđāļāļŠāđāļ§āļāļāļąāļ§' },
+ { value: 'careers', label: 'Careers / Collaborations' },
+ ],
+ },
},
} as const;
+
+export const getCta = (locale: SupportedLocale) => ctaByLocale[locale];
+
+/** Retro-compatibilità : fallback italiano. */
+export const cta = ctaByLocale.it;
diff --git a/src/data/home/faq.ts b/src/data/home/faq.ts
index e59e54c..e5ca8b7 100644
--- a/src/data/home/faq.ts
+++ b/src/data/home/faq.ts
@@ -1,47 +1,148 @@
+import type { SupportedLocale } from './navigation';
+
/** FAQ â domande/risposte allineate a hero, prodotti, servizi e stack */
-export const faq = {
- eyebrow: 'FAQ',
- title: 'Domande frequenti',
- items: [
- {
- question: 'Che tipo di organizzazioni seguite con LexAura e MediAura?',
- answer:
- 'Lavoriamo con studi legali e strutture sanitarie â dal professionista singolo a team e sedi multiâunità â che gestiscono volumi elevati di informazione e hanno bisogno di strumenti affidabili in ambiti regolamentati. La verticalità su Legal Tech e Health Tech ÃĻ parte della nostra proposta: meno genericismo, piÃđ requisiti operativi, tracciabilità e continuità del servizio.',
- },
- {
- question: 'Lâintelligenza artificiale sostituisce avvocati o medici?',
- answer:
- 'No. I nostri prodotti sono pensati per integrarsi nei flussi professionali: sintesi, ricerca, drafting assistito, automazione della documentazione e interfacce vocali liberano tempo, ma la decisione finale e la responsabilità restano del professionista. Lâobiettivo ÃĻ ridurre il carico ripetitivo e offrire una base analitica solida, non sostituire il giudizio umano.',
- },
- {
- question: 'Cosa succede dopo lâadozione del software?',
- answer:
- 'Il modello di servizio va oltre la licenza: onboarding e formazione specialistica per team legali e sanitari, supporto tecnico e consulenza operativa continuativi, aggiornamento dei motori di analisi e manutenzione evolutiva rispetto a normative e contesto di mercato. Per criticità urgenti sono previsti protocolli di intervento prioritario, cosÎ che studi e strutture non restino isolati dai propri strumenti.',
- },
- {
- question: 'Potete collegare LexAura o MediAura ai nostri sistemi già in uso?',
- answer:
- 'SÃŽ, quando serve. Oltre ai prodotti standard supportiamo integrazioni tramite API e moduli personalizzati nel perimetro dei nostri SaaS, per collegare gestionali o flussi documentali preesistenti senza reinventare lâintero stack informativo.',
- },
- {
- question: 'Come gestite sicurezza, disponibilità e dati sensibili?',
- answer:
- 'Progettiamo su architetture cloudânative ad alta disponibilità , con attenzione a crittografia, protezione di perimetro (es. WAF, mitigazione DDoS) e continuità operativa. Il trattamento di informazioni legali e sanitarie ÃĻ affrontato con criteri di integrità dei dati e conformità alle normative applicabili, inclusa la chiarezza su dove risiedono i dati e sui requisiti di due diligence che i settori regolamentati si attendono.',
- },
- {
- question: 'Lavorate solo in loco o anche con clienti in Italia e allâestero?',
- answer:
- 'Siamo una software company con base operativa a Bangkok e collaboriamo con clienti a livello internazionale. Workshop e incontri possono essere online o in presenza in base al progetto; supporto e comunicazioni operative in italiano, inglese, tedesco, francese, spagnolo o tailandese, con orari concordati.',
- },
- {
- question: 'Diritto dâuso e proprietà del software: come le regolate?',
- answer:
- 'Dipende dal contratto: in genere cediamo lâesclusiva sul deliverable a saldo, con clausole esplicite su componenti open source e librerie di terze parti. Per licenze SaaS, permessi dâuso e responsabilità sono definiti nei termini commerciali e nel contratto quadro.',
- },
- {
- question: 'Qual ÃĻ il modo piÃđ rapido per parlarne con voi?',
- answer:
- 'Il punto di ingresso principale ÃĻ la chat dal pulsante ÂŦChattiamoÂŧ in header: prima vedi se il canale ÃĻ con operatore umano, solo chatbot o misto, poi lasci email (e facoltativamente il nome) per ricevere un link o un codice monouso e aprire la sessione senza perdite di tempo. In chat operatore umano e chatbot collaborano per orientamento iniziale, requisiti e passi successivi. Per il supporto via web ci interfacciamo in italiano, inglese, tedesco, francese, spagnolo o tailandese. Per materiale sensibile useremo sempre i canali concordati in fase di rapporto commerciale. Se ci si sente piÃđ a proprio agio usando un form di contatto, in fondo alla homepage nella sezione Contatti trovate il modulo a destra del testo introduttivo.',
- },
- ] as const,
+const faqByLocale = {
+ it: {
+ eyebrow: 'FAQ',
+ title: 'Domande frequenti',
+ items: [
+ {
+ question: 'Che tipo di organizzazioni seguite con LexAura e MediAura?',
+ answer:
+ 'Lavoriamo con studi legali e strutture sanitarie â dal professionista singolo a team e sedi multiâunità â che gestiscono volumi elevati di informazione e hanno bisogno di strumenti affidabili in ambiti regolamentati. La verticalità su Legal Tech e Health Tech ÃĻ parte della nostra proposta: meno genericismo, piÃđ requisiti operativi, tracciabilità e continuità del servizio.',
+ },
+ {
+ question: 'Lâintelligenza artificiale sostituisce avvocati o medici?',
+ answer:
+ 'No. I nostri prodotti sono pensati per integrarsi nei flussi professionali: sintesi, ricerca, drafting assistito, automazione della documentazione e interfacce vocali liberano tempo, ma la decisione finale e la responsabilità restano del professionista. Lâobiettivo ÃĻ ridurre il carico ripetitivo e offrire una base analitica solida, non sostituire il giudizio umano.',
+ },
+ {
+ question: 'Cosa succede dopo lâadozione del software?',
+ answer:
+ 'Il modello di servizio va oltre la licenza: onboarding e formazione specialistica per team legali e sanitari, supporto tecnico e consulenza operativa continuativi, aggiornamento dei motori di analisi e manutenzione evolutiva rispetto a normative e contesto di mercato. Per criticità urgenti sono previsti protocolli di intervento prioritario, cosÎ che studi e strutture non restino isolati dai propri strumenti.',
+ },
+ {
+ question: 'Potete collegare LexAura o MediAura ai nostri sistemi già in uso?',
+ answer:
+ 'SÃŽ, quando serve. Oltre ai prodotti standard supportiamo integrazioni tramite API e moduli personalizzati nel perimetro dei nostri SaaS, per collegare gestionali o flussi documentali preesistenti senza reinventare lâintero stack informativo.',
+ },
+ {
+ question: 'Come gestite sicurezza, disponibilità e dati sensibili?',
+ answer:
+ 'Progettiamo su architetture cloudânative ad alta disponibilità , con attenzione a crittografia, protezione di perimetro (es. WAF, mitigazione DDoS) e continuità operativa. Il trattamento di informazioni legali e sanitarie ÃĻ affrontato con criteri di integrità dei dati e conformità alle normative applicabili, inclusa la chiarezza su dove risiedono i dati e sui requisiti di due diligence che i settori regolamentati si attendono.',
+ },
+ {
+ question: 'Lavorate solo in loco o anche con clienti in Italia e allâestero?',
+ answer:
+ 'Siamo una software company con base operativa a Bangkok e collaboriamo con clienti a livello internazionale. Workshop e incontri possono essere online o in presenza in base al progetto; supporto e comunicazioni operative in italiano, inglese, tedesco, francese, spagnolo o tailandese, con orari concordati.',
+ },
+ {
+ question: 'Diritto dâuso e proprietà del software: come le regolate?',
+ answer:
+ 'Dipende dal contratto: in genere cediamo lâesclusiva sul deliverable a saldo, con clausole esplicite su componenti open source e librerie di terze parti. Per licenze SaaS, permessi dâuso e responsabilità sono definiti nei termini commerciali e nel contratto quadro.',
+ },
+ {
+ question: 'Qual ÃĻ il modo piÃđ rapido per parlarne con voi?',
+ answer:
+ 'Il punto di ingresso principale ÃĻ la chat dal pulsante ÂŦChattiamoÂŧ in header: prima vedi se il canale ÃĻ con operatore umano, solo chatbot o misto, poi lasci email (e facoltativamente il nome) per ricevere un link o un codice monouso e aprire la sessione senza perdite di tempo. In chat operatore umano e chatbot collaborano per orientamento iniziale, requisiti e passi successivi. Per il supporto via web ci interfacciamo in italiano, inglese, tedesco, francese, spagnolo o tailandese. Per materiale sensibile useremo sempre i canali concordati in fase di rapporto commerciale. Se ci si sente piÃđ a proprio agio usando un form di contatto, in fondo alla homepage nella sezione Contatti trovate il modulo a destra del testo introduttivo.',
+ },
+ ] as const,
+ },
+ en: {
+ eyebrow: 'FAQ',
+ title: 'Frequently asked questions',
+ items: [
+ {
+ question: 'What organizations do you support with LexAura and MediAura?',
+ answer:
+ 'We work with law firms and healthcare organizations, from solo professionals to multi-site teams, that manage high information volumes and need reliable tools in regulated environments.',
+ },
+ {
+ question: 'Does AI replace lawyers or doctors?',
+ answer:
+ 'No. Our products support professional workflows with summarization, research, assisted drafting, and automation. Final decisions and responsibility always remain with the professional.',
+ },
+ {
+ question: 'What happens after software adoption?',
+ answer:
+ 'Our service model goes beyond licensing: specialist onboarding and training, continuous technical support and consulting, and ongoing engine updates aligned with regulations and market context.',
+ },
+ {
+ question: 'Can you integrate LexAura or MediAura with our existing systems?',
+ answer:
+ 'Yes, when needed. We support API integrations and custom modules within our SaaS perimeter to connect existing management or document flows.',
+ },
+ {
+ question: 'How do you handle security, availability, and sensitive data?',
+ answer:
+ 'We design for high-availability cloud-native architectures, encryption, perimeter protection, and operational continuity, with clear data-governance practices aligned with applicable regulations.',
+ },
+ {
+ question: 'Do you work only locally or also with international clients?',
+ answer:
+ 'We are based in Bangkok and collaborate internationally. Workshops can be remote or on-site depending on the project.',
+ },
+ {
+ question: 'How do you handle software usage rights and ownership?',
+ answer:
+ 'This depends on the contract. In many engagements, exclusive rights on deliverables are transferred after final payment, with explicit clauses for open source and third-party components.',
+ },
+ {
+ question: 'What is the fastest way to talk with your team?',
+ answer:
+ 'The primary entry point is the chat button in the header. You provide your email to receive a one-time link or code, then start the session without delay.',
+ },
+ ] as const,
+ },
+ th: {
+ eyebrow: 'āļāļģāļāļēāļĄāļāļĩāđāļāļāļāđāļāļĒ',
+ title: 'āļāļģāļāļēāļĄāļāļĩāđāļāļāļāđāļāļĒ',
+ items: [
+ {
+ question: 'āļāļāļāđāļāļĢāđāļāļāđāļŦāļāļāļĩāđāđāļŦāļĄāļēāļ°āļāļąāļ LexAura āđāļĨāļ° MediAura?',
+ answer:
+ 'āđāļĢāļēāļāļģāļāļēāļāļāļąāļāļŠāļģāļāļąāļāļāļēāļāļāļāļŦāļĄāļēāļĒāđāļĨāļ°āļāļāļāđāļāļĢāļŠāļļāļāļ āļēāļ āļāļąāđāļāđāļāđāļāļđāđāđāļāļĩāđāļĒāļ§āļāļēāļāđāļāļĩāđāļĒāļ§āđāļāļāļāļāļķāļāļāļĩāļĄāļŦāļĨāļēāļĒāļŠāļēāļāļē āļāļĩāđāļāđāļāļāļāļąāļāļāļēāļĢāļāđāļāļĄāļđāļĨāļāļģāļāļ§āļāļĄāļēāļāđāļāļāļĢāļīāļāļāļāļĩāđāļĄāļĩāļāđāļāļāļģāļāļąāļāļŠāļđāļ',
+ },
+ {
+ question: 'AI āļāļ°āđāļāļāļāļĩāđāļāļāļēāļĒāļŦāļĢāļ·āļāđāļāļāļĒāđāļŦāļĢāļ·āļāđāļĄāđ?',
+ answer:
+ 'āđāļĄāđāđāļāđ āđāļāđāļēāļŦāļĄāļēāļĒāļāļāļāđāļĢāļēāļāļ·āļāļāđāļ§āļĒāļāļēāļāđāļāļīāļāļ§āļīāđāļāļĢāļēāļ°āļŦāđ āļāļēāļāđāļāļāļŠāļēāļĢ āđāļĨāļ°āđāļ§āļīāļĢāđāļāđāļāļĨāļ§āđāļāđāļģ āđ āđāļāļĒāļāļēāļĢāļāļąāļāļŠāļīāļāđāļāļŠāļļāļāļāđāļēāļĒāļĒāļąāļāļāļāđāļāđāļāļŦāļāđāļēāļāļĩāđāļāļāļāļāļđāđāđāļāļĩāđāļĒāļ§āļāļēāļ',
+ },
+ {
+ question: 'āļŦāļĨāļąāļāđāļĢāļīāđāļĄāđāļāđāļāļēāļāļāļāļāļāđāđāļ§āļĢāđāđāļĨāđāļ§āļāļ°āđāļāļīāļāļāļ°āđāļĢāļāļķāđāļ?',
+ answer:
+ 'āđāļĢāļēāļĄāļĩāļāļĢāļīāļāļēāļĢāļŦāļĨāļąāļāļāļēāļĢāđāļāđāļāļēāļāļāļĢāļāļ§āļāļāļĢ āļāļąāđāļ onboarding āļāļēāļĢāļāļāļĢāļĄāđāļāļāļēāļ°āļāļēāļ āļāļēāļĢāļŠāļāļąāļāļŠāļāļļāļāļāļēāļāđāļāļāļāļīāļ āđāļĨāļ°āļāļēāļĢāļāļąāļāđāļāļāļĢāļ°āļāļāļāļĒāđāļēāļāļāđāļāđāļāļ·āđāļāļ',
+ },
+ {
+ question: 'āļŠāļēāļĄāļēāļĢāļāđāļāļ·āđāļāļĄ LexAura āļŦāļĢāļ·āļ MediAura āļāļąāļāļĢāļ°āļāļāđāļāļīāļĄāļāļāļāđāļĢāļēāđāļāđāđāļŦāļĄ?',
+ answer:
+ 'āđāļāđ āđāļĢāļēāļĢāļāļāļĢāļąāļāļāļēāļĢāđāļāļ·āđāļāļĄāļāđāļāļāđāļēāļ API āđāļĨāļ°āđāļĄāļāļđāļĨāđāļāļāļāļģāļŦāļāļāđāļāļāļ āļēāļĒāđāļāļāļāļāđāļāļ SaaS āļāļāļāđāļĢāļē',
+ },
+ {
+ question: 'āļāļąāļāļāļēāļĢāļāļ§āļēāļĄāļāļĨāļāļāļ āļąāļĒ āļāļ§āļēāļĄāļāļĢāđāļāļĄāđāļāđāļāļēāļ āđāļĨāļ°āļāđāļāļĄāļđāļĨāļāđāļāļāđāļŦāļ§āļāļĒāđāļēāļāđāļĢ?',
+ answer:
+ 'āđāļĢāļēāđāļāđāļŠāļāļēāļāļąāļāļĒāļāļĢāļĢāļĄāļāļĨāļēāļ§āļāđāļāļĩāđāļāļĢāđāļāļĄāđāļāđāļāļēāļāļŠāļđāļ āļāļēāļĢāđāļāđāļēāļĢāļŦāļąāļŠ āļāļēāļĢāļāđāļāļāļāļąāļāļĢāļ°āļāļąāļāđāļāļĢāļ·āļāļāđāļēāļĒ āđāļĨāļ°āđāļāļ§āļāļāļīāļāļąāļāļīāļāđāļēāļāļāļēāļĢāļāļģāļāļąāļāļāđāļāļĄāļđāļĨāđāļŦāđāļŠāļāļāļāļĨāđāļāļāļāđāļāļāļģāļāļąāļāļāļĩāđāđāļāļĩāđāļĒāļ§āļāđāļāļ',
+ },
+ {
+ question: 'āļĢāļąāļāļāļēāļāđāļāļāļēāļ°āđāļāļāļ·āđāļāļāļĩāđāļŦāļĢāļ·āļāļĢāļąāļāļĨāļđāļāļāđāļēāļāđāļēāļāļāļĢāļ°āđāļāļĻāļāđāļ§āļĒ?',
+ answer:
+ 'āļŠāļģāļāļąāļāļāļēāļāđāļŦāļāđāļāļāļīāļāļąāļāļīāļāļēāļĢāļāļāļāđāļĢāļēāļāļĒāļđāđāļāļĩāđāļāļĢāļļāļāđāļāļāļŊ āđāļĨāļ°āļāļģāļāļēāļāļāļąāļāļĨāļđāļāļāđāļēāļāđāļēāļāļāļĢāļ°āđāļāļĻāđāļāđ āļāļąāđāļāļāļāļāđāļĨāļāđāđāļĨāļ°āļāļāļāđāļāļāđāļāļēāļĄāļāļ§āļēāļĄāđāļŦāļĄāļēāļ°āļŠāļĄāļāļāļāđāļāļĢāļāļāļēāļĢ',
+ },
+ {
+ question: 'āļŠāļīāļāļāļīāļāļēāļĢāđāļāđāļāļēāļāđāļĨāļ°āļāļ§āļēāļĄāđāļāđāļāđāļāđāļēāļāļāļāļāļāļāļāđāđāļ§āļĢāđāļāļģāļŦāļāļāļāļĒāđāļēāļāđāļĢ?',
+ answer:
+ 'āļāļķāđāļāļāļąāļāļŠāļąāļāļāļē āđāļāļĒāļāļąāđāļ§āđāļāļāļ°āļĢāļ°āļāļļāđāļāļ·āđāļāļāđāļāļāļēāļĢāđāļāđāļāļēāļ āļāļ§āļēāļĄāļĢāļąāļāļāļīāļāļāļāļ āđāļĨāļ°āļŠāļīāļāļāļīāđāļāļāļīāđāļāļāļēāļāļāļĒāđāļēāļāļāļąāļāđāļāļ āļĢāļ§āļĄāļāļķāļāļŠāđāļ§āļāļāļĢāļ°āļāļāļāđāļāđāļāļāļāļāļĢāđāļŠāđāļĨāļ° third-party',
+ },
+ {
+ question: 'āļāđāļēāļāđāļāļāļāļēāļĢāļāļļāļĒāđāļĢāđāļ§āļāļĩāđāļŠāļļāļāļāļ§āļĢāļāļīāļāļāđāļāļāđāļāļāļāļēāļāđāļŦāļ?',
+ answer:
+ 'āļāļāļāļļāđāļĄāđāļāļāļāļāļŠāđāļ§āļāļŦāļąāļ§āđāļ§āđāļāđāļāļāđ āđāļŠāđāļāļĩāđāļĄāļĨāđāļāļ·āđāļāļĢāļąāļāļĨāļīāļāļāđāļŦāļĢāļ·āļāđāļāđāļāđāļāļāđāļāđāļāļĢāļąāđāļāđāļāļĩāļĒāļ§ āđāļĨāđāļ§āđāļĢāļīāđāļĄāđāļāļŠāļāļąāļāđāļāđāļāļąāļāļāļĩ',
+ },
+ ] as const,
+ },
} as const;
+
+export const getFaq = (locale: SupportedLocale) => faqByLocale[locale];
+
+/** Retro-compatibilità : fallback italiano. */
+export const faq = faqByLocale.it;
diff --git a/src/data/home/footer.ts b/src/data/home/footer.ts
index 680b421..b7e1ef7 100644
--- a/src/data/home/footer.ts
+++ b/src/data/home/footer.ts
@@ -1,87 +1,178 @@
+import type { SupportedLocale } from './navigation';
+
/** Footer â griglia 4 colonne (link); newsletter in blocco unico sotto, allineata a sinistra */
-export const footer = {
- brandName: 'NexStudio',
- tagline: 'Ingegneria del software e IA per settori regolamentati.',
- legalLine: 'P.IVA e note legali: da inserire.',
-
- columnTitles: {
- sections: 'Sezioni',
- legal: 'Normative',
- social: 'Reti sociali',
- company: 'Azienda',
- } as const,
-
- /** Colonna 1 â ancore sulla homepage */
- homeNav: [
- { label: 'Prodotti', href: '/#prodotti' },
- { label: 'Servizi', href: '/#servizi' },
- { label: 'Stack', href: '/#stack' },
- { label: 'FAQ', href: '/#faq' },
- ] as const,
-
- /** Pannello preferenze (CMP): non ÃĻ un documento legale; tenuto fuori dalla colonna Normative */
- cookiePreferences: {
- label: 'Impostazioni cookie',
- hint: 'Preferenze di consenso sul tuo browser (non ÃĻ un testo legale).',
- } as const,
-
- /** Colonna 2 â documenti legali (testi bozza nelle rispettive pagine) */
- legalColumnNav: [
- { label: 'Condizioni dâuso', href: '/terms' },
- { label: 'Informativa cookie', href: '/cookies' },
- { label: 'Privacy', href: '/privacy' },
- { label: 'Diritti privacy (GDPR)', href: '/gdpr' },
- ] as const,
-
- /**
- * Colonna 3 â social (sostituire gli URL con i profili reali).
- * Lasciare `href` vuoto per mostrare solo etichetta disabilitata finchÃĐ non configurato.
- */
- socialLinks: [
- { label: 'Facebook', href: '' },
- { label: 'LinkedIn', href: '' },
- { label: 'Twitter / X', href: '' },
- { label: 'GitHub', href: '' },
- ] as const,
-
- /** Colonna 4 â pagine istituzionali e compliance */
- companyNav: [
- { label: 'Chi siamo', href: '/about' },
- { label: 'Codice etico', href: '/codice-etico' },
- { label: 'Modello organizzativo', href: '/modello-organizzativo' },
- { label: 'Dove siamo', href: '/dove-siamo' },
- ] as const,
-
- /**
- * Newsletter â invio via POST a un endpoint esterno.
- *
- * Opzione A (consigliata per partire): Formspree
- * 1. Crea account su https://formspree.io e un nuovo form.
- * 2. Copia lâURL tipo `https://formspree.io/f/abcdefgh` in `actionUrl`.
- * 3. Opzionale: `successRedirect` = URL assoluta della pagina di ringraziamento
- * (es. `https://tuodominio.com/newsletter/grazie` â vedi `src/pages/newsletter/grazie.astro`).
- * 4. In Formspree collega lâinvio a email / Slack / Google Sheets.
- *
- * Opzione B: Brevo, Mailchimp, Buttondown, ConvertKit â usano spesso un URL
- * dedicato o un embed; adatta `fieldName` al nome campo richiesto dalla doc.
- *
- * Opzione C: Worker Cloudflare + lista in KV/D1 (piÃđ controllo, piÃđ codice).
- */
- newsletter: {
- title: 'Newsletter',
- description: 'Aggiornamenti su prodotti e roadmap.',
- placeholder: 'La tua email',
- buttonLabel: 'Iscriviti',
- /** Formspree: `https://formspree.io/f/xxxx` â vuoto = modulo disabilitato */
- actionUrl: '',
- /** Nome campo email richiesto dal provider (Formspree: di solito `email`) */
- fieldName: 'email',
- /**
- * Formspree: redirect dopo invio (`_next`). Deve essere URL **assoluta**
- * (es. produzione). Vuoto = pagina di ringrazio predefinita Formspree.
- */
- successRedirect: '',
- /** Formspree: oggetto della mail di notifica (`_subject`) */
- notifySubject: 'Nuova iscrizione newsletter â NexStudio',
+const footerByLocale = {
+ it: {
+ brandName: 'NexStudio',
+ tagline: 'Ingegneria del software e IA per settori regolamentati.',
+ legalLine: 'P.IVA e note legali: da inserire.',
+ columnTitles: {
+ sections: 'Sezioni',
+ legal: 'Normative',
+ social: 'Reti sociali',
+ company: 'Azienda',
+ } as const,
+ homeNav: [
+ { label: 'Prodotti', href: '/#prodotti' },
+ { label: 'Servizi', href: '/#servizi' },
+ { label: 'Stack', href: '/#stack' },
+ { label: 'FAQ', href: '/#faq' },
+ ] as const,
+ cookiePreferences: {
+ label: 'Impostazioni cookie',
+ hint: 'Preferenze di consenso sul tuo browser (non ÃĻ un testo legale).',
+ } as const,
+ legalColumnNav: [
+ { label: 'Condizioni dâuso', href: '/terms' },
+ { label: 'Informativa cookie', href: '/cookies' },
+ { label: 'Privacy', href: '/privacy' },
+ { label: 'Diritti privacy (GDPR)', href: '/gdpr' },
+ ] as const,
+ socialLinks: [
+ { label: 'Facebook', href: '' },
+ { label: 'LinkedIn', href: '' },
+ { label: 'Twitter / X', href: '' },
+ { label: 'GitHub', href: '' },
+ ] as const,
+ companyNav: [
+ { label: 'Chi siamo', href: '/about' },
+ { label: 'Codice etico', href: '/codice-etico' },
+ { label: 'Modello organizzativo', href: '/modello-organizzativo' },
+ { label: 'Dove siamo', href: '/dove-siamo' },
+ ] as const,
+ newsletter: {
+ title: 'Newsletter',
+ description: 'Aggiornamenti su prodotti e roadmap.',
+ placeholder: 'La tua email',
+ buttonLabel: 'Iscriviti',
+ actionUrl: '',
+ fieldName: 'email',
+ successRedirect: '',
+ notifySubject: 'Nuova iscrizione newsletter â NexStudio',
+ },
+ labels: {
+ cookieTitle: 'Impostazioni cookie',
+ socialPlaceholderTitle: 'URL da configurare in footer.ts',
+ companyPlaceholderTitle: 'Collegamento in arrivo',
+ newsletterComingSoon:
+ 'Iscrizione in arrivo: configura lâendpoint nel progetto per attivare il modulo.',
+ },
+ },
+ en: {
+ brandName: 'NexStudio',
+ tagline: 'Software engineering and AI for regulated industries.',
+ legalLine: 'VAT number and legal notes: to be added.',
+ columnTitles: {
+ sections: 'Sections',
+ legal: 'Legal',
+ social: 'Social',
+ company: 'Company',
+ } as const,
+ homeNav: [
+ { label: 'Products', href: '/#prodotti' },
+ { label: 'Services', href: '/#servizi' },
+ { label: 'Stack', href: '/#stack' },
+ { label: 'FAQ', href: '/#faq' },
+ ] as const,
+ cookiePreferences: {
+ label: 'Cookie settings',
+ hint: 'Consent preferences in your browser (this is not a legal document).',
+ } as const,
+ legalColumnNav: [
+ { label: 'Terms of use', href: '/terms' },
+ { label: 'Cookie policy', href: '/cookies' },
+ { label: 'Privacy', href: '/privacy' },
+ { label: 'Privacy rights (GDPR)', href: '/gdpr' },
+ ] as const,
+ socialLinks: [
+ { label: 'Facebook', href: '' },
+ { label: 'LinkedIn', href: '' },
+ { label: 'Twitter / X', href: '' },
+ { label: 'GitHub', href: '' },
+ ] as const,
+ companyNav: [
+ { label: 'About us', href: '/about' },
+ { label: 'Code of ethics', href: '/codice-etico' },
+ { label: 'Organizational model', href: '/modello-organizzativo' },
+ { label: 'Where we are', href: '/dove-siamo' },
+ ] as const,
+ newsletter: {
+ title: 'Newsletter',
+ description: 'Updates on products and roadmap.',
+ placeholder: 'Your email',
+ buttonLabel: 'Subscribe',
+ actionUrl: '',
+ fieldName: 'email',
+ successRedirect: '',
+ notifySubject: 'New newsletter signup â NexStudio',
+ },
+ labels: {
+ cookieTitle: 'Cookie settings',
+ socialPlaceholderTitle: 'URL to configure in footer.ts',
+ companyPlaceholderTitle: 'Coming soon',
+ newsletterComingSoon:
+ 'Newsletter signups coming soon: configure the endpoint in the project to enable this form.',
+ },
+ },
+ th: {
+ brandName: 'NexStudio',
+ tagline: 'āļ§āļīāļĻāļ§āļāļĢāļĢāļĄāļāļāļāļāđāđāļ§āļĢāđāđāļĨāļ° AI āļŠāļģāļŦāļĢāļąāļāļāļļāļāļŠāļēāļŦāļāļĢāļĢāļĄāļāļĩāđāļĄāļĩāļāđāļāļāļģāļāļąāļ',
+ legalLine: 'āđāļĨāļāļāļĢāļ°āļāļģāļāļąāļ§āļāļđāđāđāļŠāļĩāļĒāļ āļēāļĐāļĩāđāļĨāļ°āļāđāļāļĄāļđāļĨāļāļēāļāļāļāļŦāļĄāļēāļĒ: āļĢāļāđāļāļīāđāļĄāļ āļēāļĒāļŦāļĨāļąāļ',
+ columnTitles: {
+ sections: 'āļŠāđāļ§āļāļāđāļēāļ āđ',
+ legal: 'āļāļāļŦāļĄāļēāļĒ',
+ social: 'āđāļāđāļāļĩāļĒāļĨ',
+ company: 'āļāļĢāļīāļĐāļąāļ',
+ } as const,
+ homeNav: [
+ { label: 'āļāļĨāļīāļāļ āļąāļāļāđ', href: '/#prodotti' },
+ { label: 'āļāļĢāļīāļāļēāļĢ', href: '/#servizi' },
+ { label: 'āļŠāđāļāļ', href: '/#stack' },
+ { label: 'āļāļģāļāļēāļĄāļāļĩāđāļāļāļāđāļāļĒ', href: '/#faq' },
+ ] as const,
+ cookiePreferences: {
+ label: 'āļāļąāđāļāļāđāļēāļāļļāļāļāļĩāđ',
+ hint: 'āļāļēāļĢāļāļąāđāļāļāđāļēāļāļ§āļēāļĄāļĒāļīāļāļĒāļāļĄāđāļāđāļāļĢāļēāļ§āđāđāļāļāļĢāđāļāļāļāļāļļāļ (āđāļĄāđāđāļāđāđāļāļāļŠāļēāļĢāļāļēāļāļāļāļŦāļĄāļēāļĒ)',
+ } as const,
+ legalColumnNav: [
+ { label: 'āđāļāļ·āđāļāļāđāļāļāļēāļĢāđāļāđāļāļēāļ', href: '/terms' },
+ { label: 'āļāđāļĒāļāļēāļĒāļāļļāļāļāļĩāđ', href: '/cookies' },
+ { label: 'āļāļ§āļēāļĄāđāļāđāļāļŠāđāļ§āļāļāļąāļ§', href: '/privacy' },
+ { label: 'āļŠāļīāļāļāļīāļāļ§āļēāļĄāđāļāđāļāļŠāđāļ§āļāļāļąāļ§ (GDPR)', href: '/gdpr' },
+ ] as const,
+ socialLinks: [
+ { label: 'Facebook', href: '' },
+ { label: 'LinkedIn', href: '' },
+ { label: 'Twitter / X', href: '' },
+ { label: 'GitHub', href: '' },
+ ] as const,
+ companyNav: [
+ { label: 'āđāļāļĩāđāļĒāļ§āļāļąāļāđāļĢāļē', href: '/about' },
+ { label: 'āļāļĢāļĢāļĒāļēāļāļĢāļĢāļ', href: '/codice-etico' },
+ { label: 'āđāļĄāđāļāļĨāļāļāļāđāļāļĢ', href: '/modello-organizzativo' },
+ { label: 'āļāļĩāđāļāļąāđāļ', href: '/dove-siamo' },
+ ] as const,
+ newsletter: {
+ title: 'āļāļāļŦāļĄāļēāļĒāļāđāļēāļ§',
+ description: 'āļāļąāļāđāļāļāđāļāļĩāđāļĒāļ§āļāļąāļāļāļĨāļīāļāļ āļąāļāļāđāđāļĨāļ°āđāļĢāļāđāļĄāļ',
+ placeholder: 'āļāļĩāđāļĄāļĨāļāļāļāļāļļāļ',
+ buttonLabel: 'āļŠāļĄāļąāļāļĢāļĢāļąāļāļāđāļēāļ§āļŠāļēāļĢ',
+ actionUrl: '',
+ fieldName: 'email',
+ successRedirect: '',
+ notifySubject: 'āļĄāļĩāļāļđāđāļŠāļĄāļąāļāļĢāļāļāļŦāļĄāļēāļĒāļāđāļēāļ§āđāļŦāļĄāđ â NexStudio',
+ },
+ labels: {
+ cookieTitle: 'āļāļąāđāļāļāđāļēāļāļļāļāļāļĩāđ',
+ socialPlaceholderTitle: 'āļāđāļāļāļāļąāđāļāļāđāļē URL āđāļ footer.ts',
+ companyPlaceholderTitle: 'āļāļģāļĨāļąāļāļāļ°āđāļāļīāļāđāļāđāļāļēāļ',
+ newsletterComingSoon:
+ 'āļĢāļ°āļāļāļŠāļĄāļąāļāļĢāļāļāļŦāļĄāļēāļĒāļāđāļēāļ§āļāļģāļĨāļąāļāļāļ°āđāļāļīāļāđāļāđāļāļēāļ: āļāļąāđāļāļāđāļē endpoint āđāļāđāļāļĢāđāļāļāļāđāđāļāļ·āđāļāđāļāļīāļāļāļāļĢāđāļĄāļāļĩāđ',
+ },
},
} as const;
+
+export const getFooter = (locale: SupportedLocale) => footerByLocale[locale];
+
+/** Retro-compatibilità : fallback italiano. */
+export const footer = footerByLocale.it;
diff --git a/src/data/home/hero.ts b/src/data/home/hero.ts
index 97341e9..4c98b72 100644
--- a/src/data/home/hero.ts
+++ b/src/data/home/hero.ts
@@ -1,29 +1,85 @@
+import type { SupportedLocale } from './navigation';
+
/** Sezione hero */
-export const hero = {
- badge: 'Restituiamo valore al tuo tempo',
- /** Parte prima dellâevidenziazione nel titolo */
- titleBefore: "Ingegneria del software per l'era dell'",
- /** Segmento con gradiente nel titolo */
- titleHighlight: 'Intelligenza Artificiale',
- titleAfter: '.',
- subtitle:
- 'Sviluppiamo soluzioni SaaS ad alta complessità per settori regolamentati.',
- /** Paragrafi introduttivi */
- paragraphs: [
- "Ci occupiamo di progettazione di ecosistemi digitali evoluti. La nostra specializzazione risiede nell'integrazione di modelli di Intelligenza Artificiale all'interno di flussi di lavoro professionali dove precisione, sicurezza e affidabilità sono requisiti non negoziabili.",
- 'Il nostro approccio si concentra sulla trasformazione di dati complessi in strumenti operativi fluidi, attraverso lo sviluppo di algoritmi proprietari, interfacce vocali e architetture cloud scalabili.',
- ] as const,
- businessUnitsHeading: 'Le nostre Business Unit:',
- businessUnitsIntro:
- 'Operiamo attraverso divisioni specializzate per garantire la massima verticalità e competenza di dominio:',
- businessUnits: [
- {
- name: 'Legal Tech',
- description: "Soluzioni per l'automazione e l'analisi normativa.",
- },
- {
- name: 'Health Tech',
- description: 'Sistemi avanzati per la gestione e lâautomazione sanitaria.',
- },
- ] as const,
+const heroByLocale = {
+ it: {
+ badge: 'Restituiamo valore al tuo tempo',
+ titleBefore: "Ingegneria del software per l'era dell'",
+ titleHighlight: 'Intelligenza Artificiale',
+ titleAfter: '.',
+ subtitle:
+ 'Sviluppiamo soluzioni SaaS ad alta complessità per settori regolamentati.',
+ paragraphs: [
+ "Ci occupiamo di progettazione di ecosistemi digitali evoluti. La nostra specializzazione risiede nell'integrazione di modelli di Intelligenza Artificiale all'interno di flussi di lavoro professionali dove precisione, sicurezza e affidabilità sono requisiti non negoziabili.",
+ 'Il nostro approccio si concentra sulla trasformazione di dati complessi in strumenti operativi fluidi, attraverso lo sviluppo di algoritmi proprietari, interfacce vocali e architetture cloud scalabili.',
+ ] as const,
+ businessUnitsHeading: 'Le nostre Business Unit:',
+ businessUnitsIntro:
+ 'Operiamo attraverso divisioni specializzate per garantire la massima verticalità e competenza di dominio:',
+ businessUnits: [
+ {
+ name: 'Legal Tech',
+ description: "Soluzioni per l'automazione e l'analisi normativa.",
+ },
+ {
+ name: 'Health Tech',
+ description: 'Sistemi avanzati per la gestione e lâautomazione sanitaria.',
+ },
+ ] as const,
+ },
+ en: {
+ badge: 'We give your time back',
+ titleBefore: "Software engineering for the era of ",
+ titleHighlight: 'Artificial Intelligence',
+ titleAfter: '.',
+ subtitle:
+ 'We build high-complexity SaaS solutions for regulated industries.',
+ paragraphs: [
+ 'We design advanced digital ecosystems. Our specialization is integrating AI models into professional workflows where accuracy, security, and reliability are non-negotiable requirements.',
+ 'Our approach turns complex data into smooth operational tools through proprietary algorithms, voice interfaces, and scalable cloud-native architectures.',
+ ] as const,
+ businessUnitsHeading: 'Our Business Units:',
+ businessUnitsIntro:
+ 'We operate through specialized divisions to ensure deep domain expertise and vertical focus:',
+ businessUnits: [
+ {
+ name: 'Legal Tech',
+ description: 'Solutions for legal automation and regulatory analysis.',
+ },
+ {
+ name: 'Health Tech',
+ description:
+ 'Advanced systems for healthcare workflow management and automation.',
+ },
+ ] as const,
+ },
+ th: {
+ badge: 'āļāļ·āļāļāļļāļāļāđāļēāđāļŦāđāļāļąāļāđāļ§āļĨāļēāļāļāļāļāļļāļ',
+ titleBefore: 'āļ§āļīāļĻāļ§āļāļĢāļĢāļĄāļāļāļāļāđāđāļ§āļĢāđāļŠāļģāļŦāļĢāļąāļāļĒāļļāļāļāļāļ',
+ titleHighlight: 'āļāļąāļāļāļēāļāļĢāļ°āļāļīāļĐāļāđ',
+ titleAfter: '.',
+ subtitle: 'āđāļĢāļēāļāļąāļāļāļēāđāļāļĨāļđāļāļąāļ SaaS āļāļĩāđāļāļąāļāļāđāļāļāļŠāļđāļāļŠāļģāļŦāļĢāļąāļāļāļļāļāļŠāļēāļŦāļāļĢāļĢāļĄāļāļĩāđāļĄāļĩāļāđāļāļāļģāļāļąāļ',
+ paragraphs: [
+ 'āđāļĢāļēāļāļāļāđāļāļāļĢāļ°āļāļāļāļīāđāļ§āļĻāļāļīāļāļīāļāļąāļĨāļāļąāđāļāļŠāļđāļ āđāļāļĒāđāļāļĩāđāļĒāļ§āļāļēāļāđāļāļāļēāļĢāļāļŠāļēāļāđāļĄāđāļāļĨ AI āđāļāđāļēāļāļąāļāđāļ§āļīāļĢāđāļāđāļāļĨāļ§āđāļĢāļ°āļāļąāļāļĄāļ·āļāļāļēāļāļĩāļāļāļĩāđāļāđāļāļāļāļēāļĢāļāļ§āļēāļĄāđāļĄāđāļāļĒāļģ āļāļ§āļēāļĄāļāļĨāļāļāļ āļąāļĒ āđāļĨāļ°āļāļ§āļēāļĄāļāđāļēāđāļāļ·āđāļāļāļ·āļ',
+ 'āđāļāļ§āļāļēāļāļāļāļāđāļĢāļēāļāļ·āļāđāļāļĨāļĩāđāļĒāļāļāđāļāļĄāļđāļĨāļāļĩāđāļāļąāļāļāđāļāļāđāļŦāđāđāļāđāļāđāļāļĢāļ·āđāļāļāļĄāļ·āļāļāļēāļĢāļāļģāļāļēāļāļāļĩāđāļĨāļ·āđāļāđāļŦāļĨ āļāđāļēāļāļāļąāļĨāļāļāļĢāļīāļāļķāļĄāđāļāļāļēāļ°āļāļēāļ āļāļīāļāđāļāļāļĢāđāđāļāļāđāļŠāļĩāļĒāļ āđāļĨāļ°āļŠāļāļēāļāļąāļāļĒāļāļĢāļĢāļĄāļāļĨāļēāļ§āļāđāļāļĩāđāļāļĒāļēāļĒāđāļāđ',
+ ] as const,
+ businessUnitsHeading: 'āļŦāļāđāļ§āļĒāļāļļāļĢāļāļīāļāļāļāļāđāļĢāļē:',
+ businessUnitsIntro:
+ 'āđāļĢāļēāļāļģāđāļāļīāļāļāļēāļāļāđāļēāļāļāļĩāļĄāđāļāļāļēāļ°āļāļēāļāđāļāļ·āđāļāđāļŦāđāđāļāđāļāļ§āļēāļĄāđāļāļĩāđāļĒāļ§āļāļēāļāđāļāļīāļāļĨāļķāļāđāļāđāļāđāļĨāļ°āđāļāđāļĄāļ:',
+ businessUnits: [
+ {
+ name: 'Legal Tech',
+ description: 'āđāļāļĨāļđāļāļąāļāļŠāļģāļŦāļĢāļąāļāļāļēāļāļāļāļŦāļĄāļēāļĒāļāļąāļāđāļāļĄāļąāļāļīāđāļĨāļ°āļāļēāļĢāļ§āļīāđāļāļĢāļēāļ°āļŦāđāļāđāļāļāļģāļāļąāļ',
+ },
+ {
+ name: 'Health Tech',
+ description: 'āļĢāļ°āļāļāļāļąāđāļāļŠāļđāļāļŠāļģāļŦāļĢāļąāļāļāļēāļĢāļāļąāļāļāļēāļĢāđāļĨāļ°āļāļģāļāļēāļāļāļąāļāđāļāļĄāļąāļāļīāđāļāļ āļēāļāļŠāļļāļāļ āļēāļ',
+ },
+ ] as const,
+ },
} as const;
+
+export const getHero = (locale: SupportedLocale) => heroByLocale[locale];
+
+/** Retro-compatibilità : fallback italiano. */
+export const hero = heroByLocale.it;
diff --git a/src/data/home/index.ts b/src/data/home/index.ts
index 62a6c57..778375f 100644
--- a/src/data/home/index.ts
+++ b/src/data/home/index.ts
@@ -3,13 +3,21 @@
* Modifica i file in questa cartella per aggiornare testi senza toccare il markup.
*/
export { siteMeta } from './site-meta';
+export { getSiteMeta } from './site-meta';
export { chat } from './chat';
export { navigation } from './navigation';
+export { getNavigation } from './navigation';
export { hero } from './hero';
+export { getHero } from './hero';
export { stats } from './stats';
export { services } from './services';
+export { getServices } from './services';
export { stackSection } from './stack';
+export { getStackSection } from './stack';
export { productsSection } from './products';
export { faq } from './faq';
+export { getFaq } from './faq';
export { cta } from './cta';
+export { getCta } from './cta';
export { footer } from './footer';
+export { getFooter } from './footer';
diff --git a/src/data/home/navigation.ts b/src/data/home/navigation.ts
index 4d7510c..115d110 100644
--- a/src/data/home/navigation.ts
+++ b/src/data/home/navigation.ts
@@ -1,19 +1,77 @@
import { chat } from './chat';
-/** Header â CTA unico: ingresso chat live (config in `chat.ts`) */
-export const navigation = {
- brandName: 'NexStudio',
- items: [
- { label: 'Prodotti', href: '/#prodotti' },
- { label: 'Servizi', href: '/#servizi' },
- { label: 'Stack', href: '/#stack' },
- { label: 'FAQ', href: '/#faq' },
- { label: 'Contattaci', href: '/#contatti' },
- ] as const,
- cta: {
- label: 'Chattiamo',
- linkTitle: chat.linkTitle,
- ariaLabel:
- 'Richiedi accesso alla chat NexStudio: stato operatore e chatbot, identificazione con email (link o codice) prima della sessione.',
+export type SupportedLocale = 'it' | 'en' | 'th';
+
+const navigationByLocale = {
+ it: {
+ brandName: 'NexStudio',
+ items: [
+ { label: 'Prodotti', href: '/#prodotti' },
+ { label: 'Servizi', href: '/#servizi' },
+ { label: 'Stack', href: '/#stack' },
+ { label: 'FAQ', href: '/#faq' },
+ { label: 'Contattaci', href: '/#contatti' },
+ ] as const,
+ cta: {
+ label: 'Chattiamo',
+ linkTitle: chat.linkTitle,
+ ariaLabel:
+ 'Richiedi accesso alla chat NexStudio: stato operatore e chatbot, identificazione con email (link o codice) prima della sessione.',
+ },
+ labels: {
+ mainNavAria: 'Principale',
+ mobileNavAria: 'Navigazione mobile',
+ languageSelectorAria: 'Seleziona lingua',
+ openMenuAria: 'Apri menu',
+ },
+ },
+ en: {
+ brandName: 'NexStudio',
+ items: [
+ { label: 'Products', href: '/#prodotti' },
+ { label: 'Services', href: '/#servizi' },
+ { label: 'Stack', href: '/#stack' },
+ { label: 'FAQ', href: '/#faq' },
+ { label: 'Contact', href: '/#contatti' },
+ ] as const,
+ cta: {
+ label: 'Letâs chat',
+ linkTitle: 'Open NexStudio chat access request.',
+ ariaLabel:
+ 'Request access to NexStudio chat: operator and chatbot availability, email verification link or code before session start.',
+ },
+ labels: {
+ mainNavAria: 'Main navigation',
+ mobileNavAria: 'Mobile navigation',
+ languageSelectorAria: 'Select language',
+ openMenuAria: 'Open menu',
+ },
+ },
+ th: {
+ brandName: 'NexStudio',
+ items: [
+ { label: 'āļāļĨāļīāļāļ āļąāļāļāđ', href: '/#prodotti' },
+ { label: 'āļāļĢāļīāļāļēāļĢ', href: '/#servizi' },
+ { label: 'āļŠāđāļāļ', href: '/#stack' },
+ { label: 'āļāļģāļāļēāļĄāļāļĩāđāļāļāļāđāļāļĒ', href: '/#faq' },
+ { label: 'āļāļīāļāļāđāļāđāļĢāļē', href: '/#contatti' },
+ ] as const,
+ cta: {
+ label: 'āđāļĢāļīāđāļĄāđāļāļ',
+ linkTitle: 'āđāļāļīāļāļāļģāļāļāđāļāđāļēāđāļāđāļāļēāļāđāļāļāļāļāļ NexStudio',
+ ariaLabel:
+ 'āļāļāđāļāđāļēāđāļāđāļāļēāļāđāļāļ NexStudio: āļāļĢāļ§āļāļŠāļāļāļŠāļāļēāļāļ°āļāļđāđāļāļđāđāļĨāđāļĨāļ°āđāļāļāļāļāļ āļāļĢāđāļāļĄāļĒāļ·āļāļĒāļąāļāļāļąāļ§āļāļāļāđāļ§āļĒāļāļĩāđāļĄāļĨāļāđāļāļāđāļĢāļīāđāļĄāđāļāđāļāļēāļ',
+ },
+ labels: {
+ mainNavAria: 'āđāļĄāļāļđāļŦāļĨāļąāļ',
+ mobileNavAria: 'āđāļĄāļāļđāļāļāļĄāļ·āļāļāļ·āļ',
+ languageSelectorAria: 'āđāļĨāļ·āļāļāļ āļēāļĐāļē',
+ openMenuAria: 'āđāļāļīāļāđāļĄāļāļđ',
+ },
},
} as const;
+
+export const getNavigation = (locale: SupportedLocale) => navigationByLocale[locale];
+
+/** Retro-compatibilità : fallback italiano. */
+export const navigation = navigationByLocale.it;
diff --git a/src/data/home/services.ts b/src/data/home/services.ts
index e86d14c..ea8ee6a 100644
--- a/src/data/home/services.ts
+++ b/src/data/home/services.ts
@@ -2,51 +2,153 @@
* Servizi (griglia bento).
* layout: wide = 2 colonne, tall = 2 righe + elenco puntato
*/
-export const services = {
- eyebrow: 'I nostri servizi',
- title: 'Implementazione, evoluzione e supporto',
- lead:
- 'In NexStudio, il nostro impegno non si esaurisce con la fornitura della licenza software. Il nostro modello di servizio ÃĻ progettato per garantire che ogni professionista e struttura possa estrarre il massimo valore dalle potenzialità dellâIntelligenza Artificiale integrata in LexAura e MediAura.',
- cards: [
- {
- layout: 'tall' as const,
- /** Sfera geodetica vettoriale (SVG) in basso a destra */
- decoration: 'wireframe-globe' as const,
- title: 'Onboarding e formazione specialistica',
- body:
- 'Lâadozione di un sistema basato su IA richiede un passaggio metodologico, non solo tecnico. Offriamo programmi di formazione dedicati per team legali e medici, finalizzati a:',
- bullets: [
- 'Ottimizzare lâinterazione con gli algoritmi di ricerca e sintesi.',
- 'Padroneggiare i comandi vocali e lâautomazione dei flussi documentali.',
- 'Ridurre drasticamente la curva di apprendimento tecnologico.',
- ],
- },
- {
- layout: 'wide' as const,
- title: 'Supporto Tecnico e Consulenza Operativa',
- body:
- 'Forniamo unâassistenza continua e di alto profilo per garantire la costante continuità operativa dei vostri sistemi. NexStudio non agisce come un semplice fornitore di supporto tecnico, ma come un partner strategico che affianca lo studio o la struttura sanitaria nellâottimizzazione dei processi interni attraverso lâuso dei nostri SaaS.',
- callout: {
- title: 'Intervento ÂŦBreaking GlassÂŧ',
+import type { SupportedLocale } from './navigation';
+
+const servicesByLocale = {
+ it: {
+ eyebrow: 'I nostri servizi',
+ title: 'Implementazione, evoluzione e supporto',
+ lead:
+ 'In NexStudio, il nostro impegno non si esaurisce con la fornitura della licenza software. Il nostro modello di servizio ÃĻ progettato per garantire che ogni professionista e struttura possa estrarre il massimo valore dalle potenzialità dellâIntelligenza Artificiale integrata in LexAura e MediAura.',
+ cards: [
+ {
+ layout: 'tall' as const,
+ decoration: 'wireframe-globe' as const,
+ title: 'Onboarding e formazione specialistica',
body:
- 'Per le situazioni di estrema urgenza o criticità sistemica, garantiamo protocolli di accesso rapido e intervento prioritario. Questa procedura di emergenza permette di superare i normali flussi di assistenza per risolvere istantaneamente anomalie che potrebbero impattare sulla continuità del servizio, assicurando che il professionista non resti mai isolato dai propri dati o strumenti decisionali.',
+ 'Lâadozione di un sistema basato su IA richiede un passaggio metodologico, non solo tecnico. Offriamo programmi di formazione dedicati per team legali e medici, finalizzati a:',
+ bullets: [
+ 'Ottimizzare lâinterazione con gli algoritmi di ricerca e sintesi.',
+ 'Padroneggiare i comandi vocali e lâautomazione dei flussi documentali.',
+ 'Ridurre drasticamente la curva di apprendimento tecnologico.',
+ ],
},
- },
- {
- layout: 'default' as const,
- title: 'Estensioni e integrazioni personalizzate',
- body:
- 'Sebbene LexAura e MediAura siano prodotti finiti e pronti allâuso, comprendiamo che strutture complesse possano avere esigenze di interconnessione specifiche.',
- bullets: [
- 'API integration: supportiamo lâintegrazione dei nostri SaaS con sistemi gestionali preesistenti.',
- 'Custom modules: progettiamo estensioni su misura che aggiungono funzionalità specifiche allâinterno del perimetro dei nostri prodotti, per rispondere a flussi di lavoro unici.',
- ],
- },
- {
- layout: 'default' as const,
- title: 'Aggiornamento e manutenzione evolutiva',
- body:
- 'Il mondo dellâIA e delle normative (legali e sanitarie) ÃĻ in costante mutamento. Il nostro servizio include lâaggiornamento continuo dei motori di analisi, garantendo che il software sia sempre allineato con le ultime tecnologie e le evoluzioni del mercato di riferimento.',
- },
- ],
+ {
+ layout: 'wide' as const,
+ title: 'Supporto Tecnico e Consulenza Operativa',
+ body:
+ 'Forniamo unâassistenza continua e di alto profilo per garantire la costante continuità operativa dei vostri sistemi. NexStudio non agisce come un semplice fornitore di supporto tecnico, ma come un partner strategico che affianca lo studio o la struttura sanitaria nellâottimizzazione dei processi interni attraverso lâuso dei nostri SaaS.',
+ callout: {
+ title: 'Intervento ÂŦBreaking GlassÂŧ',
+ body:
+ 'Per le situazioni di estrema urgenza o criticità sistemica, garantiamo protocolli di accesso rapido e intervento prioritario. Questa procedura di emergenza permette di superare i normali flussi di assistenza per risolvere istantaneamente anomalie che potrebbero impattare sulla continuità del servizio, assicurando che il professionista non resti mai isolato dai propri dati o strumenti decisionali.',
+ },
+ },
+ {
+ layout: 'default' as const,
+ title: 'Estensioni e integrazioni personalizzate',
+ body:
+ 'Sebbene LexAura e MediAura siano prodotti finiti e pronti allâuso, comprendiamo che strutture complesse possano avere esigenze di interconnessione specifiche.',
+ bullets: [
+ 'API integration: supportiamo lâintegrazione dei nostri SaaS con sistemi gestionali preesistenti.',
+ 'Custom modules: progettiamo estensioni su misura che aggiungono funzionalità specifiche allâinterno del perimetro dei nostri prodotti, per rispondere a flussi di lavoro unici.',
+ ],
+ },
+ {
+ layout: 'default' as const,
+ title: 'Aggiornamento e manutenzione evolutiva',
+ body:
+ 'Il mondo dellâIA e delle normative (legali e sanitarie) ÃĻ in costante mutamento. Il nostro servizio include lâaggiornamento continuo dei motori di analisi, garantendo che il software sia sempre allineato con le ultime tecnologie e le evoluzioni del mercato di riferimento.',
+ },
+ ],
+ },
+ en: {
+ eyebrow: 'Our services',
+ title: 'Implementation, evolution, and support',
+ lead:
+ 'At NexStudio, our commitment goes beyond software licensing. Our service model helps each professional and organization unlock the full value of AI integrated into LexAura and MediAura.',
+ cards: [
+ {
+ layout: 'tall' as const,
+ decoration: 'wireframe-globe' as const,
+ title: 'Onboarding and specialist training',
+ body:
+ 'Adopting AI-powered systems is a methodological shift, not only a technical one. We provide dedicated programs for legal and medical teams to:',
+ bullets: [
+ 'Improve interaction with search and summarization algorithms.',
+ 'Master voice commands and document workflow automation.',
+ 'Significantly reduce the technology learning curve.',
+ ],
+ },
+ {
+ layout: 'wide' as const,
+ title: 'Technical support and operational consulting',
+ body:
+ 'We provide continuous, high-level assistance to ensure operational continuity. NexStudio is not just a support vendor, but a strategic partner for legal firms and healthcare organizations.',
+ callout: {
+ title: 'âBreaking Glassâ intervention',
+ body:
+ 'For critical urgency or systemic incidents, we offer rapid-access and priority intervention protocols. This emergency procedure bypasses standard support flows to restore continuity as fast as possible.',
+ },
+ },
+ {
+ layout: 'default' as const,
+ title: 'Custom extensions and integrations',
+ body:
+ 'Although LexAura and MediAura are complete, ready-to-use products, complex organizations may still require specific interoperability needs.',
+ bullets: [
+ 'API integration: we integrate our SaaS with your existing management systems.',
+ 'Custom modules: we build tailored extensions inside our product perimeter to support unique workflows.',
+ ],
+ },
+ {
+ layout: 'default' as const,
+ title: 'Evolutionary updates and maintenance',
+ body:
+ 'AI and regulated frameworks evolve continuously. Our service includes ongoing analysis-engine updates to keep software aligned with new technologies and market requirements.',
+ },
+ ],
+ },
+ th: {
+ eyebrow: 'āļāļĢāļīāļāļēāļĢāļāļāļāđāļĢāļē',
+ title: 'āļāļēāļĢāļāļīāļāļāļąāđāļ āļāļēāļĢāļāļąāļāļāļē āđāļĨāļ°āļāļēāļĢāļŠāļāļąāļāļŠāļāļļāļ',
+ lead:
+ 'āļāļĩāđ NexStudio āļāļ§āļēāļĄāļĄāļļāđāļāļĄāļąāđāļāļāļāļāđāļĢāļēāđāļĄāđāđāļāđāļāļāđāļāđāļāļēāļĢāđāļŦāđāļŠāļīāļāļāļīāđāđāļāđāļāļēāļāļāļāļāļāđāđāļ§āļĢāđ āđāļĄāđāļāļĨāļāļĢāļīāļāļēāļĢāļāļāļāđāļĢāļēāļāđāļ§āļĒāđāļŦāđāļāļĩāļĄāļāļēāļāļāļķāļāļĻāļąāļāļĒāļ āļēāļāļŠāļđāļāļŠāļļāļāļāļēāļ AI āļāļĩāđāļāļŠāļēāļāđāļ LexAura āđāļĨāļ° MediAura',
+ cards: [
+ {
+ layout: 'tall' as const,
+ decoration: 'wireframe-globe' as const,
+ title: 'āļāļēāļĢāđāļĢāļīāđāļĄāđāļāđāļāļēāļāđāļĨāļ°āļāļēāļĢāļāļāļĢāļĄāđāļāļāļēāļ°āļāļēāļ',
+ body:
+ 'āļāļēāļĢāļāļģāļĢāļ°āļāļ AI āļĄāļēāđāļāđāļāđāļāļāļāļēāļĻāļąāļĒāļāļēāļĢāđāļāļĨāļĩāđāļĒāļāļāđāļēāļāđāļāļīāļāļ§āļīāļāļĩāļāļēāļĢ āđāļĄāđāđāļāđāđāļāđāđāļāļāļāļīāļ āđāļĢāļēāļĄāļĩāđāļāļĢāđāļāļĢāļĄāļāļāļĢāļĄāļŠāļģāļŦāļĢāļąāļāļāļĩāļĄāļāļāļŦāļĄāļēāļĒāđāļĨāļ°āļāļēāļĢāđāļāļāļĒāđāđāļāļ·āđāļ:',
+ bullets: [
+ 'āđāļāļīāđāļĄāļāļĢāļ°āļŠāļīāļāļāļīāļ āļēāļāļāļēāļĢāđāļāđāļāļēāļāļāļąāļĨāļāļāļĢāļīāļāļķāļĄāļāđāļāļŦāļēāđāļĨāļ°āļŠāļĢāļļāļāļāļĨ',
+ 'āđāļāđāļāļēāļāļāļģāļŠāļąāđāļāđāļŠāļĩāļĒāļāđāļĨāļ°āļĢāļ°āļāļāļāļēāļāđāļāļāļŠāļēāļĢāļāļąāļāđāļāļĄāļąāļāļīāđāļāđāļāļĒāđāļēāļāļāļĨāđāļāļāļāļąāļ§',
+ 'āļĨāļāļāđāļ§āļāđāļ§āļĨāļēāđāļĢāļĩāļĒāļāļĢāļđāđāđāļāļāđāļāđāļĨāļĒāļĩāļāļĒāđāļēāļāļĄāļĩāļāļąāļĒāļŠāļģāļāļąāļ',
+ ],
+ },
+ {
+ layout: 'wide' as const,
+ title: 'āļŠāļāļąāļāļŠāļāļļāļāļāļēāļāđāļāļāļāļīāļāđāļĨāļ°āļāļĩāđāļāļĢāļķāļāļĐāļēāļāļēāļĢāļāļāļīāļāļąāļāļīāļāļēāļ',
+ body:
+ 'āđāļĢāļēāđāļŦāđāļāļēāļĢāļŠāļāļąāļāļŠāļāļļāļāļāļĒāđāļēāļāļāđāļāđāļāļ·āđāļāļāđāļāļ·āđāļāļāļāļāļ§āļēāļĄāļāđāļāđāļāļ·āđāļāļāđāļāļāļēāļĢāļāļģāđāļāļīāļāļāļēāļ NexStudio āđāļĄāđāđāļāđāđāļāđāļāđāļāļĩāļĒāļāļāļđāđāđāļŦāđāļāļĢāļīāļāļēāļĢāļāļąāļāļāļāļĢāđāļ āđāļāđāđāļāđāļāļāļēāļĢāđāļāđāļāļāļĢāđāđāļāļīāļāļāļĨāļĒāļļāļāļāđāļŠāļģāļŦāļĢāļąāļāļāļāļāđāļāļĢ',
+ callout: {
+ title: 'āļāļēāļĢāđāļāļĢāļāđāļāļāđāļāļ âBreaking Glassâ',
+ body:
+ 'āđāļĄāļ·āđāļāđāļāļīāļāđāļŦāļāļļāđāļĢāđāļāļāđāļ§āļāļŦāļĢāļ·āļāļāļ§āļēāļĄāļāļīāļāļāļāļāļīāļĢāļ°āļāļąāļāļ§āļīāļāļĪāļ āđāļĢāļēāļĄāļĩāđāļāļĢāđāļāļāļāļĨāđāļāđāļēāļāļķāļāļāđāļ§āļāđāļĨāļ°āļāļąāļāļĨāļģāļāļąāļāļāļ§āļēāļĄāļŠāļģāļāļąāļāļŠāļđāļāļŠāļļāļ āđāļāļ·āđāļāđāļāđāļāļąāļāļŦāļēāđāļāđāļāļąāļāļāļĩāđāļĨāļ°āļĢāļąāļāļĐāļēāļāļ§āļēāļĄāļāđāļāđāļāļ·āđāļāļāļāļāļāļāļĢāļīāļāļēāļĢ',
+ },
+ },
+ {
+ layout: 'default' as const,
+ title: 'āļŠāđāļ§āļāļāļĒāļēāļĒāđāļĨāļ°āļāļēāļĢāđāļāļ·āđāļāļĄāļāđāļāđāļāļāļāļģāļŦāļāļāđāļāļ',
+ body:
+ 'āđāļĄāđ LexAura āđāļĨāļ° MediAura āļāļ°āļāļĢāđāļāļĄāđāļāđāļāļēāļāļāļąāļāļāļĩ āđāļāđāļāļēāļāļāļāļāđāļāļĢāļāļēāļāļāđāļāļāļāļēāļĢāļāļēāļĢāđāļāļ·āđāļāļĄāļāđāļāđāļāļāļēāļ°āļāļēāļāļāļąāļāļĢāļ°āļāļāđāļāļīāļĄ',
+ bullets: [
+ 'API integration: āđāļāļ·āđāļāļĄ SaaS āļāļāļāđāļĢāļēāđāļāđāļēāļāļąāļāļĢāļ°āļāļāļāļąāļāļāļēāļĢāļāļĩāđāđāļāđāļāļĒāļđāđāđāļĨāđāļ§',
+ 'Custom modules: āļāļāļāđāļāļāļŠāđāļ§āļāļāļĒāļēāļĒāđāļāļāļēāļ°āļāļēāļāļ āļēāļĒāđāļāļāļāļāđāļāļāļāļĨāļīāļāļ āļąāļāļāđāļāļāļāđāļĢāļē',
+ ],
+ },
+ {
+ layout: 'default' as const,
+ title: 'āļāļąāļāđāļāļāđāļĨāļ°āļāļģāļĢāļļāļāļĢāļąāļāļĐāļēāđāļāļīāļāļāļąāļāļāļē',
+ body:
+ 'āđāļĨāļāļāļāļ AI āđāļĨāļ°āļāđāļāļāļģāļāļąāļāđāļāļĨāļĩāđāļĒāļāđāļāļĨāļāļāļĨāļāļāđāļ§āļĨāļē āļāļĢāļīāļāļēāļĢāļāļāļāđāļĢāļēāļĢāļ§āļĄāļāļķāļāļāļēāļĢāļāļąāļāđāļāļāđāļāļāļāļīāļāļ§āļīāđāļāļĢāļēāļ°āļŦāđāļāļĒāđāļēāļāļāđāļāđāļāļ·āđāļāļāđāļāļ·āđāļāđāļŦāđāļāļāļāļāđāđāļ§āļĢāđāļāļąāļāļŠāļĄāļąāļĒāđāļĨāļ°āļŠāļāļāļāļĨāđāļāļāļāļĢāļīāļāļāļāļĨāļēāļ',
+ },
+ ],
+ },
} as const;
+
+export const getServices = (locale: SupportedLocale) => servicesByLocale[locale];
+
+/** Retro-compatibilità : fallback italiano. */
+export const services = servicesByLocale.it;
diff --git a/src/data/home/site-meta.ts b/src/data/home/site-meta.ts
index 0f8ca16..d6370ce 100644
--- a/src/data/home/site-meta.ts
+++ b/src/data/home/site-meta.ts
@@ -1,6 +1,25 @@
+import type { SupportedLocale } from './navigation';
+
/** Meta pagina principale â usato da BaseLayout */
-export const siteMeta = {
- title: 'NexStudio â Ingegneria del software e IA per settori regolamentati',
- description:
- 'NexStudio: software company con sede a Bangkok. SaaS ad alta complessità , integrazione di IA in flussi professionali, Legal Tech e Health Tech.',
+const siteMetaByLocale = {
+ it: {
+ title: 'NexStudio â Ingegneria del software e IA per settori regolamentati',
+ description:
+ 'NexStudio: software company con sede a Bangkok. SaaS ad alta complessità , integrazione di IA in flussi professionali, Legal Tech e Health Tech.',
+ },
+ en: {
+ title: 'NexStudio â Software engineering and AI for regulated industries',
+ description:
+ 'NexStudio is a software company based in Bangkok. We build high-complexity SaaS products and integrate AI into professional workflows across Legal Tech and Health Tech.',
+ },
+ th: {
+ title: 'NexStudio â āļ§āļīāļĻāļ§āļāļĢāļĢāļĄāļāļāļāļāđāđāļ§āļĢāđāđāļĨāļ° AI āļŠāļģāļŦāļĢāļąāļāļāļļāļāļŠāļēāļŦāļāļĢāļĢāļĄāļāļĩāđāļĄāļĩāļāđāļāļāļģāļāļąāļ',
+ description:
+ 'NexStudio āļāļ·āļāļāļĢāļīāļĐāļąāļāļāļāļāļāđāđāļ§āļĢāđāđāļāļāļĢāļļāļāđāļāļāļŊ āļāļąāļāļāļē SaaS āļāļ§āļēāļĄāļāļąāļāļāđāļāļāļŠāļđāļ āđāļĨāļ°āļāļŠāļēāļ AI āđāļāđāļēāļāļąāļāđāļ§āļīāļĢāđāļāđāļāļĨāļ§āđāļĢāļ°āļāļąāļāļĄāļ·āļāļāļēāļāļĩāļāđāļāļŠāļēāļĒ Legal Tech āđāļĨāļ° Health Tech',
+ },
} as const;
+
+export const getSiteMeta = (locale: SupportedLocale) => siteMetaByLocale[locale];
+
+/** Retro-compatibilità : fallback italiano. */
+export const siteMeta = siteMetaByLocale.it;
diff --git a/src/data/home/stack.ts b/src/data/home/stack.ts
index 04e3e3b..cb1bbcd 100644
--- a/src/data/home/stack.ts
+++ b/src/data/home/stack.ts
@@ -1,9 +1,12 @@
+import type { SupportedLocale } from './navigation';
+
/** Sezione stack â infrastruttura Cloudflare e sicurezza */
-export const stackSection = {
+const stackIt = {
eyebrow: 'Lo stack tecnologico',
title: 'Infrastruttura e sicurezza',
lead:
'In NexStudio, la qualità dellâesperienza utente ÃĻ inscindibile dalla solidità dellâinfrastruttura. Per questo motivo ci affidiamo a partner globali ad alta efficienza che garantiscono i piÃđ elevati standard di disponibilità e protezione dei dati.',
+ infrastructureHeading: 'Infrastruttura',
cloudflare: {
title: 'Ecosistema Cloudflare',
intro:
@@ -145,3 +148,168 @@ export const stackSection = {
] as const,
},
} as const;
+
+const stackByLocale = {
+ it: stackIt,
+ en: {
+ ...stackIt,
+ eyebrow: 'Technology stack',
+ title: 'Infrastructure and security',
+ lead:
+ 'At NexStudio, user experience quality is inseparable from infrastructure resilience. That is why we rely on high-efficiency global partners that provide strong availability and data protection standards.',
+ infrastructureHeading: 'Infrastructure',
+ cloudflare: {
+ ...stackIt.cloudflare,
+ title: 'Cloudflare ecosystem',
+ intro:
+ '"Cloudflare helps accelerate performance, secure app availability, and optimize web experiences globally."',
+ points: [
+ {
+ title: 'Performance without compromise',
+ body:
+ 'Access to our services remains low-latency worldwide, ensuring fluid usage even during complex data-processing operations.',
+ },
+ {
+ title: 'Advanced security',
+ body:
+ 'We apply modern protection layers including end-to-end encryption, DDoS mitigation, and Web Application Firewall controls.',
+ },
+ {
+ title: 'Compliance and data integrity',
+ body:
+ 'We use geographic data-control capabilities to align legal and medical data processing with local and international privacy requirements.',
+ },
+ ] as const,
+ },
+ continuity: {
+ title: 'Continuity and scalability',
+ body:
+ 'We provide professional-grade SLA uptime. Our cloud-native architecture scales instantly for workload peaks, large offices, and multi-site organizations.',
+ },
+ whyThisChoice: {
+ title: 'Why NexStudio',
+ points: [
+ 'Regulated vertical focus: we design for Legal Tech and Health Tech, where traceability, privacy, and service continuity are core product requirements.',
+ 'AI in real professional workflows: we embed models and automation with attention to accuracy, auditability, and human oversight.',
+ 'End-to-end responsibility: architecture, development, and evolution stay under one ownership model for clearer priorities and delivery.',
+ ] as const,
+ },
+ cloudflareBadge: {
+ ...stackIt.cloudflareBadge,
+ label: 'Cloudflare ecosystem',
+ slogan: '"Helping build a better Internet."',
+ },
+ awsBadge: {
+ ...stackIt.awsBadge,
+ label: 'AWS ecosystem',
+ slogan: '"The worldâs most comprehensive and broadly adopted cloud platform."',
+ },
+ infrastructureCarousel: {
+ ...stackIt.infrastructureCarousel,
+ ariaLabel: 'NexStudio infrastructure and technology partners',
+ items: [
+ {
+ ...stackIt.infrastructureCarousel.items[0],
+ label: 'Cloudflare ecosystem',
+ slogan: '"Helping build a better Internet."',
+ },
+ {
+ ...stackIt.infrastructureCarousel.items[1],
+ label: 'AWS ecosystem',
+ slogan: '"The worldâs most comprehensive and broadly adopted cloud platform."',
+ },
+ {
+ ...stackIt.infrastructureCarousel.items[2],
+ label: 'GitHub ecosystem',
+ },
+ {
+ ...stackIt.infrastructureCarousel.items[3],
+ label: 'OpenAI ecosystem',
+ },
+ ] as const,
+ },
+ },
+ th: {
+ ...stackIt,
+ eyebrow: 'āđāļāļāđāļāđāļĨāļĒāļĩāļŠāđāļāļ',
+ title: 'āđāļāļĢāļāļŠāļĢāđāļēāļāļāļ·āđāļāļāļēāļāđāļĨāļ°āļāļ§āļēāļĄāļāļĨāļāļāļ āļąāļĒ',
+ lead:
+ 'āļāļĩāđ NexStudio āļāļļāļāļ āļēāļāļāļĢāļ°āļŠāļāļāļēāļĢāļāđāļāļđāđāđāļāđāđāļĒāļāđāļĄāđāļāļāļāļāļēāļāļāļ§āļēāļĄāļĄāļąāđāļāļāļāļāļāļāđāļāļĢāļāļŠāļĢāđāļēāļāļāļ·āđāļāļāļēāļ āđāļĢāļēāļāļķāļāđāļĨāļ·āļāļāļāļēāļĢāđāļāđāļāļāļĢāđāļĢāļ°āļāļąāļāđāļĨāļāļāļĩāđāļĄāļĩāļāļĢāļ°āļŠāļīāļāļāļīāļ āļēāļāļŠāļđāļāđāļāļ·āđāļāđāļŦāđāđāļāđāļĄāļēāļāļĢāļāļēāļāļāđāļēāļāļāļ§āļēāļĄāļāļĢāđāļāļĄāđāļāđāļāļēāļāđāļĨāļ°āļāļ§āļēāļĄāļāļĨāļāļāļ āļąāļĒāļāļāļāļāđāļāļĄāļđāļĨ',
+ infrastructureHeading: 'āđāļāļĢāļāļŠāļĢāđāļēāļāļāļ·āđāļāļāļēāļ',
+ cloudflare: {
+ ...stackIt.cloudflare,
+ title: 'āļĢāļ°āļāļāļāļīāđāļ§āļĻ Cloudflare',
+ intro:
+ '"Cloudflare āļāđāļ§āļĒāđāļĢāđāļāļāļĢāļ°āļŠāļīāļāļāļīāļ āļēāļ āļĢāļąāļāļāļĢāļ°āļāļąāļāļāļ§āļēāļĄāļāļĢāđāļāļĄāđāļāđāļāļēāļāļāļāļāđāļāļ āđāļĨāļ°āļĒāļāļĢāļ°āļāļąāļāļāļĢāļ°āļŠāļāļāļēāļĢāļāđāđāļ§āđāļāļāļąāđāļ§āđāļĨāļ"',
+ points: [
+ {
+ title: 'āļāļĢāļ°āļŠāļīāļāļāļīāļ āļēāļāļāļĩāđāđāļĄāđāļāļĢāļ°āļāļĩāļāļĢāļ°āļāļāļĄ',
+ body:
+ 'āđāļāđāļēāļāļķāļāļāļĢāļīāļāļēāļĢāļāļāļāđāļĢāļēāđāļāđāļāļĒāđāļēāļāļŦāļāđāļ§āļāļāđāļģāļāļēāļāļāļļāļāļāļĩāđāļāļąāđāļ§āđāļĨāļ āđāļĄāđāđāļāļāļēāļāļāļĢāļ°āļĄāļ§āļĨāļāļĨāļāđāļāļĄāļđāļĨāļāļĩāđāļāļąāļāļāđāļāļ',
+ },
+ {
+ title: 'āļāļ§āļēāļĄāļāļĨāļāļāļ āļąāļĒāļāļąāđāļāļŠāļđāļ',
+ body:
+ 'āđāļĢāļēāđāļāđāļāļĨāđāļāļāđāļāļāļāļąāļāļŠāļĄāļąāļĒāđāļŦāļĄāđ āđāļāđāļ āļāļēāļĢāđāļāđāļēāļĢāļŦāļąāļŠ end-to-end āļāļēāļĢāļāđāļāļāļāļąāļ DDoS āđāļĨāļ° Web Application Firewall',
+ },
+ {
+ title: 'āļāļēāļĢāļāļāļīāļāļąāļāļīāļāļēāļĄāļāđāļāļāļģāļāļąāļāđāļĨāļ°āļāļ§āļēāļĄāļāļđāļāļāđāļāļāļāļāļāļāđāļāļĄāļđāļĨ',
+ body:
+ 'āđāļĢāļēāđāļāđāļāļ§āļēāļĄāļŠāļēāļĄāļēāļĢāļāđāļāļāļēāļĢāļāļģāļāļąāļāļāļģāđāļŦāļāđāļāļāđāļāļĄāļđāļĨāđāļāļ·āđāļāđāļŦāđāļāļēāļĢāļāļąāļāļāļēāļĢāļāđāļāļĄāļđāļĨāļāđāļāļāđāļŦāļ§āļāđāļēāļāļāļāļŦāļĄāļēāļĒāđāļĨāļ°āļāļēāļĢāđāļāļāļĒāđāļŠāļāļāļāļĨāđāļāļāļāļąāļāļāđāļāļāļģāļāļąāļāļāļ§āļēāļĄāđāļāđāļāļŠāđāļ§āļāļāļąāļ§',
+ },
+ ] as const,
+ },
+ continuity: {
+ title: 'āļāļ§āļēāļĄāļāđāļāđāļāļ·āđāļāļāđāļĨāļ°āļāļēāļĢāļāļĒāļēāļĒāļāļąāļ§',
+ body:
+ 'āđāļĢāļēāļĢāļąāļāļāļĢāļ°āļāļąāļ uptime āļĢāļ°āļāļąāļāļĄāļ·āļāļāļēāļāļĩāļāļāļēāļĄ SLA āđāļĨāļ°āļŠāļāļēāļāļąāļāļĒāļāļĢāļĢāļĄ cloud-native āļāļĩāđāļāļĒāļēāļĒāđāļāđāļāļąāļāļāļĩāđāļĄāļ·āđāļāļĄāļĩāđāļŦāļĨāļāļŠāļđāļ',
+ },
+ whyThisChoice: {
+ title: 'āļāļģāđāļĄāļāđāļāļ NexStudio',
+ points: [
+ 'āđāļāļĩāđāļĒāļ§āļāļēāļāļāļļāļāļŠāļēāļŦāļāļĢāļĢāļĄāļāļĩāđāļĄāļĩāļāđāļāļāļģāļāļąāļ: Legal Tech āđāļĨāļ° Health Tech',
+ 'āļāļŠāļēāļ AI āđāļāđāļēāļāļąāļāļāļēāļāļāļĢāļīāļ āđāļāļĒāļāļģāļāļķāļāļāļķāļāļāļ§āļēāļĄāđāļĄāđāļāļĒāļģ āļāļēāļĢāļāļĢāļ§āļāļŠāļāļāļĒāđāļāļāļŦāļĨāļąāļ āđāļĨāļ°āļāļēāļĢāļāļģāļāļąāļāđāļāļĒāļĄāļāļļāļĐāļĒāđ',
+ 'āļĢāļąāļāļāļīāļāļāļāļāđāļāļ end-to-end: āļŠāļāļēāļāļąāļāļĒāļāļĢāļĢāļĄ āļāļēāļĢāļāļąāļāļāļē āđāļĨāļ°āļāļēāļĢāļāđāļāļĒāļāļāļāļĒāļđāđāļ āļēāļĒāđāļāđāļāļĩāļĄāđāļāļĩāļĒāļ§',
+ ] as const,
+ },
+ cloudflareBadge: {
+ ...stackIt.cloudflareBadge,
+ label: 'āļĢāļ°āļāļāļāļīāđāļ§āļĻ Cloudflare',
+ slogan: '"āļāđāļ§āļĒāļāļąāļāļŠāļĢāđāļēāļāļāļīāļāđāļāļāļĢāđāđāļāđāļāļāļĩāđāļāļĩāļāļ§āđāļē"',
+ },
+ awsBadge: {
+ ...stackIt.awsBadge,
+ label: 'āļĢāļ°āļāļāļāļīāđāļ§āļĻ AWS',
+ slogan: '"āđāļāļĨāļāļāļāļĢāđāļĄāļāļĨāļēāļ§āļāđāļāļĩāđāļāļĢāļāļāļāļĨāļļāļĄāđāļĨāļ°āđāļāđāļĢāļąāļāļāļēāļĢāđāļāđāļāļēāļāļāļĒāđāļēāļāļāļ§āđāļēāļāļāļ§āļēāļāļāļĩāđāļŠāļļāļāđāļāđāļĨāļ"',
+ },
+ infrastructureCarousel: {
+ ...stackIt.infrastructureCarousel,
+ ariaLabel: 'āļāļēāļĢāđāļāđāļāļāļĢāđāđāļāļĢāļāļŠāļĢāđāļēāļāļāļ·āđāļāļāļēāļāđāļĨāļ°āđāļāļāđāļāđāļĨāļĒāļĩāļāļāļ NexStudio',
+ items: [
+ {
+ ...stackIt.infrastructureCarousel.items[0],
+ label: 'āļĢāļ°āļāļāļāļīāđāļ§āļĻ Cloudflare',
+ slogan: '"āļāđāļ§āļĒāļāļąāļāļŠāļĢāđāļēāļāļāļīāļāđāļāļāļĢāđāđāļāđāļāļāļĩāđāļāļĩāļāļ§āđāļē"',
+ },
+ {
+ ...stackIt.infrastructureCarousel.items[1],
+ label: 'āļĢāļ°āļāļāļāļīāđāļ§āļĻ AWS',
+ slogan: '"āđāļāļĨāļāļāļāļĢāđāļĄāļāļĨāļēāļ§āļāđāļāļĩāđāļāļĢāļāļāļāļĨāļļāļĄāđāļĨāļ°āđāļāđāļĢāļąāļāļāļēāļĢāđāļāđāļāļēāļāļāļĒāđāļēāļāļāļ§āđāļēāļāļāļ§āļēāļāļāļĩāđāļŠāļļāļāđāļāđāļĨāļ"',
+ },
+ {
+ ...stackIt.infrastructureCarousel.items[2],
+ label: 'āļĢāļ°āļāļāļāļīāđāļ§āļĻ GitHub',
+ },
+ {
+ ...stackIt.infrastructureCarousel.items[3],
+ label: 'āļĢāļ°āļāļāļāļīāđāļ§āļĻ OpenAI',
+ },
+ ] as const,
+ },
+ },
+} as const;
+
+export const getStackSection = (locale: SupportedLocale) => stackByLocale[locale];
+
+/** Retro-compatibilità : fallback italiano. */
+export const stackSection = stackByLocale.it;
diff --git a/src/layouts/SubpageLayout.astro b/src/layouts/SubpageLayout.astro
index ff4f9cf..3156d34 100644
--- a/src/layouts/SubpageLayout.astro
+++ b/src/layouts/SubpageLayout.astro
@@ -1,6 +1,7 @@
---
import BaseLayout from './BaseLayout.astro';
import SiteFooter from '../components/SiteFooter.astro';
+import { getNavigation } from '../data/home';
interface Props {
title: string;
@@ -29,7 +30,8 @@ const printDate = new Intl.DateTimeFormat('it-IT', {
const printSource = Astro.url.href;
const path = Astro.url.pathname;
const localeMatch = path.match(/^\/(en|th)(\/|$)/);
-const currentLocale = localeMatch?.[1] ?? 'it';
+const currentLocale = (localeMatch?.[1] ?? 'it') as 'it' | 'en' | 'th';
+const navigation = getNavigation(currentLocale);
const strippedPath = path.replace(/^\/(en|th)(?=\/|$)/, '') || '/';
const localeHref = (locale: 'it' | 'en' | 'th') => {
if (locale === 'it') return strippedPath;
@@ -71,7 +73,7 @@ const langMeta = {
{langMeta[currentLocale].code}
@@ -129,7 +131,7 @@ const langMeta = {
Contattaci {navigation.items[4]?.label ?? 'Contattaci'}
diff --git a/src/pages/index.astro b/src/pages/index.astro
index d83fa82..31603cc 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -6,21 +6,33 @@ import ContactFormInline from '../components/ContactFormInline.astro';
import CardBottomRightTexture from '../components/CardBottomRightTexture.astro';
import SiteFooter from '../components/SiteFooter.astro';
import {
- siteMeta,
- navigation,
- hero,
+ getSiteMeta,
+ getNavigation,
+ getHero,
stats,
- services,
- stackSection,
+ getServices,
+ getStackSection,
productsSection,
- faq,
- cta,
+ getFaq,
+ getCta,
} from '../data/home';
const infrastructureCarouselItems = stackSection.infrastructureCarousel.items;
const path = Astro.url.pathname;
const localeMatch = path.match(/^\/(en|th)(\/|$)/);
-const currentLocale = localeMatch?.[1] ?? 'it';
+const currentLocale = (localeMatch?.[1] ?? 'it') as 'it' | 'en' | 'th';
+const navigation = getNavigation(currentLocale);
+const siteMeta = getSiteMeta(currentLocale);
+const hero = getHero(currentLocale);
+const services = getServices(currentLocale);
+const stackSection = getStackSection(currentLocale);
+const faq = getFaq(currentLocale);
+const cta = getCta(currentLocale);
+const pageLabels = {
+ it: { focus: 'Focus' },
+ en: { focus: 'Focus' },
+ th: { focus: 'āļāļļāļāđāļāđāļ' },
+}[currentLocale];
const localize = (href: string) => {
if (currentLocale === 'it') return href;
if (href.startsWith(`/${currentLocale}`)) return href;
@@ -64,7 +76,7 @@ const langMeta = {
{navigation.items.map((item) => {
const sectionId = item.href.includes('#')
@@ -87,7 +99,7 @@ const langMeta = {
{langMeta[currentLocale].code}
@@ -157,7 +169,7 @@ const langMeta = {
@click="mobile = !mobile"
:aria-expanded="mobile"
aria-controls="mobile-nav"
- aria-label="Apri menu"
+ aria-label={navigation.labels.openMenuAria}
>
-
+
{navigation.items.map((item) => {
const sectionId = item.href.includes('#')
? item.href.split('#').pop()!
@@ -356,7 +368,7 @@ const langMeta = {
pi === 0 ? 'text-sky-200/85' : 'text-emerald-200/85',
]}
>
- Focus â
+ {pageLabels.focus} â
{product.focus}
@@ -497,7 +509,7 @@ const langMeta = {
class="relative z-[1] mt-12 rounded-2xl border border-orange-500/20 bg-gradient-to-br from-orange-950/20 to-nx-elevated/40 p-6 sm:p-8"
>
- Infrastruttura
+ {stackSection.infrastructureHeading}
Date: Mon, 27 Apr 2026 09:49:40 +0200
Subject: [PATCH 4/4] Corregge il rendering della home localizzata spostando
l'inizializzazione del carosello dopo stackSection.
Evita l'errore runtime su /en e /th che causava pagina vuota o UI rotta nel selettore lingua.
Made-with: Cursor
---
src/pages/index.astro | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 31603cc..2aabe3a 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -17,7 +17,6 @@ import {
getCta,
} from '../data/home';
-const infrastructureCarouselItems = stackSection.infrastructureCarousel.items;
const path = Astro.url.pathname;
const localeMatch = path.match(/^\/(en|th)(\/|$)/);
const currentLocale = (localeMatch?.[1] ?? 'it') as 'it' | 'en' | 'th';
@@ -28,6 +27,7 @@ const services = getServices(currentLocale);
const stackSection = getStackSection(currentLocale);
const faq = getFaq(currentLocale);
const cta = getCta(currentLocale);
+const infrastructureCarouselItems = stackSection.infrastructureCarousel.items;
const pageLabels = {
it: { focus: 'Focus' },
en: { focus: 'Focus' },