[DOCS+I18N] Guida aggiornata, i18n idle timeout, 3 documenti commerciali

- help.js: aggiornate sezioni per idle timeout, banner AI dismissible, matrice rischi real-time
- i18n.js: aggiunte 5 chiavi session.* per idle timeout (IT/EN)
- common.js: _showIdleWarning() usa I18n.t() per testi IT/EN
- docs/commercial/scheda-commerciale.html: scheda A4 stampabile (problema/soluzione, moduli, AI, target)
- docs/commercial/scheda-tecnica.html: specifiche stack, architettura, API, DB, sicurezza, deploy
- docs/commercial/presentazione.html: presentazione 10 slide completa (contesto, moduli, AI, compliance, ROI, roadmap)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
DevEnv nis2-agile 2026-02-20 12:43:17 +01:00
parent 59fad22c0e
commit 1bfca3fbe3
6 changed files with 2323 additions and 10 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,499 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NIS2 Agile — Scheda Commerciale</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', Arial, sans-serif;
background: #fff;
color: #1a1a2e;
font-size: 13px;
line-height: 1.5;
}
/* ── Layout A4 ── */
.page {
width: 210mm;
min-height: 297mm;
margin: 0 auto;
padding: 0;
background: #fff;
position: relative;
overflow: hidden;
}
/* ── Header ── */
.header {
background: linear-gradient(135deg, #1a73e8 0%, #0d47a1 60%, #1565c0 100%);
padding: 32px 40px 28px;
position: relative;
overflow: hidden;
}
.header::before {
content: '';
position: absolute;
right: -60px; top: -60px;
width: 200px; height: 200px;
border-radius: 50%;
background: rgba(255,255,255,0.06);
}
.header::after {
content: '';
position: absolute;
right: 40px; bottom: -40px;
width: 140px; height: 140px;
border-radius: 50%;
background: rgba(255,255,255,0.04);
}
.logo-row {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 20px;
}
.logo-icon {
width: 42px; height: 42px;
background: rgba(255,255,255,0.15);
border-radius: 10px;
display: flex; align-items: center; justify-content: center;
}
.logo-icon svg { width: 26px; height: 26px; fill: #fff; }
.logo-text h1 { font-size: 22px; font-weight: 800; color: #fff; letter-spacing: -0.5px; }
.logo-text span { font-size: 10px; color: rgba(255,255,255,0.7); letter-spacing: 1px; text-transform: uppercase; }
.tagline {
font-size: 19px;
font-weight: 700;
color: #fff;
line-height: 1.3;
max-width: 420px;
margin-bottom: 10px;
}
.sub-tagline {
font-size: 12px;
color: rgba(255,255,255,0.8);
max-width: 400px;
}
.badge-row {
display: flex;
gap: 8px;
margin-top: 16px;
flex-wrap: wrap;
}
.badge {
background: rgba(255,255,255,0.15);
color: #fff;
font-size: 10px;
font-weight: 700;
padding: 4px 10px;
border-radius: 20px;
border: 1px solid rgba(255,255,255,0.25);
letter-spacing: 0.3px;
}
/* ── Problema / Soluzione ── */
.problem-solution {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0;
border-bottom: 1px solid #e8edf3;
}
.problem {
background: #fef2f2;
padding: 20px 24px;
border-right: 1px solid #fecaca;
}
.solution {
background: #f0fdf4;
padding: 20px 24px;
}
.ps-label {
font-size: 9px;
font-weight: 800;
letter-spacing: 1.2px;
text-transform: uppercase;
margin-bottom: 8px;
}
.problem .ps-label { color: #dc2626; }
.solution .ps-label { color: #16a34a; }
.ps-title {
font-size: 13px;
font-weight: 700;
margin-bottom: 10px;
}
.problem .ps-title { color: #991b1b; }
.solution .ps-title { color: #14532d; }
.ps-list { list-style: none; padding: 0; }
.ps-list li {
font-size: 11.5px;
padding: 3px 0 3px 16px;
position: relative;
color: #374151;
}
.ps-list li::before {
content: '';
position: absolute;
left: 0; top: 9px;
width: 5px; height: 5px;
border-radius: 50%;
}
.problem .ps-list li::before { background: #dc2626; }
.solution .ps-list li::before { background: #16a34a; }
/* ── Funzionalità ── */
.features-section {
padding: 22px 40px;
}
.section-title {
font-size: 11px;
font-weight: 800;
letter-spacing: 1.2px;
text-transform: uppercase;
color: #1a73e8;
margin-bottom: 16px;
padding-bottom: 8px;
border-bottom: 2px solid #e8edf3;
}
.features-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 14px;
}
.feature-card {
background: #f8faff;
border: 1px solid #e0eaff;
border-radius: 8px;
padding: 14px;
}
.feature-icon {
width: 32px; height: 32px;
background: #1a73e8;
border-radius: 7px;
display: flex; align-items: center; justify-content: center;
margin-bottom: 8px;
}
.feature-icon svg { width: 17px; height: 17px; fill: #fff; }
.feature-name {
font-size: 11px;
font-weight: 700;
color: #0d47a1;
margin-bottom: 4px;
}
.feature-desc {
font-size: 10.5px;
color: #4b5563;
line-height: 1.5;
}
.feature-tag {
display: inline-block;
background: #dbeafe;
color: #1d4ed8;
font-size: 9px;
font-weight: 700;
padding: 2px 7px;
border-radius: 10px;
margin-top: 6px;
text-transform: uppercase;
letter-spacing: 0.3px;
}
/* ── Target ── */
.target-section {
background: #f8faff;
border-top: 1px solid #e0eaff;
padding: 18px 40px;
}
.target-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
margin-top: 12px;
}
.target-card {
background: #fff;
border: 1px solid #e0eaff;
border-radius: 8px;
padding: 12px 14px;
display: flex;
gap: 10px;
align-items: flex-start;
}
.target-num {
width: 26px; height: 26px;
background: linear-gradient(135deg, #1a73e8, #0d47a1);
color: #fff;
border-radius: 6px;
display: flex; align-items: center; justify-content: center;
font-size: 12px;
font-weight: 800;
flex-shrink: 0;
}
.target-name { font-size: 11px; font-weight: 700; color: #1a1a2e; margin-bottom: 2px; }
.target-desc { font-size: 10px; color: #6b7280; }
/* ── AI Section ── */
.ai-section {
border-top: 1px solid #e8edf3;
padding: 18px 40px;
background: linear-gradient(135deg, #fdf4ff 0%, #f0f9ff 100%);
display: flex;
gap: 20px;
align-items: center;
}
.ai-icon-wrap {
width: 52px; height: 52px;
background: linear-gradient(135deg, #7c3aed, #2563eb);
border-radius: 12px;
display: flex; align-items: center; justify-content: center;
flex-shrink: 0;
}
.ai-icon-wrap svg { width: 28px; height: 28px; fill: #fff; }
.ai-title { font-size: 14px; font-weight: 800; color: #4c1d95; margin-bottom: 4px; }
.ai-desc { font-size: 11px; color: #5b21b6; line-height: 1.5; }
.ai-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.ai-chip {
background: rgba(124,58,237,0.1);
color: #6d28d9;
font-size: 9.5px;
font-weight: 600;
padding: 3px 8px;
border-radius: 10px;
border: 1px solid rgba(124,58,237,0.2);
}
/* ── Stats ── */
.stats-bar {
background: #0d47a1;
padding: 14px 40px;
display: flex;
justify-content: space-around;
align-items: center;
}
.stat-item { text-align: center; }
.stat-num { font-size: 20px; font-weight: 800; color: #fff; }
.stat-label { font-size: 9px; color: rgba(255,255,255,0.7); text-transform: uppercase; letter-spacing: 0.5px; }
.stat-sep { width: 1px; height: 32px; background: rgba(255,255,255,0.2); }
/* ── Footer ── */
.footer {
border-top: 1px solid #e8edf3;
padding: 14px 40px;
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
}
.footer-brand { font-size: 12px; font-weight: 800; color: #1a73e8; }
.footer-url { font-size: 11px; color: #6b7280; }
.footer-compliance {
font-size: 9px;
color: #9ca3af;
text-align: right;
line-height: 1.4;
}
@media print {
body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.page { width: 100%; margin: 0; }
}
</style>
</head>
<body>
<div class="page">
<!-- HEADER -->
<div class="header">
<div class="logo-row">
<div class="logo-icon">
<svg viewBox="0 0 24 24"><path d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm0 2.18l7 3.12v4.7c0 4.83-3.23 9.36-7 10.57C8.23 20.36 5 15.83 5 11V6.3l7-3.12zM10 12.5l-2-2-1.41 1.41L10 15.32l5.41-5.41L14 8.5l-4 4z"/></svg>
</div>
<div class="logo-text">
<h1>NIS2 Agile</h1>
<span>Compliance Platform</span>
</div>
</div>
<div class="tagline">La piattaforma SaaS che rende semplice la conformità alla Direttiva NIS2</div>
<div class="sub-tagline">Gestione integrata di rischi, incidenti, policy e audit — con AI integrata — per soggetti essenziali e importanti ai sensi del D.Lgs. 138/2024</div>
<div class="badge-row">
<span class="badge">D.Lgs. 138/2024</span>
<span class="badge">Direttiva UE 2022/2555</span>
<span class="badge">AI Powered</span>
<span class="badge">Multi-Tenant SaaS</span>
<span class="badge">ISO 27001 Aligned</span>
</div>
</div>
<!-- PROBLEMA / SOLUZIONE -->
<div class="problem-solution">
<div class="problem">
<div class="ps-label">Il Problema</div>
<div class="ps-title">La NIS2 è obbligatoria. La compliance è complessa.</div>
<ul class="ps-list">
<li>Sanzioni fino a €10M o 2% fatturato globale</li>
<li>Responsabilità personale dei dirigenti</li>
<li>Obblighi stringenti su notifiche, rischi, policy, formazione</li>
<li>Processi dispersi tra Excel, email e documenti non strutturati</li>
<li>Assenza di visibilità real-time sul livello di compliance</li>
</ul>
</div>
<div class="solution">
<div class="ps-label">La Soluzione</div>
<div class="ps-title">NIS2 Agile centralizza e automatizza tutto.</div>
<ul class="ps-list">
<li>Gap analysis automatica sui 10 requisiti Art. 21</li>
<li>Gestione incidenti con timeline Art. 23 (24h/72h/30gg)</li>
<li>Risk register con matrice ISO 27005</li>
<li>Policy generate dall'AI e approvabili con un clic</li>
<li>Dashboard di compliance con score aggiornato in real-time</li>
</ul>
</div>
</div>
<!-- FUNZIONALITÀ CHIAVE -->
<div class="features-section">
<div class="section-title">Moduli Inclusi</div>
<div class="features-grid">
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 20 20"><path d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z"/><path fill-rule="evenodd" d="M4 5a2 2 0 012-2 3 3 0 003 3h2a3 3 0 003-3 2 2 0 012 2v11a2 2 0 01-2 2H6a2 2 0 01-2-2V5zm9.707 5.707a1 1 0 00-1.414-1.414L9 12.586l-1.293-1.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/></svg>
</div>
<div class="feature-name">Gap Analysis NIS2</div>
<div class="feature-desc">Wizard di assessment con 80 domande sui 10 requisiti Art. 21. Punteggio automatico e report di priorità.</div>
<span class="feature-tag">Art. 21</span>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 20 20"><path fill-rule="evenodd" d="M10 1.944A11.954 11.954 0 012.166 5C2.056 5.649 2 6.319 2 7c0 5.225 3.34 9.67 8 11.317C14.66 16.67 18 12.225 18 7c0-.682-.057-1.35-.166-2.001A11.954 11.954 0 0110 1.944zM11 14a1 1 0 11-2 0 1 1 0 012 0zm0-7a1 1 0 10-2 0v3a1 1 0 102 0V7z" clip-rule="evenodd"/></svg>
</div>
<div class="feature-name">Gestione Rischi</div>
<div class="feature-desc">Risk register completo con matrice 5×5, trattamenti e ownership. Conforme ISO 27005.</div>
<span class="feature-tag">ISO 27005</span>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 20 20"><path d="M10 2a6 6 0 00-6 6v3.586l-.707.707A1 1 0 004 14h12a1 1 0 00.707-1.707L16 11.586V8a6 6 0 00-6-6zM10 18a3 3 0 01-3-3h6a3 3 0 01-3 3z"/></svg>
</div>
<div class="feature-name">Gestione Incidenti</div>
<div class="feature-desc">Timeline automatica 24h/72h/30gg con notifiche CSIRT. Decision tree per incidenti significativi.</div>
<span class="feature-tag">Art. 23</span>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 20 20"><path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4zm2 6a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1zm1 3a1 1 0 100 2h6a1 1 0 100-2H7z" clip-rule="evenodd"/></svg>
</div>
<div class="feature-name">Policy Management</div>
<div class="feature-desc">Ciclo di vita completo con approvazione. Template per tutte le categorie NIS2.</div>
<span class="feature-tag">Art. 21</span>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 20 20"><path fill-rule="evenodd" d="M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5zm-5 5a2 2 0 012.828 0 1 1 0 101.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5a2 2 0 11-2.828-2.828l3-3z" clip-rule="evenodd"/></svg>
</div>
<div class="feature-name">Supply Chain Security</div>
<div class="feature-desc">Valutazione fornitori critici con scoring automatico e monitoraggio scadenze contrattuali.</div>
<span class="feature-tag">Art. 21(d)</span>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg viewBox="0 0 20 20"><path d="M2 11a1 1 0 011-1h2a1 1 0 011 1v5a1 1 0 01-1 1H3a1 1 0 01-1-1v-5zm6-4a1 1 0 011-1h2a1 1 0 011 1v9a1 1 0 01-1 1H9a1 1 0 01-1-1V7zm6-3a1 1 0 011-1h2a1 1 0 011 1v12a1 1 0 01-1 1h-2a1 1 0 01-1-1V4z"/></svg>
</div>
<div class="feature-name">Audit & Report</div>
<div class="feature-desc">Audit log immutabile, evidenze allegabili, report esecutivo e export CSV multi-modulo.</div>
<span class="feature-tag">Art. 32-33</span>
</div>
</div>
</div>
<!-- AI SECTION -->
<div class="ai-section">
<div class="ai-icon-wrap">
<svg viewBox="0 0 20 20"><path d="M5 2a1 1 0 011 1v1h1a1 1 0 010 2H6v1a1 1 0 01-2 0V6H3a1 1 0 010-2h1V3a1 1 0 011-1zm0 10a1 1 0 011 1v1h1a1 1 0 110 2H6v1a1 1 0 11-2 0v-1H3a1 1 0 110-2h1v-1a1 1 0 011-1zm7-10a1 1 0 01.967.744L14.146 7.2 17.5 8.512a1 1 0 010 1.836l-3.354 1.311-1.18 4.456a1 1 0 01-1.932 0L9.854 11.66 6.5 10.348a1 1 0 010-1.836l3.354-1.311 1.18-4.456A1 1 0 0112 2z"/></svg>
</div>
<div>
<div class="ai-title">AI Integrata con Claude (Anthropic)</div>
<div class="ai-desc">NIS2 Agile integra l'AI generativa per ridurre drasticamente il tempo dedicato alla compliance. L'AI analizza i gap, suggerisce rischi specifici per settore, genera policy complete e classifica automaticamente la gravità degli incidenti.</div>
<div class="ai-chips">
<span class="ai-chip">Gap Analysis AI</span>
<span class="ai-chip">Risk Suggest AI</span>
<span class="ai-chip">Policy Generate AI</span>
<span class="ai-chip">Incident Classify AI</span>
<span class="ai-chip">Dati anonimizzati</span>
</div>
</div>
</div>
<!-- STATS BAR -->
<div class="stats-bar">
<div class="stat-item">
<div class="stat-num">15</div>
<div class="stat-label">Moduli Integrati</div>
</div>
<div class="stat-sep"></div>
<div class="stat-item">
<div class="stat-num">80</div>
<div class="stat-label">Domande Assessment</div>
</div>
<div class="stat-sep"></div>
<div class="stat-item">
<div class="stat-num">22</div>
<div class="stat-label">Tabelle DB / 7 Ruoli</div>
</div>
<div class="stat-sep"></div>
<div class="stat-item">
<div class="stat-num">100%</div>
<div class="stat-label">Art. 21 Copertura</div>
</div>
<div class="stat-sep"></div>
<div class="stat-item">
<div class="stat-num">SaaS</div>
<div class="stat-label">Multi-Tenant</div>
</div>
</div>
<!-- TARGET -->
<div class="target-section">
<div class="section-title">A chi è destinato</div>
<div class="target-grid">
<div class="target-card">
<div class="target-num">1</div>
<div>
<div class="target-name">PMI — Soggetti Importanti</div>
<div class="target-desc">Medie imprese nei settori Allegato I e II che necessitano di compliance NIS2 strutturata senza un team IT dedicato.</div>
</div>
</div>
<div class="target-card">
<div class="target-num">2</div>
<div>
<div class="target-name">Enterprise — Soggetti Essenziali</div>
<div class="target-desc">Grandi organizzazioni in settori critici (energia, trasporti, sanità, finanza, ICT) soggette a vigilanza proattiva AGID/ACN.</div>
</div>
</div>
<div class="target-card">
<div class="target-num">3</div>
<div>
<div class="target-name">Consulenti & CISO</div>
<div class="target-desc">Consulenti di sicurezza e CISO che gestiscono la compliance NIS2 per conto di più organizzazioni clienti da un'unica piattaforma.</div>
</div>
</div>
</div>
</div>
<!-- FOOTER -->
<div class="footer">
<div>
<div class="footer-brand">NIS2 Agile</div>
<div class="footer-url">nis2.certisource.it</div>
</div>
<div class="footer-compliance">
Conforme a D.Lgs. 138/2024 (recepimento Direttiva UE 2022/2555)<br>
Allineato ISO 27001 · GDPR · ACN Framework
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,660 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NIS2 Agile — Scheda Tecnica</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', Arial, sans-serif;
background: #f8faff;
color: #1a1a2e;
font-size: 12.5px;
line-height: 1.6;
}
.page {
width: 210mm;
margin: 0 auto;
background: #fff;
}
/* ── Header ── */
.header {
background: #0d2137;
padding: 24px 36px 20px;
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.header-left h1 { font-size: 18px; font-weight: 800; color: #fff; margin-bottom: 4px; }
.header-left p { font-size: 10px; color: #7ea8c4; text-transform: uppercase; letter-spacing: 1px; }
.header-right {
text-align: right;
}
.version-badge {
display: inline-block;
background: #1a73e8;
color: #fff;
font-size: 9px;
font-weight: 700;
padding: 4px 10px;
border-radius: 4px;
margin-bottom: 4px;
}
.header-right p { font-size: 9px; color: #7ea8c4; }
/* ── Content ── */
.content { padding: 0 36px 24px; }
/* ── Section ── */
.section { margin-top: 22px; }
.section-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
padding-bottom: 6px;
border-bottom: 2px solid #e0eaff;
}
.section-num {
width: 22px; height: 22px;
background: #1a73e8;
color: #fff;
border-radius: 5px;
display: flex; align-items: center; justify-content: center;
font-size: 11px;
font-weight: 800;
flex-shrink: 0;
}
.section-title {
font-size: 12px;
font-weight: 800;
color: #0d2137;
text-transform: uppercase;
letter-spacing: 0.8px;
}
/* ── Stack grid ── */
.stack-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
.stack-item {
background: #f8faff;
border: 1px solid #e0eaff;
border-radius: 6px;
padding: 10px 14px;
display: flex;
gap: 10px;
align-items: flex-start;
}
.stack-label {
font-size: 9px;
font-weight: 800;
color: #1a73e8;
text-transform: uppercase;
letter-spacing: 0.5px;
min-width: 80px;
flex-shrink: 0;
padding-top: 1px;
}
.stack-value {
font-size: 11px;
color: #374151;
line-height: 1.5;
}
.stack-value strong { color: #0d2137; font-weight: 700; }
/* ── Architettura ── */
.arch-diagram {
background: #f8faff;
border: 1px solid #e0eaff;
border-radius: 8px;
padding: 16px;
font-size: 11px;
}
.arch-layers {
display: flex;
flex-direction: column;
gap: 8px;
}
.arch-layer {
display: flex;
gap: 8px;
align-items: center;
}
.arch-layer-label {
font-size: 8.5px;
font-weight: 800;
color: #6b7280;
text-transform: uppercase;
letter-spacing: 0.5px;
min-width: 68px;
text-align: right;
}
.arch-layer-boxes {
display: flex;
gap: 6px;
flex-wrap: wrap;
}
.arch-box {
background: #1a73e8;
color: #fff;
font-size: 9.5px;
font-weight: 600;
padding: 4px 10px;
border-radius: 4px;
white-space: nowrap;
}
.arch-box.alt { background: #0d47a1; }
.arch-box.gray { background: #4b5563; }
.arch-box.green { background: #059669; }
.arch-box.purple { background: #7c3aed; }
.arch-arrow {
font-size: 16px;
color: #9ca3af;
text-align: center;
padding-left: 68px;
margin: -4px 0;
}
/* ── API table ── */
.api-table {
width: 100%;
border-collapse: collapse;
font-size: 10.5px;
}
.api-table th {
background: #0d2137;
color: #fff;
padding: 6px 10px;
font-size: 9px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
text-align: left;
}
.api-table td {
padding: 5px 10px;
border-bottom: 1px solid #e8edf3;
vertical-align: top;
}
.api-table tr:nth-child(even) td { background: #f8faff; }
.method {
display: inline-block;
font-size: 8.5px;
font-weight: 700;
padding: 1px 5px;
border-radius: 3px;
color: #fff;
}
.get { background: #059669; }
.post { background: #1a73e8; }
.put { background: #d97706; }
.del { background: #dc2626; }
/* ── DB table ── */
.db-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 6px;
}
.db-table-item {
background: #f8faff;
border: 1px solid #e0eaff;
border-radius: 5px;
padding: 7px 10px;
font-size: 10px;
}
.db-table-name { font-weight: 700; color: #0d2137; margin-bottom: 2px; }
.db-table-desc { font-size: 9px; color: #6b7280; }
/* ── Security ── */
.security-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
.sec-item {
background: #f0fdf4;
border: 1px solid #bbf7d0;
border-radius: 6px;
padding: 10px 12px;
}
.sec-item.warn { background: #fff7ed; border-color: #fed7aa; }
.sec-icon { font-size: 15px; margin-bottom: 4px; }
.sec-name { font-size: 10.5px; font-weight: 700; color: #14532d; margin-bottom: 3px; }
.sec-item.warn .sec-name { color: #92400e; }
.sec-desc { font-size: 9.5px; color: #166534; line-height: 1.5; }
.sec-item.warn .sec-desc { color: #78350f; }
/* ── Performance ── */
.perf-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.perf-item {
background: #f8faff;
border: 1px solid #e0eaff;
border-radius: 6px;
padding: 10px;
text-align: center;
}
.perf-num { font-size: 18px; font-weight: 800; color: #1a73e8; }
.perf-unit { font-size: 9px; color: #6b7280; }
.perf-label { font-size: 9px; color: #4b5563; margin-top: 3px; }
/* ── Deploy ── */
.deploy-options {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
}
.deploy-card {
border: 1px solid #e0eaff;
border-radius: 6px;
padding: 12px;
}
.deploy-type {
font-size: 10px;
font-weight: 800;
color: #0d47a1;
margin-bottom: 6px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.deploy-specs { list-style: none; }
.deploy-specs li {
font-size: 9.5px;
color: #4b5563;
padding: 1px 0 1px 12px;
position: relative;
}
.deploy-specs li::before {
content: '✓';
position: absolute;
left: 0;
color: #1a73e8;
font-size: 8px;
top: 2px;
}
/* ── Compliance map ── */
.compliance-map {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
}
.cm-item {
display: flex;
gap: 8px;
align-items: center;
background: #f8faff;
border: 1px solid #e0eaff;
border-radius: 5px;
padding: 7px 10px;
}
.cm-art {
font-size: 9px;
font-weight: 800;
color: #fff;
background: #1a73e8;
padding: 2px 6px;
border-radius: 4px;
white-space: nowrap;
}
.cm-desc { font-size: 10px; color: #374151; }
/* ── Footer ── */
.footer {
background: #0d2137;
padding: 12px 36px;
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 20px;
}
.footer-left { font-size: 10px; color: #7ea8c4; }
.footer-left strong { color: #fff; font-size: 12px; }
.footer-right { font-size: 9px; color: #7ea8c4; text-align: right; }
@media print {
body { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.page { width: 100%; margin: 0; }
}
</style>
</head>
<body>
<div class="page">
<!-- HEADER -->
<div class="header">
<div class="header-left">
<h1>NIS2 Agile — Scheda Tecnica</h1>
<p>Specifiche di architettura, stack tecnologico e integrazione</p>
</div>
<div class="header-right">
<div class="version-badge">v1.0 — Febbraio 2026</div>
<p>nis2.certisource.it</p>
</div>
</div>
<div class="content">
<!-- 1. STACK TECNOLOGICO -->
<div class="section">
<div class="section-header">
<div class="section-num">1</div>
<div class="section-title">Stack Tecnologico</div>
</div>
<div class="stack-grid">
<div class="stack-item">
<div class="stack-label">Backend</div>
<div class="stack-value"><strong>PHP 8.4</strong> — vanilla, Front Controller pattern, zero dipendenze framework. Router personalizzato con pattern matching per URI gerarchici.</div>
</div>
<div class="stack-item">
<div class="stack-label">Database</div>
<div class="stack-value"><strong>MySQL 8.0</strong> — 22 tabelle, indici ottimizzati, soft delete, trigger immutabili su audit_log. PDO con prepared statements.</div>
</div>
<div class="stack-item">
<div class="stack-label">Frontend</div>
<div class="stack-value"><strong>HTML5 / CSS3 / JavaScript</strong> — vanilla, nessun framework JS. 17 pagine HTML + 3 admin. CSS custom ~1.600 righe. i18n IT/EN integrato.</div>
</div>
<div class="stack-item">
<div class="stack-label">Autenticazione</div>
<div class="stack-value"><strong>JWT HS256</strong> — access token 2h, refresh token 7d. Refresh atomico con SELECT FOR UPDATE. Idle timeout 30min con avviso.</div>
</div>
<div class="stack-item">
<div class="stack-label">AI Integration</div>
<div class="stack-value"><strong>Anthropic Claude</strong> — modello <em>claude-sonnet-4-5</em>. Prompt anonimizzati (no ragione sociale, no fatturato). 4 funzionalità AI.</div>
</div>
<div class="stack-item">
<div class="stack-label">Infrastruttura</div>
<div class="stack-value"><strong>Hetzner CPX31</strong> — Ubuntu, Apache 2.4, subdomain dedicato. Docker-ready (Dockerfile + nginx.conf inclusi).</div>
</div>
</div>
</div>
<!-- 2. ARCHITETTURA -->
<div class="section">
<div class="section-header">
<div class="section-num">2</div>
<div class="section-title">Architettura Sistema</div>
</div>
<div class="arch-diagram">
<div class="arch-layers">
<div class="arch-layer">
<div class="arch-layer-label">Browser</div>
<div class="arch-layer-boxes">
<span class="arch-box">HTML5 Pages</span>
<span class="arch-box alt">api.js Client</span>
<span class="arch-box alt">i18n.js IT/EN</span>
<span class="arch-box alt">common.js Utils</span>
<span class="arch-box alt">help.js</span>
</div>
</div>
<div class="arch-arrow">↓ HTTPS / JWT Bearer</div>
<div class="arch-layer">
<div class="arch-layer-label">Router</div>
<div class="arch-layer-boxes">
<span class="arch-box green">public/index.php — Front Controller</span>
<span class="arch-box gray">.htaccess Rewrite</span>
</div>
</div>
<div class="arch-arrow">↓ /api/{controller}/{action}/{id?}</div>
<div class="arch-layer">
<div class="arch-layer-label">Controllers</div>
<div class="arch-layer-boxes">
<span class="arch-box">Auth</span>
<span class="arch-box">Assessment</span>
<span class="arch-box">Risk</span>
<span class="arch-box">Incident</span>
<span class="arch-box">Policy</span>
<span class="arch-box">SupplyChain</span>
<span class="arch-box">Audit</span>
<span class="arch-box alt">+ 8 altri</span>
</div>
</div>
<div class="arch-arrow">↓ PDO / Services</div>
<div class="arch-layer">
<div class="arch-layer-label">Services</div>
<div class="arch-layer-boxes">
<span class="arch-box purple">AIService (Claude)</span>
<span class="arch-box gray">EmailService</span>
<span class="arch-box gray">ReportService</span>
<span class="arch-box gray">RateLimitService</span>
<span class="arch-box gray">VisuraService</span>
</div>
</div>
<div class="arch-arrow">↓ PDO Singleton</div>
<div class="arch-layer">
<div class="arch-layer-label">Database</div>
<div class="arch-layer-boxes">
<span class="arch-box green">MySQL 8.0 — nis2_agile_db — 22 tabelle</span>
</div>
</div>
</div>
</div>
</div>
<!-- 3. API ENDPOINTS -->
<div class="section">
<div class="section-header">
<div class="section-num">3</div>
<div class="section-title">API REST — Endpoint Principali</div>
</div>
<p style="font-size:10px;color:#6b7280;margin-bottom:8px;">Base URL: <code style="background:#f8faff;padding:1px 5px;border-radius:3px;font-size:10px;">https://nis2.certisource.it/api/{controller}/{action}/{id?}</code> — Auth: Bearer JWT + X-Organization-Id header</p>
<table class="api-table">
<thead>
<tr>
<th style="width:16%">Modulo</th>
<th style="width:12%">Metodo</th>
<th style="width:35%">Endpoint</th>
<th>Descrizione</th>
</tr>
</thead>
<tbody>
<tr><td>Auth</td><td><span class="method post">POST</span></td><td>/auth/login, /register, /refresh</td><td>Login, registrazione, rinnovo token JWT</td></tr>
<tr><td>Auth</td><td><span class="method get">GET</span></td><td>/auth/me</td><td>Dati utente autenticato e organizzazioni</td></tr>
<tr><td>Organizations</td><td><span class="method post">POST</span></td><td>/organizations/create, /classify</td><td>Crea org, classifica soggetto NIS2</td></tr>
<tr><td>Assessment</td><td><span class="method get">GET</span></td><td>/assessments/{id}/questions</td><td>80 domande gap analysis (10 categorie Art.21)</td></tr>
<tr><td>Assessment</td><td><span class="method post">POST</span></td><td>/assessments/{id}/ai-analyze</td><td>Analisi AI dei gap con raccomandazioni</td></tr>
<tr><td>Risks</td><td><span class="method get">GET</span></td><td>/risks/matrix</td><td>Matrice rischi 5×5 aggregata</td></tr>
<tr><td>Risks</td><td><span class="method post">POST</span></td><td>/risks/ai-suggest</td><td>Suggerimenti rischi AI per settore/asset</td></tr>
<tr><td>Incidents</td><td><span class="method post">POST</span></td><td>/incidents/{id}/early-warning</td><td>Early warning CSIRT entro 24h (Art.23)</td></tr>
<tr><td>Incidents</td><td><span class="method post">POST</span></td><td>/incidents/{id}/final-report</td><td>Report finale CSIRT entro 30gg (Art.23)</td></tr>
<tr><td>Policies</td><td><span class="method post">POST</span></td><td>/policies/ai-generate</td><td>Genera policy NIS2 con AI (per categoria)</td></tr>
<tr><td>Audit</td><td><span class="method get">GET</span></td><td>/audit/executive-report</td><td>Report esecutivo HTML stampabile</td></tr>
<tr><td>Audit</td><td><span class="method get">GET</span></td><td>/audit/export?type=risks</td><td>Export CSV (rischi/incidenti/controlli/asset)</td></tr>
<tr><td>NCR/CAPA</td><td><span class="method post">POST</span></td><td>/ncr/from-assessment</td><td>Genera NCR automatiche dai gap assessment</td></tr>
<tr><td>Onboarding</td><td><span class="method post">POST</span></td><td>/onboarding/upload-visura</td><td>Estrazione AI da PDF visura camerale</td></tr>
</tbody>
</table>
</div>
<!-- 4. DATABASE -->
<div class="section">
<div class="section-header">
<div class="section-num">4</div>
<div class="section-title">Schema Database — 22 Tabelle</div>
</div>
<div class="db-grid">
<div class="db-table-item"><div class="db-table-name">organizations</div><div class="db-table-desc">Tenant principale + classificazione NIS2</div></div>
<div class="db-table-item"><div class="db-table-name">users</div><div class="db-table-desc">Utenti (7 ruoli, multi-org)</div></div>
<div class="db-table-item"><div class="db-table-name">user_organizations</div><div class="db-table-desc">Mapping utente↔org + ruolo</div></div>
<div class="db-table-item"><div class="db-table-name">refresh_tokens</div><div class="db-table-desc">Token refresh JWT indicizzati</div></div>
<div class="db-table-item"><div class="db-table-name">assessments</div><div class="db-table-desc">Sessioni gap analysis</div></div>
<div class="db-table-item"><div class="db-table-name">assessment_responses</div><div class="db-table-desc">Risposte singole domande</div></div>
<div class="db-table-item"><div class="db-table-name">risks</div><div class="db-table-desc">Register rischi (soft delete)</div></div>
<div class="db-table-item"><div class="db-table-name">risk_treatments</div><div class="db-table-desc">Piani di trattamento</div></div>
<div class="db-table-item"><div class="db-table-name">incidents</div><div class="db-table-desc">Incidenti + flag significativo</div></div>
<div class="db-table-item"><div class="db-table-name">incident_timeline</div><div class="db-table-desc">Aggiornamenti e notifiche</div></div>
<div class="db-table-item"><div class="db-table-name">policies</div><div class="db-table-desc">Policy (soft delete, versioning)</div></div>
<div class="db-table-item"><div class="db-table-name">suppliers</div><div class="db-table-desc">Fornitori catena approvv.</div></div>
<div class="db-table-item"><div class="db-table-name">training_courses</div><div class="db-table-desc">Catalogo corsi formazione</div></div>
<div class="db-table-item"><div class="db-table-name">training_assignments</div><div class="db-table-desc">Assegnazioni e completamenti</div></div>
<div class="db-table-item"><div class="db-table-name">assets</div><div class="db-table-desc">Inventario ICT (4 tipi)</div></div>
<div class="db-table-item"><div class="db-table-name">compliance_controls</div><div class="db-table-desc">Controlli NIS2 per org</div></div>
<div class="db-table-item"><div class="db-table-name">evidence_files</div><div class="db-table-desc">Allegati e documenti audit</div></div>
<div class="db-table-item"><div class="db-table-name">audit_logs</div><div class="db-table-desc">Log immutabili (trigger MySQL)</div></div>
<div class="db-table-item"><div class="db-table-name">ai_interactions</div><div class="db-table-desc">Storico chiamate API AI</div></div>
<div class="db-table-item"><div class="db-table-name">email_log</div><div class="db-table-desc">Log notifiche email CSIRT</div></div>
<div class="db-table-item"><div class="db-table-name">non_conformities</div><div class="db-table-desc">NCR — Non Conformity Reports</div></div>
<div class="db-table-item"><div class="db-table-name">corrective_actions</div><div class="db-table-desc">CAPA — Azioni correttive</div></div>
</div>
</div>
<!-- 5. SICUREZZA -->
<div class="section">
<div class="section-header">
<div class="section-num">5</div>
<div class="section-title">Sicurezza Applicativa</div>
</div>
<div class="security-grid">
<div class="sec-item">
<div class="sec-name">JWT + Refresh Token Atomico</div>
<div class="sec-desc">Access token 2h, refresh 7d. Rinnovo con SELECT FOR UPDATE (no race conditions). Revoca token al logout.</div>
</div>
<div class="sec-item">
<div class="sec-name">CORS Configurato</div>
<div class="sec-desc">No wildcard. Origin verificata contro lista bianca configurabile. Header personalizzati sicuri.</div>
</div>
<div class="sec-item">
<div class="sec-name">Rate Limiting</div>
<div class="sec-desc">File-based per IP (proxy-aware, X-Forwarded-For). Login: 5/min, 20/h. Register: 3/10min. AI: 10/min.</div>
</div>
<div class="sec-item">
<div class="sec-name">SQL Injection Prevention</div>
<div class="sec-desc">PDO esclusivo con prepared statements. Nessuna concatenazione di query. Input validato lato server.</div>
</div>
<div class="sec-item">
<div class="sec-name">XSS Prevention</div>
<div class="sec-desc">escapeHtml() su ogni output frontend. Content-Security-Policy header configurato.</div>
</div>
<div class="sec-item">
<div class="sec-name">Audit Log Immutabile</div>
<div class="sec-desc">Trigger MySQL prevent_update + prevent_delete su audit_logs. Ogni operazione registrata con utente, azione e timestamp.</div>
</div>
<div class="sec-item">
<div class="sec-name">AI Data Privacy</div>
<div class="sec-desc">Prompt anonimizzati: ragione sociale e fatturato mai inviati ad Anthropic. Dipendenti convertiti in range (micro/piccola/media/grande).</div>
</div>
<div class="sec-item warn">
<div class="sec-name">Idle Session Timeout</div>
<div class="sec-desc">Logout automatico dopo 30 min di inattività. Avviso con countdown 5 min. Monitoraggio eventi mouse/keyboard/scroll.</div>
</div>
</div>
</div>
<!-- 6. PERFORMANCE -->
<div class="section">
<div class="section-header">
<div class="section-num">6</div>
<div class="section-title">Performance Target</div>
</div>
<div class="perf-grid">
<div class="perf-item">
<div class="perf-num">&lt;1s</div>
<div class="perf-unit">secondi</div>
<div class="perf-label">Caricamento Dashboard</div>
</div>
<div class="perf-item">
<div class="perf-num">&lt;2s</div>
<div class="perf-unit">secondi</div>
<div class="perf-label">Report Compliance</div>
</div>
<div class="perf-item">
<div class="perf-num">100+</div>
<div class="perf-unit">rischi</div>
<div class="perf-label">Matrice Fluida</div>
</div>
<div class="perf-item">
<div class="perf-num"></div>
<div class="perf-unit">tenant</div>
<div class="perf-label">Multi-Tenant Isolati</div>
</div>
</div>
</div>
<!-- 7. DEPLOY -->
<div class="section">
<div class="section-header">
<div class="section-num">7</div>
<div class="section-title">Opzioni di Deploy</div>
</div>
<div class="deploy-options">
<div class="deploy-card">
<div class="deploy-type">Cloud SaaS</div>
<ul class="deploy-specs">
<li>Hosting su nis2.certisource.it</li>
<li>Zero configurazione client</li>
<li>Aggiornamenti automatici</li>
<li>Backup giornaliero incluso</li>
<li>SSL/TLS incluso</li>
</ul>
</div>
<div class="deploy-card">
<div class="deploy-type">On-Premise / VPS</div>
<ul class="deploy-specs">
<li>PHP 8.4 + MySQL 8.0 + Apache/Nginx</li>
<li>Deploy via git pull + .env config</li>
<li>Supporto subdomain dedicato</li>
<li>Documentazione SQL migrations</li>
<li>Chiave SSH per accesso sicuro</li>
</ul>
</div>
<div class="deploy-card">
<div class="deploy-type">Docker / Container</div>
<ul class="deploy-specs">
<li>Dockerfile ottimizzato incluso</li>
<li>docker-compose.yml pronto</li>
<li>nginx.conf + php.ini configurati</li>
<li>Compatibile Kubernetes</li>
<li>Multi-stage build support</li>
</ul>
</div>
</div>
</div>
<!-- 8. COMPLIANCE MAP -->
<div class="section">
<div class="section-header">
<div class="section-num">8</div>
<div class="section-title">Copertura Normativa NIS2</div>
</div>
<div class="compliance-map">
<div class="cm-item"><span class="cm-art">Art. 20</span><div class="cm-desc">Governance — Formazione obbligatoria management, responsabilità organi</div></div>
<div class="cm-item"><span class="cm-art">Art. 21.1</span><div class="cm-desc">Risk-based approach — Risk register, matrice rischi, trattamenti</div></div>
<div class="cm-item"><span class="cm-art">Art. 21.2(a)</span><div class="cm-desc">Politiche sicurezza — Gap analysis 80 domande, policy management</div></div>
<div class="cm-item"><span class="cm-art">Art. 21.2(b)</span><div class="cm-desc">Gestione incidenti — Ciclo di vita, classificazione AI, timeline</div></div>
<div class="cm-item"><span class="cm-art">Art. 21.2(c)</span><div class="cm-desc">Business continuity — Asset inventory, dipendenze, backup</div></div>
<div class="cm-item"><span class="cm-art">Art. 21.2(d)</span><div class="cm-desc">Supply chain — Registro fornitori, valutazione rischio, scoring</div></div>
<div class="cm-item"><span class="cm-art">Art. 21.2(g)</span><div class="cm-desc">Formazione — Training management, compliance tracking, report</div></div>
<div class="cm-item"><span class="cm-art">Art. 23</span><div class="cm-desc">Notifica incidenti — Early warning 24h, notifica 72h, report 30gg</div></div>
<div class="cm-item"><span class="cm-art">Art. 32-33</span><div class="cm-desc">Vigilanza — Audit log immutabili, evidenze, controlli compliance</div></div>
<div class="cm-item"><span class="cm-art">D.Lgs. 138/2024</span><div class="cm-desc">Recepimento italiano NIS2 — Classificazione soggetti, settori</div></div>
</div>
</div>
</div><!-- /content -->
<!-- FOOTER -->
<div class="footer">
<div class="footer-left">
<strong>NIS2 Agile</strong><br>
Piattaforma SaaS compliance NIS2 per PMI e Enterprise
</div>
<div class="footer-right">
nis2.certisource.it<br>
Versione 1.0 · Febbraio 2026<br>
24.000+ righe di codice · 50+ file sorgente
</div>
</div>
</div>
</body>
</html>

View File

@ -510,25 +510,26 @@ function _showIdleWarning() {
'background:rgba(0,0,0,0.55)', 'display:flex', 'align-items:center', 'justify-content:center' 'background:rgba(0,0,0,0.55)', 'display:flex', 'align-items:center', 'justify-content:center'
].join(';'); ].join(';');
const _t = (key, fallback) => (typeof I18n !== 'undefined' ? I18n.t(key) : fallback);
overlay.innerHTML = ` overlay.innerHTML = `
<div style="background:var(--card-bg,#fff);border-radius:12px;padding:32px;max-width:400px;width:90%;text-align:center;box-shadow:0 20px 60px rgba(0,0,0,0.3);"> <div style="background:var(--card-bg,#fff);border-radius:12px;padding:32px;max-width:400px;width:90%;text-align:center;box-shadow:0 20px 60px rgba(0,0,0,0.3);">
<div style="width:56px;height:56px;background:#fff7ed;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto 16px;"> <div style="width:56px;height:56px;background:#fff7ed;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto 16px;">
<svg width="28" height="28" viewBox="0 0 20 20" fill="#c2410c"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"/></svg> <svg width="28" height="28" viewBox="0 0 20 20" fill="#c2410c"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"/></svg>
</div> </div>
<h3 style="font-size:1.1rem;font-weight:700;color:var(--gray-800,#1f2937);margin-bottom:8px;">Sessione in scadenza</h3> <h3 style="font-size:1.1rem;font-weight:700;color:var(--gray-800,#1f2937);margin-bottom:8px;">${_t('session.expiring_title', 'Sessione in scadenza')}</h3>
<p style="font-size:0.875rem;color:var(--gray-500,#6b7280);margin-bottom:20px;"> <p style="font-size:0.875rem;color:var(--gray-500,#6b7280);margin-bottom:20px;">
Per motivi di sicurezza, verrai disconnesso tra<br> ${_t('session.expiring_msg', 'Per motivi di sicurezza, verrai disconnesso tra')}<br>
<strong id="idle-countdown" style="font-size:1.5rem;color:#c2410c;display:block;margin:8px 0;">5:00</strong> <strong id="idle-countdown" style="font-size:1.5rem;color:#c2410c;display:block;margin:8px 0;">5:00</strong>
a causa di inattivita'. ${_t('session.idle_reason', "a causa di inattivita'.")}
</p> </p>
<div style="display:flex;gap:12px;justify-content:center;"> <div style="display:flex;gap:12px;justify-content:center;">
<button id="idle-stay-btn" <button id="idle-stay-btn"
style="padding:10px 24px;background:var(--primary,#2563eb);color:#fff;border:none;border-radius:8px;font-weight:600;cursor:pointer;font-size:0.875rem;"> style="padding:10px 24px;background:var(--primary,#2563eb);color:#fff;border:none;border-radius:8px;font-weight:600;cursor:pointer;font-size:0.875rem;">
Rimani connesso ${_t('session.stay', 'Rimani connesso')}
</button> </button>
<button onclick="api.logout();" <button onclick="api.logout();"
style="padding:10px 24px;background:var(--gray-100,#f3f4f6);color:var(--gray-700,#374151);border:none;border-radius:8px;font-weight:600;cursor:pointer;font-size:0.875rem;"> style="padding:10px 24px;background:var(--gray-100,#f3f4f6);color:var(--gray-700,#374151);border:none;border-radius:8px;font-weight:600;cursor:pointer;font-size:0.875rem;">
Disconnetti ${_t('session.logout_now', 'Disconnetti')}
</button> </button>
</div> </div>
</div> </div>

View File

@ -151,7 +151,8 @@ const HelpSystem = (function () {
items: [ items: [
'Ogni rischio registrato include: descrizione, categoria, asset coinvolti, owner e piano di trattamento.', 'Ogni rischio registrato include: descrizione, categoria, asset coinvolti, owner e piano di trattamento.',
'Lo stato di ogni rischio e\' tracciato nel tempo con lo storico delle modifiche.', 'Lo stato di ogni rischio e\' tracciato nel tempo con lo storico delle modifiche.',
'I rischi possono essere collegati ad asset, incidenti e controlli di compliance.' 'I rischi possono essere collegati ad asset, incidenti e controlli di compliance.',
'La <strong>Matrice Rischi</strong> si aggiorna in tempo reale: eliminando un rischio dalla vista dettaglio, la matrice si ricalcola automaticamente senza richiedere un refresh manuale.'
] ]
} }
], ],
@ -234,7 +235,7 @@ const HelpSystem = (function () {
'La funzione <strong>Genera con AI</strong> crea automaticamente bozze di policy conformi NIS2.', 'La funzione <strong>Genera con AI</strong> crea automaticamente bozze di policy conformi NIS2.',
'L\'AI utilizza il contesto della tua organizzazione (settore, dimensione, classificazione) per personalizzare il contenuto.', 'L\'AI utilizza il contesto della tua organizzazione (settore, dimensione, classificazione) per personalizzare il contenuto.',
'Le policy generate includono: obiettivo, ambito di applicazione, responsabilita\', procedure e riferimenti normativi.', 'Le policy generate includono: obiettivo, ambito di applicazione, responsabilita\', procedure e riferimenti normativi.',
'Le bozze generate devono essere revisionate e personalizzate prima dell\'approvazione.' 'Le bozze AI sono contrassegnate da un <strong>banner arancione di avviso</strong> che ricorda l\'obbligo di revisione prima dell\'approvazione. Il banner puo\' essere chiuso premendo la X.'
] ]
}, },
{ {
@ -485,10 +486,11 @@ const HelpSystem = (function () {
] ]
}, },
{ {
heading: 'Sicurezza', heading: 'Sicurezza Account',
items: [ items: [
'Modifica la password del tuo account.', 'Modifica la password del tuo account in qualsiasi momento.',
'Visualizza le sessioni attive e disconnetti dispositivi remoti.', 'La piattaforma applica un <strong>timeout di sessione automatico</strong> dopo 30 minuti di inattivita\'. Un avviso con countdown appare 5 minuti prima del logout per permetterti di rimanere connesso.',
'Il logout automatico protegge le informazioni sensibili in caso di postazione incustodita.',
'Configura le impostazioni di notifica per scadenze e alert.' 'Configura le impostazioni di notifica per scadenze e alert.'
] ]
} }

View File

@ -168,6 +168,13 @@ const I18n = (function () {
'msg.error_connection': { it: 'Errore di connessione al server.', en: 'Server connection error.' }, 'msg.error_connection': { it: 'Errore di connessione al server.', en: 'Server connection error.' },
'msg.no_data': { it: 'Nessun dato disponibile.', en: 'No data available.' }, 'msg.no_data': { it: 'Nessun dato disponibile.', en: 'No data available.' },
// ── Sessione / Idle timeout ─────────────────────
'session.expiring_title': { it: 'Sessione in scadenza', en: 'Session expiring' },
'session.expiring_msg': { it: 'Per motivi di sicurezza, verrai disconnesso tra', en: 'For security reasons, you will be logged out in' },
'session.idle_reason': { it: 'a causa di inattivita\'.', en: 'due to inactivity.' },
'session.stay': { it: 'Rimani connesso', en: 'Stay connected' },
'session.logout_now': { it: 'Disconnetti', en: 'Log out' },
// ── Tempo relativo ───────────────────────────── // ── Tempo relativo ─────────────────────────────
'time.now': { it: 'Adesso', en: 'Just now' }, 'time.now': { it: 'Adesso', en: 'Just now' },
'time.min_ago': { it: 'min fa', en: 'min ago' }, 'time.min_ago': { it: 'min fa', en: 'min ago' },