Files
SteUP_Dotnet/SteUp.Shared/wwwroot/css/base.css
T
MarcoE ac501dc261 Metti l'anello di focus solo sui comandi
La regola valeva per qualunque elemento, e la WebView sposta il fuoco anche su
contenitori non interattivi: dopo la chiusura di un dialog restava un anello
azzurro intorno al titolo della testata, che indicava un bersaglio inesistente.
Ora lo prendono link, bottoni, campi e gli elementi dichiaratamente tappabili.

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

288 lines
7.4 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;
}
/* L'anello segna un comando raggiunto da tastiera. Va messo sui controlli, non
su qualunque elemento che il motore decida di mettere a fuoco: la WebView
sposta il fuoco anche su contenitori non interattivi (per esempio la testata,
dopo la chiusura di un dialog) e li' l'anello indica un bersaglio che non
esiste. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[role="button"]:focus-visible,
[tabindex]:not([tabindex="-1"]):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;
}
}