Rifacimento della UI secondo STILE_UI.md

Adotta lo stile condiviso delle app Integry: superfici piatte, raggi ampi,
spaziature a scala fissa, gerarchia data dallo spazio prima che dalla
decorazione. La palette storica di SteUP resta intatta; sono stati aggiunti
solo i ruoli che mancavano (workspace, surfaceMuted, divider, inkMuted e le
triplette dei toni semantici).

Fondamenta
- tokens.css: ruoli colore, scale di spazio/raggi/tipografia, curve di
  movimento e scala z-index semantica. Unica fonte di verita': pilotano
  anche le variabili CSS di MudBlazor.
- Inter variabile ospitata in locale (133KB) al posto di Nunito da Google
  Fonts: l'app lavora offline, un font che arriva dalla rete in campo non
  arriva.
- base.css: shell applicativa e comportamenti da app nativa — niente
  selezione testo, niente menu al tocco lungo, niente lampo grigio sul tap,
  niente rimbalzo elastico, niente zoom a doppio tocco, scroll con inerzia.
- mudblazor-overrides.css: MudBlazor appiattito (elevation 0, nessun tint,
  target 44/48, etichette in caso naturale).
- Rimossi Bootstrap (CSS, icone e JS) e i 996 righe di CSS con ambito per
  componente del vecchio sistema: erano tutti inutilizzati.

Struttura
- Navigazione flottante in basso con icona piena sulla voce attiva; da 720px
  diventa colonna laterale. Il MudFabMenu e' sostituito da un bottom sheet:
  stessa funzione, bersagli molto piu' grandi.
- Testata alta col titolo a sinistra, fusa con la pagina.
- Nel form scheda il salvataggio sta in una barra ancorata in fondo, non in
  coda a uno scroll lungo.
- Scelta di punto vendita e articoli a schermo intero con ricerca; la
  selezione multipla usa righe da 56px invece di un menu a tendina.
- Urgenza scelta a pillole invece che da una select.

Stato e riscontro
- StatusBadgeHelper: tono, icona ed etichetta di ogni stato in un punto solo,
  cosi' lo stesso stato si presenta identico ovunque.
- Scheletri al posto degli spinner; l'overlay bloccante dice sempre cosa sta
  facendo; gli stati vuoti suggeriscono la mossa successiva.
- Rimosso il ritardo artificiale di 250ms in InspectionCard, che non
  attendeva nulla.

DESIGN.md riscritto sul nuovo sistema.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-17 11:09:26 +02:00
parent 3a9174f6fc
commit 2a0054aa30
77 changed files with 4595 additions and 3060 deletions
-335
View File
@@ -1,335 +0,0 @@
html {
overflow: hidden;
}
.page, article, main {
height: 100% !important;
overflow: hidden;
}
#app {
height: 100vh;
}
html, body {
font-family: "Nunito", sans-serif;
font-size: 14px;
font-weight: 400;
line-height: 1.8;
color: black;
}
* {
font-family: "Nunito", sans-serif !important;
}
html ::-webkit-scrollbar {
width: 3px;
height: 3px;
}
html ::-webkit-scrollbar-thumb {
background: #bbb;
border-radius: 2px;
}
.mud-button-label {
font-weight: 700 !important;
}
a, .btn-link {
/*color: #006bb7;*/
text-decoration: none;
color: inherit;
}
article {
display: flex;
flex-direction: column;
}
/*ServicesIsDown" : "SystemOk" : "NetworkKo*/
.Connection {
padding: 0 .75rem;
font-weight: 700;
display: flex;
flex-direction: row;
gap: 1rem;
font-size: larger;
transition: all 0.5s ease;
opacity: 0;
transform: translateY(-35px);
min-height: 35px;
align-items: center;
}
.Connection.ServicesIsDown, .Connection.NetworkKo {
background-color: var(--mud-palette-error);
color: white;
}
.Connection.SystemOk {
background-color: var(--mud-palette-success);
color: white;
}
.Connection.Show {
opacity: 1;
transform: translateY(0);
}
.Connection.Hide ~ .page {
transition: all 0.5s ease;
transform: translateY(-35px);
}
.btn-primary {
color: #fff;
background-color: var(--primary-color);
border-color: var(--darker-color);
}
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}
.content {
padding-top: 1rem;
display: flex;
align-items: center;
flex-direction: column;
height: 90vh;
}
h1:focus {
outline: none;
}
.valid.modified:not([type=checkbox]) {
outline: 1px solid #26b050;
}
.invalid {
outline: 1px solid #e50000;
}
.validation-message {
color: #e50000;
}
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}
.blazor-error-boundary {
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
padding: 1rem 1rem 1rem 3.7rem;
color: white;
}
.blazor-error-boundary::after {
content: "An error has occurred."
}
.status-bar-safe-area {
display: none;
}
.page-title {
font-size: x-large;
font-weight: 800;
margin: 0;
line-height: normal;
color: var(--mud-palette-text-primary);
}
.custom-mudfab {
position: fixed !important;
bottom: 4rem;
margin-bottom: 16px;
right: 16px;
}
.divider {
display: block;
width: 100%;
border: .05rem solid var(--mud-palette-lines-inputs);
}
.pb-safe-area {
padding-bottom: 75px;
overflow: auto;
}
/*Spinner*/
.spinner-container {
display: flex;
justify-content: center;
height: 100vh;
align-items: center;
color: var(--mud-palette-primary);
}
.not-fullScreen {
height: auto !important;
padding: 2rem 0 !important;
}
.loader {
width: 50px;
aspect-ratio: 1;
border-radius: 50%;
border: 8px solid #0000;
border-right-color: var(--mud-palette-primary);
position: relative;
animation: l24 1s infinite linear;
}
.loader:before,
.loader:after {
content: "";
position: absolute;
inset: -8px;
border-radius: 50%;
border: inherit;
animation: inherit;
animation-duration: 2s;
}
.loader:after {
animation-duration: 4s;
}
@keyframes l24 {
100% {
transform: rotate(1turn)
}
}
/*MudBlazor Personalization*/
.mud-button-group-horizontal:not(.mud-button-group-rtl) > .mud-button-root:not(:last-child), .mud-button-group-horizontal:not(.mud-button-group-rtl) > :not(:last-child) .mud-button-root {
border-top-right-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}
.mud-button-group-horizontal:not(.mud-button-group-rtl) > .mud-button-root:not(:first-child), .mud-button-group-horizontal:not(.mud-button-group-rtl) > :not(:first-child) .mud-button-root {
border-top-left-radius: 0 !important;
border-bottom-left-radius: 0 !important;
}
.customDialog-form .mud-dialog-content {
padding: 0 0;
margin: 0;
overflow: hidden;
}
.custom-item-select {
padding: 6px 16px;
}
.custom-item-select .mud-typography-body1 {
font-weight: 600;
font-size: .9rem;
}
.container {
padding-right: var(--m-page-x) !important;
padding-left: var(--m-page-x) !important;
}
.lm-container {
padding-right: calc(var(--m-page-x) * 0.5) !important;
padding-left: calc(var(--m-page-x) * 0.5) !important;
}
.mud-message-box > .mud-dialog-title > h6 {
font-weight: 800 !important;
}
.mud-dialog-actions button {
margin-left: .5rem !important;
margin-right: .5rem !important;
}
@supports (-webkit-touch-callout: none) {
.status-bar-safe-area {
display: flex;
position: fixed;
top: 0;
height: env(safe-area-inset-top);
width: 100%;
z-index: 1;
background-color: var(--mud-palette-surface);
}
.modal {
padding-top: env(safe-area-inset-top);
}
.safe-area-bottom {
margin-bottom: env(safe-area-inset-bottom) !important;
}
.pb-safe-area {
padding-bottom: env(safe-area-inset-bottom) !important;
}
#app {
margin-top: env(safe-area-inset-top);
height: calc(100vh - env(safe-area-inset-top));
}
.flex-column, .navbar-brand {
padding-left: env(safe-area-inset-left);
}
.customDialog-form .mud-dialog-content {
margin-top: env(safe-area-inset-top);
}
}
/*Ripple*/
.ripple-container {
position: relative;
overflow: hidden;
cursor: pointer;
transform: translateZ(0);
}
.ripple {
position: absolute;
border-radius: 50%;
transform: scale(0);
animation: ripple-effect 0.6s linear;
background-color: rgba(0, 0, 0, 0.2);
pointer-events: none;
}
@keyframes ripple-effect {
to {
transform: scale(4);
opacity: 0;
}
}
.ripple-white .ripple {
background-color: rgba(255, 255, 255, 0.5);
}
+276
View File
@@ -0,0 +1,276 @@
/* =============================================================================
SteUP — Base
Reset, shell applicativa, tipografia e comportamenti "da app nativa".
========================================================================== */
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
height: 100%;
overflow: hidden;
/* La WebView non deve comportarsi come un browser: niente rimbalzo elastico
ai bordi, niente pull-to-refresh, niente zoom a doppio tocco. */
overscroll-behavior: none;
touch-action: manipulation;
-webkit-text-size-adjust: 100%;
}
body {
height: 100%;
margin: 0;
overflow: hidden;
background-color: var(--workspace);
color: var(--ink);
font-family: var(--font-sans);
font-size: var(--body-lg-size);
line-height: var(--body-lg-height);
font-weight: 400;
/* Inter: cifre a larghezza fissa, cosi' i contatori non "ballano" mentre
si aggiornano, e forme delle lettere piu' leggibili in piccolo. */
font-feature-settings: "tnum" 1, "cv05" 1;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
/* Niente selezione del testo, niente menu contestuale al tocco lungo,
niente lampo grigio sul tap: sono i tre segnali che tradiscono una
pagina web dentro un'app. */
user-select: none;
-webkit-user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: transparent;
cursor: default;
}
/* Il contenuto dei dati resta selezionabile: un barcode o un codice servono
anche da copiare. */
.selectable,
input,
textarea {
user-select: text;
-webkit-user-select: text;
-webkit-touch-callout: default;
}
#app {
height: 100dvh;
overflow: hidden;
}
img {
max-width: 100%;
display: block;
}
[hidden] {
display: none !important;
}
/* -----------------------------------------------------------------------------
Tipografia — scala fissa (STILE_UI §4)
La gerarchia si fa con peso e dimensione, mai con il maiuscolo spaziato.
-------------------------------------------------------------------------- */
.t-headline-md {
font-size: var(--headline-md-size);
line-height: var(--headline-md-height);
font-weight: 700;
letter-spacing: -0.02em;
}
.t-headline-sm {
font-size: var(--headline-sm-size);
line-height: var(--headline-sm-height);
font-weight: 700;
letter-spacing: -0.02em;
}
.t-title-lg {
font-size: var(--title-lg-size);
line-height: var(--title-lg-height);
font-weight: 700;
letter-spacing: -0.01em;
}
.t-title-md {
font-size: var(--title-md-size);
line-height: var(--title-md-height);
font-weight: 700;
}
.t-body-lg {
font-size: var(--body-lg-size);
line-height: var(--body-lg-height);
font-weight: 400;
}
.t-body-md {
font-size: var(--body-md-size);
line-height: var(--body-md-height);
font-weight: 400;
}
.t-label-lg {
font-size: var(--label-lg-size);
line-height: 1.25;
font-weight: 600;
}
.t-label-md {
font-size: var(--label-md-size);
line-height: 1.25;
font-weight: 600;
}
/* Identificativo tecnico sopra il titolo di una card (STILE_UI §4) */
.t-ident {
font-size: var(--label-sm-size);
line-height: 1.3;
font-weight: 700;
letter-spacing: 0.3px;
color: var(--ink-muted);
}
.t-muted {
color: var(--ink-muted);
}
/* Il testo secondario si distingue per colore, mai per opacita'. */
.t-meta {
font-size: var(--body-md-size);
line-height: var(--body-md-height);
font-weight: 600;
color: var(--ink-muted);
}
/* Prosa: righe non piu' lunghe di 65-75 caratteri. */
.t-prose {
max-width: 68ch;
text-wrap: pretty;
}
h1, h2, h3 {
text-wrap: balance;
margin: 0;
}
h1, h2, h3, h4, h5, h6, p {
margin: 0;
}
/* -----------------------------------------------------------------------------
Shell applicativa
-------------------------------------------------------------------------- */
.app-shell {
display: flex;
flex-direction: column;
height: 100dvh;
overflow: hidden;
background-color: var(--workspace);
}
/* Area scorrevole unica della schermata. Lo scroll con inerzia e il
contenimento evitano che il gesto "sfondi" sulla pagina sottostante. */
.app-scroll {
flex: 1;
min-height: 0;
overflow-y: auto;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
overscroll-behavior: contain;
scrollbar-width: none;
}
.app-scroll::-webkit-scrollbar {
display: none;
}
/* Contenitore di pagina (STILE_UI §6.1): su telefono e' trasparente, su
schermo largo tiene una colonna leggibile invece di allargarsi all'infinito. */
.page-width {
width: 100%;
max-width: var(--content-max);
margin-inline: auto;
padding-inline: var(--space-md);
}
/* Spazio in coda per non finire sotto la barra di navigazione flottante. */
.page-body {
padding-bottom: calc(var(--nav-clearance) + env(safe-area-inset-bottom, 0px));
}
/* Pagine senza barra di navigazione (login, form a schermo pieno). */
.page-body--flush {
padding-bottom: calc(var(--space-lg) + env(safe-area-inset-bottom, 0px));
}
.stack {
display: flex;
flex-direction: column;
}
.stack-xs { gap: var(--space-xs); }
.stack-10 { gap: var(--space-10); }
.stack-sm { gap: var(--space-sm); }
.stack-md { gap: var(--space-md); }
.stack-lg { gap: var(--space-lg); }
/* -----------------------------------------------------------------------------
Focus
Visibile e coerente ovunque, senza sporcare il tocco: solo da tastiera.
-------------------------------------------------------------------------- */
:focus {
outline: none;
}
:focus-visible {
outline: 2px solid var(--focus-ring);
outline-offset: 2px;
border-radius: var(--radius-compact);
}
/* -----------------------------------------------------------------------------
Risposta al tocco
Feedback fisico immediato (principio "Feedback immediato a ogni scan"):
l'elemento cede sotto il dito e torna. Niente stati basati sull'hover, che
su un touch screen non esiste e lascia elementi "accesi" dopo il tocco.
-------------------------------------------------------------------------- */
.pressable {
transition: transform var(--duration-fast) var(--ease-out),
background-color var(--duration-fast) var(--ease-out);
}
.pressable:active {
transform: scale(0.98);
}
@media (hover: hover) and (pointer: fine) {
.pressable:hover {
background-color: var(--surface-muted);
}
}
/* -----------------------------------------------------------------------------
Movimento ridotto — non e' opzionale
-------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
.pressable:active {
transform: none;
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
@@ -1,54 +0,0 @@
/*---Blazor custom---*/
.mud-snackbar {
border-radius: 1em !important;
}
.mud-paper {
border-radius: 1em !important;
}
.mud-dialog {
border-radius: 1em !important;
}
.mud-overlay.on-top {
z-index: 10001 !important;
}
.mud-popover.mud-popover-open {
border-radius: 1em !important;
}
.mud-picker-popover-paper {
border-radius: 1em !important;
}
.mud-skeleton {
border-radius: .5em !important;
}
/*.mud-expand-panel{*/
/* background: var(--light-card-background) !important;*/
/* box-shadow: unset !important;*/
/*}*/
.mud-expansion-panels {
width: 100%;
}
.ripple-container .mud-ripple-effect {
display: none !important;
}
.ripple-container .mud-ripple-effect-expanding {
display: none !important;
}
.ripple-container .mud-button:focus-visible, .ripple-container .mud-button:active{
background-color: unset !important;
}
.ripple-container .mud-button-outlined:focus-visible, .ripple-container .mud-button-outlined:active{
background-color: unset !important;
}
@@ -1,15 +0,0 @@
:root {
/*Color*/
--card-border-color: hsl(from var(--mud-palette-gray-light) h s 86%);
--gray-for-shadow: hsl(from var(--mud-palette-overlay-dark)h s 40%);
/*Utility*/
--exception-box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.3);
--custom-box-shadow: 1px 2px 5px var(--gray-for-shadow);
/* Ombra morbida a due livelli, tinta col navy del brand: stacca le card dallo sfondo senza pesare */
--card-box-shadow: 0 1px 2px rgba(0, 35, 57, 0.08), 0 6px 16px rgba(0, 35, 57, 0.10);
--mud-default-borderradius: 20px !important;
--m-page-x: 1rem;
--mh-header: 4rem;
--light-card-background: hsl(from var(--mud-palette-background-gray) h s 97%);
}
+28
View File
@@ -0,0 +1,28 @@
/* =============================================================================
SteUP Carattere
Inter variabile, ospitato in locale. Non si carica da Google Fonts: l'app
lavora in negozio con la rete incerta o assente, e un carattere che arriva
dalla rete e' un carattere che in campo non arriva.
========================================================================== */
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 100 900;
font-display: swap;
src: url("../fonts/inter-latin.woff2") format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 100 900;
font-display: swap;
src: url("../fonts/inter-latin-ext.woff2") format("woff2");
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
-218
View File
@@ -1,218 +0,0 @@
.title {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 1rem;
}
.customDialog-form.disable-safe-area .mud-dialog-content {
margin-top: unset !important;
}
.customDialog-form.disable-safe-area .content {
height: 100% !important;
}
.customDialog-form.mud-dialog {
border-radius: unset !important;
}
.customDialog-form .content {
height: calc(100vh - (.6rem + 40px));
overflow: auto;
gap: 1.5rem;
padding-top: unset !important;
padding-bottom: 2rem !important;
padding-left: .75rem !important;
padding-right: .75rem !important;
}
@supports (-webkit-touch-callout: none) {
.customDialog-form .content {
height: calc(100vh - (.6rem + 40px) - env(safe-area-inset-top)) !important;
}
.customDialog-form.disable-safe-area .content {
height: 100% !important;
}
.customDialog-form.disable-safe-area .mud-dialog-content {
margin-top: unset !important;
}
}
.customDialog-form .header {
padding: 0 .75rem !important;
}
.input-card {
width: 100%;
background: var(--mud-palette-background-gray);
border-radius: 9px;
padding: .5rem 1rem;
}
.input-card.clearButton {
display: flex;
align-items: center;
justify-content: space-between;
padding: .4rem 1rem !important;
}
.input-card.clearButton.custom-border-bottom {
border-bottom: .1rem solid var(--card-border-color);
}
.input-card > .divider {
margin: 0 !important;
}
.form-container {
display: flex;
justify-content: space-between;
align-items: center;
min-height: 35px;
}
.form-container > span {
font-weight: 700;
width: 50%;
margin-right: .3rem;
}
.form-container > .warning-text {
font-weight: 700;
color: var(--mud-palette-gray-darker);
width: unset;
margin: 0;
}
.form-container > .disable-full-width {
width: unset !important;
white-space: nowrap;
}
.dateTime-picker {
display: flex;
gap: .3rem;
flex-direction: row;
align-items: center;
}
/*Custom mudBlazor*/
.form-container .mud-input.mud-input-underline:before {
border-bottom: none !important;
}
.form-container .mud-input.mud-input-underline:after {
border-bottom: none !important;
}
.form-container.text-align-end .mud-input-slot {
text-align: end;
}
.input-card .mud-input.mud-input-underline:before {
border-bottom: none !important;
}
.input-card .mud-input.mud-input-underline:after {
border-bottom: none !important;
}
.form-container .customIcon-select .mud-icon-root.mud-svg-icon {
rotate: 90deg !important;
font-size: 1.1rem;
}
.form-container .customIcon-select .mud-input-slot {
text-align: end;
}
.input-card .mud-input {
width: 100%;
font-weight: 500;
}
.container-button {
width: 100%;
background: var(--mud-palette-table-striped);
padding: .5rem 0;
border-radius: 20px;
margin-bottom: 2rem;
}
.container-button.remove-backgroud {
background: unset !important;
}
.container-button.mud-elevation-1 {
background: unset !important;
}
.container-button .divider {
margin: .5rem 0 .5rem 3rem;
width: unset;
}
.container-button .button-settings {
border: none !important;
}
.container-button .button-settings .mud-icon-root {
border-radius: 6px;
padding: 2px;
min-width: 25px;
min-height: 25px;
}
.container-button > .mud-button-root {
padding-top: .15rem;
padding-bottom: .15rem;
}
.container-button .button-settings.gray-icon .mud-icon-root {
border: 1px solid hsl(from var(--mud-palette-gray-darker) h s 88%);
background: hsl(from var(--mud-palette-gray-darker) h s 88%);
color: var(--mud-palette-dark);
}
.container-button .button-settings.primary-icon .mud-icon-root {
border: 1px solid hsl(from var(--mud-palette-primary) h s 95%);
background: hsl(from var(--mud-palette-primary-lighten) h s 95%);
color: var(--mud-palette-primary-darken);
}
.container-button .button-settings.green-icon .mud-icon-root {
border: 1px solid hsl(from var(--mud-palette-success-lighten) h s 95%);
background: hsl(from var(--mud-palette-success-lighten) h s 95%);
color: var(--mud-palette-success-darken);
}
.container-button .button-settings.red-icon .mud-icon-root {
border: 1px solid hsl(from var(--mud-palette-error-lighten) h s 95%);
background: hsl(from var(--mud-palette-error-lighten) h s 95%);
color: var(--mud-palette-error-darken);
}
.container-button .button-settings .mud-button-label {
justify-content: flex-start;
text-transform: capitalize;
font-size: 1rem;
}
.container-button.ripple-container{
overflow: clip;
}
.container-button .button-settings.exit {
padding: 0;
}
.container-button .button-settings.exit .mud-button-label {
justify-content: center;
font-size: 1.1rem;
line-height: normal;
}
+392
View File
@@ -0,0 +1,392 @@
/* =============================================================================
SteUP Form
Il form scheda e' il cuore dell'app: si compila in piedi, con una mano.
Ogni campo e' un blocco largo e tappabile, non una riga di tabella.
========================================================================== */
/* -----------------------------------------------------------------------------
Gruppo di campo un Panel con la sua etichetta
-------------------------------------------------------------------------- */
.form-group {
background-color: var(--surface);
border-radius: var(--radius-surface);
padding: var(--space-md);
}
.form-group__label {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-xs);
font-size: var(--label-md-size);
line-height: 1.25;
font-weight: 600;
color: var(--ink-muted);
margin-bottom: var(--space-6);
}
.form-group__count {
font-size: var(--label-md-size);
font-weight: 700;
color: var(--ink-muted);
}
/* Il valore del campo: testo grande, tocco comodo. */
.form-group .mud-input-control { margin: 0; }
.form-group .mud-input-slot,
.form-group input,
.form-group .mud-select-input {
font-size: var(--body-lg-size);
font-weight: 600;
color: var(--ink);
min-height: var(--touch-min);
}
.form-group--required .form-group__label::after {
content: "obbligatorio";
font-size: var(--label-sm-size);
font-weight: 700;
color: var(--ink-muted);
}
.form-group--invalid { box-shadow: inset 0 0 0 1px var(--danger-solid); }
.form-error {
display: flex;
align-items: center;
gap: var(--space-6);
margin-top: var(--space-xs);
font-size: var(--body-md-size);
font-weight: 600;
color: var(--danger-ink);
}
/* -----------------------------------------------------------------------------
Riga di scelta rapida (scadenza, priorita'): pillole invece di una select
-------------------------------------------------------------------------- */
.option-row {
display: flex;
flex-wrap: wrap;
gap: var(--space-xs);
}
.option {
flex: 1 1 auto;
min-width: 96px;
min-height: var(--touch-min);
padding: var(--space-xs) var(--space-sm);
border-radius: var(--radius-pill);
border: 1px solid var(--divider);
background-color: var(--surface-muted);
color: var(--ink-muted);
font-family: inherit;
font-size: var(--label-lg-size);
font-weight: 600;
transition: background-color var(--duration-fast) var(--ease-out),
border-color var(--duration-fast) var(--ease-out),
color var(--duration-fast) var(--ease-out),
transform var(--duration-fast) var(--ease-out);
}
.option:active { transform: scale(0.97); }
.option[aria-pressed="true"] {
background-color: var(--info-surface);
border-color: var(--primary);
color: var(--primary-dark);
}
@media (prefers-reduced-motion: reduce) {
.option:active { transform: none; }
}
/* -----------------------------------------------------------------------------
Campo barcode manuale affiancato al pulsante di invio
-------------------------------------------------------------------------- */
.barcode-field {
display: flex;
align-items: center;
gap: var(--space-xs);
padding: var(--space-xs) var(--space-xs) var(--space-xs) var(--space-md);
border-radius: var(--radius-pill);
background-color: var(--surface-muted);
border: 1.5px solid transparent;
transition: border-color var(--duration-fast) var(--ease-out);
}
.barcode-field:focus-within { border-color: var(--primary); }
.barcode-field input {
flex: 1 1 auto;
min-width: 0;
min-height: var(--touch-min);
border: none;
background: none;
outline: none;
font-family: inherit;
font-size: var(--body-lg-size);
font-weight: 600;
color: var(--ink);
/* Il codice si legge cifra per cifra: cifre a larghezza fissa. */
font-variant-numeric: tabular-nums;
}
.barcode-field input::placeholder { color: var(--ink-muted); font-weight: 400; }
.barcode-field__send {
flex: 0 0 auto;
display: flex;
align-items: center;
justify-content: center;
width: var(--touch-min);
height: var(--touch-min);
border: none;
border-radius: var(--radius-pill);
background-color: var(--primary);
color: var(--on-primary);
font-size: 20px;
transition: transform var(--duration-fast) var(--ease-out),
background-color var(--duration-fast) var(--ease-out);
}
.barcode-field__send:active { transform: scale(0.92); background-color: var(--primary-pressed); }
.barcode-field__send:disabled { background-color: var(--divider); color: var(--ink-muted); }
/* -----------------------------------------------------------------------------
Articoli scansionati
L'ultimo letto entra dall'alto: e' la conferma visiva della scansione.
-------------------------------------------------------------------------- */
.art-list {
display: flex;
flex-direction: column;
gap: var(--space-xs);
}
.art-item {
display: flex;
align-items: center;
gap: var(--space-sm);
padding: var(--space-10) var(--space-sm);
border-radius: var(--radius-control);
background-color: var(--surface-muted);
animation: art-enter var(--duration-slow) var(--ease-out);
}
@keyframes art-enter {
from { opacity: 0; transform: translateY(-6px); }
to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
.art-item { animation: none; }
}
.art-item__text { flex: 1 1 auto; min-width: 0; }
.art-item__name {
font-size: var(--body-lg-size);
line-height: 1.25;
font-weight: 700;
color: var(--ink);
}
.art-item__code {
margin-top: var(--space-2);
font-size: var(--label-md-size);
font-weight: 600;
color: var(--ink-muted);
font-variant-numeric: tabular-nums;
}
.art-item__remove {
flex: 0 0 auto;
display: flex;
align-items: center;
justify-content: center;
width: var(--touch-min);
height: var(--touch-min);
border: none;
border-radius: var(--radius-pill);
background: none;
color: var(--ink-muted);
font-size: 20px;
}
.art-item__remove:active { background-color: var(--danger-surface); color: var(--danger-ink); }
/* -----------------------------------------------------------------------------
Foto allegate striscia orizzontale scorrevole
-------------------------------------------------------------------------- */
.attach-strip {
display: flex;
gap: var(--space-xs);
overflow-x: auto;
scrollbar-width: none;
-webkit-overflow-scrolling: touch;
padding-inline: var(--space-md);
margin-inline: calc(var(--space-md) * -1);
}
.attach-strip::-webkit-scrollbar { display: none; }
.attach-item {
position: relative;
flex: 0 0 auto;
width: 104px;
border-radius: var(--radius-control);
overflow: hidden;
background-color: var(--surface-muted);
}
.attach-item__img {
width: 104px;
height: 104px;
object-fit: cover;
display: block;
}
.attach-item__placeholder {
width: 104px;
height: 104px;
display: flex;
align-items: center;
justify-content: center;
color: var(--ink-muted);
font-size: 26px;
}
.attach-item__remove {
position: absolute;
top: var(--space-4);
right: var(--space-4);
display: flex;
align-items: center;
justify-content: center;
width: 30px;
height: 30px;
border: none;
border-radius: var(--radius-pill);
background-color: rgba(0, 0, 0, 0.62);
color: #ffffff;
font-size: 20px;
}
.attach-item__remove:active { background-color: var(--danger-solid); }
/* -----------------------------------------------------------------------------
Bottone di azione secondaria con icona in pastiglia
-------------------------------------------------------------------------- */
.action-tile {
display: flex;
align-items: center;
gap: var(--space-sm);
width: 100%;
min-height: 56px;
padding: var(--space-sm) var(--space-md);
border: 1px solid var(--divider);
border-radius: var(--radius-control);
background-color: var(--surface);
font-family: inherit;
font-size: var(--body-lg-size);
font-weight: 600;
color: var(--ink);
text-align: left;
transition: transform var(--duration-fast) var(--ease-out),
background-color var(--duration-fast) var(--ease-out);
}
.action-tile:active { transform: scale(0.99); background-color: var(--surface-muted); }
.action-tile:disabled { color: var(--ink-muted); }
.action-tile__icon {
display: flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
border-radius: var(--radius-compact);
font-size: 20px;
flex: 0 0 auto;
}
.action-tile__icon--neutral { background-color: var(--neutral-surface); color: var(--neutral-ink); }
.action-tile__icon--primary { background-color: var(--danger-surface); color: var(--primary); }
.action-tile__icon--success { background-color: var(--success-surface); color: var(--success-ink); }
.action-tile__icon--danger { background-color: var(--danger-surface); color: var(--danger-ink); }
.action-tile__icon--info { background-color: var(--info-surface); color: var(--info-ink); }
.action-tile__label { flex: 1 1 auto; min-width: 0; }
@media (prefers-reduced-motion: reduce) {
.action-tile:active { transform: none; }
}
/* -----------------------------------------------------------------------------
Riga di selezione multipla
Una riga larga e tappabile al posto di un menu a tendina: con i guanti si
centra un bersaglio da 56px, non una casella da 18.
-------------------------------------------------------------------------- */
.select-row {
display: flex;
align-items: center;
gap: var(--space-sm);
width: 100%;
min-height: 56px;
padding: var(--space-10) var(--space-sm);
border: none;
border-radius: var(--radius-control);
background-color: var(--surface);
font-family: inherit;
text-align: left;
transition: background-color var(--duration-fast) var(--ease-out);
}
.select-row[aria-pressed="true"] { background-color: var(--info-surface); }
.select-row__check {
flex: 0 0 auto;
display: flex;
align-items: center;
justify-content: center;
width: 26px;
height: 26px;
border-radius: var(--radius-compact);
border: 2px solid var(--divider);
background-color: var(--surface);
color: transparent;
font-size: 18px;
transition: background-color var(--duration-fast) var(--ease-out),
border-color var(--duration-fast) var(--ease-out),
color var(--duration-fast) var(--ease-out);
}
.select-row[aria-pressed="true"] .select-row__check {
background-color: var(--primary);
border-color: var(--primary);
color: var(--on-primary);
}
.select-row__text { flex: 1 1 auto; min-width: 0; }
.select-row__title {
font-size: var(--body-lg-size);
line-height: 1.3;
font-weight: 600;
color: var(--ink);
}
.select-row__meta {
margin-top: var(--space-2);
font-size: var(--label-md-size);
font-weight: 600;
color: var(--ink-muted);
font-variant-numeric: tabular-nums;
}
@@ -0,0 +1,409 @@
/* =============================================================================
SteUP MudBlazor riportato allo stile condiviso
MudBlazor e' Material 2 di default: ombre per costruire gerarchia, tinte
automatiche sulle superfici, target stretti. Qui lo si appiattisce secondo
STILE_UI §1 e §5, cosi' i controlli di libreria e i componenti propri
parlano la stessa lingua.
========================================================================== */
/* -----------------------------------------------------------------------------
Aggancio delle variabili di MudBlazor ai token del progetto.
I token restano l'unica fonte di verita': cambiare un ruolo in tokens.css
aggiorna sia i componenti propri sia quelli di libreria.
-------------------------------------------------------------------------- */
:root {
--mud-palette-primary: var(--primary);
--mud-palette-primary-text: var(--on-primary);
--mud-palette-secondary: var(--primary-dark);
--mud-palette-tertiary: var(--info-surface);
--mud-palette-surface: var(--surface);
--mud-palette-background: var(--workspace);
--mud-palette-background-gray: var(--workspace);
--mud-palette-text-primary: var(--ink);
--mud-palette-text-secondary: var(--ink-muted);
--mud-palette-text-disabled: var(--ink-muted);
--mud-palette-action-default: var(--ink-muted);
--mud-palette-lines-default: var(--divider);
--mud-palette-lines-inputs: var(--divider);
--mud-palette-divider: var(--divider);
--mud-palette-divider-light: var(--divider);
--mud-palette-error: var(--danger-solid);
--mud-palette-error-text: #ffffff;
--mud-palette-success: var(--success-solid);
--mud-palette-warning: var(--warning-solid);
--mud-palette-info: var(--info-solid);
--mud-default-borderradius: var(--radius-control);
/* Tipografia: stessa scala dei token (STILE_UI §4). */
--mud-typography-default-family: "Inter", "SF Pro Display", "Roboto", system-ui, sans-serif;
--mud-typography-default-size: var(--body-lg-size);
--mud-typography-default-weight: 400;
--mud-typography-default-lineheight: var(--body-lg-height);
--mud-typography-default-letterspacing: normal;
--mud-typography-h5-family: var(--mud-typography-default-family);
--mud-typography-h5-size: var(--headline-sm-size);
--mud-typography-h5-weight: 700;
--mud-typography-h5-lineheight: var(--headline-sm-height);
--mud-typography-h6-family: var(--mud-typography-default-family);
--mud-typography-h6-size: var(--title-lg-size);
--mud-typography-h6-weight: 700;
--mud-typography-h6-lineheight: var(--title-lg-height);
--mud-typography-subtitle1-family: var(--mud-typography-default-family);
--mud-typography-subtitle1-size: var(--title-md-size);
--mud-typography-subtitle1-weight: 700;
--mud-typography-subtitle1-lineheight: var(--title-md-height);
--mud-typography-subtitle2-family: var(--mud-typography-default-family);
--mud-typography-subtitle2-size: var(--body-md-size);
--mud-typography-subtitle2-weight: 600;
--mud-typography-body1-family: var(--mud-typography-default-family);
--mud-typography-body1-size: var(--body-lg-size);
--mud-typography-body1-lineheight: var(--body-lg-height);
--mud-typography-body2-family: var(--mud-typography-default-family);
--mud-typography-body2-size: var(--body-md-size);
--mud-typography-body2-lineheight: var(--body-md-height);
--mud-typography-button-family: var(--mud-typography-default-family);
--mud-typography-button-size: var(--label-lg-size);
--mud-typography-button-weight: 600;
--mud-typography-button-transform: none;
--mud-typography-button-letterspacing: normal;
--mud-typography-caption-family: var(--mud-typography-default-family);
--mud-typography-caption-size: var(--label-md-size);
--mud-typography-caption-weight: 600;
}
/* -----------------------------------------------------------------------------
§1 Superfici piatte, nessun tint automatico
-------------------------------------------------------------------------- */
.mud-paper,
.mud-card,
.mud-expansion-panels .mud-expand-panel,
.mud-toolbar,
.mud-appbar {
box-shadow: none !important;
background-image: none !important;
background-color: var(--surface);
border-radius: var(--radius-surface);
}
.mud-elevation-0, .mud-elevation-1, .mud-elevation-2, .mud-elevation-3,
.mud-elevation-4, .mud-elevation-5, .mud-elevation-6, .mud-elevation-8,
.mud-elevation-12, .mud-elevation-16, .mud-elevation-24 {
box-shadow: none !important;
}
/* I livelli che galleggiano davvero conservano un contorno, non un'ombra. */
.mud-popover.mud-popover-open,
.mud-picker-popover-paper,
.mud-menu-popover {
border-radius: var(--radius-control) !important;
border: 1px solid var(--divider);
box-shadow: none !important;
}
/* -----------------------------------------------------------------------------
§5 Bottoni target 44/48, raggio control, etichette in caso naturale
-------------------------------------------------------------------------- */
.mud-button-root {
min-height: var(--touch-min);
border-radius: var(--radius-control);
font-family: var(--font-sans);
font-size: var(--label-lg-size);
font-weight: 600;
line-height: 1.25;
letter-spacing: normal;
text-transform: none;
transition: transform var(--duration-fast) var(--ease-out),
background-color var(--duration-fast) var(--ease-out);
}
.mud-button-root:active { transform: scale(0.97); }
.mud-button-filled {
min-height: var(--button-height);
box-shadow: none !important;
padding-inline: var(--space-lg);
}
.mud-button-filled.mud-button-filled-primary {
background-color: var(--primary);
color: var(--on-primary);
}
.mud-button-filled.mud-button-filled-primary:hover,
.mud-button-filled.mud-button-filled-primary:active {
background-color: var(--primary-pressed);
}
.mud-button-outlined {
min-height: var(--button-height);
border: 1px solid var(--divider);
color: var(--ink);
padding-inline: var(--space-lg);
}
.mud-button-text { min-height: var(--touch-min); }
.mud-icon-button {
min-width: var(--touch-min);
min-height: var(--touch-min);
border-radius: var(--radius-pill);
transition: transform var(--duration-fast) var(--ease-out),
background-color var(--duration-fast) var(--ease-out);
}
.mud-icon-button:active { transform: scale(0.92); }
/* Il FAB circolare al centro e' una firma Android di serie (§1.7): qui i FAB
sono rettangolari e stondati come il resto dei controlli. */
.mud-fab {
box-shadow: none !important;
border-radius: var(--radius-control);
min-height: var(--touch-min);
font-family: var(--font-sans);
font-weight: 600;
text-transform: none;
letter-spacing: normal;
}
.mud-fab.mud-fab-primary { background-color: var(--primary); color: var(--on-primary); }
.mud-fab.mud-fab-default { background-color: var(--surface-muted); color: var(--ink); }
.mud-fab:active { transform: scale(0.96); }
@media (prefers-reduced-motion: reduce) {
.mud-button-root:active,
.mud-icon-button:active,
.mud-fab:active { transform: none; }
}
/* -----------------------------------------------------------------------------
§5 Campi riempiti, raggio control, bordo 1px a riposo e 2px in focus
La sottolineatura Material viene rimossa: i campi sono schede, non righe.
-------------------------------------------------------------------------- */
.mud-input.mud-input-text,
.mud-input.mud-input-filled,
.mud-input-control .mud-input-slot {
font-family: var(--font-sans);
font-size: var(--body-lg-size);
color: var(--ink);
}
.mud-input:before,
.mud-input:after,
.mud-input-filled:before,
.mud-input-filled:after,
.mud-input-underline:before,
.mud-input-underline:after {
display: none !important;
border: none !important;
}
.field-shell {
background-color: var(--surface);
border: 1px solid var(--divider);
border-radius: var(--radius-control);
padding: var(--space-md);
transition: border-color var(--duration-fast) var(--ease-out),
box-shadow var(--duration-fast) var(--ease-out);
}
.field-shell:focus-within {
border-color: var(--primary);
box-shadow: inset 0 0 0 1px var(--primary);
}
.field-shell--error { border-color: var(--danger-solid); }
.field-shell--muted { background-color: var(--surface-muted); }
.mud-input-label,
.mud-input-helper-text {
font-family: var(--font-sans);
color: var(--ink-muted);
}
.mud-input-helper-text.mud-input-error,
.mud-input-error .mud-input-helper-text {
color: var(--danger-ink);
font-weight: 600;
}
/* Il testo segnaposto deve restare leggibile al sole: stesso contrasto del
testo secondario, non il grigio chiarissimo di serie. */
.mud-input input::placeholder,
.mud-input textarea::placeholder {
color: var(--ink-muted);
opacity: 1;
}
.mud-select .mud-input-adornment .mud-icon-root { color: var(--ink-muted); }
/* -----------------------------------------------------------------------------
Select, liste e voci di menu
-------------------------------------------------------------------------- */
.mud-list-item {
min-height: var(--touch-min);
border-radius: var(--radius-compact);
font-family: var(--font-sans);
font-size: var(--body-lg-size);
}
.mud-list-item.mud-selected-item {
background-color: var(--info-surface);
color: var(--primary-dark);
font-weight: 600;
}
.custom-item-select { padding-block: var(--space-xs); }
/* -----------------------------------------------------------------------------
Chip
-------------------------------------------------------------------------- */
.mud-chip {
border-radius: var(--radius-pill);
font-family: var(--font-sans);
font-size: var(--label-sm-size);
font-weight: 700;
letter-spacing: normal;
text-transform: none;
}
.mud-chip.mud-chip-filled.mud-chip-color-default {
background-color: var(--neutral-surface);
color: var(--neutral-ink);
}
/* -----------------------------------------------------------------------------
Pannelli a fisarmonica nessun bordo di serie, nessuna ombra
-------------------------------------------------------------------------- */
.mud-expansion-panels { width: 100%; }
.mud-expand-panel {
background-color: transparent !important;
border: none !important;
margin-block: 0 !important;
}
.mud-expand-panel .mud-expand-panel-header {
padding: var(--space-sm) 0;
min-height: var(--touch-min);
}
.mud-expand-panel .mud-expand-panel-content { padding: 0; }
.mud-expand-panel::before { display: none !important; }
/* -----------------------------------------------------------------------------
§6.10 Dialog
-------------------------------------------------------------------------- */
.mud-dialog {
border-radius: var(--radius-surface) !important;
background-color: var(--surface);
box-shadow: none !important;
max-width: 420px;
width: calc(100vw - 48px);
}
.mud-dialog-title {
padding: var(--space-lg) var(--space-lg) 0;
font-family: var(--font-sans);
font-size: var(--title-md-size);
line-height: var(--title-md-height);
font-weight: 700;
color: var(--ink);
}
.mud-dialog-content {
padding: var(--space-xs) var(--space-lg) 0;
font-family: var(--font-sans);
font-size: var(--body-lg-size);
line-height: 1.45;
color: var(--ink-muted);
overflow-x: hidden;
}
.mud-dialog-actions {
display: flex;
gap: var(--space-sm);
padding: var(--space-lg);
}
.mud-dialog-actions > * { flex: 1 1 0; margin: 0 !important; }
/* Il form scheda e' a schermo pieno: e' una schermata, non un riquadro. */
.mud-dialog.customDialog-form {
max-width: 100%;
width: 100%;
height: 100%;
max-height: 100%;
margin: 0;
border-radius: 0 !important;
background-color: var(--workspace);
}
.mud-dialog.customDialog-form .mud-dialog-content {
padding: 0;
max-height: 100%;
height: 100%;
color: var(--ink);
}
.mud-overlay { z-index: var(--z-overlay); }
.mud-overlay.on-top { z-index: var(--z-modal) !important; }
/* -----------------------------------------------------------------------------
§6.9 Toast riempimento pieno del tono, testo bianco, l'unica ombra
-------------------------------------------------------------------------- */
.mud-snackbar {
border-radius: var(--radius-control) !important;
box-shadow: var(--shadow-toast) !important;
font-family: var(--font-sans);
font-size: var(--body-lg-size);
font-weight: 600;
line-height: 1.35;
color: #ffffff !important;
padding: var(--space-sm) var(--space-14) !important;
z-index: var(--z-toast);
}
.mud-snackbar.mud-alert-filled-success { background-color: var(--success-solid) !important; }
.mud-snackbar.mud-alert-filled-error { background-color: var(--danger-solid) !important; }
.mud-snackbar.mud-alert-filled-warning { background-color: var(--warning-solid) !important; }
.mud-snackbar.mud-alert-filled-info { background-color: var(--info-solid) !important; }
.mud-snackbar .mud-snackbar-content-message { color: #ffffff !important; }
.mud-snackbar .mud-icon-root { color: #ffffff !important; }
/* -----------------------------------------------------------------------------
Progresso
-------------------------------------------------------------------------- */
.mud-progress-linear { border-radius: var(--radius-compact); height: 8px; }
.mud-progress-linear .mud-progress-linear-bar { background-color: var(--primary); }
.mud-progress-circular.mud-primary-text { color: var(--primary); }
/* -----------------------------------------------------------------------------
Il ripple di Mud viene disattivato dove il contenitore ha il proprio
feedback al tocco, per non avere due risposte sovrapposte allo stesso dito.
-------------------------------------------------------------------------- */
.ripple-container .mud-ripple-effect,
.ripple-container .mud-ripple-effect-expanding {
display: none !important;
}
.mud-skeleton { border-radius: var(--radius-compact) !important; }
+167
View File
@@ -0,0 +1,167 @@
/* =============================================================================
SteUP Token di design
Implementa STILE_UI.md §2 (ruoli colore) e §3 (scale) sulla palette SteUP.
Regola: nelle pagine si usano SOLO questi token. Un colore o un raggio
scritto a mano in una schermata e' un difetto, non una scorciatoia.
========================================================================== */
:root {
/* -------------------------------------------------------------------------
COLORE ruoli semantici (STILE_UI §2)
La palette storica di SteUP resta intatta: corallo azione, navy ancora,
azzurro tenue informativo. Sono stati aggiunti solo i ruoli che
mancavano: workspace, surfaceMuted, divider, inkMuted e le coppie
(foreground forte / superficie tenue) dei toni semantici.
---------------------------------------------------------------------- */
/* Accento unico di azione. La sua rarita' e' cio' che lo rende un segnale. */
--primary: #ec4c41;
--primary-pressed: #d23a30;
--on-primary: #ffffff;
/* Ancora della struttura: testo forte, icone metrica, foreground su info. */
--primary-dark: #002339;
/* Superfici: lo sfondo pagina e' piu' freddo delle superfici di lavoro.
Tre gradini netti, cosi' i pannelli staccano senza bisogno di ombre. */
--workspace: #e9edf2;
--surface: #ffffff;
--surface-muted: #f4f6f9;
--divider: #d9e0e8;
/* Testo. Inchiostro pieno per la lettura in pieno sole (Regola del
Contrasto da Sole): niente grigio chiaro sul corpo del testo. */
--ink: #000000;
--ink-muted: #465563; /* 8.3:1 su surface, 7.4:1 su workspace */
/* --- Toni semantici -----------------------------------------------------
Ogni tono e' una tripletta:
-ink foreground forte: testo e icone sopra la superficie tenue
-surface riempimento tenue: badge, pannelli, cerchi-icona dei dialog
-solid riempimento pieno: toast (testo bianco sopra)
Gli -ink sono scelti per superare 4.5:1 sulla propria superficie tenue:
i colori "puri" della palette restano per icone e riempimenti pieni,
dove il contrasto di testo non e' in gioco.
-------------------------------------------------------------------- */
/* Danger — errori, azioni distruttive, priorita' massima */
--danger-ink: #b3120c;
--danger-surface: #fdeceb;
--danger-solid: #e50000;
/* Warning — attenzione, dati incompleti, bozze da completare */
--warning-ink: #8a4f00;
--warning-surface: #fdf0db;
--warning-solid: #b26a00;
/* Success — conferme, completamenti, sincronizzato */
--success-ink: #10702f;
--success-surface: #e4f5e9;
--success-solid: #26b050;
/* Info — stato informativo, pannelli di riepilogo, selezione */
--info-ink: #002339;
--info-surface: #dff2ff;
--info-solid: #1877d8;
/* Neutral — stati senza carica semantica */
--neutral-ink: #465563;
--neutral-surface: #f4f6f9;
--neutral-solid: #465563;
/* Focus da tastiera */
--focus-ring: #258cfb;
/* -------------------------------------------------------------------------
SPAZIATURA (STILE_UI §3)
---------------------------------------------------------------------- */
--space-xs: 8px;
--space-sm: 12px;
--space-md: 16px;
--space-lg: 24px;
--space-xl: 32px;
/* Micro-distanze derivate, d'uso frequente */
--space-2: 2px;
--space-4: 4px;
--space-6: 6px;
--space-10: 10px; /* tra le card di una lista */
--space-14: 14px;
--space-18: 18px; /* padding dei pannelli di testata */
--space-20: 20px;
--space-22: 22px;
/* -------------------------------------------------------------------------
RAGGI (STILE_UI §3)
Superfici piu' arrotondate dei controlli; stati completamente stondati.
---------------------------------------------------------------------- */
--radius-compact: 8px;
--radius-control: 16px;
--radius-surface: 20px;
--radius-pill: 999px;
/* -------------------------------------------------------------------------
TIPOGRAFIA (STILE_UI §4)
Scala fissa: si legge a colpo d'occhio, non fa effetto editoriale.
---------------------------------------------------------------------- */
--font-sans: "Inter", "SF Pro Display", "Roboto", system-ui, sans-serif;
--headline-md-size: 34px;
--headline-md-height: 1.2;
--headline-sm-size: 28px;
--headline-sm-height: 1.25;
--title-lg-size: 22px;
--title-lg-height: 1.3;
--title-md-size: 18px;
--title-md-height: 1.35;
--body-lg-size: 16px;
--body-lg-height: 1.5;
--body-md-size: 15px;
--body-md-height: 1.45;
--label-lg-size: 14px;
--label-md-size: 13px;
--label-sm-size: 12px;
/* -------------------------------------------------------------------------
MISURE STRUTTURALI
---------------------------------------------------------------------- */
--appbar-height: 80px;
--navbar-height: 68px;
--touch-min: 44px;
--button-height: 48px;
--content-max: 920px;
/* Spazio che le pagine lasciano in fondo per non finire sotto la barra
flottante di navigazione (STILE_UI §6.15). */
--nav-clearance: 116px;
/* -------------------------------------------------------------------------
MOVIMENTO
Curve esponenziali in uscita: il movimento serve allo stato, mai alla
scena. Durate da prodotto, l'utente e' dentro un compito.
---------------------------------------------------------------------- */
--ease-out: cubic-bezier(0.22, 1, 0.36, 1);
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
--duration-fast: 120ms;
--duration-base: 200ms;
--duration-slow: 280ms;
/* -------------------------------------------------------------------------
PROFONDITA' scala semantica, mai valori arbitrari
Le superfici sono piatte (STILE_UI §1): questi livelli ordinano solo
cio' che galleggia davvero.
---------------------------------------------------------------------- */
--z-base: 0;
--z-sticky: 10;
--z-navbar: 20;
--z-connection: 30;
--z-overlay: 40;
--z-modal: 50;
--z-toast: 60;
/* L'unica ombra del sistema: il toast (STILE_UI §6.9). */
--shadow-toast: 0 6px 20px rgba(0, 0, 0, 0.24);
/* Breakpoint (STILE_UI §3) documentati qui, usati nelle media query:
rail 720px · twoColumn 900px · contentMax 1180px */
}