[FEAT] UI V3 — flotta: chrome top-nav + design system su 32 pagine app
Migrazione UI dal V2 (Bootstrap Italia, sidebar) al V3 (top-nav mega-menu navy/oro, Inter+Lucide self-host) fedele ai mockup docs/mockup Ui/. - 32 pagine app convertite (incl. admin/*): head Inter+v3.css, chrome topnav-v3, contenuti in card V3, dati REALI preservati (id/data-* intatti), i18n/help/FAB reali invariati, nessun CDN esterno. - v3.css: aggiunti widget condivisi (modal/toast/form/btn-variant/spinner/ progress/tag/badge) + utility (.btn base, .text-muted, .sr-only) + alias variabili V2->token V3, così modali/form/toast di common.js funzionano ovunque senza style.css. - maintenance.html: finestra estesa a ~12:15. - docs/UI_V3_FLEET_BRIEF.md: ricetta operativa della 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
b0fc190704
commit
a4150b5389
@@ -263,3 +263,125 @@ a.stat:hover{box-shadow:0 8px 20px rgba(16,40,80,.13);transform:translateY(-1px)
|
||||
.ctrl-btn{min-width:44px;min-height:44px}
|
||||
.fab{width:52px;height:52px}
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════════
|
||||
* V3 — WIDGET CONDIVISI (compat) — modali/toast/form/bottoni/spinner/progress.
|
||||
* Generati da common.js (showModal/showNotification) e dal markup di varie
|
||||
* pagine: vivevano in style.css (rimosso dalle pagine V3). Qui sono ri-portati
|
||||
* UNA volta sola e ritematizzati sui colori V3. NON ridefinisce .btn-primary /
|
||||
* .btn-ghost / .badge-t (già in v3.css sopra): nessun conflitto.
|
||||
* ═════════════════════════════════════════════════════════════════════════ */
|
||||
:root{
|
||||
/* alias V2→V3 usati dai widget sottostanti */
|
||||
--primary:#1F5FA8; --primary-dark:#16487f; --primary-light:#3b7bc4; --primary-bg:#eaf1f9;
|
||||
--secondary:#1E8A5A; --secondary-light:#27a06b; --secondary-bg:#e3f3ea;
|
||||
--warning:#D98324; --warning-light:#e89a45; --warning-bg:#fbeede;
|
||||
--danger:#C62828; --danger-light:#e05656; --danger-bg:#fbe5e5;
|
||||
--info:#1F5FA8; --info-bg:#eaf1f9;
|
||||
--gray-50:#f8fafc; --gray-100:#f1f5f9; --gray-200:#e2e8f0; --gray-300:#cbd5e1;
|
||||
--gray-400:#94a3b8; --gray-500:#64748b; --gray-600:#475569; --gray-700:#334155;
|
||||
--gray-800:#1e293b; --gray-900:#0f172a;
|
||||
--card-bg:var(--card); --border-radius:10px; --border-radius-lg:var(--radius); --border-radius-sm:6px;
|
||||
--transition:250ms ease; --transition-fast:150ms ease;
|
||||
}
|
||||
|
||||
/* Bottoni (varianti non presenti in v3.css; self-sufficient, non toccano primary/ghost) */
|
||||
.btn-secondary,.btn-success,.btn-danger,.btn-warning,.btn-outline{
|
||||
display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:10px 18px;
|
||||
font-size:.875rem;font-weight:600;font-family:inherit;border:1px solid transparent;
|
||||
border-radius:var(--radius);cursor:pointer;text-decoration:none;line-height:1.4;white-space:nowrap;
|
||||
transition:background .15s ease,border-color .15s ease,color .15s ease}
|
||||
.btn-secondary{background:var(--gray-100);color:var(--gray-700);border-color:var(--gray-300)}
|
||||
.btn-secondary:hover:not(:disabled){background:var(--gray-200);border-color:var(--gray-400)}
|
||||
.btn-success{background:var(--secondary);color:#fff;border-color:var(--secondary)}
|
||||
.btn-success:hover:not(:disabled){background:var(--secondary-light)}
|
||||
.btn-danger{background:var(--danger);color:#fff;border-color:var(--danger)}
|
||||
.btn-danger:hover:not(:disabled){background:var(--danger-light)}
|
||||
.btn-warning{background:var(--warning);color:#1a1a1a;border-color:var(--warning)}
|
||||
.btn-outline{background:transparent;color:var(--navy-nav);border-color:var(--navy-nav)}
|
||||
.btn-outline:hover:not(:disabled){background:var(--navy-nav);color:#fff}
|
||||
.btn-secondary:disabled,.btn-success:disabled,.btn-danger:disabled,.btn-warning:disabled,.btn-outline:disabled{opacity:.5;cursor:not-allowed}
|
||||
.btn-sm{padding:6px 14px;font-size:.8rem}
|
||||
.btn-lg{padding:14px 28px;font-size:1rem}
|
||||
.btn-icon{padding:8px;width:36px;height:36px}
|
||||
.btn-group{display:flex;gap:8px}
|
||||
|
||||
/* Form */
|
||||
.form-group{margin-bottom:20px}
|
||||
.form-label{display:block;font-size:.8125rem;font-weight:600;color:var(--gray-700);margin-bottom:6px}
|
||||
.form-label .required{color:var(--danger);margin-left:2px}
|
||||
.form-group .form-label{position:static;line-height:1.4;padding:0;width:auto;max-width:none;z-index:auto;background-color:transparent;cursor:default}
|
||||
.form-input,.form-select,.form-textarea{width:100%;padding:10px 14px;font-size:.875rem;font-family:inherit;color:var(--ink);background:var(--card);border:1px solid var(--line);border-radius:var(--border-radius);transition:border-color var(--transition-fast),box-shadow var(--transition-fast);outline:none}
|
||||
.form-input:focus,.form-select:focus,.form-textarea:focus{border-color:var(--navy-nav);box-shadow:0 0 0 3px rgba(31,95,168,.15)}
|
||||
.form-input::placeholder,.form-textarea::placeholder{color:var(--gray-400)}
|
||||
.form-input.error,.form-select.error,.form-textarea.error{border-color:var(--danger);box-shadow:0 0 0 3px rgba(198,40,40,.12)}
|
||||
.form-textarea{resize:vertical;min-height:100px}
|
||||
.form-select{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%2364748b' viewBox='0 0 16 16'%3E%3Cpath d='M8 11L3 6h10l-5 5z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 12px center;padding-right:36px}
|
||||
.form-help{font-size:.75rem;color:var(--gray-500);margin-top:6px}
|
||||
|
||||
/* Badge generici (style.css legacy) — coesistono con .badge-t di v3.css */
|
||||
.badge{display:inline-flex;align-items:center;gap:4px;padding:3px 10px;font-size:.7rem;font-weight:600;border-radius:100px;text-transform:uppercase;letter-spacing:.03em;white-space:nowrap}
|
||||
.badge-primary{background:var(--primary-bg);color:var(--primary)}
|
||||
.badge-success{background:var(--secondary-bg);color:#15803d}
|
||||
.badge-warning{background:var(--warning-bg);color:#a16207}
|
||||
.badge-danger{background:var(--danger-bg);color:var(--danger)}
|
||||
.badge-info{background:var(--info-bg);color:var(--primary)}
|
||||
.badge-neutral{background:var(--gray-100);color:var(--gray-600)}
|
||||
.badge-lg{padding:6px 16px;font-size:.8rem}
|
||||
.tag{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;font-size:.75rem;font-weight:500;background:var(--gray-100);color:var(--gray-600);border-radius:var(--border-radius-sm);border:1px solid var(--gray-200)}
|
||||
|
||||
/* Progress */
|
||||
.progress{width:100%;height:8px;background:var(--gray-200);border-radius:100px;overflow:hidden}
|
||||
.progress-bar{height:100%;border-radius:100px;transition:width .8s ease;background:var(--navy-nav)}
|
||||
.progress-bar.success{background:var(--secondary)}
|
||||
.progress-bar.warning{background:var(--warning)}
|
||||
.progress-bar.danger{background:var(--danger)}
|
||||
.progress-lg{height:12px}
|
||||
.progress-label{display:flex;justify-content:space-between;margin-bottom:6px;font-size:.8rem}
|
||||
.progress-label span:first-child{font-weight:600;color:var(--gray-700)}
|
||||
.progress-label span:last-child{color:var(--gray-500)}
|
||||
|
||||
/* Modal (showModal di common.js) */
|
||||
.modal-overlay{position:fixed;inset:0;width:100%;height:100%;background:rgba(15,23,42,.6);backdrop-filter:blur(4px);z-index:1000;display:flex;align-items:center;justify-content:center;opacity:0;visibility:hidden;transition:all var(--transition)}
|
||||
.modal-overlay.active{opacity:1;visibility:visible}
|
||||
.modal{background:var(--card);border-radius:var(--border-radius-lg);box-shadow:0 20px 60px rgba(0,0,0,.2);width:90%;max-width:560px;max-height:85vh;overflow-y:auto;transform:translateY(20px) scale(.95);transition:transform var(--transition)}
|
||||
.modal-overlay.active .modal{transform:translateY(0) scale(1)}
|
||||
.modal-overlay .modal{display:block;position:relative;inset:auto;margin:0;z-index:auto;pointer-events:auto}
|
||||
.modal-header{padding:20px 24px;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between}
|
||||
.modal-header h3{font-size:1.125rem;font-weight:700;color:var(--ink)}
|
||||
.modal-close{background:none;border:none;color:var(--gray-400);cursor:pointer;padding:4px;border-radius:var(--border-radius-sm);transition:color var(--transition-fast);line-height:1;font-size:1.4rem}
|
||||
.modal-close:hover{color:var(--gray-700)}
|
||||
.modal-body{padding:24px}
|
||||
.modal-footer{padding:16px 24px;border-top:1px solid var(--line);display:flex;justify-content:flex-end;gap:8px}
|
||||
|
||||
/* Notifiche / toast (showNotification di common.js) */
|
||||
.notification-container{position:fixed;top:20px;right:20px;z-index:2000;display:flex;flex-direction:column;gap:8px;pointer-events:none}
|
||||
.notification{background:var(--card);border-radius:var(--border-radius);box-shadow:0 8px 24px rgba(0,0,0,.15);padding:14px 20px;display:flex;align-items:center;gap:12px;min-width:320px;max-width:480px;pointer-events:auto;animation:slideIn .3s ease;border-left:4px solid var(--gray-400)}
|
||||
.notification.success{border-left-color:var(--secondary)}
|
||||
.notification.error{border-left-color:var(--danger)}
|
||||
.notification.warning{border-left-color:var(--warning)}
|
||||
.notification.info{border-left-color:var(--primary)}
|
||||
.notification-icon{width:20px;height:20px;flex-shrink:0}
|
||||
.notification.success .notification-icon{color:var(--secondary)}
|
||||
.notification.error .notification-icon{color:var(--danger)}
|
||||
.notification.warning .notification-icon{color:var(--warning)}
|
||||
.notification.info .notification-icon{color:var(--primary)}
|
||||
.notification-message{flex:1;font-size:.875rem;color:var(--gray-700);font-weight:500}
|
||||
.notification-close{background:none;border:none;color:var(--gray-400);cursor:pointer;padding:2px;font-size:1.1rem;line-height:1}
|
||||
.notification.fade-out{animation:slideOut .3s ease forwards}
|
||||
@keyframes slideIn{from{transform:translateX(100%);opacity:0}to{transform:translateX(0);opacity:1}}
|
||||
@keyframes slideOut{from{transform:translateX(0);opacity:1}to{transform:translateX(100%);opacity:0}}
|
||||
|
||||
/* Spinner */
|
||||
.spinner{width:24px;height:24px;border:3px solid var(--gray-200);border-top-color:var(--navy-nav);border-radius:50%;animation:spin .7s linear infinite;margin:0 auto}
|
||||
.spinner-lg{width:40px;height:40px;border-width:4px}
|
||||
@keyframes spin{to{transform:rotate(360deg)}}
|
||||
|
||||
/* Utility generiche (ex Bootstrap Italia/style.css) usate da markup di varie pagine.
|
||||
* .btn base SENZA padding → non altera il padding di .btn-primary/.btn-ghost (v3) ; i
|
||||
* variant (sm/secondary/outline/...) restano self-sufficient. */
|
||||
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-family:inherit;font-weight:600;border:1px solid transparent;border-radius:var(--radius);cursor:pointer;text-decoration:none;line-height:1.4;white-space:nowrap;transition:background .15s ease,border-color .15s ease,color .15s ease}
|
||||
.btn:disabled{opacity:.5;cursor:not-allowed}
|
||||
.text-muted{color:var(--muted)}
|
||||
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
|
||||
:root{ --success:var(--c-green); --error:var(--c-red); }
|
||||
|
||||
Reference in New Issue
Block a user