Files
SteUP_Dotnet/SteUp.Shared/wwwroot/css/forms.css
T
MarcoE 2d7e3c591e Dai una gerarchia ai pesi tipografici
Quasi tutto il testo dell'app stava fra 600 e 800: etichette, valori, indirizzi,
conteggi, voci di elenco. Un grassetto ovunque non segnala niente, e la pagina
Profilo era il caso peggiore — ogni riga gridava come un titolo.

La scala ora ha quattro gradini, documentati nei token:
  400  corpo, metadati, valori descrittivi
  500  etichette di campo, voci di lista, testo dei controlli
  600  stati brevi (badge, voce attiva), nomi in una riga di elenco
  700  titoli, uno solo per blocco

Sopra il 700 non si sale: l'800 dei titoli di card e dell'avatar e' sceso a 700.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 12:46:28 +02:00

403 lines
12 KiB
CSS

/* =============================================================================
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);
}
/* Su schermo stretto il form e' lungo: ogni pixel di padding e' una riga di
lavoro in meno visibile a colpo d'occhio. */
@media (max-width: 380px) {
.form-group { padding: var(--space-sm) var(--space-14); }
}
.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: 500;
color: var(--ink-muted);
margin-bottom: var(--space-6);
}
.form-group__count {
font-size: var(--label-md-size);
font-weight: 500;
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: 500;
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: 500;
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: 500;
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: 500;
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: 500;
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: 600;
color: var(--ink);
}
.art-item__code {
margin-top: var(--space-2);
font-size: var(--label-md-size);
font-weight: 400;
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: 500;
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); }
/* Le azioni costruttive secondarie non portano l'accento: il corallo resta del
pulsante primario. Un fondo corallo tenue sarebbe comunque indistinguibile
dal tono danger, perche' il primario di SteUP e' gia' un rosso — ed e'
esattamente cosi' che "Nuova scheda" finiva identica a "Elimina ispezione". */
.action-tile__icon--primary { background-color: var(--info-surface); color: var(--info-ink); }
.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;
}