{ "schemaVersion": 2, "generatedAt": "2026-07-08T00:00:00.000Z", "title": "Design System: SteUP", "extensions": { "colorMeta": { "primary": { "role": "primary", "displayName": "Arancio-Rosso Allerta", "canonical": "#ec4c41", "tonalRamp": ["#3a0f0b", "#5e1712", "#8a2019", "#b62f24", "#ec4c41", "#f27a72", "#f7a9a3", "#fcdcd9"] }, "secondary": { "role": "secondary", "displayName": "Blu Profondo", "canonical": "#002339", "tonalRamp": ["#000c14", "#001622", "#002339", "#003653", "#0a5480", "#3f7ea8", "#87b3d0", "#d5e6f1"] }, "tertiary": { "role": "tertiary", "displayName": "Azzurro Tenue", "canonical": "#dff2ff", "tonalRamp": ["#12313f", "#1c5570", "#2b7ba3", "#4aa4d1", "#86c8e8", "#b3ddf3", "#dff2ff", "#f2faff"] }, "ink": { "role": "neutral", "displayName": "Inchiostro", "canonical": "#000000", "tonalRamp": ["#000000", "#1a1a1a", "#333333", "#4d4d4d", "#737373", "#999999", "#cccccc", "#f5f5f5"] }, "paper": { "role": "neutral", "displayName": "Carta", "canonical": "#ffffff", "tonalRamp": ["#c2c2c2", "#d1d1d1", "#e0e0e0", "#ededed", "#f5f5f5", "#fafafa", "#ffffff", "#ffffff"] }, "success": { "role": "semantic", "displayName": "Verde OK", "canonical": "#26b050", "tonalRamp": ["#0a3318", "#125025", "#1a7d38", "#26b050", "#4fca72", "#84dc9d", "#b7ecc6", "#e6f9ec"] }, "error": { "role": "semantic", "displayName": "Rosso Errore", "canonical": "#e50000", "tonalRamp": ["#3a0000", "#5e0000", "#8a0000", "#b60000", "#e50000", "#f24d4d", "#f79999", "#fcdcdc"] }, "focus-ring": { "role": "semantic", "displayName": "Blu Focus", "canonical": "#258cfb", "tonalRamp": ["#08213f", "#0c3a70", "#1257b6", "#258cfb", "#5aa9fc", "#8fc4fd", "#c4e0fe", "#eaf4ff"] } }, "typographyMeta": { "page-title": { "displayName": "Page Title", "purpose": "Titolo di schermata; ancora l'utente al compito corrente." }, "title": { "displayName": "Title", "purpose": "Intestazioni di sezione, titoli di dialog e message-box." }, "body": { "displayName": "Body", "purpose": "Testo corrente e dati; prosa a 65-75ch." }, "label": { "displayName": "Label", "purpose": "Etichette di pulsanti e controlli di form; peso 700 per presenza al tocco." } }, "shadows": [ { "name": "ombra-custom", "value": "1px 2px 5px hsl(from var(--mud-palette-overlay-dark) h s 40%)", "purpose": "Stacco morbido per card ed elementi che galleggiano sul contenuto." }, { "name": "ombra-eccezione", "value": "1px 2px 5px rgba(0,0,0,0.3)", "purpose": "Rilievo leggermente più marcato per box di errore/eccezione." } ], "motion": [ { "name": "connection-slide", "value": "all 0.5s ease", "purpose": "Comparsa/scomparsa della barra di stato connessione (translateY)." }, { "name": "ripple", "value": "ripple-effect 0.6s linear", "purpose": "Feedback fisico al tocco su pulsanti e contenitori tattili." }, { "name": "spinner", "value": "l24 1s infinite linear", "purpose": "Loader di caricamento a doppio anello." } ], "breakpoints": [ { "name": "mobile", "value": "0px" } ] }, "components": [ { "name": "Primary Button", "kind": "button", "refersTo": "button-primary", "description": "Azione primaria: fondo accento, etichetta bianca in grassetto, angoli molto arrotondati.", "html": "", "css": ".ds-btn-primary { font-family: Nunito, sans-serif; background: #ec4c41; color: #fff; font-weight: 700; font-size: 0.9375rem; border: none; border-radius: 20px; padding: 0.65rem 1.5rem; min-height: 44px; cursor: pointer; transition: filter 0.15s ease, transform 0.1s ease; } .ds-btn-primary:hover { filter: brightness(1.05); } .ds-btn-primary:focus-visible { outline: none; box-shadow: 0 0 0 0.1rem #fff, 0 0 0 0.25rem #258cfb; } .ds-btn-primary:active { transform: translateY(1px); filter: brightness(0.95); }" }, { "name": "FAB (Floating Action)", "kind": "button", "refersTo": "button-primary", "description": "Azione primaria fissa in basso a destra, a portata di pollice; rispetta la safe-area.", "html": "", "css": ".ds-fab { font-family: Nunito, sans-serif; position: fixed; bottom: 4rem; right: 16px; width: 56px; height: 56px; border-radius: 50%; border: none; background: #ec4c41; color: #fff; display: inline-flex; align-items: center; justify-content: center; box-shadow: 1px 2px 5px rgba(0,0,0,0.3); cursor: pointer; transition: filter 0.15s ease, transform 0.1s ease; } .ds-fab:hover { filter: brightness(1.05); } .ds-fab:active { transform: translateY(1px); } .ds-fab:focus-visible { outline: none; box-shadow: 0 0 0 0.1rem #fff, 0 0 0 0.25rem #258cfb; }" }, { "name": "Input Card", "kind": "input", "refersTo": "input-card", "description": "Campo a scheda su fondo grigio tonale, senza underline; etichetta a sinistra, valore a destra.", "html": "", "css": ".ds-input-card { font-family: Nunito, sans-serif; display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; width: 100%; background: #f5f5f5; border-radius: 9px; padding: 0.5rem 1rem; min-height: 44px; } .ds-input-label { font-weight: 700; color: #000; } .ds-input-field { font-family: Nunito, sans-serif; font-weight: 500; text-align: right; border: none; background: transparent; color: #000; outline: none; min-width: 0; } .ds-input-field:focus { outline: none; }" }, { "name": "Connection Status Bar", "kind": "custom", "refersTo": null, "description": "Striscia di stato rete/servizio che scorre dall'alto: verde se OK, rosso se KO. Incarna 'Offline è la verità'.", "html": "
Nessuna connessione — lavoro salvato in locale
", "css": ".ds-connection { font-family: Nunito, sans-serif; display: flex; align-items: center; gap: 1rem; min-height: 35px; padding: 0 0.75rem; font-weight: 700; font-size: 1.05rem; color: #fff; transition: all 0.5s ease; } .ds-connection--ko { background: #e50000; } .ds-connection--ok { background: #26b050; }" }, { "name": "Panel / Card", "kind": "card", "refersTo": "panel", "description": "Superficie di contenuto: carta bianca, angoli 1em, piatta di default, ombra solo se galleggia.", "html": "

Scheda articolo

Dettagli della rilevazione.

", "css": ".ds-panel { font-family: Nunito, sans-serif; background: #fff; color: #000; border-radius: 1em; padding: 1rem; } .ds-panel-title { font-weight: 700; font-size: 1.1rem; margin: 0 0 0.5rem; } .ds-panel-body { font-weight: 400; font-size: 0.875rem; line-height: 1.8; margin: 0; }" } ], "narrative": { "northStar": "Il taccuino da campo", "overview": "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. La chiarezza viene prima di qualsiasi ornamento. Il sistema è tattile e sicuro: bersagli ampi per il pollice, una sola mano e i guanti; feedback fisico immediato a ogni tocco e scansione. Lo stato — salvato in locale, in attesa di sync, inviato, completato — non è mai ambiguo. Rifiuta il gestionale datato e denso e l'app consumer social/giocosa: è uno strumento professionale.", "keyCharacteristics": [ "Offline-first: lo stato di salvataggio e sincronizzazione è sempre esplicito", "Mobile-first, uso a una mano/guanti: tocchi ≥44px, azioni a portata di pollice", "Alto contrasto e testo generoso per la leggibilità all'aperto", "Un solo accento (Arancio-Rosso Allerta), usato per azione e stato, mai per decorazione", "Un'unica famiglia tipografica, angoli arrotondati coerenti (9px → 20px → 1em)" ], "rules": [ { "name": "La Regola dell'Unico Accento", "body": "L'Arancio-Rosso Allerta è l'unico accento del sistema e appare solo su azione o stato attivo, mai come decorazione. La sua rarità è ciò che lo rende un segnale.", "section": "colors" }, { "name": "La Regola del Contrasto da Sole", "body": "Il testo di corpo è inchiostro (#000) su carta (#fff). Il grigio chiaro 'per eleganza' è vietato sul testo leggibile: si progetta per lo schermo colpito dal sole.", "section": "colors" }, { "name": "La Regola del Peso, non del Maiuscolo", "body": "L'enfasi si ottiene con il peso (700/800) e la dimensione, non con il maiuscolo spaziato. Niente eyebrow maiuscoli tracciati sopra le sezioni.", "section": "typography" }, { "name": "La Regola del Piatto-di-Default", "body": "Le superfici sono piatte a riposo. L'ombra compare solo quando un elemento deve galleggiare (overlay, dialog, card sollevata) o rispondere a uno stato.", "section": "elevation" } ], "dos": [ "Do usare l'Arancio-Rosso Allerta (#ec4c41) solo per azione e stato attivo; mantenerlo raro.", "Do tenere il testo di corpo in inchiostro (#000) su carta (#fff); alto contrasto per la lettura al sole.", "Do dimensionare i bersagli di tocco ≥44px e collocare le azioni primarie a portata di pollice (FAB in basso a destra).", "Do rendere sempre esplicito lo stato offline/sync (barra di connessione, stati di scheda/ispezione).", "Do dare feedback fisico immediato a ogni tocco e scansione (ripple, cambio di stato).", "Do usare un'unica famiglia (Nunito) e fare gerarchia con peso e dimensione.", "Do rispettare le safe-area iOS/Android e prefers-reduced-motion." ], "donts": [ "Don't costruire un gestionale datato e denso: niente tabelle fittissime, testo minuscolo, grigio ovunque.", "Don't virare verso un'estetica consumer social/giocosa: niente colore ludico o decorazione fine a sé stessa.", "Don't usare testo grigio chiaro sul corpo 'per eleganza': causa numero uno di illeggibilità al sole.", "Don't usare bordo-laterale colorato (border-left/right > 1px) come accento su card, liste o alert.", "Don't usare testo con gradiente, glassmorphism decorativo, griglie di card tutte identiche, o eyebrow maiuscoli su ogni sezione.", "Don't introdurre animazioni di scena orchestrate al caricamento: il movimento serve allo stato, non allo spettacolo.", "Don't reinventare affordance standard (scrollbar strane, controlli di form non convenzionali) per 'carattere'." ] } }