[DOCS] UI V3 mockup: estratti index/assessment/calendario + zip (fonte visiva flotta)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
f9baf39599
commit
b2fa1a163e
@@ -0,0 +1,361 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>GAP Analysis · NIS2 Agile</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root{
|
||||
--navy-top:#0A2E54; --navy-nav:#103A61; --navy-hover:#1B4A75; --gold:#F0B429;
|
||||
--bg:#EFF4FA; --card:#FFFFFF; --ink:#15263C; --muted:#64748B; --line:#E3E9F0;
|
||||
--c-green:#1E8A5A; --c-blue:#1F5FA8; --c-amber:#D98324; --c-red:#C62828;
|
||||
--radius:12px; --shadow:0 1px 2px rgba(16,40,80,.06),0 8px 24px rgba(16,40,80,.06);
|
||||
}
|
||||
*{box-sizing:border-box} html{-webkit-text-size-adjust:100%}
|
||||
body{margin:0;background:var(--bg);color:var(--ink);
|
||||
font-family:'Inter',system-ui,-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5}
|
||||
a{color:inherit;text-decoration:none}
|
||||
:focus-visible{outline:2px solid var(--gold);outline-offset:2px;border-radius:4px}
|
||||
.appbar{position:sticky;top:0;z-index:50}
|
||||
.bar-top{background:var(--navy-top);color:#fff}
|
||||
.bar-top-in{max-width:1280px;margin:0 auto;display:flex;align-items:center;gap:16px;padding:10px 24px}
|
||||
.flag{width:18px;height:13px;border-radius:2px;overflow:hidden;display:flex;flex:0 0 auto;box-shadow:0 0 0 1px rgba(255,255,255,.25)}
|
||||
.flag i{flex:1}.flag .g{background:#1f8a4c}.flag .w{background:#fff}.flag .r{background:#cd2b2b}
|
||||
.logo-mark{width:34px;height:34px;border-radius:8px;background:var(--c-green);display:flex;align-items:center;justify-content:center;color:#fff;font-weight:800;font-size:13px;flex:0 0 auto}
|
||||
.brand-txt{line-height:1.1;min-width:0}
|
||||
.brand-txt b{font-size:15px;font-weight:700}
|
||||
.brand-txt span{display:block;font-size:10.5px;color:#A9C2DC;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||
.search{flex:1;max-width:340px;display:flex;align-items:center;gap:8px;background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.16);border-radius:8px;padding:7px 12px;color:#cfe0f1;min-width:120px}
|
||||
.search input{flex:1;border:0;background:transparent;color:#fff;font:inherit;outline:none;min-width:0}
|
||||
.search input::placeholder{color:#9db8d2}
|
||||
.spacer{flex:1}
|
||||
.btn-incident{display:inline-flex;align-items:center;gap:8px;background:#D24545;color:#fff;border:0;border-radius:8px;padding:9px 15px;font:inherit;font-weight:600;font-size:13px;cursor:pointer;box-shadow:0 1px 2px rgba(120,20,20,.35);white-space:nowrap}
|
||||
.btn-incident:hover{background:#BF3A3A}
|
||||
.btn-incident .ic{width:16px;height:16px}
|
||||
.user{display:flex;align-items:center;gap:8px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.16);border-radius:8px;padding:5px 10px 5px 5px;font-size:12px;font-weight:600;cursor:pointer;white-space:nowrap}
|
||||
.user:hover{background:rgba(255,255,255,.16)}
|
||||
.avatar{width:24px;height:24px;border-radius:6px;background:var(--c-green);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}
|
||||
.bar-nav{background:var(--navy-nav);border-top:1px solid rgba(255,255,255,.06)}
|
||||
.bar-nav-in{max-width:1280px;margin:0 auto;padding:0 16px;display:flex;align-items:stretch;gap:2px;flex-wrap:wrap}
|
||||
.nav-item{position:relative}
|
||||
.nav-link{display:flex;align-items:center;gap:7px;color:#cfe0f1;font-weight:600;font-size:13px;padding:13px 14px;white-space:nowrap;border-bottom:3px solid transparent;cursor:pointer}
|
||||
.nav-link .ic{width:15px;height:15px;opacity:.9}
|
||||
.nav-link .caret{width:13px;height:13px;opacity:.7;margin-left:-2px}
|
||||
.nav-item:hover>.nav-link{color:#fff;background:rgba(255,255,255,.06)}
|
||||
.nav-link.active{color:#fff;border-bottom-color:var(--gold)}
|
||||
.mega{position:absolute;top:100%;left:0;background:#fff;color:var(--ink);border-radius:0 0 14px 14px;box-shadow:0 18px 40px rgba(11,40,80,.18);border:1px solid var(--line);border-top:0;padding:22px;display:none;grid-template-columns:auto auto 250px;gap:30px;min-width:560px;z-index:60}
|
||||
.nav-item:hover .mega,.nav-item:focus-within .mega{display:grid}
|
||||
.nav-item:nth-last-child(-n+3) .mega{left:auto;right:0}
|
||||
.mega.no-promo{min-width:auto}
|
||||
.nav-item:hover .mega.no-promo,.nav-item:focus-within .mega.no-promo{display:flex;gap:30px;width:auto}
|
||||
.mega-col{min-width:190px}
|
||||
.mega-head{font-size:10.5px;font-weight:700;letter-spacing:.12em;color:#94A3B8;text-transform:uppercase;margin:0 0 12px}
|
||||
.mega-link{display:flex;gap:11px;padding:8px;border-radius:9px;align-items:flex-start}
|
||||
.mega-link:hover{background:#F3F7FC}
|
||||
.mega-link .mega-ic{width:36px;height:36px;border-radius:10px;background:#EAF1FA;color:var(--c-blue);display:flex;align-items:center;justify-content:center;flex:0 0 auto}
|
||||
.mega-ic .ic{width:21px;height:21px;display:block}
|
||||
.mega-link b{display:block;font-size:13.5px;font-weight:700}
|
||||
.mega-link span{display:block;font-size:11.5px;color:var(--muted);margin-top:2px}
|
||||
.promo{background:linear-gradient(160deg,#1F5FA8,#0F3F77);color:#fff;border-radius:12px;padding:18px;display:flex;flex-direction:column;gap:10px}
|
||||
.promo .badge{align-self:flex-start;background:rgba(255,255,255,.18);font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:4px 9px;border-radius:999px}
|
||||
.promo b{font-size:16px}
|
||||
.promo p{margin:0;font-size:12px;color:#cfe0f3;line-height:1.45}
|
||||
.promo .go{margin-top:auto;align-self:flex-end;width:38px;height:38px;border-radius:9px;background:#fff;color:var(--c-blue);display:flex;align-items:center;justify-content:center}
|
||||
.wrap{max-width:1280px;margin:0 auto;padding:22px 24px 80px}
|
||||
.crumb{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--muted);margin-bottom:14px}
|
||||
.crumb .ic{width:13px;height:13px}.crumb a:hover{color:var(--ink)}
|
||||
.page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;margin-bottom:24px;flex-wrap:wrap}
|
||||
.page-head h1{margin:0;font-size:26px;font-weight:800;letter-spacing:-.4px}
|
||||
.page-head .sub{margin:4px 0 0;color:var(--muted);font-size:13.5px}
|
||||
.date{display:flex;align-items:center;gap:8px;color:var(--muted);font-size:13px;background:#fff;border:1px solid var(--line);border-radius:9px;padding:8px 12px}
|
||||
.date .ic{width:15px;height:15px}
|
||||
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow)}
|
||||
.card-pad{padding:20px}
|
||||
.stack{display:grid;gap:18px}
|
||||
.cal-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px;flex-wrap:wrap}
|
||||
.cal-head h3{margin:0;font-size:15px;font-weight:700}
|
||||
.cal-ctrl{display:flex;gap:6px;align-items:center}
|
||||
.ctrl-btn{width:32px;height:32px;border:1px solid var(--line);border-radius:8px;background:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer}
|
||||
.ctrl-btn:hover{background:#F5F8FC}
|
||||
.ctrl-btn .ic{width:16px;height:16px;color:var(--muted)}
|
||||
.ctrl-today{height:32px;padding:0 13px;border:1px solid var(--line);border-radius:8px;background:#fff;font:inherit;font-weight:600;font-size:12px;display:flex;align-items:center;gap:6px;cursor:pointer;color:var(--ink)}
|
||||
.ctrl-today:hover{background:#F5F8FC}
|
||||
.ctrl-today .ic{width:14px;height:14px;color:var(--c-blue)}
|
||||
.daystrip{display:flex;gap:8px;overflow-x:auto;padding-bottom:4px;scrollbar-width:thin}
|
||||
.daycell{flex:1 1 0;min-width:64px;border:1px solid var(--line);border-radius:11px;background:#fff;padding:11px 6px 9px;text-align:center;position:relative;cursor:pointer;transition:border-color .12s,transform .12s,box-shadow .12s}
|
||||
.daycell:hover{border-color:#9FBEDD;box-shadow:0 4px 12px rgba(16,40,80,.08)}
|
||||
.daycell .wd{font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:#8093A8}
|
||||
.daycell .dn{font-size:21px;font-weight:800;line-height:1.15;margin-top:3px}
|
||||
.daycell .mo{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;margin-top:1px}
|
||||
.daycell.weekend{background:#F5F8FC}
|
||||
.daycell.weekend .wd{color:#A6B4C6}
|
||||
.daycell.today{background:var(--navy-nav);border-color:var(--navy-nav)}
|
||||
.daycell.today:hover{border-color:var(--navy-hover);box-shadow:0 6px 16px rgba(16,40,80,.22)}
|
||||
.daycell.today .wd{color:#C7D9EC}.daycell.today .dn,.daycell.today .mo{color:#fff}
|
||||
.daycell.today::before{content:"";position:absolute;left:0;right:0;top:0;height:3px;background:var(--gold);border-radius:11px 11px 0 0}
|
||||
.dots{display:flex;gap:3px;justify-content:center;margin-top:7px;min-height:6px}
|
||||
.ev{width:6px;height:6px;border-radius:50%;display:inline-block}
|
||||
.ev.green{background:var(--c-green)}.ev.blue{background:var(--c-blue)}.ev.amber{background:var(--c-amber)}.ev.red{background:var(--c-red)}
|
||||
.weekstrip{display:grid;grid-template-columns:1fr 1.25fr 1fr;gap:14px;align-items:start}
|
||||
.weekblock{border:1px solid var(--line);border-radius:12px;background:#FAFCFE;padding:13px;cursor:pointer;transition:border-color .12s,box-shadow .12s}
|
||||
.weekblock:hover{border-color:#9FBEDD;box-shadow:0 6px 16px rgba(16,40,80,.10)}
|
||||
.weekblock.current{background:#fff;border-color:#B9CFE6;box-shadow:0 6px 18px rgba(16,40,80,.08)}
|
||||
.weekblock .wl{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;gap:8px}
|
||||
.weekblock .wl b{font-size:12.5px;font-weight:700;color:var(--muted)}
|
||||
.weekblock.current .wl b{color:var(--c-blue)}
|
||||
.weekblock .wl span{font-size:9.5px;color:#A6B4C6;text-transform:uppercase;letter-spacing:.07em;font-weight:700;white-space:nowrap}
|
||||
.week7{display:grid;grid-template-columns:repeat(7,1fr);gap:3px}
|
||||
.mini{text-align:center;border-radius:8px;padding:6px 0 5px}
|
||||
.mini .mi-wd{font-size:9.5px;font-weight:700;color:#9aa8ba;text-transform:uppercase}
|
||||
.mini .mi-dn{font-size:13px;font-weight:700;margin-top:1px}
|
||||
.mini.weekend .mi-wd,.mini.weekend .mi-dn{color:#A6B4C6}
|
||||
.mini.today{background:var(--navy-nav)}.mini.today .mi-wd{color:#C7D9EC}.mini.today .mi-dn{color:#fff}
|
||||
.mini .mi-ev{display:flex;gap:2px;justify-content:center;min-height:5px;margin-top:3px}
|
||||
.mini .mi-ev .ev{width:4px;height:4px}
|
||||
.cal-pop{position:fixed;z-index:80;display:none;width:252px;background:#fff;border:1px solid var(--line);border-radius:11px;box-shadow:0 14px 36px rgba(11,40,80,.20);padding:13px 14px;pointer-events:none;opacity:0;transform:translateY(5px);transition:opacity .12s ease,transform .12s ease}
|
||||
.cal-pop.show{opacity:1;transform:none}
|
||||
.cal-pop h4{margin:0 0 9px;font-size:12.5px;font-weight:700;text-transform:capitalize}
|
||||
.cal-pop .pe{display:flex;gap:9px;align-items:flex-start;padding:6px 0;border-top:1px solid #EFF3F8}
|
||||
.cal-pop .pe:first-of-type{border-top:0;padding-top:0}
|
||||
.cal-pop .pe .ev{margin-top:5px;flex:0 0 auto}
|
||||
.cal-pop .pe .tt{font-size:10.5px;color:var(--muted);font-variant-numeric:tabular-nums;display:block}
|
||||
.cal-pop .pe b{font-size:12px;font-weight:600;line-height:1.3;display:block}
|
||||
.cal-pop .empty{font-size:12px;color:#94A3B8}
|
||||
.fab-stack{position:fixed;right:22px;bottom:22px;display:flex;flex-direction:column;gap:12px;z-index:40}
|
||||
.fab{width:46px;height:46px;border-radius:50%;border:0;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 8px 20px rgba(16,40,80,.22)}
|
||||
.fab .ic{width:20px;height:20px}
|
||||
.fab.blue{background:var(--c-blue)}.fab.red{background:var(--c-red)}.fab.violet{background:#7C4DD6}
|
||||
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
|
||||
.split2{display:grid;grid-template-columns:1fr 1fr;gap:18px}
|
||||
.split-anag{display:grid;grid-template-columns:1.35fr 1fr;gap:18px}
|
||||
.sec-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:14px}
|
||||
.sec-head h3{margin:0;font-size:15px;font-weight:700}
|
||||
.sec-head .hint{font-size:11.5px;color:var(--muted)}
|
||||
.stat{display:flex;gap:14px;align-items:flex-start;border-left:4px solid var(--c-blue)}
|
||||
.stat.green{border-left-color:var(--c-green)}.stat.amber{border-left-color:var(--c-amber)}.stat.blue{border-left-color:var(--c-blue)}
|
||||
.stat .ibox{width:42px;height:42px;border-radius:11px;display:flex;align-items:center;justify-content:center;flex:0 0 auto;background:#EAF1FA;color:var(--c-blue)}
|
||||
.stat.green .ibox{background:#E6F4EC;color:var(--c-green)}.stat.amber .ibox{background:#FBF1E2;color:var(--c-amber)}
|
||||
.stat .ibox .ic{width:20px;height:20px}
|
||||
.stat .lbl{font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#7a8aa0}
|
||||
.stat .val{font-size:27px;font-weight:800;line-height:1.1;margin:3px 0 1px}
|
||||
.stat.green .val{color:var(--c-green)}.stat.amber .val{color:var(--c-amber)}.stat.blue .val{color:var(--c-blue)}
|
||||
.stat .sub{font-size:12px;color:var(--muted)}
|
||||
.bar{height:7px;background:#EAF0F6;border-radius:99px;overflow:hidden;margin-top:9px;max-width:180px}
|
||||
.bar>i{display:block;height:100%;background:var(--c-amber);border-radius:99px}
|
||||
.btn-primary{display:inline-flex;align-items:center;gap:7px;background:var(--c-blue);color:#fff;border:0;border-radius:8px;padding:8px 13px;font:inherit;font-weight:600;font-size:12.5px;cursor:pointer}
|
||||
.btn-primary:hover{background:#1A5494}
|
||||
.btn-primary .ic{width:15px;height:15px}
|
||||
.btn-ghost{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line);background:#fff;border-radius:8px;padding:7px 12px;font:inherit;font-weight:600;font-size:12.5px;color:var(--ink);cursor:pointer}
|
||||
.btn-ghost:hover{background:#F5F8FC;border-color:#c7d4e4}
|
||||
.btn-ghost .ic{width:15px;height:15px;color:var(--c-blue)}
|
||||
.dpill{flex:0 0 auto;width:46px;text-align:center;background:#EFF4FB;border:1px solid var(--line);border-radius:9px;padding:6px 0}
|
||||
.dpill b{display:block;font-size:15px;font-weight:800;line-height:1}
|
||||
.dpill span{font-size:9.5px;font-weight:700;letter-spacing:.05em;color:var(--muted);text-transform:uppercase}
|
||||
.sca{display:flex;gap:13px;align-items:flex-start;padding:12px 0;border-top:1px solid var(--line)}
|
||||
.sca:first-of-type{border-top:0;padding-top:0}
|
||||
.sca .body{flex:1;min-width:0}
|
||||
.sca .body b{font-size:13px;font-weight:600;display:block}
|
||||
.meta{display:flex;gap:8px;align-items:center;margin-top:5px;flex-wrap:wrap}
|
||||
.who{font-size:11.5px;color:var(--muted)}
|
||||
.badge-t{font-size:10px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;padding:2px 7px;border-radius:6px;background:#EEF2F7;color:#5b6b80;white-space:nowrap}
|
||||
.badge-t.blue{background:#E7F0FB;color:#1F5FA8}.badge-t.amber{background:#FBF1E2;color:#9A6418}.badge-t.red{background:#FBE9E9;color:#B23636}.badge-t.green{background:#E6F4EC;color:#1E7A4E}.badge-t.gray{background:#EEF2F7;color:#5b6b80}
|
||||
.act-scroll{max-height:330px;overflow-y:auto;padding-right:4px;scrollbar-width:thin}
|
||||
.act{display:flex;gap:12px;align-items:flex-start;justify-content:space-between;padding:12px;border:1px solid var(--line);border-radius:10px;margin-bottom:8px;background:#fff}
|
||||
.act:last-child{margin-bottom:0}
|
||||
.act .body{flex:1;min-width:0}.act .body b{font-size:13px;font-weight:600;display:block}
|
||||
.anag{display:flex;gap:16px;align-items:flex-start}
|
||||
.anag-logo{width:60px;height:60px;border-radius:13px;background:linear-gradient(135deg,#143A5C,#1F5FA8);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:17px;letter-spacing:.5px;flex:0 0 auto}
|
||||
.anag .info{flex:1;min-width:0}
|
||||
.anag .nm{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
|
||||
.anag .nm h3{margin:0;font-size:16px;font-weight:800}
|
||||
.badge-nis{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;padding:3px 8px;border-radius:6px;background:#E7F0FB;color:#1F5FA8}
|
||||
.anag-grid{display:grid;grid-template-columns:1fr 1fr;gap:11px 18px;margin-top:14px}
|
||||
.anag-grid .f span{display:block;font-size:10.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#8093A8}
|
||||
.anag-grid .f b{font-size:13px;font-weight:600}
|
||||
.doc{display:flex;align-items:center;gap:12px;width:100%;text-align:left;border:1px solid var(--line);background:#fff;border-radius:10px;padding:12px 14px;cursor:pointer;font:inherit;margin-bottom:10px}
|
||||
.doc:last-child{margin-bottom:0}
|
||||
.doc:hover{border-color:#c7d4e4;background:#FAFCFE}
|
||||
.doc .di{width:36px;height:36px;border-radius:9px;background:#EAF1FA;color:var(--c-blue);display:flex;align-items:center;justify-content:center;flex:0 0 auto}
|
||||
.doc .di .ic{width:18px;height:18px}
|
||||
.doc .dt{flex:1;min-width:0}
|
||||
.doc .dt b{font-size:13.5px;font-weight:700;display:block}
|
||||
.doc .dt small{font-size:11px;color:var(--muted)}
|
||||
.doc .st{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;font-weight:700;padding:5px 10px;border-radius:999px;white-space:nowrap}
|
||||
.doc .st .ic{width:14px;height:14px}
|
||||
.doc.has .st{background:#E6F4EC;color:#1E7A4E}
|
||||
.doc.miss .st{background:#FBF1E2;color:#9A6418}
|
||||
@media (max-width:900px){.weekstrip{grid-template-columns:1fr}.grid3,.split2,.split-anag{grid-template-columns:1fr}.mega{grid-template-columns:1fr;min-width:280px}.search{display:none}}
|
||||
@media (max-width:560px){.brand-txt span{display:none}.btn-incident span{display:none}}
|
||||
|
||||
.ga-intro{display:flex;gap:12px;align-items:flex-start;background:#EEF4FB;border:1px solid #D5E3F2;color:#2C4A6B;border-radius:11px;padding:14px 16px;font-size:13px;margin-bottom:20px}
|
||||
.ga-intro .ic{width:18px;height:18px;flex:0 0 auto;color:var(--c-blue);margin-top:1px}
|
||||
.ga-kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:20px}
|
||||
.ga-grid{display:grid;grid-template-columns:330px 1fr;gap:18px;align-items:start}
|
||||
.ga-side .sec-head{margin-bottom:12px}
|
||||
.emp-list{display:flex;flex-direction:column;gap:10px}
|
||||
.emp{display:flex;align-items:center;gap:12px;padding:12px 13px;border:1px solid var(--line);border-radius:11px;background:#fff;cursor:pointer;box-shadow:var(--shadow);text-align:left;font:inherit;width:100%}
|
||||
.emp:hover{border-color:#9FBEDD}
|
||||
.emp.on{border-color:var(--c-blue);box-shadow:0 0 0 2px rgba(31,95,168,.18)}
|
||||
.emp .av{width:40px;height:40px;border-radius:10px;background:linear-gradient(135deg,#143A5C,#1F5FA8);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:13px;flex:0 0 auto}
|
||||
.emp .ei{flex:1;min-width:0}
|
||||
.emp .ei b{font-size:13.5px;font-weight:700;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||
.emp .ei span{font-size:11.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}
|
||||
.emp .mt{font-size:14px;font-weight:800;flex:0 0 auto}
|
||||
.emp .mt.ok{color:var(--c-green)}.emp .mt.warn{color:var(--c-amber)}.emp .mt.crit{color:var(--c-red)}
|
||||
.det{background:#fff;border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow);overflow:hidden}
|
||||
.det-head{display:flex;align-items:center;gap:16px;padding:20px;border-bottom:1px solid var(--line)}
|
||||
.det-head .av{width:54px;height:54px;border-radius:12px;background:linear-gradient(135deg,#143A5C,#1F5FA8);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:17px;flex:0 0 auto}
|
||||
.det-head .hi{flex:1;min-width:0}
|
||||
.det-head .hi h3{margin:0;font-size:18px;font-weight:800}
|
||||
.det-head .hi .role{font-size:13px;color:var(--muted);margin-top:2px}
|
||||
.det-head .score{text-align:right;flex:0 0 auto}
|
||||
.det-head .score .pct{font-size:26px;font-weight:800;line-height:1}
|
||||
.det-head .score .pct.ok{color:var(--c-green)}.det-head .score .pct.warn{color:var(--c-amber)}.det-head .score .pct.crit{color:var(--c-red)}
|
||||
.det-head .score .lb{font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:#8093A8;margin-top:3px}
|
||||
.det-body{padding:6px 20px 14px}
|
||||
.crow{display:grid;grid-template-columns:1.25fr 250px 116px;gap:18px;align-items:center;padding:14px 0;border-top:1px solid var(--line)}
|
||||
.crow:first-child{border-top:0}
|
||||
.crow .cn{font-size:13.5px;font-weight:600}
|
||||
.levels{display:grid;gap:7px}
|
||||
.lvlrow{display:flex;align-items:center;gap:9px}
|
||||
.lvlrow .lab{font-size:9.5px;font-weight:700;color:#8093A8;text-transform:uppercase;width:70px;letter-spacing:.03em}
|
||||
.dots5{display:flex;gap:5px}
|
||||
.dots5 i{width:13px;height:13px;border-radius:50%;background:#E7ECF2;display:block}
|
||||
.dots5 i.req{background:#94A3B8}
|
||||
.gbadge{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.03em;padding:4px 0;border-radius:999px;text-align:center}
|
||||
.gbadge.ok{background:#E6F4EC;color:#1E7A4E}
|
||||
.gbadge.warn{background:#FBF1E2;color:#9A6418}
|
||||
.gbadge.crit{background:#FBE9E9;color:#B23636}
|
||||
@media (max-width:900px){.ga-kpis{grid-template-columns:repeat(2,1fr)}.ga-grid{grid-template-columns:1fr}.crow{grid-template-columns:1fr;gap:10px}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header class="appbar">
|
||||
<div class="bar-top"><div class="bar-top-in">
|
||||
<span class="flag"><i class="g"></i><i class="w"></i><i class="r"></i></span>
|
||||
<div class="logo-mark">N2</div>
|
||||
<div class="brand-txt"><b>NIS2 Agile</b><span>Conformità Direttiva (UE) 2022/2555 · D.Lgs. 138/2024</span></div>
|
||||
<label class="search"><i data-lucide="search" class="ic"></i><input placeholder="Cerca misura, rischio, incidente…"></label>
|
||||
<span class="spacer"></span>
|
||||
<button class="btn-incident"><i data-lucide="siren" class="ic"></i><span>Registra incidente</span></button>
|
||||
<span class="user"><span class="avatar">SF</span>Simone Fatteri<i data-lucide="chevron-down" class="ic"></i></span>
|
||||
</div></div>
|
||||
<nav class="bar-nav"><div class="bar-nav-in">
|
||||
<div class="nav-item"><a class="nav-link" href="index.html"><i data-lucide="layout-dashboard" class="ic"></i><span>Dashboard</span></a></div>
|
||||
<div class="nav-item"><a class="nav-link" href="calendario.html"><i data-lucide="calendar" class="ic"></i><span>Calendario</span></a></div>
|
||||
<div class="nav-item"><a class="nav-link" href="stakeholders.html"><i data-lucide="users" class="ic"></i><span>Stakeholders</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">RELAZIONI</p><a class="mega-link" href="stakeholders.html"><span class="mega-ic"><i data-lucide="handshake" class="ic"></i></span><span><b>Stakeholders</b><span>Soggetti interni ed esterni rilevanti</span></span></a><a class="mega-link" href="supply-chain.html"><span class="mega-ic"><i data-lucide="link" class="ic"></i></span><span><b>Supply-Chain</b><span>Rischio fornitori e terze parti</span></span></a><a class="mega-link" href="stakeholder-activities.html"><span class="mega-ic"><i data-lucide="activity" class="ic"></i></span><span><b>Attività su Stakeholders</b><span>Interazioni, richieste e impegni</span></span></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link active" href="organigramma.html"><i data-lucide="building-2" class="ic"></i><span>Struttura interna</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">RUOLI E COMPETENZE</p><a class="mega-link" href="organigramma.html"><span class="mega-ic"><i data-lucide="network" class="ic"></i></span><span><b>Organigramma</b><span>Ruoli, deleghe e responsabilità</span></span></a><a class="mega-link" href="competenze.html"><span class="mega-ic"><i data-lucide="award" class="ic"></i></span><span><b>Competenze</b><span>Skill matrix e copertura dei ruoli</span></span></a><a class="mega-link" href="assessment.html"><span class="mega-ic"><i data-lucide="git-compare" class="ic"></i></span><span><b>GAP Analysis</b><span>Scostamento tra stato attuale e atteso</span></span></a><a class="mega-link" href="training.html"><span class="mega-ic"><i data-lucide="graduation-cap" class="ic"></i></span><span><b>Formazione</b><span>Piani formativi e completamento</span></span></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="risks.html"><i data-lucide="shield-alert" class="ic"></i><span>Rischi</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">GESTIONE RISCHIO</p><a class="mega-link" href="risks.html"><span class="mega-ic"><i data-lucide="map" class="ic"></i></span><span><b>Mappa dei rischi</b><span>Registro rischi e piani di trattamento</span></span></a><a class="mega-link" href="assets.html"><span class="mega-ic"><i data-lucide="boxes" class="ic"></i></span><span><b>Inventario</b><span>Asset e perimetro tecnico</span></span></a><a class="mega-link" href="policies.html"><span class="mega-ic"><i data-lucide="file-text" class="ic"></i></span><span><b>Policy</b><span>Politiche approvate e in revisione</span></span></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="whistleblowing.html"><i data-lucide="radar" class="ic"></i><span>Monitoraggio</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">VIGILANZA E AUDIT</p><a class="mega-link" href="whistleblowing.html"><span class="mega-ic"><i data-lucide="megaphone" class="ic"></i></span><span><b>Segnalazioni ricevute</b><span>Whistleblowing e segnalazioni interne</span></span></a><a class="mega-link" href="internal-audits.html"><span class="mega-ic"><i data-lucide="clipboard-check" class="ic"></i></span><span><b>Audit interni</b><span>Programma e esiti degli audit</span></span></a><a class="mega-link" href="reports.html"><span class="mega-ic"><i data-lucide="file-check" class="ic"></i></span><span><b>Audit ACN</b><span>Verifiche e ispezioni dell'autorità</span></span></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="report.html"><i data-lucide="scale" class="ic"></i><span>Lex e ISO</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">NORMATIVA E ISO</p><a class="mega-link" href="normative.html"><span class="mega-ic"><i data-lucide="scroll-text" class="ic"></i></span><span><b>Normative</b><span>Direttiva, decreto e riferimenti applicabili</span></span></a><a class="mega-link" href="isms.html"><span class="mega-ic"><i data-lucide="shield-check" class="ic"></i></span><span><b>Modello SGSI (ISO 27001)</b><span>Sistema di gestione sicurezza informazioni</span></span></a><a class="mega-link" href="misure-requisiti.html"><span class="mega-ic"><i data-lucide="list-checks" class="ic"></i></span><span><b>Misure e requisiti ACN</b><span>Misure tecniche e organizzative Art. 21</span></span></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="ai.html"><i data-lucide="sparkles" class="ic"></i><span>AI</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">ASSISTENTE</p><a class="mega-link" href="cross-analysis.html"><span class="mega-ic"><i data-lucide="sparkles" class="ic"></i></span><span><b>AI Cross-Analysis</b><span>Analisi trasversale di rischi e misure</span></span></a><a class="mega-link" href="kb.html"><span class="mega-ic"><i data-lucide="book-open" class="ic"></i></span><span><b>Knowledge Base</b><span>Procedure, linee guida e riferimenti</span></span></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="guida.html"><i data-lucide="life-buoy" class="ic"></i><span>Guida</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">GUIDA</p><a class="mega-link" href="guida.html"><span class="mega-ic"><i data-lucide="life-buoy" class="ic"></i></span><span><b>Guida all'uso</b><span>Manuale e istruzioni della piattaforma</span></span></a><a class="mega-link" href="integrazioniext.html"><span class="mega-ic"><i data-lucide="plug" class="ic"></i></span><span><b>Integrazioni Esterne</b><span>Connettori e servizi collegati</span></span></a></div><div class="mega-col"><p class="mega-head">SISTEMA</p><a class="mega-link" href="setting.html"><span class="mega-ic"><i data-lucide="settings" class="ic"></i></span><span><b>Impostazioni</b><span>Configurazione del workspace</span></span></a><a class="mega-link" href="architecture.html"><span class="mega-ic"><i data-lucide="layers" class="ic"></i></span><span><b>Architettura</b><span>Modello dati e struttura del sistema</span></span></a></div></div></div>
|
||||
</div></nav>
|
||||
</header>
|
||||
|
||||
<main class="wrap">
|
||||
<nav class="crumb"><i data-lucide="home" class="ic"></i><a href="index.html">Home</a><i data-lucide="chevron-right" class="ic"></i><a href="organigramma.html">Struttura interna</a><i data-lucide="chevron-right" class="ic"></i><span>GAP Analysis</span></nav>
|
||||
<div class="page-head">
|
||||
<div><h1>GAP Analysis — Competenze</h1><p class="sub">Allineamento tra le competenze possedute dai dipendenti e quelle richieste dal ruolo ricoperto</p></div>
|
||||
<div class="date"><i data-lucide="calendar" class="ic"></i>giovedì 25 giugno 2026</div>
|
||||
</div>
|
||||
|
||||
<div class="ga-intro"><i data-lucide="info" class="ic"></i><div>Per ogni dipendente dell'organigramma vengono confrontate le competenze <b>richieste dal ruolo</b> con quelle <b>effettivamente possedute</b>, evidenziando gli scostamenti (gap) su cui intervenire con la formazione.</div></div>
|
||||
|
||||
<div class="ga-kpis" id="ga-kpis"></div>
|
||||
|
||||
<div class="ga-grid">
|
||||
<aside class="ga-side">
|
||||
<div class="sec-head"><h3>Dipendenti</h3></div>
|
||||
<div class="emp-list" id="emp-list"></div>
|
||||
</aside>
|
||||
<section class="det" id="detail"></section>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="fab-stack">
|
||||
<button class="fab blue" title="Notifiche"><i data-lucide="bell" class="ic"></i></button>
|
||||
<button class="fab red" title="Assistenza"><i data-lucide="life-buoy" class="ic"></i></button>
|
||||
<button class="fab violet" title="Assistente AI"><i data-lucide="sparkles" class="ic"></i></button>
|
||||
</div>
|
||||
|
||||
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
|
||||
<script>
|
||||
const EMP=[
|
||||
{id:1,name:'Marco Bianchi',role:'CISO / Resp. Sicurezza',comps:[
|
||||
['Gestione del rischio ICT',5,4],['Sicurezza delle reti',5,5],['Gestione incidenti (Art. 23)',5,3],
|
||||
['Conformit\u00e0 NIS2',4,4],['Crittografia',3,2],['Continuit\u00e0 operativa',4,4]]},
|
||||
{id:2,name:'Laura Verdi',role:'Responsabile IT',comps:[
|
||||
['Amministrazione sistemi',5,5],['Gestione accessi (IAM)',4,3],['Backup e ripristino',4,4],
|
||||
['Hardening',3,2],['Monitoraggio e log',3,3]]},
|
||||
{id:3,name:'Andrea Rossi',role:'SOC Analyst',comps:[
|
||||
['Monitoraggio SIEM',4,4],['Analisi incidenti',4,3],['Threat intelligence',3,2],['Digital forensics',3,1]]},
|
||||
{id:4,name:'Giulia Neri',role:'Data Protection / Compliance',comps:[
|
||||
['Normativa privacy (GDPR)',4,4],['Conformit\u00e0 NIS2',4,3],['Gestione documentale',3,3],['Audit interni',3,2]]},
|
||||
{id:5,name:'Paolo Gialli',role:'Resp. Formazione',comps:[
|
||||
['Pianificazione formazione',4,4],['Security awareness',3,3],['Gestione competenze',3,2]]},
|
||||
{id:6,name:'Sara Blu',role:'Sistemista',comps:[
|
||||
['Amministrazione sistemi',3,3],['Gestione accessi',3,2],['Backup e ripristino',3,3],['Hardening',3,3]]}
|
||||
];
|
||||
const STC={ok:'var(--c-green)',warn:'var(--c-amber)',crit:'var(--c-red)'};
|
||||
function ini(n){return n.split(' ').map(p=>p[0]).join('').slice(0,2).toUpperCase();}
|
||||
function cstat(req,act){const g=req-act;return g<=0?'ok':g===1?'warn':'crit';}
|
||||
function estat(e){let w=false;for(const[,req,act]of e.comps){const g=req-act;if(g>=2)return'crit';if(g===1)w=true;}return w?'warn':'ok';}
|
||||
function pct(e){let s=0,t=0;for(const[,req,act]of e.comps){s+=Math.min(act,req);t+=req;}return Math.round(s/t*100);}
|
||||
function gaps(e){return e.comps.filter(([,req,act])=>req-act>0).length;}
|
||||
function dots(filled,color){let h='';for(let i=1;i<=5;i++){const on=i<=filled;h+='<i'+(on&&!color?' class="req"':'')+(on&&color?' style="background:'+color+'"':'')+'></i>';}return h;}
|
||||
|
||||
function renderKpis(){
|
||||
const n=EMP.length;
|
||||
const avg=Math.round(EMP.reduce((a,e)=>a+pct(e),0)/n);
|
||||
const totGap=EMP.reduce((a,e)=>a+gaps(e),0);
|
||||
const roles=new Set(EMP.map(e=>e.role)).size;
|
||||
const cards=[
|
||||
['blue','users','Dipendenti valutati',n,'nell\'organigramma'],
|
||||
['green','target','Allineamento medio',avg+'%','competenze vs ruolo'],
|
||||
['amber','triangle-alert','Competenze in gap',totGap,'da colmare'],
|
||||
['blue','briefcase','Ruoli coperti',roles,'profili valutati']
|
||||
];
|
||||
document.getElementById('ga-kpis').innerHTML=cards.map(([c,ic,l,v,s])=>
|
||||
'<div class="card card-pad stat '+c+'"><div class="ibox"><i data-lucide="'+ic+'"></i></div>'+
|
||||
'<div style="flex:1;min-width:0"><div class="lbl">'+l+'</div><div class="val">'+v+'</div><div class="sub">'+s+'</div></div></div>').join('');
|
||||
}
|
||||
|
||||
function renderList(sel){
|
||||
document.getElementById('emp-list').innerHTML=EMP.map(e=>{
|
||||
const st=estat(e);
|
||||
return '<button class="emp'+(e.id===sel?' on':'')+'" data-id="'+e.id+'">'+
|
||||
'<span class="av">'+ini(e.name)+'</span>'+
|
||||
'<span class="ei"><b>'+e.name+'</b><span>'+e.role+'</span></span>'+
|
||||
'<span class="mt '+st+'">'+pct(e)+'%</span></button>';
|
||||
}).join('');
|
||||
document.querySelectorAll('.emp').forEach(b=>b.onclick=()=>select(+b.dataset.id));
|
||||
}
|
||||
|
||||
function renderDetail(id){
|
||||
const e=EMP.find(x=>x.id===id);const st=estat(e);const STL={ok:'In linea',warn:'Da rafforzare',crit:'Gap critico'};
|
||||
let rows=e.comps.map(([name,req,act])=>{
|
||||
const s=cstat(req,act);const g=req-act;
|
||||
const badge=g<=0?'<span class="gbadge ok">In linea</span>':g===1?'<span class="gbadge warn">Gap \u22121</span>':'<span class="gbadge crit">Gap \u2212'+g+'</span>';
|
||||
return '<div class="crow"><div class="cn">'+name+'</div>'+
|
||||
'<div class="levels">'+
|
||||
'<div class="lvlrow"><span class="lab">Richiesto</span><div class="dots5">'+dots(req,null)+'</div></div>'+
|
||||
'<div class="lvlrow"><span class="lab">Posseduto</span><div class="dots5">'+dots(act,STC[s])+'</div></div>'+
|
||||
'</div>'+badge+'</div>';
|
||||
}).join('');
|
||||
document.getElementById('detail').innerHTML=
|
||||
'<div class="det-head"><span class="av">'+ini(e.name)+'</span>'+
|
||||
'<div class="hi"><h3>'+e.name+'</h3><div class="role">'+e.role+'</div></div>'+
|
||||
'<div class="score"><div class="pct '+st+'">'+pct(e)+'%</div><div class="lb">'+STL[st]+'</div></div></div>'+
|
||||
'<div class="det-body">'+rows+'</div>';
|
||||
}
|
||||
|
||||
let current=1;
|
||||
function select(id){current=id;renderList(id);renderDetail(id);lucide.createIcons();}
|
||||
|
||||
renderKpis();renderList(current);renderDetail(current);
|
||||
window.lucide && lucide.createIcons();
|
||||
</script>
|
||||
</body></html>
|
||||
@@ -0,0 +1,578 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Calendario · NIS2 Agile</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root{
|
||||
--navy-top:#0A2E54; --navy-nav:#103A61; --navy-hover:#1B4A75; --gold:#F0B429;
|
||||
--bg:#EFF4FA; --card:#FFFFFF; --ink:#15263C; --muted:#64748B; --line:#E3E9F0;
|
||||
--c-green:#1E8A5A; --c-blue:#1F5FA8; --c-amber:#D98324; --c-red:#C62828;
|
||||
--radius:12px; --shadow:0 1px 2px rgba(16,40,80,.06),0 8px 24px rgba(16,40,80,.06);
|
||||
}
|
||||
*{box-sizing:border-box} html{-webkit-text-size-adjust:100%}
|
||||
body{margin:0;background:var(--bg);color:var(--ink);
|
||||
font-family:'Inter',system-ui,-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5}
|
||||
a{color:inherit;text-decoration:none}
|
||||
:focus-visible{outline:2px solid var(--gold);outline-offset:2px;border-radius:4px}
|
||||
.appbar{position:sticky;top:0;z-index:50}
|
||||
.bar-top{background:var(--navy-top);color:#fff}
|
||||
.bar-top-in{max-width:1280px;margin:0 auto;display:flex;align-items:center;gap:16px;padding:10px 24px}
|
||||
.flag{width:18px;height:13px;border-radius:2px;overflow:hidden;display:flex;flex:0 0 auto;box-shadow:0 0 0 1px rgba(255,255,255,.25)}
|
||||
.flag i{flex:1}.flag .g{background:#1f8a4c}.flag .w{background:#fff}.flag .r{background:#cd2b2b}
|
||||
.logo-mark{width:34px;height:34px;border-radius:8px;background:var(--c-green);display:flex;align-items:center;justify-content:center;color:#fff;font-weight:800;font-size:13px;flex:0 0 auto}
|
||||
.brand-txt{line-height:1.1;min-width:0}
|
||||
.brand-txt b{font-size:15px;font-weight:700}
|
||||
.brand-txt span{display:block;font-size:10.5px;color:#A9C2DC;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||
.search{flex:1;max-width:340px;display:flex;align-items:center;gap:8px;background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.16);border-radius:8px;padding:7px 12px;color:#cfe0f1;min-width:120px}
|
||||
.search input{flex:1;border:0;background:transparent;color:#fff;font:inherit;outline:none;min-width:0}
|
||||
.search input::placeholder{color:#9db8d2}
|
||||
.spacer{flex:1}
|
||||
.btn-incident{display:inline-flex;align-items:center;gap:8px;background:#D24545;color:#fff;border:0;border-radius:8px;padding:9px 15px;font:inherit;font-weight:600;font-size:13px;cursor:pointer;box-shadow:0 1px 2px rgba(120,20,20,.35);white-space:nowrap}
|
||||
.btn-incident:hover{background:#BF3A3A}
|
||||
.btn-incident .ic{width:16px;height:16px}
|
||||
.user{display:flex;align-items:center;gap:8px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.16);border-radius:8px;padding:5px 10px 5px 5px;font-size:12px;font-weight:600;cursor:pointer;white-space:nowrap}
|
||||
.user:hover{background:rgba(255,255,255,.16)}
|
||||
.avatar{width:24px;height:24px;border-radius:6px;background:var(--c-green);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}
|
||||
.bar-nav{background:var(--navy-nav);border-top:1px solid rgba(255,255,255,.06)}
|
||||
.bar-nav-in{max-width:1280px;margin:0 auto;padding:0 16px;display:flex;align-items:stretch;gap:2px;flex-wrap:wrap}
|
||||
.nav-item{position:relative}
|
||||
.nav-link{display:flex;align-items:center;gap:7px;color:#cfe0f1;font-weight:600;font-size:13px;padding:13px 14px;white-space:nowrap;border-bottom:3px solid transparent;cursor:pointer}
|
||||
.nav-link .ic{width:15px;height:15px;opacity:.9}
|
||||
.nav-link .caret{width:13px;height:13px;opacity:.7;margin-left:-2px}
|
||||
.nav-item:hover>.nav-link{color:#fff;background:rgba(255,255,255,.06)}
|
||||
.nav-link.active{color:#fff;border-bottom-color:var(--gold)}
|
||||
.mega{position:absolute;top:100%;left:0;background:#fff;color:var(--ink);border-radius:0 0 14px 14px;box-shadow:0 18px 40px rgba(11,40,80,.18);border:1px solid var(--line);border-top:0;padding:22px;display:none;grid-template-columns:auto auto 250px;gap:30px;min-width:560px;z-index:60}
|
||||
.nav-item:hover .mega,.nav-item:focus-within .mega{display:grid}
|
||||
.nav-item:nth-last-child(-n+3) .mega{left:auto;right:0}
|
||||
.mega.no-promo{min-width:auto}
|
||||
.nav-item:hover .mega.no-promo,.nav-item:focus-within .mega.no-promo{display:flex;gap:30px;width:auto}
|
||||
.mega-col{min-width:190px}
|
||||
.mega-head{font-size:10.5px;font-weight:700;letter-spacing:.12em;color:#94A3B8;text-transform:uppercase;margin:0 0 12px}
|
||||
.mega-link{display:flex;gap:11px;padding:8px;border-radius:9px;align-items:flex-start}
|
||||
.mega-link:hover{background:#F3F7FC}
|
||||
.mega-ic{width:30px;height:30px;border-radius:8px;background:#EAF1FA;color:var(--c-blue);display:flex;align-items:center;justify-content:center;flex:0 0 auto}
|
||||
.mega-ic .ic{width:16px;height:16px}
|
||||
.mega-link b{display:block;font-size:13.5px;font-weight:700}
|
||||
.mega-link span{display:block;font-size:11.5px;color:var(--muted);margin-top:2px}
|
||||
.promo{background:linear-gradient(160deg,#1F5FA8,#0F3F77);color:#fff;border-radius:12px;padding:18px;display:flex;flex-direction:column;gap:10px}
|
||||
.promo .badge{align-self:flex-start;background:rgba(255,255,255,.18);font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:4px 9px;border-radius:999px}
|
||||
.promo b{font-size:16px}
|
||||
.promo p{margin:0;font-size:12px;color:#cfe0f3;line-height:1.45}
|
||||
.promo .go{margin-top:auto;align-self:flex-end;width:38px;height:38px;border-radius:9px;background:#fff;color:var(--c-blue);display:flex;align-items:center;justify-content:center}
|
||||
.wrap{max-width:1280px;margin:0 auto;padding:22px 24px 80px}
|
||||
.crumb{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--muted);margin-bottom:14px}
|
||||
.crumb .ic{width:13px;height:13px}.crumb a:hover{color:var(--ink)}
|
||||
.page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;margin-bottom:24px;flex-wrap:wrap}
|
||||
.page-head h1{margin:0;font-size:26px;font-weight:800;letter-spacing:-.4px}
|
||||
.page-head .sub{margin:4px 0 0;color:var(--muted);font-size:13.5px}
|
||||
.date{display:flex;align-items:center;gap:8px;color:var(--muted);font-size:13px;background:#fff;border:1px solid var(--line);border-radius:9px;padding:8px 12px}
|
||||
.date .ic{width:15px;height:15px}
|
||||
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow)}
|
||||
.card-pad{padding:20px}
|
||||
.stack{display:grid;gap:18px}
|
||||
.cal-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px;flex-wrap:wrap}
|
||||
.cal-head h3{margin:0;font-size:15px;font-weight:700}
|
||||
.cal-ctrl{display:flex;gap:6px;align-items:center}
|
||||
.ctrl-btn{width:32px;height:32px;border:1px solid var(--line);border-radius:8px;background:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer}
|
||||
.ctrl-btn:hover{background:#F5F8FC}
|
||||
.ctrl-btn .ic{width:16px;height:16px;color:var(--muted)}
|
||||
.ctrl-today{height:32px;padding:0 13px;border:1px solid var(--line);border-radius:8px;background:#fff;font:inherit;font-weight:600;font-size:12px;display:flex;align-items:center;gap:6px;cursor:pointer;color:var(--ink)}
|
||||
.ctrl-today:hover{background:#F5F8FC}
|
||||
.ctrl-today .ic{width:14px;height:14px;color:var(--c-blue)}
|
||||
.daystrip{display:flex;gap:8px;overflow-x:auto;padding-bottom:4px;scrollbar-width:thin}
|
||||
.daycell{flex:1 1 0;min-width:64px;border:1px solid var(--line);border-radius:11px;background:#fff;padding:11px 6px 9px;text-align:center;position:relative;cursor:pointer;transition:border-color .12s,transform .12s,box-shadow .12s}
|
||||
.daycell:hover{border-color:#9FBEDD;box-shadow:0 4px 12px rgba(16,40,80,.08)}
|
||||
.daycell .wd{font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:#8093A8}
|
||||
.daycell .dn{font-size:21px;font-weight:800;line-height:1.15;margin-top:3px}
|
||||
.daycell .mo{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;margin-top:1px}
|
||||
.daycell.weekend{background:#F5F8FC}
|
||||
.daycell.weekend .wd{color:#A6B4C6}
|
||||
.daycell.today{background:var(--navy-nav);border-color:var(--navy-nav)}
|
||||
.daycell.today:hover{border-color:var(--navy-hover);box-shadow:0 6px 16px rgba(16,40,80,.22)}
|
||||
.daycell.today .wd{color:#C7D9EC}.daycell.today .dn,.daycell.today .mo{color:#fff}
|
||||
.daycell.today::before{content:"";position:absolute;left:0;right:0;top:0;height:3px;background:var(--gold);border-radius:11px 11px 0 0}
|
||||
.dots{display:flex;gap:3px;justify-content:center;margin-top:7px;min-height:6px}
|
||||
.ev{width:6px;height:6px;border-radius:50%;display:inline-block}
|
||||
.ev.green{background:var(--c-green)}.ev.blue{background:var(--c-blue)}.ev.amber{background:var(--c-amber)}.ev.red{background:var(--c-red)}
|
||||
.weekstrip{display:grid;grid-template-columns:1fr 1.25fr 1fr;gap:14px;align-items:start}
|
||||
.weekblock{border:1px solid var(--line);border-radius:12px;background:#FAFCFE;padding:13px;cursor:pointer;transition:border-color .12s,box-shadow .12s}
|
||||
.weekblock:hover{border-color:#9FBEDD;box-shadow:0 6px 16px rgba(16,40,80,.10)}
|
||||
.weekblock.current{background:#fff;border-color:#B9CFE6;box-shadow:0 6px 18px rgba(16,40,80,.08)}
|
||||
.weekblock .wl{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;gap:8px}
|
||||
.weekblock .wl b{font-size:12.5px;font-weight:700;color:var(--muted)}
|
||||
.weekblock.current .wl b{color:var(--c-blue)}
|
||||
.weekblock .wl span{font-size:9.5px;color:#A6B4C6;text-transform:uppercase;letter-spacing:.07em;font-weight:700;white-space:nowrap}
|
||||
.week7{display:grid;grid-template-columns:repeat(7,1fr);gap:3px}
|
||||
.mini{text-align:center;border-radius:8px;padding:6px 0 5px}
|
||||
.mini .mi-wd{font-size:9.5px;font-weight:700;color:#9aa8ba;text-transform:uppercase}
|
||||
.mini .mi-dn{font-size:13px;font-weight:700;margin-top:1px}
|
||||
.mini.weekend .mi-wd,.mini.weekend .mi-dn{color:#A6B4C6}
|
||||
.mini.today{background:var(--navy-nav)}.mini.today .mi-wd{color:#C7D9EC}.mini.today .mi-dn{color:#fff}
|
||||
.mini .mi-ev{display:flex;gap:2px;justify-content:center;min-height:5px;margin-top:3px}
|
||||
.mini .mi-ev .ev{width:4px;height:4px}
|
||||
.cal-pop{position:fixed;z-index:80;display:none;width:252px;background:#fff;border:1px solid var(--line);border-radius:11px;box-shadow:0 14px 36px rgba(11,40,80,.20);padding:13px 14px;pointer-events:none;opacity:0;transform:translateY(5px);transition:opacity .12s ease,transform .12s ease}
|
||||
.cal-pop.show{opacity:1;transform:none}
|
||||
.cal-pop h4{margin:0 0 9px;font-size:12.5px;font-weight:700;text-transform:capitalize}
|
||||
.cal-pop .pe{display:flex;gap:9px;align-items:flex-start;padding:6px 0;border-top:1px solid #EFF3F8}
|
||||
.cal-pop .pe:first-of-type{border-top:0;padding-top:0}
|
||||
.cal-pop .pe .ev{margin-top:5px;flex:0 0 auto}
|
||||
.cal-pop .pe .tt{font-size:10.5px;color:var(--muted);font-variant-numeric:tabular-nums;display:block}
|
||||
.cal-pop .pe b{font-size:12px;font-weight:600;line-height:1.3;display:block}
|
||||
.cal-pop .empty{font-size:12px;color:#94A3B8}
|
||||
.fab-stack{position:fixed;right:22px;bottom:22px;display:flex;flex-direction:column;gap:12px;z-index:40}
|
||||
.fab{width:46px;height:46px;border-radius:50%;border:0;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 8px 20px rgba(16,40,80,.22)}
|
||||
.fab .ic{width:20px;height:20px}
|
||||
.fab.blue{background:var(--c-blue)}.fab.red{background:var(--c-red)}.fab.violet{background:#7C4DD6}
|
||||
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
|
||||
.split2{display:grid;grid-template-columns:1fr 1fr;gap:18px}
|
||||
.split-anag{display:grid;grid-template-columns:1.35fr 1fr;gap:18px}
|
||||
.sec-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:14px}
|
||||
.sec-head h3{margin:0;font-size:15px;font-weight:700}
|
||||
.sec-head .hint{font-size:11.5px;color:var(--muted)}
|
||||
.stat{display:flex;gap:14px;align-items:flex-start;border-left:4px solid var(--c-blue)}
|
||||
.stat.green{border-left-color:var(--c-green)}.stat.amber{border-left-color:var(--c-amber)}.stat.blue{border-left-color:var(--c-blue)}
|
||||
.stat .ibox{width:42px;height:42px;border-radius:11px;display:flex;align-items:center;justify-content:center;flex:0 0 auto;background:#EAF1FA;color:var(--c-blue)}
|
||||
.stat.green .ibox{background:#E6F4EC;color:var(--c-green)}.stat.amber .ibox{background:#FBF1E2;color:var(--c-amber)}
|
||||
.stat .ibox .ic{width:20px;height:20px}
|
||||
.stat .lbl{font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#7a8aa0}
|
||||
.stat .val{font-size:27px;font-weight:800;line-height:1.1;margin:3px 0 1px}
|
||||
.stat.green .val{color:var(--c-green)}.stat.amber .val{color:var(--c-amber)}.stat.blue .val{color:var(--c-blue)}
|
||||
.stat .sub{font-size:12px;color:var(--muted)}
|
||||
.bar{height:7px;background:#EAF0F6;border-radius:99px;overflow:hidden;margin-top:9px;max-width:180px}
|
||||
.bar>i{display:block;height:100%;background:var(--c-amber);border-radius:99px}
|
||||
.btn-primary{display:inline-flex;align-items:center;gap:7px;background:var(--c-blue);color:#fff;border:0;border-radius:8px;padding:8px 13px;font:inherit;font-weight:600;font-size:12.5px;cursor:pointer}
|
||||
.btn-primary:hover{background:#1A5494}
|
||||
.btn-primary .ic{width:15px;height:15px}
|
||||
.btn-ghost{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line);background:#fff;border-radius:8px;padding:7px 12px;font:inherit;font-weight:600;font-size:12.5px;color:var(--ink);cursor:pointer}
|
||||
.btn-ghost:hover{background:#F5F8FC;border-color:#c7d4e4}
|
||||
.btn-ghost .ic{width:15px;height:15px;color:var(--c-blue)}
|
||||
.dpill{flex:0 0 auto;width:46px;text-align:center;background:#EFF4FB;border:1px solid var(--line);border-radius:9px;padding:6px 0}
|
||||
.dpill b{display:block;font-size:15px;font-weight:800;line-height:1}
|
||||
.dpill span{font-size:9.5px;font-weight:700;letter-spacing:.05em;color:var(--muted);text-transform:uppercase}
|
||||
.sca{display:flex;gap:13px;align-items:flex-start;padding:12px 0;border-top:1px solid var(--line)}
|
||||
.sca:first-of-type{border-top:0;padding-top:0}
|
||||
.sca .body{flex:1;min-width:0}
|
||||
.sca .body b{font-size:13px;font-weight:600;display:block}
|
||||
.meta{display:flex;gap:8px;align-items:center;margin-top:5px;flex-wrap:wrap}
|
||||
.who{font-size:11.5px;color:var(--muted)}
|
||||
.badge-t{font-size:10px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;padding:2px 7px;border-radius:6px;background:#EEF2F7;color:#5b6b80;white-space:nowrap}
|
||||
.badge-t.blue{background:#E7F0FB;color:#1F5FA8}.badge-t.amber{background:#FBF1E2;color:#9A6418}.badge-t.red{background:#FBE9E9;color:#B23636}.badge-t.green{background:#E6F4EC;color:#1E7A4E}.badge-t.gray{background:#EEF2F7;color:#5b6b80}
|
||||
.act-scroll{max-height:330px;overflow-y:auto;padding-right:4px;scrollbar-width:thin}
|
||||
.act{display:flex;gap:12px;align-items:flex-start;justify-content:space-between;padding:12px;border:1px solid var(--line);border-radius:10px;margin-bottom:8px;background:#fff}
|
||||
.act:last-child{margin-bottom:0}
|
||||
.act .body{flex:1;min-width:0}.act .body b{font-size:13px;font-weight:600;display:block}
|
||||
.anag{display:flex;gap:16px;align-items:flex-start}
|
||||
.anag-logo{width:60px;height:60px;border-radius:13px;background:linear-gradient(135deg,#143A5C,#1F5FA8);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:17px;letter-spacing:.5px;flex:0 0 auto}
|
||||
.anag .info{flex:1;min-width:0}
|
||||
.anag .nm{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
|
||||
.anag .nm h3{margin:0;font-size:16px;font-weight:800}
|
||||
.badge-nis{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;padding:3px 8px;border-radius:6px;background:#E7F0FB;color:#1F5FA8}
|
||||
.anag-grid{display:grid;grid-template-columns:1fr 1fr;gap:11px 18px;margin-top:14px}
|
||||
.anag-grid .f span{display:block;font-size:10.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#8093A8}
|
||||
.anag-grid .f b{font-size:13px;font-weight:600}
|
||||
.doc{display:flex;align-items:center;gap:12px;width:100%;text-align:left;border:1px solid var(--line);background:#fff;border-radius:10px;padding:12px 14px;cursor:pointer;font:inherit;margin-bottom:10px}
|
||||
.doc:last-child{margin-bottom:0}
|
||||
.doc:hover{border-color:#c7d4e4;background:#FAFCFE}
|
||||
.doc .di{width:36px;height:36px;border-radius:9px;background:#EAF1FA;color:var(--c-blue);display:flex;align-items:center;justify-content:center;flex:0 0 auto}
|
||||
.doc .di .ic{width:18px;height:18px}
|
||||
.doc .dt{flex:1;min-width:0}
|
||||
.doc .dt b{font-size:13.5px;font-weight:700;display:block}
|
||||
.doc .dt small{font-size:11px;color:var(--muted)}
|
||||
.doc .st{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;font-weight:700;padding:5px 10px;border-radius:999px;white-space:nowrap}
|
||||
.doc .st .ic{width:14px;height:14px}
|
||||
.doc.has .st{background:#E6F4EC;color:#1E7A4E}
|
||||
.doc.miss .st{background:#FBF1E2;color:#9A6418}
|
||||
@media (max-width:900px){.weekstrip{grid-template-columns:1fr}.grid3,.split2,.split-anag{grid-template-columns:1fr}.mega{grid-template-columns:1fr;min-width:280px}.search{display:none}}
|
||||
@media (max-width:560px){.brand-txt span{display:none}.btn-incident span{display:none}}
|
||||
|
||||
.cal-app{display:grid;grid-template-columns:250px 1fr;gap:18px;align-items:start}
|
||||
.cal-side{display:flex;flex-direction:column;gap:16px}
|
||||
.btn-create{display:inline-flex;align-items:center;justify-content:center;gap:8px;background:var(--c-blue);color:#fff;border:0;border-radius:10px;padding:12px 16px;font:inherit;font-weight:700;font-size:14px;cursor:pointer;box-shadow:0 2px 8px rgba(31,95,168,.3)}
|
||||
.btn-create:hover{background:#1A5494}
|
||||
.btn-create .ic{width:18px;height:18px}
|
||||
.mini{background:#fff;border:1px solid var(--line);border-radius:12px;padding:14px;box-shadow:var(--shadow)}
|
||||
.mini-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:9px}
|
||||
.mini-head b{font-size:13px;font-weight:700;text-transform:capitalize}
|
||||
.mini-nav{display:flex;gap:2px}
|
||||
.mini-nav button{width:24px;height:24px;border:0;background:transparent;border-radius:6px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--muted)}
|
||||
.mini-nav button:hover{background:#F0F4F9}
|
||||
.mini-nav .ic{width:14px;height:14px}
|
||||
.mini-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:1px}
|
||||
.mini-grid .h{font-size:9.5px;font-weight:700;color:#9aa8ba;text-align:center;padding:3px 0}
|
||||
.mini-grid .d{font-size:11px;text-align:center;padding:5px 0;border-radius:50%;cursor:pointer;color:var(--ink)}
|
||||
.mini-grid .d:hover{background:#EDF2F8}
|
||||
.mini-grid .d.other{color:#C2CCD8}
|
||||
.mini-grid .d.today{background:var(--c-blue);color:#fff;font-weight:700}
|
||||
.mini-grid .d.sel{outline:2px solid var(--c-blue);outline-offset:-2px;font-weight:700}
|
||||
.legend{background:#fff;border:1px solid var(--line);border-radius:12px;padding:14px;box-shadow:var(--shadow)}
|
||||
.legend p{margin:0 0 9px;font-size:10.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#8093A8}
|
||||
.legend .li{display:flex;align-items:center;gap:9px;padding:4px 0;font-size:12.5px}
|
||||
.legend .li i{width:11px;height:11px;border-radius:3px;flex:0 0 auto}
|
||||
.cal-main{min-width:0}
|
||||
.cal-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:14px;flex-wrap:wrap}
|
||||
.tb-left{display:flex;align-items:center;gap:10px}
|
||||
.tb-nav{display:flex;gap:2px}
|
||||
.tb-title{font-size:19px;font-weight:800;text-transform:capitalize;letter-spacing:-.3px;margin-left:4px}
|
||||
.view-switch{display:inline-flex;background:#E7EDF4;border-radius:9px;padding:3px}
|
||||
.view-switch button{border:0;background:transparent;font:inherit;font-weight:600;font-size:12.5px;color:var(--muted);padding:6px 14px;border-radius:7px;cursor:pointer}
|
||||
.view-switch button.on{background:#fff;color:var(--ink);box-shadow:0 1px 2px rgba(16,40,80,.12)}
|
||||
.mv{background:#fff;border:1px solid var(--line);border-radius:12px;overflow:hidden;box-shadow:var(--shadow)}
|
||||
.mv-dow{display:grid;grid-template-columns:repeat(7,1fr);background:#F6F9FC;border-bottom:1px solid var(--line)}
|
||||
.mv-dow div{padding:9px 8px;font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#7a8aa0}
|
||||
.mv-grid{display:grid;grid-template-columns:repeat(7,1fr)}
|
||||
.mc{min-height:108px;border-right:1px solid var(--line);border-bottom:1px solid var(--line);padding:6px 7px;cursor:pointer;position:relative;overflow:hidden}
|
||||
.mc:nth-child(7n){border-right:0}
|
||||
.mc:hover{background:#FAFCFE}
|
||||
.mc .dnum{font-size:12.5px;font-weight:600;width:25px;height:25px;display:flex;align-items:center;justify-content:center;border-radius:50%;color:var(--ink)}
|
||||
.mc.other{background:#FAFBFD}.mc.other .dnum{color:#AEBAC8}
|
||||
.mc.today .dnum{background:var(--c-blue);color:#fff}
|
||||
.mc .chip{display:block;font-size:11px;font-weight:600;color:#fff;border-radius:5px;padding:2px 7px;margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer}
|
||||
.mc .chip .t{opacity:.9;font-weight:700;margin-right:4px}
|
||||
.mc .more{font-size:10.5px;color:var(--muted);margin-top:3px;font-weight:600;cursor:pointer}
|
||||
.tg{background:#fff;border:1px solid var(--line);border-radius:12px;overflow:hidden;box-shadow:var(--shadow)}
|
||||
.tg-head{display:grid;border-bottom:1px solid var(--line)}
|
||||
.tg-head .corner{border-right:1px solid var(--line)}
|
||||
.tg-dh{padding:8px 6px;border-right:1px solid var(--line);text-align:center}
|
||||
.tg-dh:last-child{border-right:0}
|
||||
.tg-dh .wd{font-size:11px;font-weight:700;text-transform:uppercase;color:#7a8aa0}
|
||||
.tg-dh .dn{font-size:18px;font-weight:800;line-height:1.25;margin-top:2px;display:inline-flex;align-items:center;justify-content:center;min-width:30px;height:30px}
|
||||
.tg-dh.today .dn{color:#fff;background:var(--c-blue);border-radius:50%}
|
||||
.tg-dh .ad{margin-top:5px;display:flex;flex-direction:column;gap:2px}
|
||||
.tg-dh .ad .chip{font-size:10px;font-weight:600;color:#fff;border-radius:4px;padding:1px 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer}
|
||||
.tg-scroll{max-height:560px;overflow-y:auto}
|
||||
.tg-body{display:grid;position:relative}
|
||||
.tg-hour{border-right:1px solid var(--line);border-top:1px solid var(--line);font-size:10.5px;color:#94A3B8;text-align:right;padding:2px 6px 0 0}
|
||||
.tg-cell{border-right:1px solid var(--line);border-top:1px solid var(--line);cursor:pointer}
|
||||
.tg-cell:last-child{border-right:0}
|
||||
.tg-cell:hover{background:#F7FAFD}
|
||||
.tg-colev{position:relative;pointer-events:none}
|
||||
.tg-ev{position:absolute;left:3px;right:3px;border-radius:6px;padding:3px 7px;color:#fff;font-size:11px;font-weight:600;overflow:hidden;cursor:pointer;pointer-events:auto;box-shadow:0 1px 3px rgba(0,0,0,.2);line-height:1.25}
|
||||
.tg-ev .tm{font-size:9.5px;opacity:.92;font-weight:700;display:block}
|
||||
.mbk{position:fixed;inset:0;background:rgba(13,28,52,.45);display:none;align-items:center;justify-content:center;z-index:90;padding:20px}
|
||||
.mbk.show{display:flex}
|
||||
.modal{background:#fff;border-radius:14px;width:430px;max-width:100%;box-shadow:0 24px 60px rgba(11,30,60,.35);overflow:hidden}
|
||||
.modal-head{display:flex;align-items:center;justify-content:space-between;padding:15px 18px;border-bottom:1px solid var(--line)}
|
||||
.modal-head h3{margin:0;font-size:15px;font-weight:700}
|
||||
.modal-head .x{border:0;background:transparent;cursor:pointer;color:var(--muted);width:30px;height:30px;border-radius:7px;display:flex;align-items:center;justify-content:center}
|
||||
.modal-head .x:hover{background:#F0F4F9}
|
||||
.modal-body{padding:18px;display:grid;gap:14px}
|
||||
.field label{font-size:11.5px;font-weight:700;color:var(--muted);display:block;margin-bottom:5px;text-transform:uppercase;letter-spacing:.03em}
|
||||
.field input,.field select{width:100%;border:1px solid var(--line);border-radius:8px;padding:9px 11px;font:inherit;font-size:13.5px;outline:none;color:var(--ink);background:#fff}
|
||||
.field input:focus,.field select:focus{border-color:var(--c-blue);box-shadow:0 0 0 3px rgba(31,95,168,.12)}
|
||||
.row2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
|
||||
.chk{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:500;color:var(--ink);cursor:pointer}
|
||||
.chk input{width:auto}
|
||||
.cpick{display:flex;gap:9px}
|
||||
.cpick button{width:28px;height:28px;border-radius:50%;border:2px solid transparent;cursor:pointer}
|
||||
.cpick button.sel{border-color:var(--ink)}
|
||||
.modal-foot{display:flex;align-items:center;justify-content:space-between;padding:14px 18px;border-top:1px solid var(--line);gap:10px}
|
||||
.btn-del{border:0;background:transparent;color:var(--c-red);font:inherit;font-weight:600;font-size:13px;cursor:pointer;display:inline-flex;align-items:center;gap:6px}
|
||||
.btn-del .ic{width:15px;height:15px}
|
||||
.btn-del:hover{text-decoration:underline}
|
||||
.foot-r{display:flex;gap:10px;margin-left:auto}
|
||||
@media (max-width:900px){.cal-app{grid-template-columns:1fr}.cal-side{flex-direction:row;flex-wrap:wrap}.mini,.legend{flex:1;min-width:220px}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header class="appbar">
|
||||
<div class="bar-top"><div class="bar-top-in">
|
||||
<span class="flag"><i class="g"></i><i class="w"></i><i class="r"></i></span>
|
||||
<div class="logo-mark">N2</div>
|
||||
<div class="brand-txt"><b>NIS2 Agile</b><span>Conformità Direttiva (UE) 2022/2555 · D.Lgs. 138/2024</span></div>
|
||||
<label class="search"><i data-lucide="search" class="ic"></i><input placeholder="Cerca misura, rischio, incidente…"></label>
|
||||
<span class="spacer"></span>
|
||||
<button class="btn-incident"><i data-lucide="siren" class="ic"></i><span>Registra incidente</span></button>
|
||||
<span class="user"><span class="avatar">SF</span>Simone Fatteri<i data-lucide="chevron-down" class="ic"></i></span>
|
||||
</div></div>
|
||||
<nav class="bar-nav"><div class="bar-nav-in">
|
||||
<div class="nav-item"><a class="nav-link" href="index.html"><i data-lucide="layout-dashboard" class="ic"></i><span>Dashboard</span></a></div>
|
||||
<div class="nav-item"><a class="nav-link active" href="calendario.html"><i data-lucide="calendar" class="ic"></i><span>Calendario</span></a></div>
|
||||
<div class="nav-item"><a class="nav-link" href="organizzazione.html"><i data-lucide="network" class="ic"></i><span>Organizzazione</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega"><div class="mega-col"><p class="mega-head">STRUTTURA</p><a class="mega-link" href="organizzazione.html"><span class="mega-ic"><i data-lucide="network" class="ic"></i></span><span><b>Organigramma</b><span>Ruoli, deleghe e responsabilità</span></span></a><a class="mega-link" href="organizzazione.html"><span class="mega-ic"><i data-lucide="award" class="ic"></i></span><span><b>Competenze</b><span>Skill matrix e copertura dei ruoli</span></span></a></div><div class="mega-col"><p class="mega-head">RELAZIONI</p><a class="mega-link" href="organizzazione.html"><span class="mega-ic"><i data-lucide="users" class="ic"></i></span><span><b>Stakeholder</b><span>Soggetti interni ed esterni rilevanti</span></span></a><a class="mega-link" href="organizzazione.html"><span class="mega-ic"><i data-lucide="activity" class="ic"></i></span><span><b>Attività stakeholder</b><span>Interazioni, richieste e impegni</span></span></a></div><div class="promo"><span class="badge">Apri</span><b>Mappa dei ruoli</b><p>Chi fa cosa nel perimetro NIS2: deleghe, competenze e stakeholder in un colpo d'occhio.</p><a class="go" href="organizzazione.html"><i data-lucide="arrow-right" class="ic"></i></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="rischi.html"><i data-lucide="shield-alert" class="ic"></i><span>Rischi & Incidenti</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega"><div class="mega-col"><p class="mega-head">GESTIONE RISCHIO</p><a class="mega-link" href="rischi.html"><span class="mega-ic"><i data-lucide="shield-alert" class="ic"></i></span><span><b>Rischi</b><span>Registro rischi e piani di trattamento</span></span></a><a class="mega-link" href="rischi.html"><span class="mega-ic"><i data-lucide="link" class="ic"></i></span><span><b>Supply Chain</b><span>Rischio fornitori e terze parti</span></span></a></div><div class="mega-col"><p class="mega-head">EVENTI</p><a class="mega-link" href="rischi.html"><span class="mega-ic"><i data-lucide="siren" class="ic"></i></span><span><b>Incidenti</b><span>Registrazione e notifica Art. 23</span></span></a><a class="mega-link" href="rischi.html"><span class="mega-ic"><i data-lucide="megaphone" class="ic"></i></span><span><b>Segnalazioni</b><span>Whistleblowing e segnalazioni interne</span></span></a></div><div class="promo"><span class="badge">Apri</span><b>Notifica Art. 23</b><p>Dall'incidente alla notifica all'autorità: tempistiche e stato in un unico flusso.</p><a class="go" href="rischi.html"><i data-lucide="arrow-right" class="ic"></i></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="policy.html"><i data-lucide="file-text" class="ic"></i><span>Policy</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega"><div class="mega-col"><p class="mega-head">DOCUMENTI</p><a class="mega-link" href="policy.html"><span class="mega-ic"><i data-lucide="file-text" class="ic"></i></span><span><b>Policy</b><span>Politiche approvate e in revisione</span></span></a><a class="mega-link" href="policy.html"><span class="mega-ic"><i data-lucide="book-open" class="ic"></i></span><span><b>Knowledge Base</b><span>Procedure, linee guida e riferimenti</span></span></a></div><div class="promo"><span class="badge">Apri</span><b>Genera Policy AI</b><p>Bozze di policy assistite dall'AI, allineate ai requisiti della Direttiva.</p><a class="go" href="policy.html"><i data-lucide="arrow-right" class="ic"></i></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="operativita.html"><i data-lucide="settings-2" class="ic"></i><span>Operatività</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega"><div class="mega-col"><p class="mega-head">ATTIVITÀ</p><a class="mega-link" href="operativita.html"><span class="mega-ic"><i data-lucide="graduation-cap" class="ic"></i></span><span><b>Formazione</b><span>Piani formativi e completamento</span></span></a><a class="mega-link" href="operativita.html"><span class="mega-ic"><i data-lucide="boxes" class="ic"></i></span><span><b>Inventario</b><span>Asset e perimetro tecnico</span></span></a></div><div class="mega-col"><p class="mega-head">CONTROLLI</p><a class="mega-link" href="operativita.html"><span class="mega-ic"><i data-lucide="clipboard-check" class="ic"></i></span><span><b>Audit Interni</b><span>Programma e esiti degli audit</span></span></a><a class="mega-link" href="operativita.html"><span class="mega-ic"><i data-lucide="calendar-clock" class="ic"></i></span><span><b>Controlli periodici</b><span>Verifiche ricorrenti pianificate</span></span></a><a class="mega-link" href="operativita.html"><span class="mega-ic"><i data-lucide="gavel" class="ic"></i></span><span><b>Riesame di Direzione</b><span>Riesame periodico della Direzione</span></span></a></div><div class="promo"><span class="badge">Apri</span><b>Calendario operativo</b><p>Formazione, audit e controlli periodici: scadenze sempre sotto controllo.</p><a class="go" href="operativita.html"><i data-lucide="arrow-right" class="ic"></i></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="report.html"><i data-lucide="bar-chart-3" class="ic"></i><span>Report</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega"><div class="mega-col"><p class="mega-head">OUTPUT</p><a class="mega-link" href="report.html"><span class="mega-ic"><i data-lucide="bar-chart-3" class="ic"></i></span><span><b>Audit & Report</b><span>Reportistica e dossier di conformità</span></span></a><a class="mega-link" href="report.html"><span class="mega-ic"><i data-lucide="calendar" class="ic"></i></span><span><b>Calendario</b><span>Vista temporale di scadenze ed eventi</span></span></a></div><div class="promo"><span class="badge">Apri</span><b>Dossier NIS2</b><p>Esporta lo stato di conformità in un dossier pronto per Direzione e autorità.</p><a class="go" href="report.html"><i data-lucide="arrow-right" class="ic"></i></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="ai.html"><i data-lucide="sparkles" class="ic"></i><span>AI</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">ASSISTENTE</p><a class="mega-link" href="ai.html"><span class="mega-ic"><i data-lucide="sparkles" class="ic"></i></span><span><b>AI Cross-Analysis</b><span>Analisi trasversale di rischi e misure</span></span></a><a class="mega-link" href="ai.html"><span class="mega-ic"><i data-lucide="book-open" class="ic"></i></span><span><b>Knowledge Base</b><span>Procedure, linee guida e riferimenti</span></span></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="guida.html"><i data-lucide="life-buoy" class="ic"></i><span>Guida</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">GUIDA</p><a class="mega-link" href="guida.html"><span class="mega-ic"><i data-lucide="life-buoy" class="ic"></i></span><span><b>Guida all'uso</b><span>Manuale e istruzioni della piattaforma</span></span></a><a class="mega-link" href="integrazioni.html"><span class="mega-ic"><i data-lucide="plug" class="ic"></i></span><span><b>Integrazioni Esterne</b><span>Connettori e servizi collegati</span></span></a></div><div class="mega-col"><p class="mega-head">SISTEMA</p><a class="mega-link" href="impostazioni.html"><span class="mega-ic"><i data-lucide="settings" class="ic"></i></span><span><b>Impostazioni</b><span>Configurazione del workspace</span></span></a><a class="mega-link" href="architettura.html"><span class="mega-ic"><i data-lucide="layers" class="ic"></i></span><span><b>Architettura</b><span>Modello dati e struttura del sistema</span></span></a></div></div></div>
|
||||
</div></nav>
|
||||
</header>
|
||||
|
||||
<main class="wrap">
|
||||
<nav class="crumb"><i data-lucide="home" class="ic"></i><a href="index.html">Home</a><i data-lucide="chevron-right" class="ic"></i><span>Calendario</span></nav>
|
||||
|
||||
<div class="cal-app">
|
||||
<aside class="cal-side">
|
||||
<button class="btn-create" id="btn-create"><i data-lucide="plus" class="ic"></i>Crea evento</button>
|
||||
<div class="mini">
|
||||
<div class="mini-head"><b id="mini-label">giugno 2026</b>
|
||||
<div class="mini-nav">
|
||||
<button id="mini-prev" title="Mese precedente"><i data-lucide="chevron-left" class="ic"></i></button>
|
||||
<button id="mini-next" title="Mese successivo"><i data-lucide="chevron-right" class="ic"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mini-grid" id="mini-grid"></div>
|
||||
</div>
|
||||
<div class="legend">
|
||||
<p>Categorie</p>
|
||||
<div class="li"><i style="background:#C62828"></i>Incidenti</div><div class="li"><i style="background:#1E8A5A"></i>Formazione</div><div class="li"><i style="background:#1F5FA8"></i>Compliance / Governance</div><div class="li"><i style="background:#D98324"></i>Operatività</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<section class="cal-main">
|
||||
<div class="cal-toolbar">
|
||||
<div class="tb-left">
|
||||
<button class="ctrl-today" id="tb-today"><i data-lucide="calendar-check" class="ic"></i>Oggi</button>
|
||||
<div class="tb-nav">
|
||||
<button class="ctrl-btn" id="tb-prev" title="Precedente"><i data-lucide="chevron-left" class="ic"></i></button>
|
||||
<button class="ctrl-btn" id="tb-next" title="Successivo"><i data-lucide="chevron-right" class="ic"></i></button>
|
||||
</div>
|
||||
<span class="tb-title" id="tb-title">giugno 2026</span>
|
||||
</div>
|
||||
<div class="view-switch">
|
||||
<button data-v="month" class="on">Mese</button>
|
||||
<button data-v="week">Settimana</button>
|
||||
<button data-v="day">Giorno</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="v-month" class="mv">
|
||||
<div class="mv-dow"><div>Lun</div><div>Mar</div><div>Mer</div><div>Gio</div><div>Ven</div><div>Sab</div><div>Dom</div></div>
|
||||
<div class="mv-grid" id="mv-grid"></div>
|
||||
</div>
|
||||
<div id="v-week" style="display:none"><div class="tg" id="tg-week"></div></div>
|
||||
<div id="v-day" style="display:none"><div class="tg" id="tg-day"></div></div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="mbk" id="mbk">
|
||||
<div class="modal">
|
||||
<div class="modal-head"><h3 id="modal-title">Nuovo evento</h3>
|
||||
<button class="x" onclick="closeModal()"><i data-lucide="x" class="ic"></i></button></div>
|
||||
<div class="modal-body">
|
||||
<div class="field"><label>Titolo</label><input id="m-title" placeholder="Es. Riunione referenti NIS2"></div>
|
||||
<div class="field"><label>Data</label><input type="date" id="m-date"></div>
|
||||
<label class="chk"><input type="checkbox" id="m-allday"> Tutto il giorno</label>
|
||||
<div class="row2" id="time-row">
|
||||
<div class="field"><label>Inizio</label><input type="time" id="m-start" value="09:00"></div>
|
||||
<div class="field"><label>Fine</label><input type="time" id="m-end" value="10:00"></div>
|
||||
</div>
|
||||
<div class="field"><label>Colore</label><div class="cpick"><button data-c="blue" style="background:#1F5FA8" title="blue"></button><button data-c="green" style="background:#1E8A5A" title="green"></button><button data-c="amber" style="background:#D98324" title="amber"></button><button data-c="red" style="background:#C62828" title="red"></button></div></div>
|
||||
</div>
|
||||
<div class="modal-foot">
|
||||
<button class="btn-del" id="btn-del" style="display:none"><i data-lucide="trash-2" class="ic"></i>Elimina</button>
|
||||
<div class="foot-r">
|
||||
<button class="btn-ghost" onclick="closeModal()">Annulla</button>
|
||||
<button class="btn-primary" id="m-save">Salva</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="fab-stack">
|
||||
<button class="fab blue" title="Notifiche"><i data-lucide="bell" class="ic"></i></button>
|
||||
<button class="fab red" title="Assistenza"><i data-lucide="life-buoy" class="ic"></i></button>
|
||||
<button class="fab violet" title="Assistente AI"><i data-lucide="sparkles" class="ic"></i></button>
|
||||
</div>
|
||||
|
||||
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
|
||||
<script>
|
||||
const TODAY=new Date(2026,5,25);
|
||||
const MOf=['gennaio','febbraio','marzo','aprile','maggio','giugno','luglio','agosto','settembre','ottobre','novembre','dicembre'];
|
||||
const MOa=['gen','feb','mar','apr','mag','giu','lug','ago','set','ott','nov','dic'];
|
||||
const WDfull=['luned\u00ec','marted\u00ec','mercoled\u00ec','gioved\u00ec','venerd\u00ec','sabato','domenica'];
|
||||
const WDa=['Lun','Mar','Mer','Gio','Ven','Sab','Dom'];
|
||||
const WDi=['L','M','M','G','V','S','D'];
|
||||
const EVCOL={green:'#1E8A5A',blue:'#1F5FA8',amber:'#D98324',red:'#C62828'};
|
||||
const START=7,END=21,HH=48,NH=END-START;
|
||||
function mi(d){return (d.getDay()+6)%7;}
|
||||
function addD(d,n){return new Date(d.getFullYear(),d.getMonth(),d.getDate()+n);}
|
||||
function pad(n){return String(n).padStart(2,'0');}
|
||||
function iso(d){return d.getFullYear()+'-'+pad(d.getMonth()+1)+'-'+pad(d.getDate());}
|
||||
function monday(d){return addD(d,-mi(d));}
|
||||
function same(a,b){return iso(a)===iso(b);}
|
||||
function parseISO(s){const p=s.split('-');return new Date(+p[0],+p[1]-1,+p[2]);}
|
||||
function toMin(t){const p=t.split(':');return (+p[0])*60+(+p[1]);}
|
||||
|
||||
let events=[
|
||||
{id:1,title:'Formazione: gestione incidenti',date:'2026-06-25',start:'09:30',end:'11:00',color:'green'},
|
||||
{id:2,title:'Review policy accessi',date:'2026-06-25',start:'14:00',end:'15:00',color:'blue'},
|
||||
{id:3,title:'Notifica incidente Art. 23 \u2014 follow-up',date:'2026-06-26',start:'11:00',end:'12:00',color:'red'},
|
||||
{id:4,title:'Riunione referenti NIS2',date:'2026-06-23',start:'15:00',end:'16:30',color:'blue'},
|
||||
{id:5,title:'Audit interno \u2014 area IT',date:'2026-06-17',start:'10:00',end:'12:00',color:'green'},
|
||||
{id:6,title:'Scadenza misura supply chain',date:'2026-06-20',allDay:true,color:'amber'},
|
||||
{id:7,title:'Riesame di Direzione',date:'2026-06-30',start:'16:00',end:'17:30',color:'blue'},
|
||||
{id:8,title:'Controllo periodico backup',date:'2026-07-01',start:'09:00',end:'10:00',color:'amber'},
|
||||
{id:9,title:'Aggiornamento registro rischi',date:'2026-07-03',start:'12:00',end:'13:00',color:'amber'},
|
||||
{id:10,title:'Audit fornitore critico',date:'2026-07-08',start:'10:30',end:'12:30',color:'green'},
|
||||
{id:11,title:'Test piano risposta incidenti',date:'2026-07-10',start:'14:30',end:'16:00',color:'red'},
|
||||
{id:12,title:'Formazione: notifica Art. 23',date:'2026-06-12',start:'09:00',end:'10:30',color:'green'},
|
||||
{id:13,title:'Implementazione MFA',date:'2026-06-29',start:'09:30',end:'11:00',color:'blue'},
|
||||
{id:14,title:'Verifica log e monitoraggio',date:'2026-06-28',start:'15:00',end:'16:00',color:'blue'}
|
||||
];
|
||||
let nextId=100;
|
||||
let view='month';
|
||||
let cursor=new Date(2026,5,25);
|
||||
let selected=new Date(2026,5,25);
|
||||
let miniMonth=new Date(2026,5,1);
|
||||
let curColor='blue', editId=null;
|
||||
|
||||
const $=s=>document.querySelector(s);
|
||||
function evsOf(d){return events.filter(e=>e.date===iso(d)).sort((a,b)=>(a.allDay?-1:0)-(b.allDay?-1:0)||(a.start||'').localeCompare(b.start||''));}
|
||||
|
||||
function renderAll(){renderTitle();renderMini();renderView();}
|
||||
|
||||
function renderTitle(){
|
||||
const el=$('#tb-title');
|
||||
if(view==='month'){el.textContent=MOf[cursor.getMonth()]+' '+cursor.getFullYear();}
|
||||
else if(view==='week'){const m=monday(cursor),s=addD(m,6);
|
||||
el.textContent=(m.getMonth()===s.getMonth()?m.getDate()+' \u2013 '+s.getDate()+' '+MOa[s.getMonth()]:m.getDate()+' '+MOa[m.getMonth()]+' \u2013 '+s.getDate()+' '+MOa[s.getMonth()])+' '+s.getFullYear();}
|
||||
else{el.textContent=WDfull[mi(cursor)]+' '+cursor.getDate()+' '+MOf[cursor.getMonth()]+' '+cursor.getFullYear();}
|
||||
}
|
||||
|
||||
function renderMini(){
|
||||
$('#mini-label').textContent=MOf[miniMonth.getMonth()]+' '+miniMonth.getFullYear();
|
||||
const g=$('#mini-grid');g.innerHTML='';
|
||||
WDi.forEach(w=>{const h=document.createElement('div');h.className='h';h.textContent=w;g.appendChild(h);});
|
||||
const start=monday(new Date(miniMonth.getFullYear(),miniMonth.getMonth(),1));
|
||||
for(let i=0;i<42;i++){const d=addD(start,i);const c=document.createElement('div');
|
||||
c.className='d'+(d.getMonth()!==miniMonth.getMonth()?' other':'')+(same(d,TODAY)?' today':'')+(same(d,selected)?' sel':'');
|
||||
c.textContent=d.getDate();c.onclick=()=>setCursor(d);g.appendChild(c);}
|
||||
}
|
||||
|
||||
function renderView(){
|
||||
$('#v-month').style.display=view==='month'?'block':'none';
|
||||
$('#v-week').style.display=view==='week'?'block':'none';
|
||||
$('#v-day').style.display=view==='day'?'block':'none';
|
||||
document.querySelectorAll('.view-switch button').forEach(b=>b.classList.toggle('on',b.dataset.v===view));
|
||||
if(view==='month')renderMonth();else if(view==='week')renderWeek();else renderDay();
|
||||
}
|
||||
|
||||
function chip(e){
|
||||
const t=e.allDay?'':'<span class="t">'+e.start+'</span>';
|
||||
return '<span class="chip" style="background:'+EVCOL[e.color]+'" data-ev="'+e.id+'">'+t+escapeHtml(e.title)+'</span>';
|
||||
}
|
||||
function escapeHtml(s){return s.replace(/[&<>"]/g,c=>({'&':'&','<':'<','>':'>','"':'"'}[c]));}
|
||||
|
||||
function renderMonth(){
|
||||
const grid=$('#mv-grid');grid.innerHTML='';
|
||||
const first=new Date(cursor.getFullYear(),cursor.getMonth(),1);
|
||||
const start=monday(first);
|
||||
for(let i=0;i<42;i++){
|
||||
const d=addD(start,i);const cell=document.createElement('div');
|
||||
cell.className='mc'+(d.getMonth()!==cursor.getMonth()?' other':'')+(same(d,TODAY)?' today':'');
|
||||
const evs=evsOf(d);
|
||||
let html='<div class="dnum" data-day="'+iso(d)+'">'+d.getDate()+'</div>';
|
||||
evs.slice(0,3).forEach(e=>html+=chip(e));
|
||||
if(evs.length>3)html+='<div class="more" data-day="'+iso(d)+'">+'+(evs.length-3)+' altri</div>';
|
||||
cell.innerHTML=html;
|
||||
cell.onclick=(ev)=>{
|
||||
const ce=ev.target.closest('[data-ev]'); if(ce){openEdit(+ce.dataset.ev);return;}
|
||||
const dn=ev.target.closest('.dnum, .more'); if(dn){view='day';setCursor(parseISO(dn.dataset.day));return;}
|
||||
openCreate(d,null);
|
||||
};
|
||||
grid.appendChild(cell);
|
||||
}
|
||||
}
|
||||
|
||||
function buildTimeGrid(container,days){
|
||||
const cols='56px repeat('+days.length+',1fr)';
|
||||
// head
|
||||
let head='<div class="corner"></div>';
|
||||
days.forEach(d=>{
|
||||
const ad=evsOf(d).filter(e=>e.allDay).map(e=>'<span class="chip" style="background:'+EVCOL[e.color]+'" data-ev="'+e.id+'">'+escapeHtml(e.title)+'</span>').join('');
|
||||
head+='<div class="tg-dh'+(same(d,TODAY)?' today':'')+'"><div class="wd">'+WDa[mi(d)]+'</div><div class="dn">'+d.getDate()+'</div><div class="ad">'+ad+'</div></div>';
|
||||
});
|
||||
// body
|
||||
let body='';
|
||||
for(let h=0;h<NH;h++){
|
||||
body+='<div class="tg-hour" style="grid-column:1;grid-row:'+(h+1)+';height:'+HH+'px">'+pad(START+h)+':00</div>';
|
||||
}
|
||||
days.forEach((d,di)=>{
|
||||
for(let h=0;h<NH;h++){
|
||||
body+='<div class="tg-cell" style="grid-column:'+(di+2)+';grid-row:'+(h+1)+';height:'+HH+'px" data-day="'+iso(d)+'" data-hour="'+(START+h)+'"></div>';
|
||||
}
|
||||
// event overlay column
|
||||
let ovEv='';
|
||||
evsOf(d).filter(e=>!e.allDay).forEach(e=>{
|
||||
const s=toMin(e.start),en=toMin(e.end||e.start);
|
||||
const top=Math.max(0,(s-START*60)/60*HH);
|
||||
const hgt=Math.max(22,(en-s)/60*HH);
|
||||
ovEv+='<div class="tg-ev" style="top:'+top+'px;height:'+hgt+'px;background:'+EVCOL[e.color]+'" data-ev="'+e.id+'"><span class="tm">'+e.start+'\u2013'+(e.end||'')+'</span>'+escapeHtml(e.title)+'</div>';
|
||||
});
|
||||
body+='<div class="tg-colev" style="grid-column:'+(di+2)+';grid-row:1 / span '+NH+'">'+ovEv+'</div>';
|
||||
});
|
||||
container.innerHTML='<div class="tg-head" style="grid-template-columns:'+cols+'">'+head+'</div>'+
|
||||
'<div class="tg-scroll"><div class="tg-body" style="grid-template-columns:'+cols+';grid-template-rows:repeat('+NH+','+HH+'px)">'+body+'</div></div>';
|
||||
container.querySelectorAll('.tg-cell').forEach(c=>c.onclick=()=>openCreate(parseISO(c.dataset.day),+c.dataset.hour));
|
||||
container.querySelectorAll('[data-ev]').forEach(c=>c.onclick=(ev)=>{ev.stopPropagation();openEdit(+c.dataset.ev);});
|
||||
}
|
||||
|
||||
function renderWeek(){const m=monday(cursor);buildTimeGrid($('#tg-week'),Array.from({length:7},(_,i)=>addD(m,i)));}
|
||||
function renderDay(){buildTimeGrid($('#tg-day'),[new Date(cursor)]);}
|
||||
|
||||
function setCursor(d){cursor=new Date(d);selected=new Date(d);miniMonth=new Date(d.getFullYear(),d.getMonth(),1);renderAll();}
|
||||
|
||||
function navTb(dir){
|
||||
if(view==='month')cursor=new Date(cursor.getFullYear(),cursor.getMonth()+dir,1);
|
||||
else if(view==='week')cursor=addD(cursor,7*dir);
|
||||
else cursor=addD(cursor,dir);
|
||||
miniMonth=new Date(cursor.getFullYear(),cursor.getMonth(),1);
|
||||
if(view!=='month')selected=new Date(cursor);
|
||||
renderAll();
|
||||
}
|
||||
|
||||
// ---- modal ----
|
||||
function openCreate(d,hour){
|
||||
editId=null;$('#modal-title').textContent='Nuovo evento';$('#btn-del').style.display='none';
|
||||
$('#m-title').value='';$('#m-date').value=iso(d);
|
||||
$('#m-allday').checked=false;toggleAllday();
|
||||
const sh=hour!=null?hour:9;
|
||||
$('#m-start').value=pad(sh)+':00';$('#m-end').value=pad(Math.min(sh+1,23))+':00';
|
||||
setColor('blue');showModal();$('#m-title').focus();
|
||||
}
|
||||
function openEdit(id){
|
||||
const e=events.find(x=>x.id===id);if(!e)return;
|
||||
editId=id;$('#modal-title').textContent='Modifica evento';$('#btn-del').style.display='inline-flex';
|
||||
$('#m-title').value=e.title;$('#m-date').value=e.date;
|
||||
$('#m-allday').checked=!!e.allDay;toggleAllday();
|
||||
$('#m-start').value=e.start||'09:00';$('#m-end').value=e.end||'10:00';
|
||||
setColor(e.color);showModal();
|
||||
}
|
||||
function setColor(c){curColor=c;document.querySelectorAll('.cpick button').forEach(b=>b.classList.toggle('sel',b.dataset.c===c));}
|
||||
function toggleAllday(){const on=$('#m-allday').checked;$('#time-row').style.display=on?'none':'grid';}
|
||||
function showModal(){$('#mbk').classList.add('show');}
|
||||
function closeModal(){$('#mbk').classList.remove('show');}
|
||||
function saveEvent(){
|
||||
const title=$('#m-title').value.trim();if(!title){$('#m-title').focus();return;}
|
||||
const allDay=$('#m-allday').checked;
|
||||
const o={title,date:$('#m-date').value,color:curColor,allDay};
|
||||
if(!allDay){o.start=$('#m-start').value;o.end=$('#m-end').value;}
|
||||
if(editId){Object.assign(events.find(e=>e.id===editId),o,{id:editId});}
|
||||
else{o.id=nextId++;events.push(o);}
|
||||
closeModal();renderAll();
|
||||
}
|
||||
function delEvent(){if(editId){events=events.filter(e=>e.id!==editId);}closeModal();renderAll();}
|
||||
|
||||
// ---- wire ----
|
||||
document.getElementById('tb-today').onclick=()=>setCursor(new Date(TODAY));
|
||||
document.getElementById('tb-prev').onclick=()=>navTb(-1);
|
||||
document.getElementById('tb-next').onclick=()=>navTb(1);
|
||||
document.getElementById('mini-prev').onclick=()=>{miniMonth=new Date(miniMonth.getFullYear(),miniMonth.getMonth()-1,1);renderMini();};
|
||||
document.getElementById('mini-next').onclick=()=>{miniMonth=new Date(miniMonth.getFullYear(),miniMonth.getMonth()+1,1);renderMini();};
|
||||
document.querySelectorAll('.view-switch button').forEach(b=>b.onclick=()=>{view=b.dataset.v;renderView();renderTitle();});
|
||||
document.getElementById('btn-create').onclick=()=>openCreate(selected,9);
|
||||
document.getElementById('m-allday').onchange=toggleAllday;
|
||||
document.querySelectorAll('.cpick button').forEach(b=>b.onclick=()=>setColor(b.dataset.c));
|
||||
document.getElementById('m-save').onclick=saveEvent;
|
||||
document.getElementById('btn-del').onclick=delEvent;
|
||||
document.getElementById('mbk').addEventListener('click',e=>{if(e.target.id==='mbk')closeModal();});
|
||||
|
||||
renderAll();
|
||||
window.lucide && lucide.createIcons();
|
||||
</script>
|
||||
</body></html>
|
||||
@@ -0,0 +1,451 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Dashboard · NIS2 Agile</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root{
|
||||
--navy-top:#0A2E54; --navy-nav:#103A61; --navy-hover:#1B4A75; --gold:#F0B429;
|
||||
--bg:#EFF4FA; --card:#FFFFFF; --ink:#15263C; --muted:#64748B; --line:#E3E9F0;
|
||||
--c-green:#1E8A5A; --c-blue:#1F5FA8; --c-amber:#D98324; --c-red:#C62828;
|
||||
--radius:12px; --shadow:0 1px 2px rgba(16,40,80,.06),0 8px 24px rgba(16,40,80,.06);
|
||||
}
|
||||
*{box-sizing:border-box} html{-webkit-text-size-adjust:100%}
|
||||
body{margin:0;background:var(--bg);color:var(--ink);
|
||||
font-family:'Inter',system-ui,-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5}
|
||||
a{color:inherit;text-decoration:none}
|
||||
:focus-visible{outline:2px solid var(--gold);outline-offset:2px;border-radius:4px}
|
||||
.appbar{position:sticky;top:0;z-index:50}
|
||||
.bar-top{background:var(--navy-top);color:#fff}
|
||||
.bar-top-in{max-width:1280px;margin:0 auto;display:flex;align-items:center;gap:16px;padding:10px 24px}
|
||||
.flag{width:18px;height:13px;border-radius:2px;overflow:hidden;display:flex;flex:0 0 auto;box-shadow:0 0 0 1px rgba(255,255,255,.25)}
|
||||
.flag i{flex:1}.flag .g{background:#1f8a4c}.flag .w{background:#fff}.flag .r{background:#cd2b2b}
|
||||
.logo-mark{width:34px;height:34px;border-radius:8px;background:var(--c-green);display:flex;align-items:center;justify-content:center;color:#fff;font-weight:800;font-size:13px;flex:0 0 auto}
|
||||
.brand-txt{line-height:1.1;min-width:0}
|
||||
.brand-txt b{font-size:15px;font-weight:700}
|
||||
.brand-txt span{display:block;font-size:10.5px;color:#A9C2DC;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||
.search{flex:1;max-width:340px;display:flex;align-items:center;gap:8px;background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.16);border-radius:8px;padding:7px 12px;color:#cfe0f1;min-width:120px}
|
||||
.search input{flex:1;border:0;background:transparent;color:#fff;font:inherit;outline:none;min-width:0}
|
||||
.search input::placeholder{color:#9db8d2}
|
||||
.spacer{flex:1}
|
||||
.btn-incident{display:inline-flex;align-items:center;gap:8px;background:#D24545;color:#fff;border:0;border-radius:8px;padding:9px 15px;font:inherit;font-weight:600;font-size:13px;cursor:pointer;box-shadow:0 1px 2px rgba(120,20,20,.35);white-space:nowrap}
|
||||
.btn-incident:hover{background:#BF3A3A}
|
||||
.btn-incident .ic{width:16px;height:16px}
|
||||
.user{display:flex;align-items:center;gap:8px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.16);border-radius:8px;padding:5px 10px 5px 5px;font-size:12px;font-weight:600;cursor:pointer;white-space:nowrap}
|
||||
.user:hover{background:rgba(255,255,255,.16)}
|
||||
.avatar{width:24px;height:24px;border-radius:6px;background:var(--c-green);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700}
|
||||
.bar-nav{background:var(--navy-nav);border-top:1px solid rgba(255,255,255,.06)}
|
||||
.bar-nav-in{max-width:1280px;margin:0 auto;padding:0 16px;display:flex;align-items:stretch;gap:2px;flex-wrap:wrap}
|
||||
.nav-item{position:relative}
|
||||
.nav-link{display:flex;align-items:center;gap:7px;color:#cfe0f1;font-weight:600;font-size:13px;padding:13px 14px;white-space:nowrap;border-bottom:3px solid transparent;cursor:pointer}
|
||||
.nav-link .ic{width:15px;height:15px;opacity:.9}
|
||||
.nav-link .caret{width:13px;height:13px;opacity:.7;margin-left:-2px}
|
||||
.nav-item:hover>.nav-link{color:#fff;background:rgba(255,255,255,.06)}
|
||||
.nav-link.active{color:#fff;border-bottom-color:var(--gold)}
|
||||
.mega{position:absolute;top:100%;left:0;background:#fff;color:var(--ink);border-radius:0 0 14px 14px;box-shadow:0 18px 40px rgba(11,40,80,.18);border:1px solid var(--line);border-top:0;padding:22px;display:none;grid-template-columns:auto auto 250px;gap:30px;min-width:560px;z-index:60}
|
||||
.nav-item:hover .mega,.nav-item:focus-within .mega{display:grid}
|
||||
.nav-item:nth-last-child(-n+3) .mega{left:auto;right:0}
|
||||
.mega.no-promo{min-width:auto}
|
||||
.nav-item:hover .mega.no-promo,.nav-item:focus-within .mega.no-promo{display:flex;gap:30px;width:auto}
|
||||
.mega-col{min-width:190px}
|
||||
.mega-head{font-size:10.5px;font-weight:700;letter-spacing:.12em;color:#94A3B8;text-transform:uppercase;margin:0 0 12px}
|
||||
.mega-link{display:flex;gap:11px;padding:8px;border-radius:9px;align-items:flex-start}
|
||||
.mega-link:hover{background:#F3F7FC}
|
||||
.mega-link .mega-ic{width:36px;height:36px;border-radius:10px;background:#EAF1FA;color:var(--c-blue);display:flex;align-items:center;justify-content:center;flex:0 0 auto}
|
||||
.mega-ic .ic{width:21px;height:21px;display:block}
|
||||
.mega-link b{display:block;font-size:13.5px;font-weight:700}
|
||||
.mega-link span{display:block;font-size:11.5px;color:var(--muted);margin-top:2px}
|
||||
.promo{background:linear-gradient(160deg,#1F5FA8,#0F3F77);color:#fff;border-radius:12px;padding:18px;display:flex;flex-direction:column;gap:10px}
|
||||
.promo .badge{align-self:flex-start;background:rgba(255,255,255,.18);font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:4px 9px;border-radius:999px}
|
||||
.promo b{font-size:16px}
|
||||
.promo p{margin:0;font-size:12px;color:#cfe0f3;line-height:1.45}
|
||||
.promo .go{margin-top:auto;align-self:flex-end;width:38px;height:38px;border-radius:9px;background:#fff;color:var(--c-blue);display:flex;align-items:center;justify-content:center}
|
||||
.wrap{max-width:1280px;margin:0 auto;padding:22px 24px 80px}
|
||||
.crumb{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--muted);margin-bottom:14px}
|
||||
.crumb .ic{width:13px;height:13px}.crumb a:hover{color:var(--ink)}
|
||||
.page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;margin-bottom:24px;flex-wrap:wrap}
|
||||
.page-head h1{margin:0;font-size:26px;font-weight:800;letter-spacing:-.4px}
|
||||
.page-head .sub{margin:4px 0 0;color:var(--muted);font-size:13.5px}
|
||||
.date{display:flex;align-items:center;gap:8px;color:var(--muted);font-size:13px;background:#fff;border:1px solid var(--line);border-radius:9px;padding:8px 12px}
|
||||
.date .ic{width:15px;height:15px}
|
||||
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow)}
|
||||
.card-pad{padding:20px}
|
||||
.stack{display:grid;gap:18px}
|
||||
.cal-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px;flex-wrap:wrap}
|
||||
.cal-head h3{margin:0;font-size:15px;font-weight:700}
|
||||
.cal-ctrl{display:flex;gap:6px;align-items:center}
|
||||
.ctrl-btn{width:32px;height:32px;border:1px solid var(--line);border-radius:8px;background:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer}
|
||||
.ctrl-btn:hover{background:#F5F8FC}
|
||||
.ctrl-btn .ic{width:16px;height:16px;color:var(--muted)}
|
||||
.ctrl-today{height:32px;padding:0 13px;border:1px solid var(--line);border-radius:8px;background:#fff;font:inherit;font-weight:600;font-size:12px;display:flex;align-items:center;gap:6px;cursor:pointer;color:var(--ink)}
|
||||
.ctrl-today:hover{background:#F5F8FC}
|
||||
.ctrl-today .ic{width:14px;height:14px;color:var(--c-blue)}
|
||||
.daystrip{display:flex;gap:8px;overflow-x:auto;padding-bottom:4px;scrollbar-width:thin}
|
||||
.daycell{flex:1 1 0;min-width:64px;border:1px solid var(--line);border-radius:11px;background:#fff;padding:11px 6px 9px;text-align:center;position:relative;cursor:pointer;transition:border-color .12s,transform .12s,box-shadow .12s}
|
||||
.daycell:hover{border-color:#9FBEDD;box-shadow:0 4px 12px rgba(16,40,80,.08)}
|
||||
.daycell .wd{font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:#8093A8}
|
||||
.daycell .dn{font-size:21px;font-weight:800;line-height:1.15;margin-top:3px}
|
||||
.daycell .mo{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;margin-top:1px}
|
||||
.daycell.weekend{background:#F5F8FC}
|
||||
.daycell.weekend .wd{color:#A6B4C6}
|
||||
.daycell.today{background:var(--navy-nav);border-color:var(--navy-nav)}
|
||||
.daycell.today:hover{border-color:var(--navy-hover);box-shadow:0 6px 16px rgba(16,40,80,.22)}
|
||||
.daycell.today .wd{color:#C7D9EC}.daycell.today .dn,.daycell.today .mo{color:#fff}
|
||||
.daycell.today::before{content:"";position:absolute;left:0;right:0;top:0;height:3px;background:var(--gold);border-radius:11px 11px 0 0}
|
||||
.dots{display:flex;gap:3px;justify-content:center;margin-top:7px;min-height:6px}
|
||||
.ev{width:6px;height:6px;border-radius:50%;display:inline-block}
|
||||
.ev.green{background:var(--c-green)}.ev.blue{background:var(--c-blue)}.ev.amber{background:var(--c-amber)}.ev.red{background:var(--c-red)}
|
||||
.weekstrip{display:grid;grid-template-columns:1fr 1.25fr 1fr;gap:14px;align-items:start}
|
||||
.weekblock{border:1px solid var(--line);border-radius:12px;background:#FAFCFE;padding:13px;cursor:pointer;transition:border-color .12s,box-shadow .12s}
|
||||
.weekblock:hover{border-color:#9FBEDD;box-shadow:0 6px 16px rgba(16,40,80,.10)}
|
||||
.weekblock.current{background:#fff;border-color:#B9CFE6;box-shadow:0 6px 18px rgba(16,40,80,.08)}
|
||||
.weekblock .wl{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;gap:8px}
|
||||
.weekblock .wl b{font-size:12.5px;font-weight:700;color:var(--muted)}
|
||||
.weekblock.current .wl b{color:var(--c-blue)}
|
||||
.weekblock .wl span{font-size:9.5px;color:#A6B4C6;text-transform:uppercase;letter-spacing:.07em;font-weight:700;white-space:nowrap}
|
||||
.week7{display:grid;grid-template-columns:repeat(7,1fr);gap:3px}
|
||||
.mini{text-align:center;border-radius:8px;padding:6px 0 5px}
|
||||
.mini .mi-wd{font-size:9.5px;font-weight:700;color:#9aa8ba;text-transform:uppercase}
|
||||
.mini .mi-dn{font-size:13px;font-weight:700;margin-top:1px}
|
||||
.mini.weekend .mi-wd,.mini.weekend .mi-dn{color:#A6B4C6}
|
||||
.mini.today{background:var(--navy-nav)}.mini.today .mi-wd{color:#C7D9EC}.mini.today .mi-dn{color:#fff}
|
||||
.mini .mi-ev{display:flex;gap:2px;justify-content:center;min-height:5px;margin-top:3px}
|
||||
.mini .mi-ev .ev{width:4px;height:4px}
|
||||
.cal-pop{position:fixed;z-index:80;display:none;width:252px;background:#fff;border:1px solid var(--line);border-radius:11px;box-shadow:0 14px 36px rgba(11,40,80,.20);padding:13px 14px;pointer-events:none;opacity:0;transform:translateY(5px);transition:opacity .12s ease,transform .12s ease}
|
||||
.cal-pop.show{opacity:1;transform:none}
|
||||
.cal-pop h4{margin:0 0 9px;font-size:12.5px;font-weight:700;text-transform:capitalize}
|
||||
.cal-pop .pe{display:flex;gap:9px;align-items:flex-start;padding:6px 0;border-top:1px solid #EFF3F8}
|
||||
.cal-pop .pe:first-of-type{border-top:0;padding-top:0}
|
||||
.cal-pop .pe .ev{margin-top:5px;flex:0 0 auto}
|
||||
.cal-pop .pe .tt{font-size:10.5px;color:var(--muted);font-variant-numeric:tabular-nums;display:block}
|
||||
.cal-pop .pe b{font-size:12px;font-weight:600;line-height:1.3;display:block}
|
||||
.cal-pop .empty{font-size:12px;color:#94A3B8}
|
||||
.fab-stack{position:fixed;right:22px;bottom:22px;display:flex;flex-direction:column;gap:12px;z-index:40}
|
||||
.fab{width:46px;height:46px;border-radius:50%;border:0;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 8px 20px rgba(16,40,80,.22)}
|
||||
.fab .ic{width:20px;height:20px}
|
||||
.fab.blue{background:var(--c-blue)}.fab.red{background:var(--c-red)}.fab.violet{background:#7C4DD6}
|
||||
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
|
||||
.split2{display:grid;grid-template-columns:1fr 1fr;gap:18px}
|
||||
.split-anag{display:grid;grid-template-columns:1.35fr 1fr;gap:18px}
|
||||
.sec-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:14px}
|
||||
.sec-head h3{margin:0;font-size:15px;font-weight:700}
|
||||
.sec-head .hint{font-size:11.5px;color:var(--muted)}
|
||||
.stat{display:flex;gap:14px;align-items:flex-start;border-left:4px solid var(--c-blue);transition:box-shadow .12s,transform .12s}
|
||||
a.stat{color:inherit}
|
||||
a.stat:hover{box-shadow:0 8px 20px rgba(16,40,80,.13);transform:translateY(-1px)}
|
||||
.stat.green{border-left-color:var(--c-green)}.stat.amber{border-left-color:var(--c-amber)}.stat.blue{border-left-color:var(--c-blue)}
|
||||
.stat .ibox{width:42px;height:42px;border-radius:11px;display:flex;align-items:center;justify-content:center;flex:0 0 auto;background:#EAF1FA;color:var(--c-blue)}
|
||||
.stat.green .ibox{background:#E6F4EC;color:var(--c-green)}.stat.amber .ibox{background:#FBF1E2;color:var(--c-amber)}
|
||||
.stat .ibox .ic{width:20px;height:20px}
|
||||
.stat .lbl{font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#7a8aa0}
|
||||
.stat .val{font-size:27px;font-weight:800;line-height:1.1;margin:3px 0 1px}
|
||||
.stat.green .val{color:var(--c-green)}.stat.amber .val{color:var(--c-amber)}.stat.blue .val{color:var(--c-blue)}
|
||||
.stat .sub{font-size:12px;color:var(--muted)}
|
||||
.bar{height:7px;background:#EAF0F6;border-radius:99px;overflow:hidden;margin-top:9px;max-width:180px}
|
||||
.bar>i{display:block;height:100%;background:var(--c-amber);border-radius:99px}
|
||||
.btn-primary{display:inline-flex;align-items:center;gap:7px;background:var(--c-blue);color:#fff;border:0;border-radius:8px;padding:8px 13px;font:inherit;font-weight:600;font-size:12.5px;cursor:pointer}
|
||||
.btn-primary:hover{background:#1A5494}
|
||||
.btn-primary .ic{width:15px;height:15px}
|
||||
.btn-ghost{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line);background:#fff;border-radius:8px;padding:7px 12px;font:inherit;font-weight:600;font-size:12.5px;color:var(--ink);cursor:pointer}
|
||||
.btn-ghost:hover{background:#F5F8FC;border-color:#c7d4e4}
|
||||
.btn-ghost .ic{width:15px;height:15px;color:var(--c-blue)}
|
||||
.dpill{flex:0 0 auto;width:46px;text-align:center;background:#EFF4FB;border:1px solid var(--line);border-radius:9px;padding:6px 0}
|
||||
.dpill b{display:block;font-size:15px;font-weight:800;line-height:1}
|
||||
.dpill span{font-size:9.5px;font-weight:700;letter-spacing:.05em;color:var(--muted);text-transform:uppercase}
|
||||
.sca{display:flex;gap:13px;align-items:flex-start;padding:12px 0;border-top:1px solid var(--line)}
|
||||
.sca:first-of-type{border-top:0;padding-top:0}
|
||||
.sca .body{flex:1;min-width:0}
|
||||
.sca .body b{font-size:13px;font-weight:600;display:block}
|
||||
.meta{display:flex;gap:8px;align-items:center;margin-top:5px;flex-wrap:wrap}
|
||||
.who{font-size:11.5px;color:var(--muted)}
|
||||
.badge-t{font-size:10px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;padding:2px 7px;border-radius:6px;background:#EEF2F7;color:#5b6b80;white-space:nowrap}
|
||||
.badge-t.blue{background:#E7F0FB;color:#1F5FA8}.badge-t.amber{background:#FBF1E2;color:#9A6418}.badge-t.red{background:#FBE9E9;color:#B23636}.badge-t.green{background:#E6F4EC;color:#1E7A4E}.badge-t.gray{background:#EEF2F7;color:#5b6b80}
|
||||
.act-scroll{max-height:330px;overflow-y:auto;padding-right:4px;scrollbar-width:thin}
|
||||
.act{display:flex;gap:12px;align-items:flex-start;justify-content:space-between;padding:12px;border:1px solid var(--line);border-radius:10px;margin-bottom:8px;background:#fff}
|
||||
.act:last-child{margin-bottom:0}
|
||||
.act .body{flex:1;min-width:0}.act .body b{font-size:13px;font-weight:600;display:block}
|
||||
.anag{display:flex;gap:16px;align-items:flex-start}
|
||||
.anag-logo{width:60px;height:60px;border-radius:13px;background:linear-gradient(135deg,#143A5C,#1F5FA8);color:#fff;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:17px;letter-spacing:.5px;flex:0 0 auto}
|
||||
.anag .info{flex:1;min-width:0}
|
||||
.anag .nm{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
|
||||
.anag .nm h3{margin:0;font-size:16px;font-weight:800}
|
||||
.badge-nis{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;padding:3px 8px;border-radius:6px;background:#E7F0FB;color:#1F5FA8}
|
||||
.anag-grid{display:grid;grid-template-columns:1fr 1fr;gap:11px 18px;margin-top:14px}
|
||||
.anag-grid .f span{display:block;font-size:10.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#8093A8}
|
||||
.anag-grid .f b{font-size:13px;font-weight:600}
|
||||
.doc{display:flex;align-items:center;gap:12px;width:100%;text-align:left;border:1px solid var(--line);background:#fff;border-radius:10px;padding:12px 14px;cursor:pointer;font:inherit;margin-bottom:10px}
|
||||
.doc:last-child{margin-bottom:0}
|
||||
.doc:hover{border-color:#c7d4e4;background:#FAFCFE}
|
||||
.doc .di{width:36px;height:36px;border-radius:9px;background:#EAF1FA;color:var(--c-blue);display:flex;align-items:center;justify-content:center;flex:0 0 auto}
|
||||
.doc .di .ic{width:18px;height:18px}
|
||||
.doc .dt{flex:1;min-width:0}
|
||||
.doc .dt b{font-size:13.5px;font-weight:700;display:block}
|
||||
.doc .dt small{font-size:11px;color:var(--muted)}
|
||||
.doc .st{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;font-weight:700;padding:5px 10px;border-radius:999px;white-space:nowrap}
|
||||
.doc .st .ic{width:14px;height:14px}
|
||||
.doc.has .st{background:#E6F4EC;color:#1E7A4E}
|
||||
.doc.miss .st{background:#FBF1E2;color:#9A6418}
|
||||
@media (max-width:900px){.weekstrip{grid-template-columns:1fr}.grid3,.split2,.split-anag{grid-template-columns:1fr}.mega{grid-template-columns:1fr;min-width:280px}.search{display:none}}
|
||||
@media (max-width:560px){.brand-txt span{display:none}.btn-incident span{display:none}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header class="appbar">
|
||||
<div class="bar-top"><div class="bar-top-in">
|
||||
<span class="flag"><i class="g"></i><i class="w"></i><i class="r"></i></span>
|
||||
<div class="logo-mark">N2</div>
|
||||
<div class="brand-txt"><b>NIS2 Agile</b><span>Conformità Direttiva (UE) 2022/2555 · D.Lgs. 138/2024</span></div>
|
||||
<label class="search"><i data-lucide="search" class="ic"></i><input placeholder="Cerca misura, rischio, incidente…"></label>
|
||||
<span class="spacer"></span>
|
||||
<button class="btn-incident"><i data-lucide="siren" class="ic"></i><span>Registra incidente</span></button>
|
||||
<span class="user"><span class="avatar">SF</span>Simone Fatteri<i data-lucide="chevron-down" class="ic"></i></span>
|
||||
</div></div>
|
||||
<nav class="bar-nav"><div class="bar-nav-in">
|
||||
<div class="nav-item"><a class="nav-link active" href="index.html"><i data-lucide="layout-dashboard" class="ic"></i><span>Dashboard</span></a></div>
|
||||
<div class="nav-item"><a class="nav-link" href="calendario.html"><i data-lucide="calendar" class="ic"></i><span>Calendario</span></a></div>
|
||||
<div class="nav-item"><a class="nav-link" href="stakeholders.html"><i data-lucide="users" class="ic"></i><span>Stakeholders</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">RELAZIONI</p><a class="mega-link" href="stakeholders.html"><span class="mega-ic"><i data-lucide="handshake" class="ic"></i></span><span><b>Stakeholders</b><span>Soggetti interni ed esterni rilevanti</span></span></a><a class="mega-link" href="supply-chain.html"><span class="mega-ic"><i data-lucide="link" class="ic"></i></span><span><b>Supply-Chain</b><span>Rischio fornitori e terze parti</span></span></a><a class="mega-link" href="stakeholder-activities.html"><span class="mega-ic"><i data-lucide="activity" class="ic"></i></span><span><b>Attività su Stakeholders</b><span>Interazioni, richieste e impegni</span></span></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="organigramma.html"><i data-lucide="building-2" class="ic"></i><span>Struttura interna</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">RUOLI E COMPETENZE</p><a class="mega-link" href="organigramma.html"><span class="mega-ic"><i data-lucide="network" class="ic"></i></span><span><b>Organigramma</b><span>Ruoli, deleghe e responsabilità</span></span></a><a class="mega-link" href="competenze.html"><span class="mega-ic"><i data-lucide="award" class="ic"></i></span><span><b>Competenze</b><span>Skill matrix e copertura dei ruoli</span></span></a><a class="mega-link" href="assessment.html"><span class="mega-ic"><i data-lucide="git-compare" class="ic"></i></span><span><b>GAP Analysis</b><span>Scostamento tra stato attuale e atteso</span></span></a><a class="mega-link" href="training.html"><span class="mega-ic"><i data-lucide="graduation-cap" class="ic"></i></span><span><b>Formazione</b><span>Piani formativi e completamento</span></span></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="risks.html"><i data-lucide="shield-alert" class="ic"></i><span>Rischi</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">GESTIONE RISCHIO</p><a class="mega-link" href="risks.html"><span class="mega-ic"><i data-lucide="map" class="ic"></i></span><span><b>Mappa dei rischi</b><span>Registro rischi e piani di trattamento</span></span></a><a class="mega-link" href="assets.html"><span class="mega-ic"><i data-lucide="boxes" class="ic"></i></span><span><b>Inventario</b><span>Asset e perimetro tecnico</span></span></a><a class="mega-link" href="policies.html"><span class="mega-ic"><i data-lucide="file-text" class="ic"></i></span><span><b>Policy</b><span>Politiche approvate e in revisione</span></span></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="whistleblowing.html"><i data-lucide="radar" class="ic"></i><span>Monitoraggio</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">VIGILANZA E AUDIT</p><a class="mega-link" href="whistleblowing.html"><span class="mega-ic"><i data-lucide="megaphone" class="ic"></i></span><span><b>Segnalazioni ricevute</b><span>Whistleblowing e segnalazioni interne</span></span></a><a class="mega-link" href="internal-audits.html"><span class="mega-ic"><i data-lucide="clipboard-check" class="ic"></i></span><span><b>Audit interni</b><span>Programma e esiti degli audit</span></span></a><a class="mega-link" href="reports.html"><span class="mega-ic"><i data-lucide="file-check" class="ic"></i></span><span><b>Audit ACN</b><span>Verifiche e ispezioni dell'autorità</span></span></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="report.html"><i data-lucide="scale" class="ic"></i><span>Lex e ISO</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">NORMATIVA E ISO</p><a class="mega-link" href="normative.html"><span class="mega-ic"><i data-lucide="scroll-text" class="ic"></i></span><span><b>Normative</b><span>Direttiva, decreto e riferimenti applicabili</span></span></a><a class="mega-link" href="isms.html"><span class="mega-ic"><i data-lucide="shield-check" class="ic"></i></span><span><b>Modello SGSI (ISO 27001)</b><span>Sistema di gestione sicurezza informazioni</span></span></a><a class="mega-link" href="misure-requisiti.html"><span class="mega-ic"><i data-lucide="list-checks" class="ic"></i></span><span><b>Misure e requisiti ACN</b><span>Misure tecniche e organizzative Art. 21</span></span></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="ai.html"><i data-lucide="sparkles" class="ic"></i><span>AI</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">ASSISTENTE</p><a class="mega-link" href="cross-analysis.html"><span class="mega-ic"><i data-lucide="sparkles" class="ic"></i></span><span><b>AI Cross-Analysis</b><span>Analisi trasversale di rischi e misure</span></span></a><a class="mega-link" href="kb.html"><span class="mega-ic"><i data-lucide="book-open" class="ic"></i></span><span><b>Knowledge Base</b><span>Procedure, linee guida e riferimenti</span></span></a></div></div></div>
|
||||
<div class="nav-item"><a class="nav-link" href="guida.html"><i data-lucide="life-buoy" class="ic"></i><span>Guida</span><i data-lucide="chevron-down" class="caret"></i></a><div class="mega no-promo"><div class="mega-col"><p class="mega-head">GUIDA</p><a class="mega-link" href="guida.html"><span class="mega-ic"><i data-lucide="life-buoy" class="ic"></i></span><span><b>Guida all'uso</b><span>Manuale e istruzioni della piattaforma</span></span></a><a class="mega-link" href="integrazioniext.html"><span class="mega-ic"><i data-lucide="plug" class="ic"></i></span><span><b>Integrazioni Esterne</b><span>Connettori e servizi collegati</span></span></a></div><div class="mega-col"><p class="mega-head">SISTEMA</p><a class="mega-link" href="setting.html"><span class="mega-ic"><i data-lucide="settings" class="ic"></i></span><span><b>Impostazioni</b><span>Configurazione del workspace</span></span></a><a class="mega-link" href="architecture.html"><span class="mega-ic"><i data-lucide="layers" class="ic"></i></span><span><b>Architettura</b><span>Modello dati e struttura del sistema</span></span></a></div></div></div>
|
||||
</div></nav>
|
||||
</header>
|
||||
|
||||
<main class="wrap">
|
||||
<nav class="crumb"><i data-lucide="home" class="ic"></i><a href="index.html">Home</a><i data-lucide="chevron-right" class="ic"></i><span>Dashboard</span></nav>
|
||||
<div class="page-head">
|
||||
<div><h1>Dashboard</h1><p class="sub">Stato di conformità NIS2 del tuo perimetro</p></div>
|
||||
<div class="date"><i data-lucide="calendar" class="ic"></i>giovedì 25 giugno 2026</div>
|
||||
</div>
|
||||
|
||||
<div class="stack">
|
||||
<section class="card card-pad">
|
||||
<div class="cal-head">
|
||||
<h3>Monitor Giornaliero</h3>
|
||||
<div class="cal-ctrl">
|
||||
<button class="ctrl-btn" id="d-prev" title="Giorni precedenti"><i data-lucide="chevron-left" class="ic"></i></button>
|
||||
<button class="ctrl-today" id="d-today"><i data-lucide="calendar-check" class="ic"></i>Oggi</button>
|
||||
<button class="ctrl-btn" id="d-next" title="Giorni successivi"><i data-lucide="chevron-right" class="ic"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="daystrip" id="daystrip"></div>
|
||||
</section>
|
||||
|
||||
<section class="card card-pad">
|
||||
<div class="cal-head">
|
||||
<h3>Monitor Settimanale</h3>
|
||||
<div class="cal-ctrl">
|
||||
<button class="ctrl-btn" id="w-prev" title="Settimana precedente"><i data-lucide="chevron-left" class="ic"></i></button>
|
||||
<button class="ctrl-today" id="w-today"><i data-lucide="calendar-check" class="ic"></i>Questa settimana</button>
|
||||
<button class="ctrl-btn" id="w-next" title="Settimana successiva"><i data-lucide="chevron-right" class="ic"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="weekstrip" id="weekstrip"></div>
|
||||
</section>
|
||||
|
||||
<div class="grid3">
|
||||
<a href="assessment.html" class="card card-pad stat blue">
|
||||
<div class="ibox"><i data-lucide="git-compare" class="ic"></i></div>
|
||||
<div style="flex:1;min-width:0"><div class="lbl">Gap analysis in corso</div><div class="val">4</div><div class="sub">su 6 aree di valutazione</div></div>
|
||||
</a>
|
||||
<a href="training.html" class="card card-pad stat green">
|
||||
<div class="ibox"><i data-lucide="graduation-cap" class="ic"></i></div>
|
||||
<div style="flex:1;min-width:0"><div class="lbl">Formazione in corso</div><div class="val">3</div><div class="sub">corsi attivi alla data odierna</div></div>
|
||||
</a>
|
||||
<a href="risks.html" class="card card-pad stat amber">
|
||||
<div class="ibox"><i data-lucide="shield-check" class="ic"></i></div>
|
||||
<div style="flex:1;min-width:0"><div class="lbl">Rischi valutati</div><div class="val">68%</div><div class="sub">29 su 42 del registro rischi</div><div class="bar"><i style="width:68%"></i></div></div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="split2">
|
||||
<section class="card card-pad">
|
||||
<div class="sec-head"><h3>Scadenze · prossimi 10 giorni</h3><span class="hint">6 in agenda</span></div>
|
||||
<div class="sca"><div class="dpill"><b>26</b><span>Giu</span></div><div class="body"><b>Notifica incidente Art. 23 — follow-up</b><div class="meta"><span class="badge-t red">Incidente</span><span class="who">M. Rossi</span></div></div></div><div class="sca"><div class="dpill"><b>28</b><span>Giu</span></div><div class="body"><b>Completamento corso «Gestione incidenti»</b><div class="meta"><span class="badge-t green">Formazione</span><span class="who">A. Ferretti</span></div></div></div><div class="sca"><div class="dpill"><b>30</b><span>Giu</span></div><div class="body"><b>Riesame di Direzione — chiusura trimestre</b><div class="meta"><span class="badge-t blue">Governance</span><span class="who">Direzione</span></div></div></div><div class="sca"><div class="dpill"><b>01</b><span>Lug</span></div><div class="body"><b>Controllo periodico backup e ripristini</b><div class="meta"><span class="badge-t amber">Controllo</span><span class="who">Reparto IT</span></div></div></div><div class="sca"><div class="dpill"><b>02</b><span>Lug</span></div><div class="body"><b>Revisione SoA — ISO/IEC 27001</b><div class="meta"><span class="badge-t blue">Compliance</span><span class="who">CISO</span></div></div></div><div class="sca"><div class="dpill"><b>03</b><span>Lug</span></div><div class="body"><b>Aggiornamento registro rischi</b><div class="meta"><span class="badge-t amber">Rischio</span><span class="who">Risk Owner</span></div></div></div>
|
||||
</section>
|
||||
<section class="card card-pad">
|
||||
<div class="sec-head"><h3>Attività aperte</h3>
|
||||
<button class="btn-primary" id="btn-nuova-att"><i data-lucide="plus" class="ic"></i>Nuova attività</button></div>
|
||||
<div class="act-scroll" id="act-scroll"><div class="act"><div class="body"><b>Mappatura asset del perimetro NIS2</b><div class="meta"><span class="who">Reparto IT</span><span class="who">· scad. 4 lug</span></div></div><span class="badge-t blue">In corso</span></div><div class="act"><div class="body"><b>Definizione policy gestione accessi</b><div class="meta"><span class="who">CISO</span><span class="who">· scad. 2 lug</span></div></div><span class="badge-t amber">In revisione</span></div><div class="act"><div class="body"><b>Valutazione fornitori critici (supply chain)</b><div class="meta"><span class="who">Procurement</span><span class="who">· scad. 8 lug</span></div></div><span class="badge-t blue">In corso</span></div><div class="act"><div class="body"><b>Revisione contratti DPA fornitori</b><div class="meta"><span class="who">Ufficio Legale</span><span class="who">· scad. 20 giu</span></div></div><span class="badge-t red">In ritardo</span></div><div class="act"><div class="body"><b>Implementazione MFA accessi remoti</b><div class="meta"><span class="who">Reparto IT</span><span class="who">· scad. 30 giu</span></div></div><span class="badge-t blue">In corso</span></div><div class="act"><div class="body"><b>Procedura notifica Art. 23</b><div class="meta"><span class="who">Compliance</span><span class="who">· scad. 27 giu</span></div></div><span class="badge-t amber">In revisione</span></div><div class="act"><div class="body"><b>Piano formativo Art. 21</b><div class="meta"><span class="who">HR</span><span class="who">· scad. 12 lug</span></div></div><span class="badge-t blue">In corso</span></div><div class="act"><div class="body"><b>Gap analysis area OT</b><div class="meta"><span class="who">CISO</span><span class="who">· scad. 15 lug</span></div></div><span class="badge-t blue">In corso</span></div><div class="act"><div class="body"><b>Test piano di risposta incidenti</b><div class="meta"><span class="who">SOC</span><span class="who">· scad. 10 lug</span></div></div><span class="badge-t gray">Da avviare</span></div><div class="act"><div class="body"><b>Classificazione dati e asset</b><div class="meta"><span class="who">Data Owner</span><span class="who">· scad. 18 lug</span></div></div><span class="badge-t blue">In corso</span></div><div class="act"><div class="body"><b>Audit interno sicurezza fisica</b><div class="meta"><span class="who">Internal Audit</span><span class="who">· scad. 22 lug</span></div></div><span class="badge-t gray">Da avviare</span></div><div class="act"><div class="body"><b>Aggiornamento Business Continuity Plan</b><div class="meta"><span class="who">BCM</span><span class="who">· scad. 25 lug</span></div></div><span class="badge-t blue">In corso</span></div><div class="act"><div class="body"><b>Verifica log e monitoraggio continuo</b><div class="meta"><span class="who">SOC</span><span class="who">· scad. 28 giu</span></div></div><span class="badge-t blue">In corso</span></div><div class="act"><div class="body"><b>Aggiornamento registro incidenti</b><div class="meta"><span class="who">SOC</span><span class="who">· scad. 10 lug</span></div></div><span class="badge-t gray">Da avviare</span></div></div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="split-anag">
|
||||
<section class="card card-pad">
|
||||
<div class="sec-head"><h3>Anagrafica aziendale</h3>
|
||||
<button class="btn-ghost" id="btn-edit-anag"><i data-lucide="pencil" class="ic"></i>Modifica</button></div>
|
||||
<div class="anag">
|
||||
<div class="anag-logo">AM</div>
|
||||
<div class="info">
|
||||
<div class="nm"><h3>Acme Manifatturiera S.p.A.</h3><span class="badge-nis">Soggetto importante</span></div>
|
||||
<div class="anag-grid">
|
||||
<div class="f"><span>Settore</span><b>Metalmeccanica · Manifatturiero</b></div>
|
||||
<div class="f"><span>Partita IVA</span><b>IT 01234560360</b></div>
|
||||
<div class="f"><span>Sede legale</span><b>Modena (MO), Italia</b></div>
|
||||
<div class="f"><span>Dipendenti</span><b>248</b></div>
|
||||
<div class="f"><span>Referente NIS2</span><b>Simone Fatteri</b></div>
|
||||
<div class="f"><span>Registrazione ACN</span><b>Completata · 12/2024</b></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="card card-pad">
|
||||
<div class="sec-head"><h3>Documenti istituzionali</h3></div>
|
||||
<button class="doc has" data-doc="Mission">
|
||||
<span class="di"><i data-lucide="target" class="ic"></i></span>
|
||||
<span class="dt"><b>Mission</b><small>mission_2026.pdf · 25 giu 2026</small></span>
|
||||
<span class="st"><i data-lucide="check-circle-2" class="ic"></i>Allegato</span>
|
||||
</button>
|
||||
<button class="doc miss" data-doc="Vision">
|
||||
<span class="di"><i data-lucide="eye" class="ic"></i></span>
|
||||
<span class="dt"><b>Vision</b><small>Nessun file allegato</small></span>
|
||||
<span class="st"><i data-lucide="upload" class="ic"></i>Da allegare</span>
|
||||
</button>
|
||||
<button class="doc has" data-doc="Etica aziendale">
|
||||
<span class="di"><i data-lucide="scale" class="ic"></i></span>
|
||||
<span class="dt"><b>Etica aziendale</b><small>codice_etico_v2.pdf · 18 giu 2026</small></span>
|
||||
<span class="st"><i data-lucide="check-circle-2" class="ic"></i>Allegato</span>
|
||||
</button>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="fab-stack">
|
||||
<button class="fab blue" title="Notifiche"><i data-lucide="bell" class="ic"></i></button>
|
||||
<button class="fab red" title="Assistenza"><i data-lucide="life-buoy" class="ic"></i></button>
|
||||
<button class="fab violet" title="Assistente AI"><i data-lucide="sparkles" class="ic"></i></button>
|
||||
</div>
|
||||
|
||||
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
|
||||
<script>
|
||||
const TODAY=new Date(2026,5,25);
|
||||
const MO=['gen','feb','mar','apr','mag','giu','lug','ago','set','ott','nov','dic'];
|
||||
const WDa=['Lun','Mar','Mer','Gio','Ven','Sab','Dom'];
|
||||
const WDi=['L','M','M','G','V','S','D'];
|
||||
const DAY=86400000;
|
||||
function mi(d){return (d.getDay()+6)%7;}
|
||||
function addD(d,n){return new Date(d.getFullYear(),d.getMonth(),d.getDate()+n);}
|
||||
function iso(d){return d.getFullYear()+'-'+String(d.getMonth()+1).padStart(2,'0')+'-'+String(d.getDate()).padStart(2,'0');}
|
||||
function monday(d){return addD(d,-mi(d));}
|
||||
function same(a,b){return iso(a)===iso(b);}
|
||||
function weekLabel(m){const s=addD(m,6);return m.getMonth()===s.getMonth()?(m.getDate()+' \u2013 '+s.getDate()+' '+MO[s.getMonth()]):(m.getDate()+' '+MO[m.getMonth()]+' \u2013 '+s.getDate()+' '+MO[s.getMonth()]);}
|
||||
|
||||
const EVENTS={
|
||||
'2026-06-12':[{t:'Formazione: notifica Art. 23 \u2014 A. Ferretti',c:'green',time:'09:00'}],
|
||||
'2026-06-17':[{t:'Audit interno \u2014 area IT',c:'green',time:'10:00'}],
|
||||
'2026-06-20':[{t:'Scadenza misura tecnica supply chain',c:'amber',time:'Tutto il giorno'}],
|
||||
'2026-06-23':[{t:'Riunione referenti NIS2',c:'blue',time:'15:00'}],
|
||||
'2026-06-25':[{t:'Formazione: gestione incidenti',c:'green',time:'09:30'},{t:'Review policy accessi',c:'blue',time:'14:00'}],
|
||||
'2026-06-26':[{t:'Notifica incidente Art. 23 \u2014 follow-up',c:'red',time:'11:00'}],
|
||||
'2026-06-30':[{t:'Riesame di Direzione \u2014 chiusura trimestre',c:'blue',time:'16:00'}],
|
||||
'2026-07-01':[{t:'Controllo periodico backup',c:'amber',time:'09:00'}],
|
||||
'2026-07-03':[{t:'Aggiornamento registro rischi',c:'amber',time:'12:00'}],
|
||||
'2026-07-08':[{t:'Audit fornitore critico',c:'green',time:'10:30'}],
|
||||
'2026-07-10':[{t:'Test piano di risposta incidenti',c:'red',time:'14:30'}]
|
||||
};
|
||||
function evOf(d){return EVENTS[iso(d)]||[];}
|
||||
function dots(list){return list.slice(0,4).map(e=>'<i class="ev '+e.c+'"></i>').join('');}
|
||||
|
||||
let dayOffset=0, weekOffset=0;
|
||||
|
||||
const POP=document.createElement('div');POP.className='cal-pop';document.body.appendChild(POP);
|
||||
let popTimer;
|
||||
function showPop(anchor,html){
|
||||
clearTimeout(popTimer);
|
||||
POP.innerHTML=html;POP.style.display='block';
|
||||
const r=anchor.getBoundingClientRect();
|
||||
const pw=POP.offsetWidth, ph=POP.offsetHeight;
|
||||
let left=r.left+r.width/2-pw/2;
|
||||
left=Math.max(10,Math.min(left,window.innerWidth-pw-10));
|
||||
let top=r.top-ph-10; if(top<10) top=r.bottom+10;
|
||||
POP.style.left=left+'px';POP.style.top=top+'px';
|
||||
requestAnimationFrame(()=>POP.classList.add('show'));
|
||||
}
|
||||
function hidePop(){POP.classList.remove('show');popTimer=setTimeout(()=>{POP.style.display='none';},150);}
|
||||
|
||||
function dayPop(d){
|
||||
const list=evOf(d);
|
||||
const head=WDa[mi(d)]+' '+d.getDate()+' '+MO[d.getMonth()];
|
||||
let body=list.length
|
||||
? list.map(e=>'<div class="pe"><span class="ev '+e.c+'"></span><div><span class="tt">'+e.time+'</span><b>'+e.t+'</b></div></div>').join('')
|
||||
: '<div class="empty">Nessun appuntamento.</div>';
|
||||
return '<h4>'+head+'</h4>'+body;
|
||||
}
|
||||
function weekPop(m){
|
||||
let items=[];
|
||||
for(let i=0;i<7;i++){const d=addD(m,i);evOf(d).forEach(e=>items.push({d:d,e:e}));}
|
||||
let body=items.length
|
||||
? items.slice(0,6).map(o=>'<div class="pe"><span class="ev '+o.e.c+'"></span><div><span class="tt">'+WDa[mi(o.d)]+' '+o.d.getDate()+'</span><b>'+o.e.t+'</b></div></div>').join('')
|
||||
: '<div class="empty">Nessun appuntamento.</div>';
|
||||
if(items.length>6) body+='<div class="empty" style="margin-top:6px">+'+(items.length-6)+' altri\u2026</div>';
|
||||
return '<h4>'+weekLabel(m)+'</h4>'+body;
|
||||
}
|
||||
function openCal(){window.location.href='calendario.html';}
|
||||
|
||||
function renderDaily(){
|
||||
const center=addD(TODAY,dayOffset);
|
||||
const wrap=document.getElementById('daystrip');wrap.innerHTML='';
|
||||
for(let i=-6;i<=6;i++){
|
||||
const d=addD(center,i);
|
||||
const cell=document.createElement('div');
|
||||
cell.className='daycell'+(mi(d)>=5?' weekend':'')+(same(d,TODAY)?' today':'');
|
||||
cell.innerHTML='<div class="wd">'+WDa[mi(d)]+'</div><div class="dn">'+d.getDate()+'</div><div class="mo">'+MO[d.getMonth()]+'</div><div class="dots">'+dots(evOf(d))+'</div>';
|
||||
cell.addEventListener('mouseenter',()=>showPop(cell,dayPop(d)));
|
||||
cell.addEventListener('mouseleave',hidePop);
|
||||
cell.addEventListener('click',openCal);
|
||||
wrap.appendChild(cell);
|
||||
}
|
||||
}
|
||||
function renderWeekly(){
|
||||
const curMon=monday(TODAY);
|
||||
const centerMon=addD(curMon,weekOffset*7);
|
||||
const wrap=document.getElementById('weekstrip');wrap.innerHTML='';
|
||||
for(let w=-1;w<=1;w++){
|
||||
const m=addD(centerMon,w*7);
|
||||
const isCur=same(m,curMon);
|
||||
const diff=Math.round((m-curMon)/(7*DAY));
|
||||
let tag = diff===0?'Settimana in corso':diff===-1?'Settimana precedente':diff===1?'Settimana successiva':diff<0?(-diff)+' settimane fa':'Tra '+diff+' settimane';
|
||||
const block=document.createElement('div');
|
||||
block.className='weekblock'+(isCur?' current':'');
|
||||
let minis='';
|
||||
for(let i=0;i<7;i++){const d=addD(m,i);minis+='<div class="mini'+(mi(d)>=5?' weekend':'')+(same(d,TODAY)?' today':'')+'"><div class="mi-wd">'+WDi[mi(d)]+'</div><div class="mi-dn">'+d.getDate()+'</div><div class="mi-ev">'+dots(evOf(d))+'</div></div>';}
|
||||
block.innerHTML='<div class="wl"><b>'+weekLabel(m)+'</b><span>'+tag+'</span></div><div class="week7">'+minis+'</div>';
|
||||
block.addEventListener('mouseenter',()=>showPop(block,weekPop(m)));
|
||||
block.addEventListener('mouseleave',hidePop);
|
||||
block.addEventListener('click',openCal);
|
||||
wrap.appendChild(block);
|
||||
}
|
||||
}
|
||||
document.getElementById('d-prev').onclick=()=>{dayOffset--;renderDaily();};
|
||||
document.getElementById('d-next').onclick=()=>{dayOffset++;renderDaily();};
|
||||
document.getElementById('d-today').onclick=()=>{dayOffset=0;renderDaily();};
|
||||
document.getElementById('w-prev').onclick=()=>{weekOffset--;renderWeekly();};
|
||||
document.getElementById('w-next').onclick=()=>{weekOffset++;renderWeekly();};
|
||||
document.getElementById('w-today').onclick=()=>{weekOffset=0;renderWeekly();};
|
||||
renderDaily();renderWeekly();
|
||||
document.querySelectorAll('.doc').forEach(d=>{
|
||||
d.addEventListener('click',()=>{
|
||||
const on=!d.classList.contains('has');
|
||||
d.classList.toggle('has',on);d.classList.toggle('miss',!on);
|
||||
const file=d.dataset.doc.toLowerCase().replace(/[^a-z0-9]+/g,'_')+'_2026.pdf';
|
||||
d.querySelector('.dt small').textContent=on?(file+' \u00b7 25 giu 2026'):'Nessun file allegato';
|
||||
d.querySelector('.st').innerHTML=on?'<i data-lucide="check-circle-2"></i>Allegato':'<i data-lucide="upload"></i>Da allegare';
|
||||
lucide.createIcons();
|
||||
});
|
||||
});
|
||||
const bn=document.getElementById('btn-nuova-att');
|
||||
if(bn) bn.addEventListener('click',()=>{
|
||||
const wrap=document.getElementById('act-scroll');
|
||||
const el=document.createElement('div');el.className='act';
|
||||
el.innerHTML='<div class="body"><b>Nuova attivit\u00e0 (bozza)</b><div class="meta"><span class="who">Responsabile da assegnare</span><span class="who">\u00b7 scadenza \u2014</span></div></div><span class="badge-t gray">Bozza</span>';
|
||||
wrap.prepend(el);wrap.scrollTop=0;
|
||||
});
|
||||
window.lucide && lucide.createIcons();
|
||||
</script>
|
||||
</body></html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
Binary file not shown.
Reference in New Issue
Block a user