/**
 * Design System v3.0 - Layout e struttura
 *
 * Guscio dell'app, testata, navigazione a tab, e soprattutto .section: il
 * contenitore che ogni sezione di ogni tab usa, con la stessa anatomia di
 * intestazione. E' il pezzo che risolve il "sembra tutto appiccicato": oggi
 * ogni feature ha inventato il proprio header (.sleep-header, .steps-header,
 * .glucose-history-header...) e nessuno di questi combacia con gli altri.
 *
 * Richiede design-tokens.css e ds-base.css.
 */

/* ===========================================
   TINTA DI SEZIONE
   ===========================================
   Il meccanismo che tiene insieme "coerente" e "non monotono": la struttura e
   le distanze sono identiche ovunque, cambia solo la tinta locale, dichiarata
   con un attributo sull'elemento contenitore.

     <section class="section" data-metric="sleep">

   Tutto cio' che sta dentro legge --metric-*, quindi nessun componente ha
   bisogno di una variante per metrica. Senza attributo si usa il brand. */
[data-metric] {
  --metric-surface: var(--brand-50);
  --metric-border: var(--brand-300);
  --metric: var(--brand-600);
  --metric-text: var(--brand-700);
}
[data-metric="weight"] {
  --metric-surface: var(--m-weight-surface);
  --metric-border: var(--m-weight-border);
  --metric: var(--m-weight);
  --metric-text: var(--m-weight-text);
}
[data-metric="heart"] {
  --metric-surface: var(--m-heart-surface);
  --metric-border: var(--m-heart-border);
  --metric: var(--m-heart);
  --metric-text: var(--m-heart-text);
}
[data-metric="glucose"] {
  --metric-surface: var(--m-glucose-surface);
  --metric-border: var(--m-glucose-border);
  --metric: var(--m-glucose);
  --metric-text: var(--m-glucose-text);
}
[data-metric="pressure"] {
  --metric-surface: var(--m-pressure-surface);
  --metric-border: var(--m-pressure-border);
  --metric: var(--m-pressure);
  --metric-text: var(--m-pressure-text);
}
[data-metric="sleep"] {
  --metric-surface: var(--m-sleep-surface);
  --metric-border: var(--m-sleep-border);
  --metric: var(--m-sleep);
  --metric-text: var(--m-sleep-text);
}
[data-metric="medicine"] {
  --metric-surface: var(--m-medicine-surface);
  --metric-border: var(--m-medicine-border);
  --metric: var(--m-medicine);
  --metric-text: var(--m-medicine-text);
}
[data-metric="water"] {
  --metric-surface: var(--m-water-surface);
  --metric-border: var(--m-water-border);
  --metric: var(--m-water);
  --metric-text: var(--m-water-text);
}
[data-metric="steps"] {
  --metric-surface: var(--m-steps-surface);
  --metric-border: var(--m-steps-border);
  --metric: var(--m-steps);
  --metric-text: var(--m-steps-text);
}
[data-metric="calories"] {
  --metric-surface: var(--m-calories-surface);
  --metric-border: var(--m-calories-border);
  --metric: var(--m-calories);
  --metric-text: var(--m-calories-text);
}
[data-metric="workout"] {
  --metric-surface: var(--ink-100);
  --metric-border: var(--ink-300);
  --metric: var(--ink-700);
  --metric-text: var(--ink-800);
}

/* ===========================================
   GUSCIO
   =========================================== */
.app-shell {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  background-color: var(--surface-page);
}

.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-4);
}

.container--narrow {
  max-width: var(--container-narrow);
}

/* Il contenuto di un tab: la spaziatura fra sezioni sta QUI e in nessun altro
   posto, cosi riordinare le sezioni non cambia il ritmo verticale. */
.tab-panel {
  display: flex;
  flex-direction: column;
  gap: var(--gap-section);
  padding-block: var(--space-6) var(--space-12);
}

/* Sotto la tabbar inferiore su mobile serve aria, o l'ultima sezione ci finisce
   sotto. */
@media (max-width: 768px) {
  .tab-panel {
    padding-bottom: calc(var(--tabbar-height-mobile) + var(--space-8));
  }
}

/* ===========================================
   TESTATA
   ===========================================
   L'unico posto in tutta l'app dove compare il gradiente di brand, e ripercorre
   il logo: navy -> teal. */
/* Il colore pieno sta sotto la sfumatura, non e' ridondante: se il gradiente
   non renderizza la testata resta scura invece di diventare bianca con sopra
   testo bianco. E' anche il valore che gli strumenti di misura del contrasto
   riescono a leggere, dato che su un fondo sfumato risalgono al primo colore
   pieno che trovano. */
.app-header {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background-color: var(--ink-900);
  background-image: var(--gradient-brand);
  color: var(--fg-on-solid);
  box-shadow: var(--elevation-2);
}

.app-header__inner {
  display: flex;
  align-items: center;
  gap: var(--gap-control);
  min-height: var(--header-height);
}

.app-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline);
  margin-right: auto;
  min-width: 0;
}

.app-brand__mark {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: var(--radius-sm);
}

.app-brand__name {
  font-size: var(--type-h3-size);
  font-weight: var(--font-extrabold);
  letter-spacing: var(--tracking-tight);
  color: var(--fg-on-solid);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.app-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* Il saluto cede spazio prima di tutto il resto: fra un nome lungo e il
   bottone per uscire, quello che deve restare intero e' il bottone. */
.app-header__user {
  min-width: 0;
  font-size: var(--type-small-size);
  font-weight: var(--font-medium);
  color: var(--fg-on-solid);
  opacity: 0.92;
}

.app-header .user-profile-section {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

/* La riga di stato sta sotto la testata, sulla stessa superficie scura. */
.sync-status {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-bottom: var(--space-2);
  font-size: var(--type-caption-size);
  color: var(--fg-on-solid);
  opacity: 0.85;
}

.sync-status .status-indicator {
  width: 8px;
  height: 8px;
  flex-shrink: 0;
  border-radius: var(--radius-full);
  background-color: var(--growth-400);
}

.sync-status .status-indicator.syncing {
  background-color: var(--accent-300);
  animation: ds-pulse 1.4s ease-in-out infinite;
}

.sync-status .status-indicator.offline,
.sync-status .status-indicator.error {
  background-color: var(--danger-border);
}

@keyframes ds-pulse {
  50% {
    opacity: 0.35;
  }
}

/* Sotto i 640px il saluto sparisce: l'icona del profilo dice gia' chi sei, e
   quello spazio serve ai comandi. */
@media (max-width: 640px) {
  .app-header__user {
    display: none;
  }
}

/* Sul gradiente scuro l'anello di focus chiaro e' l'unico leggibile. */
.app-header :focus-visible {
  box-shadow: var(--focus-ring-inverse);
}

/* I bottoni dentro la testata girano su fondo scuro: i toni chiari di
   ds-controls li' sarebbero illeggibili. Il sistema li ridefinisce qui invece
   di lasciare che ogni chiamante ci metta un color:#fff inline - che e'
   esattamente il tipo di correzione locale che produce la divergenza fra una
   schermata e l'altra. */
.app-header .btn--ghost {
  color: var(--fg-on-solid);
}

/* Tinte piene e non bianco semitrasparente: un fondo traslucido cambia
   contrasto lungo la sfumatura e nessuno strumento riesce a misurarlo, quindi
   una regressione li non verrebbe vista da nessun gate. I due gradini scelti
   stanno a 9.13:1 e 6.61:1 sotto testo bianco. */
.app-header .btn--ghost:hover:not(:disabled) {
  background-color: var(--brand-800);
  color: var(--fg-on-solid);
}

.app-header .btn--secondary {
  background-color: var(--brand-800);
  border-color: var(--brand-400);
  color: var(--fg-on-solid);
}

.app-header .btn--secondary:hover:not(:disabled) {
  background-color: var(--brand-700);
  border-color: var(--brand-300);
  color: var(--fg-on-solid);
}

@media (max-width: 640px) {
  .app-brand__name {
    font-size: var(--type-h4-size);
  }
}

/* ===========================================
   NAVIGAZIONE A TAB
   =========================================== */
.app-tabs {
  display: flex;
  gap: var(--space-1);
  overflow-x: auto;
  scrollbar-width: none;
  background-color: var(--surface-card);
  border-bottom: 1px solid var(--border-subtle);
}

.app-tabs::-webkit-scrollbar {
  display: none;
}

.app-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--gap-inline);
  flex: 1 0 auto;
  min-height: var(--tabbar-height);
  padding: var(--space-2) var(--space-4);
  font-size: var(--type-small-size);
  font-weight: var(--font-semibold);
  color: var(--fg-subtle);
  white-space: nowrap;
  border-bottom: 3px solid transparent;
  transition: var(--transition-colors);
}

.app-tab:hover {
  color: var(--fg-brand);
  background-color: var(--brand-50);
}

.app-tab.active,
.app-tab[aria-selected="true"] {
  color: var(--fg-brand);
  border-bottom-color: var(--brand-600);
}

.app-tab .tab-icon {
  font-size: 1.15em;
  line-height: 1;
}

/* Barra inferiore. NON e' una tabbar fissa: l'app la duplica dentro ogni
   pannello, una copia per tab, e `tab-sections-preferences.js` la cerca per
   nome (`.app-tabs-bottom`) per tenerla in fondo quando riordina le sezioni.
   Ancorarla al viewport produrrebbe sei barre sovrapposte, una per copia.
   Resta quindi nel flusso, e l'unica differenza dalla barra in testa e' che il
   bordo attivo sta sopra invece che sotto. */
.app-tabs-bottom {
  margin-top: var(--gap-section);
  border-top: 1px solid var(--border-subtle);
  border-bottom: none;
}

.app-tabs-bottom .app-tab {
  border-bottom: none;
  border-top: 3px solid transparent;
}

.app-tabs-bottom .app-tab.active,
.app-tabs-bottom .app-tab[aria-selected="true"] {
  border-top-color: var(--brand-600);
}

@media (max-width: 640px) {
  /* Sotto i 640px l'etichetta scende sotto l'icona: sei destinazioni in riga
     non entrano, e troncarle lascerebbe sei parole mozze. */
  .app-tabs-bottom .app-tab,
  .app-tabs .app-tab {
    flex: 1 1 0;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    padding-inline: var(--space-1);
    font-size: var(--text-2xs);
  }

  .app-tab > span:not(.tab-icon) {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

/* ===========================================
   SEZIONE
   ===========================================
   Il contenitore di ogni sezione di ogni tab. Sempre questa anatomia:

     .section > .section-header ( .section-icon
                                  .section-heading ( .section-title
                                                     .section-subtitle )
                                  .section-actions )
              > .section-body

   Il sottotitolo sta accanto al titolo in colonna, non dentro di esso: dentro
   diventerebbe un elemento della riga flex e a 375px si schiaccerebbe in una
   colonna di due parole fra il titolo e i bottoni.
   Nessuna feature dichiara piu il proprio header. */
.section {
  /* padding e margin a zero: le distanze le danno .section-header e
     .section-body. Le classi legacy che una sezione conserva portano quasi
     tutte un padding proprio, che incasserebbe il filo di tinta e
     raddoppierebbe i margini fra una sezione e l'altra. */
  padding: 0;
  margin: 0;
  background-color: var(--surface-card);
  border: var(--card-border);
  border-radius: var(--card-radius);
  box-shadow: var(--card-shadow);
  overflow: hidden; /* tiene il filo di tinta dentro il raggio */
}

/* Il filo di tinta in cima e' l'unico segno che distingue una sezione
   dall'altra: identifica senza colorare l'intera superficie (l'accento resta
   sotto il 5% del viewport). */
.section::before {
  content: "";
  display: block;
  height: 3px;
  background-color: var(--metric, var(--brand-600));
}

.section-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap-control);
  padding: var(--space-4) var(--card-padding);
  border-bottom: 1px solid var(--border-subtle);
}

/* Titolo e sottotitolo in colonna. min-width:0 perche' un titolo lungo deve
   poter accorciarsi invece di spingere fuori le azioni. */
.section-heading {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  margin-right: auto;
}

.section-title {
  display: block;
  min-width: 0;
  font-size: var(--type-h2-size);
  font-weight: var(--font-bold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--fg-heading);
  overflow-wrap: anywhere;
}

/* L'icona sta in una pastiglia della tinta di sezione: e' cosi che la sezione
   si riconosce a colpo d'occhio senza cambiare struttura. */
.section-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  font-size: var(--text-lg);
  line-height: 1;
  border-radius: var(--radius-md);
  background-color: var(--metric-surface, var(--brand-50));
  color: var(--metric-text, var(--brand-700));
}

.section-subtitle {
  display: block;
  margin-top: 2px;
  font-size: var(--type-small-size);
  font-weight: var(--font-regular);
  line-height: var(--leading-snug);
  color: var(--fg-subtle);
}

.section-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

.section-body {
  display: flex;
  flex-direction: column;
  gap: var(--gap-block);
  padding: var(--card-padding);
}

.section-body--flush {
  padding: 0;
}

.section-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--gap-control);
  padding: var(--space-3) var(--card-padding);
  border-top: 1px solid var(--border-subtle);
  background-color: var(--neutral-50);
}

/* Sezione richiudibile: il titolo e' il bottone. */
.section-header--toggle {
  cursor: pointer;
  user-select: none;
}

.section-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--touch-target);
  height: var(--touch-target);
  flex-shrink: 0;
  color: var(--fg-subtle);
  border-radius: var(--radius-sm);
  transition: var(--transition-colors), transform var(--transition-base);
}

.section-toggle::before {
  content: "";
  width: 9px;
  height: 9px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform var(--transition-base);
}

.section[data-collapsed="true"] .section-toggle::before {
  transform: translateY(0) rotate(-45deg);
}

.section[data-collapsed="true"] .section-body,
.section[data-collapsed="true"] .section-footer {
  display: none;
}

.section[data-collapsed="true"] .section-header {
  border-bottom: none;
}

@media (max-width: 640px) {
  .section-header {
    padding-inline: var(--card-padding-compact);
  }

  .section-body {
    padding: var(--card-padding-compact);
  }

  .section-title {
    font-size: var(--type-h3-size);
  }

  /* Titolo e azioni non entrano insieme in 375px. Le azioni prendono una riga
     propria a piena larghezza invece di comprimere il titolo in una colonna di
     due parole; icona e titolo restano insieme sulla prima riga. */
  .section-actions {
    flex: 1 1 100%;
    justify-content: flex-end;
  }
}

/* ===========================================
   GRIGLIE
   ===========================================
   Nessuna larghezza fissa in px: le colonne si contano da sole in base allo
   spazio disponibile, quindi la stessa griglia regge 375 e 1280 senza una
   media query per ogni sezione. */
.grid {
  display: grid;
  gap: var(--gap-control);
}

.grid--stats {
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.grid--cards {
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

.grid--wide {
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
}

.grid--2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Impilamento verticale con ritmo dichiarato. */
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--gap-block);
}

.stack--tight {
  gap: var(--gap-control);
}

.stack--loose {
  gap: var(--gap-section);
}

/* Riga di elementi che va a capo da sola invece di sfondare il contenitore. */
.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap-control);
}

.cluster--between {
  justify-content: space-between;
}

.cluster--end {
  justify-content: flex-end;
}

/* Spinge a destra cio' che segue, dentro un .cluster o una .section-header. */
.push-right {
  margin-left: auto;
}

/* ===========================================
   AUTENTICAZIONE
   ===========================================
   Una card centrata su una pagina vuota. Il filo di brand in cima e' lo stesso
   segno che portano le sezioni dell'app: la prima schermata deve gia'
   assomigliare a quello che c'e' dopo il login. */
.auth-container {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100dvh;
  padding: var(--space-6) var(--space-4);
  background:
    radial-gradient(circle at 15% 12%, var(--brand-50), transparent 55%),
    radial-gradient(circle at 85% 88%, var(--ink-50), transparent 55%),
    var(--surface-page);
}

.auth-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--gap-block);
  width: 100%;
  max-width: var(--container-narrow);
  padding: var(--space-8) var(--space-6) var(--space-6);
  overflow: hidden;
  text-align: center;
  background-color: var(--surface-card);
  border: var(--card-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--elevation-3);
}

.auth-card::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 4px;
  background: var(--gradient-hairline);
}

.auth-card__mark {
  width: 56px;
  height: 56px;
}

.auth-card h1 {
  font-size: var(--text-2xl);
}

.auth-card > p {
  margin-top: calc(-1 * var(--space-3));
  font-size: var(--type-small-size);
}

.auth-card .language-selector {
  align-self: center;
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: var(--gap-field);
  width: 100%;
  text-align: left;
}

/* Il messaggio d'errore resta invisibile finche' e' vuoto: un riquadro rosso
   sempre presente insegna a ignorarlo. */
.auth-error:empty {
  display: none;
}

.auth-error {
  width: 100%;
  padding: var(--space-3) var(--space-4);
  font-size: var(--type-small-size);
  text-align: left;
  color: var(--danger-text);
  background-color: var(--danger-surface);
  border: 1px solid var(--danger-border);
  border-left-width: 3px;
  border-radius: var(--radius-md);
}

.auth-consent {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
  width: 100%;
  font-size: var(--type-small-size);
  line-height: var(--leading-snug);
  text-align: left;
  color: var(--fg-muted);
  cursor: pointer;
}

.auth-consent input[type="checkbox"] {
  width: 18px;
  height: 18px;
  margin-top: 2px;
  flex-shrink: 0;
  accent-color: var(--brand-700);
}

.password-input-wrapper {
  position: relative;
  display: flex;
}

.password-input-wrapper .input {
  padding-right: var(--space-12);
}

/* Il comando per mostrare la password: era un quadratino verde acqua senza
   contenuto visibile, perche' l'icona arrivava da uno pseudo-elemento che
   nessuna regola disegnava piu'. Ora e' un occhio, e cambia allo stato premuto. */
.toggle-password {
  position: absolute;
  inset-block: 0;
  right: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--touch-target);
  color: var(--fg-subtle);
  border-radius: var(--radius-sm);
  transition: var(--transition-colors);
}

.toggle-password::before {
  content: "\1F441";
  font-size: var(--text-lg);
  line-height: 1;
  opacity: 0.75;
}

.toggle-password:hover {
  color: var(--fg-brand);
}

.toggle-password[aria-pressed="true"]::before,
.toggle-password.is-visible::before {
  content: "\1F576";
}

.forgot-password-link {
  text-align: center;
  font-size: var(--type-small-size);
}
