:root {
    /* Palette LIGHT — verde brand The Pot su cream warm. Identita' del
       logo (#3d6649) preservata sui titoli/numeri grandi. */
    --bg: #f4f1ec;
    --fg: #2b2b2b;
    --muted: #6b6b6b;
    --accent: #4a7c59;
    --accent-dark: #3d6649;
    --card-bg: #ffffff;
    --border: #d4cfc6;
    /* Velo bianco semi-trasparente sopra le immagini di sfondo stagionali
       per ridurre il contrasto e garantire leggibilita' del contenuto.
       50% sul bg principale, 80% su navbar/footer (cromature). */
    --bg-overlay: rgba(255, 255, 255, 0.5);
    --chrome-bg: rgba(255, 255, 255, 0.8);

    /* Stati semantici. Centralizzati qui per evitare i ~60 hardcoded
       sparsi nel CSS (`#8a2020`, `#8a6420`, `#2c5482`, ecc.). Ogni
       gruppo ha bg tenue + fg leggibile + border definito. */
    --error-bg: #fde6e6;
    --error-fg: #8a2020;
    --error-border: #f0b8b8;
    --warn-bg: #faf5e9;
    --warn-fg: #8a6420;
    --warn-border: #e6d5a8;
    --info-bg: #e6eef5;
    --info-fg: #2c5482;
    --info-border: #bcd0e3;
}

/* color-scheme esplicito quando l'utente forza il tema: cos&igrave; scrollbar,
   form controls nativi e altri UA-styled element seguono il tema scelto
   invece di restare sul prefers-color-scheme del SO. Su 'auto' lascia
   light+dark cos&igrave; il browser sceglie da solo. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }
:root[data-theme="auto"]  { color-scheme: light dark; }

/* ── Dark mode ──────────────────────────────────────────────────────────
   Tre stati: 'auto' (default, segue prefers-color-scheme del SO),
   'light' (forza chiaro), 'dark' (forza scuro). L'attributo `data-theme`
   sta su <html> e arriva dal server (render.py legge users.theme_preference)
   cos&igrave; il primo paint &egrave; gi&agrave; nel tema giusto, senza FOUC.

   Palette dark The Pot: terre notturne calde, verdi smorzati. Il velo
   --bg-overlay diventa nero a 45% per integrare bene con le immagini
   stagionali notturne (spring/summer/autumn/winter_dark_bg.png). */

:root[data-theme="dark"] {
    /* Palette DARK — terra notturna + verdi chiari per leggibilit&agrave;.
       Card "elevate" (un tono sopra --bg) per staccarsi dal pattern
       stagionale dietro al velo. */
    --bg: #1a1c1a;
    --fg: #e8e3d7;
    --muted: #a8a59a;
    --accent: #7ba488;
    --accent-dark: #9bc0a5;
    --card-bg: #262824;
    --border: #3d4038;
    --bg-overlay: rgba(0, 0, 0, 0.55);
    --chrome-bg: rgba(20, 22, 20, 0.88);

    /* Stati semantici dim per dark. */
    --error-bg: #3a1f1f;
    --error-fg: #f5b8b8;
    --error-border: #804040;
    --warn-bg: #3a3520;
    --warn-fg: #e0c896;
    --warn-border: #6b5e2e;
    --info-bg: #1f2e3f;
    --info-fg: #a8c5e0;
    --info-border: #3a5275;
}

@media (prefers-color-scheme: dark) {
    :root[data-theme="auto"] {
        --bg: #1a1c1a;
        --fg: #e8e3d7;
        --muted: #a8a59a;
        --accent: #7ba488;
        --accent-dark: #9bc0a5;
        --card-bg: #262824;
        --border: #3d4038;
        --bg-overlay: rgba(0, 0, 0, 0.55);
        --chrome-bg: rgba(20, 22, 20, 0.88);

        --error-bg: #3a1f1f;
        --error-fg: #f5b8b8;
        --error-border: #804040;
        --warn-bg: #3a3520;
        --warn-fg: #e0c896;
        --warn-border: #6b5e2e;
        --info-bg: #1f2e3f;
        --info-fg: #a8c5e0;
        --info-border: #3a5275;
    }
}

/* Override mirati per banner e badge con tinte hardcoded (lineage,
   post-rinvaso, push-status, button secondari). Su dark tutti gli sfondi
   tenui chiari diventano tonalit&agrave; scure dell'accent / muted / warn.
   Stesso blocco duplicato per explicit dark e auto + media query (no var
   intermedie perch&eacute; sono solo ~8 selettori, duplicare e' pi&ugrave; leggibile). */
:root[data-theme="dark"] .rinvaso-annulla-panel,
:root[data-theme="dark"] .post-rinvaso-badge {
    background: #3a3520;
    border-color: #6b5e2e;
    color: var(--fg);
}
:root[data-theme="dark"] .lineage-banner-archived {
    background: #2a2a2a;
    border-color: #4a4a4a;
    border-left-color: #888;
    color: var(--fg);
}
:root[data-theme="dark"] .lineage-banner-archived .lineage-banner-text strong {
    color: #c5c5c5;
}
:root[data-theme="dark"] .lineage-banner-supersedes,
:root[data-theme="dark"] .profile-push-status[data-push-status="active"] {
    background: #1f2e25;
    border-color: #3a5a44;
    color: var(--fg);
}
:root[data-theme="dark"] .post-rinvaso-badge {
    color: var(--fg);
}
:root[data-theme="dark"] .secondary-button {
    background: rgba(0, 0, 0, 0.35);
}
:root[data-theme="dark"] .field input:disabled,
:root[data-theme="dark"] .field select:disabled,
:root[data-theme="dark"] .field textarea:disabled {
    background: rgba(255, 255, 255, 0.05);
}

/* Calendario, eventi, allerte: testi e bg con colori hardcoded che restavano
   chiari su dark. Ridefiniti qui in blocco. I bg "tonalit&agrave;" (rosa scaduto,
   ambra warning) sono lasciati colorati ma con opacit&agrave; aumentata per
   restare visibili su sfondo scuro. */
:root[data-theme="dark"] .alert-message,
:root[data-theme="dark"] .cal-event-title {
    color: var(--fg);
}
:root[data-theme="dark"] .cal-event-notes {
    color: var(--muted);
}
/* Giorni passati del calendario: bg pieno pi&ugrave; scuro del --card-bg
   (anzich&eacute; un nero semitrasparente che si confonde con il body bg).
   D&agrave; il senso "passato/spento" senza far sparire la cella. */
:root[data-theme="dark"] .cal-day-cell.cal-day-past {
    background: #1d1f1c;
    border-color: #2a2c28;
}
:root[data-theme="dark"] .cal-event {
    background: var(--card-bg);
}
/* Chip filtri (calendario, diario, lista vasi): non-attivi -> bg
   leggermente pi&ugrave; chiaro di --card-bg cos&igrave; non si fondono con la
   card che li contiene, testo muted. Le `-active` mantengono le
   palette colorate definite a livello base (vincono per specificity). */
:root[data-theme="dark"] .diario-cat-chip:not(.diario-cat-chip-active) {
    background: #3e413a;
    color: var(--muted);
    border-color: #4a4d44;
}
/* Numero del giorno nel calendario settimanale: color #333 hardcoded
   -> illeggibile su dark. */
:root[data-theme="dark"] .cal-day-num {
    color: var(--fg);
}
/* Chip filtri calendario (Aperti/Completati/Tutti, Tutte le categorie):
   stesso pattern delle .diario-cat-chip — bg leggermente pi&ugrave; chiaro
   di --card-bg per non confondersi con la card, testo muted. */
:root[data-theme="dark"] .calendar-chip:not(.calendar-chip-active) {
    background: #3e413a;
    color: var(--muted);
    border-color: #4a4d44;
}
:root[data-theme="dark"] .calendar-chip:not(.calendar-chip-active):hover {
    background: #4a4d44;
    color: var(--fg);
    border-color: var(--accent);
}
/* UX-6: attivo a tinta anche su dark (il verde chiarissimo del light
   stonerebbe): tinta scura opaca per lo sfondo stagionale. */
:root[data-theme="dark"] .calendar-chip-active {
    background: #31503e;
    color: #cfe3d4;
    border-color: var(--accent);
}
:root[data-theme="dark"] .calendar-chip-active:hover {
    background: #3a5f4a;
}
/* Profilo: testi descrittivi delle card (Location, Esporta, Installa,
   Notifiche push). Hanno tutti color #333/#444/#555/#666/#777/#888
   hardcoded -> illeggibili su dark. Virati su var(--fg) o var(--muted)
   in base alla gerarchia (titolo/descrizione/sub-text). */
:root[data-theme="dark"] .location-current p,
:root[data-theme="dark"] .push-pref-label,
:root[data-theme="dark"] .push-device-label {
    color: var(--fg);
}
:root[data-theme="dark"] .push-pref-desc,
:root[data-theme="dark"] .profile-export-desc,
:root[data-theme="dark"] .profile-export-content,
:root[data-theme="dark"] .profile-pwa-desc,
:root[data-theme="dark"] .profile-pwa-help,
:root[data-theme="dark"] .profile-push-desc,
:root[data-theme="dark"] .profile-push-status,
:root[data-theme="dark"] .push-device-date,
:root[data-theme="dark"] .profile-push-devices h4,
:root[data-theme="dark"] .profile-push-prefs h4,
:root[data-theme="dark"] .profile-push-help {
    color: var(--muted);
}
/* Slice ux-roles (UX-4): card evento unificata anche sulla home; il
   marker "scaduto" schiarisce il rosso su dark. */
:root[data-theme="dark"] .cal-event-overdue {
    background: rgba(176, 68, 68, 0.18);
}
/* .bucket-* e .alert-row.alert-* su dark: gli override sono stati
   rimossi quando le regole base sono passate da rgba hardcoded a
   var(--error/warn/info-*), che si auto-adattano al tema. */
/* Tab del profilo: il banner era bianco semitrasparente, su dark
   diventa nero semitrasparente per coerenza con .site-header. */
:root[data-theme="dark"] .profile-tabs {
    background-color: rgba(0, 0, 0, 0.35);
}
/* Banner overdue del calendario: il rosso pieno era molto chiaro/aggressivo
   su dark. Tonalit&agrave; ridotta. */
:root[data-theme="dark"] .cal-overdue-banner {
    background: #5a2a2a;
    border-color: #804040;
}
:root[data-theme="dark"] .cal-overdue-banner h3 {
    color: #f5b8b8;
}
/* Pianificazione: subtitle "Concimazione · ogni 30 gg" sotto al titolo
   della card. .event-detail aveva color: #444 hardcoded -> illeggibile
   su dark. */
:root[data-theme="dark"] .event-detail {
    color: var(--muted);
}
/* Attivita' recenti: il "tipo attivita'" (Rinvaso, Irrigazione) sta
   dentro .recent-title come testo non-link, con color #333. */
:root[data-theme="dark"] .recent-title {
    color: var(--fg);
}
/* Chip filtri allerte non-attivi: bg bianco semitrasparente + color #555
   diventava nero su sfondo nero. Su dark uso un bg molto scuro tenue +
   color muted. Le varianti -active mantengono le palette colorate dei
   blocchi sopra. */
/* Chip filtri Avvisi: stesso pattern di .calendar-chip / .diario-cat-chip.
   Non-active = bg #3e413a chiaro + testo muted. Active = palette
   semantica (verde Tutti, ambra Avvisi/Warning, grigio Info, rosso
   Critical) con bg pi&ugrave; saturo per essere ben visibile su dark. */
:root[data-theme="dark"] .alert-chip:not(.alert-chip-active) {
    background: #3e413a;
    color: var(--muted);
    border-color: #4a4d44;
}
:root[data-theme="dark"] .alert-chip:not(.alert-chip-active):hover {
    background: #4a4d44;
    color: var(--fg);
    border-color: var(--accent);
}
:root[data-theme="dark"] .alert-chip-all.alert-chip-active {
    background: rgba(74, 124, 89, 0.30);
    border-color: var(--accent);
    color: var(--fg);
}
:root[data-theme="dark"] .alert-chip-critical.alert-chip-active {
    background: rgba(176, 68, 68, 0.30);
    border-color: #b04444;
    color: #f5b8b8;
}
:root[data-theme="dark"] .alert-chip-warning.alert-chip-active {
    background: rgba(199, 153, 57, 0.30);
    border-color: #c79939;
    color: #e0c896;
}
:root[data-theme="dark"] .alert-chip-info.alert-chip-active {
    background: rgba(160, 160, 160, 0.28);
    border-color: #aaa;
    color: var(--fg);
}
/* Dashboard agronomica: legenda donut, etichette specie nelle barre,
   celle della tabella fitopatie. Tutti avevano color #333 hardcoded. */
:root[data-theme="dark"] .agro-legend-label,
:root[data-theme="dark"] .agro-bar-label,
:root[data-theme="dark"] .agro-table td {
    color: var(--fg);
}
/* Lineage banners (detail vaso): "Questo vaso appartiene a un lineage…"
   e "ieri. Sotto vedi la storia completa…". Color #444/#555 hardcoded. */
:root[data-theme="dark"] .lineage-banner-text,
:root[data-theme="dark"] .lineage-toggle-panel {
    color: var(--fg);
}
:root[data-theme="dark"] .lineage-banner-text strong {
    color: var(--accent-dark);
}
/* Banner post-rinvaso: il bg cream-dark che ho impostato confliggeva
   con il testo verde oliva scuro hardcoded (#4a5224 / #6a7228). Tutti
   gli elementi del badge -> var(--fg) / var(--accent-dark). */
:root[data-theme="dark"] .post-rinvaso-text strong,
:root[data-theme="dark"] .post-rinvaso-postponed,
:root[data-theme="dark"] .post-rinvaso-postponed strong {
    color: var(--fg);
}
:root[data-theme="dark"] .post-rinvaso-remaining {
    color: var(--accent-dark);
}
:root[data-theme="dark"] .post-rinvaso-postponed a {
    color: var(--accent-dark);
}

@media (prefers-color-scheme: dark) {
    :root[data-theme="auto"] .rinvaso-annulla-panel,
    :root[data-theme="auto"] .post-rinvaso-badge {
        background: #3a3520;
        border-color: #6b5e2e;
        color: var(--fg);
    }
    :root[data-theme="auto"] .lineage-banner-archived {
        background: #2a2a2a;
        border-color: #4a4a4a;
        border-left-color: #888;
        color: var(--fg);
    }
    :root[data-theme="auto"] .lineage-banner-archived .lineage-banner-text strong {
        color: #c5c5c5;
    }
    :root[data-theme="auto"] .lineage-banner-supersedes,
    :root[data-theme="auto"] .profile-push-status[data-push-status="active"] {
        background: #1f2e25;
        border-color: #3a5a44;
        color: var(--fg);
    }
    :root[data-theme="auto"] .secondary-button {
        background: rgba(0, 0, 0, 0.35);
    }
    :root[data-theme="auto"] .field input:disabled,
    :root[data-theme="auto"] .field select:disabled,
    :root[data-theme="auto"] .field textarea:disabled {
        background: rgba(255, 255, 255, 0.05);
    }
    /* Equivalente "auto" del blocco esteso sopra. */
    :root[data-theme="auto"] .alert-message,
    :root[data-theme="auto"] .cal-event-title {
        color: var(--fg);
    }
    :root[data-theme="auto"] .cal-event-notes {
        color: var(--muted);
    }
    :root[data-theme="auto"] .cal-day-cell.cal-day-past {
        background: #1d1f1c;
        border-color: #2a2c28;
    }
    :root[data-theme="auto"] .cal-event {
        background: var(--card-bg);
    }
    :root[data-theme="auto"] .diario-cat-chip:not(.diario-cat-chip-active) {
        background: #3e413a;
        color: var(--muted);
        border-color: #4a4d44;
    }
    :root[data-theme="auto"] .cal-day-num {
        color: var(--fg);
    }
    :root[data-theme="auto"] .calendar-chip:not(.calendar-chip-active) {
        background: #3e413a;
        color: var(--muted);
        border-color: #4a4d44;
    }
    :root[data-theme="auto"] .calendar-chip:not(.calendar-chip-active):hover {
        background: #4a4d44;
        color: var(--fg);
        border-color: var(--accent);
    }
    :root[data-theme="auto"] .calendar-chip-active {
        background: #31503e;
        color: #cfe3d4;
        border-color: var(--accent);
    }
    :root[data-theme="auto"] .calendar-chip-active:hover {
        background: #3a5f4a;
    }
    :root[data-theme="auto"] .location-current p,
    :root[data-theme="auto"] .push-pref-label,
    :root[data-theme="auto"] .push-device-label {
        color: var(--fg);
    }
    :root[data-theme="auto"] .push-pref-desc,
    :root[data-theme="auto"] .profile-export-desc,
    :root[data-theme="auto"] .profile-export-content,
    :root[data-theme="auto"] .profile-pwa-desc,
    :root[data-theme="auto"] .profile-pwa-help,
    :root[data-theme="auto"] .profile-push-desc,
    :root[data-theme="auto"] .profile-push-status,
    :root[data-theme="auto"] .push-device-date,
    :root[data-theme="auto"] .profile-push-devices h4,
    :root[data-theme="auto"] .profile-push-prefs h4,
    :root[data-theme="auto"] .profile-push-help {
        color: var(--muted);
    }
    :root[data-theme="auto"] .cal-event-overdue {
        background: rgba(176, 68, 68, 0.18);
    }
    /* bucket-* + alert-row.alert-*: stessa nota del blocco dark sopra. */
    :root[data-theme="auto"] .profile-tabs {
        background-color: rgba(0, 0, 0, 0.35);
    }
    :root[data-theme="auto"] .cal-overdue-banner {
        background: #5a2a2a;
        border-color: #804040;
    }
    :root[data-theme="auto"] .cal-overdue-banner h3 {
        color: #f5b8b8;
    }
    :root[data-theme="auto"] .event-detail {
        color: var(--muted);
    }
    :root[data-theme="auto"] .recent-title {
        color: var(--fg);
    }
    :root[data-theme="auto"] .alert-chip:not(.alert-chip-active) {
        background: #3e413a;
        color: var(--muted);
        border-color: #4a4d44;
    }
    :root[data-theme="auto"] .alert-chip:not(.alert-chip-active):hover {
        background: #4a4d44;
        color: var(--fg);
        border-color: var(--accent);
    }
    :root[data-theme="auto"] .alert-chip-all.alert-chip-active {
        background: rgba(74, 124, 89, 0.30);
        border-color: var(--accent);
        color: var(--fg);
    }
    :root[data-theme="auto"] .alert-chip-critical.alert-chip-active {
        background: rgba(176, 68, 68, 0.30);
        border-color: #b04444;
        color: #f5b8b8;
    }
    :root[data-theme="auto"] .alert-chip-warning.alert-chip-active {
        background: rgba(199, 153, 57, 0.30);
        border-color: #c79939;
        color: #e0c896;
    }
    :root[data-theme="auto"] .alert-chip-info.alert-chip-active {
        background: rgba(160, 160, 160, 0.28);
        border-color: #aaa;
        color: var(--fg);
    }
    :root[data-theme="auto"] .agro-legend-label,
    :root[data-theme="auto"] .agro-bar-label,
    :root[data-theme="auto"] .agro-table td {
        color: var(--fg);
    }
    :root[data-theme="auto"] .lineage-banner-text,
    :root[data-theme="auto"] .lineage-toggle-panel {
        color: var(--fg);
    }
    :root[data-theme="auto"] .lineage-banner-text strong {
        color: var(--accent-dark);
    }
    :root[data-theme="auto"] .post-rinvaso-text strong,
    :root[data-theme="auto"] .post-rinvaso-postponed,
    :root[data-theme="auto"] .post-rinvaso-postponed strong {
        color: var(--fg);
    }
    :root[data-theme="auto"] .post-rinvaso-remaining {
        color: var(--accent-dark);
    }
    :root[data-theme="auto"] .post-rinvaso-postponed a {
        color: var(--accent-dark);
    }
}

* {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    padding: 0;
}

body {
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    background: var(--bg);
    color: var(--fg);
    line-height: 1.5;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* Header e footer: full-width sopra il bg piatto del body. Il contenuto
   interno resta centrato in max-width 1200px via `.site-header-inner` /
   `.site-footer-inner`. Background bianco semi-trasparente (--chrome-bg)
   per garantire la leggibilita' di logo/nav/copyright sopra le immagini
   di sfondo stagionali. In modalita' splash queste regole sono inerti
   perche' header e footer sono display:none. */
.site-header,
.site-footer {
    width: 100%;
    padding: 0 1.5rem;
    background: var(--chrome-bg);
}

.site-main {
    max-width: 1200px;
    width: 100%;
    margin: 0 auto;
    padding: 1.25rem 1.5rem;
    /* Slice mod_footer (giu 2026): sticky footer. Il body e' flex
       column con min-height 100vh; senza questo, con poco contenuto
       (es. pochi vasi) il main non riempie l'altezza e il footer
       "fluttua" a meta' pagina lasciando spazio vuoto sotto. flex:1
       fa assorbire al main lo spazio extra e spinge il footer in
       fondo alla viewport. (grow 1, shrink 0, basis auto: non
       comprime il contenuto quando invece e' piu' alto della viewport). */
    flex: 1 0 auto;
}

.site-header {
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
    /* Slice SIST-1 (giu 2026): nav sticky su desktop. Resta incollata
       in cima allo scroll. position:sticky non richiede padding
       compensativo (a differenza di fixed): l'header resta nel flusso.
       z-index 50: sopra il contenuto normale (z 1-20) ma sotto i
       dialog modali (z 1000+) che devono coprirla. Il backdrop-filter
       sfoca il contenuto che scorre sotto (--chrome-bg e' a 0.8 di
       opacita') mantenendo logo/nav leggibili; l'ombra leggera stacca
       l'header dal contenuto. Su mobile (<=720px) torna static (vedi
       media query in fondo: lì la nav e' gia' gestita diversamente con
       la bottom-nav). */
    position: sticky;
    top: 0;
    z-index: 50;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.site-footer {
    padding-top: 1rem;
    padding-bottom: 1rem;
}

.site-header-inner,
.site-footer-inner {
    max-width: 1200px;
    width: 100%;
    margin: 0 auto;
}

/* Footer: layout su due colonne — tag dell'app a sinistra, link
   Privacy / Termini di servizio a destra. Su mobile (< 480px) si
   impila in colonna con i link sotto al tag, centrati. */
.site-footer-inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.site-footer-tag {
    margin: 0;
}

.site-header-inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    /* Niente flex-wrap: logo + nav restano sempre sulla stessa riga.
       Su mobile il media query nasconde le label dei link, lasciando
       solo le icone — la nav resta compatta. */
}

.site-title-link {
    text-decoration: none;
    color: inherit;
}

.site-title {
    margin: 0;
    color: var(--accent);
    font-size: 1.5rem;
}

/* Logo immagine nella navbar (slice modifiche grafiche). Altezza fissa,
   width auto per preservare aspect ratio. Display block per evitare il
   gap del baseline tipico delle immagini inline. */
.site-logo {
    display: block;
    height: 64px;
    width: auto;
}

@media (max-width: 600px) {
    .site-logo {
        height: 48px;
    }
}

/* Splash landing per utenti anonimi (modifiche grafiche).
   Quando il body ha la classe `.splash-mode` (impostata dal server solo
   per la pagina splash), l'intero viewport &egrave; occupato dall'immagine
   senza distrazioni: navbar e footer **nascosti**, main full-width senza
   padding, i 2 bottoni "Accedi/Registrati" centrati nel viewport. */
body.splash-mode {
    background-image: url('/static/images/spash_screen_desktop.png');
    background-size: cover;
    background-position: center center;
    background-repeat: no-repeat;
    background-attachment: fixed;
}

@media (max-width: 700px) {
    body.splash-mode {
        background-image: url('/static/images/spash_screen_mobile.png');
    }
}

/* ── Sfondi stagionali per tutte le altre pagine ────────────────────────
   Il body riceve automaticamente la classe `season-<slug>` (vedi
   render.py::current_season). Applichiamo un'immagine di sfondo diversa
   per ognuna delle 4 stagioni meteorologiche. Escludiamo `splash-mode`
   che usa la propria immagine dedicata (regola sopra).

   Il background-image e' un layered background:
     1. linear-gradient (--bg-overlay) sopra: velo bianco in light,
        nero in dark. Override automatico via custom property.
     2. l'immagine stagionale sotto: variante `_bg.png` per chiaro,
        `_dark_bg.png` per scuro (override sotto).
   Cosi' otteniamo un velo che ammorbidisce l'immagine senza CSS
   aggiuntivi (niente ::before, niente z-index acrobatici).

   Mobile: stessa immagine desktop, `background-size: cover` +
   `background-position: center` ritaglia la parte centrale. Niente
   variante dedicata per evitare il raddoppio di asset.
   `background-attachment: fixed` cos&igrave; lo sfondo resta fermo durante
   lo scroll, come la splash. */
body.season-spring:not(.splash-mode) {
    background-image:
        linear-gradient(var(--bg-overlay), var(--bg-overlay)),
        url('/static/images/spring_bg.png');
    background-size: cover;
    background-position: center center;
    background-repeat: no-repeat;
    background-attachment: fixed;
}
body.season-summer:not(.splash-mode) {
    background-image:
        linear-gradient(var(--bg-overlay), var(--bg-overlay)),
        url('/static/images/summer_bg.png');
    background-size: cover;
    background-position: center center;
    background-repeat: no-repeat;
    background-attachment: fixed;
}
body.season-autumn:not(.splash-mode) {
    background-image:
        linear-gradient(var(--bg-overlay), var(--bg-overlay)),
        url('/static/images/autumn_bg.png');
    background-size: cover;
    background-position: center center;
    background-repeat: no-repeat;
    background-attachment: fixed;
}
body.season-winter:not(.splash-mode) {
    background-image:
        linear-gradient(var(--bg-overlay), var(--bg-overlay)),
        url('/static/images/winter_bg.png');
    background-size: cover;
    background-position: center center;
    background-repeat: no-repeat;
    background-attachment: fixed;
}

/* Override dark mode: stesse stagioni, immagini notturne. Il velo
   diventa nero via --bg-overlay (gi&agrave; overrideato sopra). */
:root[data-theme="dark"] body.season-spring:not(.splash-mode) {
    background-image:
        linear-gradient(var(--bg-overlay), var(--bg-overlay)),
        url('/static/images/spring_dark_bg.png');
}
:root[data-theme="dark"] body.season-summer:not(.splash-mode) {
    background-image:
        linear-gradient(var(--bg-overlay), var(--bg-overlay)),
        url('/static/images/summer_dark_bg.png');
}
:root[data-theme="dark"] body.season-autumn:not(.splash-mode) {
    background-image:
        linear-gradient(var(--bg-overlay), var(--bg-overlay)),
        url('/static/images/autumn_dark_bg.png');
}
:root[data-theme="dark"] body.season-winter:not(.splash-mode) {
    background-image:
        linear-gradient(var(--bg-overlay), var(--bg-overlay)),
        url('/static/images/winter_dark_bg.png');
}

@media (prefers-color-scheme: dark) {
    :root[data-theme="auto"] body.season-spring:not(.splash-mode) {
        background-image:
            linear-gradient(var(--bg-overlay), var(--bg-overlay)),
            url('/static/images/spring_dark_bg.png');
    }
    :root[data-theme="auto"] body.season-summer:not(.splash-mode) {
        background-image:
            linear-gradient(var(--bg-overlay), var(--bg-overlay)),
            url('/static/images/summer_dark_bg.png');
    }
    :root[data-theme="auto"] body.season-autumn:not(.splash-mode) {
        background-image:
            linear-gradient(var(--bg-overlay), var(--bg-overlay)),
            url('/static/images/autumn_dark_bg.png');
    }
    :root[data-theme="auto"] body.season-winter:not(.splash-mode) {
        background-image:
            linear-gradient(var(--bg-overlay), var(--bg-overlay)),
            url('/static/images/winter_dark_bg.png');
    }
}

/* Splash: nascondi nav e footer, l'immagine si vede a tutto schermo
   (il logo &egrave; gi&agrave; nell'immagine, niente ridondanza). */
body.splash-mode .site-header,
body.splash-mode .site-footer {
    display: none;
}

/* Main full-width senza padding solo in modalit&agrave; splash. */
body.splash-mode .site-main {
    max-width: none;
    padding: 0;
    margin: 0;
}

/* Sezione splash: 100vh (niente nav/footer da sottrarre), bottoni
   centrati orizzontalmente E verticalmente. */
.splash {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

.splash-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 1.2rem;
    justify-content: center;
    padding: 0;
    background: transparent;
    border-radius: 0;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: none;
}

/* Bottoni SVG ornamentali della splash: cornice art-nouveau dorata su
   sfondo verde notturno semitrasparente, coerente con l'illustrazione
   dello splash (mandala oro, scritte serif "The Pot"). Hover: lieve
   ingrandimento + glow dorato attorno al SVG. */
.splash-link {
    display: inline-block;
    text-decoration: none;
    line-height: 0;   /* elimina il gap del baseline sotto l'SVG */
    transition: transform 0.25s ease, filter 0.25s ease;
    filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.45));
}

.splash-link:hover,
.splash-link:focus-visible {
    transform: scale(1.04);
    filter: drop-shadow(0 0 14px rgba(232, 209, 138, 0.55))
            drop-shadow(0 2px 6px rgba(0, 0, 0, 0.4));
    outline: none;
}

.splash-link:focus-visible {
    /* Hint accessibility: outline dorato leggero attorno al focus. */
    filter: drop-shadow(0 0 14px rgba(240, 217, 149, 0.85))
            drop-shadow(0 2px 6px rgba(0, 0, 0, 0.4));
}

.splash-svg {
    display: block;
    width: 240px;
    height: 70px;
}

/* Mobile: riduco le dimensioni cos&igrave; i 2 bottoni stanno su una colonna
   sola senza overflow. Larghezza fissa percentuale del viewport. */
@media (max-width: 480px) {
    .splash-actions {
        flex-direction: column;
        gap: 1rem;
    }
    .splash-svg {
        width: min(280px, 78vw);
        height: auto;
    }
}

/* ── Auth nav nell'header ───────────────────────────────────────────────── */

/* Slice nav-1: gap leggermente ridotto (0.3 → 0.2) per stringere le
   icone della nav top, ora che la search inline e' diventata un
   bottone modale (-1 riga). I link restano leggibili ma la nav meno
   sovraffollata. */
.auth-nav {
    font-size: 0.92rem;
    display: flex;
    align-items: center;
    gap: 0.2rem;
    flex-wrap: wrap;
}

.auth-nav .when-anonymous,
.auth-nav .when-authenticated {
    display: flex;
    align-items: center;
    gap: 0.2rem;
    flex-wrap: wrap;
}

/* Slice nav-1 + giardiniere-0.4: bottone "Apri ricerca" globale nell'header.
   Sostituisce il vecchio form inline (input + lente). Click apre
   <dialog id="search-dialog"> via setupSearchDialog in app.js. L'icona e'
   ora la mascotte del Giardiniere (riccio con la lente): unico ingresso a
   ricerca deterministica ("Cerca") e assistente ("Chiedi"). Niente cerchietto
   col bordo: l'illustrazione ha gia' la sua sagoma, hover con leggero zoom. */
.header-search-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.7rem;
    height: 2.7rem;
    padding: 0;
    margin-right: 0.3rem;
    border: none;
    background: transparent;
    cursor: pointer;
    transition: transform 0.15s ease;
}

.header-search-btn img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

.header-search-btn:hover {
    transform: scale(1.1);
}

/* Dialog modale di ricerca. Allineato visivamente al confirm-dialog
   (padding, border-radius, backdrop) ma piu' largo per ospitare un
   campo search a tutta larghezza. */
.search-dialog {
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1.2rem 1.4rem;
    background: var(--card-bg);
    color: var(--fg);
    max-width: 28rem;
    width: calc(100% - 2rem);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
}

.search-dialog::backdrop {
    background: rgba(0, 0, 0, 0.45);
}

.search-dialog-form {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin: 0;
}

.search-dialog-title {
    margin: 0;
    font-size: 1.05rem;
    color: var(--accent-dark);
}

.search-dialog-field {
    display: block;
    margin: 0;
}

.search-dialog-field input[type="search"] {
    width: 100%;
    padding: 0.55rem 0.85rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg);
    color: var(--fg);
    font: inherit;
    font-size: 1rem;
    line-height: 1.3;
    box-sizing: border-box;
    -webkit-appearance: none;
    appearance: none;
}

.search-dialog-field input[type="search"]:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(74, 124, 89, 0.18);
}

.search-dialog-hint {
    margin: 0;
    font-size: 0.8rem;
    color: var(--muted);
}

.search-dialog-hint em {
    font-style: normal;
    color: var(--accent-dark);
    background: rgba(74, 124, 89, 0.10);
    padding: 0.05rem 0.35rem;
    border-radius: 4px;
    margin: 0 0.1rem;
}

.search-dialog-actions {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.25rem;
}

/* Override locale: i due bottoni del dialog (Annulla / Cerca) devono
   avere padding sobrio e uguale. .primary-button ha di default
   margin-top 0.75rem e padding 0.75rem 1rem (pensato per form),
   .secondary-button ha padding 0.4rem 0.85rem: con il primary che si
   alza visualmente, Annulla finiva con l'apparire sproporzionato
   rispetto al Cerca. Qui li allineo entrambi a un padding compatto. */
.search-dialog-actions .primary-button,
.search-dialog-actions .secondary-button {
    margin-top: 0;
    padding: 0.45rem 1rem;
    font-size: 0.92rem;
    line-height: 1.2;
}

/* ── Giardiniere Virtuale: modalita' "Chiedi" del dialog (giardiniere-0.3) ── */
.search-dialog-modes {
    display: flex;
    gap: 0.4rem;
    margin-bottom: 0.9rem;
}
/* I due pannelli del dialog devono escludersi: senza questa regola,
   display:flex su .search-dialog-form / .giardiniere-panel vincerebbe
   sull'attributo [hidden] e mostrerebbe entrambe le modalita' insieme. */
[data-search-panel][hidden] { display: none; }

.search-mode-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    min-height: 3rem;
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg);
    color: var(--muted);
    font: inherit;
    font-size: 0.95rem;
    cursor: pointer;
}
.search-mode-btn.is-active {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}
.search-mode-btn img {
    width: 2.7rem;
    height: 2.7rem;
    object-fit: cover;
    border-radius: 8px;
    display: block;
}
.search-mode-icon {
    font-size: 1.7rem;
    line-height: 1;
}
.giardiniere-panel {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}
.giardiniere-log {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-height: 45vh;
    overflow-y: auto;
    padding: 0.15rem;
}
.giardiniere-intro {
    margin: 0;
    font-size: 0.85rem;
    color: var(--muted);
}
/* giardiniere-2.x: chat a bolle. Riccio a sinistra (iconcina + fumetto),
   utente a destra. .giardiniere-msg e' il wrapper, .giardiniere-bubble il
   fumetto col testo. */
.giardiniere-msg {
    display: flex;
    align-items: flex-end;
    gap: 0.4rem;
    max-width: 92%;
}
.giardiniere-msg-utente { align-self: flex-end; }
.giardiniere-msg-riccio { align-self: flex-start; }
.giardiniere-msg-avatar {
    width: 2.8rem;
    height: 2.8rem;
    object-fit: cover;
    border-radius: 50%;
    border: 1px solid var(--border);
    flex-shrink: 0;
}
.giardiniere-bubble {
    padding: 0.5rem 0.7rem;
    border-radius: 12px;
    font-size: 0.9rem;
    line-height: 1.45;
    white-space: pre-wrap;
}
.giardiniere-msg-utente .giardiniere-bubble {
    background: rgba(74, 124, 89, 0.15);
    color: var(--fg);
    border-bottom-right-radius: 3px;
}
.giardiniere-msg-riccio .giardiniere-bubble {
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--fg);
    border-bottom-left-radius: 3px;
}
.giardiniere-bubble.is-pending {
    color: var(--muted);
    font-style: italic;
}
.giardiniere-bubble.is-error {
    background: rgba(200, 60, 60, 0.12);
    border: 1px solid rgba(200, 60, 60, 0.30);
    color: #b04444;
}
/* giardiniere-raffinamento 2/3: Markdown sanitizzato nelle risposte del riccio.
   Con HTML nel fumetto il layout lo gestiscono i tag, non il pre-wrap. */
.giardiniere-bubble.is-md { white-space: normal; }
.giardiniere-bubble.is-md p { margin: 0 0 0.5rem; }
.giardiniere-bubble.is-md p:last-child { margin-bottom: 0; }
.giardiniere-bubble.is-md ul,
.giardiniere-bubble.is-md ol { margin: 0.25rem 0 0.5rem; padding-left: 1.2rem; }
.giardiniere-bubble.is-md ul:last-child,
.giardiniere-bubble.is-md ol:last-child { margin-bottom: 0; }
.giardiniere-bubble.is-md li { margin: 0.1rem 0; }
.giardiniere-bubble.is-md code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.85em;
    background: rgba(0, 0, 0, 0.06);
    padding: 0.05rem 0.3rem;
    border-radius: 4px;
}

/* giardiniere-3.1: card di proposta evento (riccio propone, utente conferma). */
.giardiniere-proposta {
    align-self: flex-start;
    max-width: 92%;
    margin-left: 2.2rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.6rem 0.7rem;
    border-radius: 12px;
    background: rgba(74, 124, 89, 0.08);
    border: 1px solid var(--accent);
}
.giardiniere-proposta-testo {
    font-size: 0.9rem;
    color: var(--fg);
}
.giardiniere-proposta-azioni {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
}
.giardiniere-proposta-azioni button {
    padding: 0.3rem 0.9rem;
    font-size: 0.85rem;
}

/* giardiniere-2.1: allega-foto per la diagnosi. Nota [hidden]: display:flex
   lo sovrascriverebbe, serve la regola esplicita (come per i pannelli). */
.giardiniere-photo {
    display: flex;
    align-items: flex-start;
    gap: 0.4rem;
    margin-top: 0.4rem;
}
.giardiniere-photo[hidden] { display: none; }
.giardiniere-photo img {
    max-height: 6rem;
    max-width: 80%;
    border-radius: 8px;
    border: 1px solid var(--border);
}
.giardiniere-photo-remove {
    border: 1px solid var(--border);
    background: var(--card-bg);
    color: var(--muted);
    border-radius: 50%;
    width: 1.6rem;
    height: 1.6rem;
    line-height: 1;
    cursor: pointer;
    flex-shrink: 0;
}
.giardiniere-photo-btn {
    display: inline-flex;
    align-items: center;
    cursor: pointer;
    margin-right: auto;
}

/* giardiniere-2.x: il riccio nel tab "Chiedi" mostra lo STATO (dorme all'inizio,
   contento/incerto dopo). L'ANIMAZIONE del "pensa" (movimento) sta invece
   sull'iconcina della bolla in attesa, nella chat. */
.giardiniere-msg-avatar.is-thinking {
    animation: giardiniere-bob 1.1s ease-in-out infinite;
}
@keyframes giardiniere-bob {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-4px); }
}
.giardiniere-form textarea {
    width: 100%;
    resize: vertical;
    padding: 0.55rem 0.85rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg);
    color: var(--fg);
    font: inherit;
}
.giardiniere-form textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(74, 124, 89, 0.18);
}

/* Utility: testo invisibile-ma-leggibile-da-screen-reader. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ── Release modal "What's new" (slice modal release) ──────────────────── */
/*
 * Mostrato automaticamente al primo render post-login (o dopo bump
 * dell'id in release_notes.LATEST_RELEASE) se
 * users.last_seen_release_id != id corrente. Vedi
 * _render_release_modal_html in render.py + setupReleaseModal in app.js.
 */
.release-modal {
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 1.4rem 1.5rem 1.2rem;
    background: var(--card-bg);
    color: var(--fg);
    max-width: 32rem;
    width: calc(100% - 2rem);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.22);
}

.release-modal::backdrop {
    background: rgba(0, 0, 0, 0.45);
}

.release-modal-form {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    margin: 0;
}

.release-modal-header {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25rem;
}

.release-modal-badge {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    background: rgba(199, 153, 57, 0.18);
    color: #8a6420;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.release-modal-title {
    margin: 0;
    font-size: 1.2rem;
    color: var(--accent-dark);
    font-weight: 700;
    line-height: 1.25;
}

.release-modal-date {
    margin: 0;
    font-size: 0.82rem;
    color: var(--muted);
}

.release-modal-intro {
    margin: 0;
    font-size: 0.92rem;
    line-height: 1.5;
    color: var(--fg);
}

.release-modal-bullets {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.release-modal-bullet {
    padding: 0.5rem 0.7rem;
    border-radius: 8px;
    background: rgba(74, 124, 89, 0.06);
    border-left: 3px solid var(--accent);
    font-size: 0.9rem;
    line-height: 1.4;
}

.release-modal-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-top: 0.3rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
}

.release-modal-details-link {
    color: var(--accent-dark);
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 500;
}

.release-modal-details-link:hover {
    text-decoration: underline;
}

.release-modal-ok {
    /* riusa primary-button, qui overrides per padding coerente con
       gli altri modal (search-dialog, ecc.): no margin-top extra. */
    margin-top: 0;
    padding: 0.5rem 1.2rem;
    min-width: 8rem;
}

/* Mobile: footer in colonna invece di affiancato, cosi' "Ho capito"
   resta full-width e tap-friendly. */
@media (max-width: 480px) {
    .release-modal-footer {
        flex-direction: column-reverse;
        align-items: stretch;
    }
    .release-modal-details-link {
        text-align: center;
    }
}

/* Link nav: pill con padding interno + hover background tenue.
   Icone affiancate al testo (gap controllato). Niente underline.
   Slice nav-1: padding orizzontale ridotto (0.85 → 0.6rem) e gap
   tra icona e label ridotto (0.4 → 0.35rem) per stringere la nav. */
.nav-link {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.45rem 0.6rem;
    border-radius: 999px;
    color: var(--accent-dark);
    text-decoration: none;
    font-weight: 500;
    transition: background 0.15s, color 0.15s;
    line-height: 1.2;
}

.nav-link:hover {
    background: rgba(74, 124, 89, 0.10);
    color: var(--accent-dark);
    text-decoration: none;
}

.nav-icon {
    font-size: 1.05rem;
    line-height: 1;
}
/* Icone navbar come immagini (illustrazioni) al posto di emoji/SVG. */
.nav-link .nav-icon-img {
    width: 2.5rem;
    height: 2.5rem;
    display: block;
    object-fit: contain;
    flex-shrink: 0;
}
/* Navbar su una riga: le voci a sinistra, il nome utente spinto a destra. Tema
   e logout sono nel footer, cosi' la navbar resta compatta e sta in 1200px. */
.auth-nav {
    flex: 1;
    min-width: 0;
}
.auth-nav .when-authenticated {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.3rem 0.4rem;
}
.auth-nav .when-authenticated .user-name {
    margin-left: auto;
}
/* Tema + logout nel footer: icona + testo, stile link discreto. Nascosti agli
   utenti anonimi (il footer e' visibile anche a loro). */
.footer-user-actions {
    display: flex;
    align-items: center;
    gap: 1rem;
}
body.auth-state-anonymous .footer-user-actions {
    display: none;
}
.footer-action-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--muted);
    font: inherit;
    padding: 0.2rem 0.3rem;
}
.footer-action-btn:hover {
    color: var(--fg);
    text-decoration: underline;
}
.footer-action-btn svg {
    width: 1rem;
    height: 1rem;
}

/* Divider verticale tra link di navigazione e blocco utente. */
.nav-divider {
    display: inline-block;
    width: 1px;
    height: 1.4rem;
    background: rgba(0, 0, 0, 0.12);
    margin: 0 0.2rem;
}

/* Chip utente: stesso pattern dei link ma con sfondo accent tenue
   per differenziarlo. */
.user-name {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.85rem;
    border-radius: 999px;
    background: rgba(74, 124, 89, 0.10);
    color: var(--fg);
    font-weight: 600;
    text-decoration: none;
    transition: background 0.15s;
    line-height: 1.2;
}

.user-name:hover {
    background: rgba(74, 124, 89, 0.20);
    color: var(--accent-dark);
    text-decoration: none;
}

/* Toggle dark mode: bottone tondo come il logout, ciclo auto/light/dark.
   Sta subito prima del logout nella nav header. */
.theme-toggle-form {
    display: inline;
    margin: 0 0 0 0.3rem;
}

.theme-toggle-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.2rem;
    height: 2.2rem;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 50%;
    color: var(--fg);
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 0;
    transition: border-color 0.15s, background 0.15s, transform 0.15s;
}

.theme-toggle-icon:hover {
    border-color: var(--accent);
    background: rgba(74, 124, 89, 0.10);
    transform: rotate(20deg);
}

.logout-form {
    display: inline;
    margin: 0 0 0 0.4rem;   /* margine sinistro: separa dal theme toggle */
}

/* Bottone "Esci": icona tonda, separata visivamente dal resto della
   nav. Hover diventa rossastro (azione "uscita"). */
.logout-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.2rem;
    height: 2.2rem;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 50%;
    color: var(--muted);
    cursor: pointer;
    font-size: 1.1rem;
    line-height: 1;
    transition: border-color 0.15s, background 0.15s, transform 0.15s;
    padding: 0;
}

.logout-icon:hover {
    border-color: #b04444;
    background: rgba(176, 68, 68, 0.08);
    color: #b04444;
    transform: translateX(2px);
}

/* SVG inline ridimensionato al bottone (usa currentColor cos&igrave;
   eredita color in hover/normale). */
.logout-icon svg {
    width: 1.05rem;
    height: 1.05rem;
    display: block;
}

/* `.link-button` resta disponibile per altri usi inline (es. form
   sottoposti come link nel resto dell'app), niente pi&ugrave; nella nav. */
.link-button {
    background: none;
    border: none;
    color: var(--accent);
    cursor: pointer;
    padding: 0;
    font: inherit;
    text-decoration: underline;
}

.link-button:hover {
    text-decoration: none;
}

/* Mobile: nascondi le label dei link, lascia solo le icone (compatto). */
@media (max-width: 700px) {
    .nav-link .nav-label {
        display: none;
    }
    .nav-link {
        padding: 0.4rem 0.6rem;
    }
    /* User name: tieni la label perch&eacute; senza nome &egrave; un po' anonimo. */
    .nav-divider {
        display: none;
    }
    .auth-nav {
        gap: 0.2rem;
    }
    /* Slice nav-1: il vecchio form inline e' stato sostituito da un
       bottone modale (.header-search-btn) sempre della stessa
       dimensione touch su mobile. Niente media query specifiche piu'
       necessarie qui (il dialog occupa quasi tutta la viewport via
       max-width: 28rem + width: calc(100% - 2rem)). */
}

/* Visibilità nav in base allo stato di auth (impostato sul body). */
body.auth-state-anonymous .when-authenticated { display: none; }
body.auth-state-authenticated .when-anonymous { display: none; }

/* Link contestuali nelle pagine /login e /register: mostro solo l'altro
   (se sei sulla pagina di login non ha senso il link "Accedi"). */
body.page-login .when-anonymous a[href="/login"] { display: none; }
body.page-register .when-anonymous a[href="/register"] { display: none; }

/* Slice mod_footer: il flex dello sticky-footer e' consolidato sul
   blocco .site-main principale (vedi sopra, flex: 1 0 auto). Qui resta
   solo lo styling cromatico del footer. */
.site-footer {
    color: var(--muted);
    font-size: 0.85rem;
    border-top: 1px solid rgba(0, 0, 0, 0.08);
}

/* ── Hero (home post-login) ─────────────────────────────────────────────── */

.hero {
    margin-top: 2rem;
}

.hero h2 {
    font-size: 2rem;
    margin: 0 0 0.5rem;
}

.hero-sub {
    color: var(--muted);
    margin: 0;
}

.hero-sub code {
    background: #ece6dc;
    padding: 0.1rem 0.4rem;
    border-radius: 4px;
    font-size: 0.95rem;
}

/* ── Card auth (login/register) ─────────────────────────────────────────── */

.auth-card {
    max-width: 480px;
    margin: 2rem auto;
    background: var(--card-bg);
    padding: 1.75rem 1.75rem 1.5rem;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.auth-card h2 {
    margin: 0 0 1.25rem;
    color: var(--accent);
    font-size: 1.5rem;
}

.auth-form {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

/* ── Continua con Google (slice Google OAuth) ──────────────────────────── */
/* Bottone full-width sopra il form email/password nella login card.
   Stile aderente alle Google Brand Guidelines (Sign in with Google):
   sfondo bianco, bordo grigio, testo nero, logo Google ufficiale a
   sinistra, no shadow pesante. Hover: leggero alone azzurro Google.
   Non viene reso se l'host non e' autorizzato (vedi server.py). */
.google-signin-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    width: 100%;
    padding: 0.7rem 1rem;
    margin: 0 0 0.5rem;
    background: #fff;
    color: #1f1f1f;
    border: 1px solid #dadce0;
    border-radius: 8px;
    font: inherit;
    font-size: 0.95rem;
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s;
}

.google-signin-btn:hover {
    background: #f8faff;
    border-color: #d2e3fc;
    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.18);
    text-decoration: none;
    color: #1f1f1f;
}

.google-signin-btn:active {
    background: #eef3fe;
    border-color: #c2d7fb;
}

.google-signin-icon {
    /* !important: stesso pattern di .profile-google-icon — alcuni
       browser ignorano width/height CSS sugli SVG inline (la G di
       Google diventa "responsive" e riempie il container). Anche
       l'SVG ha width/height attributi HTML in _render_login. */
    width: 1.1rem !important;
    height: 1.1rem !important;
    flex-shrink: 0;
}

/* Divisore "oppure" tra bottone Google e form email/password.
   Linea orizzontale con il testo "oppure" centrato sopra di essa. */
.auth-divider {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0.85rem 0;
    color: var(--muted);
    font-size: 0.82rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.auth-divider::before,
.auth-divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--border);
}

.auth-divider span {
    padding: 0 0.25rem;
}

/* Dark mode: il bottone Google bianco-bianco stride col fondo scuro.
   Allunghiamo il bordo e gli diamo un grigio caldo per riconoscibilita'. */
:root[data-theme="dark"] .google-signin-btn {
    background: #1f1f1f;
    color: #e3e3e3;
    border-color: #5f6368;
}

:root[data-theme="dark"] .google-signin-btn:hover {
    background: #2a2a2a;
    border-color: #8ab4f8;
    box-shadow: 0 1px 2px rgba(138, 180, 248, 0.18);
    color: #e3e3e3;
}

@media (prefers-color-scheme: dark) {
    :root[data-theme="auto"] .google-signin-btn {
        background: #1f1f1f;
        color: #e3e3e3;
        border-color: #5f6368;
    }
    :root[data-theme="auto"] .google-signin-btn:hover {
        background: #2a2a2a;
        border-color: #8ab4f8;
        box-shadow: 0 1px 2px rgba(138, 180, 248, 0.18);
    }
}

.field {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-size: 0.9rem;
}

.field > span {
    color: var(--muted);
    font-weight: 500;
}

.field input[type="text"],
.field input[type="email"],
.field input[type="password"],
.field input[type="number"],
.field input[type="date"],
.field input[type="search"],
.field select,
.field textarea {
    padding: 0.55rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    font: inherit;
    background: var(--card-bg);
}

/* Ricerca specie nel form vaso: input sopra al <select size="8">.
   Margin in basso minimo per dare un piccolo respiro al select. */
.field .species-search-input {
    margin-bottom: 0.35rem;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
    border-color: var(--accent);
}

/* Stato disabled (per i campi Da/A nei filtri diario quando il range non e'
   "Personalizzato"). Visivamente sbiaditi cos&igrave; l'utente capisce che non
   sono interagibili. */
.field input:disabled,
.field select:disabled,
.field textarea:disabled {
    background: rgba(0, 0, 0, 0.04);
    color: var(--muted);
    cursor: not-allowed;
}

/* Slice mod_selectbox (giu 2026): stile BASE uniforme per tutte le
   <select>, incluse quelle fuori da un .field (es. il menu "stato" nei
   feedback admin) che altrimenti mostrano il look nativo del browser
   (bordo nero, font di sistema). Le select dentro contenitori con stile
   dedicato (.field, .pot-form, .recipe-row, ...) NON cambiano: i loro
   selettori sono piu' specifici e vincono su questa regola generica. */
select {
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    font: inherit;
    background: var(--card-bg);
    color: inherit;
    cursor: pointer;
}
select:focus {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
    border-color: var(--accent);
}

.field-checkbox {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.9rem;
    color: var(--muted);
    cursor: pointer;
    margin-top: 0.25rem;
}

/* Variante per checkbox con testo lungo multi-riga (es. consenso GDPR
   PlantNet nel signup): allinea il checkbox in alto invece che al
   centro del paragrafo, e da' un padding di lettura piu' generoso. */
.field-checkbox-consent {
    align-items: flex-start;
    gap: 0.6rem;
    margin-top: 0.75rem;
    color: var(--ink);
    line-height: 1.45;
    cursor: default; /* il click sul testo lungo non e' intuitivo come toggle */
}
.field-checkbox-consent input[type="checkbox"] {
    /* Allinea verticalmente con la prima riga di testo (un po' di
       offset compensa la baseline della checkbox vs quella del testo). */
    margin-top: 0.2rem;
    flex-shrink: 0;
    cursor: pointer;
}
.field-checkbox-consent small {
    display: block;
    margin-top: 0.3rem;
    color: var(--muted);
    font-size: 0.85rem;
}

.primary-button {
    margin-top: 0.75rem;
    padding: 0.75rem 1rem;
    background: var(--accent);
    color: #fff;
    border: none;
    border-radius: 6px;
    font: inherit;
    font-weight: 600;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: background 0.15s;
}

.primary-button:hover {
    background: var(--accent-dark);
}

/* Slice FOTO-4 (giu 2026): stato "caricamento" del bottone upload foto.
   Mostra uno spinner rotante accanto alla label "Caricamento…" e
   disabilita visivamente il bottone. Generico: vale per qualsiasi
   .primary-button.is-uploading. */
.primary-button.is-uploading {
    opacity: 0.85;
    cursor: progress;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
}
.primary-button.is-uploading::before {
    content: "";
    width: 1em;
    height: 1em;
    border: 2px solid rgba(255, 255, 255, 0.45);
    border-top-color: #fff;
    border-radius: 50%;
    animation: upload-spin 0.6s linear infinite;
    flex: 0 0 auto;
}
@keyframes upload-spin {
    to { transform: rotate(360deg); }
}

/* Bottone secondario: look outline / ghost, meno prominente del primary.
   Usato per azioni "lateralmente importanti" come "+ Nuova fitopatia" nel
   detail vaso. */
.secondary-button {
    display: inline-block;
    padding: 0.4rem 0.85rem;
    background: rgba(255, 255, 255, 0.8);
    color: var(--accent);
    border: 1px solid var(--accent);
    border-radius: 6px;
    font: inherit;
    font-weight: 600;
    font-size: 0.9rem;
    letter-spacing: 0.02em;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.secondary-button:hover {
    background: var(--accent);
    color: #fff;
}

.error,
.success {
    border-radius: 6px;
    padding: 0.65rem 0.85rem;
    font-size: 0.9rem;
    margin-bottom: 0.75rem;
}

.error {
    background: var(--error-bg);
    color: var(--error-fg);
    border: 1px solid var(--error-border);
}

.success {
    background: #e2f0e6;
    color: #2d5a3a;
    border: 1px solid #b8d8c2;
}

/* Quando il template stampa un messaggio vuoto, il div resta nel DOM ma
   vuoto: queste regole lo nascondono. */
.error:empty,
.success:empty {
    display: none;
}

/* ── Nav header: link "Catalogo" ────────────────────────────────────────── */

.auth-nav .nav-link {
    color: var(--accent);
    text-decoration: none;
    font-weight: 500;
    margin-right: 0.5rem;
}

.auth-nav .nav-link:hover {
    text-decoration: underline;
}

/* ── Catalogo (pagina indice) ───────────────────────────────────────────── */

.catalog {
    margin: 1.5rem auto;
}

.catalog h2 {
    color: var(--accent);
    margin: 0 0 0.5rem;
}

/* Breadcrumb di routing sopra il titolo di pagina. Pill bianca opaca
   per restare leggibile sopra le immagini di sfondo stagionali; resta
   "inline" cos&igrave; non occupa l'intera larghezza. */
.breadcrumb {
    display: inline-block;
    margin: 0 0 0.75rem;
    padding: 0.25rem 0.7rem;
    background: var(--chrome-bg);
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--fg);
    font-size: 0.85rem;
}

.breadcrumb a {
    color: var(--accent);
    text-decoration: none;
}

.breadcrumb a:hover {
    color: var(--accent-dark);
    text-decoration: underline;
}

.catalog-intro {
    color: var(--muted);
    margin: 0 0 0.75rem;
}

.catalog-note {
    color: var(--muted);
    font-size: 0.85rem;
    margin: 0 0 1.5rem;
    font-style: italic;
}

.catalog-list {
    list-style: none;
    padding: 0;
    margin: 1.5rem 0 0;
    display: grid;
    gap: 0.75rem;
}

.catalog-entry {
    background: var(--card-bg);
    border-radius: 8px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
    transition: transform 0.1s, box-shadow 0.15s;
}

.catalog-entry a {
    display: block;
    padding: 1rem 1.25rem;
    text-decoration: none;
    color: inherit;
}

.catalog-entry a:hover {
    background: rgba(74, 124, 89, 0.04);
}

.catalog-entry h3 {
    margin: 0 0 0.25rem;
    color: var(--accent);
    font-size: 1.1rem;
}

.catalog-entry p {
    margin: 0;
    color: var(--muted);
    font-size: 0.9rem;
}

.catalog-entry.disabled {
    opacity: 0.55;
    padding: 1rem 1.25rem;
}

.catalog-entry.disabled h3 {
    color: var(--muted);
}

/* ── Catalogo componenti ────────────────────────────────────────────────── */

.catalog-content {
    margin-top: 1rem;
}

.catalog-section {
    margin-bottom: 2rem;
}

.catalog-section h3 {
    color: var(--accent);
    margin: 0 0 0.75rem;
    font-size: 1.1rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
    padding-bottom: 0.35rem;
}

.component-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 0.75rem;
}

.component-card {
    background: var(--card-bg);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    border-left: 4px solid var(--accent);
}

.component-card.cat-matrice    { border-left-color: #6b8e3d; }  /* verde scuro */
.component-card.cat-inerte     { border-left-color: #9a9a9a; }  /* grigio */
.component-card.cat-bonsai     { border-left-color: #b58a44; }  /* ocra */
.component-card.cat-carbone    { border-left-color: #2b2b2b; }  /* nero */
.component-card.cat-organico   { border-left-color: #8b5a2b; }  /* marrone */

.component-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
    margin-bottom: 0.4rem;
}

.component-head h4 {
    margin: 0;
    font-size: 1rem;
    color: var(--fg);
}

.component-slug {
    font-family: ui-monospace, "Cascadia Code", "SF Mono", Consolas, monospace;
    font-size: 0.75rem;
    color: var(--muted);
    background: rgba(0, 0, 0, 0.04);
    padding: 0.1rem 0.35rem;
    border-radius: 3px;
}

.component-descr {
    margin: 0 0 0.5rem;
    color: var(--fg);
    font-size: 0.9rem;
    line-height: 1.4;
}

.component-stats {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.15rem 0.5rem;
    margin: 0 0 0.5rem;
    font-size: 0.85rem;
}

.component-stats dt {
    color: var(--muted);
    font-weight: 500;
}

.component-stats dd {
    margin: 0;
    color: var(--fg);
}

.component-note {
    margin: 0;
    font-size: 0.82rem;
    color: var(--muted);
    border-top: 1px dashed rgba(0, 0, 0, 0.08);
    padding-top: 0.4rem;
    line-height: 1.4;
}

/* ── Catalogo substrati ─────────────────────────────────────────────────── */

.substrate-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 0.85rem;
}

.substrate-card {
    background: var(--card-bg);
    border-radius: 8px;
    padding: 1rem 1.1rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    border-left: 4px solid var(--accent);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.substrate-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
}

.substrate-head h4 {
    margin: 0;
    font-size: 1.05rem;
    color: var(--fg);
}

.substrate-slug {
    font-family: ui-monospace, "Cascadia Code", "SF Mono", Consolas, monospace;
    font-size: 0.75rem;
    color: var(--muted);
    background: rgba(0, 0, 0, 0.04);
    padding: 0.1rem 0.35rem;
    border-radius: 3px;
}

.substrate-descr {
    margin: 0;
    color: var(--fg);
    font-size: 0.9rem;
    line-height: 1.4;
}

.substrate-stats {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.15rem 0.5rem;
    margin: 0;
    font-size: 0.85rem;
}

.substrate-stats dt {
    color: var(--muted);
    font-weight: 500;
}

.substrate-stats dd {
    margin: 0;
    color: var(--fg);
}

.substrate-recipe {
    background: rgba(74, 124, 89, 0.06);
    padding: 0.5rem 0.75rem;
    border-radius: 5px;
}

.substrate-recipe h5 {
    margin: 0 0 0.35rem;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--accent);
    font-weight: 600;
}

.recipe-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    font-size: 0.85rem;
}

.recipe-list li {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
}

.recipe-comp {
    color: var(--fg);
}

.recipe-pct {
    font-variant-numeric: tabular-nums;
    color: var(--accent);
    font-weight: 600;
    min-width: 3em;
    text-align: right;
}

.recipe-empty {
    margin: 0;
    color: var(--muted);
    font-size: 0.85rem;
    font-style: italic;
}

.substrate-note {
    margin: 0;
    font-size: 0.82rem;
    color: var(--muted);
    border-top: 1px dashed rgba(0, 0, 0, 0.08);
    padding-top: 0.4rem;
    line-height: 1.4;
}

/* ── Catalogo piante ────────────────────────────────────────────────────── */

.catalog-section .count {
    color: var(--muted);
    font-weight: 400;
    font-size: 0.9rem;
    margin-left: 0.25rem;
}

.species-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 0.85rem;
}

.species-card {
    background: var(--card-bg);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    border-left: 4px solid var(--accent);
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.species-head {
    display: flex;
    gap: 0.6rem;
    align-items: center;
}

.species-icon {
    font-size: 1.6rem;
    line-height: 1;
}

.species-titles {
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
    min-width: 0;
}

.species-titles h4 {
    margin: 0;
    font-size: 1rem;
    color: var(--fg);
}

.species-scientific {
    font-style: italic;
    color: var(--muted);
    font-size: 0.85rem;
}

.species-meta {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.78rem;
}

.species-family {
    color: var(--accent);
    background: rgba(74, 124, 89, 0.08);
    padding: 0.1rem 0.45rem;
    border-radius: 10px;
    font-weight: 500;
}

.species-slug {
    font-family: ui-monospace, "Cascadia Code", "SF Mono", Consolas, monospace;
    font-size: 0.72rem;
    color: var(--muted);
    background: rgba(0, 0, 0, 0.04);
    padding: 0.1rem 0.35rem;
    border-radius: 3px;
}

.species-descr {
    margin: 0;
    color: var(--fg);
    font-size: 0.88rem;
    line-height: 1.4;
}

.months-bar {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 2px;
    margin: 0.1rem 0;
}

.month {
    text-align: center;
    font-size: 0.65rem;
    font-weight: 600;
    padding: 0.2rem 0;
    border-radius: 3px;
    color: #fff;
    text-transform: uppercase;
    cursor: help;
}

.month-active     { background: var(--accent); }
.month-transition { background: #c79939; }
.month-dormant    { background: #c4bfb6; color: #6b6b6b; }

/* Slice H3a: chips dei mesi di concimazione. Stesso layout della
   months-bar ma palette dedicata: arancio per "concimare" (on),
   grigio chiaro per "non concimare" (off). Cosi' a colpo d'occhio
   l'utente distingue le 2 informazioni (attivita' vegetativa vs
   concimazione) senza confondersi. */
.months-bar-label {
    font-size: 0.72rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin: 0.5rem 0 0.1rem;
    font-weight: 600;
}
.month-fert-on  { background: #d97706; }
/* `fert-off` riusa la palette di `month-dormant` per coerenza visiva
   con la barra "Attivit&agrave; vegetativa" sopra: stesso grigio, stesso
   color del testo. Risolve un problema di contrasto su tema scuro
   dove il chip era quasi invisibile sul bg della card. */
.month-fert-off { background: #c4bfb6; color: #6b6b6b; }
.legend-fert {
    font-size: 0.72rem;
    color: var(--muted);
}

/* Slice H3b: griglia stadi fenologici × 12 mesi nella detail specie.
   Table layout per allineamento perfetto (head mese + righe stadio).
   Celle "on" colorate con il colore distintivo dello stadio (passato
   via inline style), "off" grigio chiaro. */
.phenology-calendar-wrap {
    overflow-x: auto;
    margin: 0.3rem 0 0.5rem;
    /* Scrollbar visibile su mobile per indicare che la griglia
       continua a destra (Stadi fenologici × 12 mesi non sta in
       340-400px). Su desktop la barra resta sottile e auto. */
    scrollbar-width: thin;
}
@media (max-width: 720px) {
    .phenology-calendar-wrap {
        /* Hint visivo "shadow di scroll" sul bordo destro: indica
           che c'è altro contenuto da scorrere. Non blocca lo scroll. */
        background:
            linear-gradient(to right, var(--card-bg) 30%, transparent),
            linear-gradient(to left, var(--card-bg) 30%, transparent) right,
            linear-gradient(to right, rgba(0,0,0,0.10), transparent),
            linear-gradient(to left, rgba(0,0,0,0.10), transparent) right;
        background-repeat: no-repeat;
        background-size: 30px 100%, 30px 100%, 12px 100%, 12px 100%;
        background-attachment: local, local, scroll, scroll;
    }
    .phenology-calendar {
        font-size: 0.68rem;
    }
    .phenology-calendar th,
    .phenology-calendar td {
        padding: 0.15rem 0.2rem;
    }
}

/* Label "Stadi fenologici" merita pi&ugrave; aria perch&eacute; inizia una
   sezione concettualmente distinta dalle 2 barre di mesi sopra. */
.months-bar-label-phenology {
    margin-top: 1.4rem;
}
.phenology-calendar {
    border-collapse: collapse;
    width: 100%;
    font-size: 0.72rem;
}
.phenology-calendar th,
.phenology-calendar td {
    text-align: center;
    padding: 0.18rem 0.25rem;
    border: 1px solid rgba(0, 0, 0, 0.06);
}
.phenology-month-head {
    background: rgba(0, 0, 0, 0.04);
    text-transform: uppercase;
    font-weight: 600;
    color: var(--muted);
    letter-spacing: 0.05em;
}
.phenology-stage-head {
    background: rgba(0, 0, 0, 0.04);
    text-align: left;
    color: var(--muted);
    font-weight: 600;
    padding-left: 0.5rem;
}
.phenology-stage-label {
    background: rgba(0, 0, 0, 0.02);
    text-align: left;
    font-weight: 500;
    padding-left: 0.5rem;
    white-space: nowrap;
}
/* Rettangolino colorato accanto alla label dello stadio (palette
   distintiva per ciascuno: dormienza marrone, fioritura arancio,
   ecc.). Stessa proporzione delle celle della griglia per
   richiamarne la palette. */
.phenology-stage-dot {
    display: inline-block;
    width: 0.95rem;
    height: 0.95rem;
    border-radius: 3px;
    margin-right: 0.5rem;
    vertical-align: middle;
}
.phenology-cell-on {
    color: #fff;
    font-size: 0.65rem;
}
.phenology-cell-off {
    background: #f7f5f0;
}
.phenology-disclaimer {
    font-size: 0.72rem;
    color: var(--muted);
    font-style: italic;
    margin-top: 0.4rem;
}

.species-stats {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.15rem 0.5rem;
    margin: 0;
    font-size: 0.83rem;
}

.species-stats dt {
    color: var(--muted);
    font-weight: 500;
}

.species-stats dd {
    margin: 0;
    color: var(--fg);
}

.species-stats dd a {
    color: var(--accent);
    text-decoration: none;
}

.species-stats dd a:hover {
    text-decoration: underline;
}

.species-note {
    margin: 0;
    font-size: 0.8rem;
    color: var(--muted);
    border-top: 1px dashed rgba(0, 0, 0, 0.08);
    padding-top: 0.4rem;
    line-height: 1.4;
}

/* ── Catalogo fertilizzanti ─────────────────────────────────────────────── */

.fertilizer-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 0.85rem;
}

.fertilizer-card {
    background: var(--card-bg);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    border-left: 4px solid var(--accent);
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.fert-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
}

.fert-head h4 {
    margin: 0;
    font-size: 1rem;
    color: var(--fg);
}

.fert-meta {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    font-size: 0.75rem;
}

.fert-brand {
    background: rgba(74, 124, 89, 0.12);
    color: var(--accent);
    padding: 0.1rem 0.5rem;
    border-radius: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.fert-form {
    background: rgba(0, 0, 0, 0.04);
    color: var(--muted);
    padding: 0.1rem 0.5rem;
    border-radius: 10px;
}

.fert-organic {
    background: rgba(107, 142, 61, 0.1);
    color: #6b8e3d;
    padding: 0.1rem 0.5rem;
    border-radius: 10px;
    font-weight: 500;
}

.fert-descr {
    margin: 0;
    color: var(--fg);
    font-size: 0.88rem;
    line-height: 1.4;
}

.fert-npk {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
    background: rgba(74, 124, 89, 0.08);
    padding: 0.4rem 0.8rem;
    border-radius: 6px;
    font-size: 0.85rem;
    width: fit-content;
}

.fert-npk span {
    color: var(--muted);
    font-weight: 500;
}

.fert-npk strong {
    color: var(--accent);
    font-size: 1.05rem;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.05em;
}

.fert-stats {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.15rem 0.5rem;
    margin: 0;
    font-size: 0.83rem;
}

.fert-stats dt {
    color: var(--muted);
    font-weight: 500;
}

.fert-stats dd {
    margin: 0;
    color: var(--fg);
}

.fert-note {
    margin: 0;
    font-size: 0.8rem;
    color: var(--muted);
    border-top: 1px dashed rgba(0, 0, 0, 0.08);
    padding-top: 0.4rem;
    line-height: 1.4;
}

/* Anchor highlight: card richiamata via #<slug> */
.fertilizer-card:target {
    box-shadow: 0 0 0 2px var(--accent), 0 1px 3px rgba(0, 0, 0, 0.1);
}

/* ── Catalogo fitopatie ─────────────────────────────────────────────────── */

.disease-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
    gap: 0.85rem;
}

.disease-card {
    background: var(--card-bg);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    border-left: 4px solid var(--accent);
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

/* Bordo sinistro colorato in base al tipo di patologia */
.disease-card.disease-type-fungal       { border-left-color: #6b8e3d; } /* verde scuro */
.disease-card.disease-type-bacterial    { border-left-color: #c79939; } /* ocra */
.disease-card.disease-type-viral        { border-left-color: #8a4fbf; } /* viola */
.disease-card.disease-type-pest         { border-left-color: #a13434; } /* rosso parassita */
.disease-card.disease-type-deficiency   { border-left-color: #4a8caa; } /* blu */
.disease-card.disease-type-physiological { border-left-color: #888; }   /* grigio */

.disease-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.5rem;
}

.disease-titles {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

.disease-titles h4 {
    margin: 0;
    font-size: 1rem;
    color: var(--fg);
}

.disease-scientific {
    font-style: italic;
    color: var(--muted);
    font-size: 0.82rem;
}

.disease-badges {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    font-size: 0.75rem;
}

.disease-severity {
    padding: 0.1rem 0.5rem;
    border-radius: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.disease-severity-lieve     { background: rgba(199, 153, 57, 0.15); color: #8a6420; }
.disease-severity-moderata  { background: rgba(199, 99, 57, 0.18);  color: #a04a20; }
.disease-severity-grave     { background: rgba(161, 52, 52, 0.18);  color: #8a2020; }

.disease-contagious {
    background: rgba(138, 79, 191, 0.12);
    color: #6b3a99;
    padding: 0.1rem 0.5rem;
    border-radius: 10px;
    font-weight: 500;
}

.disease-symptoms {
    background: rgba(74, 124, 89, 0.05);
    border-left: 3px solid var(--accent);
    padding: 0.5rem 0.75rem;
    border-radius: 0 4px 4px 0;
    font-size: 0.88rem;
    line-height: 1.4;
    color: var(--fg);
}

.disease-stats {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.2rem 0.5rem;
    margin: 0;
    font-size: 0.83rem;
}

.disease-stats dt {
    color: var(--muted);
    font-weight: 500;
    align-self: start;
}

.disease-stats dd {
    margin: 0;
    color: var(--fg);
    line-height: 1.4;
}

.disease-meta {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin-top: 0.2rem;
}

.disease-groups {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

.disease-group {
    background: rgba(0, 0, 0, 0.04);
    color: var(--muted);
    padding: 0.1rem 0.5rem;
    border-radius: 10px;
    font-size: 0.75rem;
}

.disease-group-all {
    background: rgba(74, 124, 89, 0.1);
    color: var(--accent);
    font-weight: 500;
}

.disease-note {
    margin: 0;
    font-size: 0.8rem;
    color: var(--muted);
    border-top: 1px dashed rgba(0, 0, 0, 0.08);
    padding-top: 0.4rem;
    line-height: 1.4;
}

.disease-card:target {
    box-shadow: 0 0 0 2px var(--accent), 0 1px 3px rgba(0, 0, 0, 0.1);
}

/* Prodotti consigliati (pesticidi associati alla fitopatia via join) */
.treatment-pills-wrap {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.83rem;
    background: rgba(74, 124, 89, 0.05);
    padding: 0.5rem 0.7rem;
    border-radius: 6px;
}

.treatment-pills-label {
    color: var(--accent);
    font-weight: 500;
}

.treatment-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

.treatment-pill {
    background: rgba(74, 124, 89, 0.1);
    color: var(--accent);
    padding: 0.15rem 0.55rem;
    border-radius: 12px;
    font-size: 0.78rem;
    text-decoration: none;
    border: 1px solid rgba(74, 124, 89, 0.2);
}

.treatment-pill:hover {
    background: rgba(74, 124, 89, 0.2);
    text-decoration: none;
}

/* ── Catalogo materiali del vaso ────────────────────────────────────────── */

.material-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 0.85rem;
}

.material-card {
    background: var(--card-bg);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    border-left: 4px solid var(--accent);
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.material-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
}

.material-head h4 {
    margin: 0;
    font-size: 1rem;
    color: var(--fg);
}

.material-meta {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    font-size: 0.78rem;
}

.material-porosity {
    padding: 0.1rem 0.5rem;
    border-radius: 10px;
    font-weight: 500;
    text-transform: lowercase;
}

.material-porosity-molto-bassa { background: rgba(0, 0, 0, 0.08); color: var(--muted); }
.material-porosity-bassa       { background: rgba(0, 0, 0, 0.06); color: var(--muted); }
.material-porosity-moderata    { background: rgba(199, 153, 57, 0.15); color: #8a6420; }
.material-porosity-alta        { background: rgba(107, 142, 61, 0.15); color: #4a6630; }
.material-porosity-molto-alta  { background: rgba(74, 124, 89, 0.18); color: var(--accent); }

.material-breathable {
    background: rgba(74, 124, 89, 0.1);
    color: var(--accent);
    padding: 0.1rem 0.5rem;
    border-radius: 10px;
    font-weight: 500;
}

.material-descr {
    margin: 0;
    color: var(--fg);
    font-size: 0.88rem;
    line-height: 1.4;
}

.material-stats {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.15rem 0.5rem;
    margin: 0;
    font-size: 0.85rem;
}

.material-stats dt {
    color: var(--muted);
    font-weight: 500;
}

.material-stats dd {
    margin: 0;
    color: var(--fg);
    font-variant-numeric: tabular-nums;
}

.material-note {
    margin: 0;
    font-size: 0.8rem;
    color: var(--muted);
    border-top: 1px dashed rgba(0, 0, 0, 0.08);
    padding-top: 0.4rem;
    line-height: 1.4;
}

.material-card:target {
    box-shadow: 0 0 0 2px var(--accent), 0 1px 3px rgba(0, 0, 0, 0.1);
}

/* ── Vasi (entit&agrave; di dominio) ─────────────────────────────────────────── */

.action-buttons {
    display: flex;
    gap: 0.5rem;
    margin: 1rem 0;
    flex-wrap: wrap;
    align-items: center;
}

.action-buttons .primary-button,
.action-buttons .button-danger {
    display: inline-block;
    text-decoration: none;
    margin: 0;                  /* annulla margin-top di .primary-button */
    padding: 0.75rem 1rem;       /* identico tra i due bottoni */
    line-height: 1.2;
    box-sizing: border-box;
}

.button-danger {
    padding: 0.75rem 1rem;
    background: var(--error-bg);
    color: var(--error-fg);
    border: 1px solid var(--error-border);
    border-radius: 6px;
    font: inherit;
    font-weight: 600;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: background 0.15s;
}

.button-danger:hover {
    background: var(--error-border);
}

.inline-form {
    display: inline;
    margin: 0;
}

/* Icon-button per azioni rapide sulla card vaso (matita, cestino) */

.icon-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.85rem;
    height: 1.85rem;
    border-radius: 5px;
    background: transparent;
    border: 1px solid transparent;
    color: var(--muted);
    cursor: pointer;
    text-decoration: none;
    font-size: 0.95rem;
    line-height: 1;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.icon-button:hover {
    background: rgba(74, 124, 89, 0.1);
    color: var(--accent);
    border-color: rgba(74, 124, 89, 0.25);
}

.icon-button-danger:hover {
    background: rgba(138, 32, 32, 0.08);
    color: var(--error-fg);
    border-color: rgba(138, 32, 32, 0.25);
}

/* Etichette accessibili nascoste visualmente (per screen reader). */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ── Dialog di conferma (HTML5 <dialog>) ────────────────────────────────── */

.confirm-dialog {
    border: none;
    border-radius: 8px;
    padding: 0;
    background: var(--card-bg);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25);
    max-width: 440px;
    width: calc(100% - 2rem);
    color: var(--fg);
}

.confirm-dialog::backdrop {
    background: rgba(0, 0, 0, 0.4);
}

.confirm-dialog-form {
    padding: 1.5rem;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.confirm-dialog-title {
    margin: 0;
    color: var(--accent);
    font-size: 1.2rem;
}

.confirm-dialog-message {
    margin: 0;
    color: var(--fg);
    line-height: 1.5;
    font-size: 0.95rem;
}

.confirm-dialog-actions {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
    margin-top: 0.5rem;
}

.confirm-dialog-actions .primary-button,
.confirm-dialog-actions .button-danger {
    margin: 0;
    padding: 0.6rem 1rem;
    font-size: 0.95rem;
}

/* ── Page header (titolo + azioni allineati su una riga) ────────────────
   Pattern usato dalle pagine principali per allineare il titolo
   <h2> a sinistra e il bottone azione primario a destra (es.
   "+ Nuovo vaso"). Su mobile a <600px ricade in colonna per non
   schiacciare il bottone sotto al titolo lungo. */
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin: 0 0 1rem;
}

.page-header h2 {
    margin: 0;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

.page-header .primary-button {
    flex-shrink: 0;
}

/* Variante del titolo nel detail vaso: include un'icona grande
   (.detail-icon, 3rem) prima del nome del vaso e il bottone help dopo.
   `align-items: center` allinea verticalmente icona-titolo-`?` su una
   sola riga. */
.page-header .detail-head-title {
    gap: 0.65rem;
}

/* Raggruppa pi&ugrave; bottoni nell'angolo destro del .page-header (es.
   Modifica + Elimina vaso nel detail). Su mobile cade in nuova riga
   grazie al flex-wrap del genitore, ma i bottoni restano affiancati
   tra di loro. */
.page-header-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex-wrap: wrap;
}

.page-header-actions .primary-button,
.page-header-actions .secondary-button,
.page-header-actions .button-danger {
    margin: 0;
    text-decoration: none;
    padding: 0.6rem 0.95rem;
    line-height: 1.2;
}

/* Bottone "?" a cerchio per aprire il modal di aiuto contestuale.
   Pattern data-help-dialog="<id>" gestito da
   static/js/app.js::setupHelpDialogs. */
.help-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.6rem;
    height: 1.6rem;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: var(--card-bg);
    color: var(--accent);
    font-size: 0.9rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}

.help-btn:hover,
.help-btn:focus-visible {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
    outline: none;
}

/* ── Modal di aiuto contestuale (dialog HTML5) ────────────────────────── */
.help-dialog {
    border: none;
    border-radius: 8px;
    padding: 0;
    background: var(--card-bg);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25);
    max-width: 560px;
    width: calc(100% - 2rem);
    color: var(--fg);
}

.help-dialog::backdrop {
    background: rgba(0, 0, 0, 0.4);
}

.help-dialog-form {
    padding: 1.5rem;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.help-dialog-form h3 {
    margin: 0;
    color: var(--accent);
    font-size: 1.2rem;
}

/* Slice mod_help: sotto-titoli di gruppo nei dialog "guida colonne"
   (parametri tecnici / metriche agronomiche). */
.help-dialog-form h4 {
    margin: 0.4rem 0 -0.2rem;
    color: var(--accent-dark);
    font-size: 1rem;
}

.help-dialog-form p {
    margin: 0;
    line-height: 1.5;
}

.help-dialog-form ul {
    margin: 0;
    padding-left: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    line-height: 1.4;
}

.help-dialog-tip {
    margin-top: 0.25rem;
    padding: 0.65rem 0.85rem;
    background: rgba(74, 124, 89, 0.08);
    border-left: 3px solid var(--accent);
    border-radius: 4px;
    color: var(--fg);
    font-size: 0.92rem;
}

.help-dialog-actions {
    display: flex;
    justify-content: flex-end;
    margin-top: 0.5rem;
}

.actions-row {
    margin: 0.5rem 0 1.5rem;
}

.actions-row .primary-button {
    display: inline-block;
    text-decoration: none;
}

.empty-state {
    text-align: center;
    padding: 2.5rem 1rem;
    background: var(--card-bg);
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    color: var(--muted);
}

.empty-state h3 {
    color: var(--accent);
    margin: 0 0 0.5rem;
}

.empty-state p {
    margin: 0.25rem 0;
}

.empty-state .primary-button {
    display: inline-block;
    text-decoration: none;
    margin-top: 0.75rem;
}

/* Toolbar di ricerca della pagina /vasi (slice ricerca vasi). Filtra le
   .pot-card via input testuale; il valore di data-search su ogni card e'
   label + specie + nome scientifico (lowercased dal server). Match
   accent-insensitive e case-insensitive in static/js/app.js
   setupPotsSearch. */
.pots-toolbar {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    flex-wrap: wrap;
    margin: 0 0 0.85rem;
    padding: 0.5rem 0.75rem;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
}

.pots-search-input {
    flex: 1 1 320px;
    min-width: 0;
    padding: 0.55rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    font: inherit;
    background: var(--card-bg);
}

.pots-search-input:focus {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
    border-color: var(--accent);
}

.pots-counter {
    color: var(--muted);
    font-size: 0.88rem;
    white-space: nowrap;
}

.pots-counter-visible {
    color: var(--accent);
    font-weight: 600;
}

.pots-counter-sep {
    margin: 0 0.2rem;
    color: var(--border);
}

.pots-empty-search {
    margin: 1rem 0;
    padding: 1.25rem;
    text-align: center;
    color: var(--muted);
    background: rgba(0, 0, 0, 0.03);
    border-radius: 6px;
    font-style: italic;
}

.pot-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 0.85rem;
}

/* ── Slice mod_grid (giu 2026, rev. mod_grid2): "I miei vasi" come
   griglia di TILE quadrati con foto di copertina. La card e' INTERAMENTE
   cliccabile (-> detail); al passaggio del mouse compare un TOOLTIP
   FLOTTANTE (sopra la card, non la copre) con le info + azioni.
   Max 5 colonne, card grandi. ──────────────────────────────────────── */
.pot-tile-grid {
    display: grid;
    /* Max 5 colonne: ogni colonna e' almeno (100% - 4 gap)/5, quindi
       non piu' di 5 ci stanno; su schermi stretti il floor 200px fa
       scendere il numero di colonne (responsive). */
    grid-template-columns: repeat(auto-fill,
        minmax(max(200px, calc((100% - 4 * 1rem) / 5)), 1fr));
    gap: 1rem;
}
.pot-tile {
    position: relative;
    aspect-ratio: 1 / 1;
    border-radius: 10px;
    background: var(--card-bg);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
    /* NIENTE overflow:hidden: il tooltip flottante deve poter sporgere
       oltre i bordi della card. L'arrotondamento foto/caption e' sul
       link interno. */
}
.pot-tile-link {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 10px;
    overflow: hidden;
    text-decoration: none;
    color: inherit;
}
.pot-tile-visual,
.pot-tile-img {
    display: block;
    width: 100%;
    height: 100%;
}
.pot-tile-img {
    object-fit: cover;
}
.pot-tile-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    font-size: 4rem;
    background: linear-gradient(135deg,
        rgba(74, 124, 89, 0.14), rgba(74, 124, 89, 0.04));
}
.pot-tile-caption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 1.6rem 0.7rem 0.55rem;
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
    color: #fff;
    background: linear-gradient(to top,
        rgba(0, 0, 0, 0.74), rgba(0, 0, 0, 0));
    pointer-events: none;        /* il click passa al link sottostante */
    border-radius: 0 0 10px 10px;
}
.pot-tile-label {
    font-weight: 700;
    line-height: 1.15;
}
.pot-tile-species {
    font-size: 0.82rem;
    opacity: 0.92;
}
/* Tooltip flottante: appare SOPRA la card in hover/focus, senza coprirla.
   E' figlio di .pot-tile nel DOM -> l'hover sul tooltip mantiene
   .pot-tile:hover (continuita' garantita dalla leggera sovrapposizione
   bottom: calc(100% - 8px), niente gap "morto"). */
.pot-tile-tooltip {
    position: absolute;
    left: 50%;
    /* mod_grid2 (fix z-index, issue_07): il tooltip va SOTTO la card,
       non sopra: sopra la prima riga finiva dietro la nav sticky
       (z-index 50/200) e veniva tagliato. Sotto non incontra header
       sticky; lo z-index alto lo tiene sopra le card adiacenti. La
       leggera sovrapposizione (top: calc(100% - 8px)) evita il gap
       morto di hover. */
    top: calc(100% - 8px);
    transform: translateX(-50%);
    width: max(100%, 250px);
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.22);
    padding: 0.7rem 0.85rem;
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.12s ease;
}
.pot-tile:hover .pot-tile-tooltip,
.pot-tile:focus-within .pot-tile-tooltip,
.pot-tile.is-open .pot-tile-tooltip {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
}
/* mod_grid2: bottone "info" per TOUCH (tap -> apre il tooltip via JS).
   Su desktop (hover) e' un'affordance discreta che sparisce all'hover
   perche' il tooltip si apre da solo; su touch resta sempre visibile. */
.pot-tile-info-btn {
    position: absolute;
    top: 0.45rem;
    left: 0.45rem;
    z-index: 25;
    width: 1.8rem;
    height: 1.8rem;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: 0.95rem;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}
@media (hover: hover) {
    .pot-tile-info-btn { opacity: 0.55; transition: opacity 0.12s; }
    .pot-tile:hover .pot-tile-info-btn { opacity: 0; }
}
/* Slice ux-quicklog: bottone 💧 "irrigazione oggi" sulla tile, in alto
   a destra (l'info-btn sta a sinistra). Fuori dal link: la tile resta
   cliccabile. Sempre ben visibile: è l'azione quotidiana. */
.pot-tile-quick {
    position: absolute;
    top: 0.45rem;
    right: 0.45rem;
    z-index: 25;
    display: flex;
    gap: 0.28rem;
}
.pot-tile-quick-form { margin: 0; }
.pot-tile-quick-btn {
    width: 1.8rem;
    height: 1.8rem;
    padding: 0;
    border: none;
    border-radius: 50%;
    color: #fff;
    font-size: 0.95rem;
    line-height: 1;
    cursor: pointer;
    text-decoration: none;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.1s, background 0.12s, opacity 0.12s;
}
.pot-tile-quick-btn:hover { transform: scale(1.08); }
/* Colori per tipo: coerenti con la palette journal-cat (blue/teal/olive). */
.pot-tile-quick-irrigazione     { background: rgba(46, 96, 140, 0.75); }
.pot-tile-quick-irrigazione:hover { background: rgba(46, 96, 140, 0.95); }
.pot-tile-quick-fertirrigazione { background: rgba(58, 145, 145, 0.78); }
.pot-tile-quick-fertirrigazione:hover { background: rgba(44, 110, 110, 0.95); }
.pot-tile-quick-concimazione    { background: rgba(124, 138, 61, 0.8); }
.pot-tile-quick-concimazione:hover { background: rgba(88, 100, 43, 0.95); }
.pot-tile-quick-more            { background: rgba(0, 0, 0, 0.45); }
.pot-tile-quick-more:hover      { background: rgba(0, 0, 0, 0.65); }

/* Overlay "Altre attività": lista chip (riusa journal-type-btn-small). */
.quicklog-more-hint {
    color: var(--muted);
    font-size: 0.88rem;
    margin: 0.25rem 0 0.6rem;
}
.quicklog-more-list { margin-top: 0; }
.pot-tile-info-title {
    font-weight: 700;
    line-height: 1.2;
}
.pot-tile-info-species {
    font-size: 0.82rem;
    color: var(--muted);
}
.pot-tile-tooltip .pot-stats {
    margin: 0;
}
.pot-tile-tooltip .pot-card-actions {
    margin-top: 0.3rem;
}
.pot-tile-alert {
    position: absolute;
    top: 0.55rem;  /* centrato otticamente sulla fila dei bottoni */
    /* Slice ux-quicklog (estensione): la fila di bottoni rapidi occupa
       tutto l'angolo in alto a destra -> il badge fitopatie sta a
       sinistra, accanto al bottone info. */
    left: 2.55rem;
    z-index: 2;
    background: #b04444;
    color: #fff;
    font-size: 0.75rem;
    font-weight: 700;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    text-decoration: none;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}

/* Nasconde le card filtrate dalla ricerca testuale. Vedi
   app.js::setupPotsSearch. Regola esplicita perch&eacute; l'attributo
   HTML5 ``hidden`` su un grid item pu&ograve; essere ignorato in alcuni
   browser/setup. */
.pot-card[data-search-hidden="true"] {
    display: none;
}

.pot-card {
    background: var(--card-bg);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    border-left: 4px solid var(--accent);
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    /* Necessario per il banner .pot-card-alert: il banner usa margini
       negativi per arrivare ai bordi della card e va clippato dal
       border-radius (8px) per non sporgere agli angoli alti. */
    overflow: hidden;
}

.pot-head {
    display: flex;
    gap: 0.6rem;
    align-items: flex-start;
}

.pot-icon {
    font-size: 1.6rem;
    line-height: 1;
    margin-top: 0.1rem;
}

/* Slice FOTO-1 (giu 2026): foto di copertina nelle schede vaso.
   Thumbnail quadrata 48px al posto dell'emoji specie quando il vaso
   ha almeno una foto. object-fit cover per riempire senza distorcere. */
.pot-icon-photo {
    font-size: 0;          /* annulla lo spazio dell'emoji ereditato */
    margin-top: 0;
    flex: 0 0 auto;
}
.pot-icon-photo img {
    width: 48px;
    height: 48px;
    object-fit: cover;
    border-radius: 8px;
    display: block;
    background: rgba(0, 0, 0, 0.04);
}

.pot-titles {
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
    min-width: 0;
    flex: 1;                /* spinge .pot-card-actions a destra */
}

.pot-card-actions {
    display: flex;
    gap: 0.2rem;
    align-self: flex-start;
}

.pot-titles h4 {
    margin: 0;
    font-size: 1.05rem;
    color: var(--fg);
}

.pot-titles h4 a {
    color: inherit;
    text-decoration: none;
}

.pot-titles h4 a:hover {
    color: var(--accent);
    text-decoration: underline;
}

.pot-species {
    color: var(--accent);
    font-weight: 500;
    font-size: 0.85rem;
}

.pot-scientific {
    font-style: italic;
    color: var(--muted);
    font-size: 0.78rem;
}

.pot-stats {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.15rem 0.5rem;
    margin: 0;
    font-size: 0.83rem;
}

.pot-stats dt {
    color: var(--muted);
    font-weight: 500;
}

.pot-stats dd {
    margin: 0;
    color: var(--fg);
}

.pot-stats dd a {
    color: var(--accent);
    text-decoration: none;
}

.pot-stats dd a:hover {
    text-decoration: underline;
}

/* Form 'Nuovo vaso' */

.pot-form-card {
    /* Slice "pianifica per periodi": il form vaso include una griglia
       12-colonne (~700px). 540px stretto del form auth standard era
       troppo stretto su desktop e la griglia debordava (segnalazione
       utente 2026-05-24). 860px sta dentro tutto comodamente; resta
       responsive su tablet/mobile via i media query del .auth-card.
       NB: questa classe e' diventata un alias di .auth-card-wide
       (definita sotto): tenuta per backward-compat dei template che
       la usano gia'. */
    max-width: 860px;
}

/* Classe generica per i form "lunghi" (vaso, diario, fitopatia,
   substrato, calendario, profilo): allarga il container a 860px
   su desktop, mentre login/register restano stretti a 480px col
   default di .auth-card. Su mobile il viewport e' < 860 e il
   container occupa lo spazio disponibile (responsive). Aggiunta
   2026-05-24 dopo la segnalazione utente sul form vaso. */
.auth-card-wide {
    max-width: 860px;
}

.pot-form select,
.pot-form input[type="number"],
.pot-form input[type="date"],
.pot-form textarea {
    padding: 0.55rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    font: inherit;
    background: var(--card-bg);
    width: 100%;
}

.pot-form textarea {
    resize: vertical;
    min-height: 4em;
}

.pot-form select:focus,
.pot-form input:focus,
.pot-form textarea:focus {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
    border-color: var(--accent);
}

.pot-form .field-group {
    border: 1px solid rgba(0, 0, 0, 0.08);
    border-radius: 6px;
    padding: 0.6rem 0.85rem;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    /* Bugfix mag 2026: senza min-width:0 i flex items hanno min-width:auto
       (default) e NON shrinka se il content (es. griglia 12 col mese) ha
       larghezza naturale > container. Risultato visibile: il fieldset
       Fertilizzanti abituali sforava il modal su mobile. */
    min-width: 0;
}

/* Gruppi di campi dimensionali condizionali: HTML hidden attribute li
   nasconde via CSS; ridichiarato qui per chiarezza e per evitare che
   un display: flex genitore lo bypassi. */
.pot-form .dim-fields[hidden] {
    display: none;
}

.pot-form .dim-fields {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.pot-form .field-group legend {
    color: var(--accent);
    font-weight: 500;
    font-size: 0.82rem;
    padding: 0 0.35rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.field-error {
    color: var(--error-fg);
    font-size: 0.8rem;
    margin-top: 0.2rem;
}

.pot-form input[aria-invalid="true"],
.pot-form select[aria-invalid="true"] {
    border-color: var(--error-border);
    background: var(--error-bg);
}

/* ── Catalogo prodotti fitosanitari ─────────────────────────────────────── */

.pesticide-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
    gap: 0.85rem;
}

.pesticide-card {
    background: var(--card-bg);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    border-left: 4px solid var(--accent);
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

/* Bordo sinistro per tipo (allineato ai colori del catalogo fitopatie) */
.pesticide-card.pest-type-fungicide    { border-left-color: #6b8e3d; }
.pesticide-card.pest-type-insecticide  { border-left-color: #a13434; }
.pesticide-card.pest-type-acaricide    { border-left-color: #c79939; }
.pesticide-card.pest-type-multipurpose { border-left-color: #4a8caa; }
.pesticide-card.pest-type-molluscicide { border-left-color: #8a4fbf; }
.pesticide-card.pest-type-trap         { border-left-color: #888; }

.pest-mode {
    background: rgba(0, 0, 0, 0.05);
    color: var(--muted);
    padding: 0.1rem 0.5rem;
    border-radius: 10px;
    font-style: italic;
}

.pest-active {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    background: rgba(74, 124, 89, 0.06);
    padding: 0.4rem 0.7rem;
    border-radius: 6px;
    font-size: 0.83rem;
    line-height: 1.4;
}

.pest-active span {
    color: var(--muted);
    font-weight: 500;
    flex-shrink: 0;
}

.pest-active strong {
    color: var(--fg);
    font-weight: 500;
}

.pest-targets-wrap {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.83rem;
}

.pest-targets-label {
    color: var(--muted);
    font-weight: 500;
}

.pest-targets {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

.target-pill {
    background: rgba(161, 52, 52, 0.08);
    color: #8a3030;
    padding: 0.15rem 0.55rem;
    border-radius: 12px;
    font-size: 0.78rem;
    text-decoration: none;
    border: 1px solid rgba(161, 52, 52, 0.18);
}

.target-pill:hover {
    background: rgba(161, 52, 52, 0.15);
    text-decoration: none;
}

.target-pill-none {
    background: rgba(0, 0, 0, 0.04);
    color: var(--muted);
    border-color: transparent;
}

.target-pill-unmapped {
    background: rgba(0, 0, 0, 0.04);
    color: var(--muted);
    border-color: rgba(0, 0, 0, 0.08);
    cursor: help;
}

.pesticide-card:target {
    box-shadow: 0 0 0 2px var(--accent), 0 1px 3px rgba(0, 0, 0, 0.1);
}

/* ── Dettaglio pianta ───────────────────────────────────────────────────── */

.species-card .species-titles h4 a {
    color: inherit;
    text-decoration: none;
}

.species-card .species-titles h4 a:hover {
    color: var(--accent);
    text-decoration: underline;
}

.species-detail {
    margin: 1.5rem auto;
}

.detail-head {
    display: flex;
    gap: 1rem;
    align-items: center;
    margin: 1rem 0;
}

.detail-icon {
    font-size: 3rem;
    line-height: 1;
}

.detail-titles {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 0;
}

.detail-titles h2 {
    margin: 0;
    color: var(--fg);
    font-size: 1.6rem;
}

.detail-scientific {
    margin: 0;
    font-style: italic;
    color: var(--muted);
}

/* Versione inline del nome scientifico, usata nel page-header del detail
   pianta quando icona+nome+? sono allineati su una sola riga e il nome
   scientifico segue il nome comune in piccolo. */
.detail-scientific-inline {
    display: block;
    margin-top: 0.1rem;
    font-size: 0.85rem;
    font-style: italic;
    font-weight: normal;
    color: var(--muted);
}

.detail-meta {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    font-size: 0.8rem;
    margin-top: 0.25rem;
}

.detail-description {
    color: var(--fg);
    font-size: 1rem;
    margin: 0.5rem 0 1.5rem;
    line-height: 1.5;
}

.detail-sections {
    /* Slice modifiche grafiche: il container del detail vaso non &egrave; pi&ugrave;
       una grid (la grid &egrave; ora `.pot-detail-grid` interna, vedi sotto).
       Lasciamo solo il margin di chiusura per coerenza con il resto. */
    margin-bottom: 1.5rem;
}

/* Pagina /catalogo/piante/<slug> — slice species-detail-2card
   (lug 2026): DUE sole card. La card di testa (identita': famiglia,
   descrizione, nota) + un'unica card con tutte le informazioni,
   i cui blocchi (Substrato, Calendario, Luce, Temperatura, ...) si
   dispongono in una griglia interna auto-adattante. La classe
   ``.species-catalog-detail`` resta scoped al solo template
   ``catalogo_pianta_detail.html``. */
.species-catalog-detail .detail-sections {
    display: block;
}

.species-head-card {
    margin-bottom: 1rem;
}

/* Galleria foto della specie (sezione "## Foto" della scheda .md). */
.species-gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 0.6rem;
    margin: 0 0 0.9rem;
}

.species-gallery-single {
    grid-template-columns: minmax(0, 340px);
}

.species-photo {
    display: block;
    border-radius: 8px;
    overflow: hidden;
    aspect-ratio: 4 / 3;
    background: rgba(0, 0, 0, 0.05);
    border: 1px solid rgba(0, 0, 0, 0.06);
}

.species-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.2s ease;
}

.species-photo:hover img { transform: scale(1.03); }

.species-head-card .detail-meta { margin-top: 0; }

.species-head-card .detail-description {
    margin: 0.5rem 0 0;
}

.species-head-note {
    margin: 0.6rem 0 0;
    color: var(--muted);
    font-style: italic;
}

.species-head-note:empty { display: none; }

.species-blocks {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 1.1rem 1.6rem;
}

.species-block {
    min-width: 0;
}

.species-block-wide {
    grid-column: 1 / -1;
}

.species-block h4 {
    margin: 0 0 0.4rem;
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--accent-dark);
    border-bottom: 1px solid var(--border);
    padding-bottom: 0.25rem;
}

@media (max-width: 700px) {
    /* Mobile: blocchi in colonna singola; contenuti larghi
       (composizione substrato, months-bar 12 colonne) si adattano
       invece di sfondare il viewport. */
    .species-blocks {
        grid-template-columns: 1fr;
    }
    .species-catalog-detail .detail-card {
        min-width: 0;
        overflow-wrap: anywhere;
    }
    .species-catalog-detail .months-bar {
        gap: 1px;
    }
    .species-catalog-detail .month {
        font-size: 0.55rem;
        padding: 0.18rem 0;
    }
}

/* Grid 6 colonne per il detail vaso (slice modifiche grafiche).
   Ogni "slot" &egrave; un wrapper invisibile (`display: contents`) che applica
   `grid-column: span N` al figlio diretto (la card). Cos&igrave; non dobbiamo
   modificare le card pre-renderizzate da altri moduli. */
/* Slice H1: pannello "Hai appena rinvasato?" sopra la griglia del detail.
   Visibile solo per Pot creati da un rinvaso recente (≤ 7 gg), permette
   di annullare il rinvaso riattivando il Pot precedente. Pattern visuale
   alla "banner informativo + azione" — non sembra una sezione dati ma
   un'azione temporanea. */
.rinvaso-annulla-panel {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem;
    padding: 0.7rem 1rem;
    margin: 0 0 1rem 0;
    background: #faf5e9;
    border: 1px solid #e6d5a8;
    border-left: 3px solid #c79939;
    border-radius: 5px;
    font-size: 0.92rem;
    color: #5a4a20;
}

.rinvaso-annulla-text {
    flex: 1 1 28ch;
    min-width: 0;
    line-height: 1.4;
}

.rinvaso-annulla-text strong {
    color: #5a4a20;
}

.rinvaso-annulla-panel .inline-form {
    margin: 0;
    flex-shrink: 0;
}

/* Slice H2: banner di superseding (lineage navigation). Sopra la griglia
   del detail vaso, mostrano "Questo vaso è stato sostituito da..." sui
   Pot archiviati e "Sostituisce..." sui Pot nuovi da rinvaso. Pattern
   3-col: icona + testo (flex grow) + bottone azione. */
.lineage-banner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.8rem;
    padding: 0.75rem 1rem;
    margin: 0 0 1rem 0;
    border-radius: 5px;
    font-size: 0.93rem;
    line-height: 1.4;
}

.lineage-banner-icon {
    font-size: 1.4rem;
    flex-shrink: 0;
}

.lineage-banner-text {
    flex: 1 1 28ch;
    min-width: 0;
    color: #444;
}

.lineage-banner-text strong {
    color: var(--info-fg);
}

.lineage-banner-action {
    flex-shrink: 0;
}

.lineage-banner-archived {
    background: #f4f4f4;
    border: 1px solid #d4d4d4;
    border-left: 3px solid #888;
}

.lineage-banner-archived .lineage-banner-text strong {
    color: #555;
}

.lineage-banner-supersedes {
    background: #eef4ef;
    border: 1px solid #bfd1c5;
    border-left: 3px solid var(--accent-dark);
}

.lineage-banner-supersedes .lineage-banner-text strong {
    color: var(--accent-dark);
}

/* Slice H4: badge "In fase post-rinvaso fino al [data]". Stato del Pot
   nuovo durante la finestra di stress fisiologico (14-30 gg specie-
   specifica). Visivamente: palette verde-foglia chiara (la pianta si
   sta riprendendo), border-left accent verde per coerenza con il
   banner "sostituisce" che lo precede. */
.post-rinvaso-badge {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.7rem;
    padding: 0.65rem 1rem;
    margin: 0 0 1rem 0;
    background: #f0f6e8;
    border: 1px solid #c5d6a8;
    border-left: 3px solid #7c8a3d;
    border-radius: 5px;
    font-size: 0.92rem;
    line-height: 1.4;
    color: #4a5224;
}

.post-rinvaso-icon {
    font-size: 1.4rem;
    flex-shrink: 0;
}

.post-rinvaso-text {
    flex: 1 1 28ch;
    min-width: 0;
}

.post-rinvaso-text strong {
    color: #4a5224;
}

.post-rinvaso-remaining {
    color: #6a7228;
    font-weight: 600;
}

/* Slice H5: sub-banner con il riepilogo eventi spostati. */
.post-rinvaso-postponed {
    margin-top: 0.4rem;
    padding-top: 0.4rem;
    border-top: 1px dashed #c5d6a8;
    font-size: 0.88rem;
    color: #4a5224;
}

.post-rinvaso-postponed strong {
    color: #4a5224;
}

.post-rinvaso-postponed a {
    color: var(--accent-dark);
    text-decoration: underline;
}

.post-rinvaso-postponed a:hover {
    color: #2a4e34;
}

/* Toggle "Solo questo vaso fisico" vs "Storia completa del lineage". */
.lineage-toggle-panel {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem;
    padding: 0.65rem 1rem;
    margin: 0 0 1rem 0;
    background: var(--card-bg);
    border: 1px dashed #bcc3b1;
    border-radius: 5px;
    font-size: 0.9rem;
    color: #555;
}

.lineage-toggle-info {
    flex: 1 1 30ch;
    min-width: 0;
    line-height: 1.4;
}

.lineage-toggle-info strong {
    color: #1f3a5f;
}

.lineage-toggle-controls {
    display: flex;
    flex-shrink: 0;
    gap: 0.3rem;
    background: var(--bg);
    border: 1px solid #cfd2c8;
    border-radius: 999px;
    padding: 2px;
}

.lineage-toggle-btn {
    font-family: inherit;
    font-size: 0.85rem;
    background: transparent;
    border: none;
    color: #555;
    border-radius: 999px;
    padding: 0.25rem 0.8rem;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
    line-height: 1.3;
}

.lineage-toggle-btn:hover {
    background: rgba(74, 124, 89, 0.08);
}

.lineage-toggle-btn:focus-visible {
    outline: 2px solid var(--accent-dark);
    outline-offset: 1px;
}

.lineage-toggle-btn.lineage-toggle-active {
    background: var(--accent-dark);
    color: #fff;
    font-weight: 600;
}

/* Stato "filtrato" applicato dal JS quando il toggle è in modalita
   'single': nasconde gli elementi dei Pot non corrispondenti al pot_id
   corrente. Stesso pattern di data-search-hidden / data-alert-filtered. */
[data-lineage-pot-id][data-lineage-hidden="true"] {
    display: none;
}

.pot-detail-grid {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.pot-detail-grid .pdc-slot {
    display: contents;
}

.pot-detail-grid .pdc-posizione         > * { grid-column: span 3; }
.pot-detail-grid .pdc-date              > * { grid-column: span 3; }
.pot-detail-grid .pdc-fitopatie         > * { grid-column: span 3; }
.pot-detail-grid .pdc-fitopatie-storico > * { grid-column: span 3; }
.pot-detail-grid .pdc-preset            > * { grid-column: span 3; }
.pot-detail-grid .pdc-sensori           > * { grid-column: span 3; }
.pot-detail-grid .pdc-water-curve       > * { grid-column: span 6; }
.pot-detail-grid .pdc-diario            > * { grid-column: span 6; }
/* Slice ux-tabs (UX-7): slot generici per la composizione per-tab. */
.pot-detail-grid .pdc-half              > * { grid-column: span 3; }
.pot-detail-grid .pdc-third             > * { grid-column: span 2; }
.pot-detail-grid .pdc-full              > * { grid-column: span 6; }

/* Slice cover-in-panoramica (lug 2026): card con la foto di copertina,
   PRIMA card della Panoramica; click sull'immagine -> tab Foto.
   aspect-ratio fissa = proporzioni costanti qualunque sia la foto
   (object-fit: cover ritaglia senza deformare). */
.pdc-cover-link { display: block; }
.pdc-cover-img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: 6px;
    border: 1px solid var(--border);
}

/* Slice ux-tabs (UX-7): nav delle tab della scheda vaso. Riusa lo stile
   .profile-tabs/.profile-tab; qui solo gli extra: scroll orizzontale su
   mobile (5 tab non ci stanno) e badge numerico sulla tab Salute
   (numero di fitopatie aperte: il contenuto delle tab non attive e'
   invisibile, un problema di salute non deve sparire). */
.pot-detail-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
}
.pot-detail-tabs .profile-tab { white-space: nowrap; }
.pot-tab-count {
    display: inline-block;
    min-width: 1.25em;
    padding: 0 0.3em;
    border-radius: 999px;
    background: #b3541e;
    color: #fff;
    font-size: 0.72em;
    font-weight: 700;
    text-align: center;
    line-height: 1.6;
    vertical-align: 0.1em;
}

/* Slice ui-level (lug 2026): blocco "🔬 Strumenti avanzati" richiudibile
   nella vista Essenziale. Discreto da chiuso, griglia interna da aperto. */
.adv-reveal > summary {
    cursor: pointer;
    color: var(--muted);
    font-size: 0.92rem;
    padding: 0.45rem 0.2rem;
    user-select: none;
    list-style-position: inside;
}
.adv-reveal > summary:hover { color: var(--accent-dark); }
.adv-reveal[open] > summary {
    color: var(--accent-dark);
    font-weight: 600;
    margin-bottom: 0.4rem;
}
/* Variante del reveal per i GRUPPI DI CAMPI nei form (ui-level UI-2):
   bordo a sinistra per raggruppare visivamente i campi collassati. */
.adv-reveal-fields {
    margin: 0.6rem 0;
    border-left: 2px solid var(--border);
    padding-left: 0.7rem;
}
.adv-reveal-fields[open] {
    border-left-color: var(--accent);
    padding-bottom: 0.2rem;
}
/* Slice ux-empty (UX-2): hint esplicativi di agenda/calendario vuoti. */
.dash-empty-hint {
    color: var(--muted);
    font-size: 0.92em;
    max-width: 56ch;
    margin: 0.4rem auto 0.8rem;
}
.calendar-empty-hint { margin: 0.8rem 0; }

/* Badge "strumento avanzato" negli header delle dashboard (UI-6). */
.adv-badge {
    display: inline-block;
    font-size: 0.62em;
    font-weight: 500;
    color: var(--muted);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 0.15em 0.7em;
    margin-left: 0.5rem;
    vertical-align: middle;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

/* Slice H1: card "Fertilizzanti abituali" nel detail vaso.
   Link "modifica" piccolo in header, lista item con dose+periodo
   compatti. */
.detail-preset .card-edit-link {
    font-size: 0.78rem;
    font-weight: normal;
    color: var(--accent-dark);
    text-decoration: none;
    margin-left: 0.5rem;
}
.detail-preset .card-edit-link:hover {
    text-decoration: underline;
}
.preset-list {
    list-style: none;
    padding: 0;
    margin: 0.4rem 0 0;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}
.preset-item {
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: rgba(74, 124, 89, 0.04);
}
.preset-item-head a {
    color: var(--accent-dark);
    text-decoration: none;
}
.preset-item-head a:hover {
    text-decoration: underline;
}
.preset-form {
    font-size: 0.78rem;
    color: var(--muted);
}
.preset-dose {
    margin-top: 0.2rem;
    font-size: 0.85rem;
}
.preset-dose-note {
    color: var(--muted);
    font-style: italic;
}
.preset-period {
    margin-top: 0.15rem;
    font-size: 0.78rem;
    color: var(--muted);
    font-style: italic;
}

/* Mobile: tutto 1 colonna verticale. */
@media (max-width: 800px) {
    .pot-detail-grid {
        grid-template-columns: 1fr;
    }
    .pot-detail-grid .pdc-slot > * {
        grid-column: 1 / -1 !important;
    }
}

.detail-card {
    background: var(--card-bg);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    border-left: 4px solid var(--accent);
}

/* Sezione larga il doppio (occupa 2 colonne della grid auto-fill).
   Su layout stretto (mobile/tablet con 1 colonna) span 2 si comporta come
   single column: niente rotture. Usata per la sezione diario (slice C1+) */
.detail-card-wide {
    grid-column: span 2;
}

/* Card "placeholder": occupa la sua cella della grid mantenendo
   l'allineamento, ma con stile tratteggiato e tono tenue per indicare
   che &egrave; "vuota in attesa di contenuto". Es. "Storico fitopatie
   risolte" quando non ci sono ancora risolte. */
.detail-card-placeholder {
    background: transparent;
    box-shadow: none;
    border: 2px dashed var(--border);
    border-left: 2px dashed var(--border);  /* override su border-left accent */
}

.detail-card-placeholder h3 {
    color: var(--muted);  /* override su color: var(--accent) di .detail-card h3 */
}

.detail-card-placeholder-text {
    color: var(--muted);
    font-style: italic;
    font-size: 0.9rem;
    margin: 0;
}

.detail-card h3 {
    margin: 0 0 0.5rem;
    color: var(--accent);
    font-size: 0.95rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 600;
}

.detail-card .card-headline {
    margin: 0 0 0.4rem;
    font-size: 1rem;
    font-weight: 500;
}

.detail-card .card-headline a {
    color: var(--accent);
    text-decoration: none;
}

.detail-card .card-headline a:hover {
    text-decoration: underline;
}

.detail-stats {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.2rem 0.6rem;
    margin: 0;
    font-size: 0.85rem;
}

.detail-stats dt {
    color: var(--muted);
    font-weight: 500;
}

.detail-stats dd {
    margin: 0;
    color: var(--fg);
}

.detail-card-note {
    margin: 0.5rem 0 0;
    color: var(--muted);
    font-size: 0.85rem;
    line-height: 1.4;
}

.legend {
    margin: 0.4rem 0;
    font-size: 0.78rem;
    color: var(--muted);
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.25rem;
}

.legend .month {
    display: inline-block;
    width: 1.4em;
    margin-right: 0.15rem;
}

.disease-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.disease-pill {
    background: rgba(138, 32, 32, 0.08);
    color: var(--error-fg);
    padding: 0.2rem 0.55rem;
    border-radius: 12px;
    font-size: 0.8rem;
    border: 1px solid rgba(138, 32, 32, 0.2);
}

/* Slice 2 "Trattamenti preventivi": card del detail pianta con lista
   di trattamenti suggeriti. Ciascuno = blocco con nome + dl
   (periodo/mesi/intervallo/prodotto) + nota. Separatore sottile fra
   trattamenti per dare struttura senza appesantire. */
.treatments-list {
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
}

.treatment-item + .treatment-item {
    border-top: 1px dashed var(--border);
    padding-top: 0.55rem;
}

.treatment-name {
    margin: 0 0 0.3rem;
    font-size: 0.92rem;
    font-weight: 600;
    color: var(--fg);
    letter-spacing: normal;
    text-transform: none;  /* override del default uppercase di h4 in detail-card */
}

.detail-note {
    background: rgba(74, 124, 89, 0.06);
    border-left: 3px solid var(--accent);
    padding: 0.7rem 1rem;
    border-radius: 0 6px 6px 0;
    color: var(--fg);
    font-size: 0.9rem;
    margin: 1rem 0 0;
    font-style: italic;
}

.detail-note:empty {
    display: none;
}

/* Anchor highlight: substrato richiamato via /catalogo/substrati#<slug> */
.substrate-card:target {
    box-shadow: 0 0 0 2px var(--accent), 0 1px 3px rgba(0, 0, 0, 0.1);
    transition: box-shadow 0.3s;
}

/* ── Pagina profilo ─────────────────────────────────────────────────────── */

.profile {
    margin: 2rem auto;
}

.profile h2 {
    color: var(--accent);
    margin: 0 0 1.25rem;
    text-align: center;
}

.profile-card h3 {
    margin: 0 0 1rem;
    color: var(--accent);
    font-size: 1.15rem;
}

/* Grid 2 colonne per le card del profilo (ordine row-by-row).
   Le 4 card si dispongono in 2x2: Dati / Password sulla prima riga,
   Location / Elimina sulla seconda. Su mobile (≤700px) torna a
   1 colonna verticale.
   `align-items: stretch` (default) fa s&igrave; che le card della stessa riga
   abbiano altezza uguale (la pi&ugrave; corta si estende), evitando lo "scalino"
   tra prima e seconda riga. */
.profile-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.25rem;
}

@media (max-width: 700px) {
    .profile-grid {
        grid-template-columns: 1fr;
    }
}

/* Card profilo: niente max-width 480 dell'.auth-card, niente margin
   centrato. Occupano la cella della grid e usano flex column per
   distribuire il contenuto: la form si espande, il bottone resta in
   fondo, no buchi. */
.profile-grid .auth-card {
    max-width: none;
    margin: 0;
    display: flex;
    flex-direction: column;
}

.profile-grid .auth-card .auth-form {
    flex: 1;
    display: flex;
    flex-direction: column;
}

.profile-grid .auth-card .auth-form button[type="submit"] {
    margin-top: auto;
}

/* Card "danger zone" per l'eliminazione dell'account: bordo rosso a
   sinistra, titolo rosso, sfondo leggermente desaturato. Indica
   visivamente che l'azione &egrave; distruttiva e va presa sul serio. */
.profile-card.danger-zone {
    border-left: 4px solid rgb(102, 18, 18);
    background: rgb(228, 87, 87);
}

.profile-card.danger-zone h3 {
    color: rgb(102, 18, 18);
}

/* Export GDPR card (slice "Esporta i tuoi dati"). Border blu per
   differenziarla visivamente dalle azioni standard. */
.profile-card-export {
    border-left: 4px solid #2b5687;
}

.profile-card-export h3 {
    color: var(--info-fg);
}

.profile-export-desc,
.profile-export-content {
    color: #555;
    line-height: 1.5;
    margin: 0.5rem 0;
}

/* Slice Google OAuth: card "Account Google" del profilo. Visibile
   solo se user.google_sub != NULL. Pattern visivo: pill verde
   "Collegato" + email Google + bottone Scollega secondary-button. */
.profile-card-google {
    border-left: 4px solid #4285F4;
}

.profile-card-google h3 {
    color: #1f1f1f;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.profile-google-icon {
    /* !important: alcuni browser ignorano width/height CSS sugli SVG
       inline e usano l'intrinsic size del viewBox -> icona enorme che
       riempie l'h3 in flex. Lo blocchiamo qui. Anche l'SVG ha
       width/height come attributi HTML (vedi _render_google_account_card
       in server.py), il !important garantisce coerenza. */
    width: 1.25rem !important;
    height: 1.25rem !important;
    flex-shrink: 0;
}

.profile-google-status {
    margin: 0.6rem 0 0.8rem;
    font-size: 0.95rem;
    color: var(--fg);
}

.profile-google-pill {
    display: inline-block;
    padding: 0.15rem 0.55rem;
    background: rgba(52, 168, 83, 0.16);
    color: #1f7a3a;
    border: 1px solid rgba(52, 168, 83, 0.35);
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 600;
    margin-right: 0.3rem;
}

.profile-google-warning {
    margin: 0.4rem 0 0.8rem;
    padding: 0.55rem 0.75rem;
    background: rgba(199, 153, 57, 0.10);
    border-left: 3px solid #c79939;
    border-radius: 0 6px 6px 0;
    color: #6b5520;
    font-size: 0.88rem;
    line-height: 1.5;
}

.profile-google-warning em {
    font-style: normal;
    font-weight: 600;
    color: var(--accent-dark);
}

/* Dark mode: tono Google blu mantenuto, pill verde piu' soft. */
:root[data-theme="dark"] .profile-card-google h3 {
    color: #e3e3e3;
}

:root[data-theme="dark"] .profile-google-pill {
    background: rgba(52, 168, 83, 0.22);
    color: #8edaa3;
    border-color: rgba(52, 168, 83, 0.5);
}

/* Slice nav-2: card "Risorse" del profilo (Novità + Guida).
   Sostituisce i 2 link spostati dalla top-nav (sovraffollata) qui in
   un hub secondario. Border-left ambra per distinguerla visivamente
   dalle altre profile-card (e' una "shortcut box", non una config). */
.profile-card-resources {
    border-left: 4px solid #c79939;
}

.profile-card-resources h3 {
    color: #8a6420;
}

.profile-resources-desc {
    color: #555;
    line-height: 1.5;
    margin: 0.5rem 0 0.9rem 0;
}

.profile-resources-links {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

/* Ogni "resource link" e' una riga cliccabile larga: icona a sinistra
   + titolo + descrizione breve. Click intero (tutta la card e'
   wrap su <a>), tap target ampio per mobile. */
.profile-resource-link {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.7rem 0.9rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card-bg);
    color: var(--fg);
    text-decoration: none;
    transition: border-color 0.15s, background 0.15s, transform 0.12s;
}

.profile-resource-link:hover {
    border-color: var(--accent);
    background: rgba(74, 124, 89, 0.06);
    color: var(--fg);
    text-decoration: none;
    transform: translateY(-1px);
}

.profile-resource-icon {
    font-size: 1.4rem;
    line-height: 1;
    flex-shrink: 0;
    margin-top: 0.1rem;
}

.profile-resource-body {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.profile-resource-body strong {
    font-weight: 600;
    color: var(--accent-dark);
    font-size: 1rem;
}

.profile-resource-body small {
    color: var(--muted);
    font-size: 0.85rem;
    line-height: 1.4;
}

/* PWA install card (slice "Installa come app"). Stile coerente con le
   altre profile-card ma con accent verde su border-left per richiamare
   il theme-color del manifest (#3d6649). */
.profile-card-pwa {
    border-left: 4px solid var(--accent-dark);
}

.profile-card-pwa h3 {
    color: var(--accent-dark);
}

.profile-pwa-desc {
    color: #555;
    line-height: 1.5;
    margin: 0.5rem 0 0.8rem 0;
}

.profile-pwa-help {
    margin-top: 0.8rem;
    font-size: 0.92rem;
    color: #666;
}

.profile-pwa-help summary {
    cursor: pointer;
    color: var(--accent-dark);
    padding: 0.3rem 0;
}

.profile-pwa-help summary:hover {
    color: var(--accent);
}

.profile-pwa-help ul {
    margin: 0.5rem 0 0 1.2rem;
    padding: 0;
    line-height: 1.5;
}

.profile-pwa-help li {
    margin: 0.3rem 0;
}

/* Slice N1: card "Notifiche push" — stesso pattern visivo della PWA. */
.profile-card-push {
    border-left: 4px solid var(--warn-border);
}

.profile-card-push h3 {
    color: var(--warn-fg);
}

.profile-push-desc {
    color: #555;
    line-height: 1.5;
    margin: 0.5rem 0 0.8rem 0;
}

.profile-push-status {
    padding: 0.5rem 0.75rem;
    margin: 0.5rem 0;
    border-radius: 4px;
    font-size: 0.92rem;
    background: var(--bg);
    border: 1px solid #d4cfc6;
    color: #555;
}

.profile-push-status[data-push-status="active"] {
    background: #eef4ef;
    border-color: #bfd1c5;
    color: #2a4e34;
}

.profile-push-status[data-push-status="inactive"] {
    background: #faf5e9;
    border-color: #e6d5a8;
    color: #8a6420;
}

.profile-push-status[data-push-status="denied"] {
    background: rgb(253, 230, 230);
    border-color: rgb(240, 184, 184);
    color: rgb(138, 32, 32);
}

.profile-push-status[data-push-status="unsupported"] {
    background: var(--bg);
    border-color: #d4cfc6;
    color: #777;
    font-style: italic;
}

.profile-push-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0.8rem 0;
}

.profile-push-devices {
    margin-top: 1rem;
}

.profile-push-devices h4 {
    font-size: 0.95rem;
    color: #555;
    margin: 0.5rem 0;
}

.push-devices-list {
    list-style: none;
    padding: 0;
    margin: 0.5rem 0;
}

.push-device-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.7rem;
    background: var(--card-bg);
    border: 1px solid #d4cfc6;
    border-radius: 4px;
    margin: 0.3rem 0;
    font-size: 0.92rem;
}

.push-device-label {
    color: #444;
    flex: 1 1 auto;
    min-width: 0;
}

.push-device-icon {
    margin-right: 0.3rem;
}

.push-device-date {
    color: #888;
    margin-left: 0.3rem;
}

.profile-push-help {
    margin-top: 0.8rem;
    font-size: 0.92rem;
    color: #666;
}

.profile-push-help summary {
    cursor: pointer;
    color: #8a6420;
    padding: 0.3rem 0;
}

.profile-push-help summary:hover {
    color: #6a4815;
}

.profile-push-help ul {
    margin: 0.5rem 0 0 1.2rem;
    padding: 0;
    line-height: 1.5;
}

.profile-push-help li {
    margin: 0.3rem 0;
}

/* Slice N5: form preferenze granulari notifiche. */
.profile-push-prefs {
    margin-top: 1.2rem;
    padding-top: 1rem;
    border-top: 1px dashed #d4cfc6;
}

.profile-push-prefs h4 {
    margin: 0 0 0.6rem 0;
    color: #555;
    font-size: 0.95rem;
}

.push-prefs-fieldset {
    margin: 0 0 1rem 0;
    padding: 0.6rem 0.9rem 0.8rem 0.9rem;
    border: 1px solid #d4cfc6;
    border-radius: 5px;
    background: var(--card-bg);
}

.push-prefs-fieldset legend {
    color: #8a6420;
    font-weight: 600;
    font-size: 0.92rem;
    padding: 0 0.4rem;
}

.push-pref-toggle {
    display: block;
    margin: 0.45rem 0;
    cursor: pointer;
    line-height: 1.4;
}

.push-pref-toggle input[type="checkbox"] {
    margin-right: 0.5rem;
    vertical-align: middle;
    transform: scale(1.1);
}

.push-pref-label {
    font-weight: 500;
    color: #2b2b2b;
    vertical-align: middle;
}

.push-pref-desc {
    display: block;
    margin-left: 1.8rem;
    color: #777;
    font-size: 0.85rem;
    line-height: 1.3;
}

.push-prefs-times-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0.7rem 1rem;
}

.push-pref-time {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin: 0.3rem 0;
}

.push-pref-time input[type="time"] {
    font: inherit;
    padding: 0.3rem 0.5rem;
    border: 1px solid #cfd2c8;
    border-radius: 4px;
    background: var(--card-bg);
    max-width: 130px;
}

.push-pref-time .push-pref-desc {
    margin-left: 0;
}

.push-prefs-actions {
    margin-top: 1rem;
    text-align: right;
}

/* ──────────────────────────────────────────────────────────────────────────
   TAB BAR del profilo (/profilo, /profilo/catalogo, /profilo/catalogo/*)
   ────────────────────────────────────────────────────────────────────────── */

.profile-tabs {
    display: flex;
    gap: 0.25rem;
    border-bottom: 1px solid var(--border);
    margin: 0.75rem 0 1.25rem;
    background-color: rgba(255, 255, 255, 0.8);
}

.profile-tab {
    padding: 0.6rem 1rem;
    color: var(--muted);
    text-decoration: none;
    font-size: 0.95rem;
    font-weight: 500;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;  /* sovrappone il bordo bottom del nav */
    transition: color 0.15s, border-color 0.15s;
}

.profile-tab:hover {
    color: var(--accent);
}

.profile-tab.profile-tab-active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

/* ── Slice N7: tab "Gestione notifiche" del profilo ─────────────────────
   Layout master-detail desktop (>=900px): lista a sinistra fissa,
   detail a destra che riempie. Mobile: detail scende sotto la lista. */

.profile-tab-badge {
    display: inline-block;
    margin-left: 0.35rem;
    min-width: 1.4em;
    padding: 0.05rem 0.4rem;
    font-size: 0.72rem;
    font-weight: 700;
    text-align: center;
    line-height: 1.5;
    color: white;
    background: #c0392b;
    border-radius: 999px;
    vertical-align: middle;
}

.notifications-tab {
    display: grid;
    grid-template-columns: minmax(280px, 360px) 1fr;
    gap: 1.25rem;
    align-items: start;
}

@media (max-width: 900px) {
    .notifications-tab {
        grid-template-columns: 1fr;
    }
}

.notifications-list-panel {
    background: white;
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    max-height: 78vh;
}

.notifications-list-header {
    border-bottom: 1px solid var(--border);
    padding: 0.6rem 0.75rem;
    background: rgba(255, 255, 255, 0.6);
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.notifications-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

.notif-filter {
    padding: 0.3rem 0.7rem;
    font-size: 0.82rem;
    font-weight: 500;
    color: var(--muted);
    background: rgba(0, 0, 0, 0.04);
    border-radius: 999px;
    text-decoration: none;
    transition: background 0.15s, color 0.15s;
}

.notif-filter:hover {
    background: rgba(0, 0, 0, 0.08);
    color: var(--fg);
}

.notif-filter-active {
    background: var(--accent);
    color: white;
}

.notif-filter-active:hover {
    background: var(--accent);
    color: white;
}

.notif-mark-all-form {
    margin: 0;
    align-self: flex-end;
}

.notif-mark-all-btn {
    font-size: 0.8rem;
    color: var(--muted);
    cursor: pointer;
}

.notif-mark-all-btn:hover {
    color: var(--accent);
    text-decoration: underline;
}

.notifications-list {
    overflow-y: auto;
    display: flex;
    flex-direction: column;
}

.notif-empty {
    padding: 1.5rem 1rem;
    color: var(--muted);
    text-align: center;
    font-size: 0.9rem;
}

.notif-card {
    display: flex;
    gap: 0.6rem;
    padding: 0.75rem;
    border-bottom: 1px solid var(--border);
    text-decoration: none;
    color: var(--fg);
    transition: background 0.12s;
    align-items: flex-start;
}

.notif-card:last-child {
    border-bottom: none;
}

.notif-card:hover {
    background: rgba(0, 0, 0, 0.03);
}

.notif-card-selected {
    background: rgba(80, 130, 95, 0.10);
    border-left: 3px solid var(--accent);
    padding-left: calc(0.75rem - 3px);
}

.notif-card-selected:hover {
    background: rgba(80, 130, 95, 0.14);
}

.notif-card-icon {
    flex: 0 0 auto;
    font-size: 1.2rem;
    line-height: 1.4;
}

.notif-card-body {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 0;
}

.notif-card-title {
    font-weight: 600;
    font-size: 0.92rem;
    line-height: 1.3;
    color: var(--fg);
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.notif-card-unread .notif-card-title {
    color: var(--accent);
}

.notif-unread-dot {
    display: inline-block;
    width: 0.55rem;
    height: 0.55rem;
    background: var(--accent);
    border-radius: 50%;
    flex: 0 0 auto;
}

.notif-card-snippet {
    font-size: 0.85rem;
    color: var(--muted);
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.notif-card-when {
    font-size: 0.75rem;
    color: var(--muted);
    margin-top: 0.1rem;
}

.notifications-detail-panel {
    background: white;
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.25rem;
    min-height: 200px;
}

.notif-detail-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 200px;
}

.notif-detail-empty-text {
    color: var(--muted);
    text-align: center;
    margin: 0;
}

.notif-detail-header {
    margin-bottom: 0.5rem;
}

.notif-detail-kind {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.6rem;
    font-size: 0.78rem;
    font-weight: 500;
    background: rgba(80, 130, 95, 0.10);
    color: var(--accent);
    border-radius: 999px;
}

.notif-detail-title {
    font-size: 1.25rem;
    margin: 0.4rem 0 0.75rem;
    color: var(--fg);
    line-height: 1.3;
}

.notif-detail-body {
    font-size: 1rem;
    line-height: 1.5;
    color: var(--fg);
    margin-bottom: 1rem;
    white-space: pre-wrap;
    word-wrap: break-word;
}

.notif-detail-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem 1.2rem;
    font-size: 0.82rem;
    color: var(--muted);
    padding-top: 0.75rem;
    border-top: 1px dashed var(--border);
    margin-bottom: 1rem;
}

.notif-meta-item strong {
    color: var(--fg);
    font-weight: 500;
}

.notif-meta-unread {
    color: var(--accent);
    font-weight: 500;
}

.notif-detail-actions {
    display: flex;
    justify-content: flex-end;
}

.notif-cta-link {
    text-decoration: none;
}

/* Dark mode: invertiamo i bg bianchi e ammorbidiamo le evidenze. */
:root[data-theme="dark"] .notifications-list-panel,
:root[data-theme="dark"] .notifications-detail-panel {
    background: rgba(255, 255, 255, 0.05);
}

:root[data-theme="dark"] .notifications-list-header {
    background: rgba(0, 0, 0, 0.25);
}

:root[data-theme="dark"] .notif-card:hover {
    background: rgba(255, 255, 255, 0.04);
}

:root[data-theme="dark"] .notif-card-selected {
    background: rgba(120, 175, 140, 0.18);
}

:root[data-theme="dark"] .notif-card-selected:hover {
    background: rgba(120, 175, 140, 0.22);
}

@media (prefers-color-scheme: dark) {
    :root[data-theme="auto"] .notifications-list-panel,
    :root[data-theme="auto"] .notifications-detail-panel {
        background: rgba(255, 255, 255, 0.05);
    }
    :root[data-theme="auto"] .notifications-list-header {
        background: rgba(0, 0, 0, 0.25);
    }
    :root[data-theme="auto"] .notif-card:hover {
        background: rgba(255, 255, 255, 0.04);
    }
    :root[data-theme="auto"] .notif-card-selected {
        background: rgba(120, 175, 140, 0.18);
    }
    :root[data-theme="auto"] .notif-card-selected:hover {
        background: rgba(120, 175, 140, 0.22);
    }
}

/* Landing /profilo/catalogo: riusa .catalog-list ma con i 4 box
   disabilitati (slice futuri). */
.catalog-entry.disabled h3 {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.badge-soon {
    background: rgba(120, 120, 120, 0.15);
    color: var(--muted);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.15rem 0.45rem;
    border-radius: 999px;
    font-weight: 600;
}

/* ──────────────────────────────────────────────────────────────────────────
   AVVISI METEO PERSONALIZZATI (slice G2)
   /profilo/catalogo/avvisi-meteo
   ────────────────────────────────────────────────────────────────────────── */

.advice-species-list {
    list-style: none;
    padding: 0;
    margin: 1rem 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.advice-species-row {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
}

.advice-species-link {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.75rem 1rem;
    text-decoration: none;
    color: inherit;
    transition: background 0.1s;
}

.advice-species-link:hover {
    background: rgba(74, 124, 89, 0.04);
}

.advice-species-icon {
    font-size: 1.7rem;
    line-height: 1;
}

.advice-species-info {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.advice-species-info small {
    color: var(--muted);
    font-size: 0.85rem;
}

/* Form modifica avvisi (7 textarea) */
.advice-form {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.advice-intro {
    color: var(--muted);
    font-size: 0.9rem;
    margin: 0 0 0.5rem;
    padding: 0.6rem 0.8rem;
    background: rgba(74, 124, 89, 0.06);
    border-left: 3px solid var(--accent);
    border-radius: 4px;
}

.advice-field-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.3rem;
}

.advice-field-icon {
    font-size: 1.2rem;
}

.advice-field textarea {
    width: 100%;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    font: inherit;
    font-size: 0.95rem;
    resize: vertical;
    min-height: 3.2rem;
    background: var(--card-bg);
}

.advice-field textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(74, 124, 89, 0.18);
}

.advice-field textarea::placeholder {
    color: rgba(0, 0, 0, 0.35);
    font-style: italic;
}

.advice-delete-form {
    margin-top: 1rem;
    text-align: center;
}

.danger-warning {
    margin: 0 0 0.6rem;
    padding: 0.65rem 0.85rem;
    background: var(--error-bg);
    border: 1px solid var(--error-border);
    border-radius: 6px;
    color: var(--error-fg);
    font-size: 0.9rem;
    line-height: 1.4;
}

.danger-impact {
    margin: 0 0 1rem;
    color: white;
    font-size: 0.92rem;
    line-height: 1.5;
}

.field em {
    font-style: normal;
    font-size: 0.85em;
    opacity: 0.85;
}

.auth-alt {
    margin: 1.5rem 0 0;
    text-align: center;
    color: var(--muted);
    font-size: 0.9rem;
}

.auth-alt a {
    color: var(--accent);
}

/* Slice mod_pwreset: testo introduttivo + link "Password dimenticata?". */
.auth-intro {
    margin: 0 0 1.1rem;
    color: var(--muted);
    line-height: 1.5;
}
.auth-forgot {
    margin-top: 0.4rem;
}

/* ====================================================================
   Fitopatie del vaso (slice B1)
   ==================================================================== */

.pot-disease-section-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-bottom: 0.85rem;
}

.pot-disease-section-head h3 {
    margin: 0;
}

.pot-disease-empty {
    color: var(--muted);
    font-style: italic;
    margin: 0;
}

.pot-disease-list {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

.pot-disease-card {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.75rem 0.95rem;
    background: var(--card-bg);
    border-left-width: 4px;
    border-left-color: var(--muted);
    transition: box-shadow 0.15s ease;
}

.pot-disease-card-aperta          { border-left-color: #b04444; }
.pot-disease-card-in-trattamento  { border-left-color: #c79939; }
.pot-disease-card-risolta         { border-left-color: var(--accent); opacity: 0.85; }

.pot-disease-card:hover {
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}

.pot-disease-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.6rem;
    margin-bottom: 0.4rem;
}

.pot-disease-head h4 {
    margin: 0;
    font-size: 1rem;
    line-height: 1.25;
}

.pot-disease-head h4 a {
    color: var(--fg);
    text-decoration: none;
    border-bottom: 1px dashed var(--border);
}

.pot-disease-head h4 a:hover {
    border-bottom-color: var(--accent);
}

.pot-disease-actions {
    display: flex;
    gap: 0.3rem;
    flex-shrink: 0;
}

.pot-disease-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    align-items: center;
    margin-bottom: 0.35rem;
}

/* Status badge */
.pd-status {
    display: inline-block;
    padding: 0.1rem 0.55rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.pd-status-aperta          { background: rgba(176, 68, 68, 0.15);  color: #8a2020; }
.pd-status-in-trattamento  { background: rgba(199, 153, 57, 0.18); color: #8a6420; }
.pd-status-risolta         { background: rgba(74, 124, 89, 0.18);  color: var(--accent-dark); }

/* Severity badge (osservata) — riusa la palette di disease-severity */
.pd-severity {
    display: inline-block;
    padding: 0.1rem 0.55rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 500;
}

.pd-severity-lieve     { background: rgba(199, 153, 57, 0.15); color: #8a6420; }
.pd-severity-moderata  { background: rgba(199, 99, 57, 0.18);  color: #a04a20; }
.pd-severity-grave     { background: rgba(161, 52, 52, 0.18);  color: #8a2020; }

.pd-detected {
    color: var(--muted);
    font-size: 0.85rem;
}

.pot-disease-card .pd-note {
    margin: 0.3rem 0 0;
    color: var(--fg);
    font-size: 0.92rem;
    line-height: 1.4;
}

/* Bottoni di azione: usa il pattern icon-button gi&agrave; in uso sul detail vaso */
.pot-disease-actions .icon-action {
    display: inline-flex;
    margin: 0;
}

/* ====================================================================
   Fitopatie del vaso (slice B2: trattamento, risolte, prossima applicazione)
   ==================================================================== */

/* Storico risolte: leggermente pi&ugrave; "spento" del blocco delle aperte */
.pot-disease-resolved-section h3 {
    color: var(--muted);
}

.pot-disease-resolved-count {
    color: var(--muted);
    font-size: 0.85rem;
}

.pot-disease-resolved-section .pot-disease-card {
    /* opacity: 0.85 era gi&agrave; su .pot-disease-card-risolta, ridichiariamo
       qui per l'intera lista risolte. Niente ulteriore dimming, le risolte
       restano leggibili. */
    background: var(--card-bg);
}

/* Bottone success per "&#10003; Risolvi" — variante verde dell'icon-button */
.icon-button-success:hover {
    background: rgba(74, 124, 89, 0.18);
    color: var(--accent-dark);
    border-color: rgba(74, 124, 89, 0.4);
}

/* Bottone "Salta per pioggia" — variante blu dell'icon-button. Usato
   accanto al check ✅ sulle card irrigazione computed quando il forecast
   prevede precipitazioni sopra soglia (vedi pot_events._render_computed_card
   + weather.RAIN_SKIP_THRESHOLD_MM). Il form wrappa il bottone senza
   margini extra cos&igrave; risulta allineato con il check adiacente. */
.cal-event-skip-form {
    display: inline-flex;
    margin: 0;
}

.icon-button-rain {
    background: rgba(57, 102, 153, 0.08);
    border-color: rgba(57, 102, 153, 0.28);
}

.icon-button-rain:hover {
    background: rgba(57, 102, 153, 0.18);
    border-color: rgba(57, 102, 153, 0.45);
}

/* Sotto-meta della card che mostra "🌧️ ~X mm previsti": piccola riga
   discreta che spiega *perch&eacute;* il bottone "Salta" appare. */
.cal-event-rain-hint {
    color: rgba(57, 102, 153, 0.85);
    font-style: italic;
}

/* Riga "extra" delle card (Trattamento con / Iniziato il / Prossima
   applicazione / Risolta il). Layout dl identico al detail vaso. */
.pd-extras {
    margin: 0.4rem 0 0;
    padding: 0.45rem 0;
    display: grid;
    grid-template-columns: max-content 1fr;
    column-gap: 0.85rem;
    row-gap: 0.2rem;
    border-top: 1px dashed var(--border);
    font-size: 0.88rem;
}

.pd-extras dt {
    color: var(--muted);
    margin: 0;
}

.pd-extras dd {
    margin: 0;
    color: var(--fg);
}

.pd-extras dd a {
    color: var(--accent);
}

/* "Prossima applicazione": evidenzia in rosso se la data &egrave; passata. */
.pd-next-source {
    color: var(--muted);
    font-size: 0.78rem;
    font-style: italic;
}

.pd-overdue {
    color: var(--error-fg);
    font-weight: 600;
}

/* Form di modifica fitopatia: i blocchi condizionali hanno lo stesso
   pattern dei .dim-fields del form vaso (hidden = display: none). */
.pot-form .pd-treatment-fields[hidden] {
    display: none;
}

.pot-form .pd-treatment-fields {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.4rem 0 0;
}

/* Spaziatura della checkbox "mostra anche prodotti non consigliati" dentro
   il <label class="field"> del select pesticide. */
.pot-form .field-checkbox {
    margin-top: 0.4rem;
    font-weight: 400;
    font-size: 0.88rem;
    color: var(--muted);
}

/* ====================================================================
   Slice B3: banner alert "N fitopatie attive" sul bordo superiore della
   card della lista vasi. Pattern: il banner sfora il padding della card
   con margini negativi e si attacca ai bordi. Il border-radius e
   l'overflow: hidden della .pot-card lo clippano agli angoli alti.
   ==================================================================== */

.pot-card-alert {
    display: block;
    /* Margini negativi che annullano il padding 0.85rem (top) e 1rem
       (left/right) della .pot-card, cos&igrave; il banner arriva ai bordi.
       margin-bottom: 0 mantiene il gap tra banner e header. */
    margin: -0.85rem -1rem 0;
    padding: 0.4rem 0.85rem;
    background: rgba(176, 68, 68, 0.12);
    border-bottom: 1px solid rgba(176, 68, 68, 0.25);
    color: #8a2020;
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    text-align: center;
    text-decoration: none;
    line-height: 1.2;
    transition: background 0.15s;
}

.pot-card-alert:hover {
    background: rgba(176, 68, 68, 0.2);
}

/* ====================================================================
   Diario del giardiniere (slice C1)
   ==================================================================== */

.journal-section-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-bottom: 0.85rem;
}

.journal-section-head h3 {
    margin: 0;
}

.journal-empty {
    color: var(--muted);
    font-style: italic;
    margin: 0;
}

.journal-list {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.journal-entry {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.6rem 0.85rem;
    background: var(--card-bg);
    border-left-width: 4px;
    border-left-color: var(--muted);
    transition: box-shadow 0.15s;
}

.journal-entry:hover {
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.07);
}

.journal-entry-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.6rem;
    margin-bottom: 0.3rem;
}

.journal-entry-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
}

.journal-date {
    color: var(--muted);
    font-size: 0.85rem;
}

.journal-weather {
    color: var(--muted);
    font-size: 0.82rem;
}

.journal-entry-actions {
    display: flex;
    gap: 0.3rem;
    flex-shrink: 0;
}

.journal-summary {
    margin: 0.15rem 0;
    color: var(--fg);
    font-size: 0.92rem;
}

.journal-note {
    margin: 0.2rem 0 0;
    color: var(--fg);
    font-size: 0.9rem;
    line-height: 1.4;
}

/* Pillola della categoria con icona */
.journal-cat {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.12rem 0.55rem;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.01em;
}

.journal-cat-icon {
    font-size: 0.95rem;
    line-height: 1;
}

/* Palette per le 10 categorie. C1 usa solo blue (irrigazione) e neutral
   (osservazione); le altre sono pronte per C2/C3 senza nuovi rilasci CSS. */
.journal-cat-blue    { background: rgba(58, 110, 165, 0.15); color: #2c5482; }
.journal-cat-teal    { background: rgba(58, 145, 145, 0.15); color: #2c6e6e; }
.journal-cat-olive   { background: rgba(124, 138, 61, 0.18); color: #58642b; }
.journal-cat-red     { background: rgba(176, 68, 68, 0.15);  color: #8a2020; }
.journal-cat-amber   { background: rgba(199, 153, 57, 0.18); color: #8a6420; }
.journal-cat-brown   { background: rgba(140, 96, 60, 0.18);  color: #6b4422; }
.journal-cat-green   { background: rgba(74, 124, 89, 0.18);  color: var(--accent-dark); }
.journal-cat-grey    { background: rgba(120, 120, 120, 0.18); color: #4a4a4a; }
.journal-cat-neutral { background: rgba(120, 120, 120, 0.10); color: var(--muted); }

/* Border-left della card colorato per categoria (matcha la pillola) */
.journal-entry-irrigazione     { border-left-color: #3a6ea5; }
.journal-entry-fertirrigazione { border-left-color: #3a9191; }
.journal-entry-concimazione    { border-left-color: #7c8a3d; }
.journal-entry-trattamento     { border-left-color: #b04444; }
.journal-entry-potatura        { border-left-color: #c79939; }
.journal-entry-rinvaso         { border-left-color: #8c603c; }
.journal-entry-talea           { border-left-color: var(--accent); }
.journal-entry-pulizia         { border-left-color: #787878; }
.journal-entry-osservazione    { border-left-color: var(--muted); }
.journal-entry-altro           { border-left-color: var(--muted); }

/* ── Slice ux-diario (UX-5): picker categoria a bottoni-icona ─────────
   I 3 tipi più usati (irrigazione/fertirrigazione/concimazione) come
   bottoni grandi + toggle «Altre…» che apre le chip delle altre
   categorie. Il picker parte hidden (fallback no-JS = select). */
.journal-type-picker[hidden] { display: none; }

/* Col picker attivo il JS nasconde il campo select: .field è flex,
   serve la regola esplicita perché [hidden] vinca. */
.field[data-journal-type-select-field][hidden] { display: none; }

.journal-type-picker {
    margin-bottom: 0.75rem;
}

.journal-type-primary {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.5rem;
}

.journal-type-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card-bg, #fff);
    color: var(--fg, #2b2b2b);
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
}

.journal-type-btn:hover {
    border-color: var(--accent);
}

.journal-type-btn-big {
    padding: 0.7rem 0.4rem;
}

.journal-type-btn-big .journal-type-btn-icon {
    font-size: 1.6rem;
    line-height: 1;
}

.journal-type-btn-big .journal-type-btn-label {
    font-size: 0.78rem;
    font-weight: 600;
}

/* Slice ux-micro (UX-6): sub-label dei bottoni grandi — chiarisce
   fertirrigazione (liquido) vs concimazione (secco) a colpo d'occhio. */
.journal-type-btn-hint {
    font-size: 0.66rem;
    color: var(--muted);
    line-height: 1.1;
}

.journal-type-btn-active {
    border-color: var(--accent);
    background: rgba(74, 124, 89, 0.12);
    box-shadow: inset 0 0 0 1px var(--accent);
}

.journal-type-rest {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.5rem;
}

.journal-type-rest[hidden] { display: none; }

.journal-type-btn-small {
    flex-direction: row;
    gap: 0.35rem;
    padding: 0.35rem 0.7rem;
    border-radius: 999px;
    font-size: 0.85rem;
}

.journal-type-btn-small .journal-type-btn-icon {
    font-size: 1rem;
    line-height: 1;
}

@media (max-width: 600px) {
    .journal-type-primary {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Form: campi condizionali per categoria, stesso pattern dei dim-fields */
.pot-form .journal-cat-fields[hidden] {
    display: none;
}

.pot-form .journal-cat-fields {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* Slice F1: multi-fertilizzante. Lista righe + template + bottoni. */
.fert-items-list {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin: 0.5rem 0 0.6rem;
}

.fert-item-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 7rem 7rem auto;
    gap: 0.55rem;
    align-items: end;
    padding: 0.55rem 0.7rem 0.4rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: rgba(74, 124, 89, 0.04);
}

/* Mobile (<= 720px): la grid 4 colonne è troppo larga, esce dal
   viewport. Stack verticale dei campi (prodotto + dose ml/L + dose g
   + override) su 1 colonna; il bottone × passa in alto a destra come
   absolute per non occupare una riga propria. */
@media (max-width: 720px) {
    .fert-item-row {
        grid-template-columns: 1fr;
        padding: 0.65rem 0.75rem 0.55rem;
        position: relative;
    }
    .fert-item-row .field {
        max-width: 100%;
    }
    .fert-item-remove {
        position: absolute;
        top: 0.45rem;
        right: 0.45rem;
        width: 1.7rem;
        height: 1.7rem;
        font-size: 1rem;
    }
    /* Prodotto: ridotto padding-right per non collidere con la × */
    .fert-item-prod {
        padding-right: 2rem;
    }
}

/* Slice H2: campo "Cadenza personalizzata" su riga intera sotto il
   blocco dose + nascosto sotto al testo periodicita'. */
.fert-item-override {
    grid-column: 1 / -1;
    margin: 0.15rem 0 0;
    max-width: 22rem;
}
.fert-item-override > span {
    font-size: 0.75rem;
    color: var(--muted);
}
.fert-item-override > span em {
    font-style: normal;
    font-size: 0.72rem;
    opacity: 0.7;
}
.preset-period-override {
    color: var(--accent-dark) !important;
    font-style: normal !important;
}
.preset-period-override small {
    color: var(--muted);
    font-style: italic;
}

.fert-item-row .field {
    margin: 0;
}

.fert-item-row .field > span {
    font-size: 0.78rem;
    color: var(--muted);
}

/* I 2 wrap dose hanno data-fert-item-dose. Il JS toggla hidden in base
   alla form del prodotto. Quando hidden la field-row sparisce dalla
   grid: usiamo display:none invece di solo visibility cosi' lo spazio
   viene riassorbito. */
.fert-item-row [data-fert-item-dose][hidden] {
    display: none;
}

.fert-item-remove {
    width: 2rem;
    height: 2rem;
    margin-bottom: 0.1rem;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 50%;
    color: var(--muted);
    cursor: pointer;
    font-size: 1.2rem;
    line-height: 1;
    padding: 0;
    transition: border-color 0.15s, color 0.15s, background 0.15s;
}

/* Slice G6: testo periodicita' del prodotto sotto la riga preset.
   Span tutta la grid (4 col) e :empty -> display:none cosi' non
   occupa spazio quando il prodotto non e' ancora selezionato o non
   ha periods nel DB. */
.fert-item-periods {
    grid-column: 1 / -1;
    margin: 0.1rem 0 0;
    font-size: 0.78rem;
    color: var(--muted);
    font-style: italic;
}

.fert-item-periods:empty {
    display: none;
}

.fert-item-remove:hover {
    border-color: #b04444;
    background: rgba(176, 68, 68, 0.08);
    color: #b04444;
}

.fert-item-add {
    align-self: flex-start;
    margin-top: 0.3rem;
}

/* Nota: una vecchia media query @media (max-width: 640px) con
   grid-template-areas è stata rimossa qui perché sovrascriveva
   la media query 720px sopra (1fr stack completo) e ricostruiva
   "ml | g" sulla stessa riga. Il responsive del fieldset è ora
   centralizzato nella media query 720px alla riga ~4900. */

/* Slice C2: link ai cataloghi nella card del diario (fertilizer, pesticide,
   diagnosi). Visibili solo se la categoria li popola. Stile leggero,
   ancorato al riquadro della card. */
.journal-entry .journal-links {
    margin: 0.2rem 0 0;
    color: var(--muted);
    font-size: 0.85rem;
}

.journal-entry .journal-links a {
    color: var(--accent);
    text-decoration: none;
    border-bottom: 1px dashed var(--border);
}

.journal-entry .journal-links a:hover {
    border-bottom-color: var(--accent);
}

/* Slice C2: riga affiancata dei due campi dose pesticide (ml/L e g/L).
   Su layout stretto cade su due righe automaticamente. */
.pot-form .journal-dose-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.6rem;
}

@media (max-width: 480px) {
    .pot-form .journal-dose-row {
        grid-template-columns: 1fr;
    }
}

/* Evidenza visiva del campo dose con valore (per indicare quale formulazione
   ha scelto l'utente). Ridotta deliberatamente perch&eacute; non &egrave; un'azione
   distruttiva, solo aiuto visivo. */
.pot-form .journal-dose-active {
    border-color: var(--accent);
    background: rgba(74, 124, 89, 0.04);
}

/* ====================================================================
   Slice C4: pagina dedicata `/vasi/<id>/diario` con filtri ricchi
   ==================================================================== */

/* Link "Vedi tutto il diario" sotto la lista nel detail vaso (solo se
   ci sono pi&ugrave; di 5 entry). */
.journal-view-all {
    margin: 0.6rem 0 0;
    text-align: right;
}

.journal-view-all a {
    color: var(--accent);
    text-decoration: none;
    font-weight: 600;
    font-size: 0.9rem;
    border-bottom: 1px dashed var(--border);
}

.journal-view-all a:hover {
    border-bottom-color: var(--accent);
}

/* Pagina diario: contenitore principale */
.diario-page {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* Sezione filtri: chip categoria sopra, form GET sotto */
.diario-filters {
    background: var(--card-bg);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

/* Chip categoria: link con plurali colorati. Pattern uguale a journal-cat
   ma cliccabile e con stato attivo. */
.diario-cat-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

/* Slice ux-micro (UX-6): metriche unificate per TUTTE le famiglie di
   chip-filtro (diario, foto, calendario, avvisi): padding 0.25/0.7,
   font 0.85rem, radius 999px, attivo = tinta + testo colorato. */
.diario-cat-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.25rem 0.7rem;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 500;
    text-decoration: none;
    border: 1px solid var(--border);
    background: var(--card-bg);
    color: var(--fg);
    transition: background 0.15s, border-color 0.15s;
}

.diario-cat-chip:hover {
    border-color: var(--accent);
}

.diario-cat-chip-active {
    border-color: var(--accent);
    background: rgba(74, 124, 89, 0.12);
    color: var(--accent-dark);
    font-weight: 600;
}

/* Riusa la palette di journal-cat per le chip colorate */
.diario-cat-chip-blue.diario-cat-chip-active    { background: rgba(58, 110, 165, 0.18); border-color: #3a6ea5; color: #2c5482; }
.diario-cat-chip-teal.diario-cat-chip-active    { background: rgba(58, 145, 145, 0.18); border-color: #3a9191; color: #2c6e6e; }
.diario-cat-chip-olive.diario-cat-chip-active   { background: rgba(124, 138, 61, 0.20); border-color: #7c8a3d; color: #58642b; }
.diario-cat-chip-red.diario-cat-chip-active     { background: rgba(176, 68, 68, 0.18);  border-color: #b04444; color: #8a2020; }
.diario-cat-chip-amber.diario-cat-chip-active   { background: rgba(199, 153, 57, 0.20); border-color: #c79939; color: #8a6420; }
.diario-cat-chip-brown.diario-cat-chip-active   { background: rgba(140, 96, 60, 0.20);  border-color: #8c603c; color: #6b4422; }
.diario-cat-chip-green.diario-cat-chip-active   { background: rgba(74, 124, 89, 0.20);  border-color: var(--accent); color: var(--accent-dark); }
.diario-cat-chip-grey.diario-cat-chip-active    { background: rgba(120, 120, 120, 0.20); border-color: #787878; color: #4a4a4a; }
.diario-cat-chip-neutral.diario-cat-chip-active { background: rgba(120, 120, 120, 0.15); border-color: var(--muted); color: var(--fg); }

/* Slice 4 - Sub-chip "preventivi / curativi" del diario, visibile solo
   quando la chip categoria attiva è "Trattamento". Pi&ugrave; piccole della
   chip principale per dare gerarchia visiva. Riutilizzano il colore
   ambra (preventivo) e rosso (curativo) dalla palette journal-cat. */
.diario-subchips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.4rem;
    padding-left: 1rem;
    border-left: 2px solid var(--border);
}

.diario-subchip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 500;
    text-decoration: none;
    border: 1px solid var(--border);
    background: var(--card-bg);
    color: var(--fg);
}

.diario-subchip:hover {
    border-color: var(--accent);
}

.diario-subchip-active {
    border-color: var(--accent);
    background: rgba(74, 124, 89, 0.12);
    color: var(--accent-dark);
    font-weight: 600;
}

.diario-subchip.diario-cat-chip-amber.diario-subchip-active {
    background: rgba(199, 153, 57, 0.20); border-color: #c79939; color: #8a6420;
}

.diario-subchip.diario-cat-chip-red.diario-subchip-active {
    background: rgba(176, 68, 68, 0.18); border-color: #b04444; color: #8a2020;
}

/* Form filtri: range, custom from/to, ricerca testo */
.diario-filters-form {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 0.65rem;
    align-items: end;
}

.diario-filter-custom {
    display: flex;
    gap: 0.5rem;
    grid-column: span 2;
}

.diario-filter-custom .field {
    flex: 1;
}

.diario-filter-actions {
    display: flex;
    gap: 0.4rem;
    align-items: center;
}

.diario-filters-form .primary-button,
.diario-filters-form .secondary-button {
    margin: 0;
    padding: 0.45rem 0.85rem;
    font-size: 0.88rem;
    white-space: nowrap;
}

/* Sommario conteggi: totale + filtri attivi rimovibili + breakdown */
.diario-counts {
    background: var(--card-bg);
    border-radius: 8px;
    padding: 0.7rem 1rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    display: flex;
    flex-wrap: wrap;
    gap: 0.7rem;
    align-items: center;
}

.diario-counts-total {
    margin: 0;
    color: var(--fg);
    font-size: 0.95rem;
}

.diario-active-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

.diario-active-filter {
    display: inline-flex;
    align-items: center;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-size: 0.78rem;
    background: rgba(74, 124, 89, 0.12);
    color: var(--accent-dark);
    text-decoration: none;
    border: 1px solid rgba(74, 124, 89, 0.2);
}

.diario-active-filter:hover {
    background: rgba(74, 124, 89, 0.2);
}

.diario-counts-breakdown {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-left: auto;
}

.diario-counts-item {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    font-size: 0.82rem;
    background: rgba(0, 0, 0, 0.04);
    color: var(--fg);
}

/* ====================================================================
   Slice D1: foto allegate alle entry del diario
   ==================================================================== */

/* Griglia di thumbnail dentro la card della entry. Auto-fit responsive:
   pi&ugrave; thumb in linea su desktop, meno (o singola colonna) su mobile.
   Il bottone "Aggiungi foto" sta nell'ultima cella della stessa griglia. */
.photo-grid {
    margin-top: 0.5rem;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
    gap: 0.5rem;
    align-items: stretch;
}

/* Variante "vuota" (nessuna foto): non serve la grid larga, basta il
   bottone in linea con il resto del testo. */
.photo-grid-empty {
    grid-template-columns: max-content;
}

/* Slice D3: la photo-thumb &egrave; SEMPRE quadrata (aspect-ratio 1/1) cos&igrave;
   tutte le celle della grid hanno la stessa altezza, indipendentemente
   dalla presenza/assenza di caption o context-link. Caption e context
   sono overlay assoluti in basso (gradient nero). */
.photo-thumb {
    margin: 0;
    position: relative;
    aspect-ratio: 1 / 1;
    border-radius: 6px;
    overflow: hidden;
    border: 1px solid var(--border);
    background: rgba(0, 0, 0, 0.04);
}

.photo-thumb-link {
    display: block;
    width: 100%;
    height: 100%;
    line-height: 0;
}

.photo-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Overlay in basso: contiene caption + context-link impilati. Gradient
   semi-trasparente per far risaltare il testo bianco sull'immagine. */
.photo-thumb-overlay {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 0.45rem 0.5rem 0.35rem;
    background: linear-gradient(to top,
        rgba(0, 0, 0, 0.75) 30%,
        rgba(0, 0, 0, 0));
    color: #fff;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.photo-thumb-overlay .photo-caption {
    font-size: 0.72rem;
    line-height: 1.2;
    /* Una riga, ellipsis se troppo lungo */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.photo-thumb-overlay .photo-context-link {
    display: block;
    font-size: 0.7rem;
    line-height: 1.2;
    color: #cce4d3;       /* verde chiaro per leggibilit&agrave; sul gradient nero */
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    /* Reset stile dello stato D3 (sfondo verde chiaro) — qui &egrave; overlay */
    background: transparent;
    border-top: none;
    padding: 0;
}

.photo-thumb-overlay .photo-context-link:hover {
    color: #fff;
    background: transparent;
}

.photo-thumb-overlay .photo-context-icon {
    margin-right: 0.2rem;
}

/* Bottone elimina sovrapposto in alto a destra */
.photo-thumb .photo-delete {
    position: absolute;
    top: 0.25rem;
    right: 0.25rem;
    margin: 0;
    z-index: 1;  /* sopra l'immagine ma irrilevante rispetto all'overlay basso */
}

.photo-thumb .photo-delete .icon-button {
    background: rgba(255, 255, 255, 0.85);
    width: 1.7rem;
    height: 1.7rem;
    border-radius: 50%;
    border: 1px solid var(--border);
    backdrop-filter: blur(2px);
}

.photo-thumb .photo-delete .icon-button:hover {
    background: rgba(255, 255, 255, 1);
}

/* Slice FOTO-2 (giu 2026): bottone "imposta copertina" (stella) in
   alto a sinistra (il delete e' in alto a destra) + badge "copertina"
   sulla foto attualmente di copertina. */
.photo-thumb .photo-cover-set {
    position: absolute;
    top: 0.25rem;
    left: 0.25rem;
    margin: 0;
    z-index: 1;
}
.photo-thumb .photo-cover-set .icon-button {
    background: rgba(255, 255, 255, 0.85);
    width: 1.7rem;
    height: 1.7rem;
    border-radius: 50%;
    border: 1px solid var(--border);
    backdrop-filter: blur(2px);
    color: #b8860b;            /* stella oro tenue */
    font-size: 1rem;
    line-height: 1;
}
.photo-thumb .photo-cover-set .icon-button:hover {
    background: rgba(255, 255, 255, 1);
    color: #c79939;
}
.photo-thumb .photo-cover-badge {
    position: absolute;
    top: 0.25rem;
    left: 0.25rem;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    padding: 0.15rem 0.45rem;
    font-size: 0.72rem;
    font-weight: 600;
    color: #fff;
    background: rgba(74, 124, 89, 0.92);
    border-radius: 999px;
    backdrop-filter: blur(2px);
}

/* Bottone "Aggiungi foto" coerente come dimensione della grid cell */
.photo-add-btn {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    aspect-ratio: 1 / 1;
    border-radius: 6px;
    border: 2px dashed var(--border);
    background: rgba(0, 0, 0, 0.02);
    color: var(--muted);
    text-decoration: none;
    text-align: center;
    transition: border-color 0.15s, color 0.15s, background 0.15s;
    padding: 0.4rem;
    gap: 0.2rem;
}

.photo-add-btn:hover {
    border-color: var(--accent);
    color: var(--accent);
    background: rgba(74, 124, 89, 0.06);
}

.photo-add-icon {
    font-size: 1.6rem;
    line-height: 1;
}

.photo-add-label {
    font-size: 0.78rem;
    font-weight: 600;
}

/* Mobile: thumb pi&ugrave; piccoli, max 2 colonne quando c'&egrave; poco spazio */
@media (max-width: 480px) {
    .photo-grid {
        grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
    }
}

/* ====================================================================
   Slice D2: sezione "Galleria del vaso" come detail-card-wide
   ==================================================================== */

/* La galleria &egrave; renderizzata come `.detail-card.detail-card-wide` —
   span 2 colonne della grid auto-fill del detail, stesso pattern del
   diario. Niente CSS di layout speciale; la classe .pot-gallery-section
   serve solo per gli override puntuali (es. dimensioni thumbnail pi&ugrave;
   ariose visto che lo spazio &egrave; pi&ugrave; ampio rispetto alle card del diario). */

.pot-gallery-section .photo-grid {
    /* Thumbnail leggermente pi&ugrave; grandi (140px min) per dare evidenza
       alle foto del vaso rispetto alla griglia del diario (110px min). */
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    margin-top: 0.5rem;
}

@media (max-width: 480px) {
    .pot-gallery-section .photo-grid {
        grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
    }
}

/* Slice D3: link "Vedi tutte le foto del vaso" sotto la griglia della
   galleria nel detail (visibile se ci sono pi&ugrave; foto generali del limite
   di 6 mostrato). */
.gallery-view-all {
    margin: 0.6rem 0 0;
    text-align: right;
}

.gallery-view-all a {
    color: var(--accent);
    text-decoration: none;
    font-weight: 600;
    font-size: 0.9rem;
    border-bottom: 1px dashed var(--border);
}

.gallery-view-all a:hover {
    border-bottom-color: var(--accent);
}

/* ====================================================================
   Slice D3: pagina dedicata `/vasi/<id>/foto` cross-source
   ==================================================================== */

.foto-page {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* Chip di filtro source (Tutte / Generali / Da diario) — riusa il
   look-and-feel di .diario-cat-chip. */
.foto-source-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    background: var(--card-bg);
    border-radius: 8px;
    padding: 0.7rem 0.85rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

.foto-source-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.25rem 0.7rem;   /* UX-6: metriche chip unificate */
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 500;
    text-decoration: none;
    border: 1px solid var(--border);
    background: var(--card-bg);
    color: var(--fg);
    transition: background 0.15s, border-color 0.15s;
}

.foto-source-chip:hover {
    border-color: var(--accent);
}

.foto-source-chip-active {
    border-color: var(--accent);
    background: rgba(74, 124, 89, 0.12);
    color: var(--accent-dark);
    font-weight: 600;
}

/* Sommario "N trovate" + breakdown per source */
.foto-counts {
    background: var(--card-bg);
    border-radius: 8px;
    padding: 0.7rem 1rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    display: flex;
    flex-wrap: wrap;
    gap: 0.7rem;
    align-items: center;
}

.foto-counts-total {
    margin: 0;
    color: var(--fg);
    font-size: 0.95rem;
}

.foto-counts-breakdown {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-left: auto;
}

.foto-counts-item {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-size: 0.82rem;
    background: rgba(0, 0, 0, 0.04);
    color: var(--fg);
}

/* Griglia foto pagina dedicata: card su sfondo bianco per dare aria */
.foto-page .photo-grid {
    background: var(--card-bg);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    margin-top: 0;
}

/* Stili .photo-context-link e .photo-context-icon sono definiti
   sopra dentro .photo-thumb-overlay: il context-link &egrave; un overlay
   bianco/verde-chiaro su gradient nero, non una riga sotto la thumb. */

/* ====================================================================
   Slice D4: lightbox/viewer foto full-screen
   ==================================================================== */

#lightbox-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    background: rgba(0, 0, 0, 0.92);
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
    cursor: zoom-out;  /* segnala che click sullo sfondo chiude */
}

#lightbox-overlay[hidden] {
    display: none;
}

/* Disabilita lo scroll del body quando il lightbox &egrave; aperto */
body.lightbox-open {
    overflow: hidden;
}

.lb-img {
    max-width: 90vw;
    max-height: 80vh;
    object-fit: contain;
    border-radius: 4px;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.5);
    cursor: default;  /* sopra l'immagine niente "zoom-out" cursor */
}

/* Bottoni di controllo (X, prev, next): cerchio semi-trasparente
   con bordo bianco. Diventano pi&ugrave; opachi all'hover. */
.lb-close,
.lb-prev,
.lb-next {
    position: absolute;
    background: rgba(255, 255, 255, 0.12);
    border: 1px solid rgba(255, 255, 255, 0.35);
    color: #fff;
    border-radius: 50%;
    width: 3rem;
    height: 3rem;
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: background 0.15s, border-color 0.15s;
    z-index: 1;
}

.lb-close:hover,
.lb-prev:not(:disabled):hover,
.lb-next:not(:disabled):hover {
    background: rgba(255, 255, 255, 0.28);
    border-color: rgba(255, 255, 255, 0.6);
}

.lb-close {
    top: 1rem;
    right: 1rem;
    font-size: 1.6rem;
}

.lb-prev {
    left: 1rem;
    top: 50%;
    transform: translateY(-50%);
}

.lb-next {
    right: 1rem;
    top: 50%;
    transform: translateY(-50%);
}

.lb-prev:disabled,
.lb-next:disabled {
    opacity: 0.25;
    cursor: not-allowed;
}

/* Riquadro meta in basso: counter + caption + context-link */
.lb-meta {
    position: absolute;
    bottom: 1.2rem;
    left: 50%;
    transform: translateX(-50%);
    color: #fff;
    text-align: center;
    background: rgba(0, 0, 0, 0.55);
    padding: 0.55rem 1rem;
    border-radius: 8px;
    max-width: 80vw;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    cursor: default;
}

.lb-counter {
    font-size: 0.78rem;
    color: rgba(255, 255, 255, 0.65);
    letter-spacing: 0.04em;
}

.lb-caption {
    font-size: 0.95rem;
    line-height: 1.3;
    color: #fff;
}

.lb-caption:empty {
    display: none;
}

.lb-context {
    font-size: 0.82rem;
    color: #cce4d3;
    text-decoration: none;
    border-bottom: 1px dashed rgba(204, 228, 211, 0.4);
}

.lb-context:hover {
    color: #fff;
    border-bottom-color: rgba(255, 255, 255, 0.7);
}

.lb-context[hidden] {
    display: none;
}

/* Mobile: controlli pi&ugrave; piccoli e padding ridotto */
@media (max-width: 600px) {
    #lightbox-overlay {
        padding: 0.5rem;
    }
    .lb-img {
        max-width: 95vw;
        max-height: 75vh;
    }
    .lb-close,
    .lb-prev,
    .lb-next {
        width: 2.4rem;
        height: 2.4rem;
        font-size: 1.1rem;
    }
    .lb-close { top: 0.5rem; right: 0.5rem; }
    .lb-prev { left: 0.5rem; }
    .lb-next { right: 0.5rem; }
    .lb-meta {
        bottom: 0.6rem;
        max-width: 95vw;
        padding: 0.45rem 0.8rem;
    }
}

/* ============================================================
   Dashboard / agenda cross-vaso (slice E1)
   ============================================================ */

.dashboard {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    margin-top: 0.5rem;
}

/* Quick stats: 4 card sempre affiancate su desktop, 2 colonne su tablet,
   1 colonna su mobile. Niente auto-fit: garantisce 4-su-riga finch&eacute;
   c'&egrave; spazio sufficiente. */
.quick-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.75rem;
}

@media (max-width: 800px) {
    .quick-stats {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 480px) {
    .quick-stats {
        grid-template-columns: 1fr;
    }
}

.stat-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem;
    text-align: center;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}

.stat-icon {
    font-size: 1.6rem;
    line-height: 1;
}

.stat-value {
    font-size: 2rem;
    font-weight: 700;
    color: var(--accent-dark);
    margin-top: 0.25rem;
    line-height: 1.1;
}

.stat-label {
    font-size: 0.85rem;
    color: var(--muted);
    margin-top: 0.15rem;
}

.stat-sub {
    font-size: 0.78rem;
    color: var(--muted);
    margin-top: 0.4rem;
}

.stat-sub-alert {
    color: #8a2020;
    font-weight: 600;
}

/* Grid per le 2 sezioni mediane (pianificazione larga, recenti stretta).
   Su mobile si impilano. */
.dash-grid {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    gap: 1rem;
}

/* Slice home-align (lug 2026): le due sezioni affiancate («Da fare
   ora» + «Attività recenti») devono partire e finire allineate.
   Annulla il margine verticale ereditato da .dash-section +
   .dash-section (pensato per le dashboard impilate, non per la
   griglia) e ancora il footer in fondo; gli stati vuoti si centrano
   nello spazio che resta. */
.dash-grid > .dash-section + .dash-section { margin-top: 0; }
.dash-grid > .dash-section {
    display: flex;
    flex-direction: column;
}
.dash-grid .dash-empty-block {
    margin-top: auto;
    margin-bottom: auto;
}
/* Più specifico della regola base .dash-planning-footer (definita
   dopo nel file): dentro la griglia il footer va in fondo alla card. */
.dash-grid .dash-planning-footer { margin-top: auto; }

@media (max-width: 800px) {
    .dash-grid {
        grid-template-columns: 1fr;
    }
}

.dash-section {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem 1.25rem;
}
/* Slice A1-HOTFIX (mag 2026): spaziatura verticale fra sezioni
   consecutive della dashboard (tecnica / agronomica). Senza questa,
   la nuova "Parametri tecnici" / "Metriche agronomiche" si attaccava
   visivamente allo scatter / widget sopra. Selettore adjacent
   sibling: si applica SOLO fra dash-section consecutive, non
   sull'header pagina (che usa .page-header). */
.dash-section + .dash-section {
    margin-top: 1.25rem;
}
/* Sull'agronomica, i 7 widget aggregati sono dentro
   <section class="agro-dashboard">, NON dash-section. La nuova
   sezione "Metriche per vaso" (.dash-section) la segue: serve un
   secondo selettore per separare le due. */
.agro-dashboard + .dash-section {
    margin-top: 1.25rem;
}

.dash-section h2 {
    font-size: 1.1rem;
    margin: 0;
    color: var(--accent-dark);
}

/* Header della sezione (titolo + bottone azione a destra). Bottone
   secondary &egrave; opzionale: senza, l'header collassa al solo h2. */
.dash-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
    flex-wrap: wrap;
}

.dash-section-header .secondary-button {
    margin: 0;
    padding: 0.35rem 0.75rem;
    font-size: 0.85rem;
}

.dash-empty {
    color: var(--muted);
    font-style: italic;
    margin: 0.5rem 0;
}

/* Box per messaggio vuoto + CTA: testo + bottone primario centrati. */
.dash-empty-block {
    text-align: center;
    padding: 1.5rem 1rem;
}

.dash-empty-block p {
    color: var(--muted);
    margin: 0 0 0.85rem 0;
}

.dash-empty-block .primary-button {
    display: inline-block;
    text-decoration: none;
    margin-top: 0;
    padding: 0.6rem 1rem;
}

/* ── Pianificazione: bucket + righe evento ─────────────────────────── */

/* max-height + overflow-y: lo scroll &egrave; solo sulla lista interna, cos&igrave;
   l'header (titolo + bottone "+ Registra attivit&agrave;") e il footer
   "Vedi tutto sul calendario" restano sempre visibili. `padding-right`
   piccolo per non far sovrapporre la scrollbar al contenuto. */
.event-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    max-height: 24rem;
    overflow-y: auto;
    padding-right: 0.25rem;
}

.bucket-header {
    font-weight: 600;
    font-size: 0.95rem;
    padding: 0.4rem 0.6rem;
    border-radius: 5px;
    margin-top: 0.5rem;
    background: rgba(120, 120, 120, 0.08);
    color: #555;
}

.bucket-header:first-child {
    margin-top: 0;
}

.bucket-overdue {
    background: var(--error-bg);
    color: var(--error-fg);
}

.bucket-today {
    background: var(--warn-bg);
    color: var(--warn-fg);
}

.bucket-count {
    font-weight: 400;
    opacity: 0.75;
    margin-left: 0.25rem;
}

/* Slice ux-roles (UX-4): la home usa la card evento unificata del
   calendario (.cal-event, vedi sezione calendario). Qui solo il
   wrapper di lista, la riga data e il marker "scaduto". */
.event-li {
    list-style: none;
}

.event-when {
    font-size: 0.82rem;
    color: var(--muted);
    margin-top: 0.15rem;
}

.event-relative {
    font-style: italic;
}

/* Doppia classe: .cal-event (definita più avanti) imposta il background
   con la stessa specificità — così il tint "scaduto" vince comunque. */
.cal-event.cal-event-overdue {
    border-left: 3px solid #b04444;
    background: rgba(176, 68, 68, 0.05);
}

.cal-event-overdue .event-when {
    color: #b04444;
}

.dash-nothing-today p {
    color: var(--muted);
    margin: 0.4rem 0;
}

/* ── Attivit&agrave; recenti ──────────────────────────────────────────── */

/* Stessa logica di .event-list: scroll solo sulla lista, header con
   il bottone "+ Aggiungi foto" resta fisso. Anche se l'attivit&agrave;
   recenti &egrave; gi&agrave; limitata a 5 entry server-side, il cap visivo
   uniforma le due colonne della dash-grid. */
.recent-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    max-height: 24rem;
    overflow-y: auto;
    padding-right: 0.25rem;
}

.recent-row {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 0.6rem;
    padding: 0.45rem 0.6rem;
    border-radius: 5px;
}

.recent-row:hover {
    background: rgba(120, 120, 120, 0.06);
}

.recent-icon {
    width: 1.85rem;
    height: 1.85rem;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.95rem;
    flex-shrink: 0;
}

/* min-width: 0 fa stringere la colonna 1fr al suo spazio reale invece
   del min-content (default `auto` in Grid). Senza questo, una parola
   lunga come "Fertirrigazione" gonfia la colonna e spinge la data fuori
   dal bordo destro della card. */
.recent-body {
    min-width: 0;
}

.recent-title {
    font-size: 0.92rem;
    color: #333;
    overflow-wrap: anywhere;
}

.recent-title a {
    color: var(--accent-dark);
    text-decoration: none;
    font-weight: 600;
}

.recent-title a:hover {
    text-decoration: underline;
}

.recent-date {
    font-size: 0.8rem;
    color: var(--muted);
    white-space: nowrap;
}

/* ── Tile sotto-dashboard ─────────────────────────────────────────── */

.dash-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 0.75rem;
    background: transparent;
    border: none;
    padding: 0;
}

/* Slice mod_03: tile compatte a riga (icona | testo) invece delle
   vecchie card alte impilate. Padding ridotto -> meno ingombro
   verticale ora che sono in cima alla home. */
.dashboard-tile {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0.75rem;
    padding: 0.7rem 1rem;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: inherit;
    text-decoration: none;
    transition: border-color 0.15s, box-shadow 0.15s, transform 0.15s;
}

.dashboard-tile:hover {
    border-color: var(--accent);
    box-shadow: 0 3px 8px rgba(74, 124, 89, 0.12);
    transform: translateY(-1px);
}

.tile-icon {
    font-size: 1.5rem;
    line-height: 1;
    flex-shrink: 0;
}

/* Slice mod_03: wrapper che impila titolo+sottotitolo a destra
   dell'icona. */
.tile-text {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

.tile-title {
    font-size: 1rem;
    font-weight: 700;
    color: var(--accent-dark);
}

.tile-sub {
    font-size: 0.82rem;
    color: var(--muted);
}

/* ── Stato vuoto (0 vasi AND 0 entry AND 0 foto) ─────────────────── */

.dashboard-empty {
    text-align: center;
    padding: 3rem 1.5rem;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
}

.dashboard-empty .empty-icon {
    font-size: 4rem;
    line-height: 1;
}

.dashboard-empty h2 {
    margin: 1rem 0 0.5rem 0;
    color: var(--accent-dark);
}

.dashboard-empty p {
    color: var(--muted);
    max-width: 540px;
    margin: 0.5rem auto 1.25rem auto;
    line-height: 1.5;
}

.dashboard-empty .primary-button {
    display: inline-block;
    text-decoration: none;
    padding: 0.85rem 1.4rem;
}

/* Riccio accoglie (empty-state come fumetto del giardiniere virtuale):
   niente card bianca ne' cerchio, per un look piu' naturale. */
.dashboard-empty-riccio {
    background: transparent;
    border: none;
    padding: 1rem 1rem 2rem 1rem;
}
.dashboard-empty-riccio .riccio-hero-avatar {
    width: 200px;
    height: 200px;
    object-fit: cover;
    display: block;
    margin: 0 auto;
    /* L'immagine ha uno sfondo non trasparente: invece del cerchio netto, una
       maschera radiale sfuma i bordi (look naturale). Per un ritaglio nitido
       servirebbe un PNG del riccio con sfondo trasparente. */
    -webkit-mask-image: radial-gradient(circle at 50% 47%, #000 60%, rgba(0, 0, 0, 0) 80%);
    mask-image: radial-gradient(circle at 50% 47%, #000 60%, rgba(0, 0, 0, 0) 80%);
}
.dashboard-empty-riccio .riccio-fumetto {
    position: relative;
    max-width: 560px;
    margin: 1rem auto 0 auto;
    padding: 1.25rem 1.5rem;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 14px;
    text-align: left;
}
/* Codina del fumetto che punta all'avatar di Riccio sopra. */
.dashboard-empty-riccio .riccio-fumetto::before {
    content: "";
    position: absolute;
    top: -8px;
    left: 50%;
    transform: translateX(-50%) rotate(45deg);
    width: 15px;
    height: 15px;
    background: var(--bg);
    border-left: 1px solid var(--border);
    border-top: 1px solid var(--border);
}
.dashboard-empty-riccio .riccio-fumetto p {
    color: var(--fg);
    max-width: none;
    margin: 0 0 0.75rem 0;
    line-height: 1.55;
}
.dashboard-empty-riccio .riccio-fumetto p:last-of-type {
    margin-bottom: 1.1rem;
}
/* Azioni (bottoni) del fumetto: allineate su una riga, centrate, con wrap
   pulito se non ci stanno (es. i due bottoni della pagina Gruppi). */
.dashboard-empty-riccio .riccio-azioni {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.6rem;
}
.dashboard-empty-riccio .riccio-azioni .primary-button,
.dashboard-empty-riccio .riccio-azioni .secondary-button {
    text-decoration: none;
}

/* ── Placeholder pagine sotto-dashboard ──────────────────────────── */

.dashboard-placeholder {
    text-align: center;
    padding: 2.5rem 1.5rem;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
}

.dashboard-placeholder .placeholder-icon {
    font-size: 3.5rem;
    line-height: 1;
}

.dashboard-placeholder h2 {
    margin: 0.75rem 0 0.4rem 0;
    color: var(--accent-dark);
}

.placeholder-tag {
    display: inline-block;
    background: rgba(199, 153, 57, 0.18);
    color: #8a6420;
    padding: 0.25rem 0.75rem;
    border-radius: 4px;
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin: 0.25rem 0 1rem 0;
}

.placeholder-description {
    max-width: 600px;
    margin: 0 auto 1.5rem auto;
    color: #444;
    line-height: 1.55;
}

.dashboard-placeholder .primary-button {
    display: inline-block;
    text-decoration: none;
    padding: 0.6rem 1rem;
}

/* Responsive: su mobile riduci padding e font dei vari box. */
@media (max-width: 600px) {
    .stat-card { padding: 0.75rem; }
    .stat-icon { font-size: 1.3rem; }
    .stat-value { font-size: 1.6rem; }
    .stat-label { font-size: 0.78rem; }
    .dash-section { padding: 0.85rem 1rem; }
    .dashboard-empty { padding: 2rem 1rem; }
    .dashboard-empty .empty-icon { font-size: 3rem; }
}

/* ============================================================
   Dashboard Agronomica (slice E5)
   ============================================================ */

.agronomia-page {
    margin-top: 0.5rem;
}

.agro-dashboard {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* KPI hero (indice di salute). Bordo colorato in base alla soglia
   (verde >=80, ambra >=50, rosso <50). */
.agro-kpi {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1.25rem 1.5rem;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-left: 6px solid #888;
    border-radius: 8px;
}

.agro-kpi.kpi-good { border-left-color: var(--accent); }
.agro-kpi.kpi-mid  { border-left-color: var(--warn-border); }
.agro-kpi.kpi-bad  { border-left-color: var(--error-border); }

.agro-kpi-icon {
    font-size: 2.5rem;
    line-height: 1;
}

.agro-kpi-body {
    flex: 1;
    min-width: 0;
}

.agro-kpi-label {
    font-size: 0.85rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
}

.agro-kpi-value {
    font-size: 2.6rem;
    font-weight: 700;
    color: var(--accent-dark);
    line-height: 1.05;
    margin-top: 0.15rem;
}

.kpi-good .agro-kpi-value { color: var(--accent); }
.kpi-mid .agro-kpi-value  { color: var(--warn-fg); }
.kpi-bad .agro-kpi-value  { color: var(--error-fg); }

.agro-kpi-sub {
    font-size: 0.9rem;
    color: var(--muted);
    margin-top: 0.2rem;
}

/* Grid card auto-fill: minmax 320 cos&igrave; su desktop standard
   appaiono 2-3 colonne. */
.agro-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 1rem;
}

.agro-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem 1.25rem;
}

.agro-card h3 {
    font-size: 1rem;
    margin: 0 0 0.85rem 0;
    color: var(--accent-dark);
}

.agro-card h3 small {
    font-weight: 400;
    color: var(--muted);
    margin-left: 0.3rem;
}

.agro-empty {
    color: var(--muted);
    font-style: italic;
    margin: 0.5rem 0;
}

/* ── Donut SVG ────────────────────────────────────────────────────────── */

.agro-donut-wrap {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 0 0 0.85rem 0;
}

.agro-donut {
    width: 140px;
    height: 140px;
}

.agro-donut-center {
    position: absolute;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}

.agro-donut-center strong {
    font-size: 1.8rem;
    color: var(--accent-dark);
    line-height: 1;
}

.agro-donut-center small {
    font-size: 0.75rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.agro-legend {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.agro-legend-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.85rem;
}

.agro-legend-swatch {
    display: inline-block;
    width: 0.85rem;
    height: 0.85rem;
    border-radius: 3px;
    flex-shrink: 0;
}

.agro-legend-label {
    flex: 1;
    color: #333;
}

.agro-legend-count {
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

/* ── Bar list (specie + vasi attenzione) ─────────────────────────────── */

.agro-bar-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.agro-bar-row {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(60px, 2fr) auto;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.88rem;
}

.agro-bar-label {
    color: #333;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.agro-bar-label a {
    color: var(--accent-dark);
    text-decoration: none;
    font-weight: 600;
}

.agro-bar-label a:hover {
    text-decoration: underline;
}

.agro-bar-track {
    display: block;
    background: rgba(120, 120, 120, 0.10);
    border-radius: 3px;
    height: 0.55rem;
    overflow: hidden;
    position: relative;
}

.agro-bar-fill {
    display: block;
    height: 100%;
    background: var(--accent);
    border-radius: 3px;
    transition: width 0.2s;
}

.agro-bar-count {
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    font-size: 0.82rem;
    white-space: nowrap;
}

.agro-bar-extra {
    margin-left: 0.3rem;
    color: var(--muted);
    font-style: italic;
}

/* ── Mini stat indoor / outdoor ──────────────────────────────────────── */

.agro-loc-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem;
}

.agro-loc-cell {
    text-align: center;
    padding: 0.6rem 0.4rem;
    background: rgba(74, 124, 89, 0.04);
    border-radius: 5px;
}

.agro-loc-icon {
    font-size: 1.6rem;
    line-height: 1;
}

.agro-loc-count {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--accent-dark);
    line-height: 1.1;
    margin-top: 0.2rem;
}

.agro-loc-label {
    font-size: 0.75rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-top: 0.1rem;
}

/* ── Tabelle (fitopatie, frequenza diario) ───────────────────────────── */

.agro-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.88rem;
}

.agro-table th {
    text-align: left;
    padding: 0.4rem 0.5rem;
    color: var(--muted);
    border-bottom: 1px solid var(--border);
    font-weight: 600;
    text-transform: uppercase;
    font-size: 0.72rem;
    letter-spacing: 0.04em;
}

.agro-table td {
    padding: 0.45rem 0.5rem;
    border-bottom: 1px solid rgba(120, 120, 120, 0.08);
    color: #333;
}

.agro-table tbody tr:last-child td {
    border-bottom: none;
}

.agro-table .agro-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.agro-table a {
    color: var(--accent-dark);
    text-decoration: none;
    font-weight: 600;
}

.agro-table a:hover {
    text-decoration: underline;
}

/* ============================================================
   Calendario / eventi pianificati (slice E2)
   ============================================================ */

/* Header pagina con titolo a sinistra e bottone azione a destra. */
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.page-header h2 {
    margin: 0;
    color: var(--accent-dark);
}

.page-header .primary-button,
.page-header .secondary-button {
    margin: 0;
}

.calendar-page,
.calendar-form-page {
    margin-top: 0.5rem;
}

/* Footer "Vedi tutto sul calendario →" sotto la sezione Pianificazione
   della home. */
.dash-planning-footer {
    margin-top: 0.85rem;
    padding-top: 0.6rem;
    border-top: 1px solid var(--border);
    text-align: right;
}

.dash-link-more {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--accent);
    text-decoration: none;
}

.dash-link-more:hover {
    text-decoration: underline;
}

/* ── Sommario + filtri chip ─────────────────────────────────────────── */

.calendar-summary {
    margin: 0 0 0.85rem 0;
    color: #444;
}

.calendar-summary strong {
    color: var(--accent-dark);
    font-size: 1.1rem;
}

.calendar-summary-breakdown {
    color: var(--muted);
    font-size: 0.88rem;
    margin-left: 0.4rem;
}

.calendar-filters {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin-bottom: 1rem;
}

.calendar-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.calendar-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.25rem 0.7rem;   /* UX-6: metriche chip unificate */
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--card-bg);
    color: #444;
    font-size: 0.85rem;
    text-decoration: none;
    transition: background 0.12s, border-color 0.12s;
}

.calendar-chip:hover {
    /* Colore opaco equivalente a rgba(74,124,89,0.08) appiattito su
       bianco: serve perche' con lo sfondo stagionale attivo, un valore
       semi-trasparente lasciava trasparire l'immagine sotto la chip. */
    background: #eef3ef;
    border-color: rgba(74, 124, 89, 0.3);
}

/* UX-6: attivo = tinta + testo colorato come le chip di diario/foto/
   avvisi (era verde pieno + bianco, unica famiglia diversa). Colore
   opaco (tinta accent 0.12 appiattita su bianco) per lo sfondo
   stagionale, come per l'hover sopra. */
.calendar-chip-active {
    background: #e9efeb;
    color: var(--accent-dark);
    border-color: var(--accent);
    font-weight: 600;
}

.calendar-chip-active:hover {
    background: #dee8e1;
    border-color: var(--accent-dark);
}

/* Slice 4 - Sub-chip "preventivi / curativi" del calendario, visibile
   solo quando la chip categoria attiva &egrave; "Trattamento". Pi&ugrave;
   piccole della chip principale (gerarchia visiva), indentate. */
.calendar-subchips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.35rem;
    padding-left: 1rem;
    border-left: 2px solid rgba(255, 255, 255, 0.4);
}

.calendar-subchip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--card-bg);
    color: #444;
    font-size: 0.78rem;
    font-weight: 500;
    text-decoration: none;
}

.calendar-subchip:hover {
    background: #eef3ef;
    border-color: rgba(74, 124, 89, 0.3);
}

.calendar-subchip-active {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
    font-weight: 600;
}

.calendar-subchip.calendar-chip-amber.calendar-subchip-active {
    background: #c79939; border-color: #c79939;
}

.calendar-subchip.calendar-chip-red.calendar-subchip-active {
    background: #b04444; border-color: #b04444;
}

.calendar-pot-filter {
    margin: 0;
    max-width: 360px;
}

.calendar-pot-filter .field {
    margin: 0;
}

/* ── Navigatore settimana ────────────────────────────────────────────── */

.cal-week-nav {
    display: grid;
    grid-template-columns: auto 1fr auto auto;
    align-items: center;
    gap: 0.6rem;
    margin: 1rem 0 0.6rem 0;
}

.cal-week-title {
    margin: 0;
    text-align: center;
    color: var(--accent-dark);
    font-size: 1.05rem;
}

.cal-nav-arrow {
    margin: 0;
    padding: 0.4rem 0.75rem;
    font-size: 1rem;
    line-height: 1;
}

.cal-nav-today {
    margin: 0;
    padding: 0.4rem 0.85rem;
    font-size: 0.85rem;
}

@media (max-width: 600px) {
    /* Su mobile: titolo in alto su tutta la riga, sotto i bottoni
       di navigazione su una riga unica.
       Bugfix mag 2026: prima usavamo "auto 1fr auto" che, quando il
       bottone "Oggi" non c'era (settimana corrente), assegnava al
       "→" la colonna 1fr (largo) e al "←" la "auto" (stretto). Adesso
       usiamo :has() per distribuire le 2 frecce 50/50 quando "Oggi"
       e' assente, e 3 bottoni 33/33/33 quando e' presente. */
    .cal-week-nav {
        grid-template-columns: 1fr 1fr;
        gap: 0.4rem;
    }
    .cal-week-nav:has(.cal-nav-today) {
        grid-template-columns: 1fr 1fr 1fr;
    }
    .cal-week-title {
        grid-column: 1 / -1;
        order: -1;
    }
    .cal-nav-today {
        padding: 0.4rem 0.7rem;
        font-size: 0.82rem;
        /* Riempie la colonna anche con label corta */
        text-align: center;
    }
    .cal-nav-arrow {
        padding: 0.4rem 0.6rem;
        /* Idem: riempie la colonna in modo simmetrico */
        text-align: center;
    }
}

/* ── Banner overdue ──────────────────────────────────────────────────── */

.cal-overdue-banner {
    background: rgb(228, 87, 87);
    border: 1px solid rgb(102, 18, 18);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    margin-bottom: 1rem;
}

.cal-overdue-banner h3 {
    margin: 0 0 0.6rem 0;
    color: rgb(102, 18, 18);
    font-size: 1rem;
}

.cal-overdue-banner .overdue-count {
    font-weight: 400;
    opacity: 0.8;
}

.cal-overdue-list {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    /* Con molte scadenze (10+ eventi non ancora completati) il banner
       monopolizzava lo scroll della pagina, costringendo a scorrere
       a lungo prima di arrivare alla griglia settimanale. Limitiamo
       l'altezza a ~5 card visibili: il titolo "Scaduti (N)" sopra
       resta sempre visibile come header, la lista scorre internamente. */
    max-height: 22rem;
    overflow-y: auto;
    /* Spazio per non far sovrapporre la scrollbar alle card. */
    padding-right: 0.35rem;
}

/* ── Griglia settimanale ─────────────────────────────────────────────── */

/* 2 giorni per riga su desktop (4 righe per coprire i 7 giorni). 7
   colonne erano troppo strette: il testo di un evento andava in
   verticale per parola lunga ("Concimazione"). Su mobile ≤600px
   diventa 1 colonna. */
.cal-week-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.6rem;
}

@media (max-width: 600px) {
    .cal-week-grid {
        grid-template-columns: 1fr;
    }
}

.cal-day-cell {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.6rem;
    min-height: 7rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.cal-day-cell.cal-day-today {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(74, 124, 89, 0.15);
}

.cal-day-cell.cal-day-past {
    background: rgba(255, 255, 255, 0.6);
}

.cal-day-header {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    border-bottom: 1px solid var(--border);
    padding-bottom: 0.3rem;
}

.cal-day-name {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    font-weight: 600;
}

.cal-day-today .cal-day-name {
    color: var(--accent);
}

.cal-day-num {
    font-size: 0.92rem;
    color: #333;
    font-weight: 500;
}

.cal-day-events {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    flex: 1;
}

.cal-day-empty {
    color: var(--muted);
    text-align: center;
    margin: 0.5rem 0 0 0;
    font-size: 0.85rem;
}

/* Slice ux-compact (UX-3): giorno vuoto = riga sottile con intestazione
   inline, tono attenuato. Oggi resta sempre a card piena. */
.cal-day-cell.cal-day-compact {
    min-height: 0;
    padding: 0.35rem 0.6rem;
    opacity: 0.7;
    background: transparent;
}
.cal-day-compact .cal-day-header {
    flex-direction: row;
    align-items: baseline;
    gap: 0.5rem;
    border-bottom: none;
    padding-bottom: 0;
}

/* ── Card evento ─────────────────────────────────────────────────────── */

.cal-event {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: start;
    gap: 0.5rem;
    padding: 0.5rem 0.6rem;
    background: rgba(255, 255, 255, 0.85);
    border: 1px solid var(--border);
    border-radius: 5px;
    font-size: 0.85rem;
}

.cal-event.event-done {
    opacity: 0.55;
    text-decoration: line-through;
    text-decoration-thickness: 1px;
    background: rgba(120, 120, 120, 0.05);
}

.cal-event-icon {
    font-size: 1.05rem;
    line-height: 1.1;
    flex-shrink: 0;
}

.cal-event-body {
    min-width: 0;
}

.cal-event-title {
    font-weight: 600;
    color: #222;
    overflow-wrap: anywhere;
}

.cal-event-meta {
    font-size: 0.78rem;
    color: var(--muted);
    margin-top: 0.1rem;
}

.cal-event-meta a {
    color: var(--accent-dark);
    text-decoration: none;
    font-weight: 600;
}

.cal-event-meta a:hover {
    text-decoration: underline;
}

.cal-event-notes {
    font-size: 0.78rem;
    color: #555;
    margin-top: 0.2rem;
    font-style: italic;
}

.cal-event-actions {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    flex-shrink: 0;
}

.cal-event-actions .icon-button,
.cal-event-actions .inline-form {
    margin: 0;
}

/* ── Card meteo (slice E4: orizzonte 7gg nel calendario) ─────────── */

/* Card link al vaso, stile minimale, severity-colored border-left. Non
   ha azioni (informativa); icona meteo + titolo breve + messaggio
   dettagliato come secondary line. */
.cal-event-meteo {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: start;
    gap: 0.5rem;
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--border);
    border-radius: 5px;
    text-decoration: none;
    color: inherit;
    border-left-width: 3px;
}

.cal-event-meteo:hover {
    background: rgba(74, 124, 89, 0.04);
}

.cal-event-meteo .cal-event-title {
    font-size: 0.85rem;
    font-weight: 600;
    color: #333;
}

.cal-event-meteo .cal-event-meta {
    font-size: 0.78rem;
    color: var(--muted);
    line-height: 1.35;
}

.cal-event-meteo .cal-event-meta strong {
    color: var(--accent-dark);
}

.cal-event-meteo-critical {
    background: rgba(176, 68, 68, 0.06);
    border-left-color: #b04444;
}

.cal-event-meteo-critical .cal-event-title {
    color: #8a2020;
}

.cal-event-meteo-warning {
    background: rgba(199, 153, 57, 0.08);
    border-left-color: #c79939;
}

.cal-event-meteo-warning .cal-event-title {
    color: #8a6420;
}

.cal-event-meteo-info {
    background: rgba(120, 120, 120, 0.04);
    border-left-color: #888;
}

/* ── Card "Stress idrico previsto" (slice S1.3) ────────────────────── */

/* Stesso pattern grafico delle card meteo (border-left severity), ma con
   accento blu acqua per indicare il dominio (bilancio idrico FAO-56)
   invece del meteo grezzo. La card e' un link al detail vaso dove
   l'utente trova la curva idrica nel pdc-water-curve. */
.cal-event-water-stress {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: start;
    gap: 0.5rem;
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--border);
    border-radius: 5px;
    text-decoration: none;
    color: inherit;
    border-left-width: 3px;
}
.cal-event-water-stress:hover {
    background: rgba(60, 130, 200, 0.05);
}
.cal-event-water-stress .cal-event-title {
    font-size: 0.85rem;
    font-weight: 600;
    color: #333;
}
.cal-event-water-stress .cal-event-meta {
    font-size: 0.78rem;
    color: var(--muted);
    line-height: 1.35;
}
.cal-event-water-stress .cal-event-meta strong {
    color: #1c4a7a;
}
.cal-event-water-stress-warning {
    background: rgba(60, 130, 200, 0.08);
    border-left-color: #3a82c8;
}
.cal-event-water-stress-warning .cal-event-title {
    color: #1c4a7a;
}
.cal-event-water-stress-critical {
    background: rgba(176, 68, 68, 0.06);
    border-left-color: #b04444;
}
.cal-event-water-stress-critical .cal-event-title {
    color: #8a2020;
}

/* ── Card computed (scadenze calcolate da catalogo) ─────────────────── */

/* Stile pi&ugrave; tenue (border tratteggiato, background leggermente sfumato)
   per distinguere visivamente le scadenze calcolate dagli eventi utente. */
.cal-event-computed {
    border-style: dashed;
    background: rgba(255, 255, 255, 0.7);
}

.cal-event-meta-sub {
    font-size: 0.78rem;
    color: var(--muted);
    margin-top: 0.1rem;
}

.cal-event-auto-tag {
    display: inline-block;
    margin-top: 0.25rem;
    padding: 0.1rem 0.4rem;
    background: rgba(120, 120, 120, 0.10);
    color: var(--muted);
    border-radius: 3px;
    font-size: 0.7rem;
    font-style: italic;
    letter-spacing: 0.02em;
}

/* ── Form evento ─────────────────────────────────────────────────────── */

.event-form textarea {
    resize: vertical;
    min-height: 4rem;
}

/* ── Ricorrenza (slice E2-bis) ──────────────────────────────────────── */

.recurrence-fieldset {
    margin-top: 1rem;
}

.recurrence-config {
    margin-top: 0.75rem;
    padding: 0.6rem 0.85rem;
    background: rgba(74, 124, 89, 0.05);
    border-left: 3px solid var(--accent);
    border-radius: 0 4px 4px 0;
}

.recurrence-config[hidden] {
    display: none;
}

.recurrence-end {
    margin-top: 0.75rem;
}

.field-radio {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin: 0.4rem 0;
}

.field-radio input[type="number"],
.field-radio input[type="date"] {
    padding: 0.25rem 0.4rem;
    max-width: 8rem;
}

.field-help {
    display: block;
    color: var(--muted);
    font-size: 0.78rem;
    margin-top: 0.25rem;
}

/* Badge ricorrenza sulla card evento. Inline con il titolo, prima del testo. */
.cal-event-recurrence-badge {
    display: inline-block;
    margin-right: 0.3rem;
    font-size: 0.85em;
    cursor: help;
    user-select: none;
}

/* ============================================================
   Strip meteo home (slice E4)
   ============================================================ */

/* 7 celle (giorni) affiancate sopra le Quick Stats. Su mobile si
   spezza naturalmente con flex-wrap. */
.weather-strip {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.75rem 1rem;
    margin-bottom: 0.75rem;
}

.weather-strip-header {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 0.4rem;
}

.weather-location {
    font-size: 0.85rem;
    color: var(--muted);
}

/* Slice B (giu 2026): strip meteo a 14gg con toggle "+7 giorni".
   Layout flex con wrap: 7 giorni + bottone toggle stanno in una
   riga (8 celle); quando l'utente preme il toggle, gli altri 7
   giorni (.weather-day-extended) vengono mostrati nella riga
   successiva. CSS: i giorni extended sono display:none di default
   e :flex quando la section ha la classe .weather-strip-expanded. */
.weather-strip-cells {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}
.weather-strip-cells > .weather-day {
    flex: 1 1 calc(12.5% - 0.5rem);
    min-width: 90px;
    max-width: 180px;
}

@media (max-width: 800px) {
    .weather-strip-cells > .weather-day {
        flex: 1 1 calc(25% - 0.5rem);
    }
}

@media (max-width: 480px) {
    .weather-strip-cells > .weather-day {
        flex: 1 1 calc(50% - 0.5rem);
    }
}

/* I giorni della 2a settimana (8-14) sono nascosti di default e
   compaiono solo quando l'utente preme il toggle. */
.weather-day-extended {
    display: none !important;
}
.weather-strip-expanded .weather-day-extended {
    display: flex !important;
}

/* Bottone toggle "+N giorni": stesso layout di una cella weather-day,
   ma look distintivo (border dashed, accent color). */
.weather-day-toggle {
    background: rgba(74, 124, 89, 0.06);
    border-style: dashed !important;
    border-color: var(--accent, #4a7c59) !important;
    color: var(--accent-dark, #2f5d3b);
    cursor: pointer;
    justify-content: center;
    transition: background 0.15s;
}
.weather-day-toggle:hover {
    background: rgba(74, 124, 89, 0.12);
}
.weather-day-toggle-icon {
    font-size: 1.4rem;
    margin: 0.2rem 0 0.3rem;
    transition: transform 0.2s;
}
.weather-strip-expanded .weather-day-toggle .weather-day-toggle-icon {
    transform: rotate(180deg);
}
.weather-day-toggle-label {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--accent-dark, #2f5d3b);
}

/* Dark mode toggle */
:root[data-theme="dark"] .weather-day-toggle {
    background: rgba(120, 175, 140, 0.10);
}
@media (prefers-color-scheme: dark) {
    :root[data-theme="auto"] .weather-day-toggle {
        background: rgba(120, 175, 140, 0.10);
    }
}

.weather-day {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
    padding: 0.35rem 0.25rem;
    background: rgba(74, 124, 89, 0.04);
    border-radius: 5px;
    text-align: center;
    font-size: 0.8rem;
    min-width: 0;
    /* Slice "modal meteo 3h" (mag 2026): le card sono <button>. Reset
       degli stili button browser + cursor pointer + hover. Senza
       questi reset, il bordo button default e il background bianco
       sovrascriverebbero il look originale della card. */
    border: 1px solid transparent;
    font: inherit;
    color: inherit;
    cursor: pointer;
    transition: background 120ms ease, transform 80ms ease,
                border-color 120ms ease;
}
.weather-day:hover,
.weather-day:focus-visible {
    background: rgba(74, 124, 89, 0.10);
    border-color: rgba(74, 124, 89, 0.30);
    outline: none;
}
.weather-day:active {
    transform: scale(0.98);
}

/* Domenica evidenziata con sfondo giallino tenue. */
.weather-day-sunday {
    background: rgba(199, 153, 57, 0.18);
}

.weather-day-label {
    font-weight: 600;
    color: var(--accent-dark);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.weather-day-icon {
    font-size: 1.5rem;
    line-height: 1;
    margin: 0.1rem 0;
}

.weather-day-temps {
    color: #333;
    font-weight: 500;
}

.weather-day-temps .t-max {
    color: #b04444;
}

.weather-day-temps .t-min {
    color: #2c5482;
}

.weather-precip,
.weather-wind {
    font-size: 0.7rem;
    color: var(--muted);
    margin-top: 0.15rem;
}

.weather-strip-empty {
    text-align: center;
}

.weather-strip-invite {
    color: var(--muted);
    margin: 0.4rem 0;
    font-size: 0.9rem;
}

/* ── Modal meteo 3h (mag 2026) ───────────────────────────────────────── */

.weather-day-modal {
    border: none;
    border-radius: 10px;
    padding: 0;
    width: 100%;
    max-width: 520px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
    background: var(--card-bg, #fff);
    color: var(--ink, #222);
}
.weather-day-modal::backdrop {
    background: rgba(0, 0, 0, 0.45);
}
.weather-day-modal-form {
    margin: 0;
    padding: 1.2rem 1.3rem;
}
.weather-day-modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.6rem;
}
.weather-day-modal-header h3 {
    margin: 0;
    color: var(--accent);
    font-size: 1.05rem;
}
.weather-day-modal-close {
    background: transparent;
    border: none;
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
    color: var(--muted);
    padding: 0 0.3rem;
}
.weather-day-modal-close:hover {
    color: var(--ink);
}
.weather-day-modal-body {
    min-height: 4rem;
}
.weather-day-location {
    margin: 0 0 0.6rem;
    font-size: 0.85rem;
    color: var(--muted);
}
.weather-day-loading,
.weather-day-error,
.weather-day-empty,
.weather-day-warning {
    margin: 0.5rem 0;
    color: var(--muted);
    text-align: center;
    font-size: 0.9rem;
}
.weather-day-error {
    color: #b43c3c;
}
.weather-day-warning {
    color: #a07020;
    background: rgba(230, 180, 60, 0.10);
    border-radius: 6px;
    padding: 0.5rem 0.7rem;
}

/* Lista dei 8 slot 3h: una riga per slot, griglia tabellare compatta. */
.weather-slots-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.weather-slot {
    display: grid;
    grid-template-columns: 3.5rem 1.6rem 1fr;
    grid-template-rows: auto auto;
    align-items: center;
    gap: 0.15rem 0.6rem;
    padding: 0.5rem 0.6rem;
    background: rgba(74, 124, 89, 0.05);
    border-radius: 6px;
}
.weather-slot .ws-time {
    grid-column: 1;
    grid-row: 1 / span 2;
    font-weight: 600;
    color: var(--accent-dark);
    font-size: 0.9rem;
    align-self: center;
}
.weather-slot .ws-icon {
    grid-column: 2;
    grid-row: 1 / span 2;
    font-size: 1.3rem;
    line-height: 1;
    text-align: center;
    align-self: center;
}
.weather-slot .ws-temp {
    grid-column: 3;
    grid-row: 1;
    font-weight: 600;
    color: #333;
}
.weather-slot .ws-apparent {
    color: var(--muted);
    font-weight: normal;
    font-size: 0.78rem;
    margin-left: 0.4rem;
}
.weather-slot .ws-meta {
    grid-column: 3;
    grid-row: 2;
    font-size: 0.78rem;
    color: var(--muted);
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 0.7rem;
}
.weather-slot .ws-precip-none {
    opacity: 0.4;
}

@media (max-width: 480px) {
    .weather-day-modal {
        max-width: calc(100vw - 1rem);
        margin: 0.5rem;
    }
    .weather-day-modal-form {
        padding: 0.9rem 1rem;
    }
    .weather-slot {
        grid-template-columns: 3rem 1.4rem 1fr;
        gap: 0.1rem 0.45rem;
        padding: 0.4rem 0.5rem;
    }
    .weather-slot .ws-meta {
        font-size: 0.74rem;
        gap: 0.3rem 0.5rem;
    }
}

.weather-strip-invite a {
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
}

.weather-strip-invite a:hover {
    text-decoration: underline;
}

/* Quick Stats compatte (slice E4): ridotto padding e size del valore
   per dare pi&ugrave; spazio alla strip meteo sopra. */
.stat-card {
    padding: 0.6rem 0.75rem;
}

.stat-icon {
    font-size: 1.3rem;
}

.stat-value {
    font-size: 1.5rem;
    margin-top: 0.15rem;
}

.stat-label {
    font-size: 0.78rem;
}

/* ============================================================
   Card location e meteo (slice E4)
   ============================================================ */

.location-card {
    /* eredita .auth-card .profile-card */
}

.location-current {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    padding: 0.6rem 0.85rem;
    background: rgba(74, 124, 89, 0.06);
    border-radius: 5px;
    margin-bottom: 0.85rem;
}

.location-current p {
    margin: 0;
    color: #333;
}

.location-current .secondary-button {
    margin: 0;
}

.location-empty {
    color: var(--muted);
    margin: 0 0 0.85rem 0;
    line-height: 1.45;
}

.location-search-form {
    display: flex;
    flex-wrap: wrap;
    align-items: end;
    gap: 0.6rem;
}

.location-search-form .field {
    flex: 1;
    min-width: 200px;
    margin: 0;
}

.location-search-form .secondary-button {
    margin: 0;
}

.location-results-form {
    margin-top: 1rem;
    padding-top: 0.85rem;
    border-top: 1px dashed var(--border);
}

.location-results-title {
    margin: 0 0 0.4rem 0;
    font-weight: 600;
    color: #333;
}

.location-no-results {
    margin-top: 0.85rem;
    padding: 0.5rem 0.75rem;
    background: rgba(120, 120, 120, 0.06);
    border-radius: 5px;
    color: var(--muted);
    font-size: 0.9rem;
}

/* ============================================================
   Avvisi / allerte (slice E3)
   ============================================================ */

/* Card sezione avvisi (in home: full-width tra Quick Stats e dash-grid;
   nel detail vaso: prima sezione, full-width). Eredita il padding/border/
   border-radius di .dash-section quando lo scope &egrave; 'home'; nel detail
   vaso usiamo classi proprie con stile coerente. */
.alerts-section {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem 1.25rem;
}

/* Quando in home, eredita anche da .dash-section (gi&agrave; styled), quindi
   sovrascriviamo solo se serve. */
.alerts-section.dash-section {
    /* niente overrides — eredita lo styling di .dash-section. */
}

/* ── Slice F-ritiro-4: sezione "Transizione stagionale" ────────────────
   Contenitore con i 2 blocchi "Da ricoverare" e "Da rimettere fuori".
   Si auto-nasconde quando non ci sono alert pertinenti. */
.recovery-section {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem 1.25rem;
}

.recovery-section .dash-section-header {
    margin-bottom: 0.5rem;
}

.recovery-block {
    margin-top: 0.85rem;
    padding: 0.85rem 1rem;
    border-radius: 6px;
    background: rgba(74, 124, 89, 0.04);
    border-left: 4px solid var(--accent);
}

.recovery-block + .recovery-block {
    margin-top: 0.6rem;
}

.recovery-block.recovery-uscita {
    background: rgba(199, 153, 57, 0.06);
    border-left-color: #c79939;
}

.recovery-block h3 {
    margin: 0 0 0.5rem;
    font-size: 1rem;
    color: var(--fg);
}

.recovery-block .recovery-count {
    font-weight: 400;
    color: var(--muted);
    font-size: 0.9rem;
}

.recovery-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.recovery-row {
    font-size: 0.92rem;
    line-height: 1.4;
}

.recovery-row-count,
.recovery-row-date {
    color: var(--muted);
    font-size: 0.85rem;
}

.recovery-hint {
    margin: 0.65rem 0 0;
    font-size: 0.85rem;
    color: var(--muted);
    font-style: italic;
}

/* Detail vaso: la sezione avvisi va span su tutta la grid auto-fill di
   `.detail-sections`, cos&igrave; appare come banda intera in cima (sopra la
   galleria). */
.detail-sections > .alerts-section {
    grid-column: 1 / -1;
}

.alerts-section h2 {
    font-size: 1.1rem;
    margin: 0;
    color: var(--accent-dark);
}

.alerts-count {
    font-weight: 400;
    opacity: 0.75;
    margin-left: 0.25rem;
}

.alert-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    max-height: 24rem;
    overflow-y: auto;
    padding-right: 0.25rem;
}

.alert-row {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: start;
    gap: 0.6rem;
    padding: 0.55rem 0.7rem;
    border-radius: 5px;
    border-left: 3px solid transparent;
}

.alert-icon {
    font-size: 1.15rem;
    line-height: 1.1;
    flex-shrink: 0;
}

.alert-body {
    min-width: 0;
}

.alert-message {
    color: #333;
    text-decoration: none;
    overflow-wrap: anywhere;
    line-height: 1.35;
}

.alert-message:hover {
    text-decoration: underline;
}

.alert-message strong {
    color: var(--accent-dark);
}

.alert-message em {
    font-style: italic;
}

/* Severity: critical = rosso (azione urgente), warning = ambra,
   info = grigio neutro. */
.alert-row.alert-critical {
    background: var(--error-bg);
    border-left-color: var(--error-border);
}

.alert-row.alert-critical .alert-message strong {
    color: var(--error-fg);
}

.alert-row.alert-warning {
    background: var(--warn-bg);
    border-left-color: var(--warn-border);
}

.alert-row.alert-warning .alert-message strong {
    color: var(--warn-fg);
}

.alert-row.alert-info {
    background: var(--info-bg);
    border-left-color: var(--info-border);
}

.alert-row.alert-info .alert-message strong {
    color: var(--info-fg);
}

/* Filtro chip per categoria allerte (rendered da render_alerts_section quando
   sono presenti almeno 2 severity diverse). Logica in static/js/app.js
   funzione setupAlertsFilter: filtra .alert-row via data-severity, aggiorna
   il counter e mostra/nasconde lo stato vuoto. Stesso pattern visivo delle
   `diario-cat-chip` ma adattato al contesto delle allerte. */
.alerts-filter-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin: 0 0 0.55rem 0;
    align-items: center;
}

.alert-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.85rem;
    font-family: inherit;
    background: rgba(255, 255, 255, 0.55);
    border: 1px solid var(--border);
    color: #555;
    border-radius: 999px;
    padding: 0.25rem 0.7rem;   /* UX-6: metriche chip unificate */
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
    line-height: 1.3;
}

.alert-chip:hover {
    background: rgba(255, 255, 255, 0.85);
    border-color: #a3a89a;
}

.alert-chip:focus-visible {
    outline: 2px solid var(--accent-dark);
    outline-offset: 1px;
}

.alert-chip-count {
    opacity: 0.7;
    font-weight: 400;
    margin-left: 0.15rem;
}

/* Stato attivo: palette coerente con .alert-row.alert-<sev> ma applicato
   alla chip. Le chip vuote non vengono renderizzate, quindi tutte quelle
   visibili sono cliccabili. */
.alert-chip-active {
    font-weight: 600;
}
.alert-chip-all.alert-chip-active {
    background: rgba(73, 102, 67, 0.15);
    border-color: var(--accent-dark);
    color: var(--accent-dark);
}
.alert-chip-critical.alert-chip-active {
    background: rgba(176, 68, 68, 0.15);
    border-color: #b04444;
    color: #8a2020;
}
.alert-chip-warning.alert-chip-active {
    background: rgba(199, 153, 57, 0.18);
    border-color: #c79939;
    color: #8a6420;
}
.alert-chip-info.alert-chip-active {
    background: rgba(120, 120, 120, 0.12);
    border-color: #888;
    color: #555;
}

/* Riga nascosta dal filtro: usata via attributo invece di hidden HTML5
   per evitare conflitti con altre regole. Stessa strategia di
   .pot-card[data-search-hidden]. */
.alert-row[data-alert-filtered="true"] {
    display: none;
}

/* Counter "totale" accanto al numero filtrato: visibile solo quando il
   filtro non e' "all" (gestito da JS via aria-pressed sulla chip). */
.alerts-count-total {
    font-weight: 400;
    opacity: 0.55;
    display: none;
}

[data-alerts-section][data-alerts-filtered="true"] .alerts-count-total {
    display: inline;
}

/* Stato vuoto del filtro: messaggio "Nessun avviso in questa categoria".
   Aggiunto dinamicamente dal JS quando il filtro nasconde tutti gli item. */
.alerts-empty-filter {
    color: #777;
    font-style: italic;
    padding: 0.5rem 0.2rem;
    font-size: 0.9rem;
}

/* ──────────────────────────────────────────────────────────────────────────
   RICERCA CATALOGHI (toolbar client-side)
   Markup generato da catalog.render_catalog_toolbar(...). Logica in
   static/js/catalog-search.js: filtra le card via data-search/data-cat,
   nasconde le sezioni vuote, aggiorna il contatore, sincronizza l'URL.
   ────────────────────────────────────────────────────────────────────────── */

.catalog-toolbar {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.75rem 1rem;
    margin-bottom: 1.25rem;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04);
}

.catalog-toolbar-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
}

.catalog-search-wrap {
    flex: 1 1 240px;
    min-width: 200px;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.4rem 0.75rem;
    transition: border-color 0.15s, box-shadow 0.15s;
}

.catalog-search-wrap:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(74, 124, 89, 0.12);
}

.catalog-search-icon {
    color: var(--muted);
    font-size: 1rem;
    line-height: 1;
}

.catalog-search-input {
    flex: 1;
    border: none;
    background: transparent;
    font: inherit;
    color: inherit;
    padding: 0.15rem 0;
    outline: none;
    min-width: 0;
}

.catalog-search-input::-webkit-search-cancel-button {
    cursor: pointer;
}

/* ── Multi-select disclosure (pattern <details>/<summary>) ─────────────── */

.catalog-filter {
    /* Ancora per il pannello dropdown (.multi-select-options) che &egrave;
       posizionato in absolute. Selettore comune sia ai filtri
       multi-select che ai filtri npk-exact. */
    position: relative;
}

.multi-select-summary {
    list-style: none;
    cursor: pointer;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.45rem 0.75rem;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.95rem;
    user-select: none;
    transition: border-color 0.15s, background 0.15s;
}

.multi-select-summary::-webkit-details-marker {
    display: none;
}

.multi-select-summary:hover {
    border-color: var(--accent);
}

.catalog-filter[open] > .multi-select-summary {
    border-color: var(--accent);
    background: rgba(74, 124, 89, 0.06);
}

.multi-select-label {
    font-weight: 500;
}

.multi-select-badge {
    background: var(--accent);
    color: #fff;
    font-size: 0.75rem;
    line-height: 1;
    padding: 0.15rem 0.4rem;
    border-radius: 999px;
    font-weight: 600;
    min-width: 1.1rem;
    text-align: center;
}

.multi-select-badge[hidden] {
    display: none;
}

.multi-select-arrow {
    font-size: 0.7rem;
    color: var(--muted);
    transition: transform 0.15s;
}

.catalog-filter[open] .multi-select-arrow {
    transform: rotate(180deg);
}

.multi-select-options {
    position: absolute;
    top: calc(100% + 0.25rem);
    left: 0;
    z-index: 20;
    margin: 0;
    padding: 0.5rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card-bg);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.1);
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 12rem;
    max-height: 60vh;
    overflow-y: auto;
}

.multi-select-option {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0.5rem;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.95rem;
    transition: background 0.1s;
}

.multi-select-option:hover {
    background: rgba(74, 124, 89, 0.08);
}

.multi-select-option input[type="checkbox"] {
    accent-color: var(--accent);
    cursor: pointer;
    margin: 0;
}

/* ── Filtro npk-exact (3 input numerici N/P/K) ────────────────────────── */

.npk-exact-content {
    /* Eredita position/box da .multi-select-options. Aggiungiamo solo il
       layout interno specifico dei 3 input + hint testuale. */
    min-width: 16rem;
}

.npk-exact-hint {
    margin: 0 0 0.6rem;
    color: var(--muted);
    font-size: 0.85rem;
    line-height: 1.35;
}

.npk-exact-hint strong {
    color: var(--accent);
    font-weight: 600;
}

.npk-exact-inputs {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.5rem;
}

.npk-exact-input {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
}

.npk-exact-letter {
    color: var(--accent);
    font-weight: 700;
    font-size: 0.95rem;
}

.npk-exact-input input[type="number"] {
    width: 100%;
    padding: 0.35rem 0.4rem;
    border: 1px solid var(--border);
    border-radius: 5px;
    background: var(--bg);
    color: inherit;
    font: inherit;
    font-size: 0.95rem;
    text-align: center;
    /* Riserviamo abbastanza spazio per "16.5" senza overflow ma manteniamo
       i 3 campi proporzionati nella griglia. */
    min-width: 0;
    -moz-appearance: textfield;
}

.npk-exact-input input[type="number"]::-webkit-inner-spin-button,
.npk-exact-input input[type="number"]::-webkit-outer-spin-button {
    /* Spinner nativi: nascosti per coerenza visiva con gli altri input. */
    -webkit-appearance: none;
    margin: 0;
}

.npk-exact-input input[type="number"]:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(74, 124, 89, 0.18);
}

/* ── Reset / counter ───────────────────────────────────────────────────── */

.catalog-reset-btn {
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--muted);
    cursor: pointer;
    padding: 0.4rem 0.75rem;
    font: inherit;
    font-size: 0.9rem;
    transition: color 0.15s, border-color 0.15s;
}

.catalog-reset-btn:hover {
    color: var(--accent);
    border-color: var(--accent);
}

.catalog-reset-btn[hidden] {
    display: none;
}

.catalog-counter {
    margin-left: auto;
    color: var(--muted);
    font-size: 0.9rem;
    white-space: nowrap;
}

.catalog-counter-visible {
    color: var(--accent);
    font-weight: 600;
}

/* ── Empty state ───────────────────────────────────────────────────────── */

.catalog-empty-state {
    margin: 0.75rem 0 0;
    padding: 0.75rem 1rem;
    background: rgba(120, 120, 120, 0.06);
    border-radius: 6px;
    color: var(--muted);
    font-style: italic;
    text-align: center;
}

.catalog-empty-state[hidden] {
    display: none;
}

/* ── Card e sezioni nascoste dal filtro ────────────────────────────────── */

[data-search-hidden="true"] {
    display: none !important;
}

/* Highlight sottile delle sezioni mostrate quando la search ha un valore.
   Quando l'utente cerca, vogliamo che il match sia visivamente "centrale". */
.catalog-toolbar[data-active-search="true"] ~ .catalog-content
        .catalog-section h3 .count {
    opacity: 0.6;
}

/* Mobile: contatore va a capo sotto il resto. */
@media (max-width: 600px) {
    .catalog-counter {
        margin-left: 0;
        flex-basis: 100%;
        text-align: right;
    }
}

/* ──────────────────────────────────────────────────────────────────────────
   SUBSTRATO PERSONALIZZATO (modal + form)
   ────────────────────────────────────────────────────────────────────────── */

.substrate-modal {
    border: none;
    border-radius: 10px;
    padding: 0;
    background: var(--card-bg);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
    width: min(640px, calc(100vw - 2rem));
    max-height: 92vh;
    overflow: visible;
}

.substrate-modal::backdrop {
    background: rgba(0, 0, 0, 0.45);
}

.substrate-modal-inner {
    padding: 1.5rem;
    overflow-y: auto;
    max-height: 92vh;
}

.substrate-modal h3 {
    margin: 0 0 1rem;
    color: var(--accent);
}

.substrate-form .field {
    margin-bottom: 0.75rem;
}

.recipe-fieldset {
    margin: 0.75rem 0;
    padding: 0.85rem 1rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg);
}

.recipe-fieldset legend {
    padding: 0 0.4rem;
    font-weight: 600;
    color: var(--accent);
}

.recipe-fieldset legend em {
    color: var(--muted);
    font-weight: 400;
    font-style: normal;
    font-size: 0.85rem;
}

.recipe-rows {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin-bottom: 0.5rem;
}

.recipe-row {
    display: grid;
    grid-template-columns: 1fr 5rem auto;
    gap: 0.5rem;
    align-items: center;
}

.recipe-row select,
.recipe-row input[type="number"] {
    padding: 0.4rem 0.5rem;
    border: 1px solid var(--border);
    border-radius: 5px;
    background: var(--card-bg);
    font: inherit;
}

.recipe-row select:focus,
.recipe-row input[type="number"]:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(74, 124, 89, 0.18);
}

.recipe-row-remove {
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 5px;
    width: 2rem;
    height: 2rem;
    cursor: pointer;
    color: var(--muted);
    font-size: 0.95rem;
    transition: color 0.1s, border-color 0.1s;
}

.recipe-row-remove:hover {
    color: var(--error-fg);
    border-color: var(--error-fg);
}

.recipe-rows .recipe-row:only-child .recipe-row-remove {
    /* Quando c'&egrave; una sola riga, nascondiamo il pulsante remove
       (non si pu&ograve; rimuovere l'unica riga). */
    visibility: hidden;
}

.recipe-row-add {
    margin-top: 0.4rem;
}

.recipe-sum {
    margin: 0.6rem 0 0;
    color: var(--muted);
    font-size: 0.9rem;
}

.recipe-sum-value {
    color: var(--accent);
    font-weight: 700;
}

.recipe-sum-warn {
    color: var(--error-fg);
    font-weight: 500;
    margin-left: 0.5rem;
}

.substrate-extra {
    margin: 0.5rem 0;
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0 1rem;
}

.substrate-extra > summary {
    padding: 0.6rem 0;
    cursor: pointer;
    font-weight: 500;
    color: var(--muted);
    list-style: none;
}

.substrate-extra > summary::-webkit-details-marker {
    display: none;
}

.substrate-extra[open] > summary {
    color: var(--accent);
}

.substrate-extra-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.5rem 0.75rem;
    margin: 0.5rem 0;
}

.form-actions {
    display: flex;
    gap: 0.75rem;
    justify-content: flex-end;
    align-items: stretch;  /* altezza identica fra i 2 bottoni */
    margin-top: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
}

/* Uniforma altezza/padding di .primary-button (<button>) e
   .secondary-button (<a>) dentro la stessa toolbar: nativamente i due
   elementi hanno line-height e box-sizing diversi e darebbero altezze
   visibilmente disuguali. */
.form-actions .primary-button,
.form-actions .secondary-button {
    margin: 0;
    padding: 0.6rem 1.1rem;
    font-size: 0.95rem;
    line-height: 1.2;
    border-radius: 6px;
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.form-actions .primary-button {
    /* Il primary ha bordo invisibile (stesso colore del fill) cos&igrave;
       eredita gli stessi box-metrics del secondary che ha border 1px. */
    border: 1px solid var(--accent);
}

@media (max-width: 600px) {
    .recipe-row {
        grid-template-columns: 1fr 4rem auto;
        gap: 0.4rem;
    }
    .substrate-extra-grid {
        grid-template-columns: 1fr;
    }
}

/* Bottone-link: stile testuale ma cliccabile, per "+ Crea substrato",
   "+ Aggiungi componente" e i bottoni Modifica/Elimina nella sezione
   profilo. */
.link-button {
    background: none;
    border: none;
    padding: 0.2rem 0;
    color: var(--accent);
    font: inherit;
    font-size: 0.95rem;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
}

.link-button:hover {
    color: var(--accent-dark);
}

.link-button-danger {
    background: none;
    border: none;
    padding: 0.2rem 0;
    color: var(--error-fg);
    font: inherit;
    font-size: 0.95rem;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
}

.link-button-danger:hover {
    color: #5a1010;
}

.inline-form {
    display: inline;
}

.empty-state {
    margin: 0;
    padding: 0.75rem;
    background: rgba(120, 120, 120, 0.06);
    border-radius: 6px;
    color: var(--muted);
    font-style: italic;
    text-align: center;
}

/* Sezione "Catalogo personale" in /profilo: riusa le cards di
   /catalogo/substrati (.substrate-card) e aggiunge un wrapper
   .user-card-wrap con bottoni Modifica/Elimina sotto la card. */

.user-catalog {
    margin: 0 0 1rem;
}

.user-catalog-title {
    margin: 0 0 0.6rem;
    color: var(--accent);
    font-size: 1rem;
}

.user-catalog-count {
    color: var(--muted);
    font-weight: 400;
    font-size: 0.9rem;
}

.user-catalog-actions {
    margin-top: 0.5rem;
}

.user-card-wrap {
    display: flex;
    flex-direction: column;
}

.user-card-wrap > .substrate-card {
    /* Card piena: lasciamo il bordo arrotondato in alto, ma in basso
       diamo un bordo netto perché sotto c'è la barra azioni. */
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    margin-bottom: 0;
}

.user-card-actions {
    display: flex;
    gap: 1rem;
    align-items: center;
    justify-content: flex-end;
    padding: 0.5rem 0.85rem;
    background: var(--bg);
    border: 1px solid var(--border);
    border-top: none;
    border-bottom-left-radius: 8px;
    border-bottom-right-radius: 8px;
}

.user-card-actions .link-button,
.user-card-actions .link-button-danger {
    font-size: 0.9rem;
}

/* Modal mix kg: eredita da .substrate-modal il wrapper, ma rimuove la
   modalità "form esteso" — qui mostriamo solo dati read-only. */
.mix-modal {
    width: min(560px, calc(100vw - 2rem));
}

.mix-modal .detail-stats {
    margin-bottom: 0.75rem;
}

.mix-modal .form-actions {
    margin-top: 1rem;
}

/* Note "i parametri agronomici sono calcolati automaticamente" sotto
   la ricetta nel form substrato. */
.substrate-derived-note {
    margin: 0.5rem 0;
    padding: 0.6rem 0.8rem;
    background: rgba(74, 124, 89, 0.06);
    border-left: 3px solid var(--accent);
    border-radius: 4px;
    color: var(--muted);
    font-size: 0.88rem;
    line-height: 1.4;
}

/* ──────────────────────────────────────────────────────────────────────────
   MODAL "MIX PER QUESTO VASO" (calcolatore kg, slice F2-bis)
   Aperto via bottone "Calcola mix" nella card Pianta del detail vaso,
   solo se il substrato è personalizzato e il vaso ha volume noto.
   ────────────────────────────────────────────────────────────────────────── */

/* Pill bottone "Calcola mix" inline accanto al nome substrato. Più
   visibile del link-button (sottolineato testuale): bordo accent + bg
   soft, hover full accent. Inline con il testo della <dd>. */
.mix-trigger {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    margin-left: 0.5rem;
    padding: 0.2rem 0.6rem;
    background: rgba(74, 124, 89, 0.08);
    border: 1px solid var(--accent);
    border-radius: 999px;
    color: var(--accent);
    font: inherit;
    font-size: 0.82rem;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, transform 0.05s;
    white-space: nowrap;
    vertical-align: baseline;
}

.mix-trigger:hover {
    background: var(--accent);
    color: #fff;
}

.mix-trigger:active {
    transform: translateY(1px);
}

.mix-table {
    width: 100%;
    border-collapse: collapse;
    margin: 0.5rem 0;
    font-size: 0.95rem;
}

.mix-table th,
.mix-table td {
    text-align: left;
    padding: 0.5rem 0.6rem;
    border-bottom: 1px solid var(--border);
}

.mix-table thead th {
    color: var(--muted);
    font-weight: 500;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-bottom: 1.5px solid var(--border);
}

.mix-table .num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.mix-table tbody tr:hover {
    background: rgba(74, 124, 89, 0.04);
}

.mix-table tfoot th {
    border-top: 1.5px solid var(--accent);
    border-bottom: none;
    color: var(--accent);
    font-weight: 600;
}

.mix-note {
    margin: 0.5rem 0 0;
    color: var(--muted);
    font-size: 0.85rem;
    font-style: italic;
    line-height: 1.4;
}

/* ── Pagina /cerca: risultati ricerca globale ───────────────────────────── */

.search-page {
    max-width: 900px;
    margin: 0 auto;
    padding: 1rem 0;
}

/* Conteggio totale risultati nell'header, accanto al titolo H2. */
.search-page-total {
    font-size: 0.85rem;
    font-weight: 400;
    color: var(--muted);
    margin-left: 0.6rem;
}

/* Form di ricerca con input grande + bottone. Stesso pattern di altri
   form della app: input cresce, bottone fisso a destra. */
.search-page-form {
    display: flex;
    gap: 0.6rem;
    margin: 1rem 0 1.5rem;
}

.search-page-form input[type="search"] {
    flex: 1;
    padding: 0.6rem 1rem;
    border: 1.5px solid var(--border);
    border-radius: 8px;
    background: var(--bg);
    color: var(--fg);
    font: inherit;
    font-size: 1rem;
    transition: border-color 0.15s, box-shadow 0.15s;
    -webkit-appearance: none;
    appearance: none;
}

.search-page-form input[type="search"]:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(74, 124, 89, 0.18);
}

/* Container delle sezioni risultati. Layout vertical con spazio fra sezioni. */
.search-page-results {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

/* Singola sezione = un'area (vasi, specie, ...). Card su sfondo bianco
   con header e lista di righe risultato. */
.search-section {
    background: var(--card-bg, #fff);
    border: 1px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
}

.search-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    background: rgba(74, 124, 89, 0.06);
    border-bottom: 1px solid var(--border);
}

/* Header titolo della sezione risultati. Supporta sia il pattern
   esplicito `<header class="search-section-header"><h3>` sia il
   pattern flat `<section><h3>` usato dal render attuale di
   _render_search_sections (5 sezioni: vasi, specie, substrati,
   fertilizzanti, fitopatie, note). Stessi stili per entrambi. */
.search-section-header h3,
.search-section > h3 {
    margin: 0;
    padding: 0.75rem 1rem;
    font-size: 1rem;
    font-weight: 600;
    color: var(--accent-dark);
    background: rgba(74, 124, 89, 0.06);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.search-count {
    font-size: 0.85rem;
    color: var(--muted);
    font-weight: 400;
}

/* Lista di righe risultato. Ogni riga e' un <a> cliccabile a tutta
   larghezza con icona + main + sub-text. */
.search-section-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.search-section-list li {
    border-bottom: 1px solid var(--border);
}

.search-section-list li:last-child {
    border-bottom: none;
}

.search-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.7rem 1rem;
    color: var(--fg);
    text-decoration: none;
    transition: background 0.12s;
}

.search-row:hover {
    background: rgba(74, 124, 89, 0.06);
    text-decoration: none;
    color: var(--fg);
}

/* Icona/emoji a sinistra: dim fissa per allineamento verticale. */
.search-row-icon {
    flex: 0 0 auto;
    width: 1.6rem;
    text-align: center;
    font-size: 1.2rem;
    line-height: 1;
}

/* Blocco testo principale: nome + sub-text in due righe. */
.search-row-main {
    flex: 1 1 auto;
    min-width: 0;   /* permette ellipsis sui figli */
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.search-row-title {
    font-weight: 500;
    color: var(--fg);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.search-row-sub {
    font-size: 0.85rem;
    color: var(--muted);
    font-style: italic;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Meta a destra (date, tipo, etc.) - opzionale. */
.search-row-meta {
    flex: 0 0 auto;
    font-size: 0.8rem;
    color: var(--muted);
    white-space: nowrap;
}

/* Stato vuoto: nessun risultato in tutte le aree. */
.search-empty {
    text-align: center;
    padding: 3rem 1rem;
    color: var(--muted);
}

.search-empty p {
    margin: 0.3rem 0;
}

/* Hint "digita almeno 2 caratteri". */
.search-hint {
    text-align: center;
    padding: 2rem 1rem;
    color: var(--muted);
    font-style: italic;
}

/* Mobile: padding ridotto, icone visibili, sub-text wrap su 2 righe. */
@media (max-width: 600px) {
    .search-page {
        padding: 0.5rem 0;
    }
    .search-page-form {
        flex-direction: column;
    }
    .search-row {
        padding: 0.6rem 0.75rem;
    }
    .search-row-meta {
        display: none;   /* salva spazio su mobile */
    }
}

/* ── Pagina /guida: manuale utente in HTML ──────────────────────────────
   Convertito al volo da docs/USER-GUIDE.md via guide.py + libreria
   markdown. Reading-friendly: max-width contenuta per misura lettura
   ottimale (~75 ch), typography fluida coerente con il PDF generato. */

.guida-page {
    max-width: 880px;
    margin: 0 auto;
    padding: 1rem 0;
}

/* Toolbar superiore: titolo a sx, bottone scarica PDF a dx. Sticky-like
   ma non sticky (per ora): non vale il rumore visivo. */
.guida-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem;
    margin: 0 0 1.5rem 0;
    padding-bottom: 0.85rem;
    border-bottom: 1px solid var(--border);
}

.guida-title {
    margin: 0;
    color: var(--accent-dark);
    font-size: 1.5rem;
    font-weight: 600;
}

.guida-pdf-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.5rem 0.95rem;
    background: var(--accent);
    color: #fff;
    border-radius: 6px;
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 600;
    transition: background 0.15s;
}
.guida-pdf-btn:hover {
    background: var(--accent-dark);
    color: #fff;
    text-decoration: none;
}

/* Container per pi&ugrave; bottoni nella toolbar della guida (Novita',
   Scarica PDF, ecc.). Su mobile si impila verticalmente. */
.guida-toolbar-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Bottone secondario nella toolbar della guida: stesso layout del
   primario ma outline invece di filled (gerarchia visuale).
   Sfondo card-bg invece di transparent: serve un riempimento
   opaco per non confondersi con il body floreale di sfondo, che
   altrimenti vince sul testo del bottone e lo rende illeggibile
   (vale sia tema chiaro sia scuro). */
.guida-secondary-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.5rem 0.95rem;
    background: var(--card-bg);
    color: var(--accent-dark);
    border: 1.5px solid var(--accent);
    border-radius: 6px;
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 600;
    transition: background 0.15s, color 0.15s;
}
.guida-secondary-btn:hover {
    background: var(--accent);
    color: #fff;
    text-decoration: none;
}

/* Container del contenuto: tipografia generosa, righe larghe, headings
   gerarchici coerenti con il PDF. Background card opaco per leggibilita'
   sopra le immagini stagionali. */
.guida-content {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 2rem 2.5rem;
    line-height: 1.65;
    color: var(--fg);
}

/* Slice legal: pagine /privacy e /terms riusano il rendering markdown
   di .guida-content ma con una larghezza piu' contenuta (testo legale
   piu' agevole da leggere) e un piccolo footer con link incrociati. */
.legal-page {
    max-width: 820px;
    margin: 0 auto;
}

.legal-content {
    padding: 1.8rem 2.2rem;
}

.legal-content table {
    border-collapse: collapse;
    margin: 0.6rem 0;
    font-size: 0.92rem;
}

.legal-content table th,
.legal-content table td {
    border: 1px solid var(--border);
    padding: 0.4rem 0.7rem;
    text-align: left;
}

.legal-content table th {
    background: rgba(74, 124, 89, 0.08);
    color: var(--accent-dark);
}

.legal-footer {
    margin-top: 1rem;
    padding: 0.8rem 0;
    text-align: center;
    font-size: 0.85rem;
    color: var(--muted);
}

.legal-footer a {
    color: var(--accent-dark);
    text-decoration: none;
}

.legal-footer a:hover {
    text-decoration: underline;
}

/* Footer globale: link "Privacy / Termini" allineati a destra
   (vedi .site-footer-inner display:flex justify-content:space-between
   nella sezione layout sopra). margin 0: niente offset verticale. */
.site-footer-legal {
    margin: 0;
    font-size: 0.82rem;
    color: var(--muted);
}

.site-footer-legal a {
    color: var(--accent-dark);
    text-decoration: none;
}

.site-footer-legal a:hover {
    text-decoration: underline;
}

.guida-content h1 {
    color: var(--accent-dark);
    font-size: 1.6rem;
    border-bottom: 2px solid var(--border);
    padding-bottom: 0.4rem;
    margin: 2rem 0 1rem 0;
}
.guida-content h1:first-child { margin-top: 0; }

.guida-content h2 {
    color: var(--accent-dark);
    font-size: 1.25rem;
    border-bottom: 1px solid var(--border);
    padding-bottom: 0.3rem;
    margin: 1.8rem 0 0.8rem 0;
}

.guida-content h3 {
    color: var(--accent);
    font-size: 1.05rem;
    margin: 1.2rem 0 0.5rem 0;
}

.guida-content h4 {
    color: var(--accent);
    font-size: 0.95rem;
    margin: 0.9rem 0 0.4rem 0;
    font-weight: 600;
}

.guida-content p, .guida-content li {
    margin: 0.5rem 0;
}

.guida-content ul, .guida-content ol {
    margin: 0.6rem 0 0.6rem 1.5rem;
    padding: 0;
}

.guida-content strong { color: var(--fg); }
.guida-content em { color: var(--muted); }

.guida-content a {
    color: var(--accent-dark);
    text-decoration: none;
    border-bottom: 1px dotted var(--accent);
}
.guida-content a:hover { border-bottom-style: solid; }

/* Codice inline e blocchi: stessa filosofia del PDF (sfondo grigio
   tenue, monospace, code in rosso scuro per i nomi tecnici). */
.guida-content code {
    font-family: "Cascadia Code", "Consolas", "Courier New", monospace;
    font-size: 0.88em;
    background: rgba(120, 120, 120, 0.10);
    border: 1px solid var(--border);
    border-radius: 3px;
    padding: 0.05rem 0.35rem;
    color: var(--error-fg);
}

.guida-content pre {
    font-family: "Cascadia Code", "Consolas", "Courier New", monospace;
    font-size: 0.85rem;
    background: rgba(120, 120, 120, 0.08);
    border: 1px solid var(--border);
    border-radius: 5px;
    padding: 0.7rem 1rem;
    overflow-x: auto;
    line-height: 1.45;
    white-space: pre-wrap;
    word-break: break-word;
}
.guida-content pre code {
    background: none;
    border: none;
    padding: 0;
    color: var(--fg);
}

/* Tabelle: header con tinta success, righe alternate sottili. */
.guida-content table {
    width: 100%;
    border-collapse: collapse;
    margin: 1rem 0;
    font-size: 0.9rem;
}
.guida-content th {
    background: rgba(74, 124, 89, 0.10);
    color: var(--accent-dark);
    text-align: left;
    border: 1px solid var(--border);
    padding: 0.45rem 0.65rem;
    font-weight: 600;
}
.guida-content td {
    border: 1px solid var(--border);
    padding: 0.4rem 0.65rem;
    vertical-align: top;
}

/* Blockquote come "nota stile italic" — stesso pattern del PDF. */
.guida-content blockquote {
    border-left: 3px solid var(--accent);
    background: rgba(74, 124, 89, 0.05);
    padding: 0.5rem 1rem;
    margin: 0.9rem 0 0.9rem 0.3rem;
    color: var(--muted);
    font-style: italic;
}

/* Screenshot: bordo cream, centrate, max-width contenuto per non
   debordare. */
.guida-content img {
    display: block;
    max-width: 100%;
    height: auto;
    margin: 1rem auto;
    border: 1px solid var(--border);
    border-radius: 5px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
}

.guida-content hr {
    border: none;
    border-top: 1px solid var(--border);
    margin: 1.5rem 0;
}

/* Mobile: padding interno ridotto, font leggermente piu' piccolo. */
@media (max-width: 600px) {
    .guida-content {
        padding: 1.1rem 1rem;
        font-size: 0.95rem;
    }
    .guida-content h1 { font-size: 1.35rem; }
    .guida-content h2 { font-size: 1.1rem; }
    .guida-toolbar {
        flex-direction: column;
        align-items: flex-start;
    }
}

/* ── Bottone "?" sulle pagine login e register ──────────────────────────
   Cerchietto piccolo in alto a destra dell'.auth-card che porta alla
   guida. Visibile anche su mobile: serve a chi non sa cos'e' l'app. */
.auth-card {
    position: relative;
}

.auth-help-btn {
    position: absolute;
    top: 0.8rem;
    right: 0.85rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: var(--card-bg);
    color: var(--accent-dark);
    text-decoration: none;
    font-weight: 700;
    font-size: 1rem;
    line-height: 1;
    transition: background 0.15s, border-color 0.15s, transform 0.15s;
}
.auth-help-btn:hover {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
    text-decoration: none;
    transform: scale(1.08);
}

/* SVG libro+? nella navbar (auth): forza dimensioni dell'icona uguali
   alle altre nav-icon e ne usa il color via currentColor. */
.nav-link .nav-icon svg {
    width: 1.15rem;
    height: 1.15rem;
    display: block;
    vertical-align: middle;
}

/* Badge "Posizione fissa" nella card Posizione del detail vaso: piccolo
   pannello info che spiega all'utente perch&eacute; non vede gli avvisi di
   transizione stagionale. Stile coerente con gli altri info-badge dell'app. */
.position-lock-badge {
    margin: 0.5rem 0 0 0;
    padding: 0.4rem 0.7rem;
    background: rgba(74, 124, 89, 0.08);
    border-left: 3px solid var(--accent);
    border-radius: 4px;
    font-size: 0.88rem;
    color: var(--fg);
}
.position-lock-badge em {
    color: var(--muted);
    font-style: italic;
}

/* Banner della 'catena di registrazione': appare sopra il form quando
   l'utente sta percorrendo una serie di eventi della stessa categoria
   programmati per oggi. Mostra cosa e' stato appena registrato e
   offre un'uscita rapida con 'Termina catena'. */
.chain-banner {
    margin: 0 0 1rem 0;
    padding: 0.7rem 1rem;
    background: rgba(74, 124, 89, 0.12);
    border: 1px solid rgba(74, 124, 89, 0.3);
    border-left: 4px solid var(--accent);
    border-radius: 6px;
    font-size: 0.95rem;
    color: var(--fg);
    line-height: 1.4;
}
.chain-banner strong {
    color: var(--accent-dark);
}
.chain-banner-date {
    color: var(--muted);
    font-size: 0.88rem;
    margin-left: 0.3rem;
}
.chain-banner-skip {
    float: right;
    color: var(--muted);
    text-decoration: none;
    font-size: 0.88rem;
    margin-left: 0.5rem;
}
.chain-banner-skip:hover {
    color: var(--accent);
    text-decoration: underline;
}
/* Mobile: skip link sotto al testo invece di affianco. */
@media (max-width: 480px) {
    .chain-banner-skip {
        float: none;
        display: block;
        margin: 0.4rem 0 0 0;
    }
}

/* ── Mobile bottom-nav fissa (slice nav-3) ─────────────────────────────── */
/*
 * Su desktop la bottom-nav e' display:none (top-nav classica con tutti i
 * link). Su mobile (<=720px) la top-nav perde i link, mantiene solo
 * logo + bottoni di servizio (search/tema/logout/utente), e la
 * bottom-nav fissa diventa la navigazione primaria con 5 tab
 * principali. Pattern UX standard iOS/Android: tap target ampio,
 * pollice-friendly, mai oscurato da scroll.
 */

.mobile-bottom-nav {
    display: none;
}

.mobile-tab {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.15rem;
    padding: 0.4rem 0.3rem;
    text-decoration: none;
    color: var(--muted);
    font-size: 0.7rem;
    font-weight: 500;
    line-height: 1.1;
    flex: 1;
    min-width: 0;
    transition: color 0.15s;
}

.mobile-tab:hover {
    color: var(--accent-dark);
    text-decoration: none;
}

.mobile-tab-active {
    color: var(--accent-dark);
    font-weight: 600;
}

.mobile-tab-active .mobile-tab-icon {
    transform: scale(1.08);
}

.mobile-tab-icon {
    font-size: 1.4rem;
    line-height: 1;
    transition: transform 0.15s;
}

.mobile-tab-label {
    /* Tronca su tab molto strette (es. iPhone SE in landscape).
       Calendario e' la label piu' lunga: ammesso wrap su 1 riga
       comunque grazie al font ridotto. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

@media (max-width: 720px) {
    /* Slice SIST-1 (giu 2026): su mobile la top-nav NON e' sticky
       (richiesta utente: "nel layout per telefono va bene com'e'").
       La navigazione mobile e' la bottom-nav fissa; la top-nav torna
       a scorrere normalmente. Annullo anche backdrop/ombra. */
    .site-header {
        position: static;
        z-index: auto;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        box-shadow: none;
    }
    /* Mostra la bottom-nav su mobile/tablet stretti. */
    .mobile-bottom-nav {
        display: flex;
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 200;
        background: var(--chrome-bg);
        border-top: 1px solid rgba(0, 0, 0, 0.10);
        box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.06);
        padding: 0.25rem 0.2rem;
        /* iOS safe-area: home-indicator iPhone non oscura le tab. */
        padding-bottom: calc(0.25rem + env(safe-area-inset-bottom, 0px));
    }
    /* Hide bottom-nav per utenti anonimi (login / register / splash). */
    body.auth-state-anonymous .mobile-bottom-nav {
        display: none;
    }
    /* Spazio sotto al footer per non finire coperto dalla bottom-nav
       fissa quando l'utente arriva in fondo alla pagina. Lo metto sul
       footer (non sul main) cosi' il background --chrome-bg del footer
       si estende fino sopra la bottom-nav (stesso colore, niente buco
       visivo). Stimo ~3.4rem (tab) + ~0.8rem margine + safe-area iOS;
       il calc() include l'inset dell'home-indicator. */
    body.auth-state-authenticated .site-footer {
        padding-bottom: calc(4.2rem + env(safe-area-inset-bottom, 0px));
    }
    /* Sulla top-nav nascondiamo i link principali (sono nella
       bottom-nav). Anche l'icona Profilo (.user-name) e' ridondante
       perche' c'e' gia' la tab "Profilo" nella bottom-nav: la
       nascondiamo del tutto. Restano: search modal, theme toggle,
       logout. La barra in alto e' cosi' davvero leggera. */
    .auth-nav .when-authenticated .nav-link,
    .auth-nav .when-authenticated .user-name,
    .auth-nav .when-authenticated .nav-divider {
        display: none;
    }
}

/* iPhone SE / schermi molto stretti: tab piu' compatte ancora. */
@media (max-width: 380px) {
    .mobile-tab {
        font-size: 0.65rem;
    }
    .mobile-tab-icon {
        font-size: 1.25rem;
    }
}

/* ── Pagina /admin (slice I) ───────────────────────────────────────────── */

.admin-page {
    max-width: 1100px;
    margin: 0 auto;
    padding: 1rem;
}

.admin-header h2 {
    margin: 0 0 0.3rem;
    color: var(--accent-dark);
}

.admin-subtitle {
    margin: 0 0 1.2rem;
    color: var(--muted);
    font-size: 0.9rem;
}

.admin-flash {
    padding: 0.75rem 1rem;
    border-radius: 6px;
    margin: 0 0 1rem;
    font-size: 0.9rem;
}

.admin-flash-ok {
    background: rgba(74, 124, 89, 0.12);
    border: 1px solid rgba(74, 124, 89, 0.35);
    color: var(--accent-dark);
}

.admin-flash-err {
    background: rgba(180, 60, 60, 0.10);
    border: 1px solid rgba(180, 60, 60, 0.35);
    color: #b43c3c;
}

/* Barra admin del catalogo piante: pulsante sync .md -> DB (solo staff). */
.catalog-admin-sync {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 0.9rem;
    padding: 0.7rem 0.9rem;
    margin: 0 0 1rem;
    border: 1px dashed rgba(74, 124, 89, 0.4);
    border-radius: 8px;
    background: rgba(74, 124, 89, 0.05);
}

.catalog-admin-hint {
    font-size: 0.82rem;
    color: var(--text-muted, #6b6b6b);
}

.catalog-admin-hint code {
    font-size: 0.9em;
}

/* Stats: 4 card affiancate, stack su mobile. */
.admin-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 0.7rem;
    margin: 0 0 1.5rem;
}

.admin-stat {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.7rem 0.9rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.admin-stat-n {
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--accent-dark);
    line-height: 1;
}

.admin-stat-l {
    font-size: 0.78rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.admin-section {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem;
    margin: 0 0 1.5rem;
}

.admin-section h3 {
    margin: 0 0 0.7rem;
    color: var(--accent-dark);
    font-size: 1.05rem;
}

.admin-table-wrap {
    overflow-x: auto;
}

.admin-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.88rem;
}

.admin-table th,
.admin-table td {
    text-align: left;
    padding: 0.55rem 0.6rem;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}

.admin-table th {
    background: rgba(74, 124, 89, 0.06);
    font-weight: 600;
    color: var(--muted);
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.admin-user-id {
    color: var(--muted);
    font-family: ui-monospace, monospace;
    font-size: 0.82rem;
}

.admin-user-email,
.admin-wl-email {
    font-family: ui-monospace, monospace;
    font-size: 0.82rem;
    word-break: break-all;
}

.admin-user-since {
    color: var(--muted);
}

.admin-self-label {
    color: var(--muted);
    font-style: italic;
}

/* Chip stato (sessione, bloccato, google) */
.admin-chip {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    white-space: nowrap;
}

.admin-chip-online {
    background: rgba(74, 124, 89, 0.15);
    color: var(--accent-dark);
}

.admin-chip-offline {
    background: rgba(0, 0, 0, 0.06);
    color: var(--muted);
}

.admin-chip-blocked {
    background: rgba(180, 60, 60, 0.12);
    color: #b43c3c;
    margin-left: 0.3rem;
}

.admin-chip-google {
    background: #4285f4;
    color: #fff;
    margin-left: 0.3rem;
    padding: 0.1rem 0.4rem;
    font-size: 0.7rem;
}

/* Form add whitelist + bottoni azione */
.admin-add-form {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin: 0 0 0.8rem;
}

.admin-input {
    flex: 1;
    min-width: 14rem;
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg);
    color: var(--fg);
    font-size: 0.9rem;
}

.admin-input-note {
    min-width: 10rem;
}

.admin-inline-form {
    display: inline-block;
    margin: 0;
}

.admin-btn {
    padding: 0.4rem 0.85rem;
    border: 1px solid var(--border);
    border-radius: 5px;
    background: var(--card-bg);
    color: var(--fg);
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.admin-btn:hover {
    background: var(--bg);
}

.admin-btn-add {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}

.admin-btn-add:hover {
    background: var(--accent-dark);
}

.admin-btn-block,
.admin-btn-remove {
    color: #b43c3c;
    border-color: rgba(180, 60, 60, 0.35);
}

.admin-btn-block:hover,
.admin-btn-remove:hover {
    background: rgba(180, 60, 60, 0.10);
}

.admin-btn-unblock {
    color: var(--accent-dark);
    border-color: rgba(74, 124, 89, 0.4);
}

.admin-btn-unblock:hover {
    background: rgba(74, 124, 89, 0.10);
}

/* Mobile: tabelle in overflow-x scroll. */
@media (max-width: 720px) {
    .admin-page {
        padding: 0.5rem;
    }
    .admin-table {
        font-size: 0.78rem;
        min-width: 600px;
    }
    .admin-add-form .admin-input,
    .admin-add-form .admin-input-note {
        min-width: 100%;
    }
}


/* ── Dashboard Tecnica: scatter stress + KPI cards ─────────────────────── */
.tecnica-page .page-header h2 { display: flex; align-items: center; gap: 0.5rem; }

.dash-stress-kpi {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 0.85rem;
    margin: 1rem 0 1.5rem 0;
}

.kpi-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-left: 4px solid var(--muted);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    text-align: center;
}

.kpi-card.kpi-good { border-left-color: var(--accent); }
.kpi-card.kpi-mid  { border-left-color: var(--warn-border); }
.kpi-card.kpi-bad  { border-left-color: var(--error-border); }

.kpi-card .kpi-value {
    font-size: 2rem;
    font-weight: 700;
    line-height: 1;
    color: var(--ink);
}

.kpi-card.kpi-good .kpi-value { color: var(--accent); }
.kpi-card.kpi-mid  .kpi-value { color: var(--warn-fg); }
.kpi-card.kpi-bad  .kpi-value { color: var(--error-fg); }

.kpi-card .kpi-label {
    font-size: 0.85rem;
    color: var(--muted);
    margin-top: 0.4rem;
}

.dashboard-scatter {
    width: 100%;
    max-width: 720px;
    margin: 1rem auto;
}

.scatter-svg {
    width: 100%;
    height: auto;
    display: block;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.5rem;
}

.scatter-point {
    transition: transform 0.15s ease;
    cursor: pointer;
}

.scatter-point:hover circle,
.scatter-point:focus circle {
    r: 10;
    stroke-width: 3;
    opacity: 1;
}

/* Slice mod_04-scatter: rimosso l'anello blu "stress idrico previsto"
   (.scatter-water-ring). Lo stress idrico ora pesa sull'asse X
   (stress esterno) ed e' indicato solo nel tooltip del punto. */

.scatter-empty {
    text-align: center;
    padding: 2rem 1rem;
    background: var(--card-bg);
    border: 1px dashed var(--border);
    border-radius: 8px;
    color: var(--muted);
}

.dash-section-note {
    color: var(--muted);
    font-size: 0.92rem;
    margin: 0.3rem 0 0.9rem 0;
}

.dash-coming-soon {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-left: 4px solid var(--accent);
    border-radius: 8px;
    padding: 1rem 1.25rem;
    margin-top: 1.5rem;
}

.dash-coming-soon h3 {
    margin: 0 0 0.5rem 0;
    color: var(--accent-dark);
    font-size: 1rem;
}

.dash-coming-soon ul {
    margin: 0;
    padding-left: 1.2rem;
}

.dash-coming-soon li {
    color: var(--muted);
    line-height: 1.6;
}

/* ── Dashboard Tecnica: toolbar filtri scatter ─────────────────────────── */
.stress-filter-form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    margin: 0.5rem 0 1rem 0;
    padding: 0.7rem 0.85rem;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
}

.stress-filter-form .filter-field {
    flex: 1 1 160px;
    min-width: 140px;
}

.stress-filter-form .filter-field select {
    width: 100%;
    padding: 0.55rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--card-bg);
    color: var(--ink);
    font: inherit;
    font-size: 0.9rem;
}

.stress-filter-form .filter-field select:focus {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
    border-color: var(--accent);
}

.stress-filter-form .filter-submit {
    /* Padding verticale uguale al select (0.55rem) + 1px di border
       trasparente compensa il border del select: cosi' bottone e
       select hanno la stessa altezza renderizzata. margin: 0 cancella
       il margin-top: 0.75rem ereditato da .primary-button che
       spostava il bottone fuori centro verticale. */
    margin: 0;
    padding: 0.55rem 1.1rem;
    border: 1px solid transparent;
    font-size: 0.9rem;
    line-height: 1.2;
    flex-shrink: 0;
}

.stress-filter-form .filter-reset {
    color: var(--muted);
    font-size: 0.88rem;
    text-decoration: none;
    padding: 0.3rem 0.5rem;
    flex-shrink: 0;
}

.stress-filter-form .filter-reset:hover {
    color: var(--accent-dark);
    text-decoration: underline;
}

@media (max-width: 640px) {
    .stress-filter-form .filter-field {
        flex: 1 1 100%;
    }
    .stress-filter-form .filter-submit,
    .stress-filter-form .filter-reset {
        flex: 1 1 100%;
        text-align: center;
    }
}

/* ── Bottone "Torna in cima" globale (base.html) ────────────────────────── */
.scroll-to-top-btn {
    position: fixed;
    bottom: 1.2rem;
    right: 1.2rem;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    border: 1px solid var(--border);
    background: var(--accent);
    color: #ffffff;
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 0.2s ease, transform 0.2s ease, background 0.2s ease;
    z-index: 50;
}

.scroll-to-top-btn:hover {
    background: var(--accent-dark);
}

.scroll-to-top-btn:focus {
    outline: 2px solid var(--accent-dark);
    outline-offset: 2px;
}

.scroll-to-top-btn-visible {
    opacity: 0.92;
    transform: translateY(0);
}

/* Su mobile: lo spostiamo leggermente più in alto per evitare la
   bottom-nav (slice nav-3). */
@media (max-width: 640px) {
    .scroll-to-top-btn {
        bottom: 5rem;
        right: 0.9rem;
        width: 44px;
        height: 44px;
    }
}

/* ──────────────────────────────────────────────────────────────────────────
   PLANTNET — Modal "Identifica con foto" (slice PlantNet A3)
   ────────────────────────────────────────────────────────────────────────── */

.plantnet-identify-btn {
    margin-bottom: 0.5rem;
    align-self: flex-start;
}

.plantnet-modal {
    border: none;
    border-radius: 10px;
    padding: 0;
    background: var(--card-bg);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.2);
    width: min(680px, calc(100vw - 2rem));
    max-height: 92vh;
    overflow: visible;
}
.plantnet-modal::backdrop {
    background: rgba(0, 0, 0, 0.5);
}

.plantnet-modal-form {
    padding: 1.5rem;
    overflow-y: auto;
    max-height: 92vh;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.plantnet-modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0;
}
.plantnet-modal-header h3 {
    margin: 0;
    color: var(--accent);
}
.plantnet-modal-close {
    background: transparent;
    border: none;
    font-size: 1.6rem;
    color: var(--muted);
    cursor: pointer;
    padding: 0 0.5rem;
    line-height: 1;
}
.plantnet-modal-close:hover {
    color: var(--ink);
}

.plantnet-modal-intro {
    margin: 0;
    color: var(--muted);
    font-size: 0.9rem;
    line-height: 1.5;
}

.plantnet-photo-rows {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.plantnet-photo-row {
    display: grid;
    grid-template-columns: 1fr 180px auto;
    gap: 0.5rem;
    align-items: center;
    padding: 0.6rem;
    background: rgba(0, 0, 0, 0.025);
    border-radius: 6px;
}
/* ── Slice photo-capture (lug 2026): Scatta/Scegli foto sugli upload ──
   Wrapper generico [data-photo-capture] per gli input foto multiple
   (galleria vaso, foto diario, screenshot feedback). Senza JS l'input
   resta visibile; con JS la classe -active lo nasconde e compaiono i
   bottoni + le anteprime accumulate. */
.photo-capture-active > input[type="file"] { display: none; }
.photo-capture-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
}
.photo-capture-controls[hidden] { display: none; }
.photo-capture-btn {
    padding: 0.35rem 0.7rem;
    font-size: 0.85rem;
    white-space: nowrap;
}
@media (hover: hover) and (pointer: fine) {
    .photo-capture-camera { display: none; }
}
.photo-capture-count {
    font-size: 0.82rem;
    color: var(--muted);
}
.photo-capture-list {
    list-style: none;
    margin: 0.45rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
.photo-capture-list[hidden] { display: none; }
.photo-capture-list li {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    min-width: 0;
}
.photo-capture-list img {
    width: 2.6rem;
    height: 2.6rem;
    object-fit: cover;
    border-radius: 5px;
    border: 1px solid var(--border);
    flex-shrink: 0;
}
.photo-capture-name {
    font-size: 0.82rem;
    color: var(--muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}
.photo-capture-remove {
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 5px;
    cursor: pointer;
    color: var(--muted);
    line-height: 1;
    padding: 0.15rem 0.45rem;
    flex-shrink: 0;
}
.photo-capture-remove:hover {
    color: #b04444;
    border-color: #b04444;
}

/* Slice plantnet-capture (lug 2026): input file nascosto, pilotato dai
   bottoni «Scatta» / «Scegli foto». Il modal si apre solo via JS,
   quindi nascondere l'input non toglie nulla al no-JS. */
.plantnet-photo-pick input[type="file"] {
    display: none;
}
.plantnet-photo-pick {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    min-width: 0;
}
.plantnet-pick-btn {
    padding: 0.35rem 0.7rem;
    font-size: 0.85rem;
    white-space: nowrap;
}
/* «Scatta» ha senso solo dove c'è una fotocamera: su desktop
   (puntatore fine + hover) resta solo «Scegli foto». */
@media (hover: hover) and (pointer: fine) {
    .plantnet-pick-camera { display: none; }
}
.plantnet-file-status {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    min-width: 0;
    font-size: 0.82rem;
    color: var(--muted);
}
.plantnet-file-thumb {
    width: 2.2rem;
    height: 2.2rem;
    object-fit: cover;
    border-radius: 5px;
    border: 1px solid var(--border);
    flex-shrink: 0;
}
.plantnet-file-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 9rem;
}
.plantnet-photo-row select {
    padding: 0.4rem 0.5rem;
    border: 1px solid var(--border);
    border-radius: 5px;
    background: var(--card-bg);
    color: var(--ink);
    font-size: 0.88rem;
}

.plantnet-row-remove {
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 5px;
    width: 32px;
    height: 32px;
    font-size: 1.1rem;
    color: var(--muted);
    cursor: pointer;
}
.plantnet-row-remove:hover {
    border-color: #b43c3c;
    color: #b43c3c;
}

.plantnet-row-add {
    align-self: flex-start;
}
.plantnet-row-add:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.plantnet-modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.6rem;
    padding-top: 0.5rem;
    border-top: 1px solid var(--border);
}
/* Bugfix mag 2026: uniformiamo padding/min-width dei bottoni nel modal
   PlantNet. Senza queste regole, "Annulla" (secondary-button) e
   "Identifica" (primary-button) avevano dimensioni leggermente diverse
   (secondary ha padding piu' generoso di default), risultato asimmetrico. */
.plantnet-modal-actions > button {
    min-width: 7.5rem;
    padding: 0.6rem 1.1rem;
    font-size: 0.95rem;
    line-height: 1.2;
    margin: 0;
}

.plantnet-results {
    border-top: 1px solid var(--border);
    padding-top: 1rem;
    margin-top: 0.5rem;
}
.plantnet-results h4 {
    margin: 0 0 0.7rem;
    color: var(--accent);
}
.plantnet-results-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.plantnet-result-row {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.8rem;
    align-items: center;
    padding: 0.7rem 0.85rem;
    background: rgba(0, 0, 0, 0.025);
    border-radius: 6px;
    border: 1px solid var(--border);
}
.plantnet-result-info {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    min-width: 0;
}
.plantnet-result-score {
    flex-shrink: 0;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 0.9rem;
}
.plantnet-result-body {
    font-size: 0.9rem;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.plantnet-badge-found {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.1rem 0.5rem;
    border-radius: 10px;
    background: rgba(74, 124, 89, 0.15);
    color: #4a7c59;
    font-size: 0.78rem;
    font-weight: 600;
}
.plantnet-badge-new {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.1rem 0.5rem;
    border-radius: 10px;
    background: rgba(180, 60, 60, 0.10);
    color: #b43c3c;
    font-size: 0.78rem;
    font-weight: 600;
}

/* Slice FOTO-3 (giu 2026): sezione "Aggiungi alla galleria" nel modal
   PlantNet. Thumbnail delle foto caricate con checkbox per scegliere
   quali importare nella galleria del vaso (la prima = copertina). */
.plantnet-gallery-add {
    margin-top: 1rem;
    padding-top: 0.8rem;
    border-top: 1px solid var(--border);
}
.plantnet-gallery-add h5 {
    margin: 0 0 0.3rem;
    font-size: 0.95rem;
    color: var(--accent-dark);
}
.plantnet-gallery-hint {
    margin: 0 0 0.6rem;
    font-size: 0.82rem;
    color: var(--muted);
}
.plantnet-gallery-thumbs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}
.plantnet-gallery-pick {
    position: relative;
    cursor: pointer;
    display: inline-block;
}
.plantnet-gallery-pick img {
    width: 72px;
    height: 72px;
    object-fit: cover;
    border-radius: 6px;
    border: 2px solid transparent;
    display: block;
    opacity: 0.55;
    transition: opacity 0.12s, border-color 0.12s;
}
/* Checkbox in alto a sinistra sulla thumbnail. */
.plantnet-gallery-pick input[type="checkbox"] {
    position: absolute;
    top: 0.25rem;
    left: 0.25rem;
    z-index: 1;
    width: 1.1rem;
    height: 1.1rem;
    accent-color: var(--accent);
    cursor: pointer;
}
/* Foto spuntata: piena opacita' + bordo accent. */
.plantnet-gallery-pick:has(input:checked) img {
    opacity: 1;
    border-color: var(--accent);
}

/* Slice B2: wrapper del bottone "Identifica con foto" nel form
   fitopatia. Distinto dal trigger del form vaso (che e' inline accanto
   al select specie) perche' qui e' presentato come "fast path" sopra
   il select Tipologia, con una hint testuale sotto. */
.plantnet-trigger {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin-bottom: 0.8rem;
}
.plantnet-trigger .plantnet-identify-btn {
    align-self: flex-start;
}

/* Slice B2: badge codice EPPO mostrato accanto al match-status nella
   lista di candidati fitopatie. Standard internazionale, monospace per
   leggibilita'. */
.plantnet-badge-eppo {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.1rem 0.5rem;
    border-radius: 10px;
    background: rgba(80, 80, 80, 0.10);
    color: var(--muted, #666);
    font-family: ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.02em;
}

/* Slice B2: descrizione breve della fitopatia ritornata da PlantNet,
   mostrata sotto il nome nella card del candidato. Tronca con ellipsis
   a 200 char lato JS; qui solo lo stile testo "secondario". */
.plantnet-result-desc {
    margin: 0.4rem 0 0;
    font-size: 0.82rem;
    color: var(--muted, #666);
    line-height: 1.35;
}

.plantnet-select-btn {
    padding: 0.5rem 1rem;
    font-size: 0.85rem;
    margin: 0;
    white-space: nowrap;
}

.plantnet-quota {
    display: block;
    margin-top: 0.8rem;
    color: var(--muted);
    font-size: 0.8rem;
    text-align: right;
}

.plantnet-loading {
    color: var(--muted);
    font-style: italic;
}

.plantnet-error {
    color: #b43c3c;
    padding: 0.6rem 0.8rem;
    background: rgba(180, 60, 60, 0.08);
    border-radius: 6px;
    border-left: 3px solid #b43c3c;
}

/* Slice "PlantNet A4": form di creazione specie personale. Nested
   nello stesso modal, visibile quando l'utente sceglie un candidate
   non in catalogo. */
.plantnet-create-form {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    border-top: 1px solid var(--border);
    padding-top: 1rem;
    margin-top: 0.5rem;
}
.plantnet-create-form h4 {
    margin: 0;
    color: var(--accent);
}
.plantnet-create-intro {
    color: var(--muted);
    font-size: 0.88rem;
    line-height: 1.5;
    margin: 0;
}
.plantnet-create-form input[readonly] {
    background: rgba(0, 0, 0, 0.04);
    color: var(--muted);
    cursor: not-allowed;
}
.plantnet-cf-error {
    color: #b43c3c;
    padding: 0.55rem 0.8rem;
    background: rgba(180, 60, 60, 0.08);
    border-radius: 6px;
    border-left: 3px solid #b43c3c;
    font-size: 0.9rem;
}

/* Slice "PlantNet A5": lista specie personali in /profilo/catalogo/piante */
.user-species-list {
    list-style: none;
    padding: 0;
    margin: 1rem 0 0;
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}
.user-species-card {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 1rem;
    align-items: center;
    padding: 1rem 1.2rem;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
}
.user-species-info h4 {
    margin: 0 0 0.2rem;
    color: var(--accent);
}
.user-species-scientific {
    margin: 0 0 0.3rem;
    color: var(--muted);
    font-size: 0.9rem;
}
.user-species-meta {
    margin: 0;
    font-size: 0.85rem;
    color: var(--muted);
}
.user-species-badge {
    display: inline-block;
    padding: 0.1rem 0.55rem;
    background: rgba(74, 124, 89, 0.15);
    color: #4a7c59;
    border-radius: 10px;
    font-weight: 600;
    font-size: 0.78rem;
    text-transform: capitalize;
}
.user-species-actions {
    display: flex;
    gap: 0.5rem;
}

@media (max-width: 640px) {
    .user-species-card {
        grid-template-columns: 1fr;
    }
    .user-species-actions {
        justify-content: flex-end;
    }
}

/* ──────────────────────────────────────────────────────────────────────────
   PIANIFICA PER PERIODI — Griglia mese × fertilizzante (slice 2/4)
   ────────────────────────────────────────────────────────────────────────── */

/* Palette 8 colori per i preset. Assegnati in ordine di posizione
   (preset 0 -> color-0, 1 -> color-1, ...). Tonalità desaturate per
   evitare di "gridare" sopra al resto del form. */
:root {
    --preset-color-0: #4a7c59;  /* verde acanto */
    --preset-color-1: #2d5e8a;  /* blu lavanda */
    --preset-color-2: #8a4a8a;  /* viola */
    --preset-color-3: #c87530;  /* arancio bruciato */
    --preset-color-4: #4a9e9e;  /* turchese */
    --preset-color-5: #8a5a3a;  /* marrone caldo */
    --preset-color-6: #6e8a3a;  /* verde oliva */
    --preset-color-7: #a04a4a;  /* rosso muto */
}

/* Toggle "Pianifica per periodi": riusa .field-checkbox con variante */
.preset-schedule-toggle {
    margin-top: 1rem;
    padding: 0.6rem 0.8rem;
    background: rgba(74, 124, 89, 0.05);
    border: 1px solid var(--border);
    border-radius: 6px;
}
.preset-schedule-toggle small {
    display: block;
    margin-top: 0.3rem;
    color: var(--muted);
    font-size: 0.83rem;
    line-height: 1.4;
}

/* Container griglia */
.preset-schedule-grid {
    margin-top: 0.75rem;
    overflow-x: auto;  /* scroll orizzontale su mobile */
    max-width: 100%;
    /* Bugfix mag 2026: -webkit-overflow-scrolling per smooth scroll iOS. */
    -webkit-overflow-scrolling: touch;
}
.preset-schedule-empty {
    color: var(--muted);
    font-style: italic;
    padding: 1rem;
    background: rgba(0, 0, 0, 0.03);
    border-radius: 6px;
}
.preset-schedule-hint {
    display: block;
    margin-top: 0.5rem;
    color: var(--muted);
    font-size: 0.82rem;
    line-height: 1.4;
}

.preset-schedule-table {
    /* width: max-content + min-width: 100% = tabella prende dimensione
       naturale (somma delle celle, ~700px con 12 mesi + prodotto), ma
       e' almeno larga quanto il container su desktop. Senza max-content
       la tabella si stringerebbe a width:100% rendendo le celle 22px
       su mobile (illeggibili). Lo scroll-x del container compensa. */
    width: max-content;
    min-width: 100%;
    border-collapse: separate;
    border-spacing: 2px;
    font-size: 0.85rem;
}
.preset-schedule-table th,
.preset-schedule-table td {
    padding: 0;
    text-align: center;
    vertical-align: middle;
}
.preset-schedule-table .preset-schedule-prod {
    text-align: left;
    padding: 0.4rem 0.6rem;
    background: rgba(0, 0, 0, 0.03);
    border-radius: 4px;
    font-weight: 500;
    color: var(--ink);
    min-width: 150px;
    max-width: 220px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.preset-schedule-table .preset-schedule-month {
    background: rgba(0, 0, 0, 0.03);
    padding: 0.4rem 0;
    font-size: 0.78rem;
    color: var(--muted);
    font-weight: 600;
    min-width: 44px;
}
.preset-schedule-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin-right: 0.45rem;
    vertical-align: middle;
}

.preset-schedule-cell {
    width: 44px;
    height: 38px;
    background: rgba(0, 0, 0, 0.02);
    border: 1px solid var(--border);
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.1s, transform 0.05s;
}
.preset-schedule-cell:hover {
    background: rgba(0, 0, 0, 0.06);
}
.preset-schedule-cell-active {
    border: none;
}
/* Colore della cella attiva = colore del preset di quella riga.
   Assegniamo via data-preset-color sulla TR genitore. */
.preset-schedule-row[data-preset-color="0"] .preset-schedule-cell-active {
    background: var(--preset-color-0);
    color: #fff;
}
.preset-schedule-row[data-preset-color="1"] .preset-schedule-cell-active {
    background: var(--preset-color-1);
    color: #fff;
}
.preset-schedule-row[data-preset-color="2"] .preset-schedule-cell-active {
    background: var(--preset-color-2);
    color: #fff;
}
.preset-schedule-row[data-preset-color="3"] .preset-schedule-cell-active {
    background: var(--preset-color-3);
    color: #fff;
}
.preset-schedule-row[data-preset-color="4"] .preset-schedule-cell-active {
    background: var(--preset-color-4);
    color: #fff;
}
.preset-schedule-row[data-preset-color="5"] .preset-schedule-cell-active {
    background: var(--preset-color-5);
    color: #fff;
}
.preset-schedule-row[data-preset-color="6"] .preset-schedule-cell-active {
    background: var(--preset-color-6);
    color: #fff;
}
.preset-schedule-row[data-preset-color="7"] .preset-schedule-cell-active {
    background: var(--preset-color-7);
    color: #fff;
}
/* Numero cadenza dentro la cella attiva. Solo display (no click
   handler dedicato): la cella nel suo insieme reagisce a single click
   (toggle) e double click (popover modifica cadenza). */
.preset-schedule-cell-days {
    font-size: 0.78rem;
    font-weight: 600;
    line-height: 1;
    color: #fff;
    user-select: none;
}
/* Impedisce la selezione del testo "14" al doppio click, cosi'
   l'utente vede solo il popover che si apre. */
.preset-schedule-cell {
    user-select: none;
}

/* Popover cadenza */
.preset-schedule-popover {
    position: fixed;
    z-index: 1000;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.7rem 0.85rem;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
    min-width: 200px;
}
.preset-schedule-popover label {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-size: 0.85rem;
    margin-bottom: 0.6rem;
}
.preset-schedule-popover input {
    padding: 0.4rem 0.55rem;
    border: 1px solid var(--border);
    border-radius: 5px;
    font-size: 0.95rem;
}
.preset-schedule-popover-actions {
    display: flex;
    justify-content: space-between;  /* Disattiva a sx, Annulla/OK a dx */
    gap: 0.4rem;
    flex-wrap: wrap;
}
.preset-schedule-popover-actions button {
    padding: 0.35rem 0.85rem;
    font-size: 0.85rem;
    margin: 0;
}
/* Slice fix UX 2026-05-24: bottone Disattiva esplicito col rosso
   "muto" per distinguerlo da Annulla. */
.preset-schedule-popover-deactivate {
    color: #b43c3c;
    border-color: rgba(180, 60, 60, 0.4) !important;
}
.preset-schedule-popover-deactivate:hover {
    background: rgba(180, 60, 60, 0.08);
    border-color: #b43c3c !important;
}

@media (max-width: 640px) {
    .preset-schedule-cell {
        width: 36px;
        height: 34px;
    }
    .preset-schedule-table .preset-schedule-prod {
        min-width: 110px;
        font-size: 0.8rem;
    }
}

@media (max-width: 640px) {
    .plantnet-photo-row {
        grid-template-columns: 1fr;
        gap: 0.4rem;
    }
    .plantnet-row-remove {
        justify-self: end;
        margin-top: -32px;
    }
    .plantnet-result-row {
        grid-template-columns: 1fr;
    }
    .plantnet-select-btn {
        width: 100%;
    }
}

/* ── Card stima fertirrigazione (slice fitosim-4) ────────────────────── */

.fertirrigation-suggest-card {
    background: rgba(46, 125, 50, 0.06);
    border: 1px solid rgba(46, 125, 50, 0.18);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    margin: 0.6rem 0;
}
.fert-sug-title {
    margin: 0 0 0.5rem;
    color: var(--accent);
    font-size: 1rem;
}
.fert-sug-empty,
.fert-sug-loading {
    margin: 0.2rem 0;
    color: var(--muted);
    font-size: 0.88rem;
    font-style: italic;
}
.fert-sug-error {
    margin: 0.2rem 0;
    color: #b43c3c;
    font-size: 0.88rem;
}
.fert-sug-water {
    font-size: 1.05rem;
    color: var(--ink);
    margin-bottom: 0.5rem;
}
.fert-sug-water strong {
    color: var(--accent-dark);
}
.fert-sug-water small {
    color: var(--muted);
    font-weight: normal;
    margin-left: 0.3rem;
}
.fert-sug-ferts {
    list-style: none;
    padding: 0;
    margin: 0.4rem 0 0.6rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.fert-sug-fert {
    padding: 0.45rem 0.6rem;
    background: rgba(255, 255, 255, 0.55);
    border-radius: 5px;
    font-size: 0.9rem;
}
.fert-sug-fert-name {
    font-weight: 600;
    color: var(--ink);
}
.fert-sug-fert-dose {
    color: var(--accent-dark);
    font-weight: 600;
    margin-left: 0.3rem;
}
.fert-sug-source {
    color: var(--muted);
    font-size: 0.78rem;
    font-style: italic;
}
.fert-sug-msg {
    display: inline-block;
    color: var(--muted);
    font-size: 0.78rem;
    margin-top: 0.15rem;
}
.fert-sug-msg-warn {
    color: #b07a25;
}
.fert-sug-notes {
    list-style: disc inside;
    padding: 0;
    margin: 0.4rem 0;
    color: var(--muted);
    font-size: 0.8rem;
}
.fert-sug-notes li {
    margin-bottom: 0.15rem;
}
.fert-sug-actions {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    margin-top: 0.6rem;
    flex-wrap: wrap;
}
.fert-sug-disclaimer {
    color: var(--muted);
    font-size: 0.75rem;
    font-style: italic;
}
[data-fert-sug-apply] {
    padding: 0.45rem 0.9rem;
    font-size: 0.85rem;
    margin: 0;
}

/* ── Gruppi di vasi (slice G1, mag 2026) ────────────────────────────── */

.pot-groups-page {
    max-width: 960px;
    margin: 0 auto;
}

/* Lista gruppi */
/* Slice mod_auto-groups: header multi-azione + anteprima gruppi
   suggeriti (per specie / esposizione). */
.page-header-actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    align-items: center;
}
.auto-groups-intro {
    color: var(--muted);
    margin: 0 0 1rem;
    max-width: 60ch;
}
/* Selettore ambiti (rev. giu 2026): scelta globale irrigazione/
   concimazione/trattamenti, in cima ai suggerimenti. */
.auto-scope-picker {
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card-bg);
    margin: 0 0 1.2rem;
}
.auto-scope-picker fieldset {
    border: 0;
    margin: 0;
    padding: 0.8rem 1rem 1rem;
}
.auto-scope-picker legend {
    font-weight: 600;
    padding: 0;
}
.auto-scope-options {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.2rem;
    margin: 0.6rem 0 0.9rem;
}
.auto-scope-option {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
}
.auto-groups-form {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1rem;
}
.auto-group-card {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem;
    margin: 0;
    background: var(--card-bg);
}
.auto-group-create {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.6rem;
}
.auto-group-name { margin-bottom: 0.5rem; }
.auto-group-scope { color: var(--muted); margin: 0 0 0.6rem; }
.auto-group-members {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
.auto-group-member {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
}
.auto-group-member small { color: var(--muted); }
.auto-groups-actions {
    grid-column: 1 / -1;
    display: flex;
    gap: 0.75rem;
    align-items: center;
    margin-top: 0.5rem;
}

/* Slice mod_protocols: step "protocolli in atto" post-creazione vaso. */
.protocols-intro {
    color: var(--muted);
    margin: 0 0 1rem;
    max-width: 62ch;
}
.protocols-form {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 1rem;
}
.protocol-card {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1rem;
    margin: 0;
    background: var(--card-bg);
}
.protocol-active {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.6rem;
}
.protocol-fields {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.protocol-mode {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    font-size: 0.9rem;
    color: var(--muted);
}
.protocols-actions {
    grid-column: 1 / -1;
    display: flex;
    gap: 0.75rem;
    align-items: center;
    margin-top: 0.5rem;
}

/* Wrapper "scheda" per le tab profilo il cui contenuto starebbe altrimenti
   direttamente sullo sfondo stagionale (feedback, sensori), risultando poco
   leggibile: gli dà lo stesso trattamento card delle altre schede, ma a
   larghezza piena (non centrato/stretto come .auth-card). */
.profile-panel {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 1.5rem 1.75rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
    margin-top: 1rem;
}
.profile-panel > :first-child { margin-top: 0; }
.profile-panel > :last-child { margin-bottom: 0; }

/* Slice mod_feedback: form invio feedback + lista admin. */
.feedback-intro {
    color: var(--muted);
    margin: 0 0 1rem;
    max-width: 62ch;
}
.feedback-form {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    max-width: 640px;
}
.feedback-form textarea {
    width: 100%;
    resize: vertical;
}
.feedback-actions {
    margin-top: 0.5rem;
}
.feedback-admin-list {
    list-style: none;
    padding: 0;
    margin: 1rem 0 0;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}
.feedback-admin-item {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    background: var(--card-bg);
}
.feedback-admin-meta {
    font-size: 0.85rem;
    color: var(--muted);
    margin-bottom: 0.4rem;
}
.feedback-admin-msg {
    line-height: 1.5;
}
.feedback-admin-atts {
    margin-top: 0.5rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}
.feedback-att-link {
    font-size: 0.85rem;
}
.feedback-badge {
    display: inline-block;
    font-size: 0.75rem;
    padding: 0.05rem 0.4rem;
    border-radius: 4px;
    background: rgba(120, 120, 120, 0.15);
}
.feedback-badge-sent {
    background: rgba(74, 124, 89, 0.18);
    color: var(--accent-dark);
}

/* Slice mod_feedback2: badge per stato del feedback + form admin +
   storico utente. */
.feedback-status-visualizzato { background: rgba(199, 153, 57, 0.20); color: #8a6d1f; }
.feedback-status-issue { background: rgba(58, 130, 200, 0.20); color: #2a5a8a; }
.feedback-status-implementazione { background: rgba(74, 124, 89, 0.22); color: var(--accent-dark); }
.feedback-status-scartato { background: rgba(120, 120, 120, 0.20); color: var(--muted); }
.feedback-admin-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
    margin-top: 0.6rem;
}
.feedback-status-form {
    display: flex;
    gap: 0.3rem;
    align-items: center;
}
.feedback-history {
    margin-top: 1.5rem;
}
.feedback-history-list {
    list-style: none;
    padding: 0;
    margin: 0.5rem 0 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.feedback-history-item {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.6rem 0.8rem;
    background: var(--card-bg);
}
.feedback-history-meta {
    font-size: 0.8rem;
    color: var(--muted);
    margin-bottom: 0.25rem;
}
/* Slice mod_feedback5: badge col numero di feedback non letti sul
   bottone "Feedback ricevuti" nella pagina admin. */
.admin-feedback-badge {
    display: inline-block;
    min-width: 1.3rem;
    padding: 0.05rem 0.35rem;
    border-radius: 999px;
    background: #b04444;
    color: #fff;
    font-size: 0.78rem;
    font-weight: 700;
    text-align: center;
    line-height: 1.3;
}

/* Slice mod_diario: modal "Vedi tutte le attività" (elenco compatto).
   Prefisso .journal-all-dialog per vincere su .help-dialog-form ul. */
.journal-all-dialog { max-width: 560px; }
.journal-all-dialog .journal-compact-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0;
    max-height: 60vh;
    overflow-y: auto;
}
.journal-all-dialog .journal-compact-row {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
    padding: 0.4rem 0;
    border-bottom: 1px solid var(--border);
    font-size: 0.9rem;
}
.journal-all-dialog .journal-compact-date {
    color: var(--muted);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.journal-all-dialog .journal-compact-note {
    color: var(--fg);
    flex: 1 1 100%;
}

.group-list {
    list-style: none;
    padding: 0;
    margin: 1rem 0 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1rem;
}
.group-card {
    background: var(--card-bg);
    border-radius: 8px;
    box-shadow: 0 2px 6px rgba(0,0,0,0.06);
    overflow: hidden;
    transition: transform 80ms ease, box-shadow 120ms ease;
}
.group-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0,0,0,0.10);
}
.group-card-link {
    display: block;
    color: inherit;
    text-decoration: none;
}
.group-color-strip {
    height: 6px;
}
.group-card-body {
    padding: 0.9rem 1rem;
}
.group-card-body h3 {
    margin: 0 0 0.3rem;
    color: var(--accent);
    font-size: 1.05rem;
}
.group-scope {
    margin: 0.2rem 0;
    color: var(--muted);
    font-size: 0.82rem;
}
.group-meta {
    margin: 0.4rem 0 0.2rem;
    font-size: 0.9rem;
}
.group-desc {
    margin: 0.4rem 0 0;
    font-size: 0.85rem;
    color: var(--muted);
    font-style: italic;
}

/* Form gruppo */
.group-form .field-group {
    margin-bottom: 1rem;
}
.group-color-palette {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    align-items: center;
}
.group-color-radio {
    cursor: pointer;
    position: relative;
}
.group-color-radio input[type="radio"] {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}
.group-color-swatch {
    display: block;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 2px solid transparent;
    transition: border-color 120ms ease, transform 80ms ease;
}
.group-color-radio input[type="radio"]:checked + .group-color-swatch {
    border-color: var(--ink);
    transform: scale(1.1);
}
.group-color-radio:hover .group-color-swatch {
    transform: scale(1.05);
}

.group-scope-list,
.group-members-list {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin-top: 0.4rem;
}
.group-members-empty {
    color: var(--muted);
    font-size: 0.9rem;
}
.group-member-checkbox small {
    color: var(--muted);
    font-weight: normal;
    margin-left: 0.3rem;
}
.group-actions {
    display: flex;
    gap: 0.8rem;
    align-items: center;
    margin-top: 1rem;
    flex-wrap: wrap;
}
.group-delete-form {
    /* Ora è un form fratello (non più annidato nel form di modifica):
       lo stacchiamo con un separatore per marcare la "zona pericolosa". */
    margin-top: 1.5rem;
    padding-top: 1.2rem;
    border-top: 1px solid rgba(0, 0, 0, 0.08);
}

/* Pagina Sensori (ecowitt E2): gateway + sensori rilevati. */
.sensori-intro {
    color: var(--muted);
    max-width: 60ch;
    margin: 0 0 1rem;
}
.sensor-gateway-card {
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card-bg);
    padding: 1rem;
    margin: 0 0 1rem;
}
.sensor-gateway-card h3 { margin: 0 0 0.2rem; }
.sensor-gateway-mac { color: var(--muted); margin: 0 0 0.6rem; }
.sensor-list { margin: 0.4rem 0; padding-left: 1.2rem; }
.sensor-empty { color: var(--muted); }
.sensor-gateway-actions {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-top: 0.6rem;
}
.sensor-inline-form { margin: 0; }
.sensor-add-form { margin: 0; }
.modal-actions {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 1rem;
    flex-wrap: wrap;
}
/* Nei modal i bottoni primario/secondario vanno alla stessa altezza:
   il .primary-button globale ha margin-top e padding piu' generosi. */
.modal-actions .primary-button,
.modal-actions .secondary-button {
    margin-top: 0;
    padding: 0.55rem 1.1rem;
    font-size: 0.95rem;
}
/* I contenuti dei modal custom (gateway, cambia sensore, wizard
   calibrazione) hanno bisogno del padding: .help-dialog e' padding 0
   (nella guida lo da' .help-dialog-form). */
dialog.help-dialog > .sensor-add-form,
dialog.help-dialog > .pot-sensor-attach,
dialog.help-dialog > .cal-wizard {
    display: block;
    padding: 1.1rem 1.3rem 1.3rem;
}

/* Card "Sensori suolo" nel dettaglio vaso (ecowitt E2b). */
/* La card usa lo stile uniforme .detail-card (bordo-sinistra accent +
   ombra); qui solo le specifiche interne dei sensori. */
.pot-sensor-list { list-style: none; margin: 0 0 0.8rem; padding: 0; }
.pot-sensor-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    padding: 0.35rem 0;
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.pot-sensor-attach { margin-top: 0.6rem; }
.link-button {
    background: none;
    border: none;
    color: #b43c3c;
    cursor: pointer;
    padding: 0;
    font: inherit;
    text-decoration: underline;
}

/* Lettura sensore nel dettaglio vaso (ecowitt E4): valore + sparkline. */
.pot-sensor-item {
    padding: 0.6rem 0;
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.pot-sensor-item:last-of-type { border-bottom: none; }
.pot-sensor-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    color: var(--muted);
    font-size: 0.9em;
}
.pot-sensor-head-actions {
    display: inline-flex;
    align-items: center;
    gap: 0.7rem;
}
.pot-sensor-head-actions .link-button { text-decoration: none; }
.pot-sensor-head-actions .link-button:hover { text-decoration: underline; }

/* Wizard calibrazione sensore (E5d). */
.sensor-cal-dialog { max-width: 34rem; }
.cal-live {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem 0.7rem;
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: rgba(74, 124, 89, 0.05);
    font-size: 0.92em;
}
.cal-wizard h4 { margin: 0.8rem 0 0.4rem; }
[data-cal-status] { flex-basis: 100%; }
.sensor-readings-row {
    display: flex;
    align-items: baseline;
    gap: 1.6rem;
    flex-wrap: wrap;
    margin: 0.3rem 0;
}
.sensor-reading {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    margin: 0.3rem 0;
}
.sensor-readings-row .sensor-reading { margin: 0; }
/* EC e temperatura del WH52: valori secondari, più piccoli dell'umidità. */
.sensor-reading-sec .sensor-reading-value {
    font-size: 1.15rem;
    font-weight: 600;
}
.sensor-reading-sec .sensor-reading-value small {
    font-size: 0.72rem;
    font-weight: 400;
    color: var(--muted);
}
.sensor-reading-value {
    font-size: 1.8rem;
    font-weight: 700;
    color: var(--accent, #3d6649);
}
.sensor-reading-label { color: var(--muted); }
.sensor-metrics {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem 1rem;
    color: var(--muted);
    font-size: 0.9em;
    margin-bottom: 0.3rem;
}
.sensor-sparkline {
    display: block;
    color: var(--accent, #3d6649);
    opacity: 0.85;
}
.sensor-sparkline-label {
    font-size: 10px;
    fill: var(--muted, #777);
    font-style: italic;
}
.sensor-sparkline-axis {
    stroke: rgba(0, 0, 0, 0.15);
    stroke-width: 1;
}
/* Bottone azione nell'header di una card (es. "cambia sensore"):
   stesso registro visivo del link "modifica" della card preset. */
.card-action-btn {
    background: none;
    border: none;
    padding: 0;
    margin-left: 0.5rem;
    font-size: 0.78rem;
    font-weight: normal;
    color: var(--accent-dark, #2f5d3b);
    text-decoration: none;
    cursor: pointer;
    font-family: inherit;
}
.card-action-btn:hover { text-decoration: underline; }
.sensor-reading-when { color: var(--muted); margin: 0.2rem 0 0; }
.sensor-threshold-form {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.5rem;
    color: var(--muted);
    font-size: 0.9em;
}
.sensor-threshold-label {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}
.sensor-threshold-input { width: 4rem; }
.danger-button {
    color: #b43c3c;
    border-color: rgba(180, 60, 60, 0.5);
}
.danger-button:hover {
    background: rgba(180, 60, 60, 0.08);
    border-color: #b43c3c;
}

/* Badge dei gruppi sulla pagina detail vaso */
.pot-groups-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin: 0.4rem 0 0.8rem;
    font-size: 0.88rem;
}
.pot-groups-label {
    color: var(--muted);
    font-weight: 600;
}
.pot-group-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.25rem 0.65rem;
    border-radius: 999px;
    color: #fff;
    font-size: 0.82rem;
    font-weight: 500;
    text-decoration: none;
    transition: opacity 100ms ease, transform 80ms ease;
}
.pot-group-badge:hover {
    opacity: 0.9;
    transform: translateY(-1px);
}

/* Slice G2: bottoni "Applica al gruppo" nel form journal */
.apply-to-group-block {
    background: rgba(74, 124, 89, 0.05);
    border: 1px dashed rgba(74, 124, 89, 0.25);
    border-radius: 8px;
    padding: 0.8rem 1rem;
    margin: 1rem 0;
}
.apply-to-group-hint {
    margin: 0 0 0.6rem;
    font-size: 0.88rem;
    color: var(--muted);
}
.apply-to-group-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}
.apply-to-group-btn {
    border-width: 2px !important;
    border-style: solid;
    background: var(--card-bg);
    font-size: 0.88rem;
    padding: 0.5rem 0.8rem;
    margin: 0;
}
.apply-to-group-btn:hover {
    background: rgba(74, 124, 89, 0.08);
}
.apply-to-group-btn strong {
    color: var(--accent-dark);
}

/* Slice TODO-1: wrap di preview+button per ogni gruppo. Display column
   cosi` la preview "Stima per gli altri vasi" sta sopra il bottone. */
.apply-to-group-item {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    flex: 1 1 auto;
    min-width: 220px;
}

.apply-to-group-preview {
    background: var(--card-bg);
    border: 1px solid rgba(74, 124, 89, 0.25);
    border-radius: 6px;
    padding: 0.55rem 0.7rem;
    font-size: 0.85rem;
}

.apply-to-group-preview-title {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--accent-dark);
    margin: 0 0 0.4rem;
}

.apply-to-group-preview-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.apply-to-group-preview-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.15rem 0;
    font-size: 0.85rem;
    color: var(--fg);
    border-bottom: 1px dashed rgba(0, 0, 0, 0.05);
}

.apply-to-group-preview-row:last-child {
    border-bottom: none;
}

.apply-to-group-preview-row strong {
    color: var(--accent-dark);
    font-variant-numeric: tabular-nums;
}

.apply-to-group-preview-error {
    color: var(--muted);
    font-style: italic;
}

.apply-to-group-preview-error small {
    color: rgba(192, 57, 43, 0.85);
}

.apply-to-group-preview-loading {
    margin: 0;
    color: var(--muted);
    font-style: italic;
    font-size: 0.82rem;
}

.apply-to-group-preview-total {
    margin: 0.45rem 0 0;
    padding-top: 0.4rem;
    border-top: 1px solid rgba(74, 124, 89, 0.2);
    font-size: 0.86rem;
    color: var(--accent-dark);
}

.apply-to-group-preview-total strong {
    font-variant-numeric: tabular-nums;
}

/* Dark mode per la preview */
:root[data-theme="dark"] .apply-to-group-preview {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(120, 175, 140, 0.35);
}
:root[data-theme="dark"] .apply-to-group-preview-row {
    border-bottom-color: rgba(255, 255, 255, 0.08);
}
@media (prefers-color-scheme: dark) {
    :root[data-theme="auto"] .apply-to-group-preview {
        background: rgba(255, 255, 255, 0.04);
        border-color: rgba(120, 175, 140, 0.35);
    }
    :root[data-theme="auto"] .apply-to-group-preview-row {
        border-bottom-color: rgba(255, 255, 255, 0.08);
    }
}

/* Slice V2: fieldset "Vasi del set" multi-row nel form vaso */
.variant-rows-list {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    margin: 0.4rem 0 0.6rem;
}
.variant-row {
    border: 1px solid rgba(0, 0, 0, 0.08);
    border-left: 3px solid var(--accent, #4a7c59);
    border-radius: 6px;
    padding: 0.6rem 0.85rem;
    background: rgba(74, 124, 89, 0.03);
    min-width: 0;
}
.variant-row-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.4rem;
}
.variant-row-title {
    color: var(--accent-dark);
    font-size: 0.92rem;
}
.variant-row-remove {
    background: transparent;
    border: 1px solid rgba(180, 60, 60, 0.4);
    color: #b43c3c;
    border-radius: 4px;
    width: 1.8rem;
    height: 1.8rem;
    line-height: 1;
    font-size: 1.1rem;
    cursor: pointer;
    padding: 0;
}
.variant-row-remove:hover {
    background: rgba(180, 60, 60, 0.08);
}
.variant-row-add {
    align-self: flex-start;
    margin-top: 0.3rem;
}

/* Slice V2/V3: card "Tipologia e dimensioni" in modalità set di vasi.
   Lista verticale di blocchi (uno per variant) con totale in cima. */
.variant-detail-list {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    margin-top: 0.5rem;
}
.variant-detail-block {
    border: 1px solid rgba(0, 0, 0, 0.08);
    border-left: 3px solid var(--accent, #4a7c59);
    border-radius: 6px;
    padding: 0.55rem 0.85rem;
    background: rgba(74, 124, 89, 0.03);
}
.variant-detail-title {
    margin: 0 0 0.35rem;
    font-size: 0.95rem;
    color: var(--accent-dark);
    font-weight: 600;
}
.variant-detail-title em {
    font-weight: 400;
    color: var(--text-muted, #666);
}
.variant-detail-total {
    margin: 0.2rem 0 0.4rem;
    padding: 0.45rem 0.7rem;
    background: rgba(74, 124, 89, 0.08);
    border-radius: 4px;
    color: var(--accent-dark);
    font-size: 0.95rem;
}

/* Slice T1: tabella "Parametri tecnici dei vasi" sulla dashboard tecnica.
   Tabella vasi × metriche con super-header colorato per i 4 gruppi
   (Identita`, Statici, Set, Derivati, ET). Scrollabile orizzontalmente
   su mobile via wrap container. */
.tech-table-wrap {
    overflow-x: auto;
    margin: 0.5rem 0 0.4rem;
    border: 1px solid rgba(0, 0, 0, 0.08);
    border-radius: 6px;
    background: #fff;
}
.tech-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.88rem;
    min-width: 1100px;  /* forza scroll su viewport stretti */
}
.tech-table thead th {
    text-align: left;
    padding: 0.5rem 0.7rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
    font-weight: 600;
    color: #2a2a2a;
    white-space: nowrap;
    background: #fafafa;
    position: sticky;
    top: 0;
    z-index: 1;
}
.tech-table-supergroup th {
    text-align: center;
    font-size: 0.82rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-bottom: 2px solid rgba(0, 0, 0, 0.12);
    padding: 0.35rem 0.5rem;
}
/* Pastelli per i 4 gruppi: verde accent (id), giallo tenue (statici),
   azzurro (set), lavanda (derivati), rosa (ET). */
.tech-table-supergroup th.tech-group-id     { background: rgba(74, 124, 89, 0.14); }
.tech-table-supergroup th.tech-group-static { background: rgba(220, 180, 60, 0.14); }
.tech-table-supergroup th.tech-group-set    { background: rgba(80, 140, 200, 0.14); }
.tech-table-supergroup th.tech-group-derived{ background: rgba(160, 120, 200, 0.14); }
.tech-table-supergroup th.tech-group-et     { background: rgba(220, 110, 140, 0.14); }
.tech-table tbody td {
    padding: 0.45rem 0.7rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
    vertical-align: top;
    white-space: nowrap;
}
.tech-table tbody tr:last-child td {
    border-bottom: none;
}
.tech-table tbody tr:hover td {
    background: rgba(74, 124, 89, 0.04);
}
.tech-table .tech-icon {
    display: inline-block;
    width: 1.1em;
    margin-right: 0.2em;
}
.tech-table .tech-cell-nd {
    color: rgba(0, 0, 0, 0.35);
    font-style: italic;
}
.tech-table a {
    color: var(--accent-dark);
    text-decoration: none;
}
.tech-table a:hover {
    text-decoration: underline;
}
.tech-table-empty {
    padding: 1.5rem;
    text-align: center;
    color: rgba(0, 0, 0, 0.55);
    background: #fafafa;
    border: 1px dashed rgba(0, 0, 0, 0.15);
    border-radius: 6px;
}
.tech-table-note {
    font-size: 0.82rem;
    color: rgba(0, 0, 0, 0.55);
    margin: 0.4rem 0 0;
}
/* Slice F-A: badge "*" per ET₀ stimato con Hargreaves (cache pre-F-A).
   Cursore help per indicare che e' interattivo via tooltip. */
.tech-et-badge {
    color: rgba(220, 110, 60, 0.85);
    font-weight: 700;
    cursor: help;
    margin-left: 0.15em;
}
/* Slice F-B4: variant del badge per tier Penman-Monteith FISICO
   (gold standard specie-specifico). Tinta dorata/verde per
   indicare il metodo "premium" — distintivo a colpo d'occhio. */
.tech-et-badge.tech-et-badge-pm-physical {
    color: rgba(60, 130, 90, 0.95);  /* verde accent */
    font-size: 0.85em;
}
.tech-et-badge.tech-et-badge-hargreaves {
    color: rgba(220, 110, 60, 0.85);  /* ambra (= il vecchio default) */
}

/* Slice T3: sortable header. Icona ↕ tenue di default; ↑/↓ attiva
   quando la colonna e' ordinata. Cursor pointer + nessuna selezione
   testo (evita selezione accidentale durante click ripetuti). */
.tech-table th.sortable {
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
}
.tech-table th.sortable:hover {
    background: rgba(74, 124, 89, 0.08);
}
.tech-table th.sortable .sort-arrow {
    display: inline-block;
    margin-left: 0.3em;
    color: rgba(0, 0, 0, 0.25);
    font-size: 0.8em;
}
.tech-table th.sortable .sort-arrow::before {
    content: "↕";
}
.tech-table th.sortable.sort-asc .sort-arrow {
    color: var(--accent-dark, #2f5d3b);
}
.tech-table th.sortable.sort-asc .sort-arrow::before {
    content: "↑";
}
.tech-table th.sortable.sort-desc .sort-arrow {
    color: var(--accent-dark, #2f5d3b);
}
.tech-table th.sortable.sort-desc .sort-arrow::before {
    content: "↓";
}
.tech-table th.sortable.sort-asc,
.tech-table th.sortable.sort-desc {
    background: rgba(74, 124, 89, 0.12);
}

/* Slice A1: tabella "Metriche agronomiche per vaso" sulla dashboard
   agronomica. Stessa struttura della .tech-table ma:
   - 5 gruppi semantici diversi (salute/diario/ciclo/foto vs
     statici/derivati/ET): colori pastello dedicati.
   - Cella stato con label + class colorata (healthy/warning/critical).
   Sortable: il JS tech-table-sort.js si aggancia anche a
   .agro-metrics-table.
   NB classe `.agro-metrics-table` (NON `.agro-table`) per evitare
   collisione con widget pre-esistenti che usano gia` .agro-table
   per tabelline 3-4 colonne dentro card 1/3 di larghezza
   (vedi agronomy.py: top diseases, journal frequency). Senza
   rename, il min-width 1200px qui sotto le esplode visivamente
   (issue A1-HOTFIX, mag 2026). */
.agro-metrics-wrap {
    overflow-x: auto;
    margin: 0.5rem 0 0.4rem;
    border: 1px solid rgba(0, 0, 0, 0.08);
    border-radius: 6px;
    background: #fff;
}
.agro-metrics-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.88rem;
    min-width: 1200px;  /* 19 colonne → scroll su mobile */
}
.agro-metrics-table thead th {
    text-align: left;
    padding: 0.5rem 0.7rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
    font-weight: 600;
    color: #2a2a2a;
    white-space: nowrap;
    background: #fafafa;
    position: sticky;
    top: 0;
    z-index: 1;
}
.agro-metrics-supergroup th {
    text-align: center;
    font-size: 0.82rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-bottom: 2px solid rgba(0, 0, 0, 0.12);
    padding: 0.35rem 0.5rem;
}
/* Pastelli per i 5 gruppi semantici: verde accent (id),
   rosso tenue (stato salute), arancio (attivita`), giallo (ciclo),
   viola (foto/lineage). */
.agro-metrics-supergroup th.agro-group-id     { background: rgba(74, 124, 89, 0.14); }
.agro-metrics-supergroup th.agro-group-salute { background: rgba(220, 110, 90, 0.14); }
.agro-metrics-supergroup th.agro-group-diario { background: rgba(230, 160, 60, 0.14); }
.agro-metrics-supergroup th.agro-group-ciclo  { background: rgba(220, 200, 60, 0.14); }
.agro-metrics-supergroup th.agro-group-foto   { background: rgba(160, 110, 200, 0.14); }
.agro-metrics-table tbody td {
    padding: 0.45rem 0.7rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
    vertical-align: top;
    white-space: nowrap;
}
.agro-metrics-table tbody tr:last-child td {
    border-bottom: none;
}
.agro-metrics-table tbody tr:hover td {
    background: rgba(74, 124, 89, 0.04);
}
.agro-metrics-table .agro-icon {
    display: inline-block;
    width: 1.1em;
    margin-right: 0.2em;
}
.agro-metrics-table .agro-cell-nd {
    color: rgba(0, 0, 0, 0.35);
    font-style: italic;
}
.agro-metrics-table a {
    color: var(--accent-dark);
    text-decoration: none;
}
.agro-metrics-table a:hover {
    text-decoration: underline;
}
.agro-metrics-empty {
    padding: 1.5rem;
    text-align: center;
    color: rgba(0, 0, 0, 0.55);
    background: #fafafa;
    border: 1px dashed rgba(0, 0, 0, 0.15);
    border-radius: 6px;
}
.agro-metrics-note {
    font-size: 0.82rem;
    color: rgba(0, 0, 0, 0.55);
    margin: 0.4rem 0 0;
}

/* ── Slice SIST-2 (giu 2026): tabelle dashboard → schede su mobile ──
   Le tabelle tecnica (.tech-table, 20 col) e agronomica
   (.agro-metrics-table, 19 col) hanno min-width 1100-1200px e su
   telefono richiedono uno scroll orizzontale scomodissimo. Sotto i
   720px le trasformiamo in SCHEDE verticali: ogni riga (= 1 pianta)
   diventa una card con "label: valore" per ogni parametro (la label
   viene da data-label sui td, vedi dashboard_*.py). L'header tabella
   e' nascosto; la cella "Vaso" (.tech-card-title / .agro-card-title)
   fa da intestazione della card. Su desktop questo blocco e' inerte
   (la tabella resta tabella). */
@media (max-width: 720px) {
    .tech-table-wrap,
    .agro-metrics-wrap {
        overflow-x: visible;
        border: none;
        border-radius: 0;
        background: transparent;
    }
    .tech-table,
    .agro-metrics-table {
        display: block;
        width: 100%;
        min-width: 0;       /* annulla il min-width che forzava lo scroll */
        font-size: 0.9rem;
    }
    /* Niente header tabella su mobile (super-group + sotto-header). */
    .tech-table thead,
    .agro-metrics-table thead {
        display: none;
    }
    .tech-table tbody,
    .agro-metrics-table tbody {
        display: block;
    }
    /* Ogni riga = 1 card pianta. */
    .tech-table tbody tr,
    .agro-metrics-table tbody tr {
        display: block;
        margin: 0 0 0.9rem;
        padding: 0.3rem 0.75rem 0.5rem;
        border: 1px solid rgba(0, 0, 0, 0.12);
        border-radius: 8px;
        background: #fff;
        box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
    }
    /* Ogni cella = riga "label · valore". */
    .tech-table tbody td,
    .agro-metrics-table tbody td {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 0.8rem;
        padding: 0.32rem 0;
        border-bottom: 1px solid rgba(0, 0, 0, 0.06);
        white-space: normal;
        text-align: right;
    }
    .tech-table tbody td:last-child,
    .agro-metrics-table tbody td:last-child {
        border-bottom: none;
    }
    /* Label a sinistra (da data-label). */
    .tech-table tbody td::before,
    .agro-metrics-table tbody td::before {
        content: attr(data-label);
        font-weight: 600;
        color: var(--muted, rgba(0, 0, 0, 0.55));
        text-align: left;
        flex: 0 1 auto;
        margin-right: auto;
    }
    /* Cella "Vaso": intestazione della card, full-width, niente label. */
    .tech-table td.tech-card-title,
    .agro-metrics-table td.agro-card-title {
        display: block;
        text-align: left;
        font-size: 1.05rem;
        font-weight: 600;
        padding: 0.1rem 0 0.4rem;
        margin-bottom: 0.35rem;
        border-bottom: 2px solid var(--accent, #4a7c59);
    }
    .tech-table td.tech-card-title::before,
    .agro-metrics-table td.agro-card-title::before {
        display: none;
    }
    /* Hover desktop irrilevante su mobile: niente bg hover sulle celle. */
    .tech-table tbody tr:hover td,
    .agro-metrics-table tbody tr:hover td {
        background: transparent;
    }
    /* Dark mode: card scure invece del bianco hardcoded. SOLO dentro
       il media query mobile (su desktop le righe restano tabella). */
    :root[data-theme="dark"] .tech-table tbody tr,
    :root[data-theme="dark"] .agro-metrics-table tbody tr {
        background: rgba(255, 255, 255, 0.05);
        border-color: rgba(255, 255, 255, 0.12);
    }
}
@media (max-width: 720px) and (prefers-color-scheme: dark) {
    :root[data-theme="auto"] .tech-table tbody tr,
    :root[data-theme="auto"] .agro-metrics-table tbody tr {
        background: rgba(255, 255, 255, 0.05);
        border-color: rgba(255, 255, 255, 0.12);
    }
}

/* Sortable (stesso pattern .tech-table); duplicato perche` il
   selettore base e' diverso. */
.agro-metrics-table th.sortable {
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
}
.agro-metrics-table th.sortable:hover {
    background: rgba(74, 124, 89, 0.08);
}
.agro-metrics-table th.sortable .sort-arrow {
    display: inline-block;
    margin-left: 0.3em;
    color: rgba(0, 0, 0, 0.25);
    font-size: 0.8em;
}
.agro-metrics-table th.sortable .sort-arrow::before {
    content: "↕";
}
.agro-metrics-table th.sortable.sort-asc .sort-arrow,
.agro-metrics-table th.sortable.sort-desc .sort-arrow {
    color: var(--accent-dark, #2f5d3b);
}
.agro-metrics-table th.sortable.sort-asc .sort-arrow::before {
    content: "↑";
}
.agro-metrics-table th.sortable.sort-desc .sort-arrow::before {
    content: "↓";
}
.agro-metrics-table th.sortable.sort-asc,
.agro-metrics-table th.sortable.sort-desc {
    background: rgba(74, 124, 89, 0.12);
}

/* Stato salute: pill colorata per healthy/warning/critical. */
.agro-state-healthy {
    background: rgba(80, 160, 100, 0.18);
    color: #2f5d3b;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-weight: 600;
    font-size: 0.82rem;
}
.agro-state-warning {
    background: rgba(230, 180, 60, 0.22);
    color: #7a5a10;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-weight: 600;
    font-size: 0.82rem;
}
.agro-state-critical {
    background: rgba(220, 80, 60, 0.18);
    color: #8a2a1a;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-weight: 600;
    font-size: 0.82rem;
}

/* ============================================================
   Slice S1.2 (mag 2026): "Curva idrica" del detail vaso
   ============================================================
   Sparkline SVG 360×130 con curva acqua disponibile in %,
   linea verticale "oggi", soglia di allerta tratteggiata,
   marker rossi sui giorni di stress futuro. Tooltip JS su
   hover dei punti (water-curve-tooltip.js).
*/
.water-curve-section {
    /* Eredita stile da .detail-card; aggiungiamo solo padding extra
       per il chart e il tooltip che si posiziona absolute al wrap. */
}
.water-curve-method {
    color: rgba(0, 0, 0, 0.45);
    font-weight: 400;
    font-size: 0.78rem;
    margin-left: 0.4em;
}
.water-curve-chart-wrap {
    position: relative;
    margin: 0.6rem 0 0.5rem;
}
.water-curve-svg {
    /* Slice TODO-2 (giu 2026): rimosso max-width 480px per far
       occupare al grafico tutta la larghezza della scheda. L'SVG si
       scala uniformemente preservando l'aspect ratio (360:160 single,
       360:220 set), così con card più larga l'altezza aumenta
       proporzionalmente lasciando i 14 giorni più leggibili e le N
       polyline del set ancor più distinguibili. */
    width: 100%;
    height: auto;
    display: block;
}
/* Decoratori SVG */
/* Slice TODO-2 (giu 2026): font-size e stroke-width raddoppiati
   coerentemente col viewBox SVG che e' passato da 360x160 a 720x320.
   Cosi` su card desktop ~800px la scala finale e' ~1.1x e i font
   appaiono nelle loro dimensioni naturali (~10px reali). */
.water-curve-axis {
    stroke: rgba(0, 0, 0, 0.3);
    stroke-width: 1;
    fill: none;
}
.water-curve-grid {
    stroke: rgba(0, 0, 0, 0.08);
    stroke-width: 1;
    fill: none;
}
/* Slice mod_02: gridline verticali (una per giorno) ancora piu' tenui
   delle orizzontali, cosi` non competono con la linea "oggi" e il
   confine "+7gg" che restano ben visibili sopra. */
.water-curve-grid-v {
    stroke: rgba(0, 0, 0, 0.05);
}
.water-curve-tick {
    font-size: 11px;
    fill: rgba(0, 0, 0, 0.6);
    font-family: inherit;
}
/* Slice mod_02: etichette asse X (solo numero del giorno). Piu' piccole
   dei tick standard perche' ora ce n'e' una per (quasi) ogni giorno. */
.water-curve-xtick {
    font-size: 9px;
}
.water-curve-alert-line {
    stroke: rgba(200, 100, 40, 0.7);
    stroke-width: 1;
    stroke-dasharray: 8 6;
    fill: none;
}
.water-curve-alert-label {
    font-size: 12px;
    fill: rgba(200, 100, 40, 0.85);
    font-style: italic;
}
.water-curve-today-line {
    stroke: rgba(74, 124, 89, 0.5);
    stroke-width: 1;
    stroke-dasharray: 4 4;
    fill: none;
}
.water-curve-today-label {
    font-size: 14px;
    fill: var(--accent-dark, #2f5d3b);
    font-weight: 600;
}
/* Slice C1 (giu 2026): polygon area rimosso (era pesante visivamente
   con curve a 14gg che restano alte). La classe resta nel CSS come
   no-op per retrocompat di eventuali snapshot, ma il render non
   emette piu` <polygon class="water-curve-area">. */
.water-curve-area {
    display: none;
}
.water-curve-line {
    fill: none;
    stroke: var(--accent-dark, #2f5d3b);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
}
/* Punti */
.water-curve-point {
    fill: var(--accent-dark, #2f5d3b);
    stroke: white;
    stroke-width: 2;
    cursor: help;
    transition: r 0.1s ease;
}
.water-curve-point:hover,
.water-curve-point:focus {
    outline: none;
    r: 7;
}
.water-curve-point.today {
    fill: var(--accent-dark, #2f5d3b);
    stroke: white;
    stroke-width: 2;
}
.water-curve-point.stress {
    fill: rgba(220, 110, 60, 0.95);  /* ambra */
}
.water-curve-point.stress-future {
    fill: rgba(220, 80, 60, 0.95);   /* rosso più acceso */
}
/* Tooltip */
.water-curve-tooltip {
    position: absolute;
    pointer-events: none;
    background: rgba(40, 40, 40, 0.96);
    color: #fff;
    padding: 0.4rem 0.6rem;
    border-radius: 4px;
    font-size: 0.78rem;
    line-height: 1.35;
    max-width: 180px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    z-index: 10;
}
.water-curve-tooltip[hidden] {
    display: none;
}
.water-curve-tooltip-date {
    font-size: 0.72rem;
    color: rgba(255, 255, 255, 0.7);
    margin-bottom: 0.15rem;
}
.water-curve-tooltip-row {
    white-space: nowrap;
}
.water-curve-tooltip-stress {
    margin-left: 0.4em;
    color: rgba(255, 180, 120, 1);
    font-weight: 600;
}
.water-curve-tooltip-precip {
    color: rgba(140, 200, 255, 1);
    font-size: 0.72rem;
    margin-top: 0.1rem;
}

/* Slice S1.6: barre verticali pioggia in basso al plot.
   Blu acqua tenue, sopra l'asse X ma sotto la curva. */
.water-curve-precip-bar {
    fill: rgba(60, 130, 200, 0.35);
    stroke: rgba(60, 130, 200, 0.55);
    stroke-width: 1;
}
.water-curve-precip-legend {
    font-size: 12px;
    fill: rgba(60, 130, 200, 0.75);
    font-style: italic;
}
/* Slice S1.6-bis: label numerica "X.X mm" sopra ogni barra pioggia.
   Stesso blu della legenda ma un tone più scuro (0.95 vs 0.75) per
   leggibilità anche su barre cortissime (0.3-0.5 mm). font-weight 600
   per il contrasto col background dell'area verde tenue. */
.water-curve-precip-label {
    font-size: 12px;
    font-weight: 500;
    fill: rgba(40, 105, 175, 0.95);
}

/* Slice S1.9: polyline per i sub-vasi di un set. Tratteggiate per
   distinguersi dalla linea media (continua, verde scuro). Opacità
   intermedia: visibile ma "sotto" la principale visivamente. Palette
   5 colori distinti che ciclano sui set con >5 sub-vasi (raro).
   Slice S1.9-bis: stroke più spesso (2.2) e dasharray più visibile
   (5 4) per distinguersi anche quando le N curve sono ravvicinate
   (range water_pct stretto, es. 92-100% nei primi giorni). */
/* Slice C1 (giu 2026): variants piu` "ghost" — opacita` 0.55 (era 0.85)
   e stroke piu` sottile. Slice C2: di default sono HIDDEN (toggle via
   chip della legenda). */
.water-curve-variant-line {
    fill: none;
    stroke-width: 2.5;
    stroke-dasharray: 8 6;
    stroke-linecap: round;
    opacity: 0.65;
    pointer-events: none;
    display: none;  /* Slice C2: hidden di default */
}
/* Quando la chip corrispondente nella legenda viene attivata,
   data-variant-N="1" sulla section mostra la polyline. */
.water-curve-section[data-variant-1="1"] .water-curve-variant-line-1,
.water-curve-section[data-variant-2="1"] .water-curve-variant-line-2,
.water-curve-section[data-variant-3="1"] .water-curve-variant-line-3,
.water-curve-section[data-variant-4="1"] .water-curve-variant-line-4,
.water-curve-section[data-variant-5="1"] .water-curve-variant-line-5 {
    display: inline;
}
.water-curve-variant-line-1 { stroke: #5a83c8; }  /* blu */
.water-curve-variant-line-2 { stroke: #a070c8; }  /* viola */
.water-curve-variant-line-3 { stroke: #d8965a; }  /* arancio */
.water-curve-variant-line-4 { stroke: #c87096; }  /* rosa */
.water-curve-variant-line-5 { stroke: #6ba888; }  /* verde acqua */

/* Slice TODO-2: segmento "extended" della curva (giorni +8..+14).
   Tratteggiato e con opacita` ridotta per comunicare l'accuratezza
   meteo decrescente. Applicato sia alla linea principale che alle
   variant (per coerenza visiva). */
.water-curve-line-extended {
    stroke-dasharray: 8 6;
    opacity: 0.55;
}
/* Slice overlay-sensore (lug 2026): letture reali di umidità del
   sensore suolo sovrapposte al passato della curva. Blu tratteggiato,
   distinto dal verde della simulata: si confronta l'andamento, non il
   valore (grandezze diverse: umidità terreno vs % riserva utile). */
.water-curve-sensor-line {
    fill: none;
    stroke: rgba(60, 130, 200, 0.85);
    stroke-width: 2;
    stroke-dasharray: 5 4;
    stroke-linejoin: round;
    stroke-linecap: round;
}
.water-curve-variant-line-extended {
    stroke-dasharray: 4 6;
    opacity: 0.5;
}

/* Linea verticale di confine "+7gg": dashed grigia + label piccola. */
.water-curve-extended-boundary {
    stroke: rgba(120, 120, 120, 0.55);
    stroke-width: 2;
    stroke-dasharray: 4 4;
}
.water-curve-extended-label {
    font-size: 12px;
    fill: rgba(110, 110, 110, 0.85);
    font-style: italic;
}

/* Slice S1.9: legenda chip per il set di vasi sotto al grafico. */
.water-curve-set-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 0.55rem;
    margin: 0.5rem 0 0.75rem;
    padding: 0;
    font-size: 0.82rem;
    color: var(--muted);
}

.water-curve-set-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.2rem 0.65rem;
    background: rgba(0, 0, 0, 0.04);
    border-radius: 999px;
    line-height: 1.4;
    border: 1px solid transparent;
    font-size: 0.85rem;
    color: var(--muted);
    font-family: inherit;
}
/* Chip cliccabili (sub-vasi). Button reset + cursor pointer + stato
   attivo quando aria-pressed=true. */
button.water-curve-set-chip {
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s, color 0.12s;
}
button.water-curve-set-chip:hover {
    background: rgba(0, 0, 0, 0.08);
    border-color: rgba(0, 0, 0, 0.15);
}
button.water-curve-set-chip[aria-pressed="true"] {
    background: rgba(74, 124, 89, 0.10);
    border-color: rgba(74, 124, 89, 0.4);
    color: var(--fg);
    font-weight: 600;
}
/* Hint sotto la legenda */
.water-curve-set-hint {
    display: block;
    margin: 0.35rem 0 0;
    font-size: 0.78rem;
    color: var(--muted);
    font-style: italic;
}

.water-curve-set-chip-swatch {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 2px;
    background: #999;
    flex: 0 0 auto;
}

.water-curve-set-chip-1 .water-curve-set-chip-swatch {
    background: #5a83c8;
    border: 1px dashed #5a83c8;
    background-image: none;
    height: 2px;
    margin-top: 1px;
    width: 14px;
}
.water-curve-set-chip-2 .water-curve-set-chip-swatch {
    background: #a070c8; height: 2px; margin-top: 1px; width: 14px;
}
.water-curve-set-chip-3 .water-curve-set-chip-swatch {
    background: #d8965a; height: 2px; margin-top: 1px; width: 14px;
}
.water-curve-set-chip-4 .water-curve-set-chip-swatch {
    background: #c87096; height: 2px; margin-top: 1px; width: 14px;
}
.water-curve-set-chip-5 .water-curve-set-chip-swatch {
    background: #6ba888; height: 2px; margin-top: 1px; width: 14px;
}
.water-curve-set-chip-mean {
    background: rgba(80, 130, 95, 0.15);
    color: var(--accent);
    font-weight: 600;
}
.water-curve-set-chip-mean .water-curve-set-chip-swatch {
    background: var(--accent);
    height: 3px;
    margin-top: 1px;
    width: 14px;
    border-radius: 1px;
}

/* Dark mode per le chip del set */
:root[data-theme="dark"] .water-curve-set-chip {
    background: rgba(255, 255, 255, 0.06);
}
:root[data-theme="dark"] .water-curve-variant-line {
    opacity: 0.85;
}
@media (prefers-color-scheme: dark) {
    :root[data-theme="auto"] .water-curve-set-chip {
        background: rgba(255, 255, 255, 0.06);
    }
    :root[data-theme="auto"] .water-curve-variant-line {
        opacity: 0.85;
    }
}
/* Pill row sotto il grafico */
.water-curve-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    margin: 0.4rem 0 0.5rem;
}
.water-curve-pill {
    background: #fafafa;
    border: 1px solid rgba(0, 0, 0, 0.08);
    padding: 0.3rem 0.6rem;
    border-radius: 999px;
    font-size: 0.82rem;
    color: #333;
}
.water-curve-pill-stress {
    background: rgba(220, 110, 60, 0.12);
    border-color: rgba(220, 110, 60, 0.25);
    color: #8a3a10;
}
.water-curve-pill-ok {
    background: rgba(80, 160, 100, 0.12);
    border-color: rgba(80, 160, 100, 0.25);
    color: #2f5d3b;
}
.water-curve-pill-irrigation {
    background: rgba(60, 130, 200, 0.10);
    border-color: rgba(60, 130, 200, 0.22);
    color: #1c4a7a;
}
.water-curve-pill-capacity {
    color: rgba(0, 0, 0, 0.55);
}
/* Slice S1.7-B: pill distintiva per stima indoor. Arancione/ambra
   per ricordare visivamente che e` un'approssimazione (±25%) vs il
   verde "preciso FAO-56" dei vasi outdoor. */
.water-curve-pill-indoor {
    background: rgba(230, 160, 60, 0.14);
    border-color: rgba(230, 160, 60, 0.30);
    color: #8a5a10;
}
.water-curve-pill-indoor small {
    color: rgba(0, 0, 0, 0.55);
    margin-left: 0.25em;
}
.water-curve-pill small {
    color: rgba(0, 0, 0, 0.55);
    margin-left: 0.25em;
}
/* Disclaimer + placeholder */
.water-curve-disclaimer {
    font-size: 0.78rem;
    color: rgba(0, 0, 0, 0.55);
    margin: 0.4rem 0 0;
    line-height: 1.4;
}

/* Slice C4 (giu 2026): disclaimer collassato dentro <details>. Click
   sul summary "Cos'è?" lo espande. Stile minimal, niente triangolo
   default del browser. */
.water-curve-disclaimer-details {
    margin: 0.6rem 0 0;
    font-size: 0.82rem;
    color: var(--muted);
}
.water-curve-disclaimer-summary {
    list-style: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.2rem 0.55rem;
    background: rgba(0, 0, 0, 0.03);
    border-radius: 999px;
    font-size: 0.8rem;
    color: var(--muted);
    transition: background 0.12s;
    user-select: none;
}
.water-curve-disclaimer-summary::-webkit-details-marker {
    display: none;  /* nasconde la freccia default su Safari */
}
.water-curve-disclaimer-summary::marker {
    content: "";  /* nasconde la freccia default su Firefox/Chrome */
}
.water-curve-disclaimer-summary:hover {
    background: rgba(0, 0, 0, 0.06);
}
.water-curve-disclaimer-details[open] .water-curve-disclaimer-summary {
    background: rgba(74, 124, 89, 0.10);
    color: var(--accent-dark);
}
.water-curve-disclaimer-body {
    margin: 0.5rem 0 0;
    padding: 0.6rem 0.8rem;
    background: rgba(0, 0, 0, 0.02);
    border-left: 3px solid rgba(74, 124, 89, 0.4);
    border-radius: 4px;
    font-size: 0.82rem;
    line-height: 1.5;
    color: rgba(0, 0, 0, 0.7);
}

/* Slice C3 (giu 2026): media query mobile per font/cerchi piu` grandi
   nel grafico (la viewBox e' fissa, lo SVG si scala col CSS). Mobile
   ≤600px: ingrandiamo i tick e gli elementi testuali per resterare
   leggibili anche quando lo SVG totale e' piu` piccolo. */
@media (max-width: 600px) {
    .water-curve-tick { font-size: 24px; }
    /* Slice mod_02: le etichette giorno (numeriche, una per giorno)
       restano piu' contenute anche su mobile per non sovrapporsi. */
    .water-curve-xtick { font-size: 15px; }
    .water-curve-alert-label { font-size: 22px; }
    .water-curve-today-label { font-size: 24px; }
    .water-curve-extended-label { font-size: 22px; }
    .water-curve-precip-label { font-size: 22px; font-weight: 700; }
    .water-curve-precip-legend { font-size: 22px; }
    .water-curve-line { stroke-width: 5; }
    .water-curve-variant-line { stroke-width: 3.5; }
    .water-curve-sensor-line { stroke-width: 4; }
    .water-curve-set-legend { gap: 0.25rem 0.4rem; }
    .water-curve-set-chip { font-size: 0.82rem; padding: 0.25rem 0.6rem; }
    .water-curve-section h3 { font-size: 1.05rem; }
    .water-curve-method { display: block; margin-left: 0; font-size: 0.74rem; }
}
.water-curve-section.water-curve-unavailable .water-curve-placeholder {
    padding: 1rem;
    text-align: center;
    color: rgba(0, 0, 0, 0.55);
    background: #fafafa;
    border: 1px dashed rgba(0, 0, 0, 0.15);
    border-radius: 6px;
    margin: 0.6rem 0 0;
}

/* ── Giardiniere M2: memoria nel profilo ("Cosa ricorda di te il Riccio") ── */
.giardiniere-memoria { margin-top: 1rem; padding-top: 0.75rem;
    border-top: 1px dashed rgba(0, 0, 0, 0.15); }
.giardiniere-memoria .memoria-title { margin: 0 0 0.35rem; }
.giardiniere-messaggi { margin-top: 1rem; padding-top: 0.75rem;
    border-top: 1px dashed rgba(0, 0, 0, 0.15); }
.giardiniere-messaggi .memoria-title { margin: 0 0 0.35rem; }
.messaggi-cadenza-form { display: flex; flex-direction: column;
    gap: 0.5rem; margin: 0.5rem 0 0.35rem; }
.messaggi-cadenza-opt { display: flex; align-items: baseline; gap: 0.5rem;
    cursor: pointer; }
.messaggi-cadenza-opt input { margin-top: 0.15rem; }
.messaggi-cadenza-opt span { font-size: 0.9rem; line-height: 1.35; }
.memoria-voci { list-style: none; padding: 0; margin: 0.5rem 0; }
.memoria-voce-row { display: flex; justify-content: space-between;
    align-items: baseline; gap: 0.5rem; padding: 0.3rem 0;
    border-bottom: 1px dashed rgba(0, 0, 0, 0.12); }
.memoria-voce-row .memoria-data { color: rgba(0, 0, 0, 0.5); }
.memoria-inline-form { margin: 0; }
.memoria-del-btn { background: none; border: none; cursor: pointer;
    color: inherit; opacity: 0.55; font-size: 0.95rem; padding: 0 0.25rem; }
.memoria-del-btn:hover { opacity: 1; }
.memoria-add-form { display: flex; gap: 0.5rem; margin-top: 0.6rem; }
.memoria-add-form input[type="text"] { flex: 1; min-width: 0; }
