Files
SteUP_Dotnet/SteUp.Shared/wwwroot/css/base.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

277 lines
6.9 KiB
CSS

/* =============================================================================
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: 500;
}
.t-label-md {
font-size: var(--label-md-size);
line-height: 1.25;
font-weight: 500;
}
/* 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: 400;
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;
}
}