2a0054aa30
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>
271 lines
12 KiB
Markdown
271 lines
12 KiB
Markdown
---
|
||
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 100–900), **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.
|