Files
SteUP_Dotnet/DESIGN.md
T
MarcoE 2a0054aa30 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>
2026-09-17 11:09:26 +02:00

271 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: SteUP
description: Strumento da campo per ispezioni nei punti vendita — solido, chiaro, offline-first.
colors:
primary: "#ec4c41"
primary-pressed: "#d23a30"
primary-dark: "#002339"
on-primary: "#ffffff"
workspace: "#e9edf2"
surface: "#ffffff"
surface-muted: "#f4f6f9"
divider: "#d9e0e8"
ink: "#000000"
ink-muted: "#465563"
danger-ink: "#b3120c"
danger-surface: "#fdeceb"
danger-solid: "#e50000"
warning-ink: "#8a4f00"
warning-surface: "#fdf0db"
warning-solid: "#b26a00"
success-ink: "#10702f"
success-surface: "#e4f5e9"
success-solid: "#26b050"
info-ink: "#002339"
info-surface: "#dff2ff"
info-solid: "#1877d8"
neutral-ink: "#465563"
neutral-surface: "#f4f6f9"
focus-ring: "#258cfb"
typography:
headline-medium:
fontFamily: "Inter, sans-serif"
fontSize: "34px"
fontWeight: 700
lineHeight: 1.2
letterSpacing: "-0.02em"
headline-small:
fontFamily: "Inter, sans-serif"
fontSize: "28px"
fontWeight: 700
lineHeight: 1.25
letterSpacing: "-0.02em"
title-large:
fontFamily: "Inter, sans-serif"
fontSize: "22px"
fontWeight: 700
lineHeight: 1.3
letterSpacing: "-0.01em"
title-medium:
fontFamily: "Inter, sans-serif"
fontSize: "18px"
fontWeight: 700
lineHeight: 1.35
letterSpacing: "normal"
body-large:
fontFamily: "Inter, sans-serif"
fontSize: "16px"
fontWeight: 400
lineHeight: 1.5
letterSpacing: "normal"
body-medium:
fontFamily: "Inter, sans-serif"
fontSize: "15px"
fontWeight: 400
lineHeight: 1.45
letterSpacing: "normal"
label-large:
fontFamily: "Inter, sans-serif"
fontSize: "14px"
fontWeight: 600
lineHeight: 1.25
letterSpacing: "normal"
label-medium:
fontFamily: "Inter, sans-serif"
fontSize: "13px"
fontWeight: 600
lineHeight: 1.25
letterSpacing: "normal"
label-small:
fontFamily: "Inter, sans-serif"
fontSize: "12px"
fontWeight: 700
lineHeight: 1.3
letterSpacing: "0.3px"
icon-sm:
fontFamily: "remixicon"
fontSize: "15px"
fontWeight: 400
lineHeight: 1
letterSpacing: "normal"
icon-md:
fontFamily: "remixicon"
fontSize: "20px"
fontWeight: 400
lineHeight: 1
letterSpacing: "normal"
icon-lg:
fontFamily: "remixicon"
fontSize: "26px"
fontWeight: 400
lineHeight: 1
letterSpacing: "normal"
icon-xl:
fontFamily: "remixicon"
fontSize: "44px"
fontWeight: 400
lineHeight: 1
letterSpacing: "normal"
rounded:
compact: "8px"
control: "16px"
surface: "20px"
sheet: "24px"
pill: "999px"
spacing:
xs: "8px"
sm: "12px"
md: "16px"
lg: "24px"
xl: "32px"
touch-min: "44px"
button-height: "48px"
appbar-height: "80px"
navbar-height: "68px"
content-max: "920px"
components:
panel:
backgroundColor: "{colors.surface}"
textColor: "{colors.ink}"
rounded: "{rounded.surface}"
padding: "16px"
button-primary:
backgroundColor: "{colors.primary}"
textColor: "{colors.on-primary}"
rounded: "{rounded.control}"
typography: "{typography.label-large}"
padding: "0 24px"
button-outlined:
backgroundColor: "{colors.surface}"
textColor: "{colors.ink}"
rounded: "{rounded.control}"
typography: "{typography.label-large}"
badge:
rounded: "{rounded.pill}"
typography: "{typography.label-small}"
padding: "5px 9px"
navbar:
backgroundColor: "{colors.surface}"
rounded: "{rounded.sheet}"
---
# Design System: SteUP
## 1. Overview
**Creative North Star: "Il taccuino da campo"**
SteUP è lo strumento che il rilevatore tiene in mano mentre gira i punti vendita: deve funzionare come carta e inchiostro — sempre, anche senza rete, leggibile in pieno sole, comprensibile con un'occhiata.
Il sistema visivo segue **`STILE_UI.md`**, lo stile condiviso delle app Integry (riferimento: Fixiy). Quel documento definisce forma, ritmo, tipografia e composizione; questo documento fissa i valori concreti di SteUP su quei ruoli.
**Caratteristiche portanti:**
- **Superfici piatte.** Nessuna ombra costruisce gerarchia: la separazione viene dal contrasto di superficie (sfondo pagina più freddo delle superfici) e dallo spazio. L'unica ombra del sistema è quella del toast.
- **Offline-first.** Lo stato di salvataggio e sincronizzazione è sempre esplicito. Il carattere è ospitato in locale: un font che arriva dalla rete è un font che in campo non arriva.
- **Il pollice comanda.** Tocchi ≥44px, azioni primarie in basso: navigazione flottante, barra azioni ancorata in fondo ai form.
- **Alto contrasto.** Inchiostro pieno sul corpo del testo, per la luce diretta del sole.
- **Un solo accento.** Il corallo indica azione e stato attivo, mai decorazione.
## 2. Colors
I ruoli sono quelli di `STILE_UI.md` §2, riempiti con la palette storica di SteUP. Sono stati aggiunti solo i ruoli che mancavano: `workspace`, `surface-muted`, `divider`, `ink-muted` e le triplette dei toni semantici.
### Accento e ancora
- **Corallo** (`#ec4c41`) — `primary`: il colore dell'azione. Pulsanti primari, selezione, progresso, FAB. La sua rarità è ciò che lo rende un segnale.
- **Blu Profondo** (`#002339`) — `primary-dark`: ancora della struttura. Testo su superfici informative, icone metrica, valori in evidenza, bottone di accesso.
### Superfici — tre gradini netti
- `workspace` (`#e9edf2`): sfondo dell'applicazione, più freddo delle superfici di lavoro.
- `surface` (`#ffffff`): card, pannelli, testate, barra di navigazione, dialog.
- `surface-muted` (`#f4f6f9`): superficie secondaria dentro una superficie (campo di ricerca, chip a riposo, riquadri interni).
- `divider` (`#d9e0e8`): bordi 1px e contorni dei controlli a riposo.
### Testo
- `ink` (`#000000`): corpo del testo. **La Regola del Contrasto da Sole**: il grigio chiaro "per eleganza" è vietato sul testo leggibile.
- `ink-muted` (`#465563`): testo secondario, metadati, icone non attive. 8.3:1 su `surface`, 7.4:1 su `workspace`. Il testo secondario si distingue per **colore**, mai per opacità o peso sotto 400.
### Toni semantici — la regola delle triplette
Ogni tono è una tripletta *(ink, surface, solid)*:
- `-ink` colora testo e icone **sopra la superficie tenue** (sempre ≥4.5:1 su quella superficie);
- `-surface` riempie badge, pannelli di feedback e cerchi-icona dei dialog;
- `-solid` è il riempimento pieno dei toast, con testo bianco sopra.
I colori "puri" della palette storica (`#e50000`, `#26b050`) vivono come `-solid`: sono giusti per riempimenti e icone, non abbastanza contrastati per il testo. Per questo esistono `danger-ink` e `success-ink`.
| Tono | Uso |
|---|---|
| danger | errori, azioni distruttive, schede da inviare |
| warning | attenzione, dati incompleti, bozze da completare |
| success | conferme, completamenti, sincronizzato |
| info | stato informativo, pannelli di riepilogo, selezione |
| neutral | stati senza carica semantica |
### Named Rules
**La Regola dell'Unico Accento.** Il corallo appare solo su azione o stato attivo, mai come decorazione.
**Mai il solo colore.** Ogni stato porta sempre icona **e** etichetta testuale. Le mappature stanno in `StatusBadgeHelper`: uno stato si presenta identico ovunque, e uno nuovo si aggiunge in un punto solo.
## 3. Typography
**Famiglia unica: Inter** (variabile 100900), **ospitata in locale** in `wwwroot/fonts`. Scala fissa, pensata per la scansione rapida, non per l'effetto editoriale. La gerarchia si fa con peso e dimensione.
Le cifre sono tabellari (`font-feature-settings: "tnum"`), così contatori e codici non "ballano" mentre si aggiornano.
### Named Rules
**La Regola del Peso, non del Maiuscolo.** L'enfasi si ottiene con il peso (600/700/800) e la dimensione. Niente maiuscoletto spaziato, niente eyebrow sopra le sezioni.
**Il titolo è l'entità.** Nelle card di elenco il titolo è il punto vendita o il motivo, non il tipo di record. L'identificativo tecnico sta sopra, in 12px `ink-muted`.
**Le righe di metadato** si compongono con separatore ` · `.
## 4. Elevation
**Zero.** Le superfici sono piatte: nessuna ombra, nessun `surface-tint`. La profondità è tonale (`surface` su `workspace`) più lo spazio.
Le uniche eccezioni: il **toast**, che deve leggersi sopra qualunque contenuto, e i livelli modali di sistema (scrim del bottom sheet e degli overlay). Popover e menu si staccano con un bordo 1px `divider`, non con un'ombra.
La profondità di impilamento usa una **scala semantica** (`--z-sticky``--z-navbar``--z-connection``--z-overlay``--z-modal``--z-toast`), mai valori arbitrari.
## 5. Components
- **Panel** — il mattone di tutto: `surface`, raggio 20, padding 16, senza bordo. Varianti tonali per riepiloghi (`info`) e sotto-riquadri (`muted`).
- **Card di elenco** — identificativo, titolo-entità, riga meta, badge, footer con conteggi, barra azioni interna che passa a colonna sotto i 350px.
- **Badge** — pillola con icona 15px + etichetta 12px peso 700, costruita da funzione di mappatura.
- **Testata** — alta 80px, titolo a sinistra, sfondo uguale alla pagina. Non una AppBar colorata col titolo centrato.
- **Navigazione** — barra flottante in basso (raggio 24, margine 16, bordo 1px), icona outline a riposo e piena da selezionata, pastiglia `info-surface` sulla voce attiva. Da 720px diventa colonna laterale.
- **Bottom sheet** — maniglia, testata, un'unica linea di struttura, corpo scorrevole. Sostituisce i menu flottanti.
- **Barra azioni ancorata** — bordo superiore 1px, bottoni in riga, colonna sotto i 390px. Nei form il salvataggio sta qui, non in fondo allo scroll.
- **Campi** — riempiti, raggio 16, bordo 1px a riposo e 2px in focus. Sottolineatura Material rimossa: i campi sono schede, non righe.
- **Selezione multipla** — righe da 56px con casella 26px, non un menu a tendina: con i guanti si centra un bersaglio grande.
- **Stato vuoto** — icona, titolo, messaggio che **suggerisce la mossa successiva**, azione facoltativa.
- **Caricamento** — scheletri che hanno già la forma del contenuto, non spinner in mezzo alla pagina. L'overlay pieno è riservato alle operazioni bloccanti, e dice sempre cosa sta facendo.
### Signature: Barra di Stato Connessione
Striscia sottile ancorata in cima che scende con una transizione morbida quando la rete o il backend cambiano stato. È l'incarnazione visiva di "Offline è la verità".
## 6. Motion
Curve esponenziali in uscita (`cubic-bezier(0.22, 1, 0.36, 1)`), durate 120/200/280ms. Il movimento **serve allo stato**: risposta al tocco (l'elemento cede sotto il dito), entrata di un articolo scansionato, salita di uno sheet, disegno della spunta di conferma. Niente animazioni di scena al caricamento.
Nessuno stato dipende dall'hover: su un touch screen non esiste, e lascia elementi accesi dopo il tocco. Gli stili hover sono dietro `@media (hover: hover)`.
`prefers-reduced-motion` ha un'alternativa per ogni animazione.
## 7. Do's and Don'ts
### Do:
- **Do** usare solo i token: un colore, un raggio o una spaziatura scritti a mano in una schermata sono un difetto da correggere.
- **Do** mostrare sempre i conteggi ("12 schede", "3 da inviare"): il rilevatore deve sapere quanto ha davanti senza contare.
- **Do** distinguere "non c'è nulla" da "i filtri non trovano nulla", e nel secondo caso offrire l'azzeramento.
- **Do** dimensionare i bersagli ≥44px e tenere le azioni primarie a portata di pollice.
- **Do** rendere esplicito lo stato offline/sync, sempre con icona più etichetta.
- **Do** rispettare le safe-area e `prefers-reduced-motion`.
### Don't:
- **Don't** usare ombre per costruire gerarchia, né `surface-tint` sulle superfici.
- **Don't** usare le firme Android di serie: card con ombra, FAB circolare al centro, AppBar colorata col titolo centrato, snackbar di sistema.
- **Don't** usare bordo-laterale colorato (`border-left/right` > 1px) come accento.
- **Don't** usare testo grigio chiaro sul corpo, testo con gradiente, glassmorphism decorativo, griglie di card tutte identiche, eyebrow maiuscoli.
- **Don't** reinventare affordance standard per "carattere".
- **Don't** far dipendere un'informazione dal solo colore.