:root {
  /* Palette "arancione acceso + prugna": due famiglie di colore, non più pastelli misti */
  --bg: #FDF8F4;
  --card: #FFFFFF;
  --ink: #3D2244;
  --ink-soft: #8C7C91;
  /* Fil, 2026-08-23, trovato controllando la modalità scura: --ink cambia
     valore lì sotto (deve, è il colore del TESTO, in dark mode diventa
     chiaro) — otto punti nell'app però lo usavano come SFONDO di un
     blocco pensato per restare sempre scuro (bolla indietro, pillola
     attiva, popup del lettore audio, toast, badge del giorno scelto,
     riquadri "Nuova proposta"/"Amici"...): in dark mode diventavano chiari
     con sopra testo bianco, quasi invisibili. Token a parte, fisso, mai
     ridefinito qui sotto — per gli sfondi che devono restare scuri A
     PRESCINDERE dal tema, non per il testo. */
  --surface-dark: #3D2244;
  --mint: #FF7A29;
  --mint-soft: #FFE3C7;
  --peach: #FF7A29;
  --peach-soft: #FFE3C7;
  --lavender: #6B3F73;
  --lavender-soft: #EFE3F0;
  --sky: #9C6BA3;
  --sky-soft: #F3E7F4;
  --butter: #FFB35C;
  --butter-soft: #FFEDD6;
  /* Era troppo sul marrone/terracotta (Fil, 2026-08-23) — hue spostato più
     verso il rosso vero, restando smorzato (non il rosso acceso del
     cestino swipe-to-remove, che deve restare urgente). */
  --cancel: #BC4749;
  --cancel-soft: #F5DCDC;
  /* "Confermato" (Fil, 2026-08-23): il viola era coerente con la palette ma
     non si legge a colpo d'occhio come "confermato" — il verde ce lo mette
     mezzo secolo di convenzione (spunte, semafori...). Smorzato, non il
     verde acceso di prima del restyling: stessa disciplina del resto della
     palette, applicato a un colore che qui ha un significato preciso
     (stato), non decorativo. Stesso colore ovunque significhi "confermato"
     — riquadro Home, bordo card evento, pillina badge. */
  --confirmed: #4F8B5C;
  --confirmed-soft: #DCEBDC;
  --past-soft: #ECE7EE;
  --shadow: 0 20px 60px rgba(58, 50, 90, 0.15);
  /* Sfondo neutro riusato in 4 punti diversi (barra progresso, spunta chip,
     "+N altri" avatar, badge del giorno leader): prima erano 4 copie dello
     stesso #F0E6EA, ora una variabile sola così la dark mode qui sotto la
     cambia in un posto solo. */
  --track-soft: #F0E6EA;
}

/* Dark mode (Fil, 2026-07-21): segue il tema di sistema, nessun tasto/opzione
   in più da mostrare — coerente con l'idea "il meno possibile da toccare".
   Cambiano solo le superfici neutre (sfondo pagina, card, testo, ombre):
   i colori "soft" dei badge/notifiche restano quelli di sempre, con lo
   stesso testo scuro abbinato — restano leggibili come pillole chiare sopra
   lo sfondo scuro, senza dover riscrivere ogni singolo abbinamento colore. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #201829;
    --card: #2C2233;
    --ink: #F4EEF6;
    --ink-soft: #B3A3BB;
    --track-soft: #3B2E44;
    --shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
  }

  body {
    background: #14101A;
  }

  .phone {
    border-color: #14101A;
  }

  .splash-screen {
    background: var(--bg);
  }

  /* Le due "lastre di vetro" dell'app (header con foto profilo, navbar in
     basso) erano pensate come vetro smerigliato BIANCO sopra uno sfondo
     chiaro: lasciate così sarebbero rimaste due barre chiare e stonate
     sopra tutto il resto ormai scuro. Stesso effetto vetro, tinta scura. */
  .header {
    background: linear-gradient(135deg, rgba(255, 122, 41, 0.28), rgba(107, 63, 115, 0.5));
    border-color: rgba(255, 255, 255, 0.12);
  }

  .navbar {
    background: linear-gradient(180deg, rgba(44, 34, 51, 0.85), rgba(44, 34, 51, 0.6));
    border-color: rgba(255, 255, 255, 0.1);
    box-shadow:
      0 18px 40px rgba(0, 0, 0, 0.35),
      0 2px 6px rgba(0, 0, 0, 0.2),
      inset 0 1px 0 rgba(255, 255, 255, 0.08);
  }
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* overflow-x:hidden qui, non solo su .phone: senza, basta un pixel di troppo
   da qualche parte (o anche solo il pinch-zoom, vedi meta viewport) perché
   Safari iOS permetta di scorrere/panare la pagina lateralmente e bisogna poi
   ricentrarla a mano — bug notato da Fil su iPhone 13 il 2026-07-05. */
html {
  overflow-x: hidden;
}

body {
  background: #EDE3E6;
  font-family: 'Inter', sans-serif;
  color: var(--ink);
  display: flex;
  justify-content: center;
  align-items: flex-start;
  min-height: 100vh;
  padding: 40px 16px;
  overflow-x: hidden;
  width: 100%;
}

a { text-decoration: none; color: inherit; }

.phone {
  width: 390px;
  max-width: 100%;
  height: 780px;
  background: var(--bg);
  border-radius: 40px;
  box-shadow: var(--shadow);
  overflow: hidden;
  position: relative;
  border: 8px solid #2b2924;
  display: flex;
  flex-direction: column;
}

/* Su un dispositivo vero (telefono o tablet, non un PC/laptop col mouse) il mockup
   non deve sembrare "una foto di un telefono": il finto bordo/bezel sparisce e il
   contenuto riempie tutto lo schermo. "hover:none e pointer:coarse" riconosce i
   dispositivi touch a prescindere da quanto è larga la finestra/lo schermo. */
@media (max-width: 480px), (hover: none) and (pointer: coarse) {
  /* Fil, 2026-07-19: su Safari iOS la barra in basso (indirizzo/tab) è
     traslucida e "galleggia" sopra il contenuto — su un sito normale
     (esempio: Quanta Magazine) si vede la pagina stessa continuare sotto,
     nessuna cucitura. Da noi invece si vedeva uno sfondo bianco-grigiastro
     diverso da quello dell'app in quello spazio: il .phone (sfondo
     var(--bg), l'unico "vero" contenuto) è alto esattamente 100dvh/
     --app-height e si ferma lì, mentre il <body> dietro aveva un colore di
     sfondo diverso (#EDE3E6, pensato per fare da "tavolo" dietro al mockup
     su desktop) — qualunque spiraglio rivelato dalla barra traslucida, o
     dal suo nascondersi/mostrarsi durante lo scroll, mostrava quella
     cucitura di colore. Qui dentro (solo su dispositivo vero, non nel
     mockup desktop) html/body prendono lo stesso colore dell'app ed sono
     alti quanto la viewport più grande possibile (100lvh: toolbar
     nascosta), così qualunque spazio la barra traslucida lasci intravedere
     è dello stesso colore dell'app, non un bianco che stona. */
  html {
    background: var(--bg);
  }

  body {
    padding: 0;
    align-items: stretch;
    background: var(--bg);
    min-height: 100vh;
    min-height: 100lvh;
  }

  .phone {
    width: 100%;
    /* 100dvh come base; se lo script inline nell'<head> riesce a misurare
       window.innerHeight (più affidabile di dvh su alcune combinazioni
       Android/PWA installata), --app-height la sovrascrive. Risolve la navbar
       che finiva tagliata/sotto la gesture bar sull'app installata. */
    height: 100dvh;
    height: var(--app-height, 100dvh);
    border: none;
    border-radius: 0;
    box-shadow: none;
  }

  .navbar {
    bottom: calc(14px + env(safe-area-inset-bottom));
  }
}

/* Sfondo "aurora": forme sfumate pastello dietro la card del saluto (solo Home) */
.aurora-bg {
  position: absolute;
  top: -50px;
  left: -50px;
  right: -50px;
  height: 280px;
  z-index: 0;
  pointer-events: none;
}

.aurora-bg .blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(34px);
}

.aurora-bg .blob.b1 { width: 190px; height: 190px; top: 10px; left: 20px; background: var(--peach); opacity: 0.55; }
.aurora-bg .blob.b2 { width: 210px; height: 210px; top: -20px; right: 0px; background: var(--lavender); opacity: 0.5; }
.aurora-bg .blob.b3 { width: 170px; height: 170px; top: 110px; left: 140px; background: var(--sky); opacity: 0.4; }
.aurora-bg .blob.b4 { width: 150px; height: 150px; top: 70px; right: 90px; background: var(--butter); opacity: 0.4; }

/* Header — la card di saluto in alto nella Home, in vetro sopra l'aurora */
.header {
  position: relative;
  z-index: 2;
  margin: 30px 16px 6px;
  padding: 18px 18px;
  border-radius: 28px;
  background: linear-gradient(135deg, rgba(255, 122, 41, 0.4), rgba(107, 63, 115, 0.4));
  backdrop-filter: blur(16px) saturate(160%);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, 0.6);
  box-shadow: 0 10px 26px rgba(58, 50, 90, 0.1);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.header.simple {
  margin: 0;
  padding: 22px 20px 18px;
  border-radius: 0;
  background: none;
  box-shadow: none;
  /* Il bordo bianco (rgba(255,255,255,0.6)) di .header base era pensato per
     il vecchio pannello di vetro sfumato: senza quello sfondo, restava un
     riquadro bianco intorno all'header — invisibile su schermo chiaro,
     ben visibile in dark mode (Fil, 2026-08-24, foto reale dal telefono:
     "appena percettibile con la schermata chiara, se metti modalità
     scura si vede tantissimo il riquadro bianco"). */
  border: none;
  /* .header base ha anche un backdrop-filter (blur+saturate) pensato per lo
     stesso vecchio pannello di vetro: senza sfondo dietro resta comunque un
     rettangolo con la saturazione alzata, leggermente diverso dal resto
     della pagina — "una barra a sé" (Fil, 2026-08-24). Via anche questo. */
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  justify-content: flex-start;
  gap: 14px;
  /* Stacco dal resto della pagina (Fil, 2026-08-23, terza versione: né la
     riga né l'ombra sfumata andavano bene, sempre "una riga che stacca
     troppo") — niente più elementi grafici: solo un po' più di respiro
     verticale prima del contenuto, sotto su .content. Zero da vedere. */
}

/* Solo la Home: profilo a sinistra, campanella spinta a destra invece che
   subito dopo il nome (Fil, 2026-08-23) — le altre pagine con .header.simple
   hanno un solo elemento (titolo, più la bolla indietro ora fuori
   dall'header), qui non cambierebbe nulla applicarlo lì.
   .header.simple.home-header (non solo .home-header): deve pesare almeno
   quanto .header.simple qui sopra per vincere su justify-content, altrimenti
   perde e la campanella resta dov'era (successo la prima volta). */
.header.simple.home-header { justify-content: space-between; }

.back-btn {
  width: 36px;
  height: 36px;
  border-radius: 12px;
  background: var(--card);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  box-shadow: 0 2px 8px rgba(58,50,90,0.06);
}

/* Il vero "torna indietro" (i <a>, non il bottone menu ⋮ di evento.html,
   che riusa .back-btn solo per lo stile quadrato — resta quello) diventa
   una bolla flottante in basso a sinistra (Fil, 2026-08-22): più comoda da
   raggiungere col pollice di una freccina in alto, e un bersaglio vero,
   non solo un'area di tocco allargata invisibile. */
a.back-btn {
  /* "fixed" no: .screen ha un transform per le transizioni di pagina (anche
     quando è translateX(0), un transform presente basta) e quello crea un
     nuovo "containing block" per i figli fixed — smettono di restare
     ancorati alla viewport vera e si muovono con lo scroll della pagina
     invece che restarci incollati (trovato in test: la bolla appariva fuori
     schermo). .screen è comunque position:relative e alto quanto tutto lo
     schermo, quindi absolute rispetto a lui ottiene lo stesso risultato
     visivo, in modo affidabile. */
  position: absolute;
  left: 18px;
  bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: var(--surface-dark);
  color: #fff;
  font-size: 20px;
  box-shadow: 0 12px 26px rgba(58,50,90,0.3);
  text-decoration: none;
  z-index: 30;
  transition: transform 0.15s cubic-bezier(0.34,1.56,0.64,1), opacity 0.15s ease;
}
a.back-btn:active { transform: scale(0.92); }

/* .has-open-modal la mette script.js (initBackBtnModalGuard) quando un
   .signup-overlay qualsiasi è visibile in questa .screen: vedi il
   commento lì per il perché (un semplice z-index più alto sul popup non
   basta se il popup vive dentro .content, che ha già il suo). */
.screen.has-open-modal a.back-btn {
  opacity: 0;
  pointer-events: none;
}

/* min-width:0 è necessario perché sia il flex-shrink a valere qualcosa:
   di default un figlio flex non si restringe sotto la sua larghezza intrinseca
   (il testo tutto su una riga), quindi un nome evento lungo spingeva
   .header-menu-wrap (il pulsante ⋮, margin-left:auto) fuori dallo schermo,
   invisibile e non toccabile — trovato 2026-08-24 testando un titolo lungo
   su evento.html. Qui il titolo tronca con "…" invece di spingere. */
.header-title {
  font-family: 'Fraunces', serif;
  font-size: 18px;
  font-weight: 600;
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.profile {
  display: flex;
  align-items: center;
  gap: 12px;
}

.avatar {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  /* Era un gradiente peach->lavender (Fil, 2026-08-23: in tema col resto
     del restyling, colore pieno anche qui — stesso trattamento delle altre
     "bolle" con iniziale/foto nell'app, vedi .attendee-bubble-circle e
     .account-search-avatar più sotto). */
  background: var(--peach);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Fraunces', serif;
  font-weight: 600;
  font-size: 20px;
  color: #fff;
  flex-shrink: 0;
  box-shadow: 0 4px 12px rgba(58, 50, 90, 0.15);
}

.avatar.large {
  width: 84px;
  height: 84px;
  font-size: 30px;
  margin: 10px auto 14px;
}

.greeting .name {
  font-family: 'Fraunces', serif;
  font-size: 25px;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.15;
}

.greeting .date {
  font-size: 12.5px;
  color: var(--ink-soft);
  font-weight: 500;
  margin-top: 3px;
}

/* Badge scherzoso sulla presenza agli eventi: sotto al profilo (Fil, 2026-08-24) */
.top-badge-wrap {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: center;
  padding-top: 14px;
  /* .content sotto ha già 4px di padding-top suo: 10 + 4 = 14, come sopra
     (Fil, 2026-08-24: "stesso spazio sopra e sotto", poi "troppo spazio"
     coi 26px iniziali — ridotto tenendo i due lati uguali). */
  padding-bottom: 10px;
}

.attendance-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.7);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink);
  box-shadow: 0 2px 8px rgba(58, 50, 90, 0.1);
  transition: opacity 0.22s ease, transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.25s ease;
}

/* Notifica arrivata mentre sei sulla Home (Fil, 2026-08-24): il badge si
   ingrandisce un po' e mostra il testo della notifica al posto della solita
   frase, poi torna com'era da solo dopo 5s — vedi flashAttendanceBadge in
   script.js, chiamata da refreshHome in index.html quando trova una
   notifica più recente di quella vista l'ultima volta. */
.attendance-badge--flash {
  transform: scale(1.08);
  box-shadow: 0 6px 18px rgba(58, 50, 90, 0.22);
}

/* Va DOPO la regola base sopra, non nel blocco dark-mode in cima al file:
   quello (righe ~56-90) viene prima nel sorgente, quindi qualunque
   proprietà diretta impostata lì (non una custom property in :root) perde
   comunque contro questa stessa regola più sotto, a parità di specificità
   — il cascade CSS non guarda i media query, guarda l'ordine. Ci sono
   cascato anch'io la prima volta (Fil, 2026-08-24): sembrava applicato ma
   .attendance-badge restava bianco perché la regola base qui sotto vince
   sempre. Stessa "lastra di vetro bianca" di .header/.navbar, corretta
   nel posto giusto stavolta. */
@media (prefers-color-scheme: dark) {
  .attendance-badge {
    background: rgba(44, 34, 51, 0.75);
  }
}

.bell {
  width: 40px;
  height: 40px;
  border-radius: 14px;
  background: var(--card);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  box-shadow: 0 2px 8px rgba(58,50,90,0.06);
  color: var(--ink);
}

/* Piccolo tremolio quando ci sono notifiche non lette (Fil, 2026-07-23),
   tolto via classList non appena diventano lette (vedi index.html). Solo
   sull'icona SVG dentro, non su tutto .bell (altrimenti si sposta anche il
   pallino col numero, che deve restare fermo nel suo angolo). */
.bell.has-unread svg {
  animation: bellRing 2.2s ease-in-out infinite;
  transform-origin: top center;
}

@keyframes bellRing {
  0%, 75%, 100% { transform: rotate(0deg); }
  78% { transform: rotate(-11deg); }
  81% { transform: rotate(9deg); }
  84% { transform: rotate(-7deg); }
  87% { transform: rotate(5deg); }
  90% { transform: rotate(-2deg); }
  93% { transform: rotate(0deg); }
}

/* Badge "hai N notifiche nuove?" sulla campanella (Fil, 2026-07-17, numero
   dentro aggiunto 2026-07-19 — prima solo un pallino vuoto, poco visibile e
   non diceva quante). Dentro ai bordi (top/right positivi, non negativi come
   .menu-dot) perché .bell ha overflow:hidden per contenere il ripple del
   click — un posizionamento a cavallo del bordo verrebbe tagliato via. */
.bell-badge {
  position: absolute;
  top: 3px;
  right: 3px;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  border-radius: 9px;
  background: var(--cancel, #E0637A);
  border: 2px solid var(--card, #fff);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Inter', sans-serif;
  font-size: 10px;
  font-weight: 700;
  color: #fff;
  line-height: 1;
}

/* Scrollable content */
.content {
  position: relative;
  z-index: 1;
  flex: 1;
  overflow-y: auto;
  padding: 4px 20px 100px;
}

.section-title {
  font-family: 'Fraunces', serif;
  font-size: 16px;
  font-weight: 600;
  margin: 18px 0 12px;
  color: var(--ink);
}

.section-title.first { margin-top: 6px; }

/* Cards */
.card {
  background: var(--card);
  border-radius: 22px;
  padding: 18px;
  margin-bottom: 14px;
  box-shadow: 0 4px 16px rgba(58,50,90,0.06);
  display: block;
}

/* Swipe per rimuovere una card dalla Home (Fil, 2026-07-20, solo Home:
   vedi renderEventCardHTML in data.js e initSwipeToRemove in script.js).
   Il cestino sta SOTTO la card, a destra, e si vede solo quando la card
   viene trascinata verso sinistra (transform sulla card stessa). */
.card-swipe-wrap {
  position: relative;
  border-radius: 22px;
  overflow: hidden;
  margin-bottom: 14px;
}
.card-swipe-wrap .card {
  margin-bottom: 0; /* lo spazio sotto lo dà il wrapper, non la card */
  position: relative;
  z-index: 1;
  touch-action: pan-y; /* lo scroll verticale resta libero, si cattura solo il drag orizzontale */
}
.card-swipe-trash {
  position: absolute;
  top: 0;
  /* Fil, 2026-07-22: da destra a sinistra -- lo swipe per rimuovere una
     card andava verso sinistra, lo stesso verso usato per passare alla tab
     successiva (vedi initTabSwipeNavigation in script.js): due gesti
     opposti nello stesso posto si confondevano a vicenda. Ora il cestino
     compare trascinando verso DESTRA (SWIPE_OPEN_X positivo qui sotto),
     lasciando il trascinamento verso sinistra libero per cambiare tab. */
  left: 0;
  bottom: 0;
  width: 76px;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Rosso vero (Fil, 2026-07-20), non var(--cancel) (rosso smorzato, vedi
     in cima al file): qui serve il segnale "elimina" immediato di uno
     swipe-to-delete, il resto dell'app usa apposta un rosso smorzato ma
     qui va più diretto. */
  background: #E5484D;
  color: #fff;
  font-size: 22px;
  border-radius: 22px;
  /* Fil, 2026-07-20: la card sopra fa il fade-in di .reveal (parte da
     opacità 0), e per quella mezza/un secondo il rosso pieno qui sotto si
     vedeva a piena forza attraverso — un lampo rosso a ogni apertura
     dell'app. Resta invisibile finché la card non ha finito il suo reveal
     (.card.in-view qui sotto), poi appare con la sua stessa dissolvenza. */
  opacity: 0;
  transition: opacity 0.35s ease;
}
.card-swipe-wrap .card.in-view + .card-swipe-trash {
  opacity: 1;
}

/* Evento confermato: bordo netto invece dell'alone verde sfocato di prima
   (Fil, 2026-08-23: "non è più in tema per nulla" — un verde acceso in
   glow, mai toccato dal restyling perché non è una classe home-*). Prima
   provata in lavanda per coerenza con la Home, ma il viola non si legge
   a colpo d'occhio come "confermato" quanto il verde (Fil aveva ragione) —
   var(--confirmed), un verde smorzato, non il verde acceso di prima:
   stessa disciplina della palette, applicata a un colore di stato. Niente
   sfocatura: un bordo pieno, come il resto del restyling. */
.card.is-done {
  box-shadow: inset 0 0 0 1.5px var(--confirmed), 0 4px 16px rgba(58,50,90,0.06);
}

/* Card intera più scura per un evento annullato (non solo il badge, Fil
   2026-07-10): deve saltare subito all'occhio anche scorrendo veloce.
   Bordo netto invece del tint di sfondo (Fil, 2026-08-23: stessa logica
   di .card.is-done qui sopra — un colore, coerente ovunque significhi
   "annullato": riquadro Home, bordo qui, pillina badge). */
.card.is-cancelled {
  box-shadow: inset 0 0 0 1.5px var(--cancel), 0 4px 16px rgba(58,50,90,0.06);
}

.card.is-cancelled .card-date {
  color: var(--cancel);
}

.card-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 10px;
}

.card-top-left {
  min-width: 0;
}

/* Stesso bug del titolo evento nell'header (vedi .header-title): un nome
   evento lungo, senza freno, spingeva il .badge di stato fuori dalla card
   invece di lasciargli spazio — trovato 2026-08-24 nella stessa sessione. */
.card-title {
  font-family: 'Fraunces', serif;
  font-size: 17px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.card-date {
  font-size: 12.5px;
  color: var(--ink-soft);
  margin-top: 3px;
}

.badge {
  font-size: 11px;
  font-weight: 600;
  padding: 5px 10px;
  border-radius: 999px;
  white-space: nowrap;
  flex-shrink: 0;
}

.badge.waiting { background: var(--sky-soft); color: #7A3F82; }
.badge.almost { background: var(--butter-soft); color: #9C4A0F; }
.badge.done { background: var(--confirmed-soft); color: #2E5C38; }
.badge.cancelled { background: var(--cancel-soft); color: #7A2B2D; }
.badge.passato { background: var(--past-soft); color: var(--ink-soft); }
.badge.linked { background: var(--mint-soft); color: #4A2B52; }
.badge.tie { background: var(--butter); color: #4A2B52; }

/* puntino "c'è qualcosa qui" sul menu ⋮ dell'evento, prima volta soltanto
   (vedi setupHeaderMenu in evento.html) — niente testo, solo un richiamo
   visivo che sparisce al primo click. */
.menu-dot {
  position: absolute;
  top: -2px;
  right: -2px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--cancel, #E0637A);
  border: 2px solid var(--card, #fff);
}

/* mini-avatar (foto o iniziale) davanti a un nome collegato a un account,
   nelle righe di lista amici/invitati — vedi NdumaUI.attachAccountSearch
   e amici.html/crea.html. Sostituisce il vecchio pallino verde muto: si vede
   subito la persona vera invece di un indicatore senza spiegazione. */
.linked-mini-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--lavender);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  margin-right: 7px;
  flex-shrink: 0;
  overflow: hidden;
  vertical-align: middle;
}
.linked-mini-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.progress-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
}

.progress-track {
  flex: 1;
  height: 8px;
  border-radius: 999px;
  background: var(--track-soft);
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  border-radius: 999px;
}

.progress-label {
  font-size: 12px;
  color: var(--ink-soft);
  font-weight: 500;
}

.empty-hint {
  text-align: center;
  color: var(--ink-soft);
  font-size: 13px;
  padding: 30px 10px;
}

/* I link dentro empty-hint (es. "Proponine uno tu →", "Torna alla Home →")
   ereditavano lo stile generico "a" (niente sottolineato, colore uguale al
   testo intorno) e sembravano testo normale, non cliccabile. Stesso
   trattamento di .field-hint a: colore + grassetto (Fil, 2026-07-17). */
.empty-hint a {
  color: var(--lavender);
  font-weight: 600;
}

/* Fumetto informativo "una volta sola" — vedi NdumaUI.showOnceHint in
   script.js. Sempre nel flusso normale del documento (mai position:absolute):
   dopo il bug del menu ⋮ finito sotto la foto per colpa di stacking context,
   qui si preferisce spingere giù il contenuto sotto invece di sovrapporsi a
   qualcosa. Volutamente leggero (sfondo tenue, testo piccolo, niente ✕): Fil,
   2026-07-07, "mi sa troppo di banner" sulla prima versione — sparisce da
   solo quando interagisci col campo a cui si riferisce, vedi showOnceHint. */
.hint-bubble {
  background: var(--lavender-soft);
  color: var(--lavender);
  font-size: 11.5px;
  line-height: 1.4;
  padding: 6px 10px;
  border-radius: 9px;
  margin-top: 6px;
}

/* Filter pills (eventi.html) */
/* Su schermi stretti (320px, i vari filtri di eventi.html: "Confermati" /
   "In attesa" / "Annullati" / "Tutti") 4 pill non ci stavano affiancate:
   si schiacciavano sotto la loro larghezza naturale e il testo veniva
   tagliato senza puntini, tipo "Conferma" al posto di "Confermati" —
   trovato 2026-08-24 testando a 320px. Riga scorrevole invece di pill
   compresse: ogni pill tiene la sua larghezza piena (flex-shrink:0), la
   riga scorre in orizzontale solo se davvero non ci sta tutta. */
.pill-row {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
  overflow-x: auto;
  scrollbar-width: none;
}
.pill-row::-webkit-scrollbar { display: none; }

.pill {
  font-size: 12.5px;
  font-weight: 500;
  padding: 8px 14px;
  border-radius: 999px;
  background: var(--card);
  color: var(--ink-soft);
  box-shadow: 0 2px 8px rgba(58,50,90,0.06);
  flex-shrink: 0;
  white-space: nowrap;
}

.pill.active {
  background: var(--surface-dark);
  color: #fff;
}

/* Fil, 2026-07-23: toggle testo/vocale in crea.html — solo icona, senza
   etichetta (le due icone bastano da sole a distinguere le modalità, il
   testo era ridondante). Stesso comportamento attivo/inattivo di .pill,
   solo forma circolare invece che a pillola con testo. */
.pill-icon {
  width: 36px;
  height: 36px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Fil, 2026-07-23: schermata "registrazione in corso" (crea.html) — al
   posto della scritta rossa, un microfono con un alone che pulsa e delle
   barrette che si muovono a tempo con il volume vero della voce (lette
   dal microfono via AnalyserNode, vedi animateWaveBars in crea.html — non
   è un'animazione decorativa a loop fisso). */
.rec-mic-wrap {
  position: relative;
  width: 56px;
  height: 56px;
  margin: 0 auto 12px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.rec-mic-pulse {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--cancel);
  opacity: 0.3;
  animation: recPulse 1.6s ease-out infinite;
}

@keyframes recPulse {
  0% { transform: scale(0.65); opacity: 0.35; }
  100% { transform: scale(1.35); opacity: 0; }
}

.rec-mic-icon {
  position: relative;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--cancel);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 10px rgba(184,101,74,0.32);
}

.rec-wave {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 4px;
  height: 22px;
  margin-bottom: 10px;
}

.rec-wave-bar {
  width: 3px;
  height: 4px;
  border-radius: 2px;
  background: var(--cancel);
  transition: height 0.09s ease;
}

.rec-timer {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 4px;
}

/* Fil, 2026-07-23: player della nota vocale registrata — sostituisce i
   controlli nativi del browser (<audio controls>, look diverso su ogni
   browser/OS e non personalizzabile via CSS) con uno in stile app, vedi
   audioPlayBtn/audioProgressTrack in crea.html per la logica. */
.audio-player {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--card);
  border-radius: 14px;
  padding: 10px 12px;
  margin-bottom: 8px;
  box-shadow: 0 2px 8px rgba(58,50,90,0.06);
}

.audio-play-btn {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: none;
  background: var(--surface-dark);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}

.audio-play-btn svg { display: block; }

.audio-play-btn:active { transform: scale(0.94); }

.audio-player-body { flex: 1; min-width: 0; }

.audio-progress-track {
  height: 5px;
  border-radius: 3px;
  background: var(--track-soft);
  cursor: pointer;
  margin-bottom: 6px;
  position: relative;
}

.audio-progress-fill {
  height: 100%;
  width: 0%;
  border-radius: 3px;
  background: var(--lavender);
  transition: width 0.1s linear;
}

.audio-time-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-soft);
}

/* Forms (crea.html) */
.field {
  margin-bottom: 16px;
}

.field label {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 6px;
}

/* Fil, 2026-07-23: la matita accanto a "Nome evento" si muove come se
   scrivesse mentre l'utente digita nel campo (vedi eventNamePencil in
   crea.html, classe .writing aggiunta/tolta con debounce sull'input). */
.field-pencil-icon {
  display: inline-block;
  vertical-align: -1px;
  color: var(--ink-soft);
}

.field-pencil-icon.writing {
  animation: pencilWrite 0.4s ease-in-out infinite;
  transform-origin: 78% 78%;
}

@keyframes pencilWrite {
  0%, 100% { transform: rotate(0deg); }
  30% { transform: rotate(-14deg); }
  70% { transform: rotate(11deg); }
}

.field input[type="text"],
.field input[type="number"],
.field input[type="date"],
.field input[type="time"],
.field input[type="email"],
.field input[type="password"],
.field select,
.field textarea {
  width: 100%;
  border: none;
  background: var(--card);
  border-radius: 14px;
  padding: 12px 14px;
  font-family: 'Inter', sans-serif;
  /* 16px minimo, non 14px: sotto i 16px Safari iOS zooma automaticamente
     la pagina ogni volta che il campo prende il focus (bug notato da Fil,
     "la pagina salta quando tocco un campo") — con user-scalable=no nel
     meta viewport lo zoom a volte resta anche incastrato dopo. */
  font-size: 16px;
  color: var(--ink);
  box-shadow: 0 2px 8px rgba(58,50,90,0.06);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  box-shadow: 0 0 0 3px var(--lavender-soft), 0 2px 8px rgba(58,50,90,0.06);
}

/* Select: nascondiamo la freccetta di sistema e ne disegnamo una nostra,
   coerente col resto (stesso tratto delle altre icone lineari dell'app). */
.field select {
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238C7C91' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 13px;
  padding-right: 36px;
}

/* Date: l'indicatore nativo di Chrome/Safari resta cliccabile ma invisibile,
   sopra un'icona calendario disegnata da noi nello stesso stile del resto
   (prima era l'iconcina grigia di sistema, fuori tono con Fraunces/Inter).
   appearance:none è la parte che conta su iOS: senza, Safari ignora bordi
   arrotondati/sfondo/allineamento non appena il campo ha un valore e lo
   sostituisce con la sua "pillola" di sistema a tutta larghezza e testo
   centrato — bug notato da Fil su iPhone il 2026-07-05. */
.field input[type="date"] {
  position: relative;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  text-align: left;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236B3F73' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='3'/%3E%3Cline x1='16' y1='2' x2='16' y2='6'/%3E%3Cline x1='8' y1='2' x2='8' y2='6'/%3E%3Cline x1='3' y1='10' x2='21' y2='10'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 16px;
  padding-right: 40px;
}

.field input[type="date"]::-webkit-calendar-picker-indicator {
  opacity: 0;
  position: absolute;
  right: 0;
  top: 0;
  width: 40px;
  height: 100%;
  cursor: pointer;
}

.field input[type="date"]::-webkit-datetime-edit {
  color: var(--ink);
}

.field input[type="date"]::-webkit-datetime-edit-fields-wrapper,
.field input[type="date"]::-webkit-datetime-edit-text,
.field input[type="date"]::-webkit-datetime-edit-month-field,
.field input[type="date"]::-webkit-datetime-edit-day-field,
.field input[type="date"]::-webkit-datetime-edit-year-field {
  font-family: 'Inter', sans-serif;
}

/* Stesso trattamento dell'input data qui sopra, applicato all'orario
   (Fil, 2026-07-20): senza queste regole restava con la grafica grezza del
   sistema -- piccola su iPhone, un rettangolo spoglio in stile anni 2000 su
   Android/Samsung. */
.field input[type="time"] {
  position: relative;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  text-align: left;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236B3F73' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpolyline points='12 7 12 12 15.5 14'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 16px;
  padding-right: 40px;
}

.field input[type="time"]::-webkit-calendar-picker-indicator {
  opacity: 0;
  position: absolute;
  right: 0;
  top: 0;
  width: 40px;
  height: 100%;
  cursor: pointer;
}

.field input[type="time"]::-webkit-datetime-edit {
  color: var(--ink);
}

.field input[type="time"]::-webkit-datetime-edit-fields-wrapper,
.field input[type="time"]::-webkit-datetime-edit-text,
.field input[type="time"]::-webkit-datetime-edit-hour-field,
.field input[type="time"]::-webkit-datetime-edit-minute-field,
.field input[type="time"]::-webkit-datetime-edit-ampm-field {
  font-family: 'Inter', sans-serif;
}

.field input:disabled,
.field input:read-only {
  opacity: 0.55;
  cursor: not-allowed;
}

.field-hint {
  font-size: 12px;
  color: var(--ink-soft);
  margin-top: 6px;
}

.field-hint a { color: var(--lavender); font-weight: 600; }

/* Opzioni secondarie di un form (es. "salva come lista amici", "apri il
   link a tutti" in crea.html), raggruppate in un'unica bolla leggera invece
   di un riquadro con ombra per checkbox: più leggere di un .card vero, non
   competono visivamente con i campi obbligatori sopra (Fil, 2026-07-12:
   "troppi riquadri con ombra, mettili insieme in fondo"). */
.option-group {
  background: var(--card);
  border-radius: 16px;
  padding: 4px 16px;
  margin-bottom: 16px;
}

.option-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 0;
  cursor: pointer;
}

.option-row input[type="checkbox"] {
  width: 16px;
  height: 16px;
  margin-top: 2px;
  flex-shrink: 0;
  accent-color: var(--lavender);
}

.option-row-title {
  display: block;
  font-size: 13px;
  color: var(--ink);
}

.option-row-hint {
  display: block;
  font-size: 11.5px;
  color: var(--ink-soft);
  margin-top: 1px;
}

.option-divider {
  height: 1px;
  background: rgba(58,50,90,0.08);
}

/* Switch on/off stile iOS/Android: un vero <input type="checkbox">
   ridisegnato con appearance:none, la pallina è ::before che scorre da
   sinistra a destra quando :checked (supportato da Safari e Chrome
   correnti su ::before/::after di un checkbox non-appearance). border:none
   + box-sizing:border-box tolgono il bordo di default che il browser
   applica comunque ai checkbox anche con appearance:none — senza,
   la pallina risultava spostata in basso rispetto alla barra (Fil,
   2026-07-25, trovato testando su device vero). */
.option-row-switch {
  appearance: none;
  -webkit-appearance: none;
  box-sizing: border-box;
  border: none;
  outline: none;
  padding: 0;
  width: 46px;
  height: 27px;
  min-width: 46px;
  margin: 0;
  border-radius: 999px;
  background: rgba(58,50,90,0.18);
  position: relative;
  cursor: pointer;
  transition: background 0.2s ease;
  flex-shrink: 0;
  vertical-align: middle;
}

.option-row-switch::before {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 23px;
  height: 23px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
  transition: left 0.2s ease;
}

.option-row-switch:checked {
  background: var(--lavender);
}

.option-row-switch:checked::before {
  left: 21px;
}

/* Coppie di opzioni una accanto all'altra invece che impilate in righe
   intere (Fil, 2026-07-25: "troppo lunghi e invasivi" impilati) — stesso
   spirito della griglia 2 colonne delle liste amici in amici.html, ma
   senza ombra come il resto delle opzioni secondarie di questo form. */
.option-tile-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-bottom: 16px;
}

.option-tile {
  background: var(--card);
  border-radius: 16px;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  cursor: pointer;
}

/* Una sola tile visibile nella coppia (es. "salva come lista" nascosto
   perché hai già scelto una lista): occupa tutta la riga invece di
   lasciare metà griglia vuota. */
.option-tile-solo {
  grid-column: 1 / -1;
}

.option-tile-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.option-tile-title {
  flex: 1;
  min-width: 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.25;
}

.option-tile-hint {
  font-size: 10.5px;
  color: var(--ink-soft);
  line-height: 1.3;
}

.option-tile .option-row-switch {
  width: 38px;
  height: 22px;
  min-width: 38px;
}

.option-tile .option-row-switch::before {
  width: 18px;
  height: 18px;
}

.option-tile .option-row-switch:checked::before {
  left: 18px;
}

/* Avviso "sessione scaduta" (Fil, 2026-07-13): colori da attenzione, non da
   errore vero — non è un guasto, è solo un accesso vecchio da rifare. */
.session-warning-banner {
  background: var(--butter-soft);
  color: var(--ink);
  border-radius: 14px;
  padding: 14px 16px;
  margin-bottom: 16px;
  font-size: 13px;
  line-height: 1.5;
}

.session-warning-banner .session-warning-btn {
  display: block;
  margin-top: 10px;
  background: var(--lavender);
  color: #fff;
  border: none;
  border-radius: 10px;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.field textarea { resize: none; height: 70px; }

/* Anteprima foto evento (crea.html): riquadro rettangolare arrotondato, non
   circolare come gli avatar — è pensata per un'immagine "di scena", non un
   ritratto. Vuota mostra solo un'iconcina, piena copre tutto il riquadro. */
/* Specificità: "label.event-photo-preview" (non solo ".event-photo-preview")
   serve per battere la regola generica ".field label" (display:block), che
   altrimenti vince per specificità e rompe il centraggio flex qui sotto. */
label.event-photo-preview {
  width: 100%;
  height: 116px;
  border-radius: 16px;
  background: var(--card);
  box-shadow: 0 2px 8px rgba(58,50,90,0.06);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  overflow: hidden;
  color: var(--ink-soft);
  cursor: pointer;
  text-align: center;
}

.event-photo-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

#eventPhotoEmoji {
  font-size: 28px;
  line-height: 1;
}

/* Il riquadro è un <label for="eventPhotoFile">, quindi cliccarlo ovunque
   apre già il file picker: qui serve solo lo stile del testo dentro (visibile
   finché non c'è ancora una foto scelta, poi l'img lo sostituisce). */
.photo-placeholder-text {
  font-family: 'Inter', sans-serif;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
  line-height: 1.2;
}

/* Puntini di avanzamento del form a step (crea.html) */
.wizard-dots {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin: 4px 0 22px;
}

.wizard-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--card);
  box-shadow: 0 2px 6px rgba(58,50,90,0.08);
  transition: width .2s ease, background .2s ease;
}

.wizard-dot.active {
  width: 22px;
  border-radius: 5px;
  background: var(--peach);
}

.wizard-dot.done {
  background: var(--mint-soft);
}

.date-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

/* min-width:0 è la parte che conta: senza, un flex item con contenuto "rigido"
   come un input date non si restringe mai sotto la sua dimensione naturale, e
   quando due ne stanno nella stessa riga (range di date) il telefono va in
   overflow orizzontale invece di stare nella larghezza dello schermo. Il
   padding-right più stretto (solo qui, dove i date-input sono due per riga)
   lascia un po' più di spazio libero per i segni gg/mm/aaaa.

   width:1px è la parte per iOS (Fil, 2026-07-17): un <input type="date">
   vuoto su Safari/iPhone calcola la sua larghezza "naturale" dal segnaposto
   di sistema, più stretta di quanto risulti a data scelta — il riquadro
   sembra restringersi finché non scrivi una data. Dare un width di partenza
   esplicito (qualunque valore piccolo, sovrascritto subito dalla crescita
   flex:1) impedisce a Safari di usare quel contenuto come base di calcolo:
   la larghezza viene sempre dalla riga flessibile, vuoto o pieno che sia. */
.date-row input { flex: 1; min-width: 0; width: 1px; }
.date-row input[type="date"] { padding-right: 30px; background-size: 14px; background-position: right 8px center; }
.date-row input[type="date"]::-webkit-calendar-picker-indicator { width: 30px; }

.remove-date {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: var(--peach-soft);
  color: var(--cancel);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  flex-shrink: 0;
}

.add-date-btn {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  background: var(--mint-soft);
  border-radius: 12px;
  padding: 10px;
  text-align: center;
  margin-bottom: 20px;
}

/* Ripeti questo evento (card annullata, lista + dettaglio): non è un'azione
   minore come "+Aggiungi una spesa" (quella usa .add-date-btn, tint tenue),
   è l'unica cosa che si può ancora fare su un evento morto — merita il peso
   di un CTA vero. Prima riusava .add-date-btn: pillola beige generica,
   stonava dentro una card dal bordo rosso "annullato" (Fil, 2026-08-24:
   "come pulsante degli annullati non mi piace"). Pieno come .primary-btn,
   ma più compatto per stare in una card di lista. */
.repeat-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: var(--peach);
  color: #FFF8F0;
  font-weight: 600;
  font-size: 13px;
  padding: 11px;
  border-radius: 12px;
  text-align: center;
  box-shadow: 0 6px 16px rgba(58,50,90,0.12);
}
.repeat-btn svg { flex-shrink: 0; }

.primary-btn {
  display: block;
  width: 100%;
  /* Era un gradiente peach->sky (Fil, 2026-08-23: stonava con la nuova Home,
     tutta a blocchi di colore pieno — via il gradiente anche qui e sul
     pallino attivo di .wizard-dot qui sotto, stesso accento). */
  background: var(--peach);
  color: #FFF8F0;
  font-weight: 600;
  font-size: 14.5px;
  padding: 15px;
  border-radius: 16px;
  text-align: center;
  box-shadow: 0 8px 20px rgba(58,50,90,0.15);
  border: none;
  font-family: 'Inter', sans-serif;
  cursor: pointer;
}

.form-error {
  color: var(--cancel);
  font-size: 12.5px;
  font-weight: 600;
  margin: -10px 0 14px;
  min-height: 1em;
}

/* Invitati: bolle affiancate invece di una riga piena a testa (Fil,
   2026-08-23: "tantissimo testo, pochi riquadri come la Home") — colore
   di sfondo = stato (verde disponibile, rosso assente, neutro non
   risposto ancora), stessa logica semantica già usata sui riquadri Home
   e sulle card evento. */
.invitee-chip-wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 20px;
}
.invitee-chip {
  display: inline-flex;
  align-items: center;
  padding: 7px 13px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  background: var(--track-soft);
  color: var(--ink-soft);
}
.invitee-chip svg { flex-shrink: 0; }
.invitee-chip.is-available { background: var(--confirmed-soft); color: #2E5C38; }
.invitee-chip.is-absent { background: var(--cancel-soft); color: #7A2B2D; }

/* Riepilogo "la tua disponibilità": date/location scelte, una chip
   ciascuna invece di una frase con le virgole. */
.mini-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}
.mini-chip-label {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 6px;
}
.mini-chip {
  display: inline-flex;
  align-items: center;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  /* Grigio neutro, non più pesca (Fil, 2026-08-23): "la tua disponibilità"
     è un'informazione di conferma, secondaria rispetto a "che data sta
     vincendo" (vedi .confirmed-date-card.is-leading) — il pesca ora è
     riservato a quella. */
  background: var(--track-soft);
  color: var(--ink-soft);
}
/* Location: colore diverso dalle date (Fil, 2026-08-23: "stessi colori,
   confusionario") — due categorie diverse, due colori diversi. */
.mini-chip.is-location { background: var(--lavender-soft); color: var(--lavender); }

/* ---------- evento.html: tessere compatte "dove"/"tu" (Fil, 2026-08-23)
   ----------
   "Quando mi invitano voglio sapere subito dove, cosa si tratta e in che
   data — il resto (chi viene ecc.) posso guardarlo dopo." Sostituiscono
   la vecchia riga di testo per la location e il vecchio blocco
   titolo+chip+bottone per la propria risposta: stessa idea dei riquadri
   Home, in piccolo — icona, etichetta corta, valore. */
.info-tile {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--card);
  border-radius: 18px;
  padding: 13px 15px;
  box-shadow: 0 4px 16px rgba(58,50,90,0.06);
  margin-bottom: 10px;
}
.info-tile.is-clickable { cursor: pointer; }
.info-tile-icon {
  width: 38px;
  height: 38px;
  border-radius: 12px;
  background: var(--track-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.info-tile-icon svg { width: 19px; height: 19px; stroke: var(--ink); }
.info-tile-icon.is-available { background: var(--confirmed-soft); }
.info-tile-icon.is-available svg { stroke: var(--confirmed); }
.info-tile-icon.is-absent { background: var(--cancel-soft); }
.info-tile-icon.is-absent svg { stroke: var(--cancel); }
.info-tile-body { flex: 1; min-width: 0; }
.info-tile-label {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.info-tile-value {
  font-family: 'Fraunces', serif;
  font-weight: 600;
  font-size: 14.5px;
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.info-tile-value a { color: inherit; }

/* Tessera "chi viene": invitati + grafico dei giorni dietro un tap invece
   di stare sempre in bella vista — non sono la prima cosa che serve
   sapere aprendo un invito (Fil). Il popup che apre riusa lo stile già
   esistente per il popup di gestione liste amici (.signup-overlay/
   .signup-modal), non un componente nuovo. */
.who-coming-tile {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--card);
  border-radius: 18px;
  padding: 13px 15px;
  box-shadow: 0 4px 16px rgba(58,50,90,0.06);
  margin-bottom: 16px;
  cursor: pointer;
}
.who-coming-avatars { display: flex; flex-shrink: 0; }
.who-coming-avatars span {
  width: 28px; height: 28px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: 'Fraunces', serif; font-weight: 600; font-size: 11px; color: #fff;
  border: 2px solid var(--card); margin-left: -9px; flex-shrink: 0;
}
.who-coming-avatars span:first-child { margin-left: 0; }
.who-coming-body { flex: 1; min-width: 0; }
.who-coming-title { font-family: 'Fraunces', serif; font-weight: 600; font-size: 14.5px; }
.who-coming-sub { font-size: 12px; color: var(--ink-soft); margin-top: 2px; }
.who-coming-chevron { color: var(--ink-soft); font-size: 17px; flex-shrink: 0; }

/* Date chips (evento.html) */
.chip-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 20px;
}

.chip {
  background: var(--card);
  border-radius: 16px;
  padding: 14px 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-shadow: 0 2px 8px rgba(58,50,90,0.06);
  cursor: pointer;
  border: 2px solid transparent;
}

.chip.selected {
  border-color: var(--mint);
  background: var(--mint-soft);
}

.chip .chip-date {
  font-weight: 600;
  font-size: 14px;
}

.chip .chip-check {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--track-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: transparent;
}

.chip.selected .chip-check {
  background: var(--mint);
  color: #FFF8F0;
}

/* Griglia "Quando sei disponibile?" (evento.html, Fil 2026-07-19): card
   quadrate 3 per riga invece della lista verticale di .chip — con più di
   3-4 date proposte risparmia parecchio scroll. .day-card tiene comunque
   la classe .chip (colore quando selezionata, animazione al tap, "pop"
   already gestiti da lì): qui si sovrascrive solo il layout interno, da
   riga (icona a sinistra, testo a destra) a colonna centrata. */
.day-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-bottom: 14px;
}

.day-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 8px 4px 7px;
  background: var(--bg);
  box-shadow: none;
}

.day-card .day-dow {
  font-size: 10px;
  color: var(--ink-soft);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.day-card .day-num {
  font-family: 'Fraunces', serif;
  font-weight: 700;
  font-size: 18px;
  line-height: 1.3;
  margin: 1px 0;
  color: var(--ink);
}

.day-card .day-month {
  font-size: 10px;
  color: var(--ink-soft);
  margin-bottom: 5px;
}

.day-card .chip-check {
  width: 16px;
  height: 16px;
  font-size: 9px;
  margin: 0 auto;
}

/* Riga "Conferma / Annulla evento" a mano dell'organizzatore (evento.html,
   Fil 2026-07-19): sostituisce la vecchia lista verticale con una data per
   riga, troppo lunga con tanti giorni proposti. Ora restano solo due
   bottoni affiancati in fondo alla sezione; la scelta del giorno (se ce n'è
   più di uno) si fa nel popup .confirm-day-modal qui sotto. */
.manual-confirm-btn-row {
  display: flex;
  gap: 10px;
  align-items: stretch;
}

.manual-confirm-btn-row .primary-btn {
  flex: 1;
  margin-bottom: 0;
}

.manual-confirm-cancel-btn {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 16px;
  border: 1.5px solid var(--cancel);
  color: var(--cancel);
  font-weight: 600;
  font-size: 14.5px;
  font-family: 'Inter', sans-serif;
  background: none;
  cursor: pointer;
  padding: 10px;
  text-align: center;
}

.primary-btn:disabled {
  opacity: 0.45;
  cursor: default;
  box-shadow: none;
}

/* Popup "quale giorno confermi?" (evento.html): stesso overlay/modale di
   .signup-overlay/.signup-modal, con dentro la griglia .day-grid già usata
   per "Quando sei disponibile?" — qui però ogni quadrato è selezionabile
   uno alla volta (non multiplo) e mostra quanti amici sono disponibili
   quel giorno, non solo la data. */
.confirm-day-modal {
  max-height: 88%;
  overflow-y: auto;
}

.confirm-day-modal .day-grid {
  margin-top: 4px;
}

/* Liste amici (amici.html) */
.list-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 2px;
}

.list-delete {
  font-size: 12px;
  color: var(--ink-soft);
  cursor: pointer;
  padding: 4px 6px;
}

/* Griglia liste amici (amici.html, Fil 2026-07-19): card quadrate 2 per
   riga invece di una sotto l'altra, stesso spirito della griglia giorni di
   evento.html. Tutta la card apre "Gestisci amici" (era prima solo il
   testo "Gestisci amici →", tolto per fare spazio): la ✕ di eliminazione
   resta un bersaglio separato, vedi il listener su #listsContainer in
   amici.html (usa closest(), non e.target diretto). */
#listsContainer {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

#listsContainer > .empty-hint {
  grid-column: 1 / -1;
}

.friend-list-card {
  aspect-ratio: 1;
  padding: 14px;
  border-radius: 18px;
  margin-bottom: 0;
  box-shadow: 0 2px 8px rgba(58,50,90,0.06);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.friend-list-card-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 6px;
}

.friend-list-card-name {
  font-weight: 600;
  font-size: 14px;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.friend-list-card .list-delete {
  padding: 0;
  font-size: 13px;
  color: #C9BEC6;
  flex-shrink: 0;
}

.friend-list-avatars {
  display: flex;
  align-items: center;
}

.friend-list-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 2px solid #FFFFFF;
  box-shadow: 0 2px 6px rgba(58,50,90,0.18);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Fraunces', serif;
  font-weight: 600;
  font-size: 11px;
  color: #FFF;
  overflow: hidden;
}

.friend-list-avatar:not(:first-child) {
  margin-left: -10px;
}

.friend-list-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.friend-list-avatar-more {
  background: var(--track-soft);
  color: var(--ink-soft);
  font-family: 'Inter', sans-serif;
  font-size: 10px;
}

.friend-list-card-count {
  margin: 8px 0 0;
}

.friends-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0 4px;
}

.friend-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--lavender-soft);
  color: var(--ink);
  font-size: 12.5px;
  font-weight: 600;
  padding: 7px 8px 7px 12px;
  border-radius: 999px;
}

/* Stesso bug del titolo evento (vedi .header-title/.card-title): un nome
   amico lungo, senza freno, spingeva la ✕ di rimozione fuori dalla riga —
   dentro il popup gestione-lista, ancora più stretto della pagina, la ✕
   finiva del tutto fuori vista e irraggiungibile. Trovato 2026-08-24. */
.friend-row-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.friend-remove {
  cursor: pointer;
  opacity: 0.55;
  font-size: 11px;
  flex-shrink: 0;
}

.friend-remove:active { opacity: 1; }

.inline-add-row {
  display: flex;
  gap: 8px;
  margin-top: 10px;
}

.inline-add-row input {
  flex: 1;
  border: none;
  background: var(--bg);
  border-radius: 12px;
  padding: 10px 12px;
  font-family: 'Inter', sans-serif;
  font-size: 16px; /* non sotto i 16px: zoom automatico al focus su Safari iOS */
  color: var(--ink);
}

.inline-add-row button {
  border: none;
  background: var(--mint-soft);
  color: var(--ink);
  font-weight: 700;
  font-size: 16px;
  width: 38px;
  border-radius: 12px;
  cursor: pointer;
  flex-shrink: 0;
  font-family: 'Inter', sans-serif;
}

/* "+" che compare solo quando c'è già qualcosa di valido da aggiungere
   (Fil, 2026-07-25): resta a larghezza zero finché il campo è vuoto,
   scorre dentro non appena inizi a scrivere — l'input accanto si
   restringe da solo perché è flex:1. Evita anche di premere "+" a vuoto,
   visto che finché il campo è vuoto non c'è proprio nulla da premere. */
.inline-add-row button.btn-reveal {
  width: 0;
  min-width: 0;
  padding: 0;
  opacity: 0;
  overflow: hidden;
  pointer-events: none;
  transition: width 0.2s ease, opacity 0.15s ease;
}

.inline-add-row button.btn-reveal.is-visible {
  width: 38px;
  min-width: 38px;
  opacity: 1;
  pointer-events: auto;
}

/* Riquadro "condividi link" (evento.html) */
.share-box {
  background: var(--lavender-soft);
  border-radius: 16px;
  padding: 14px 16px;
  margin-bottom: 20px;
}

.share-box .share-label {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--lavender);
  margin-bottom: 8px;
}

.share-row {
  display: flex;
  gap: 8px;
}

.share-row input {
  /* Un <input> di testo ha un min-width intrinseco (min-content) diverso da
     un div: flex:1 da solo non basta a farlo restringere sotto quel minimo,
     e su schermi stretti (320px) il pulsante "Condividi" finiva tagliato
     fuori dalla card — trovato 2026-08-24. */
  flex: 1;
  min-width: 0;
  border: none;
  background: var(--card);
  border-radius: 12px;
  padding: 10px 12px;
  font-family: 'Inter', sans-serif;
  font-size: 12.5px;
  color: var(--ink-soft);
}

.share-row button {
  border: none;
  background: var(--mint);
  color: #FFF8F0;
  font-weight: 600;
  font-size: 12.5px;
  padding: 0 14px;
  border-radius: 12px;
  cursor: pointer;
  flex-shrink: 0;
  font-family: 'Inter', sans-serif;
}

/* Notifications list */
.notif-item {
  display: flex;
  gap: 12px;
  background: var(--card);
  border-radius: 18px;
  padding: 14px;
  margin-bottom: 12px;
  box-shadow: 0 4px 16px rgba(58,50,90,0.06);
  /* Quelle legate a un evento vero sono un <a> (Fil, 2026-08-23), le altre
     restano un <div> — questa regola neutralizza lo stile di link solo
     quando serve, un <div> non la vede proprio. */
  text-decoration: none;
  color: inherit;
}
a.notif-item:active { background: var(--track-soft); }

.notif-icon {
  width: 38px;
  height: 38px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 17px;
  flex-shrink: 0;
}

.notif-icon.almost { background: var(--butter-soft); }
.notif-icon.new { background: var(--sky-soft); }
.notif-icon.confirmed { background: var(--mint-soft); }
.notif-icon.cancelled { background: var(--cancel-soft); }
.notif-icon.friend { background: var(--lavender-soft); }
.notif-icon.tie { background: var(--peach-soft); }

.notif-text { font-size: 13.5px; line-height: 1.4; }
.notif-text b { font-weight: 600; }
.notif-time { font-size: 11.5px; color: var(--ink-soft); margin-top: 4px; }

/* Profile */
.profile-header {
  text-align: center;
  padding-top: 10px;
}

.profile-header .name {
  font-family: 'Fraunces', serif;
  font-size: 20px;
  font-weight: 600;
}

.profile-header .email {
  font-size: 12.5px;
  color: var(--ink-soft);
  margin-top: 2px;
}

.settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--card);
  border-radius: 16px;
  padding: 14px 16px;
  margin-bottom: 10px;
  box-shadow: 0 2px 8px rgba(58,50,90,0.06);
  font-size: 14px;
  font-weight: 500;
}

.settings-row .left {
  display: flex;
  align-items: center;
  gap: 10px;
}

.settings-row.danger { color: var(--cancel); }

/* "Chi c'è per ogni giorno" (evento.html): bordo trasparente di base su ogni
   riga, così quando quella con più adesioni lo colora d'arancione non sposta
   di qualche pixel le altre righe (stesso spazio occupato, bordo o no). */
.day-row {
  border: 1.5px solid transparent;
}
.day-row.day-leader {
  border-color: var(--peach);
  box-shadow: 0 2px 10px rgba(255, 122, 41, 0.16);
}

/* "Chi c'è per ogni giorno" v2 (2026-07-05): fila orizzontale di barre invece
   di righe, per non sembrare identica ai chip di "quando sei disponibile".
   Ogni barra sale in base a quante persone ci sono quel giorno; toccandola
   si apre un fumetto sopra con i nomi (vedi bindDayBars in evento.html).
   v3 (2026-07-05, stesso giorno): invece di andare a capo con tanti giorni,
   la fila scorre in orizzontale (drag/swipe, vedi bindDayBarsScroll) — quanti
   giorni stanno affiancati dipende solo dalla larghezza dello schermo. */
.day-bars-hint {
  font-size: 11.5px;
  color: var(--ink-soft);
  margin: -4px 2px 10px;
}

/* overflow-x:auto + overflow-y:visible NON esiste davvero per le specifiche
   CSS: se un asse non è "visible" l'altro viene silenziosamente forzato ad
   "auto" comunque, quindi il fumetto (che sporge sopra la barra con
   position:absolute) veniva tagliato dal bordo del contenitore invece di
   restare visibile — bug notato da Fil il 2026-07-05 su desktop ("si vede
   solo una sfumatura, non si legge nulla"). Fix: non provarci nemmeno,
   riservare invece dello spazio vero sopra le barre con padding-top, così il
   fumetto ci sta dentro senza bisogno di uscire dal contenitore. */
.day-bars-scroll {
  overflow-x: auto;
  overflow-y: auto;
  padding: 58px 2px 4px;
  margin: 0 -2px;
  cursor: grab;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.day-bars-scroll::-webkit-scrollbar { display: none; }

.day-bars-scroll.dragging { cursor: grabbing; }

.day-bars-row {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  width: max-content;
  padding: 0 2px 10px;
}

.day-bar-col {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: 48px;
  flex: 0 0 auto;
  cursor: pointer;
}

.day-bar-badge {
  display: flex;
  align-items: center;
  gap: 3px;
  background: var(--track-soft);
  border-radius: 999px;
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 600;
  color: var(--ink);
  transition: background 0.2s ease, color 0.2s ease;
}

.day-bar-badge.leader { background: var(--peach-soft); }
.day-bar-badge.selected { background: var(--surface-dark); color: #FFF8F0; }

.day-bar-track {
  width: 38px;
  height: 92px;
  border-radius: 19px;
  background: var(--sky-soft);
  border: 1.5px solid transparent;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
}

.day-bar-track.leader {
  border-color: var(--peach);
  box-shadow: 0 2px 10px rgba(255, 122, 41, 0.22);
}

.day-bar-fill {
  width: 100%;
  border-radius: 19px;
  background: var(--peach);
  transition: height 0.25s ease, background 0.2s ease;
}

.day-bar-fill.selected { background: var(--surface-dark); }

.day-bar-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink);
  text-align: center;
  line-height: 1.3;
}

.day-bar-label .sub {
  font-weight: 400;
  color: var(--ink-soft);
  font-size: 10px;
}

.day-bar-bubble {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-bottom: 9px;
  background: var(--surface-dark);
  color: #FFF8F0;
  font-size: 12px;
  font-weight: 500;
  padding: 8px 12px;
  border-radius: 12px;
  white-space: normal;
  text-align: center;
  max-width: 160px;
  box-shadow: 0 6px 16px rgba(58, 50, 90, 0.28);
  z-index: 2;
}

.day-bar-bubble::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 6px solid var(--ink);
}

/* Bottom nav - capsula flottante "liquid glass", solo icone */
/* "Segnala problema" (Fil, 2026-07-20): bottone temporaneo, iniettato da
   script.js su OGNI pagina (non è nell'HTML di nessuna, vedi
   initReportProblem) -- così per toglierlo un domani basta cancellare
   quella funzione, senza toccare le dieci pagine una per una. Dentro
   .phone (che è position:relative) per restare ancorato al mockup anche
   su desktop, appena sopra la navbar. */
.report-problem-btn {
  position: absolute;
  right: 16px;
  bottom: 96px;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: var(--card);
  box-shadow: 0 6px 18px rgba(58,50,90,0.25);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  z-index: 30;
  cursor: pointer;
}
.report-problem-btn:active { transform: scale(0.92); }

.report-problem-textarea {
  width: 100%;
  min-height: 110px;
  border-radius: 14px;
  border: 1.5px solid rgba(58,50,90,0.14);
  padding: 12px 14px;
  font-family: 'Inter', sans-serif;
  font-size: 14px;
  color: var(--ink);
  resize: vertical;
  box-sizing: border-box;
}

.navbar {
  position: absolute;
  left: 22px;
  right: 22px;
  bottom: 20px;
  height: 64px;
  background: linear-gradient(180deg, rgba(255,255,255,0.75), rgba(255,255,255,0.4));
  backdrop-filter: blur(18px) saturate(180%);
  -webkit-backdrop-filter: blur(18px) saturate(180%);
  border: 1px solid rgba(255,255,255,0.75);
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: space-around;
  padding: 0 6px;
  box-shadow:
    0 18px 40px rgba(58, 50, 90, 0.18),
    0 2px 6px rgba(58, 50, 90, 0.08),
    inset 0 1px 0 rgba(255,255,255,0.9);
  transition: transform 0.2s ease, opacity 0.2s ease;
}

/* Mentre la tastiera e' aperta (vedi initKeyboardAwareNavbar in script.js):
   la navbar scivola giu' e sparisce invece di restare storta a meta' schermo. */
.navbar.navbar-hidden {
  transform: translateY(140%);
  opacity: 0;
  pointer-events: none;
}

/* Pallino che scorre da una tab all'altra, creato via script.js.
   Fil, 2026-07-13: non voleva più un cerchio pieno col bordo netto, ma una
   "nube" sfumata — niente box-shadow/bordo, sfumatura radiale che va a
   trasparente. La larghezza qui sotto è l'unica cosa che conta per il
   centraggio: indicatorTargetX() in script.js legge offsetWidth a runtime,
   quindi cambiare la dimensione non richiede toccare il JS. */
.nav-indicator {
  position: absolute;
  top: 50%;
  left: 0;
  width: 50px;
  height: 50px;
  margin-top: -25px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 122, 41, 0.45) 0%, rgba(255, 122, 41, 0.22) 45%, rgba(255, 122, 41, 0) 72%);
  pointer-events: none;
  transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1);
  z-index: 0;
}

.nav-item {
  flex: 1;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-soft);
  position: relative;
  z-index: 1;
}

.nav-item .icon {
  font-size: 18px;
  width: 42px;
  height: 42px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  position: relative;
  overflow: hidden;
  color: rgba(58, 50, 90, 0.45);
  transition: transform 0.2s ease, color 0.35s ease;
}

.nav-item .icon .ripple {
  background: rgba(58, 50, 90, 0.15);
}

.nav-item.active .icon {
  color: var(--ink);
}

.nav-item:active .icon {
  transform: scale(0.87);
}

/* ===== Animazioni ===== */

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes ripple-anim {
  from { transform: scale(0); opacity: 0.45; }
  to { transform: scale(1); opacity: 0; }
}

@keyframes chipPop {
  0% { transform: scale(1); }
  40% { transform: scale(1.04); }
  100% { transform: scale(1); }
}

/* Il "telaio" del telefono resta sempre fisso: niente fade, niente transform qui. */
.phone {
  /* intenzionalmente statico */
}

/* .screen = header + content. È questo il livello che scorre tra una pagina e l'altra,
   mentre il bordo del telefono (.phone) non si muove mai. */
.screen {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  width: 100%;
  transform: translateX(0);
  opacity: 1;
}

/* Uscita: la schermata corrente scorre via prima di navigare (vedi script.js) */
.screen.slide-out-left {
  transition: transform 0.16s cubic-bezier(0.4, 0, 1, 1), opacity 0.16s ease;
  transform: translateX(-35%);
  opacity: 0;
}

.screen.slide-out-right {
  transition: transform 0.16s cubic-bezier(0.4, 0, 1, 1), opacity 0.16s ease;
  transform: translateX(35%);
  opacity: 0;
}

/* Entrata: posizione di partenza fuori schermo, senza transizione (snap istantaneo) */
.screen.slide-in-from-right {
  transition: none;
  transform: translateX(100%);
  opacity: 0;
}

.screen.slide-in-from-left {
  transition: none;
  transform: translateX(-100%);
  opacity: 0;
}

/* Poi si attiva questa classe un istante dopo, e la transizione la riporta al centro */
.screen.slide-in-active {
  transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.18s ease;
  transform: translateX(0);
  opacity: 1;
}

/* Entrata a cascata per card e notifiche: parte "spenta", script.js accende .in-view */
.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.55s cubic-bezier(0.22, 1, 0.36, 1), transform 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}

.reveal.in-view {
  opacity: 1;
  transform: translateY(0);
}

/* Feedback al tocco/click */
.card,
.primary-btn,
.chip,
.pill,
.settings-row,
.bell,
.back-btn,
.add-date-btn,
.repeat-btn,
.remove-date,
.home-tile,
.info-tile.is-clickable,
.who-coming-tile {
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.2s ease, border-color 0.2s ease;
  position: relative;
  overflow: hidden;
}

.card:active,
.primary-btn:active,
.chip:active,
.pill:active,
.settings-row:active,
.bell:active,
.back-btn:active,
.add-date-btn:active,
.repeat-btn:active,
.home-tile:active,
.info-tile.is-clickable:active,
.who-coming-tile:active {
  transform: scale(0.97);
}

/* Ripple: cerchio generato via JS al click */
.ripple {
  position: absolute;
  border-radius: 50%;
  background: rgba(255,255,255,0.55);
  transform: scale(0);
  pointer-events: none;
  animation: ripple-anim 0.6s ease-out;
}

.card .ripple,
.settings-row .ripple {
  background: rgba(58,50,90,0.08);
}

/* Barra di progresso animata (il riempimento parte da 0, vedi script.js) */
.progress-fill {
  transition: width 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}

.count-up {
  display: inline-block;
  min-width: 0.6em;
}

/* Chip: transizione morbida su selezione + piccolo "pop" */
.chip-check {
  transition: background 0.25s ease, color 0.25s ease, transform 0.25s ease;
}

.chip.selected .chip-check {
  animation: fadeIn 0.25s ease;
}

.chip.pop {
  animation: chipPop 0.26s ease;
}

/* Confetti: canvas overlay sopra il contenuto, sotto la navbar */
.confetti-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 5;
}

/* Popup "crea il tuo profilo": mostrato in Home solo a chi non ha ancora un
   profilo, per invogliare alla registrazione senza obbligarla. Stesso
   componente riusato per OGNI popup dell'app (gestione lista amici, "Chi
   viene", spese, modifica disponibilità...). z-index sopra a.back-btn
   (30): la bolla "torna indietro" restava sopra questi popup invece di
   sparire sotto, capitava di vederla sovrapposta a pulsanti/testo del
   popup quando questo arrivava vicino al suo angolo in basso a sinistra
   (Fil, 2026-08-24: "finisce ogni tanto sovrapposto a tasti o scritte"). */
.signup-overlay {
  position: absolute;
  inset: 0;
  background: rgba(61, 34, 68, 0.55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
  padding: 20px;
}

.signup-modal {
  background: var(--card);
  border-radius: 26px;
  padding: 28px 22px 22px;
  width: 100%;
  max-width: 350px;
  box-shadow: 0 20px 50px rgba(58, 50, 90, 0.28);
  text-align: center;
  animation: signupModalIn 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

@keyframes signupModalIn {
  from { transform: translateY(24px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

.signup-modal-icon {
  font-size: 34px;
  margin-bottom: 8px;
}

.signup-modal-title {
  font-family: 'Fraunces', serif;
  font-size: 19px;
  font-weight: 600;
  margin-bottom: 8px;
}

.signup-modal-text {
  font-size: 13px;
  color: var(--ink-soft);
  line-height: 1.45;
  margin-bottom: 20px;
}

.signup-skip-link {
  display: inline-block;
  margin-top: 14px;
  font-size: 12px;
  color: var(--ink-soft);
  text-decoration: underline;
  cursor: pointer;
}

/* Popup dal basso (toast), tipo "sei stato aggiunto come Marco alla lista di Fil":
   compare da sotto la navbar, resta qualche secondo e scompare da solo.
   window.NdumaUI.toast(messaggio) in script.js lo gestisce. */
.toast {
  position: absolute;
  left: 22px;
  right: 22px;
  bottom: 96px;
  background: var(--surface-dark);
  color: #FFF8F0;
  padding: 14px 18px;
  border-radius: 16px;
  font-size: 13.5px;
  font-weight: 500;
  text-align: center;
  line-height: 1.4;
  box-shadow: 0 10px 26px rgba(58, 50, 90, 0.28);
  z-index: 30;
  opacity: 0;
  transform: translateY(20px);
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.3s ease;
  pointer-events: none;
}

.toast.show {
  opacity: 1;
  transform: translateY(0);
}

/* Bolla "nuova notifica" che scende dall'alto quando sei su una schermata
   diversa dalla Home (Fil, 2026-08-24: sulla Home ci pensa già il badge
   presenza). window.showGlobalNotifBanner in script.js la crea/rimuove;
   dentro .phone (come .toast qui sopra) per restare agganciata al bordo
   arrotondato e tagliata pulita dall'overflow:hidden mentre sta "fuori". */
.notif-banner {
  position: absolute;
  left: 14px;
  right: 14px;
  top: 0;
  margin-top: calc(10px + env(safe-area-inset-top, 0px));
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface-dark);
  color: #FFF8F0;
  padding: 12px 16px;
  border-radius: 16px;
  box-shadow: 0 14px 30px rgba(58, 50, 90, 0.3);
  z-index: 60;
  opacity: 0;
  transform: translateY(-140%);
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.3s ease;
  text-decoration: none;
}

.notif-banner.show {
  opacity: 1;
  transform: translateY(0);
}

.notif-banner-dot {
  flex-shrink: 0;
  font-size: 15px;
}

/* min-width:0 necessario perché overflow/text-overflow valgano qualcosa su
   un figlio flex — stesso motivo di .header-title più sopra. */
.notif-banner-text {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.35;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Splash screen alla prima apertura del sito (una volta per sessione, vedi
   initSplashScreen in script.js + il piccolo script inline in cima a ogni
   pagina che la nasconde subito, senza flash, quando è già stata mostrata). */
.splash-screen {
  position: fixed;
  inset: 0;
  background: #fff;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.35s ease;
}

.splash-screen.splash-hidden {
  opacity: 0;
  pointer-events: none;
}

/* Banner "aggiungi alla schermata Home" per iPhone/iPad (vedi initIosInstallHint
   in script.js): iOS non ha un banner di installazione automatico come Android/
   Chrome, quindi ne mostriamo uno nostro, solo in Home, solo se non già chiuso. */
.install-hint {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--lavender-soft);
  color: var(--ink);
  border-radius: 16px;
  padding: 12px 14px;
  margin-bottom: 14px;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.4;
}

.install-hint .dismiss {
  cursor: pointer;
  opacity: 0.55;
  font-size: 13px;
  flex-shrink: 0;
  padding: 2px 4px;
}

.install-hint .dismiss:active { opacity: 1; }

.splash-logo {
  width: 108px;
  height: auto;
  filter: drop-shadow(0 10px 22px rgba(58, 50, 90, 0.22));
}

/* ---------- evento confermato/passato: card "Quando" + bolle "Chi ci sarà" ----------
   Fil, 2026-07-07: sostituisce la quota/barre-per-giorno una volta chiusa la
   fase di risposta, con qualcosa di più a tema invece di due righe di testo. */
.confirmed-date-card {
  display: flex;
  align-items: center;
  gap: 14px;
  border-radius: 20px;
  padding: 16px 18px;
  margin: 0 2px 22px;
  box-shadow: 0 4px 16px rgba(58,50,90,0.06);
  background: var(--mint-soft);
}

.confirmed-date-card.passato { background: var(--past-soft); }
/* Non ancora certa (Fil, 2026-08-23): stessa card di quella confermata,
   ma grigio neutro invece di pesca — a colpo d'occhio si deve capire che
   è ancora provvisoria, non la stessa cosa di un evento davvero deciso. */
.confirmed-date-card.is-leading { background: var(--track-soft); }

.confirmed-date-icon {
  width: 44px;
  height: 44px;
  border-radius: 14px;
  background: rgba(255,255,255,0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  flex-shrink: 0;
}

.confirmed-date-label {
  font-size: 11px;
  color: var(--ink-soft);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.confirmed-date-value {
  font-family: 'Fraunces', serif;
  font-size: 18px;
  font-weight: 700;
  color: var(--ink);
  margin-top: 2px;
}

/* "Tocca la data per aggiungerla al calendario" (Fil, 2026-07-20). */
.confirmed-date-add-cal {
  font-size: 11.5px;
  color: var(--lavender);
  font-weight: 600;
  margin-top: 4px;
}

.attendee-bubbles {
  display: flex;
  flex-wrap: wrap;
  gap: 16px 14px;
  padding: 4px 2px 8px;
}

.attendee-bubble {
  width: 62px;
  text-align: center;
}

.attendee-bubble-circle {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Fraunces', serif;
  font-weight: 600;
  font-size: 18px;
  color: #fff;
  background: var(--peach);
  box-shadow: 0 4px 12px rgba(58, 50, 90, 0.15);
  overflow: hidden;
}

.attendee-bubble-circle img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.attendee-bubble-name {
  font-size: 11px;
  color: var(--ink-soft);
  font-weight: 500;
  margin-top: 6px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- Spese (stile Tricount), dentro evento.html — Fil, 2026-07-13 ----------
   Iterazione 2026-07-13 dopo il giro di mockup con Fil: niente bustina di
   soldi nell'intestazione, tutto chiuso in un accordion per non essere
   invadente in pagina, emoji facoltativa per spesa, conto e conguagli
   ridisegnati come pillole/frasi invece di righe di solo testo colorato. */
.expense-accordion { margin-bottom: 4px; }

.expense-accordion-header {
  background: var(--card);
  border-radius: 16px;
  padding: 12px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
}

.expense-accordion-titles { flex: 1; min-width: 0; }

.expense-accordion-title {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
}

.expense-accordion-subtitle {
  font-size: 11.5px;
  color: var(--ink-soft);
  margin-top: 1px;
}

.expense-accordion-chevron {
  font-size: 13px;
  color: var(--ink-soft);
  transition: transform 0.2s ease;
  flex-shrink: 0;
}

.expense-accordion-chevron.open { transform: rotate(180deg); }

.expense-accordion-body {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.25s ease;
}

.expense-accordion-body.open { max-height: 2000px; }

.expense-accordion-inner {
  background: var(--card);
  border-radius: 16px;
  padding: 6px 14px 14px;
  margin-top: 8px;
}

.expense-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 0;
  border-bottom: 0.5px solid rgba(58,50,90,0.08);
  gap: 10px;
}

.expense-row:last-of-type { border-bottom: none; }

.expense-row-left {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.expense-emoji-chip {
  width: 30px;
  height: 30px;
  border-radius: 10px;
  background: var(--peach-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  flex-shrink: 0;
}

.expense-desc {
  font-size: 13.5px;
  color: var(--ink);
  font-weight: 500;
}

.expense-meta {
  font-size: 11.5px;
  color: var(--ink-soft);
  margin-top: 1px;
}

.expense-row-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

.expense-amount {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}

.expense-actions {
  display: flex;
  gap: 8px;
  font-size: 13px;
  color: var(--ink-soft);
}

/* "Chi porta cosa" ridisegnata a checklist (Fil, 2026-07-25): tocchi la
   riga per prendere/liberare la voce, scorri a sinistra per eliminarla.
   Lo scroll orizzontale nativo con snap fa il lavoro dello swipe senza
   codice di drag a mano: .item-swipe-wrap scorre esattamente della
   larghezza del cestino (flex 0 0 100% + flex 0 0 64px) e si ferma sui
   due punti di snap. */
.item-swipe-wrap {
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.item-swipe-wrap::-webkit-scrollbar { display: none; }

.item-row-card {
  flex: 0 0 100%;
  scroll-snap-align: start;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 4px;
  border-bottom: 0.5px solid rgba(58,50,90,0.08);
  cursor: pointer;
}

.item-row-card.not-tappable {
  cursor: default;
}

.item-swipe-trash {
  flex: 0 0 64px;
  scroll-snap-align: end;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--cancel);
  color: #fff;
  cursor: pointer;
}

.item-row-check {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  color: #fff;
  border: 2px solid rgba(58,50,90,0.22);
  background: transparent;
  overflow: hidden;
}

.item-row-check.taken {
  border: none;
  background: var(--lavender);
}

/* Rimbalzo quando prendi/liberi una voce (Fil, 2026-07-25): stessa curva
   "a molla" già usata per welcomeAvatarPop, senza la rotazione (troppo per
   un pallino così piccolo e ripetuto in lista). */
@keyframes itemCheckPop {
  0% { transform: scale(0.4); opacity: 0.4; }
  60% { transform: scale(1.18); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

.item-row-check.pop-in {
  animation: itemCheckPop 0.32s cubic-bezier(.34, 1.56, .64, 1) both;
}

.item-row-check img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.item-row-text {
  min-width: 0;
}

.item-row-title {
  font-size: 13.5px;
  color: var(--ink);
  font-weight: 500;
}

.item-row-meta {
  font-size: 11.5px;
  color: var(--ink-soft);
  margin-top: 1px;
}

.balance-pill-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 4px;
}

.balance-pill-row {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--bg);
  border-radius: 12px;
  padding: 7px 10px;
}

.balance-pill-avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--peach-soft);
  color: var(--ink);
  font-size: 10.5px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  overflow: hidden;
}

.balance-pill-avatar img,
.settlement-sentence-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.balance-pill-name {
  flex: 1;
  font-size: 12.5px;
  color: var(--ink);
  min-width: 0;
}

.balance-pill-amount {
  font-size: 12px;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 8px;
  white-space: nowrap;
}

.balance-pill-amount-positive { color: #1D6B47; background: #E4F3EA; }
.balance-pill-amount-negative { color: var(--cancel); background: var(--cancel-soft); }
.balance-pill-amount-neutral { color: var(--ink-soft); background: var(--past-soft); }

.settlement-sentence-row {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--lavender-soft);
  border-radius: 12px;
  padding: 10px 12px;
  margin-bottom: 6px;
}

.settlement-sentence-avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--card);
  color: var(--lavender);
  font-size: 10.5px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  overflow: hidden;
}

.settlement-sentence-text {
  font-size: 12.5px;
  color: var(--lavender);
  line-height: 1.4;
}

/* ---------- riga emoji nel modale "Nuova/Modifica spesa" ---------- */
.expense-desc-row {
  display: flex;
  gap: 8px;
  align-items: center;
}

.emoji-slot {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: var(--peach-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  cursor: pointer;
}

.emoji-slot-placeholder { color: var(--ink); opacity: 0.4; }

.emoji-slot-chosen { font-size: 20px; }

.expense-desc-row input#expenseDescInput {
  flex: 1;
  min-width: 0;
}

.emoji-picker {
  display: flex;
  gap: 8px;
  margin: 8px 0 4px;
}

.emoji-choice {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: var(--card);
  border: 0.5px solid rgba(58,50,90,0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  cursor: pointer;
}

/* ---------- header: menu a 3 puntini (Modifica/Elimina) ---------- */
.header-menu-wrap { position: relative; margin-left: auto; }

.menu-dropdown {
  position: absolute;
  top: 44px;
  right: 0;
  min-width: 168px;
  max-width: 240px;
  background: var(--card);
  border-radius: 16px;
  box-shadow: 0 10px 26px rgba(58,50,90,0.22);
  overflow: hidden;
  z-index: 40;
  /* Fil, 2026-07-22: prima si mostrava/nascondeva con display:none, che non
     si può animare — un tocco e comparivano di scatto. transform-origin
     nell'angolo da cui "esce" (sotto i 3 puntini in alto a destra), scala +
     dissolvenza, coerente con le altre piccole animazioni dell'app. */
  transform-origin: top right;
  transform: scale(0.9);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: transform 0.16s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.14s ease, visibility 0s linear 0.16s;
}

.menu-dropdown.open {
  transform: scale(1);
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: transform 0.18s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.16s ease;
}

.menu-dropdown-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 13px 16px;
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.35; /* per quando il testo va comunque a capo: prima era troppo stretto */
  color: var(--ink);
  cursor: pointer;
  text-decoration: none;
}

.menu-dropdown-item + .menu-dropdown-item { border-top: 1px solid rgba(58,50,90,0.06); }

.menu-dropdown-item.danger { color: var(--cancel); }

.menu-dropdown-item:active { background: var(--mint-soft); }

/* ---------- suggerimenti account (username + foto) su un input ---------- */
.account-search-dropdown {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  max-height: 220px;
  overflow-y: auto;
  background: var(--card);
  border-radius: 14px;
  box-shadow: 0 10px 26px rgba(58,50,90,0.22);
  z-index: 40;
}

.account-search-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
}

.account-search-item + .account-search-item { border-top: 1px solid rgba(58,50,90,0.06); }

.account-search-item:active { background: var(--mint-soft); }

.account-search-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Fraunces', serif;
  font-weight: 600;
  font-size: 13px;
  color: #fff;
  background: var(--peach);
  overflow: hidden;
}

.account-search-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Anellino di caricamento mentre la ricerca account è in corso (Fil,
   2026-07-19) — stesso riquadro .account-search-dropdown, solo contenuto
   diverso finché non arrivano i risultati veri. */
.account-search-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}

.account-search-spinner {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid var(--past-soft);
  border-top-color: var(--peach);
  animation: accountSearchSpin 0.7s linear infinite;
}

@keyframes accountSearchSpin {
  to { transform: rotate(360deg); }
}

.account-search-empty {
  padding: 14px 16px;
  font-size: 12.5px;
  color: var(--ink-soft);
  text-align: center;
}

/* ---------- foto evento a schermo intero (Fil, 2026-07-10) ----------
   Tocco sulla copertina dell'evento apre questo overlay, tocco ovunque sopra
   (immagine inclusa) lo richiude: niente pulsante di chiusura dedicato,
   coerente con lo stile "niente ✕" già scelto altrove nell'app. */
.photo-lightbox {
  position: fixed;
  inset: 0;
  background: rgba(20, 12, 24, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 999;
  cursor: zoom-out;
  animation: photoLightboxIn 0.15s ease;
}

.photo-lightbox img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 14px;
  object-fit: contain;
}

@keyframes photoLightboxIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ---------- schermata di benvenuto dopo la registrazione ----------
   Fil, 2026-07-12: "stupiscimi" — avatar che entra con un piccolo rimbalzo,
   titolo/sottotitolo/bottone che salgono a cascata uno dopo l'altro, e una
   manciata di coriandoli che cadono dall'alto con i colori della palette
   dell'app (nessuna libreria esterna, solo div generati al volo). */

.welcome-avatar-pop {
  animation: welcomeAvatarPop 0.7s cubic-bezier(.34, 1.56, .64, 1) both;
}

@keyframes welcomeAvatarPop {
  0%   { transform: scale(0) rotate(-8deg); opacity: 0; }
  60%  { transform: scale(1.12) rotate(4deg); opacity: 1; }
  100% { transform: scale(1) rotate(0deg); opacity: 1; }
}

.welcome-fade-up {
  opacity: 0;
  animation: welcomeFadeUp 0.55s ease both;
}

@keyframes welcomeFadeUp {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Coriandoli: contenitore a schermo intero, sopra tutto (anche sopra la
   cornice "phone"), rimosso da solo dal JS a animazione finita. */
.confetti-overlay {
  position: fixed;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 9999;
}

.confetti-piece {
  position: absolute;
  top: -24px;
  width: 8px;
  height: 14px;
  opacity: 0.95;
  animation-name: confettiFall;
  animation-timing-function: cubic-bezier(.35, 0, .65, 1);
  animation-fill-mode: forwards;
}

.confetti-piece.round { border-radius: 50%; }

@keyframes confettiFall {
  0%   { transform: translateY(0) rotate(0deg); opacity: 1; }
  85%  { opacity: 1; }
  100% { transform: translateY(115vh) rotate(540deg); opacity: 0; }
}

/* ---------- Home: riquadri per categoria (2026-08-22) ----------
   Sostituiscono il feed unico "Ultime proposte + Organizzazione chiusa":
   ogni riquadro porta a eventi.html?only=... (vedi lì), una pagina per
   categoria sola, niente tab dentro. Colori a blocco pieno, le due
   famiglie già previste in cima a questo file (peach/lavender) invece di
   inventarne di nuove. */
.home-grid {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  grid-template-rows: auto auto;
  gap: 10px;
  margin: 4px 16px 24px;
}

.home-tile {
  border-radius: 22px;
  padding: 18px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  text-decoration: none;
  position: relative;
  overflow: hidden;
}

.home-tile.is-big { grid-row: 1 / 3; min-height: 210px; background: var(--peach); padding: 22px; }
/* Verde per "Confermati" (Fil, 2026-08-23), non più lavanda — si legge a
   colpo d'occhio molto meglio, e lo stesso colore ora vale ovunque
   compaia "confermato" (vedi .card.is-done/.badge.done in cima al file). */
.home-tile.is-mid { min-height: 100px; background: var(--confirmed); }
/* Rosso smorzato per "Annullati" (Fil, 2026-08-23), non più neutro senza
   colore — stessa logica di "Confermati" qui sopra: un colore, coerente
   ovunque significhi "annullato" (vedi .card.is-cancelled/.badge.cancelled
   in cima al file). */
.home-tile.is-cancel { min-height: 100px; background: var(--cancel); }

/* Riga d'azione in cima: crea/amici, sempre le due cose che altrimenti
   stavano nella navbar (Fil, 2026-08-22 — navbar tolta del tutto, si torna
   alla Home per tutto il resto). Spostata sopra i riquadri di stato evento
   e resa più grande/pesante: sono le due azioni primarie della Home, non
   un'appendice — vanno lette per prime, con un peso visivo vicino a quello
   del riquadro grande sotto. */
/* Fil, 2026-08-24: stessa distanza di .home-events-title sotto (28px resi
   a schermo) tra l'header e queste tile, quanto tra "I tuoi eventi" e le
   sue. */
.home-grid-actions { grid-template-columns: 1fr 1fr; grid-template-rows: none; margin-top: 24px; }
.home-tile.is-action { min-height: 128px; background: var(--surface-dark); flex-direction: column; justify-content: flex-end; align-items: flex-start; gap: 0; padding: 20px; }
.home-tile.is-action .home-tile-icon { stroke: #fff; width: 26px; height: 26px; margin-bottom: 12px; }
.home-tile.is-action .home-tile-label { color: #fff; font-size: 16px; font-weight: 600; margin-top: 0; }

/* Etichetta sopra i riquadri di stato evento (Fil, 2026-08-23: "Da
   confermare" da solo non si capiva cosa fosse) — porta con sé anche lo
   stacco dal gruppo di azioni sopra (poco: bastano per leggersi come due
   cose diverse, non un confine netto). */
/* Fil, 2026-08-24: prima lo spazio in più era sopra l'etichetta — voleva
   invece più stacco QUI, tra l'etichetta e i riquadri sotto ("fare
   scendere i riquadri... tra la scritta e i riquadri"). */
.home-events-title { margin: 46px 16px 28px; font-size: 20px; }

.home-tile-icon { width: 24px; height: 24px; }
.home-tile.is-big .home-tile-icon { width: 25px; height: 25px; }
.home-tile.is-big .home-tile-icon, .home-tile.is-mid .home-tile-icon, .home-tile.is-cancel .home-tile-icon { stroke: #fff; }

.home-tile-num {
  font-family: 'Fraunces', serif;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.home-tile.is-big .home-tile-num { font-size: 40px; color: #fff; margin-top: 12px; }
.home-tile.is-mid .home-tile-num, .home-tile.is-cancel .home-tile-num { font-size: 26px; margin-top: 2px; color: #fff; }

.home-tile-label { font-size: 13px; font-weight: 500; margin-top: 3px; }
.home-tile.is-big .home-tile-label { color: rgba(255,255,255,0.85); font-size: 15px; }
.home-tile.is-mid .home-tile-label, .home-tile.is-cancel .home-tile-label { color: rgba(255,255,255,0.72); }

.home-tile-deco {
  position: absolute; right: -18px; bottom: -18px; width: 78px; height: 78px;
  border-radius: 50%; background: rgba(255,255,255,0.14);
}
/* Stessa bolla, più piccola, sulle altre card (Fil, 2026-08-23: gli piace
   quella del riquadro grande, la vuole anche sugli altri) — non tutte
   nello stesso punto, sembrava meccanico (Fil, secondo giro), e non
   sempre incastrata proprio nell'angolo (terzo giro: "anche non
   perforza nell'angolo"). Restano sul lato destro, mai a sinistra: icona
   e numero/testo sono sempre allineati a sinistra in ogni riquadro, una
   bolla lì ci finirebbe sopra. */
.home-tile-deco.is-small {
  width: 44px; height: 44px; right: -10px; bottom: -10px;
}
.home-tile-deco.is-small.pos-tr {
  bottom: auto; top: -8px; right: -6px;
}
/* Non in un angolo: appoggiata sul bordo destro, centrata in verticale. */
.home-tile-deco.is-small.pos-mr {
  bottom: auto; top: 50%; right: -16px;
  width: 38px; height: 38px;
  margin-top: -19px;
}
