/* ============================================================================
   SHARK — sistema visivo
   ----------------------------------------------------------------------------
   Contesto d'uso, che qui conta più dello stile: due persone, casa loro, app
   usata in piedi con UNA MANO, spesso con le mani sporche, spesso al sole.
   Da qui discendono tre regole che vincono su qualunque vezzo estetico:

   1. Le azioni che si ripetono stanno in basso, nella zona del pollice.
      Su un iPhone 12/13 l'angolo in alto a destra non si raggiunge con una
      mano: lì ci va solo ciò che si usa di rado.
   2. I bersagli sono generosi e i gesti ampi. Con le mani sporche si sbaglia
      la mira: lo swipe batte il tocco di precisione.
   3. Contrasto vero, non elegante-e-illeggibile. Alla luce diretta il grigio
      tenue su bianco sparisce.

   Palette obbligatoria (decisa da Andrea). Ogni colore esiste due volte: pieno
   per le superfici, scurito per il testo. Non è un vezzo: su bianco il ciano e
   l'arancio stanno a 2,5:1 e il lime a 1,2:1 — come colore di testo sarebbero
   illeggibili proprio nella condizione in cui l'app si usa davvero.
   ========================================================================= */

:root {
  /* --- Palette --- */
  --cy:        #39B1D1;   /* ciano pieno — identità, interazione, riempimenti */
  --cy-ink:    #18718C;   /* ciano scurito — TESTO su fondo chiaro */
  /* Ciano come SUPERFICIE, con scritta bianca sopra. Serve una variabile a
     parte da --cy-ink: al buio quella diventa un ciano chiaro (giusto per il
     testo), e usarla come sfondo porterebbe la scritta bianca a 1,93:1. */
  --cy-solid:  #18718C;
  --cy-tint:   #E8F6FA;   /* velo di ciano — selezione, sfondi tenui */
  --lm:        #D6FB61;   /* lime — il colore che premia. Solo riempimento */
  --lm-ink:    #232D08;   /* inchiostro sopra il lime */
  --lm-deep:   #55731A;   /* lime scurito — quando serve come testo */
  --or:        #F6850C;   /* arancio — attenzione, non errore */
  --or-ink:    #A85A06;
  --rd:        #DE3E3E;   /* rosso — sforamento ed eliminazioni, nient'altro */
  --rd-ink:    #C22B2B;

  /* --- Superfici (impianto iOS: fondo grigio, schede bianche) --- */
  --bg:        #F2F2F7;
  --surface:   #FFFFFF;
  --surface-2: #FFFFFF;
  --sep:       rgba(60, 60, 67, 0.36);
  --sep-solid: #D8D8DC;

  /* --- Testo --- */
  --ink:       #000000;
  --ink-2:     #3C3C43;
  --ink-3:     rgba(60, 60, 67, 0.80);   /* 5,97:1 su bianco. Era 0.62 = 3,62:1: sotto
                                            soglia, ed e il colore di categoria,
                                            quantita, negozio — cioe di tutto cio che
                                            qualifica una riga. Al sole spariva. */
  --ink-4:     rgba(60, 60, 67, 0.55);   /* 3,03:1: il chevron e l'unico segnale che
                                            una riga si tocca, era a 1,96:1 */

  /* --- Materiali traslucidi (barre) --- */
  --glass:     rgba(249, 249, 249, 0.82);
  --glass-brd: rgba(60, 60, 67, 0.2);

  /* --- Raggi: la scala di iOS 17 --- */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 22px;
  --r-full: 999px;

  /* --- Spaziatura --- */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;

  /* --- Bersagli. 44pt è il minimo Apple; sulle azioni ripetute alziamo. --- */
  --tap: 44px;
  --tap-lg: 56px;

  /* --- Barre --- */
  --nav-h: 52px;
  --tab-h: 56px;

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.06);
  --shadow-2: 0 4px 16px rgba(0, 0, 0, 0.10);
  --shadow-3: 0 12px 40px rgba(0, 0, 0, 0.18);

  --ease: cubic-bezier(0.32, 0.72, 0, 1);   /* la curva delle transizioni iOS */
  --fast: 180ms;
  --slow: 320ms;
}

/* Scuro. Su iPhone non è un lusso: l'app si usa anche di sera, e un bianco
   pieno in faccia al buio è una scortesia. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg:        #000000;
    --surface:   #1C1C1E;
    --surface-2: #2C2C2E;
    --sep:       rgba(84, 84, 88, 0.65);
    --sep-solid: #38383A;
    --ink:       #FFFFFF;
    --ink-2:     #EBEBF5;
    --ink-3:     rgba(235, 235, 245, 0.60);
    --ink-4:     rgba(235, 235, 245, 0.30);
    --glass:     rgba(28, 28, 30, 0.82);
    --glass-brd: rgba(84, 84, 88, 0.6);
    /* Al buio il contrasto si ribalta: i pieni diventano leggibili come testo
       e le varianti scurite spariscono. */
    --cy-ink:    #5CC8E6;   /* chiaro: al buio e il testo a stare chiaro */
    --cy-solid:  #0E5A72;   /* la superficie invece resta scura: bianco sopra = 7,4:1 */
    --cy-tint:   rgba(57, 177, 209, 0.16);
    --lm-deep:   #C3EE4E;
    --or-ink:    #FFA23D;
    --rd-ink:    #FF6B6B;
    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-2: 0 4px 16px rgba(0, 0, 0, 0.5);
    --shadow-3: 0 12px 40px rgba(0, 0, 0, 0.7);
  }
}

/* ============================================================================
   Fondamenta
   ========================================================================= */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  height: 100%;
}

body {
  margin: 0;
  min-height: 100dvh;                 /* dvh: la barra di Safari si muove */
  background: var(--bg);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'SF Pro', system-ui, sans-serif;
  font-size: 17px;                    /* Body di iOS */
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior-y: none;        /* niente rimbalzo dell'intera pagina */
  touch-action: manipulation;         /* via il ritardo di 300 ms */
}

/* Il testo non si seleziona per sbaglio durante uno swipe. Nei campi sì. */
body { -webkit-user-select: none; user-select: none; }
input, textarea, [contenteditable] { -webkit-user-select: text; user-select: text; }

button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
input, select, textarea { font: inherit; color: inherit; }
img { max-width: 100%; display: block; }
a { color: var(--cy-ink); text-decoration: none; }

/* Il focus si vede sempre: chi naviga da tastiera non deve indovinare. */
:focus-visible {
  outline: 3px solid var(--cy);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================================
   Tipografia — la scala di iOS, con i pesi che contano
   ========================================================================= */
.t-large-title { font-size: 34px; line-height: 41px; font-weight: 700; letter-spacing: 0.37px; }
.t-title-1     { font-size: 28px; line-height: 34px; font-weight: 700; letter-spacing: 0.36px; }
.t-title-2     { font-size: 22px; line-height: 28px; font-weight: 700; letter-spacing: 0.35px; }
.t-title-3     { font-size: 20px; line-height: 25px; font-weight: 600; }
.t-headline    { font-size: 17px; line-height: 22px; font-weight: 600; }
.t-body        { font-size: 17px; line-height: 22px; font-weight: 400; }
.t-callout     { font-size: 16px; line-height: 21px; font-weight: 400; }
.t-subhead     { font-size: 15px; line-height: 20px; font-weight: 400; }
.t-footnote    { font-size: 13px; line-height: 18px; font-weight: 400; }
.t-caption     { font-size: 12px; line-height: 16px; font-weight: 400; }
.t-caption-2   { font-size: 11px; line-height: 13px; font-weight: 400; }

.t-muted  { color: var(--ink-3); }
.t-faint  { color: var(--ink-4); }
.t-accent { color: var(--cy-ink); }

/* Le cifre in colonna devono incolonnarsi davvero: in una lista della spesa
   i prezzi si confrontano con l'occhio, non leggendoli uno per uno. */
.tabular { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1; }

/* Etichetta di sezione in maiuscoletto — la convenzione delle liste iOS. */
.eyebrow {
  font-size: 13px;
  line-height: 18px;
  font-weight: 400;
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 0 var(--sp-4) var(--sp-2);
}

/* ============================================================================
   Impalcatura: barra in alto, contenuto, barra in basso
   ========================================================================= */
.app {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

/* --- Barra di navigazione. Traslucida come quelle di sistema. --- */
.navbar {
  position: sticky;
  top: 0;
  z-index: 40;
  padding-top: env(safe-area-inset-top);
  background: var(--glass);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 0.5px solid transparent;
  transition: border-color var(--fast) var(--ease);
}
.navbar.scrolled { border-bottom-color: var(--glass-brd); }

.navbar-row {
  height: var(--nav-h);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--sp-2);
  padding: 0 var(--sp-2);
}
.navbar-left  { justify-self: start; display: flex; align-items: center; gap: var(--sp-1); }
.navbar-right { justify-self: end; display: flex; align-items: center; gap: var(--sp-1); }

/* Il titolo compatto compare solo quando quello grande è scivolato via. */
.navbar-title {
  font-size: 17px;
  font-weight: 600;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--fast) var(--ease), transform var(--fast) var(--ease);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 60vw;
}
.navbar.scrolled .navbar-title { opacity: 1; transform: none; }

/* Titolo grande in testa alla schermata: si accartoccia scorrendo. */
.large-title {
  padding: var(--sp-1) var(--sp-4) var(--sp-2);
  font-size: 34px;
  line-height: 41px;
  font-weight: 700;
  letter-spacing: 0.37px;
}
.large-title-sub {
  padding: 0 var(--sp-4) var(--sp-3);
  color: var(--ink-3);
  font-size: 15px;
  line-height: 20px;
  margin-top: -2px;
}

/* Pulsanti della barra: bersaglio pieno anche se l'icona è piccola. */
.nav-btn {
  min-width: var(--tap);
  height: var(--tap);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 0 var(--sp-2);
  color: var(--cy-ink);
  border-radius: var(--r-sm);
  font-size: 17px;
  transition: opacity var(--fast) var(--ease);
}
.nav-btn:active { opacity: 0.35; }
.nav-btn.strong { font-weight: 600; }
.nav-btn.danger { color: var(--rd-ink); }

.content {
  flex: 1;
  /* Spazio anche per il pulsante flottante, che altrimenti copre l'angolo
     destro dell'ultima riga — in Spesa, proprio il prezzo. */
  padding-bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + 58px + var(--sp-6));
}

/* --- Barra delle schede. In basso: è dove arriva il pollice. --- */
.tabbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 45;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  padding-bottom: env(safe-area-inset-bottom);
  background: var(--glass);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-top: 0.5px solid var(--glass-brd);
}
.tabbar-btn {
  height: var(--tab-h);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  color: var(--ink-3);
  transition: color var(--fast) var(--ease);
}
.tabbar-btn svg { width: 26px; height: 26px; }
.tabbar-btn span { font-size: 10px; line-height: 12px; font-weight: 500; letter-spacing: 0.1px; }
/* Il solo cambio di colore vale 1,48:1 di scarto: al sole non si capiva in quale
   schermata si fosse. Peso, spessore del tratto e barretta lo dicono senza colore. */
.tabbar-btn.active { color: var(--cy-ink); }
.tabbar-btn.active svg { stroke-width: 2.4; }
.tabbar-btn.active span { font-weight: 700; }
.tabbar-btn.active::before {
  content: '';
  position: absolute;
  top: 0;
  width: 28px;
  height: 3px;
  border-radius: 0 0 3px 3px;
  background: var(--cy-ink);
}
.tabbar-btn { position: relative; }
.tabbar-btn:active { opacity: 0.5; }

/* ============================================================================
   Liste raggruppate — la struttura portante di iOS
   ========================================================================= */
.group {
  margin: 0 var(--sp-4) var(--sp-6);
  background: var(--surface);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-1);
}
.group.flush { margin-left: 0; margin-right: 0; border-radius: 0; }

.row {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--tap-lg);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
}
/* Separatore rientrato: parte dopo l'icona, come nelle liste di sistema.
   Le righe trascinabili sono avvolte in .swipe, quindi due .row non sono mai
   fratelli: senza la seconda regola le liste di Lavori e Spesa restavano
   blocchi bianchi continui, senza confini fra una voce e l'altra. */
.row + .row::before,
.swipe + .swipe .row::before {
  content: '';
  position: absolute;
  top: 0; left: var(--sp-4); right: 0;
  height: 0.5px;
  background: var(--sep);
}
.row.inset-sep + .row::before { left: 56px; }
.row-tappable { cursor: pointer; }
.row-tappable:active { background: var(--cy-tint); }

.row-main { flex: 1; min-width: 0; }
.row-title {
  font-size: 17px;
  line-height: 22px;
  font-weight: 400;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.row-sub {
  font-size: 13px;
  line-height: 18px;
  color: var(--ink-3);
  margin-top: 1px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.row-trail { display: flex; align-items: center; gap: var(--sp-2); color: var(--ink-3); flex-shrink: 0; }
.row-value { font-size: 17px; color: var(--ink-3); }

.chev { width: 9px; height: 14px; color: var(--ink-4); flex-shrink: 0; stroke-width: 2.4; }

/* Pastiglia dell'icona a sinistra della riga — la convenzione di Impostazioni. */
.row-icon {
  width: 30px; height: 30px;
  border-radius: 7px;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  color: #fff;
  background: var(--cy-solid);
}
.row-icon svg { width: 18px; height: 18px; }
.row-icon.lime   { background: var(--lm); color: var(--lm-ink); }
.row-icon.orange { background: var(--or-ink); color: #fff; }
.row-icon.red    { background: var(--rd-ink); color: #fff; }
.row-icon.grey   { background: rgba(60, 60, 67, 0.62); color: #fff; }

/* ============================================================================
   FIRMA DELL'APP — la riga che si dipinge
   ----------------------------------------------------------------------------
   Il gesto che in questa app si ripete più di ogni altro è "questo è fatto".
   Invece di un quadratino da centrare con le mani sporche, la riga si trascina
   e si riempie di lime da sinistra a destra sotto il dito: la stessa cosa che
   stanno facendo davvero, dare la mano di vernice. Oltre metà corsa il gesto è
   compiuto e il lavoro resta fatto.

   Il lime è usato esattamente come prescritto: riempimento pieno con inchiostro
   scuro sopra, mai come colore di testo su fondo chiaro.
   ========================================================================= */
.swipe {
  position: relative;
  overflow: hidden;
  background: var(--surface);
  touch-action: pan-y;               /* lo scorrimento verticale resta libero */
}
/* Il lime su bianco sta a 1,18:1: la vernice che avanza — l'unico riscontro che il
   gesto sta funzionando — al sole non si vedeva. Il bordo scuro sul fronte e visibile
   a 4,63:1 anche quando il lime non lo e. */
.swipe-paint {
  position: absolute;
  inset: 0;
  background: var(--lm);
  border-right: 3px solid var(--lm-deep);
  transform: translateX(-100%);
  will-change: transform;
  pointer-events: none;
}
/* La riga ha fondo opaco: e quello che tiene coperto il comando di
   eliminazione, che sta sotto. Senza, il rosso resta visibile sotto ogni riga e
   il testo dei lavori ci finisce sopra.
   Solo mentre si trascina verso destra la riga diventa trasparente, per un
   istante, e lascia vedere la vernice che avanza. */
.swipe-body {
  position: relative;
  z-index: 1;
  transition: transform var(--fast) var(--ease);
}
.swipe.dipingendo .swipe-body > .row { background: transparent; }
.swipe.dipingendo .swipe-body > .row.done { background: transparent; box-shadow: none; }
.swipe.fatto { background: var(--lm); }
.swipe.settling .swipe-paint,
.swipe.settling .swipe-body { transition: transform var(--slow) var(--ease); }

/* Stato compiuto: la riga resta dipinta. */
.row.done { background: var(--lm); box-shadow: inset 3px 0 0 var(--lm-deep); }
.row.done .row-title { color: var(--lm-ink); text-decoration: line-through; text-decoration-thickness: 1.5px; }
.row.done .row-sub   { color: var(--lm-ink); opacity: 0.75; }
.row.done .row-value { color: var(--lm-ink); }
.row.done .chev { color: var(--lm-ink); opacity: 0.55; }
/* IL BERSAGLIO PIU IMPORTANTE DELL'APP.
   Prima esisteva solo DOPO che il lavoro era fatto: su un lavoro da fare non
   c'era niente da toccare, e chi provava a toccare dove si aspettava la casella
   apriva la scheda di modifica. Le due azioni piu ripetute dell'app non avevano
   un bersaglio. Ora il cerchio c'e sempre, vuoto quando c'e da fare e pieno
   quando e fatto, con l'area toccabile piena altezza riga. */
.done-mark {
  position: relative;   /* il cerchio interno si aggancia qui, non alla riga */
  width: 44px;
  align-self: stretch;
  min-height: var(--tap);
  margin: calc(var(--sp-3) * -1) 0 calc(var(--sp-3) * -1) calc(var(--sp-1) * -1);
  display: grid;
  place-items: center;
  flex-shrink: 0;
  color: transparent;
}
.done-mark::before {
  content: '';
  position: absolute;
  width: 24px; height: 24px;
  border-radius: 50%;
  border: 2px solid var(--ink-4);
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.done-mark svg { width: 14px; height: 14px; position: relative; }
.done-mark:active::before { background: var(--cy-tint); border-color: var(--cy-ink); }

.row.done .done-mark { color: var(--lm); }
.row.done .done-mark::before { background: var(--lm-ink); border-color: var(--lm-ink); }

/* Eliminazione: una x rossa che si scopre trascinando la riga a sinistra.
   Prima era un pannello con la parola "Elimina" che occupava 84px, e con la
   riga trasparente restava visibile sotto ogni voce, con il testo dei lavori
   che ci finiva sopra. */
.swipe-actions {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 84px;
  display: grid;
  place-items: center;
}
.swipe-action {
  width: 34px; height: 34px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: #fff;
  background: var(--rd-ink);
}
.swipe-action svg { width: 17px; height: 17px; }

/* ============================================================================
   Controlli
   ========================================================================= */
.btn {
  min-height: var(--tap);
  padding: 0 var(--sp-5);
  border-radius: var(--r-md);
  font-size: 17px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  background: var(--surface-2);
  color: var(--cy-ink);
  transition: transform var(--fast) var(--ease), opacity var(--fast) var(--ease);
}
.btn:active { transform: scale(0.97); opacity: 0.8; }
/* Bianco su ciano pieno sta a 2,50:1: il pulsante che si cerca per primo era il meno
   leggibile dell'app. Su ciano scurito sta a 5,56:1. */
.btn-primary { background: var(--cy-solid); color: #fff; }
.btn-lime    { background: var(--lm); color: var(--lm-ink); }
.btn-danger  { background: transparent; color: var(--rd-ink); }
.btn-plain   { background: transparent; }
.btn-block   { display: flex; width: 100%; }
.btn:disabled { opacity: 0.4; pointer-events: none; }

/* Selettore a pillola — il segmented control di sistema. */
.segmented {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 2px;
  padding: 2px;
  background: rgba(120, 120, 128, 0.12);
  border-radius: var(--r-sm);
  margin: 0 var(--sp-4) var(--sp-4);
}
.segmented button {
  min-height: 40px;
  border-radius: 7px;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  transition: background var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.segmented button.active {
  background: var(--surface);
  box-shadow: var(--shadow-1);
  font-weight: 600;
}

/* Pastiglie di filtro, scorrevoli in orizzontale. */
.chips {
  display: flex;
  gap: var(--sp-2);
  padding: 0 var(--sp-4) var(--sp-4);
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.chips::-webkit-scrollbar { display: none; }
.chip {
  flex-shrink: 0;
  min-height: var(--tap);
  padding: 0 var(--sp-4);
  border-radius: var(--r-full);
  background: var(--surface);
  color: var(--ink-2);
  font-size: 15px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  box-shadow: var(--shadow-1);
}
.chip.active { background: var(--cy-solid); color: #fff; font-weight: 600; }
.chip:active { opacity: 0.6; }

/* Campi */
.field { display: block; padding: var(--sp-3) var(--sp-4); background: var(--surface); }
.field + .field { border-top: 0.5px solid var(--sep); }
.field-label {
  display: block;
  font-size: 13px;
  color: var(--ink-3);
  margin-bottom: 4px;
}
.field input, .field select, .field textarea {
  width: 100%;
  min-height: var(--tap);
  padding: 0;
  border: 0;
  background: transparent;
  font-size: 17px;
  outline: none;
  appearance: none;
  border-radius: 0;
}
.field textarea { min-height: 72px; padding-top: 6px; resize: none; line-height: 1.4; }
.field select { padding-right: var(--sp-5); }
.field-inline { display: flex; align-items: center; gap: var(--sp-3); }
.field-inline .field-label { margin: 0; flex: 1; font-size: 17px; color: var(--ink); }
.field-inline input { text-align: right; flex: 0 0 45%; }

/* Interruttore */
.switch {
  position: relative;
  width: 51px; height: 31px;
  /* L'area toccabile arriva a 44pt senza cambiare l'aspetto della pastiglia. */
  box-sizing: content-box;
  padding: 6.5px 0;
  background-clip: content-box;
  border-radius: var(--r-full);
  background: rgba(120, 120, 128, 0.55);
  flex-shrink: 0;
  transition: background var(--fast) var(--ease);
}
.switch::after {
  content: '';
  position: absolute;
  top: 8.5px; left: 2px;
  width: 27px; height: 27px;
  border-radius: 50%;
  background: #fff;
  box-shadow: var(--shadow-1);
  transition: transform var(--fast) var(--ease);
}
/* Il lime sotto il pomello bianco stava a 1,18:1: acceso o spento era una pastiglia
   bianca con dentro una macchia bianca. */
.switch.on { background: var(--cy-solid); }
.switch.on::after { transform: translateX(20px); }

/* Barre di avanzamento */
.meter {
  height: 8px;
  border-radius: var(--r-full);
  background: rgba(120, 120, 128, 0.18);
  overflow: hidden;
}
/* Il lime contro la traccia sta a 1,05:1 e l'arancio a 2,05:1: le barre erano vuote
   al sole. Il bordo interno scuro stacca sia dal riempimento sia dalla traccia. */
.meter-fill {
  height: 100%;
  border-radius: var(--r-full);
  background: var(--cy);
  box-shadow: inset 0 0 0 1.5px var(--cy-ink);
  transition: width var(--slow) var(--ease);
}
.meter-fill.lime   { background: var(--lm); box-shadow: inset 0 0 0 1.5px var(--lm-deep); }
.meter-fill.orange { background: var(--or); box-shadow: inset 0 0 0 1.5px var(--or-ink); }
.meter-fill.red    { background: var(--rd); box-shadow: inset 0 0 0 1.5px var(--rd-ink); }

/* Etichette di stato. Mai solo colore: sempre con parola. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  border-radius: var(--r-full);
  font-size: 12px;
  font-weight: 600;
  line-height: 16px;
}
.badge-lime   { background: var(--lm); color: var(--lm-ink); }
.badge-cyan   { background: var(--cy-tint); color: var(--cy-ink); }
.badge-orange { background: rgba(246, 133, 12, 0.16); color: var(--or-ink); }
.badge-red    { background: rgba(222, 62, 62, 0.14); color: var(--rd-ink); }
.badge-grey   { background: rgba(120, 120, 128, 0.14); color: var(--ink-3); }

/* ============================================================================
   Schede di riepilogo
   ========================================================================= */
.cards { display: grid; gap: var(--sp-3); padding: 0 var(--sp-4) var(--sp-6); }
.card {
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: var(--sp-4);
  box-shadow: var(--shadow-1);
  display: block;
  width: 100%;
  text-align: left;
}
.card:active { transform: scale(0.985); }
.card-head { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.card-title { font-size: 13px; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.5px; flex: 1; }
.card-figure { font-size: 28px; line-height: 34px; font-weight: 700; letter-spacing: 0.36px; }
.card-note { font-size: 13px; color: var(--ink-3); margin-top: 2px; }
.card-meter { margin-top: var(--sp-3); }

/* ============================================================================
   Fogli modali — salgono dal basso, con la maniglia
   ========================================================================= */
/* Sopra il visore foto (80): altrimenti il menu di conferma viene disegnato
   sotto l'immagine a schermo intero e non si vede ne si tocca. */
.sheet-backdrop {
  position: fixed;
  inset: 0;
  z-index: 99;
  background: rgba(0, 0, 0, 0.4);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--slow) var(--ease);
}
.sheet-backdrop.open { opacity: 1; pointer-events: auto; }

.sheet {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 100;
  max-height: 92dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  transform: translateY(100%);
  transition: transform var(--slow) var(--ease);
  box-shadow: var(--shadow-3);
  padding-bottom: env(safe-area-inset-bottom);
}
.sheet.open { transform: none; }
.sheet-grabber {
  width: 36px; height: 5px;
  border-radius: var(--r-full);
  background: var(--ink-4);
  margin: var(--sp-2) auto var(--sp-1);
  flex-shrink: 0;
}
.sheet-head {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-2) var(--sp-3);
  flex-shrink: 0;
}
.sheet-title { font-size: 17px; font-weight: 600; text-align: center; }
.sheet-body { overflow-y: auto; -webkit-overflow-scrolling: touch; padding-bottom: var(--sp-6); }

/* Foglio di scelta rapida (action sheet) */
.actionsheet {
  position: fixed;
  left: var(--sp-2); right: var(--sp-2);
  bottom: calc(env(safe-area-inset-bottom) + var(--sp-2));
  z-index: 100;
  transform: translateY(120%);
  transition: transform var(--slow) var(--ease);
}
.actionsheet.open { transform: none; }
.actionsheet-group {
  background: var(--glass);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  border-radius: var(--r-lg);
  overflow: hidden;
  margin-bottom: var(--sp-2);
}
.actionsheet-btn {
  display: block;
  width: 100%;
  min-height: 58px;
  font-size: 20px;
  color: var(--cy-ink);
  background: var(--surface);
}
.actionsheet-btn + .actionsheet-btn { border-top: 0.5px solid var(--sep); }
.actionsheet-btn.danger { color: var(--rd-ink); }
.actionsheet-btn.strong { font-weight: 600; }
.actionsheet-btn:active { background: var(--cy-tint); }
.actionsheet-title {
  padding: var(--sp-3) var(--sp-4);
  font-size: 13px;
  color: var(--ink-3);
  text-align: center;
  background: var(--surface);
  border-bottom: 0.5px solid var(--sep);
}

/* ============================================================================
   Stati vuoti — un invito ad agire, non un cartello "niente qui"
   ========================================================================= */
.empty {
  padding: var(--sp-8) var(--sp-6);
  text-align: center;
  color: var(--ink-3);
}
.empty-icon {
  width: 56px; height: 56px;
  margin: 0 auto var(--sp-4);
  border-radius: var(--r-lg);
  display: grid;
  place-items: center;
  background: var(--cy-tint);
  color: var(--cy-ink);
}
.empty-icon svg { width: 28px; height: 28px; }
.empty-title { font-size: 17px; font-weight: 600; color: var(--ink); margin-bottom: var(--sp-1); }
.empty-text { font-size: 15px; max-width: 30ch; margin: 0 auto var(--sp-5); }

/* ============================================================================
   Avvisi passeggeri
   ========================================================================= */
.toasts {
  position: fixed;
  left: 0; right: 0;
  bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + var(--sp-3));
  z-index: 110;   /* sopra il visore foto e sopra i fogli */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  pointer-events: none;
  padding: 0 var(--sp-4);
}
.toast {
  max-width: 100%;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-full);
  background: var(--glass);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  box-shadow: var(--shadow-2);
  font-size: 15px;
  font-weight: 500;
  pointer-events: auto;
  animation: toast-in var(--slow) var(--ease);
}
.toast.leaving { animation: toast-out var(--fast) var(--ease) forwards; }
/* Unico modo di recuperare qualcosa eliminato per sbaglio: era un bersaglio da 22pt.
   I margini negativi allargano l'area senza cambiare l'aspetto del riquadro. */
.toast-undo {
  color: var(--cy-ink);
  font-weight: 600;
  min-height: var(--tap);
  display: inline-flex;
  align-items: center;
  padding: 0 var(--sp-3);
  margin: -11px calc(var(--sp-3) * -1) -11px var(--sp-2);
}
@keyframes toast-in  { from { opacity: 0; transform: translateY(16px) scale(0.96); } }
@keyframes toast-out { to   { opacity: 0; transform: translateY(8px) scale(0.98); } }

/* ============================================================================
   Trascina per aggiornare
   ========================================================================= */
.ptr {
  height: 0;
  display: grid;
  place-items: center;
  overflow: hidden;
  color: var(--ink-3);
}
.ptr-spinner {
  width: 20px; height: 20px;
  border: 2px solid var(--sep-solid);
  border-top-color: var(--cy);
  border-radius: 50%;
}
.ptr.spinning .ptr-spinner { animation: spin 800ms linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ============================================================================
   Accesso
   ========================================================================= */
.login {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: none;
  flex-direction: column;
  justify-content: center;
  padding: var(--sp-6);
  padding-bottom: calc(env(safe-area-inset-bottom) + var(--sp-6));
  background: var(--bg);
}
.login.open { display: flex; }
.login-mark {
  width: 76px; height: 76px;
  margin: 0 auto var(--sp-5);
  border-radius: var(--r-xl);
  display: grid;
  place-items: center;
  background: linear-gradient(150deg, var(--cy), var(--cy-ink));
  color: #fff;
  box-shadow: var(--shadow-2);
}
.login-mark svg { width: 42px; height: 42px; }
.login h1 { font-size: 28px; font-weight: 700; text-align: center; margin: 0 0 var(--sp-1); letter-spacing: 0.36px; }
.login-sub { text-align: center; color: var(--ink-3); font-size: 15px; margin: 0 0 var(--sp-6); }
.login .group { margin-left: 0; margin-right: 0; }
.login-error {
  color: var(--rd-ink);
  font-size: 15px;
  text-align: center;
  min-height: 22px;
  margin: var(--sp-3) 0 0;
}

/* ============================================================================
   Foto
   ========================================================================= */
.photo-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
}
.photo-cell {
  position: relative;
  aspect-ratio: 1;
  background: var(--surface-2);
  overflow: hidden;
}
.photo-cell img { width: 100%; height: 100%; object-fit: cover; }
.photo-cell-tag {
  position: absolute;
  left: 4px; bottom: 4px;
  padding: 2px 6px;
  border-radius: var(--r-sm);
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.photo-add {
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  background: var(--surface-2);
  color: var(--cy-ink);
}
.photo-add svg { width: 26px; height: 26px; }

.viewer {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: #000;
  display: none;
  align-items: center;
  justify-content: center;
}
.viewer.open { display: flex; }
.viewer img { max-width: 100%; max-height: 100dvh; object-fit: contain; }
.viewer-close,
.viewer-del {
  position: absolute;
  top: calc(env(safe-area-inset-top) + var(--sp-3));
  right: var(--sp-3);
  width: var(--tap); height: var(--tap);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  display: grid;
  place-items: center;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

/* ============================================================================
   Utilità
   ========================================================================= */
/* Comandi scritti dentro un testo (es. "Impostalo", "Modifica"): l'area toccabile
   sale a 44pt con margini negativi, senza spostare il testo intorno. */
.link-tap {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0 var(--sp-2);
  margin: -13px calc(var(--sp-2) * -1);
  color: var(--cy-ink);
  font-weight: 500;
}

/* Pulsante di aggiunta: sta in basso a destra, dove arriva il pollice. In alto,
   sull'iPhone 12/13, l'angolo destro non si raggiunge con una mano sola. */
.fab {
  position: fixed;
  right: var(--sp-4);
  bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + var(--sp-4));
  z-index: 46;
  width: 58px; height: 58px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--cy-solid);
  color: #fff;
  box-shadow: var(--shadow-2);
  transition: transform var(--fast) var(--ease);
}
.fab:active { transform: scale(0.92); }
.fab svg { width: 28px; height: 28px; }

/* Salvataggio in fondo al foglio: in cima stava a oltre 100pt dal bordo alto,
   fuori portata. Qui e un bersaglio a tutta larghezza dentro la zona pollice. */
.sheet-save-bottom {
  position: sticky;
  bottom: 0;
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
  background: linear-gradient(to top, var(--bg) 70%, transparent);
}

/* Elimina foto: in basso a destra, comando esplicito. Prima l'eliminazione
   era legata al tocco sull'immagine — inciampabile con le mani sporche. */
.viewer-del {
  top: auto;
  bottom: calc(env(safe-area-inset-bottom) + var(--sp-4));
}

.hidden { display: none !important; }
.stack { display: flex; flex-direction: column; }
.hstack { display: flex; align-items: center; }
.spacer { flex: 1; }
.px { padding-left: var(--sp-4); padding-right: var(--sp-4); }
.pb { padding-bottom: var(--sp-4); }
.mt { margin-top: var(--sp-4); }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Su schermo largo l'app resta una colonna centrata: è nata per il telefono e
   allargarla in un cruscotto la snaturerebbe. */
@media (min-width: 600px) {
  .app { max-width: 480px; margin: 0 auto; box-shadow: var(--shadow-2); background: var(--bg); }
  .tabbar { max-width: 480px; left: 50%; transform: translateX(-50%); }
  .toasts { max-width: 480px; left: 50%; transform: translateX(-50%); }
  /* Anche il pulsante flottante segue la colonna, altrimenti resta appiccicato
     al bordo della finestra invece che all'app. */
  .fab { right: calc(50% - 240px + var(--sp-4)); }
}

/* ============================================================================
   Aggiunta rapida
   ----------------------------------------------------------------------------
   Mettere dieci cose nella lista della spesa richiedeva dieci giri di
   "tocca +, apri il foglio, scrivi, salva". Qui si scrive e si preme invio, e
   il campo resta pronto per la voce successiva.
   ========================================================================= */
.row.quick { gap: var(--sp-2); padding-left: var(--sp-3); }
.quick-plus {
  width: 30px; height: 30px;
  display: grid;
  place-items: center;
  color: var(--cy-ink);
  flex-shrink: 0;
}
.quick-plus svg { width: 20px; height: 20px; }
.quick-input {
  flex: 1;
  min-height: var(--tap);
  border: 0;
  background: transparent;
  font-size: 17px;
  outline: none;
  color: var(--ink);
}
.quick-input::placeholder { color: var(--ink-3); }
