[FEAT] PWA installabile Android/iOS conforme AGID (v1.15.0)
- manifest.webmanifest + service worker (offline shell, /api network-only, asset stale-while-revalidate) - set icone (192/512 + maskable + apple-touch + favicon), generate zero-deps (pure Node+zlib) - tag PWA + viewport viewport-fit=cover (zoom mantenuto, WCAG 1.4.4) in 77 pagine HTML - AGID/WCAG 2.1 AA: touch target >=44px, orientamento/zoom liberi, safe-area standalone - generatori riproducibili: scripts/gen-pwa-icons.mjs + scripts/inject-pwa-head.mjs - bump version 1.14.1 -> 1.15.0 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@@ -280,6 +280,23 @@ NIS2 Agile e' una piattaforma SaaS multi-tenant per supportare le aziende nella
|
|||||||
|
|
||||||
Target: PMI, Enterprise, Consulenti/CISO.
|
Target: PMI, Enterprise, Consulenti/CISO.
|
||||||
|
|
||||||
|
## PWA conforme AGID — v1.15.0 (2026-06-14)
|
||||||
|
|
||||||
|
NIS2 e' una **PWA installabile** (Android/Chrome, iOS/iPadOS via "Aggiungi a Home"), responsive, conforme AGID/WCAG 2.1 AA.
|
||||||
|
|
||||||
|
**File**:
|
||||||
|
- `public/manifest.webmanifest` — manifest (theme `#0066CC` blu Italia, `display: standalone`, `orientation: any`, icone any+maskable, shortcuts).
|
||||||
|
- `public/sw.js` — service worker. Cache `nis2-shell-vX.Y.Z`. **Strategia**: `/api/*` **network-only** (MAI cacheato → no leak cross-utente su device condiviso); navigazioni HTML **network-first** → fallback `/offline.html`; asset statici **stale-while-revalidate**. **Bumpare il nome cache ad ogni release** (e' legato alla versione).
|
||||||
|
- `public/offline.html` — fallback offline (Bootstrap Italia + CSS inline di riserva).
|
||||||
|
- `public/js/pwa.js` — registra il SW + banner "Installa app" (Android) + hint "Aggiungi a Home" (iOS), i18n IT/EN (chiave `nis2_lang`).
|
||||||
|
- `public/assets/icons/*` — set icone (192/512, maskable, apple-touch 180, favicon 16/32, `icon.svg` master).
|
||||||
|
- `scripts/gen-pwa-icons.mjs` — **genera le icone** senza dipendenze (pure Node + zlib): `node scripts/gen-pwa-icons.mjs`.
|
||||||
|
- `scripts/inject-pwa-head.mjs` — **inietta i tag PWA** negli `<head>` (idempotente): `node scripts/inject-pwa-head.mjs`. Esclude `offline.html` e i file `* copy`.
|
||||||
|
|
||||||
|
**AGID/WCAG**: design system Bootstrap Italia (gia' live); **zoom e orientamento non bloccati**; **touch target ≥44px** (`@media (pointer: coarse)` in `style.css`); safe-area inset in `@media (display-mode: standalone)`. La "Dichiarazione di accessibilita'" AGID e' obbligatoria solo per servizi PA → qui opzionale (non implementata).
|
||||||
|
|
||||||
|
**Deploy**: tutto **statico** → live via bind-mount nginx, **nessun `kill -USR2`** (nessun `.php` toccato). Dopo edit a `sw.js`/`pwa.js` o ai tag head ricordarsi il **cache-buster** `?v=` (i tag head usano `pwa.js?v=20260614`) e il bump del nome cache SW.
|
||||||
|
|
||||||
## Stack Tecnologico
|
## Stack Tecnologico
|
||||||
- Backend: PHP 8.4 vanilla (no framework, Front Controller pattern)
|
- Backend: PHP 8.4 vanilla (no framework, Front Controller pattern)
|
||||||
- Database: MySQL 8.x (nis2_agile_db)
|
- Database: MySQL 8.x (nis2_agile_db)
|
||||||
|
|||||||
@@ -4,6 +4,15 @@
|
|||||||
|
|
||||||
## 2026-06-14 — ✅ SUPERVISORE AUTONOMO TICKET LIVE (cron) + chiusura demo/avatar/feedback
|
## 2026-06-14 — ✅ SUPERVISORE AUTONOMO TICKET LIVE (cron) + chiusura demo/avatar/feedback
|
||||||
|
|
||||||
|
### PWA conforme AGID — v1.15.0 (sessione serale)
|
||||||
|
NIS2 reso **PWA installabile** su Android (Chrome) e iOS/iPadOS (Safari "Aggiungi a Home"), responsive, **conforme AGID/WCAG 2.1 AA**. Avviato come flotta di agenti in background, completato inline dopo riavvio del processo (gli agenti background erano andati persi).
|
||||||
|
- **File nuovi**: `public/manifest.webmanifest` (theme `#0066CC` blu Italia, display standalone, orientation any, shortcuts Dashboard/Incidenti) · `public/sw.js` · `public/offline.html` · `public/js/pwa.js` (register SW + banner installazione Android + hint iOS, i18n IT/EN) · `public/assets/icons/*` (icon-192/512 + maskable + apple-touch 180 + favicon 16/32 + `icon.svg` master) · `scripts/gen-pwa-icons.mjs` (generatore icone zero-deps, pure Node+zlib) · `scripts/inject-pwa-head.mjs` (iniezione idempotente tag head).
|
||||||
|
- **Service worker**: cache `nis2-shell-v1.15.0`; `/api/*` **network-only** (no leak cross-utente su device condiviso), navigazioni HTML **network-first** → `offline.html`, asset **stale-while-revalidate**. Bumpare il nome cache ad ogni release.
|
||||||
|
- **Head**: tag PWA iniettati in **77 HTML** (64 + 6 admin + 7 subdir, escluso `offline.html`); viewport normalizzato a `viewport-fit=cover` **mantenendo lo zoom** (WCAG 1.4.4).
|
||||||
|
- **AGID/WCAG**: Bootstrap Italia (già live), zoom+orientamento liberi, **touch target ≥44px** (`@media (pointer: coarse)` in `style.css`), safe-area in standalone. "Dichiarazione di accessibilità" obbligatoria solo per PA → opzionale, non implementata.
|
||||||
|
- **Rigenerare**: `node scripts/gen-pwa-icons.mjs` (icone) · `node scripts/inject-pwa-head.mjs` (tag head, idempotente). Tutto **statico** → live via bind-mount, nessun USR2.
|
||||||
|
- Bump `version.json` 1.14.1 → **1.15.0**. **commit/push in attesa di conferma utente** al momento del salvataggio.
|
||||||
|
|
||||||
### Supervisore autonomo ticket (lavoro principale di oggi)
|
### Supervisore autonomo ticket (lavoro principale di oggi)
|
||||||
NIS2 = **primo adopter LIVE** dello standard AgileHub `autonomous-supervisor-agent` (`hub_standards` id=32). Un agente `claude -p --model opus` headless (chiave SSH **effimera per ciclo**) fa da supervisore **end-to-end** ai ticket NIS2 → **NIS2 esce dal `ticket-agent-cron` generico**.
|
NIS2 = **primo adopter LIVE** dello standard AgileHub `autonomous-supervisor-agent` (`hub_standards` id=32). Un agente `claude -p --model opus` headless (chiave SSH **effimera per ciclo**) fa da supervisore **end-to-end** ai ticket NIS2 → **NIS2 esce dal `ticket-agent-cron` generico**.
|
||||||
- **Cron LIVE**: `/etc/cron.d/nis2-supervisor` → `17 */4 * * *` (ogni 4h, minuto 17). **Kill switch**: `touch /etc/agilehub/supervisor-nis2.disabled`. **Rollback**: `rm /etc/cron.d/nis2-supervisor`. Audit: `/var/log/nis2-supervisor-audit.jsonl`.
|
- **Cron LIVE**: `/etc/cron.d/nis2-supervisor` → `17 */4 * * *` (ogni 4h, minuto 17). **Kill switch**: `touch /etc/agilehub/supervisor-nis2.disabled`. **Rollback**: `rm /etc/cron.d/nis2-supervisor`. Audit: `/var/log/nis2-supervisor-audit.jsonl`.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Demo Sidebar BI - NIS2 Agile</title>
|
<title>Demo Sidebar BI - NIS2 Agile</title>
|
||||||
|
|
||||||
<!-- Bootstrap Italia v2.18.1 SELF-HOSTATO da /vendor (regola "MAI CDN") -->
|
<!-- Bootstrap Italia v2.18.1 SELF-HOSTATO da /vendor (regola "MAI CDN") -->
|
||||||
@@ -23,6 +23,19 @@
|
|||||||
.demo-note h1 { font-size: 1.25rem; margin: 0 0 8px; color: #17324d; }
|
.demo-note h1 { font-size: 1.25rem; margin: 0 0 8px; color: #17324d; }
|
||||||
.demo-note p { margin: 0; color: #5b6772; font-size: .9rem; }
|
.demo-note p { margin: 0; color: #5b6772; font-size: .9rem; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-shell">
|
<div class="app-shell">
|
||||||
|
|||||||
@@ -2,10 +2,23 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Bootstrap Italia self-host — smoke test</title>
|
<title>Bootstrap Italia self-host — smoke test</title>
|
||||||
<!-- SELF-HOSTED Bootstrap Italia v2.18.1 — asset LOCALI da /vendor, ZERO CDN -->
|
<!-- SELF-HOSTED Bootstrap Italia v2.18.1 — asset LOCALI da /vendor, ZERO CDN -->
|
||||||
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main class="container py-4" id="main-content">
|
<main class="container py-4" id="main-content">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Gap Analysis ACN (BI) - NIS2 Agile</title>
|
<title>Gap Analysis ACN (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -45,6 +45,19 @@
|
|||||||
/* icona inline nei bottoni BI */
|
/* icona inline nei bottoni BI */
|
||||||
.btn .icon { fill:currentColor; vertical-align:-2px; margin-right:6px; }
|
.btn .icon { fill:currentColor; vertical-align:-2px; margin-right:6px; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Gap Analysis ACN - NIS2 Agile</title>
|
<title>Gap Analysis ACN - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -45,6 +45,19 @@
|
|||||||
/* icona inline nei bottoni BI */
|
/* icona inline nei bottoni BI */
|
||||||
.btn .icon { fill:currentColor; vertical-align:-2px; margin-right:6px; }
|
.btn .icon { fill:currentColor; vertical-align:-2px; margin-right:6px; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Pannello Amministrazione (BI) - NIS2 Agile</title>
|
<title>Pannello Amministrazione (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css resta autorevole per i widget renderizzati via JS -> parita' funzionale.
|
cosi' style.css resta autorevole per i widget renderizzati via JS -> parita' funzionale.
|
||||||
@@ -182,6 +182,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Pannello Amministrazione - NIS2 Agile</title>
|
<title>Pannello Amministrazione - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css resta autorevole per i widget renderizzati via JS -> parita' funzionale.
|
cosi' style.css resta autorevole per i widget renderizzati via JS -> parita' funzionale.
|
||||||
@@ -182,6 +182,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Gestione Organizzazioni (BI) - NIS2 Agile</title>
|
<title>Gestione Organizzazioni (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -101,6 +101,19 @@
|
|||||||
fill: currentColor;
|
fill: currentColor;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Gestione Organizzazioni - NIS2 Agile</title>
|
<title>Gestione Organizzazioni - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -101,6 +101,19 @@
|
|||||||
fill: currentColor;
|
fill: currentColor;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Gestione Utenti (BI) - NIS2 Agile</title>
|
<title>Gestione Utenti (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -123,6 +123,19 @@
|
|||||||
color: var(--gray-400);
|
color: var(--gray-400);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Gestione Utenti - NIS2 Agile</title>
|
<title>Gestione Utenti - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -123,6 +123,19 @@
|
|||||||
color: var(--gray-400);
|
color: var(--gray-400);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Architettura - NIS2 Agile</title>
|
<title>Architettura - NIS2 Agile</title>
|
||||||
<link rel="stylesheet" href="css/style.css?v=20260613b">
|
<link rel="stylesheet" href="css/style.css?v=20260613b">
|
||||||
<style>
|
<style>
|
||||||
@@ -617,6 +617,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,13 +2,26 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Gap Analysis (BI) - NIS2 Agile</title>
|
<title>Gap Analysis (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
via JS (wizard/form/gauge) -> parita' funzionale assoluta. BI veste la chrome. -->
|
via JS (wizard/form/gauge) -> parita' funzionale assoluta. BI veste la chrome. -->
|
||||||
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
<link rel="stylesheet" href="/css/style.css?v=20260613b">
|
<link rel="stylesheet" href="/css/style.css?v=20260613b">
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,13 +2,26 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Gap Analysis - NIS2 Agile</title>
|
<title>Gap Analysis - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
via JS (wizard/form/gauge) -> parita' funzionale assoluta. BI veste la chrome. -->
|
via JS (wizard/form/gauge) -> parita' funzionale assoluta. BI veste la chrome. -->
|
||||||
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
<link rel="stylesheet" href="/css/style.css?v=20260613b">
|
<link rel="stylesheet" href="/css/style.css?v=20260613b">
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Inventario Asset (BI) - NIS2 Agile</title>
|
<title>Inventario Asset (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -258,6 +258,19 @@
|
|||||||
.form-grid-2 { grid-template-columns: 1fr; }
|
.form-grid-2 { grid-template-columns: 1fr; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Inventario Asset - NIS2 Agile</title>
|
<title>Inventario Asset - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -258,6 +258,19 @@
|
|||||||
.form-grid-2 { grid-template-columns: 1fr; }
|
.form-grid-2 { grid-template-columns: 1fr; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 303 B |
|
After Width: | Height: | Size: 447 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512" role="img" aria-label="NIS2 Agile">
|
||||||
|
<title>NIS2 Agile</title>
|
||||||
|
<!-- Italy-blue rounded tile -->
|
||||||
|
<rect x="40.96" y="40.96" width="430.08" height="430.08" rx="92.16" ry="92.16" fill="#0066CC"/>
|
||||||
|
<!-- White shield -->
|
||||||
|
<polygon points="114.7,99.3 397.3,99.3 395.9,202.2 386.0,263.7 360.6,325.1 315.4,386.6 256.0,428.0 196.6,386.6 151.4,325.1 126.0,263.7 116.1,202.2 114.7,99.3" fill="#FFFFFF"/>
|
||||||
|
<!-- Negative blue check -->
|
||||||
|
<polygon points="169.6,269.9 227.6,321.5 254.3,319.2 351.1,196.6 322.2,173.8 225.4,296.3 252.1,294.0 194.1,242.4" fill="#0066CC"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 696 B |
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Le Mie Aziende - NIS2 Agile</title>
|
<title>Le Mie Aziende - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (MAI CDN). Caricato PRIMA di style.css: BI veste la chrome/sidebar, style.css resta autorevole per i widget. -->
|
<!-- Bootstrap Italia v2.18.1 self-hostato (MAI CDN). Caricato PRIMA di style.css: BI veste la chrome/sidebar, style.css resta autorevole per i widget. -->
|
||||||
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
@@ -268,6 +268,19 @@
|
|||||||
gap: 16px;
|
gap: 16px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Le Mie Aziende - NIS2 Agile</title>
|
<title>Le Mie Aziende - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (MAI CDN). Caricato PRIMA di style.css: BI veste la chrome/sidebar, style.css resta autorevole per i widget. -->
|
<!-- Bootstrap Italia v2.18.1 self-hostato (MAI CDN). Caricato PRIMA di style.css: BI veste la chrome/sidebar, style.css resta autorevole per i widget. -->
|
||||||
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
@@ -268,6 +268,19 @@
|
|||||||
gap: 16px;
|
gap: 16px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>AI Cross-Analysis (BI) — NIS2 Agile</title>
|
<title>AI Cross-Analysis (BI) — NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -272,6 +272,19 @@
|
|||||||
.tab-pane { display: none; }
|
.tab-pane { display: none; }
|
||||||
.tab-pane.active { display: block; }
|
.tab-pane.active { display: block; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>AI Cross-Analysis — NIS2 Agile</title>
|
<title>AI Cross-Analysis — NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -272,6 +272,19 @@
|
|||||||
.tab-pane { display: none; }
|
.tab-pane { display: none; }
|
||||||
.tab-pane.active { display: block; }
|
.tab-pane.active { display: block; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2411,3 +2411,44 @@ tbody tr.clickable:active {
|
|||||||
.feedback-resolve-actions { flex-direction: column; }
|
.feedback-resolve-actions { flex-direction: column; }
|
||||||
.feedback-password-row { flex-direction: column; }
|
.feedback-password-row { flex-direction: column; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── PWA / AGID — Accessibilità mobile ──────────────────────────────
|
||||||
|
Touch target >= 44x44px (WCAG 2.5.5 / Linee guida di design AGID) e
|
||||||
|
gestione safe-area in modalità installata (notch). Solo aggiunte. */
|
||||||
|
@media (pointer: coarse) {
|
||||||
|
.btn,
|
||||||
|
button,
|
||||||
|
input[type="submit"],
|
||||||
|
input[type="button"],
|
||||||
|
.nav-link,
|
||||||
|
.sidebar a,
|
||||||
|
a.btn,
|
||||||
|
.icon-btn,
|
||||||
|
.sidebar-toggle {
|
||||||
|
min-height: 44px;
|
||||||
|
}
|
||||||
|
.btn,
|
||||||
|
a.btn,
|
||||||
|
input[type="submit"],
|
||||||
|
input[type="button"],
|
||||||
|
.icon-btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.icon-btn,
|
||||||
|
.sidebar-toggle {
|
||||||
|
min-width: 44px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Safe-area inset quando l'app gira installata (standalone) */
|
||||||
|
@media all and (display-mode: standalone) {
|
||||||
|
.content-header { padding-top: max(16px, env(safe-area-inset-top)); }
|
||||||
|
.main-content {
|
||||||
|
padding-left: env(safe-area-inset-left);
|
||||||
|
padding-right: env(safe-area-inset-right);
|
||||||
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
}
|
||||||
|
.sidebar { padding-top: env(safe-area-inset-top); }
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,13 +2,26 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Dashboard (BI) - NIS2 Agile</title>
|
<title>Dashboard (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
via JS (card/gauge/stat/modali) -> parita' funzionale assoluta. BI veste la chrome. -->
|
via JS (card/gauge/stat/modali) -> parita' funzionale assoluta. BI veste la chrome. -->
|
||||||
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
<link rel="stylesheet" href="/css/style.css?v=20260613b">
|
<link rel="stylesheet" href="/css/style.css?v=20260613b">
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,13 +2,26 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Dashboard - NIS2 Agile</title>
|
<title>Dashboard - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
via JS (card/gauge/stat/modali) -> parita' funzionale assoluta. BI veste la chrome. -->
|
via JS (card/gauge/stat/modali) -> parita' funzionale assoluta. BI veste la chrome. -->
|
||||||
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
<link rel="stylesheet" href="/css/style.css?v=20260613b">
|
<link rel="stylesheet" href="/css/style.css?v=20260613b">
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>NIS2 Agile — API Reference</title>
|
<title>NIS2 Agile — API Reference</title>
|
||||||
<style>
|
<style>
|
||||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
@@ -109,6 +109,19 @@
|
|||||||
.content { padding: 24px; }
|
.content { padding: 24px; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="layout">
|
<div class="layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>NIS2 Agile — Sistema di Testing & Simulazione</title>
|
<title>NIS2 Agile — Sistema di Testing & Simulazione</title>
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
@@ -233,6 +233,19 @@
|
|||||||
padding: 32px 48px; text-align: center; color: var(--muted); font-size: 0.875rem;
|
padding: 32px 48px; text-align: center; color: var(--muted); font-size: 0.875rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Password dimenticata - NIS2 Agile</title>
|
<title>Password dimenticata - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della forgot-password.html. -->
|
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della forgot-password.html. -->
|
||||||
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
@@ -15,6 +15,19 @@
|
|||||||
.auth-brand .brand-sub { color: #5a6772; font-size: .9rem; margin-top: 4px; }
|
.auth-brand .brand-sub { color: #5a6772; font-size: .9rem; margin-top: 4px; }
|
||||||
.ico { width: 1em; height: 1em; fill: currentColor; vertical-align: -.125em; }
|
.ico { width: 1em; height: 1em; fill: currentColor; vertical-align: -.125em; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main class="auth-wrap">
|
<main class="auth-wrap">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Password dimenticata - NIS2 Agile</title>
|
<title>Password dimenticata - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della forgot-password.html. -->
|
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della forgot-password.html. -->
|
||||||
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
@@ -15,6 +15,19 @@
|
|||||||
.auth-brand .brand-sub { color: #5a6772; font-size: .9rem; margin-top: 4px; }
|
.auth-brand .brand-sub { color: #5a6772; font-size: .9rem; margin-top: 4px; }
|
||||||
.ico { width: 1em; height: 1em; fill: currentColor; vertical-align: -.125em; }
|
.ico { width: 1em; height: 1em; fill: currentColor; vertical-align: -.125em; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main class="auth-wrap">
|
<main class="auth-wrap">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Guida all'uso (BI) - NIS2 Agile</title>
|
<title>Guida all'uso (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css resta autorevole per la chrome (sidebar/widget). BI veste la guida. -->
|
cosi' style.css resta autorevole per la chrome (sidebar/widget). BI veste la guida. -->
|
||||||
@@ -88,6 +88,19 @@
|
|||||||
.guide-toc-card { position: static; }
|
.guide-toc-card { position: static; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Guida all'uso - NIS2 Agile</title>
|
<title>Guida all'uso - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css resta autorevole per la chrome (sidebar/widget). BI veste la guida. -->
|
cosi' style.css resta autorevole per la chrome (sidebar/widget). BI veste la guida. -->
|
||||||
@@ -88,6 +88,19 @@
|
|||||||
.guide-toc-card { position: static; }
|
.guide-toc-card { position: static; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Gestione Incidenti (BI) - NIS2 Agile</title>
|
<title>Gestione Incidenti (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -259,6 +259,19 @@
|
|||||||
.filters-bar .form-select { min-width: 100%; }
|
.filters-bar .form-select { min-width: 100%; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Gestione Incidenti - NIS2 Agile</title>
|
<title>Gestione Incidenti - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -259,6 +259,19 @@
|
|||||||
.filters-bar .form-select { min-width: 100%; }
|
.filters-bar .form-select { min-width: 100%; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>NIS2 Agile — Compliance NIS2 semplificata per aziende e consulenti</title>
|
<title>NIS2 Agile — Compliance NIS2 semplificata per aziende e consulenti</title>
|
||||||
<meta name="description" content="Piattaforma SaaS multi-tenant per la compliance NIS2 (EU 2022/2555 e D.Lgs. 138/2024). Doppia gap analysis Art.21 e misure di base ACN (Det. 164179/2025), risk management, incident response Art.23, portale fornitori e AI consulente ancorata alle fonti normative certe.">
|
<meta name="description" content="Piattaforma SaaS multi-tenant per la compliance NIS2 (EU 2022/2555 e D.Lgs. 138/2024). Doppia gap analysis Art.21 e misure di base ACN (Det. 164179/2025), risk management, incident response Art.23, portale fornitori e AI consulente ancorata alle fonti normative certe.">
|
||||||
<link rel="canonical" href="https://nis2.agile.software/">
|
<link rel="canonical" href="https://nis2.agile.software/">
|
||||||
@@ -33,6 +33,19 @@
|
|||||||
footer.app-footer a { color: #cbd5e1; }
|
footer.app-footer a { color: #cbd5e1; }
|
||||||
</style>
|
</style>
|
||||||
<script defer data-domain="nis2.agile.software" src="https://analytics.agile.software/js/script.js"></script>
|
<script defer data-domain="nis2.agile.software" src="https://analytics.agile.software/js/script.js"></script>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>NIS2 Agile — Simplified NIS2 compliance for companies and consultants</title>
|
<title>NIS2 Agile — Simplified NIS2 compliance for companies and consultants</title>
|
||||||
<meta name="description" content="Multi-tenant SaaS platform for compliance with the NIS2 Directive (EU 2022/2555) and Legislative Decree 138/2024. AI gap analysis, risk management, Article 23 incident response, policies, training.">
|
<meta name="description" content="Multi-tenant SaaS platform for compliance with the NIS2 Directive (EU 2022/2555) and Legislative Decree 138/2024. AI gap analysis, risk management, Article 23 incident response, policies, training.">
|
||||||
<link rel="canonical" href="https://nis2.agile.software/index-en.html">
|
<link rel="canonical" href="https://nis2.agile.software/index-en.html">
|
||||||
@@ -678,6 +678,19 @@
|
|||||||
<link rel="stylesheet" href="mobile-conversion.css?v=20260519a">
|
<link rel="stylesheet" href="mobile-conversion.css?v=20260519a">
|
||||||
<!-- Plausible Analytics -->
|
<!-- Plausible Analytics -->
|
||||||
<script defer data-domain="nis2.agile.software" src="https://analytics.agile.software/js/script.js"></script>
|
<script defer data-domain="nis2.agile.software" src="https://analytics.agile.software/js/script.js"></script>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>NIS2 Agile — Compliance NIS2 semplificata per aziende e consulenti</title>
|
<title>NIS2 Agile — Compliance NIS2 semplificata per aziende e consulenti</title>
|
||||||
<meta name="description" content="Piattaforma SaaS multi-tenant per la compliance NIS2 (EU 2022/2555 e D.Lgs. 138/2024). Doppia gap analysis Art.21 e misure di base ACN (Det. 164179/2025), risk management, incident response Art.23, portale fornitori e AI consulente ancorata alle fonti normative certe.">
|
<meta name="description" content="Piattaforma SaaS multi-tenant per la compliance NIS2 (EU 2022/2555 e D.Lgs. 138/2024). Doppia gap analysis Art.21 e misure di base ACN (Det. 164179/2025), risk management, incident response Art.23, portale fornitori e AI consulente ancorata alle fonti normative certe.">
|
||||||
<link rel="canonical" href="https://nis2.agile.software/">
|
<link rel="canonical" href="https://nis2.agile.software/">
|
||||||
@@ -693,6 +693,19 @@
|
|||||||
<link rel="stylesheet" href="mobile-conversion.css?v=20260519a">
|
<link rel="stylesheet" href="mobile-conversion.css?v=20260519a">
|
||||||
<!-- Plausible Analytics -->
|
<!-- Plausible Analytics -->
|
||||||
<script defer data-domain="nis2.agile.software" src="https://analytics.agile.software/js/script.js"></script>
|
<script defer data-domain="nis2.agile.software" src="https://analytics.agile.software/js/script.js"></script>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>AllRisk × NIS2 Agile — Integrazione</title>
|
<title>AllRisk × NIS2 Agile — Integrazione</title>
|
||||||
<style>
|
<style>
|
||||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
@@ -35,6 +35,19 @@
|
|||||||
.field-map th { padding: 9px 12px; background: #f1f5f9; font-size: 0.8rem; font-weight: 700; text-align: left; }
|
.field-map th { padding: 9px 12px; background: #f1f5f9; font-size: 0.8rem; font-weight: 700; text-align: left; }
|
||||||
.field-map td { padding: 9px 12px; border-bottom: 1px solid var(--gray-200); font-size: 0.8rem; }
|
.field-map td { padding: 9px 12px; border-bottom: 1px solid var(--gray-200); font-size: 0.8rem; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>NIS2 Agile — Integrazioni</title>
|
<title>NIS2 Agile — Integrazioni</title>
|
||||||
<style>
|
<style>
|
||||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
@@ -26,6 +26,19 @@
|
|||||||
.card-link:hover { text-decoration: underline; }
|
.card-link:hover { text-decoration: underline; }
|
||||||
.badge { display: inline-flex; padding: 3px 8px; border-radius: 20px; font-size: 0.7rem; font-weight: 700; margin-bottom: 12px; }
|
.badge { display: inline-flex; padding: 3px 8px; border-radius: 20px; font-size: 0.7rem; font-weight: 700; margin-bottom: 12px; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>231 Agile × NIS2 Agile — Integrazione</title>
|
<title>231 Agile × NIS2 Agile — Integrazione</title>
|
||||||
<style>
|
<style>
|
||||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
@@ -44,6 +44,19 @@
|
|||||||
.metric-val { font-size: 1.25rem; font-weight: 700; color: var(--gray-900); }
|
.metric-val { font-size: 1.25rem; font-weight: 700; color: var(--gray-900); }
|
||||||
.metric-label { font-size: 0.7rem; color: var(--gray-500); margin-top: 2px; }
|
.metric-label { font-size: 0.7rem; color: var(--gray-500); margin-top: 2px; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>SIEM × NIS2 Agile — Integrazione</title>
|
<title>SIEM × NIS2 Agile — Integrazione</title>
|
||||||
<style>
|
<style>
|
||||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
@@ -33,6 +33,19 @@
|
|||||||
.info-box { padding: 14px 16px; border-radius: var(--radius); margin: 16px 0; font-size: 0.875rem; }
|
.info-box { padding: 14px 16px; border-radius: var(--radius); margin: 16px 0; font-size: 0.875rem; }
|
||||||
.info-purple { background: #f5f3ff; border-left: 3px solid var(--purple); color: #4c1d95; }
|
.info-purple { background: #f5f3ff; border-left: 3px solid var(--purple); color: #4c1d95; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>SustainAI × NIS2 Agile — Integrazione</title>
|
<title>SustainAI × NIS2 Agile — Integrazione</title>
|
||||||
<style>
|
<style>
|
||||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
@@ -38,6 +38,19 @@
|
|||||||
.esg-e { background: #dcfce7; color: #166534; }
|
.esg-e { background: #dcfce7; color: #166534; }
|
||||||
.esg-s { background: #faf5ff; color: #6b21a8; }
|
.esg-s { background: #faf5ff; color: #6b21a8; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>NIS2 Agile — Integrazioni Esterne</title>
|
<title>NIS2 Agile — Integrazioni Esterne</title>
|
||||||
<link rel="stylesheet" href="css/style.css?v=20260613b">
|
<link rel="stylesheet" href="css/style.css?v=20260613b">
|
||||||
<style>
|
<style>
|
||||||
@@ -203,6 +203,19 @@
|
|||||||
.tab-pane { display: none; }
|
.tab-pane { display: none; }
|
||||||
.tab-pane.active { display: block; }
|
.tab-pane.active { display: block; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Modello Organizzativo SGSI (ISO 27001) (BI) - NIS2 Agile</title>
|
<title>Modello Organizzativo SGSI (ISO 27001) (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -47,6 +47,19 @@
|
|||||||
/* Allinea l'icona sprite BI nel bottone Esporta col testo */
|
/* Allinea l'icona sprite BI nel bottone Esporta col testo */
|
||||||
.content-header-actions .btn .icon { vertical-align:text-bottom; margin-right:4px; }
|
.content-header-actions .btn .icon { vertical-align:text-bottom; margin-right:4px; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Modello Organizzativo SGSI (ISO 27001) - NIS2 Agile</title>
|
<title>Modello Organizzativo SGSI (ISO 27001) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -47,6 +47,19 @@
|
|||||||
/* Allinea l'icona sprite BI nel bottone Esporta col testo */
|
/* Allinea l'icona sprite BI nel bottone Esporta col testo */
|
||||||
.content-header-actions .btn .icon { vertical-align:text-bottom; margin-right:4px; }
|
.content-header-actions .btn .icon { vertical-align:text-bottom; margin-right:4px; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* NIS2 Agile — PWA bootstrap
|
||||||
|
* Registra il service worker e gestisce l'UI di installazione (Android + iOS).
|
||||||
|
* Vanilla JS, nessuna dipendenza. Localizzato IT/EN (chiave i18n: 'nis2_lang').
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// --- i18n minimale, allineato a i18n.js (localStorage 'nis2_lang') ---
|
||||||
|
function lang() {
|
||||||
|
try { return (localStorage.getItem('nis2_lang') || 'it').slice(0, 2); }
|
||||||
|
catch (e) { return 'it'; }
|
||||||
|
}
|
||||||
|
var STR = {
|
||||||
|
it: {
|
||||||
|
install: 'Installa app',
|
||||||
|
banner: 'Installa NIS2 Agile sul dispositivo per un accesso più rapido.',
|
||||||
|
ios: 'Per installare: tocca Condividi e poi "Aggiungi a Home".',
|
||||||
|
close: 'Chiudi'
|
||||||
|
},
|
||||||
|
en: {
|
||||||
|
install: 'Install app',
|
||||||
|
banner: 'Install NIS2 Agile on your device for faster access.',
|
||||||
|
ios: 'To install: tap Share, then "Add to Home Screen".',
|
||||||
|
close: 'Close'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function t(k) { var l = lang(); return (STR[l] && STR[l][k]) || STR.it[k]; }
|
||||||
|
|
||||||
|
function isStandalone() {
|
||||||
|
return (window.matchMedia && window.matchMedia('(display-mode: standalone)').matches)
|
||||||
|
|| window.navigator.standalone === true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- 1. Registrazione service worker ---
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
window.addEventListener('load', function () {
|
||||||
|
navigator.serviceWorker.register('/sw.js', { scope: '/' })
|
||||||
|
.catch(function (err) { console.warn('[pwa] SW registration failed', err); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gia' installata (standalone): niente banner di installazione.
|
||||||
|
if (isStandalone()) return;
|
||||||
|
|
||||||
|
// --- UI banner sobrio, indipendente dal CSS dell'app ---
|
||||||
|
function makeBanner(message, withInstallBtn) {
|
||||||
|
var bar = document.createElement('div');
|
||||||
|
bar.setAttribute('role', 'region');
|
||||||
|
bar.setAttribute('aria-label', t('install'));
|
||||||
|
bar.style.cssText = 'position:fixed;left:12px;right:12px;bottom:12px;z-index:9999;'
|
||||||
|
+ 'background:#0066CC;color:#fff;border-radius:10px;padding:12px 14px;'
|
||||||
|
+ 'box-shadow:0 6px 24px rgba(0,0,0,.25);display:flex;align-items:center;gap:10px;'
|
||||||
|
+ 'font-family:system-ui,Arial,sans-serif;font-size:.95rem;max-width:560px;margin:0 auto;';
|
||||||
|
|
||||||
|
var txt = document.createElement('span');
|
||||||
|
txt.style.cssText = 'flex:1;line-height:1.35;';
|
||||||
|
txt.textContent = message;
|
||||||
|
bar.appendChild(txt);
|
||||||
|
|
||||||
|
var btnInstall = null;
|
||||||
|
if (withInstallBtn) {
|
||||||
|
btnInstall = document.createElement('button');
|
||||||
|
btnInstall.type = 'button';
|
||||||
|
btnInstall.textContent = t('install');
|
||||||
|
btnInstall.style.cssText = 'background:#fff;color:#0066CC;border:0;border-radius:8px;'
|
||||||
|
+ 'padding:10px 16px;font-weight:600;min-height:44px;cursor:pointer;white-space:nowrap;';
|
||||||
|
bar.appendChild(btnInstall);
|
||||||
|
}
|
||||||
|
|
||||||
|
var btnClose = document.createElement('button');
|
||||||
|
btnClose.type = 'button';
|
||||||
|
btnClose.setAttribute('aria-label', t('close'));
|
||||||
|
btnClose.textContent = '✕';
|
||||||
|
btnClose.style.cssText = 'background:transparent;color:#fff;border:0;font-size:1.1rem;'
|
||||||
|
+ 'line-height:1;min-width:44px;min-height:44px;cursor:pointer;';
|
||||||
|
bar.appendChild(btnClose);
|
||||||
|
|
||||||
|
document.body.appendChild(bar);
|
||||||
|
return { bar: bar, btnInstall: btnInstall, btnClose: btnClose };
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- 2. Android / Chrome: beforeinstallprompt ---
|
||||||
|
var deferred = null;
|
||||||
|
var DISMISS_KEY = 'pwa-install-dismissed';
|
||||||
|
function dismissed() { try { return localStorage.getItem(DISMISS_KEY) === '1'; } catch (e) { return false; } }
|
||||||
|
function setDismissed() { try { localStorage.setItem(DISMISS_KEY, '1'); } catch (e) {} }
|
||||||
|
|
||||||
|
window.addEventListener('beforeinstallprompt', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
deferred = e;
|
||||||
|
if (dismissed()) return;
|
||||||
|
try {
|
||||||
|
var ui = makeBanner(t('banner'), true);
|
||||||
|
ui.btnInstall.addEventListener('click', function () {
|
||||||
|
ui.bar.remove();
|
||||||
|
if (!deferred) return;
|
||||||
|
deferred.prompt();
|
||||||
|
if (deferred.userChoice && deferred.userChoice.finally) {
|
||||||
|
deferred.userChoice.finally(function () { deferred = null; });
|
||||||
|
} else { deferred = null; }
|
||||||
|
});
|
||||||
|
ui.btnClose.addEventListener('click', function () { ui.bar.remove(); setDismissed(); });
|
||||||
|
} catch (err) { console.warn('[pwa] banner error', err); }
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('appinstalled', function () {
|
||||||
|
deferred = null;
|
||||||
|
setDismissed();
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- 3. iOS Safari: nessun beforeinstallprompt -> hint manuale (una volta) ---
|
||||||
|
try {
|
||||||
|
var ua = navigator.userAgent || '';
|
||||||
|
var isIOS = /iphone|ipad|ipod/i.test(ua)
|
||||||
|
|| (/Macintosh/.test(ua) && 'ontouchend' in document); // iPad iPadOS desktop-mode
|
||||||
|
var isSafari = /safari/i.test(ua) && !/crios|fxios|edgios|android/i.test(ua);
|
||||||
|
var IOS_KEY = 'pwa-ios-hint-dismissed';
|
||||||
|
var iosDismissed = (function () { try { return localStorage.getItem(IOS_KEY) === '1'; } catch (e) { return false; } })();
|
||||||
|
if (isIOS && isSafari && !iosDismissed) {
|
||||||
|
window.addEventListener('load', function () {
|
||||||
|
var ui = makeBanner(t('ios'), false);
|
||||||
|
ui.btnClose.addEventListener('click', function () {
|
||||||
|
ui.bar.remove();
|
||||||
|
try { localStorage.setItem(IOS_KEY, '1'); } catch (e) {}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) { console.warn('[pwa] ios hint error', err); }
|
||||||
|
})();
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Knowledge Base (BI) - NIS2 Agile</title>
|
<title>Knowledge Base (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -22,6 +22,19 @@
|
|||||||
/* Allinea l'icona sprite BI dentro i bottoni del design system esistente */
|
/* Allinea l'icona sprite BI dentro i bottoni del design system esistente */
|
||||||
.btn .icon { fill: currentColor; vertical-align: middle; }
|
.btn .icon { fill: currentColor; vertical-align: middle; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Knowledge Base - NIS2 Agile</title>
|
<title>Knowledge Base - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -22,6 +22,19 @@
|
|||||||
/* Allinea l'icona sprite BI dentro i bottoni del design system esistente */
|
/* Allinea l'icona sprite BI dentro i bottoni del design system esistente */
|
||||||
.btn .icon { fill: currentColor; vertical-align: middle; }
|
.btn .icon { fill: currentColor; vertical-align: middle; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>NIS2 Agile — Gestione Licenze</title>
|
<title>NIS2 Agile — Gestione Licenze</title>
|
||||||
<link rel="stylesheet" href="css/style.css?v=20260613b">
|
<link rel="stylesheet" href="css/style.css?v=20260613b">
|
||||||
<style>
|
<style>
|
||||||
@@ -217,6 +217,19 @@ body { background: var(--bg-main); }
|
|||||||
.modal-box h3 { font-size: 1rem; margin-bottom: 1.25rem; }
|
.modal-box h3 { font-size: 1rem; margin-bottom: 1.25rem; }
|
||||||
.modal-close { float: right; background: none; border: none; color: var(--text-secondary); font-size: 1.2rem; cursor: pointer; margin-top: -.2rem; }
|
.modal-close { float: right; background: none; border: none; color: var(--text-secondary); font-size: 1.2rem; cursor: pointer; margin-top: -.2rem; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Accedi - NIS2 Agile</title>
|
<title>Accedi - NIS2 Agile</title>
|
||||||
<!-- PILOTA Bootstrap Italia v2.18.1 (Opzione B). Self-hostato: asset serviti da /vendor (regola 'MAI CDN'). -->
|
<!-- PILOTA Bootstrap Italia v2.18.1 (Opzione B). Self-hostato: asset serviti da /vendor (regola 'MAI CDN'). -->
|
||||||
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
@@ -19,6 +19,19 @@
|
|||||||
.pw-toggle { position: absolute; right: 8px; top: 8px; background: none; border: none;
|
.pw-toggle { position: absolute; right: 8px; top: 8px; background: none; border: none;
|
||||||
color: #5a6772; cursor: pointer; padding: 6px; }
|
color: #5a6772; cursor: pointer; padding: 6px; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main class="auth-wrap">
|
<main class="auth-wrap">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Accedi - NIS2 Agile</title>
|
<title>Accedi - NIS2 Agile</title>
|
||||||
<!-- PILOTA Bootstrap Italia v2.18.1 (Opzione B). Self-hostato: asset serviti da /vendor (regola 'MAI CDN'). -->
|
<!-- PILOTA Bootstrap Italia v2.18.1 (Opzione B). Self-hostato: asset serviti da /vendor (regola 'MAI CDN'). -->
|
||||||
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
@@ -19,6 +19,19 @@
|
|||||||
.pw-toggle { position: absolute; right: 8px; top: 8px; background: none; border: none;
|
.pw-toggle { position: absolute; right: 8px; top: 8px; background: none; border: none;
|
||||||
color: #5a6772; cursor: pointer; padding: 6px; }
|
color: #5a6772; cursor: pointer; padding: 6px; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main class="auth-wrap">
|
<main class="auth-wrap">
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
{
|
||||||
|
"name": "NIS2 Agile — Compliance NIS2 & D.Lgs. 138/2024",
|
||||||
|
"short_name": "NIS2 Agile",
|
||||||
|
"description": "Piattaforma per la conformità alla direttiva NIS2 e al D.Lgs. 138/2024.",
|
||||||
|
"lang": "it",
|
||||||
|
"dir": "ltr",
|
||||||
|
"start_url": "/dashboard.html?source=pwa",
|
||||||
|
"scope": "/",
|
||||||
|
"display": "standalone",
|
||||||
|
"display_override": ["standalone", "minimal-ui"],
|
||||||
|
"orientation": "any",
|
||||||
|
"theme_color": "#0066CC",
|
||||||
|
"background_color": "#FFFFFF",
|
||||||
|
"categories": ["business", "productivity", "security"],
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/assets/icons/icon-192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "any"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/assets/icons/icon-512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "any"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/assets/icons/icon-192-maskable.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/assets/icons/icon-512-maskable.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"shortcuts": [
|
||||||
|
{
|
||||||
|
"name": "Dashboard",
|
||||||
|
"short_name": "Dashboard",
|
||||||
|
"url": "/dashboard.html?source=pwa",
|
||||||
|
"icons": [
|
||||||
|
{ "src": "/assets/icons/icon-192.png", "sizes": "192x192", "type": "image/png" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Incidenti Art.23",
|
||||||
|
"short_name": "Incidenti",
|
||||||
|
"url": "/incidents.html?source=pwa",
|
||||||
|
"icons": [
|
||||||
|
{ "src": "/assets/icons/icon-192.png", "sizes": "192x192", "type": "image/png" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>NIS2 Agile — License API · Documentazione Marketing</title>
|
<title>NIS2 Agile — License API · Documentazione Marketing</title>
|
||||||
<link rel="stylesheet" href="css/style.css?v=20260613b">
|
<link rel="stylesheet" href="css/style.css?v=20260613b">
|
||||||
<style>
|
<style>
|
||||||
@@ -81,6 +81,19 @@ table.resp code { background: rgba(255,255,255,.06); padding: .1rem .3rem; borde
|
|||||||
.sc-ro { background: rgba(34,197,94,.15); color: #22c55e; }
|
.sc-ro { background: rgba(34,197,94,.15); color: #22c55e; }
|
||||||
.sc-no { background: rgba(156,163,175,.15); color: #9ca3af; }
|
.sc-no { background: rgba(156,163,175,.15); color: #9ca3af; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="doc-layout">
|
<div class="doc-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Aggiornamenti Normativi (BI) - NIS2 Agile</title>
|
<title>Aggiornamenti Normativi (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -27,6 +27,19 @@
|
|||||||
.ack-progress { height: 6px; background: var(--gray-200); border-radius: 3px; overflow: hidden; }
|
.ack-progress { height: 6px; background: var(--gray-200); border-radius: 3px; overflow: hidden; }
|
||||||
.ack-progress-bar { height: 100%; background: var(--primary); border-radius: 3px; transition: width 0.5s ease; }
|
.ack-progress-bar { height: 100%; background: var(--primary); border-radius: 3px; transition: width 0.5s ease; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Aggiornamenti Normativi - NIS2 Agile</title>
|
<title>Aggiornamenti Normativi - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -27,6 +27,19 @@
|
|||||||
.ack-progress { height: 6px; background: var(--gray-200); border-radius: 3px; overflow: hidden; }
|
.ack-progress { height: 6px; background: var(--gray-200); border-radius: 3px; overflow: hidden; }
|
||||||
.ack-progress-bar { height: 100%; background: var(--primary); border-radius: 3px; transition: width 0.5s ease; }
|
.ack-progress-bar { height: 100%; background: var(--primary); border-radius: 3px; transition: width 0.5s ease; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="it">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<title>Offline - NIS2 Agile</title>
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
|
<style>
|
||||||
|
/* Fallback minimale: la pagina resta leggibile anche se il CSS di
|
||||||
|
Bootstrap Italia non e' presente nella cache. */
|
||||||
|
body { margin: 0; min-height: 100vh; display: flex; align-items: center;
|
||||||
|
justify-content: center; padding: 24px; text-align: center; background: #f5f6f7;
|
||||||
|
color: #1b1c1d; font-family: 'Titillium Web', system-ui, Arial, sans-serif; }
|
||||||
|
.offline-card { max-width: 420px; background: #fff; border-radius: 12px;
|
||||||
|
padding: 32px 28px; box-shadow: 0 4px 24px rgba(0,0,0,.08); }
|
||||||
|
.offline-card img { width: 72px; height: 72px; margin-bottom: 16px; }
|
||||||
|
.offline-card h1 { font-size: 1.4rem; margin: 0 0 8px; color: #0066CC; }
|
||||||
|
.offline-card p { margin: 0 0 24px; color: #5a6772; font-size: 1rem; line-height: 1.5; }
|
||||||
|
.offline-btn { display: inline-block; background: #0066CC; color: #fff; border: 0;
|
||||||
|
border-radius: 8px; padding: 12px 24px; font-size: 1rem; min-height: 44px;
|
||||||
|
cursor: pointer; text-decoration: none; }
|
||||||
|
.offline-btn:hover { background: #0052a3; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main class="offline-card">
|
||||||
|
<img src="/assets/icons/icon-192.png" alt="NIS2 Agile" width="72" height="72">
|
||||||
|
<h1>Sei offline</h1>
|
||||||
|
<p>Controlla la connessione di rete e riprova. Le pagine già visitate restano disponibili anche senza connessione.</p>
|
||||||
|
<button type="button" class="offline-btn" onclick="location.reload()">Riprova</button>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Onboarding - NIS2 Agile</title>
|
<title>Onboarding - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della onboarding.html. -->
|
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della onboarding.html. -->
|
||||||
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
@@ -100,6 +100,19 @@
|
|||||||
.wizard-step-title { font-size: 1.25rem; }
|
.wizard-step-title { font-size: 1.25rem; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="wizard-page">
|
<div class="wizard-page">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Onboarding - NIS2 Agile</title>
|
<title>Onboarding - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della onboarding.html. -->
|
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della onboarding.html. -->
|
||||||
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
@@ -100,6 +100,19 @@
|
|||||||
.wizard-step-title { font-size: 1.25rem; }
|
.wizard-step-title { font-size: 1.25rem; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="wizard-page">
|
<div class="wizard-page">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Policy (BI) - NIS2 Agile</title>
|
<title>Policy (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -239,6 +239,19 @@
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Policy - NIS2 Agile</title>
|
<title>Policy - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -239,6 +239,19 @@
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>NIS2 Agile - Compliance NIS2 AI-Powered | Agile Technology SRL</title>
|
<title>NIS2 Agile - Compliance NIS2 AI-Powered | Agile Technology SRL</title>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||||
<style>
|
<style>
|
||||||
@@ -835,6 +835,19 @@
|
|||||||
.bg-purple { background: var(--purple-dim); }
|
.bg-purple { background: var(--purple-dim); }
|
||||||
.bg-orange { background: var(--orange-dim); }
|
.bg-orange { background: var(--orange-dim); }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Registrazione - NIS2 Agile</title>
|
<title>Registrazione - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della register.html. -->
|
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della register.html. -->
|
||||||
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
@@ -62,6 +62,19 @@
|
|||||||
#step-0 { display: block; }
|
#step-0 { display: block; }
|
||||||
.ico { width: 1em; height: 1em; fill: currentColor; vertical-align: -.125em; }
|
.ico { width: 1em; height: 1em; fill: currentColor; vertical-align: -.125em; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main class="auth-wrap">
|
<main class="auth-wrap">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Registrazione - NIS2 Agile</title>
|
<title>Registrazione - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della register.html. -->
|
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della register.html. -->
|
||||||
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
@@ -62,6 +62,19 @@
|
|||||||
#step-0 { display: block; }
|
#step-0 { display: block; }
|
||||||
.ico { width: 1em; height: 1em; fill: currentColor; vertical-align: -.125em; }
|
.ico { width: 1em; height: 1em; fill: currentColor; vertical-align: -.125em; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main class="auth-wrap">
|
<main class="auth-wrap">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Audit e Report (BI) - NIS2 Agile</title>
|
<title>Audit e Report (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -343,6 +343,19 @@
|
|||||||
.report-summary-grid { grid-template-columns: 1fr 1fr; }
|
.report-summary-grid { grid-template-columns: 1fr 1fr; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Audit e Report - NIS2 Agile</title>
|
<title>Audit e Report - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -343,6 +343,19 @@
|
|||||||
.report-summary-grid { grid-template-columns: 1fr 1fr; }
|
.report-summary-grid { grid-template-columns: 1fr 1fr; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Imposta nuova password - NIS2 Agile</title>
|
<title>Imposta nuova password - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della reset-password.html. -->
|
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della reset-password.html. -->
|
||||||
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
@@ -18,6 +18,19 @@
|
|||||||
.pw-toggle { position: absolute; right: 8px; top: 8px; background: none; border: none; color: #5a6772; cursor: pointer; padding: 6px; }
|
.pw-toggle { position: absolute; right: 8px; top: 8px; background: none; border: none; color: #5a6772; cursor: pointer; padding: 6px; }
|
||||||
.ico { width: 1em; height: 1em; fill: currentColor; vertical-align: -.125em; }
|
.ico { width: 1em; height: 1em; fill: currentColor; vertical-align: -.125em; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main class="auth-wrap">
|
<main class="auth-wrap">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Imposta nuova password - NIS2 Agile</title>
|
<title>Imposta nuova password - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della reset-password.html. -->
|
<!-- Bootstrap Italia v2.18.1 — self-hostato da /vendor (MAI CDN). Variante "-bi" della reset-password.html. -->
|
||||||
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
@@ -18,6 +18,19 @@
|
|||||||
.pw-toggle { position: absolute; right: 8px; top: 8px; background: none; border: none; color: #5a6772; cursor: pointer; padding: 6px; }
|
.pw-toggle { position: absolute; right: 8px; top: 8px; background: none; border: none; color: #5a6772; cursor: pointer; padding: 6px; }
|
||||||
.ico { width: 1em; height: 1em; fill: currentColor; vertical-align: -.125em; }
|
.ico { width: 1em; height: 1em; fill: currentColor; vertical-align: -.125em; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main class="auth-wrap">
|
<main class="auth-wrap">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Gestione Rischi (BI) - NIS2 Agile</title>
|
<title>Gestione Rischi (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -298,6 +298,19 @@
|
|||||||
.filters-bar .form-select { min-width: 100%; }
|
.filters-bar .form-select { min-width: 100%; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Gestione Rischi - NIS2 Agile</title>
|
<title>Gestione Rischi - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -298,6 +298,19 @@
|
|||||||
.filters-bar .form-select { min-width: 100%; }
|
.filters-bar .form-select { min-width: 100%; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Standard Continuita di Servizio (BI) — NIS2 Agile</title>
|
<title>Standard Continuita di Servizio (BI) — NIS2 Agile</title>
|
||||||
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
<style>
|
<style>
|
||||||
@@ -56,6 +56,19 @@
|
|||||||
@media print{body{background:#fff}.page{box-shadow:none}}
|
@media print{body{background:#fff}.page{box-shadow:none}}
|
||||||
@media(max-width:700px){.content,.doc-header,.doc-footer{padding:20px}.layer{grid-template-columns:1fr}.layer-num{border-radius:8px 8px 0 0;padding:8px}.layer-body{border-radius:0 0 8px 8px;border-left:1px solid #eee}}
|
@media(max-width:700px){.content,.doc-header,.doc-footer{padding:20px}.layer{grid-template-columns:1fr}.layer-num{border-radius:8px 8px 0 0;padding:8px}.layer-body{border-radius:0 0 8px 8px;border-left:1px solid #eee}}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="page">
|
<div class="page">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Standard Continuita di Servizio — NIS2 Agile</title>
|
<title>Standard Continuita di Servizio — NIS2 Agile</title>
|
||||||
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||||
<style>
|
<style>
|
||||||
@@ -56,6 +56,19 @@
|
|||||||
@media print{body{background:#fff}.page{box-shadow:none}}
|
@media print{body{background:#fff}.page{box-shadow:none}}
|
||||||
@media(max-width:700px){.content,.doc-header,.doc-footer{padding:20px}.layer{grid-template-columns:1fr}.layer-num{border-radius:8px 8px 0 0;padding:8px}.layer-body{border-radius:0 0 8px 8px;border-left:1px solid #eee}}
|
@media(max-width:700px){.content,.doc-header,.doc-footer{padding:20px}.layer{grid-template-columns:1fr}.layer-num{border-radius:8px 8px 0 0;padding:8px}.layer-body{border-radius:0 0 8px 8px;border-left:1px solid #eee}}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="page">
|
<div class="page">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Impostazioni (BI) - NIS2 Agile</title>
|
<title>Impostazioni (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -196,6 +196,19 @@
|
|||||||
height: 16px;
|
height: 16px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Impostazioni - NIS2 Agile</title>
|
<title>Impostazioni - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -196,6 +196,19 @@
|
|||||||
height: 16px;
|
height: 16px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,9 +2,22 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Configura Organizzazione - NIS2 Agile</title>
|
<title>Configura Organizzazione - NIS2 Agile</title>
|
||||||
<link rel="stylesheet" href="css/style.css?v=20260613b">
|
<link rel="stylesheet" href="css/style.css?v=20260613b">
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Simulazione B2B — NIS2 Agile</title>
|
<title>Simulazione B2B — NIS2 Agile</title>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||||
<style>
|
<style>
|
||||||
@@ -70,6 +70,19 @@
|
|||||||
.done-title{font-size:1rem;font-weight:800;color:var(--primary);margin-bottom:6px}
|
.done-title{font-size:1rem;font-weight:800;color:var(--primary);margin-bottom:6px}
|
||||||
.done-sub{font-size:.82rem;color:#94a3b8}
|
.done-sub{font-size:.82rem;color:#94a3b8}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>NIS2 Agile — Simulazione Demo</title>
|
<title>NIS2 Agile — Simulazione Demo</title>
|
||||||
<style>
|
<style>
|
||||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
@@ -134,6 +134,19 @@
|
|||||||
|
|
||||||
@media (max-width: 768px) { .container { grid-template-columns: 1fr; } }
|
@media (max-width: 768px) { .container { grid-template-columns: 1fr; } }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<meta name="robots" content="noindex,nofollow">
|
<meta name="robots" content="noindex,nofollow">
|
||||||
<title>Questionario di Sicurezza Fornitore — NIS2 Agile</title>
|
<title>Questionario di Sicurezza Fornitore — NIS2 Agile</title>
|
||||||
<style>
|
<style>
|
||||||
@@ -34,6 +34,19 @@
|
|||||||
@keyframes spin { to { transform:rotate(360deg); } }
|
@keyframes spin { to { transform:rotate(360deg); } }
|
||||||
.foot { text-align:center; color:var(--muted); font-size:.75rem; margin-top:24px; }
|
.foot { text-align:center; color:var(--muted); font-size:.75rem; margin-top:24px; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<meta name="robots" content="noindex,nofollow">
|
<meta name="robots" content="noindex,nofollow">
|
||||||
<title>Portale Fornitori - NIS2 Agile</title>
|
<title>Portale Fornitori - NIS2 Agile</title>
|
||||||
<style>
|
<style>
|
||||||
@@ -55,6 +55,19 @@ textarea{min-height:88px;resize:vertical}
|
|||||||
.save-state{font-size:.78rem;color:var(--gray-400);text-align:right;min-height:18px}
|
.save-state{font-size:.78rem;color:var(--gray-400);text-align:right;min-height:18px}
|
||||||
.foot{text-align:center;font-size:.72rem;color:var(--gray-400);margin-top:20px;line-height:1.5}
|
.foot{text-align:center;font-size:.72rem;color:var(--gray-400);margin-top:20px;line-height:1.5}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Supply Chain (BI) - NIS2 Agile</title>
|
<title>Supply Chain (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -365,6 +365,19 @@
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Supply Chain - NIS2 Agile</title>
|
<title>Supply Chain - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -365,6 +365,19 @@
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* NIS2 Agile — Service Worker (PWA)
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
* Strategia (SaaS autenticato multi-tenant — sicurezza prima di tutto):
|
||||||
|
* - /api/* -> NETWORK-ONLY, MAI in cache. Nessun dato autenticato
|
||||||
|
* viene cacheato => zero leak cross-utente su un
|
||||||
|
* dispositivo condiviso. La sessione resta gestita da
|
||||||
|
* JWT / auth-gate.js, fuori dal service worker.
|
||||||
|
* - navigazioni HTML -> NETWORK-FIRST, fallback alla cache e infine /offline.html.
|
||||||
|
* - asset statici -> STALE-WHILE-REVALIDATE (risposta immediata dalla cache,
|
||||||
|
* aggiornamento in background).
|
||||||
|
*
|
||||||
|
* Il nome cache include la release: va BUMPATO ad ogni rilascio (vedi version.json),
|
||||||
|
* cosi' activate elimina automaticamente la shell vecchia.
|
||||||
|
*/
|
||||||
|
const CACHE = 'nis2-shell-v1.15.0';
|
||||||
|
|
||||||
|
const PRECACHE = [
|
||||||
|
'/offline.html',
|
||||||
|
'/manifest.webmanifest',
|
||||||
|
'/css/style.css',
|
||||||
|
'/js/common.js',
|
||||||
|
'/js/common-bi.js',
|
||||||
|
'/js/api.js',
|
||||||
|
'/js/i18n.js',
|
||||||
|
'/js/pwa.js',
|
||||||
|
'/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css',
|
||||||
|
'/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js',
|
||||||
|
'/vendor/bootstrap-italia/dist/svg/sprites.svg',
|
||||||
|
'/assets/icons/icon-192.png',
|
||||||
|
'/assets/icons/icon-512.png'
|
||||||
|
];
|
||||||
|
|
||||||
|
self.addEventListener('install', (event) => {
|
||||||
|
event.waitUntil((async () => {
|
||||||
|
const cache = await caches.open(CACHE);
|
||||||
|
// add uno-a-uno: un singolo asset mancante non deve far fallire l'install
|
||||||
|
await Promise.all(PRECACHE.map((url) =>
|
||||||
|
cache.add(new Request(url, { cache: 'reload' })).catch((err) =>
|
||||||
|
console.warn('[sw] precache skip', url, err && err.message))
|
||||||
|
));
|
||||||
|
await self.skipWaiting();
|
||||||
|
})());
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('activate', (event) => {
|
||||||
|
event.waitUntil((async () => {
|
||||||
|
const keys = await caches.keys();
|
||||||
|
await Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k)));
|
||||||
|
await self.clients.claim();
|
||||||
|
})());
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('fetch', (event) => {
|
||||||
|
const req = event.request;
|
||||||
|
if (req.method !== 'GET') return; // non-GET: rete normale
|
||||||
|
const url = new URL(req.url);
|
||||||
|
if (url.origin !== self.location.origin) return; // cross-origin: rete normale
|
||||||
|
|
||||||
|
// /api/* -> network-only, mai in cache
|
||||||
|
if (url.pathname.startsWith('/api/')) {
|
||||||
|
event.respondWith(
|
||||||
|
fetch(req).catch(() => new Response(
|
||||||
|
JSON.stringify({ error: 'offline', message: 'Connessione di rete assente' }),
|
||||||
|
{ status: 503, headers: { 'Content-Type': 'application/json' } }
|
||||||
|
))
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// navigazioni HTML -> network-first, fallback cache -> offline
|
||||||
|
if (req.mode === 'navigate') {
|
||||||
|
event.respondWith((async () => {
|
||||||
|
try {
|
||||||
|
return await fetch(req);
|
||||||
|
} catch (e) {
|
||||||
|
const cached = await caches.match(req);
|
||||||
|
return cached || (await caches.match('/offline.html'));
|
||||||
|
}
|
||||||
|
})());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// asset statici stesso-origin -> stale-while-revalidate
|
||||||
|
event.respondWith((async () => {
|
||||||
|
const cache = await caches.open(CACHE);
|
||||||
|
const cached = await cache.match(req);
|
||||||
|
const network = fetch(req).then((res) => {
|
||||||
|
if (res && res.status === 200 && res.type === 'basic') {
|
||||||
|
cache.put(req, res.clone());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}).catch(() => null);
|
||||||
|
return cached || (await network) || (await caches.match('/offline.html'));
|
||||||
|
})());
|
||||||
|
});
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Formazione (BI) - NIS2 Agile</title>
|
<title>Formazione (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -221,6 +221,19 @@
|
|||||||
.data-table { font-size: 0.8rem; }
|
.data-table { font-size: 0.8rem; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Formazione - NIS2 Agile</title>
|
<title>Formazione - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di style.css
|
||||||
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
cosi' style.css (design system esistente) resta autorevole per i widget renderizzati
|
||||||
@@ -221,6 +221,19 @@
|
|||||||
.data-table { font-size: 0.8rem; }
|
.data-table { font-size: 0.8rem; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":"1.14.1","build":"2026-06-14-v1.14.1","date":"2026-06-14","changelog":"Help online: rimossa icona FontAwesome residua (fas fa-comment-alt) non piu renderizzata dopo lo swap a Bootstrap Italia V2, nella guida 'Come aprire una segnalazione' (help.js). Cache-buster ?v di help.js -> 20260614 su 35 pagine. Nessuna modifica a dati o schema DB."}
|
{"version":"1.15.0","build":"2026-06-14-v1.15.0","date":"2026-06-14","changelog":"PWA installabile (Android/iOS): aggiunti manifest.webmanifest, service worker (offline shell, /api network-only, asset stale-while-revalidate), set icone (192/512 + maskable + apple-touch + favicon), tag PWA in tutte le pagine HTML. Conformita AGID/WCAG 2.1 AA: zoom e orientamento non bloccati, touch target >=44px, safe-area in modalita standalone. Nessuna modifica a dati o schema DB."}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Segnalazioni Sicurezza (BI) - NIS2 Agile</title>
|
<title>Segnalazioni Sicurezza (BI) - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di
|
||||||
style.css cosi' il design system esistente resta autorevole per i widget
|
style.css cosi' il design system esistente resta autorevole per i widget
|
||||||
@@ -30,6 +30,19 @@
|
|||||||
/* Icone sprite BI dimensionate inline per i bottoni azione */
|
/* Icone sprite BI dimensionate inline per i bottoni azione */
|
||||||
.icon-inline { width: 16px; height: 16px; fill: currentColor; vertical-align: text-bottom; }
|
.icon-inline { width: 16px; height: 16px; fill: currentColor; vertical-align: text-bottom; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Segnalazioni Sicurezza - NIS2 Agile</title>
|
<title>Segnalazioni Sicurezza - NIS2 Agile</title>
|
||||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di
|
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN). Caricato PRIMA di
|
||||||
style.css cosi' il design system esistente resta autorevole per i widget
|
style.css cosi' il design system esistente resta autorevole per i widget
|
||||||
@@ -30,6 +30,19 @@
|
|||||||
/* Icone sprite BI dimensionate inline per i bottoni azione */
|
/* Icone sprite BI dimensionate inline per i bottoni azione */
|
||||||
.icon-inline { width: 16px; height: 16px; fill: currentColor; vertical-align: text-bottom; }
|
.icon-inline { width: 16px; height: 16px; fill: currentColor; vertical-align: text-bottom; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="it">
|
<html lang="it">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>Compliance Journey - NIS2 Agile</title>
|
<title>Compliance Journey - NIS2 Agile</title>
|
||||||
<link rel="stylesheet" href="css/style.css?v=20260613b">
|
<link rel="stylesheet" href="css/style.css?v=20260613b">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||||
@@ -285,6 +285,19 @@
|
|||||||
.journey-header { flex-direction: column; }
|
.journey-header { flex-direction: column; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- PWA:start -->
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
<meta name="theme-color" content="#0066CC">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
|
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||||
|
<meta name="application-name" content="NIS2 Agile">
|
||||||
|
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||||
|
<!-- PWA:end -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
|||||||
@@ -0,0 +1,487 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* gen-pwa-icons.mjs — NIS2 Agile PWA icon generator (dependency-free)
|
||||||
|
*
|
||||||
|
* Generates the full PWA icon set using ONLY Node v20 built-ins:
|
||||||
|
* - node:zlib (deflate for PNG IDAT)
|
||||||
|
* - node:fs (write files)
|
||||||
|
* - node:path (resolve paths)
|
||||||
|
*
|
||||||
|
* Design: Italy-blue (#0066CC) square tile, centered white shield
|
||||||
|
* (compliance/security silhouette) with a bold "negative" check mark
|
||||||
|
* cut out of the shield (rendered in #0066CC) so it stays readable
|
||||||
|
* down to 16px.
|
||||||
|
*
|
||||||
|
* Rendering: each icon is drawn at 4x (supersampling) into an RGBA
|
||||||
|
* buffer using hand-written primitives (rounded rect, scanline polygon
|
||||||
|
* fill), then box-downsampled to final size for smooth anti-aliased
|
||||||
|
* edges. PNG is encoded manually (8-bit, color type 6 RGBA).
|
||||||
|
*
|
||||||
|
* Run: cd /projects/nis2-agile && node scripts/gen-pwa-icons.mjs
|
||||||
|
*/
|
||||||
|
|
||||||
|
import zlib from 'node:zlib';
|
||||||
|
import fs from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Paths
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = path.dirname(__filename);
|
||||||
|
const PROJECT_ROOT = path.resolve(__dirname, '..');
|
||||||
|
const ICONS_DIR = path.join(PROJECT_ROOT, 'public', 'assets', 'icons');
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Palette
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
const BLUE = [0, 102, 204]; // #0066CC — Italy blue
|
||||||
|
const WHITE = [255, 255, 255];
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// RGBA canvas helpers
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
function makeCanvas(w, h, fill) {
|
||||||
|
// fill = [r,g,b,a] or null => transparent (0,0,0,0)
|
||||||
|
const buf = new Uint8Array(w * h * 4);
|
||||||
|
if (fill) {
|
||||||
|
for (let i = 0; i < w * h; i++) {
|
||||||
|
const o = i * 4;
|
||||||
|
buf[o] = fill[0];
|
||||||
|
buf[o + 1] = fill[1];
|
||||||
|
buf[o + 2] = fill[2];
|
||||||
|
buf[o + 3] = fill[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { w, h, buf };
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPx(cv, x, y, rgba) {
|
||||||
|
if (x < 0 || y < 0 || x >= cv.w || y >= cv.h) return;
|
||||||
|
const o = (y * cv.w + x) * 4;
|
||||||
|
cv.buf[o] = rgba[0];
|
||||||
|
cv.buf[o + 1] = rgba[1];
|
||||||
|
cv.buf[o + 2] = rgba[2];
|
||||||
|
cv.buf[o + 3] = rgba[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill the whole canvas with an OPAQUE color.
|
||||||
|
function fillBackground(cv, rgb) {
|
||||||
|
for (let i = 0; i < cv.w * cv.h; i++) {
|
||||||
|
const o = i * 4;
|
||||||
|
cv.buf[o] = rgb[0];
|
||||||
|
cv.buf[o + 1] = rgb[1];
|
||||||
|
cv.buf[o + 2] = rgb[2];
|
||||||
|
cv.buf[o + 3] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filled rounded rectangle (opaque). r = corner radius in px (canvas space).
|
||||||
|
function fillRoundedRect(cv, x0, y0, x1, y1, r, rgb, alpha = 255) {
|
||||||
|
const minX = Math.max(0, Math.floor(x0));
|
||||||
|
const minY = Math.max(0, Math.floor(y0));
|
||||||
|
const maxX = Math.min(cv.w - 1, Math.ceil(x1));
|
||||||
|
const maxY = Math.min(cv.h - 1, Math.ceil(y1));
|
||||||
|
const rr = r * r;
|
||||||
|
for (let y = minY; y <= maxY; y++) {
|
||||||
|
for (let x = minX; x <= maxX; x++) {
|
||||||
|
const px = x + 0.5;
|
||||||
|
const py = y + 0.5;
|
||||||
|
let inside = true;
|
||||||
|
// corner clipping
|
||||||
|
if (px < x0 + r && py < y0 + r) {
|
||||||
|
const dx = px - (x0 + r), dy = py - (y0 + r);
|
||||||
|
inside = dx * dx + dy * dy <= rr;
|
||||||
|
} else if (px > x1 - r && py < y0 + r) {
|
||||||
|
const dx = px - (x1 - r), dy = py - (y0 + r);
|
||||||
|
inside = dx * dx + dy * dy <= rr;
|
||||||
|
} else if (px < x0 + r && py > y1 - r) {
|
||||||
|
const dx = px - (x0 + r), dy = py - (y1 - r);
|
||||||
|
inside = dx * dx + dy * dy <= rr;
|
||||||
|
} else if (px > x1 - r && py > y1 - r) {
|
||||||
|
const dx = px - (x1 - r), dy = py - (y1 - r);
|
||||||
|
inside = dx * dx + dy * dy <= rr;
|
||||||
|
}
|
||||||
|
if (inside) setPx(cv, x, y, [rgb[0], rgb[1], rgb[2], alpha]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scanline polygon fill. pts = [[x,y],...] in canvas space. Even-odd rule.
|
||||||
|
function fillPolygon(cv, pts, rgb, alpha = 255) {
|
||||||
|
let minY = Infinity, maxY = -Infinity;
|
||||||
|
for (const p of pts) {
|
||||||
|
if (p[1] < minY) minY = p[1];
|
||||||
|
if (p[1] > maxY) maxY = p[1];
|
||||||
|
}
|
||||||
|
minY = Math.max(0, Math.floor(minY));
|
||||||
|
maxY = Math.min(cv.h - 1, Math.ceil(maxY));
|
||||||
|
const n = pts.length;
|
||||||
|
for (let y = minY; y <= maxY; y++) {
|
||||||
|
const yc = y + 0.5;
|
||||||
|
const xs = [];
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
const a = pts[i];
|
||||||
|
const b = pts[(i + 1) % n];
|
||||||
|
const ay = a[1], by = b[1];
|
||||||
|
if ((ay <= yc && by > yc) || (by <= yc && ay > yc)) {
|
||||||
|
const t = (yc - ay) / (by - ay);
|
||||||
|
xs.push(a[0] + t * (b[0] - a[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xs.sort((p, q) => p - q);
|
||||||
|
for (let i = 0; i + 1 < xs.length; i += 2) {
|
||||||
|
const xStart = Math.max(0, Math.ceil(xs[i] - 0.5));
|
||||||
|
const xEnd = Math.min(cv.w - 1, Math.floor(xs[i + 1] - 0.5));
|
||||||
|
for (let x = xStart; x <= xEnd; x++) setPx(cv, x, y, [rgb[0], rgb[1], rgb[2], alpha]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Shield + check geometry
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// All geometry is expressed in a normalized 0..1 box, then scaled into the
|
||||||
|
// target region (cx,cy = center, half = half-size of the content square).
|
||||||
|
|
||||||
|
// Build shield outline polygon (heraldic shield: flat top, rounded shoulders
|
||||||
|
// approximated by points, tapering to a point at the bottom).
|
||||||
|
function shieldPolygon(cx, cy, half) {
|
||||||
|
// Normalized shield within a square: x in [-0.5,0.5], y in [-0.6,0.6]
|
||||||
|
// top edge slightly inset, sides curve down, bottom comes to a point.
|
||||||
|
const W = half * 0.92; // half width
|
||||||
|
const Htop = -half * 1.02;
|
||||||
|
const pts = [];
|
||||||
|
// Top edge
|
||||||
|
pts.push([cx - W, cy + Htop]);
|
||||||
|
pts.push([cx + W, cy + Htop]);
|
||||||
|
// Right side going down with a gentle inward curve, then to the point.
|
||||||
|
// Approximate the right & bottom with sampled points along a parametric path.
|
||||||
|
const right = [
|
||||||
|
[cx + W, cy + Htop],
|
||||||
|
[cx + W * 0.99, cy - half * 0.35],
|
||||||
|
[cx + W * 0.92, cy + half * 0.05],
|
||||||
|
[cx + W * 0.74, cy + half * 0.45],
|
||||||
|
[cx + W * 0.42, cy + half * 0.85],
|
||||||
|
[cx + 0, cy + half * 1.12], // bottom point
|
||||||
|
];
|
||||||
|
const left = [
|
||||||
|
[cx - W * 0.42, cy + half * 0.85],
|
||||||
|
[cx - W * 0.74, cy + half * 0.45],
|
||||||
|
[cx - W * 0.92, cy + half * 0.05],
|
||||||
|
[cx - W * 0.99, cy - half * 0.35],
|
||||||
|
[cx - W, cy + Htop],
|
||||||
|
];
|
||||||
|
// Compose: top-left -> top-right -> right path -> bottom -> left path
|
||||||
|
const poly = [];
|
||||||
|
poly.push([cx - W, cy + Htop]);
|
||||||
|
poly.push([cx + W, cy + Htop]);
|
||||||
|
for (let i = 1; i < right.length; i++) poly.push(right[i]);
|
||||||
|
for (let i = 0; i < left.length; i++) poly.push(left[i]);
|
||||||
|
return poly;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a bold check-mark polygon (thick stroke as a filled hexagon-ish shape).
|
||||||
|
// Centered roughly in the shield. `s` scales overall size, `t` is stroke thickness.
|
||||||
|
function checkPolygon(cx, cy, s, t) {
|
||||||
|
// Check has a short arm (down-left) and a long arm (up-right).
|
||||||
|
// Define center vertex (bottom of the V), short tip, long tip.
|
||||||
|
const vx = cx - s * 0.10, vy = cy + s * 0.34; // inner corner (bottom)
|
||||||
|
const s1x = cx - s * 0.46, s1y = cy + s * 0.02; // short arm tip
|
||||||
|
const l1x = cx + s * 0.50, l1y = cy - s * 0.42; // long arm tip
|
||||||
|
// Build a thick stroke by offsetting perpendicular to each segment.
|
||||||
|
// Segment A: short tip -> inner corner
|
||||||
|
// Segment B: inner corner -> long tip
|
||||||
|
const half = t / 2;
|
||||||
|
|
||||||
|
function unit(ax, ay, bx, by) {
|
||||||
|
const dx = bx - ax, dy = by - ay;
|
||||||
|
const L = Math.hypot(dx, dy) || 1;
|
||||||
|
return [dx / L, dy / L];
|
||||||
|
}
|
||||||
|
function perp(u) { return [-u[1], u[0]]; }
|
||||||
|
|
||||||
|
const uA = unit(s1x, s1y, vx, vy);
|
||||||
|
const uB = unit(vx, vy, l1x, l1y);
|
||||||
|
const pA = perp(uA);
|
||||||
|
const pB = perp(uB);
|
||||||
|
|
||||||
|
// Outer & inner offsets for each arm; assemble as a single polygon outline.
|
||||||
|
// Order: short tip outer -> corner outer -> long tip outer -> long tip inner
|
||||||
|
// -> corner inner -> short tip inner
|
||||||
|
const poly = [
|
||||||
|
[s1x + pA[0] * half, s1y + pA[1] * half], // short tip outer
|
||||||
|
[vx + pA[0] * half, vy + pA[1] * half], // corner outer (A side)
|
||||||
|
[vx + pB[0] * half, vy + pB[1] * half], // corner outer (B side)
|
||||||
|
[l1x + pB[0] * half, l1y + pB[1] * half], // long tip outer
|
||||||
|
[l1x - pB[0] * half, l1y - pB[1] * half], // long tip inner
|
||||||
|
[vx - pB[0] * half, vy - pB[1] * half], // corner inner (B side)
|
||||||
|
[vx - pA[0] * half, vy - pA[1] * half], // corner inner (A side)
|
||||||
|
[s1x - pA[0] * half, s1y - pA[1] * half], // short tip inner
|
||||||
|
];
|
||||||
|
return poly;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Draw the NIS2 emblem (shield + check) into a canvas region.
|
||||||
|
// cx,cy: center; half: half content size; simplified: bolder geometry for tiny sizes
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
function drawEmblem(cv, cx, cy, half, simplified = false) {
|
||||||
|
// White shield
|
||||||
|
const shield = shieldPolygon(cx, cy, half);
|
||||||
|
fillPolygon(cv, shield, WHITE, 255);
|
||||||
|
|
||||||
|
// Negative blue check inside the shield.
|
||||||
|
const checkScale = half * (simplified ? 1.18 : 1.05);
|
||||||
|
const stroke = half * (simplified ? 0.32 : 0.24);
|
||||||
|
const check = checkPolygon(cx, cy - half * 0.02, checkScale, stroke);
|
||||||
|
fillPolygon(cv, check, BLUE, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Box downsample (supersampled -> final). factor must divide dimensions.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
function downsample(cv, factor) {
|
||||||
|
const W = cv.w / factor;
|
||||||
|
const H = cv.h / factor;
|
||||||
|
const out = makeCanvas(W, H, null);
|
||||||
|
const f2 = factor * factor;
|
||||||
|
for (let y = 0; y < H; y++) {
|
||||||
|
for (let x = 0; x < W; x++) {
|
||||||
|
let r = 0, g = 0, b = 0, a = 0;
|
||||||
|
for (let sy = 0; sy < factor; sy++) {
|
||||||
|
for (let sx = 0; sx < factor; sx++) {
|
||||||
|
const o = ((y * factor + sy) * cv.w + (x * factor + sx)) * 4;
|
||||||
|
const sa = cv.buf[o + 3];
|
||||||
|
// premultiply for correct edge blending
|
||||||
|
r += cv.buf[o] * sa;
|
||||||
|
g += cv.buf[o + 1] * sa;
|
||||||
|
b += cv.buf[o + 2] * sa;
|
||||||
|
a += sa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const oo = (y * W + x) * 4;
|
||||||
|
if (a === 0) {
|
||||||
|
out.buf[oo] = 0; out.buf[oo + 1] = 0; out.buf[oo + 2] = 0; out.buf[oo + 3] = 0;
|
||||||
|
} else {
|
||||||
|
out.buf[oo] = Math.round(r / a);
|
||||||
|
out.buf[oo + 1] = Math.round(g / a);
|
||||||
|
out.buf[oo + 2] = Math.round(b / a);
|
||||||
|
out.buf[oo + 3] = Math.round(a / f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// PNG encoding (manual, 8-bit RGBA, color type 6)
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
const PNG_SIG = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
|
||||||
|
|
||||||
|
// CRC32 (standard polynomial 0xEDB88320)
|
||||||
|
const CRC_TABLE = (() => {
|
||||||
|
const t = new Uint32Array(256);
|
||||||
|
for (let n = 0; n < 256; n++) {
|
||||||
|
let c = n;
|
||||||
|
for (let k = 0; k < 8; k++) {
|
||||||
|
c = (c & 1) ? (0xedb88320 ^ (c >>> 1)) : (c >>> 1);
|
||||||
|
}
|
||||||
|
t[n] = c >>> 0;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
})();
|
||||||
|
|
||||||
|
function crc32(buf) {
|
||||||
|
let c = 0xffffffff;
|
||||||
|
for (let i = 0; i < buf.length; i++) {
|
||||||
|
c = CRC_TABLE[(c ^ buf[i]) & 0xff] ^ (c >>> 8);
|
||||||
|
}
|
||||||
|
return (c ^ 0xffffffff) >>> 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function chunk(type, data) {
|
||||||
|
const len = Buffer.alloc(4);
|
||||||
|
len.writeUInt32BE(data.length, 0);
|
||||||
|
const typeBuf = Buffer.from(type, 'ascii');
|
||||||
|
const body = Buffer.concat([typeBuf, data]);
|
||||||
|
const crc = Buffer.alloc(4);
|
||||||
|
crc.writeUInt32BE(crc32(body), 0);
|
||||||
|
return Buffer.concat([len, body, crc]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function encodePNG(cv) {
|
||||||
|
const { w, h, buf } = cv;
|
||||||
|
// IHDR
|
||||||
|
const ihdr = Buffer.alloc(13);
|
||||||
|
ihdr.writeUInt32BE(w, 0);
|
||||||
|
ihdr.writeUInt32BE(h, 4);
|
||||||
|
ihdr[8] = 8; // bit depth
|
||||||
|
ihdr[9] = 6; // color type RGBA
|
||||||
|
ihdr[10] = 0; // compression
|
||||||
|
ihdr[11] = 0; // filter
|
||||||
|
ihdr[12] = 0; // interlace
|
||||||
|
|
||||||
|
// Filtered raw data: each scanline prefixed with filter byte 0
|
||||||
|
const stride = w * 4;
|
||||||
|
const raw = Buffer.alloc((stride + 1) * h);
|
||||||
|
for (let y = 0; y < h; y++) {
|
||||||
|
raw[y * (stride + 1)] = 0; // filter: none
|
||||||
|
buf.subarray(y * stride, y * stride + stride)
|
||||||
|
.forEach ? null : null; // (Uint8Array subarray copy below)
|
||||||
|
const srcStart = y * stride;
|
||||||
|
raw.set(buf.subarray(srcStart, srcStart + stride), y * (stride + 1) + 1);
|
||||||
|
}
|
||||||
|
const idat = zlib.deflateSync(raw, { level: 9 });
|
||||||
|
|
||||||
|
return Buffer.concat([
|
||||||
|
PNG_SIG,
|
||||||
|
chunk('IHDR', ihdr),
|
||||||
|
chunk('IDAT', idat),
|
||||||
|
chunk('IEND', Buffer.alloc(0)),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Icon builders
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
const SS = 4; // supersampling factor
|
||||||
|
|
||||||
|
// Standard (rounded tile) icon: transparent corners, rounded blue tile,
|
||||||
|
// margin ~8%, centered emblem.
|
||||||
|
function buildStandard(size, simplified = false) {
|
||||||
|
const W = size * SS;
|
||||||
|
const cv = makeCanvas(W, W, null); // transparent background
|
||||||
|
const margin = W * 0.08;
|
||||||
|
const radius = W * 0.18;
|
||||||
|
fillRoundedRect(cv, margin, margin, W - margin, W - margin, radius, BLUE, 255);
|
||||||
|
const cx = W / 2, cy = W / 2;
|
||||||
|
// emblem content sized to ~ inner tile
|
||||||
|
const half = (W - 2 * margin) * 0.30;
|
||||||
|
drawEmblem(cv, cx, cy, half, simplified);
|
||||||
|
return downsample(cv, SS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maskable icon: FULL-BLEED blue, square corners, emblem inside the central
|
||||||
|
// 80% safe-zone.
|
||||||
|
function buildMaskable(size) {
|
||||||
|
const W = size * SS;
|
||||||
|
const cv = makeCanvas(W, W, null);
|
||||||
|
fillBackground(cv, BLUE); // full bleed, opaque
|
||||||
|
const cx = W / 2, cy = W / 2;
|
||||||
|
// safe zone is central 80% => content sized so it stays inside 0.8*W box
|
||||||
|
const half = W * 0.5 * 0.80 * 0.62; // ~31% of half-canvas
|
||||||
|
drawEmblem(cv, cx, cy, half, false);
|
||||||
|
return downsample(cv, SS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apple touch icon: fully OPAQUE blue background, square corners, emblem.
|
||||||
|
function buildAppleTouch(size) {
|
||||||
|
const W = size * SS;
|
||||||
|
const cv = makeCanvas(W, W, null);
|
||||||
|
fillBackground(cv, BLUE); // opaque, no transparency
|
||||||
|
const cx = W / 2, cy = W / 2;
|
||||||
|
const half = W * 0.30;
|
||||||
|
drawEmblem(cv, cx, cy, half, false);
|
||||||
|
return downsample(cv, SS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Favicon: rounded blue tile + bolder simplified emblem for legibility.
|
||||||
|
function buildFavicon(size) {
|
||||||
|
const W = size * SS;
|
||||||
|
const cv = makeCanvas(W, W, null);
|
||||||
|
const margin = W * 0.04;
|
||||||
|
const radius = W * 0.18;
|
||||||
|
fillRoundedRect(cv, margin, margin, W - margin, W - margin, radius, BLUE, 255);
|
||||||
|
const cx = W / 2, cy = W / 2;
|
||||||
|
const half = W * 0.34;
|
||||||
|
drawEmblem(cv, cx, cy, half, true); // simplified/bolder
|
||||||
|
return downsample(cv, SS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// SVG master (same design, vector)
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
function buildSVG() {
|
||||||
|
// Express the same geometry in a 512 viewBox.
|
||||||
|
const cx = 256, cy = 256, half = 512 * 0.30; // 153.6
|
||||||
|
const shield = shieldPolygon(cx, cy, half)
|
||||||
|
.map(p => `${p[0].toFixed(1)},${p[1].toFixed(1)}`).join(' ');
|
||||||
|
const check = checkPolygon(cx, cy - half * 0.02, half * 1.05, half * 0.24)
|
||||||
|
.map(p => `${p[0].toFixed(1)},${p[1].toFixed(1)}`).join(' ');
|
||||||
|
const margin = 512 * 0.08;
|
||||||
|
const r = 512 * 0.18;
|
||||||
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512" role="img" aria-label="NIS2 Agile">
|
||||||
|
<title>NIS2 Agile</title>
|
||||||
|
<!-- Italy-blue rounded tile -->
|
||||||
|
<rect x="${margin}" y="${margin}" width="${512 - 2 * margin}" height="${512 - 2 * margin}" rx="${r}" ry="${r}" fill="#0066CC"/>
|
||||||
|
<!-- White shield -->
|
||||||
|
<polygon points="${shield}" fill="#FFFFFF"/>
|
||||||
|
<!-- Negative blue check -->
|
||||||
|
<polygon points="${check}" fill="#0066CC"/>
|
||||||
|
</svg>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Main
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
function main() {
|
||||||
|
fs.mkdirSync(ICONS_DIR, { recursive: true });
|
||||||
|
|
||||||
|
const outputs = [];
|
||||||
|
|
||||||
|
function write(name, cv) {
|
||||||
|
const png = encodePNG(cv);
|
||||||
|
const fp = path.join(ICONS_DIR, name);
|
||||||
|
fs.writeFileSync(fp, png);
|
||||||
|
outputs.push({ name, bytes: png.length, w: cv.w, h: cv.h });
|
||||||
|
}
|
||||||
|
|
||||||
|
write('icon-192.png', buildStandard(192));
|
||||||
|
write('icon-512.png', buildStandard(512));
|
||||||
|
write('icon-192-maskable.png', buildMaskable(192));
|
||||||
|
write('icon-512-maskable.png', buildMaskable(512));
|
||||||
|
write('apple-touch-icon.png', buildAppleTouch(180));
|
||||||
|
write('favicon-32.png', buildFavicon(32));
|
||||||
|
write('favicon-16.png', buildFavicon(16));
|
||||||
|
|
||||||
|
// SVG master
|
||||||
|
const svg = buildSVG();
|
||||||
|
fs.writeFileSync(path.join(ICONS_DIR, 'icon.svg'), svg);
|
||||||
|
|
||||||
|
// ---- Validation: re-read each PNG, verify signature + IHDR dims ----
|
||||||
|
console.log('\n=== NIS2 PWA Icon Generation ===');
|
||||||
|
console.log('Output dir:', ICONS_DIR);
|
||||||
|
console.log('\nFile | Bytes | Declared | Read(IHDR) | SIG');
|
||||||
|
console.log('---------------------------|--------|----------|------------|----');
|
||||||
|
|
||||||
|
let allOk = true;
|
||||||
|
for (const o of outputs) {
|
||||||
|
const data = fs.readFileSync(path.join(ICONS_DIR, o.name));
|
||||||
|
const sigOk =
|
||||||
|
data.length >= 8 &&
|
||||||
|
data[0] === 0x89 && data[1] === 0x50 && data[2] === 0x4e && data[3] === 0x47 &&
|
||||||
|
data[4] === 0x0d && data[5] === 0x0a && data[6] === 0x1a && data[7] === 0x0a;
|
||||||
|
// IHDR starts at byte 16 (8 sig + 4 len + 4 'IHDR'); width@16, height@20
|
||||||
|
const rw = data.readUInt32BE(16);
|
||||||
|
const rh = data.readUInt32BE(20);
|
||||||
|
const nonEmpty = data.length > 0;
|
||||||
|
const ok = sigOk && nonEmpty && rw === o.w && rh === o.h;
|
||||||
|
if (!ok) allOk = false;
|
||||||
|
console.log(
|
||||||
|
`${o.name.padEnd(26)} | ${String(o.bytes).padStart(6)} | ${(o.w + 'x' + o.h).padStart(8)} | ${(rw + 'x' + rh).padStart(10)} | ${ok ? 'OK' : 'KO'}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SVG report
|
||||||
|
const svgStat = fs.statSync(path.join(ICONS_DIR, 'icon.svg'));
|
||||||
|
console.log(`${'icon.svg'.padEnd(26)} | ${String(svgStat.size).padStart(6)} | ${'vector'.padStart(8)} | ${'-'.padStart(10)} | ${svgStat.size > 0 ? 'OK' : 'KO'}`);
|
||||||
|
|
||||||
|
console.log('\nValidation:', allOk ? 'ALL PNG OK' : 'FAILURES PRESENT');
|
||||||
|
if (!allOk) process.exitCode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/*
|
||||||
|
* Inietta i tag PWA negli <head> di tutte le pagine HTML sotto public/.
|
||||||
|
* Idempotente: salta i file che contengono gia' il marker <!-- PWA:start -->.
|
||||||
|
* Normalizza il viewport mantenendo lo zoom abilitato (WCAG 1.4.4 / AGID).
|
||||||
|
* Esegue solo modifiche additive e mirate; tutto e' git-tracked => reversibile.
|
||||||
|
*
|
||||||
|
* Uso: node scripts/inject-pwa-head.mjs
|
||||||
|
*/
|
||||||
|
import fs from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
|
const ROOT = path.resolve(process.cwd(), 'public');
|
||||||
|
const EXCLUDE_BASENAMES = new Set(['offline.html']);
|
||||||
|
const MARKER = '<!-- PWA:start -->';
|
||||||
|
const VIEWPORT = '<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">';
|
||||||
|
|
||||||
|
const BLOCK = [
|
||||||
|
' <!-- PWA:start -->',
|
||||||
|
' <link rel="manifest" href="/manifest.webmanifest">',
|
||||||
|
' <meta name="theme-color" content="#0066CC">',
|
||||||
|
' <link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">',
|
||||||
|
' <link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">',
|
||||||
|
' <link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">',
|
||||||
|
' <meta name="apple-mobile-web-app-capable" content="yes">',
|
||||||
|
' <meta name="mobile-web-app-capable" content="yes">',
|
||||||
|
' <meta name="apple-mobile-web-app-status-bar-style" content="default">',
|
||||||
|
' <meta name="apple-mobile-web-app-title" content="NIS2 Agile">',
|
||||||
|
' <meta name="application-name" content="NIS2 Agile">',
|
||||||
|
' <script src="/js/pwa.js?v=20260614" defer></script>',
|
||||||
|
' <!-- PWA:end -->'
|
||||||
|
].join('\n');
|
||||||
|
|
||||||
|
function walk(dir) {
|
||||||
|
let out = [];
|
||||||
|
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
const full = path.join(dir, e.name);
|
||||||
|
if (e.isDirectory()) out = out.concat(walk(full));
|
||||||
|
else if (e.isFile() && e.name.toLowerCase().endsWith('.html')) out.push(full);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
const files = walk(ROOT).filter((f) => {
|
||||||
|
const b = path.basename(f);
|
||||||
|
if (EXCLUDE_BASENAMES.has(b)) return false;
|
||||||
|
if (/copy/i.test(b)) return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
let modified = 0, already = 0, nohead = 0, viewportFixed = 0;
|
||||||
|
const anomalies = [];
|
||||||
|
|
||||||
|
for (const f of files) {
|
||||||
|
let html = fs.readFileSync(f, 'utf8');
|
||||||
|
if (html.includes(MARKER)) { already++; continue; }
|
||||||
|
|
||||||
|
if (!/<\/head>/i.test(html)) {
|
||||||
|
nohead++;
|
||||||
|
anomalies.push('NO </head>: ' + path.relative(process.cwd(), f));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalizza il viewport (zoom SEMPRE consentito: no user-scalable=no / maximum-scale)
|
||||||
|
const vp = html.match(/<meta\s+name=["']viewport["'][^>]*>/i);
|
||||||
|
if (vp) {
|
||||||
|
if (!/viewport-fit=cover/i.test(vp[0])) {
|
||||||
|
html = html.replace(vp[0], VIEWPORT);
|
||||||
|
viewportFixed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const inject = (vp ? '' : (' ' + VIEWPORT + '\n')) + BLOCK + '\n';
|
||||||
|
// replace con funzione per evitare interpretazione di pattern '$' nel testo iniettato
|
||||||
|
html = html.replace(/<\/head>/i, () => inject + '</head>');
|
||||||
|
fs.writeFileSync(f, html);
|
||||||
|
modified++;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('HTML trovati:', files.length);
|
||||||
|
console.log('Modificati:', modified, '| gia col marker:', already,
|
||||||
|
'| senza </head>:', nohead, '| viewport normalizzati:', viewportFixed);
|
||||||
|
if (anomalies.length) {
|
||||||
|
console.log('Anomalie:');
|
||||||
|
anomalies.forEach((a) => console.log(' -', a));
|
||||||
|
}
|
||||||