Files
DevEnv nis2-agileandClaude Opus 4.8 d16fdd2c02 [DEMO] Frontend demo-mode (punto 4): demo-mode.js + demo-selectors.js + demo.css + hook ?demo=
Avatar di prodotto, product-demo-protocol v1.0.1 (NIS2 multi-page):
- public/js/demo-mode.js: runtime canale postMessage (inbound navigate/highlight/scroll_to/
  trigger_action/open_tab/...; outbound ready/spa_state_changed/step_animation_done/...),
  verifica origin+HMAC (chiave SHA-256(jwt:seed:demo-control-channel))+idempotency, banner read-only.
- public/js/demo-selectors.js: whitelist 17 viste (view->url) + azioni read-only sicure.
- public/css/demo.css: highlight pulse-blue/halo + banner.
- common-bi.js: hook che inietta gli asset SOLO con ?demo= (no-op per utenti normali).

NOTE: (a) HMAC canonical del MESSAGGIO da riconciliare con AgileHub al collaudo (canonicalize()).
(b) manca il manifest (steps+selettori) — dipende dagli id stabili in corso.
node --check OK su tutti.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 08:56:36 +02:00

36 lines
2.0 KiB
CSS

/* NIS2 Agile — Avatar di prodotto: stili demo-mode (highlight + banner).
Caricato solo in demo-mode (?demo=<session_id>). product-demo-protocol v1.0.1. */
/* Banner "Modalità dimostrazione" */
#nis2-demo-banner {
position: fixed; top: 0; left: 0; right: 0; z-index: 99998;
background: #0066CC; color: #fff; font: 600 13px/1 "Titillium Web", system-ui, sans-serif;
padding: 8px 16px; display: flex; align-items: center; gap: 10px;
box-shadow: 0 2px 8px rgba(0,0,0,.25);
}
#nis2-demo-banner .nis2-demo-dot { width: 8px; height: 8px; border-radius: 50%; background: #7ee787; animation: nis2-demo-pulse 1.4s infinite; }
#nis2-demo-banner .nis2-demo-spacer { flex: 1; }
body.nis2-demo-on { padding-top: 34px; } /* lascia spazio al banner */
/* Overlay highlight (spotlight) — applicato a un elemento target */
.nis2-demo-hl { position: relative; z-index: 99990; }
.nis2-demo-hl.pulse-blue { box-shadow: 0 0 0 3px #0066CC, 0 0 0 9px rgba(0,102,204,.25); border-radius: 6px; animation: nis2-demo-pulse 1.4s ease-in-out infinite; }
.nis2-demo-hl.halo { box-shadow: 0 0 0 3px #f59e0b, 0 0 18px 4px rgba(245,158,11,.45); border-radius: 6px; }
.nis2-demo-hl.outline { outline: 3px solid #0066CC; outline-offset: 2px; border-radius: 6px; }
@keyframes nis2-demo-pulse {
0%,100% { box-shadow: 0 0 0 3px #0066CC, 0 0 0 6px rgba(0,102,204,.30); }
50% { box-shadow: 0 0 0 3px #0066CC, 0 0 0 12px rgba(0,102,204,.06); }
}
/* In demo-mode (read-only) attenua gli elementi di scrittura per chiarezza visiva.
La sicurezza vera è server-side (guard DEMO_READ_ONLY); questo è solo UX. */
body.nis2-demo-readonly [data-demo-action]:not([data-demo-readonly-safe]) { /* azioni non-safe: nessun blocco CSS, solo hook JS */ }
/* Toast errore demo */
#nis2-demo-toast {
position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%); z-index: 99999;
background: #17324d; color: #fff; padding: 10px 16px; border-radius: 8px;
font: 500 13px/1.3 "Titillium Web", system-ui, sans-serif; max-width: 80vw; display: none;
}