/* ============================================================
   GesTask — Bacheche
   Schede task, kanban, strumenti di bacheca e viste lista, tabella e calendario.
   ============================================================ */

/*
 * La tinta di priorita passa da una variabile, non da quattro regole che si
 * ripetono: il colore lo sceglie la classe, la quantita la sceglie il tema.
 * Serve perche la stessa percentuale non rende allo stesso modo nei due temi —
 * un 8 per cento di indaco si vede sul bianco osso del tema chiaro, mentre sul
 * blu notte di quello scuro sparisce del tutto e tutte le task sembrano uguali.
 */
.task-card {
    --task-prio: var(--bs-secondary);
    --task-prio-tint: 8%;
    --task-prio-edge: 100%;

    background-color: color-mix(in srgb, var(--task-prio) var(--task-prio-tint), var(--gt-surface));
    border: 1px solid var(--gt-border);
    border-left: .3rem solid color-mix(in srgb, var(--task-prio) var(--task-prio-edge), transparent);
    border-radius: var(--p-border-radius-lg);
    padding: .85rem;
    transition: box-shadow .18s, transform .18s, background-color .25s, border-color .25s;
    animation: fadeSlideIn .2s ease backwards;
}

.task-card:hover {
    box-shadow: var(--gt-shadow-md);
    transform: translateY(-1px);
}

/* L'anteprima della descrizione. Prima l'aspetto veniva da tre utility di
   Bootstrap applicate nel markup; ora è una regola sola, e la densità
   compatta può ridurla a due righe senza competere con `!important`. */
.task-card-description {
    color: var(--p-text-muted-color);
    font-size: var(--p-font-size-sm);
    line-height: 1.45;
    margin: .25rem 0 .5rem;
}

.task-card.priority-low    { --task-prio: var(--gt-prio-low); }
.task-card.priority-normal { --task-prio: var(--gt-prio-normal); }
.task-card.priority-high   { --task-prio: var(--gt-prio-high); }
.task-card.priority-urgent { --task-prio: var(--gt-prio-urgent); animation: pulsePriority 2s infinite; }

/*
 * Nel tema scuro la tinta va spinta molto piu in alto per restare percepibile,
 * e il bordo viene schiarito: a piena saturazione su fondo scuro legge come una
 * riga spenta invece che come un accento.
 */
[data-bs-theme="dark"] .task-card {
    --task-prio-tint: 24%;
    --task-prio-edge: 78%;

    border-color: color-mix(in srgb, var(--task-prio) 30%, var(--gt-border));
    border-left-color: color-mix(in srgb, var(--task-prio) var(--task-prio-edge), transparent);
}

/*
 * Pillola di priorita, condivisa da card, dettaglio task, viste lista e tabella
 * della bacheca e dagli elenchi task delle dashboard. Prima ogni punto scriveva
 * il proprio badge: sulla card era indaco fisso per tutte e quattro le
 * priorita, altrove grigio, e la priorita risultava illeggibile a colpo
 * d'occhio. Il colore arriva da --priority-color, cosi la pillola dice la
 * stessa cosa che dice il bordo della card.
 */
.priority-pill {
    display: inline-flex;
    align-items: center;
    border-radius: var(--p-border-radius-full);
    padding: .12rem .55rem;
    font-size: .7rem;
    font-weight: 600;
    line-height: 1.45;
    white-space: nowrap;
    --priority-color: var(--bs-secondary);
    background: color-mix(in srgb, var(--priority-color) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--priority-color) 32%, transparent);
    /* Sul chiaro il colore puro sarebbe troppo tenue per un testo cosi piccolo. */
    color: color-mix(in srgb, var(--priority-color) 68%, #000);
}

/* Sullo scuro si inverte: il testo va schiarito e il fondo caricato. */
[data-bs-theme="dark"] .priority-pill {
    background: color-mix(in srgb, var(--priority-color) 26%, transparent);
    border-color: color-mix(in srgb, var(--priority-color) 45%, transparent);
    color: color-mix(in srgb, var(--priority-color) 62%, #fff);
}

.priority-pill-low    { --priority-color: var(--gt-prio-low); }
.priority-pill-normal { --priority-color: var(--gt-prio-normal); }
.priority-pill-high   { --priority-color: var(--gt-prio-high); }
.priority-pill-urgent { --priority-color: var(--gt-prio-urgent); }

/* ============================================================
   Ricorrenza
   ============================================================ */

/* Riepilogo in sola lettura sulla scheda della task modello. */
.task-recurrence-card {
    background: color-mix(in srgb, var(--gt-info) 8%, var(--gt-surface));
    border: 1px solid color-mix(in srgb, var(--gt-info) 28%, transparent);
    border-radius: var(--p-border-radius-lg);
    padding: 1rem;
}
[data-bs-theme="dark"] .task-recurrence-card {
    background: color-mix(in srgb, var(--gt-info) 16%, var(--gt-surface));
}
.task-recurrence-card-head {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-bottom: .6rem;
}
.task-recurrence-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
}
.task-recurrence-facts dt {
    color: var(--bs-secondary-color);
    font-size: .72rem;
    font-weight: 600;
    text-transform: uppercase;
}
.task-recurrence-facts dd {
    font-weight: 600;
    margin: 0;
}

/* Pannello di configurazione nel form di modifica. */
.task-recurrence-panel {
    background: var(--gt-surface-alt);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-lg);
    padding: 1rem;
}
.task-recurrence-fields.is-disabled {
    opacity: .5;
    pointer-events: none;
}
.task-recurrence-weekdays {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
}
.task-recurrence-weekday {
    align-items: center;
    background: var(--gt-surface);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-full);
    cursor: pointer;
    display: inline-flex;
    gap: .35rem;
    font-size: .8rem;
    padding: .25rem .6rem;
}
/* Il giorno scelto si legge dal colore, non solo dal quadratino. */
.task-recurrence-weekday:has(input:checked) {
    background: color-mix(in srgb, var(--gt-accent) 14%, var(--gt-surface));
    border-color: var(--gt-accent);
    font-weight: 600;
}
.task-recurrence-summary {
    background: var(--gt-surface);
    border-left: 3px solid var(--gt-accent);
    border-radius: var(--p-border-radius-sm);
    color: var(--bs-body-color);
    font-size: .85rem;
    margin-top: .75rem;
    padding: .55rem .75rem;
}

/* Badge sulla card della bacheca: distingue il modello dalle sue copie. */
.task-recurrence-chip {
    align-items: center;
    background: color-mix(in srgb, var(--gt-info) 16%, transparent);
    border-radius: var(--p-border-radius-full);
    color: color-mix(in srgb, var(--gt-info) 70%, #000);
    display: inline-flex;
    font-size: .68rem;
    font-weight: 600;
    gap: .25rem;
    padding: .1rem .5rem;
}
[data-bs-theme="dark"] .task-recurrence-chip {
    background: color-mix(in srgb, var(--gt-info) 26%, transparent);
    color: color-mix(in srgb, var(--gt-info) 60%, #fff);
}

/* La copia si distingue dal modello: stesso simbolo, tinta diversa. */
.task-recurrence-chip.is-instance {
    background: color-mix(in srgb, var(--gt-accent) 14%, transparent);
    color: color-mix(in srgb, var(--gt-accent) 70%, #000);
}
[data-bs-theme="dark"] .task-recurrence-chip.is-instance {
    background: color-mix(in srgb, var(--gt-accent) 26%, transparent);
    color: color-mix(in srgb, var(--gt-accent) 62%, #fff);
}

.task-recurrence-origin {
    align-items: center;
    color: var(--bs-secondary-color);
    display: flex;
    flex-wrap: wrap;
    font-size: .85rem;
    gap: .5rem;
}

.task-recurrence-open {
    background: var(--gt-surface);
    border-left: 3px solid var(--gt-info);
    border-radius: var(--p-border-radius-sm);
    font-size: .85rem;
    padding: .55rem .75rem;
}

.task-card-title { font-weight: 700; line-height: 1.25; }
.task-card p { font-size: .875rem; margin: .35rem 0 0; }

/*
 * Spaziatura e disposizione interne alla card.
 *
 * Vivono qui e non nelle utility di Bootstrap perche quelle sono !important:
 * finche il riempimento arrivava da "p-3" e le due file da "d-flex", la
 * densita compatta non poteva stringere nulla e le spunte dei dettagli non
 * potevano nascondere ne le etichette ne la riga di scadenza e priorita.
 */
.task-card .card-body { padding: 1rem; }

.task-card-tags {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
    margin-bottom: .5rem;
}

/* Le etichette di stato — ricorrenza, blocco, duplicati — su una fila sola. */
.task-card-chips {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
    margin-bottom: .5rem;
}

.task-card-meta {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
}

/*
 * La fila inferiore è una griglia e non una riga flessibile.
 *
 * Con `justify-content: space-between` l'ordine dipendeva da quanto stava
 * dentro: bastava una scadenza, una checklist e una pillola di priorità
 * perché le persone scendessero sotto e il cestino restasse da solo in fondo
 * a destra, in un punto diverso per ogni card. I tre posti sono fissi: le
 * etichette si accorciano andando a capo dentro il proprio, gli altri due
 * restano dove sono.
 */
.task-card-footer {
    align-items: center;
    display: grid;
    gap: .35rem .5rem;
    grid-template-columns: minmax(0, 1fr) auto auto;
    grid-template-rows: auto;
    margin-top: .6rem;
}

.task-card-footer .task-card-meta { grid-area: 1 / 1 / 2 / 2; }
.task-card-delete { grid-area: 1 / 3 / 2 / 4; margin-left: 0; }

.task-card-assignees {
    display: inline-flex;
    gap: .375rem;
    grid-area: 1 / 2 / 2 / 3;
    margin-left: 0;
}

/* Barra e percentuale sulla stessa riga, in fondo alla card. */
.task-card-progress {
    align-items: center;
    display: flex;
    gap: .5rem;
    margin-top: .6rem;
}

.task-card-progress .task-progress { flex: 1; margin-top: 0; }

.task-card-progress-value {
    color: var(--p-text-muted-color);
    font-size: .7rem;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
}

/* Il nome nella card si accorcia con i puntini invece di spingere il
   cestino fuori dalla card o mandare a capo scadenza e priorità. */
.task-card-assignees .task-assignees-names {
    color: var(--p-text-color);
    font-size: .75rem;
    font-weight: 600;
    max-width: 7.5rem;
}

/* L'anello che separa gli avatar sovrapposti prende il colore della card,
   non quello della superficie generica: le card sono tinte per priorità e
   un anello di un altro colore si vedrebbe come un bordo estraneo. */
.task-card .p-avatar-group .p-avatar {
    border-color: var(--bs-card-bg, var(--p-content-background));
}

.task-assignees {
    align-items: center;
    display: flex;
    gap: .5rem;
    min-width: 0;
}

.task-assignees-names {
    color: var(--p-text-muted-color);
    font-size: var(--p-font-size-sm);
    max-width: 16rem;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.task-meta, .task-actions { margin-top: .6rem; }

.task-meta span {
    background: color-mix(in srgb, var(--p-primary-color) 8%, transparent);
    border-radius: var(--p-border-radius-full);
    color: var(--gt-accent);
    font-size: .72rem;
    font-weight: 600;
    padding: .1rem .5rem;
}

.task-tag { border-left: .25rem solid var(--tag-color); }

/* Progress bar inside card */
.task-progress {
    height: 4px;
    border-radius: var(--p-border-radius-full);
    background: var(--bs-tertiary-bg);
    overflow: hidden;
    margin-top: .65rem;
}
.task-progress-bar {
    height: 100%;
    border-radius: var(--p-border-radius-full);
    background: linear-gradient(90deg, var(--gt-accent), var(--gt-info));
    transition: width .4s ease;
}

/* Avanzamento in sola lettura: barra e valore sulla stessa riga. */
.task-progress-readonly {
    display: flex;
    align-items: center;
    gap: .6rem;
}
.task-progress-readonly .task-progress {
    flex: 1 1 auto;
    height: 8px;
    margin-top: 0;
}

/* Drag handle */
.task-drag-handle {
    cursor: grab;
    opacity: .5;
    transition: opacity .15s;
    /*
     * touch-action none: senza, il primo movimento del dito viene interpretato
     * come scorrimento della pagina e il trascinamento non parte mai. Le altre
     * proprieta evitano che una pressione prolungata selezioni il testo o apra
     * il menu contestuale di iOS a meta gesto.
     */
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    touch-action: none;
    user-select: none;
}
.task-drag-handle:hover { opacity: 1; }
.task-drag-handle:active { cursor: grabbing; }

/* Su schermo touch la maniglia e un bersaglio da dito, e non si nasconde:
   senza puntatore non esiste un hover che la faccia comparire. */
@media (pointer: coarse) {
    .task-drag-handle {
        min-height: 2.5rem;
        min-width: 2.5rem;
        opacity: 1;
    }
}

/* ============================================================
   Kanban Board
   ============================================================ */
/*
 * Le colonne stanno su una riga flessibile, non su una griglia.
 *
 * Con la griglia la larghezza la decide la traccia, uguale per tutte: uno stato
 * compresso non poteva quindi restringersi da solo. In flex ogni colonna porta
 * la propria misura, e "flex: 1 1 0" con il min-width della colonna riproduce
 * esattamente il vecchio minmax(larghezza, 1fr).
 */
.kanban-board {
    --kanban-col-width: 290px;
    /*
     * Altezza massima di una colonna. Oltre questa misura sono le task a
     * scorrere dentro lo stato: prima uno stato con molte task allungava la
     * pagina, e per vedere gli altri stati si scorreva tutto il contenuto.
     */
    --kanban-col-height: min(70vh, 760px);
    display: flex;
    gap: 1rem;
    overflow-x: auto;
    padding-bottom: 1rem;
    padding-top: .25rem;
}

.kanban-board > .board-column {
    flex: 1 1 0;
}

/*
 * Larghezza scelta con il cursore.
 *
 * Senza questa classe le colonne si allargano fino a riempire lo spazio
 * disponibile, ed e il comportamento che vogliamo finche nessuno interviene:
 * con due o tre stati la bacheca non lascia meta schermo vuoto. Ma proprio per
 * quello, li il cursore non potrebbe restringere nulla. Alla prima regolazione
 * la misura diventa quindi fissa, e quel che si imposta e quel che si vede.
 */
.kanban-board.kanban-board-custom-width:not(.kanban-board-vertical) > .board-column {
    flex: 0 0 var(--kanban-col-width);
}

/*
 * Variante impilata: gli stati scorrono dall'alto in basso invece di
 * affiancarsi.
 *
 * Con molte colonne quella affiancata costringe a scorrere di lato per
 * raggiungere gli ultimi stati, e su schermo stretto mostra una colonna alla
 * volta. Impilandoli la bacheca torna a scorrere come una pagina normale, con
 * ogni stato a piena larghezza. La scelta e per utente e per bacheca: la
 * applica un frammento accanto all'elemento, prima del primo disegno.
 */
.kanban-board.kanban-board-vertical {
    display: flex;
    flex-direction: column;
    overflow-x: visible;
}

.kanban-board.kanban-board-vertical > .board-column {
    flex: 0 0 auto;
    min-width: 0;
    width: 100%;
}

/* A piena larghezza una zona alta come una colonna lascerebbe un vuoto sotto
   l'ultima card: qui basta lo spazio per accogliere il rilascio. */
.kanban-board-vertical .board-drop-zone {
    min-height: 64px;
}

.kanban-board-vertical .board-column-empty {
    min-height: 56px;
}

/* Nelle colonne affiancate la card è stretta: sulla stessa riga il nome
   dell'assegnatario mandava a capo scadenza e priorità. Qui gli assegnatari
   scendono su una riga propria, sotto, e il nome si accorcia solo se supera
   la card. Il cestino, rimasto sulla prima riga, riprende il margine
   automatico che cedeva agli assegnatari. Impilata la card è larga quanto la
   pagina e tutto sta su una riga sola, come nella regola base. */
.kanban-board:not(.kanban-board-vertical) .task-card-footer {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: auto auto;
}

.kanban-board:not(.kanban-board-vertical) .task-card-delete { grid-area: 1 / 2 / 2 / 3; }

.kanban-board:not(.kanban-board-vertical) .task-card-assignees {
    grid-area: 2 / 1 / 3 / 3;
    justify-self: start;
}

.kanban-board:not(.kanban-board-vertical) .task-card-assignees .task-assignees-names { max-width: 100%; }

/* Sul telefono anche la card impilata è larga quanto lo schermo, cioè
   quanto una colonna affiancata: vale la stessa riga propria. */
@media (max-width: 767.98px) {
    .kanban-board-vertical .task-card-footer {
        grid-template-columns: minmax(0, 1fr) auto;
        grid-template-rows: auto auto;
    }

    .kanban-board-vertical .task-card-delete { grid-area: 1 / 2 / 2 / 3; }

    .kanban-board-vertical .task-card-assignees {
        grid-area: 2 / 1 / 3 / 3;
        justify-self: start;
    }

    .kanban-board-vertical .task-card-assignees .task-assignees-names { max-width: 100%; }
}

/* Gli avatar piccoli si accavallano di mezzo rem su un rem e mezzo: l'avatar
   successivo copriva la seconda iniziale («MR» si leggeva «M»). Con meno
   sovrapposizione e un corpo più piccolo le due lettere restano visibili. */
.task-assignees .p-avatar-group .p-avatar-sm {
    font-size: .625rem;
    margin-left: -.3rem;
}

.task-assignees .p-avatar-group .p-avatar-sm:first-child { margin-left: 0; }

/* Impilata su schermo largo la card ha spazio: il nome non si accorcia. */
.kanban-board-vertical .task-card-assignees .task-assignees-names { max-width: 16rem; }

/* ── Preferenze d'aspetto (sezione "Aspetto" degli strumenti) ─────────────── */

/*
 * Densita compatta: stessa card, meno respiro.
 *
 * Non toglie informazioni — per quello ci sono le spunte dei dettagli — ma
 * recupera l'altezza spesa in margini, cosi in una colonna ci stanno alcune
 * task in piu senza scorrere. Le misure vincono sulle utility di Bootstrap
 * grazie alla specificita, senza !important.
 */
.kanban-density-compact .task-card .card-body {
    padding: .6rem;
}

.kanban-density-compact .board-drop-zone {
    gap: .35rem;
}

.kanban-density-compact .task-card .task-card-description {
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    display: -webkit-box;
    overflow: hidden;
}

.kanban-density-compact .board-column .card-header {
    padding-bottom: .6rem;
    padding-top: .6rem;
}

/* Dettagli che si possono togliere dalla card: chi guarda la bacheca per
   capire il carico non ha bisogno di descrizione ed etichette su ogni riga. */
.kanban-hide-description .task-card-description,
.kanban-hide-tags .task-card-tags,
.kanban-hide-meta .task-card-meta,
.kanban-hide-meta .task-card-assignees,
.kanban-hide-progress .task-progress {
    display: none;
}

/*
 * Stati vuoti nascosti.
 *
 * Su una bacheca con molti stati quelli vuoti sono spazio scorso a vuoto. La
 * colonna sparisce finche resta vuota e ricompare appena riceve una task: la
 * regola guarda il segnaposto "Nessuna task", che il codice della bacheca
 * aggiunge e toglie da solo, anche durante il trascinamento.
 */
.kanban-hide-empty .board-column:has(.board-column-empty) {
    display: none;
}

/*
 * Con gli stati vuoti nascosti la larghezza smette di adattarsi.
 *
 * Le colonne si spartiscono lo spazio disponibile: togliendone una, le altre
 * si allargavano per riempire il vuoto, e la bacheca sembrava cambiare misura
 * a ogni spunta. Fissandola sulla larghezza dichiarata, nascondere uno stato
 * toglie una colonna e basta.
 */
.kanban-board.kanban-hide-empty:not(.kanban-board-vertical) > .board-column {
    flex: 0 0 var(--kanban-col-width);
}

/*
 * Stato compresso.
 *
 * Uno stato con molte task — tipicamente "Completate" — occupa spazio senza
 * portare informazione a chi sta guardando il lavoro in corso. Compresso resta
 * visibile come striscia con titolo e conteggio, quindi si sa che c'e e quanto
 * contiene, e si riapre con lo stesso pulsante. La scelta e per utente e per
 * bacheca, come le altre preferenze d'aspetto.
 */
/*
 * Il selettore nomina anche la disposizione perche la larghezza fissa —
 * scelta col cursore o imposta dagli stati vuoti nascosti — usa gia
 * ":not(.kanban-board-vertical)": senza pari specificita uno stato compresso
 * riprendeva la misura delle altre colonne appena si toccava il cursore.
 */
.kanban-board:not(.kanban-board-vertical) > .board-column.board-column-collapsed {
    flex: 0 0 auto;
    min-width: 0;
    width: 3.25rem;
}

.board-column-collapsed .card-body {
    display: none;
}

.board-column-collapsed .card-header {
    align-items: center;
    flex-direction: column;
    gap: .7rem;
    height: 100%;
    /* Le utility di Bootstrap sono !important: per impilare il contenuto in
       alto serve la stessa forza. */
    justify-content: flex-start !important;
    padding-bottom: .8rem;
    padding-top: .8rem;
}

.board-column-collapsed .card-header h2 {
    flex-direction: column;
    min-height: 0;
}

/* Il pulsante resta in cima anche da compresso: e il comando che riapre lo
   stato, deve trovarsi dove si e premuto per chiuderlo. */
.board-column-collapsed .card-header .board-column-actions {
    flex-direction: column-reverse;
    order: -1;
}

.board-column-collapsed .board-column-title {
    max-height: 16rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    writing-mode: vertical-rl;
}

/* Con gli stati impilati non c'e larghezza da recuperare: comprimere lascia la
   sola intestazione, a piena larghezza e in orizzontale. */
.kanban-board.kanban-board-vertical > .board-column.board-column-collapsed {
    width: 100%;
}

.kanban-board-vertical .board-column-collapsed .card-header,
.kanban-board-vertical .board-column-collapsed .card-header h2 {
    flex-direction: row;
    height: auto;
}

.kanban-board-vertical .board-column-collapsed .card-header .board-column-actions {
    flex-direction: row;
    order: 0;
}

.kanban-board-vertical .board-column-collapsed .board-column-title {
    max-height: none;
    writing-mode: horizontal-tb;
}

.board-column-actions {
    align-items: center;
    display: flex;
    flex: 0 0 auto;
    gap: .4rem;
}

.board-column-toggle {
    align-items: center;
    background: transparent;
    border: 0;
    border-radius: var(--p-border-radius-sm);
    color: var(--bs-secondary-color);
    display: inline-flex;
    height: 1.6rem;
    justify-content: center;
    line-height: 0;
    padding: 0;
    transition: background-color .15s ease, color .15s ease;
    width: 1.6rem;
}

.board-column-toggle:hover,
.board-column-toggle:focus-visible {
    background: var(--col-accent-soft);
    color: var(--col-accent);
}

.board-column-toggle i {
    line-height: 0;
    transition: transform .15s ease;
}

.board-column-collapsed .board-column-toggle i {
    transform: rotate(180deg);
}

.board-appearance-field {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    margin-bottom: 1.1rem;
}

.board-appearance-field:last-child {
    margin-bottom: 0;
}

.board-appearance-label {
    color: var(--bs-secondary-color);
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
}

.board-appearance-checks {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    margin-bottom: 1.1rem;
}

/* Scrollbar styling */
.kanban-board::-webkit-scrollbar { height: 6px; }
.kanban-board::-webkit-scrollbar-track { background: transparent; }
.kanban-board::-webkit-scrollbar-thumb { background: var(--gt-border); border-radius: var(--p-border-radius-full); }

/* Colonne: l'accento arriva dal colore dello stato (BoardList::getAccentColor),
   con la palette storica come fallback se la variabile non e impostata */
.board-column {
    min-width: var(--kanban-col-width, 290px);
    --col-accent: var(--gt-col-1);
    --col-accent-soft: color-mix(in srgb, var(--p-primary-color) 15%, transparent);
}

.board-column .card {
    border: 1px solid var(--gt-border) !important;
    border-radius: var(--p-border-radius-lg) !important;
    box-shadow: var(--gt-shadow-sm);
    /* Oltre l'altezza dichiarata scorre l'elenco delle task, non la pagina:
       l'intestazione dello stato resta ferma e visibile. */
    max-height: var(--kanban-col-height, none);
    overflow: hidden;
}

.board-column .card-header {
    border-top: 3px solid var(--col-accent);
    /* L'intestazione non si comprime quando la colonna e piena: e il titolo
       dello stato a restare fermo mentre le task scorrono sotto. */
    flex: 0 0 auto;
    padding-bottom: 1rem;
    padding-top: 1rem;
}

.board-column .card-header .badge {
    background: var(--col-accent-soft);
    color: var(--col-accent);
}

/* Pallino di stato riusato da kanban e vista lista */
.board-column-dot {
    background: var(--col-accent);
    border-radius: var(--p-border-radius-full);
    display: inline-block;
    flex: 0 0 auto;
    height: .55rem;
    width: .55rem;
}

/* Etichetta stato nella vista tabella */
.board-state-chip {
    align-items: center;
    background: var(--state-accent-soft, var(--gt-surface-alt));
    border-radius: var(--p-border-radius-full);
    color: var(--state-accent, inherit);
    display: inline-flex;
    font-size: .8125rem;
    font-weight: 600;
    padding: .18rem .6rem;
}

/*
 * La zona di rilascio riempie tutta l'altezza della colonna.
 *
 * Le colonne della griglia sono alte quanto la piu piena, ma la zona si
 * fermava all'ultima card: in una colonna corta si poteva rilasciare solo
 * nella fascia occupata dalle sue task, e trascinare l'ultima task di una
 * colonna piena verso il basso della colonna accanto non produceva nulla,
 * perche li sotto non c'era piu alcun bersaglio.
 */
.board-column .card-body {
    display: flex;
    flex-direction: column;
    /* Senza min-height un contenitore flex non scende sotto il proprio
       contenuto: la colonna crescerebbe oltre l'altezza dichiarata invece di
       far scorrere le task. */
    min-height: 0;
    overflow: hidden;
}

/* Disposizione delle card: sta qui e non nelle utility "d-flex flex-column
   gap-2", che sono !important e non lascerebbero alla densita compatta alcun
   modo di stringere lo spazio fra una card e l'altra. */
.board-drop-zone {
    border: 1.5px dashed transparent;
    border-radius: var(--p-border-radius-md);
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: .5rem;
    min-height: 120px;
    /* Le task scorrono qui dentro: overscroll-behavior evita che, arrivati in
       fondo alla colonna, il gesto prosegua trascinando la pagina. */
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: .25rem;
    scrollbar-width: thin;
    transition: background .18s, border-color .18s;
}

/*
 * Le card tengono la propria altezza.
 *
 * La zona di rilascio e un contenitore flex: senza questo le card si
 * comprimevano per stare tutte nell'altezza disponibile, schiacciando testo e
 * dettagli invece di far comparire la barra di scorrimento.
 */
.board-drop-zone > .task-card,
.board-drop-zone > .board-column-empty {
    flex: 0 0 auto;
}

.board-drop-zone::-webkit-scrollbar {
    width: .45rem;
}

.board-drop-zone::-webkit-scrollbar-thumb {
    background: var(--gt-border);
    border-radius: var(--p-border-radius-full);
}

.board-drop-zone.board-drop-zone-active {
    background: color-mix(in srgb, var(--p-primary-color) 5%, transparent);
    border-color: var(--gt-accent);
}

/* Segnaposto: dice dove la task finira, senza spostare le altre card avanti e
   indietro a ogni pixel come faceva l'inserimento diretto. */
.task-drop-placeholder {
    background: color-mix(in srgb, var(--gt-accent) 10%, transparent);
    border: 1.5px dashed var(--gt-accent);
    border-radius: var(--p-border-radius-lg);
    flex: 0 0 auto;
}

/* La card in volo segue il puntatore: sta nel body, fuori dalla colonna che
   ritaglia il proprio contenuto. */
.task-card-dragging {
    box-shadow: var(--gt-shadow-lg);
    cursor: grabbing;
    margin: 0;
    opacity: .95;
    pointer-events: none;
    position: fixed;
    rotate: 1.5deg;
    z-index: 1080;
}

body.is-dragging-task {
    -webkit-user-select: none;
    user-select: none;
}

/* Durante il gesto le card si riposizionano di continuo: l'animazione di
   ingresso le farebbe lampeggiare. */
body.is-dragging-task .task-card {
    animation: none;
}


/* Empty column state */
.board-column-empty {
    align-items: center;
    border: 1.5px dashed var(--gt-border);
    border-radius: var(--p-border-radius-md);
    color: var(--bs-secondary-color);
    display: flex;
    font-size: .85rem;
    justify-content: center;
    min-height: 100px;
    padding: 1rem;
}

/* Old task-stack kept for compat */
.task-stack { display: flex; flex-direction: column; gap: .5rem; }

/* ============================================================
   Board Tools (filters / views / webhooks panel)
   ============================================================ */
.board-view-header {
    align-items: flex-start;
    display: flex;
    gap: 1rem;
    justify-content: space-between;
    margin-bottom: 1rem;
}

.board-create-task {
    background: var(--gt-surface);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-lg);
    box-shadow: var(--gt-shadow-xs);
    padding: 1rem;
}

/* Modale strumenti: navigazione a sinistra, sezione attiva a destra */
.board-tools-modal .modal-content {
    border: 0;
    border-radius: var(--p-border-radius-xl);
    overflow: hidden;
}

.board-tools-modal .modal-header {
    align-items: flex-start;
    border-bottom: 1px solid var(--gt-border);
    gap: 1rem;
}

.board-tools-modal .modal-body { background: var(--gt-surface); overflow: hidden; }

/* Due colonne indipendenti: la navigazione resta ferma mentre scorre la sezione */
.board-tools-layout {
    display: grid;
    grid-template-columns: 210px minmax(0, 1fr);
    /* Senza una riga limitata la traccia cresce quanto il pannello piu lungo e
       sfonda il max-height: il contenuto finirebbe tagliato dalla modal-body,
       che e overflow:hidden, senza poter scorrere. */
    grid-template-rows: minmax(0, 1fr);
    max-height: min(70vh, 640px);
    min-height: 55vh;
}

.board-tools-nav {
    background: var(--gt-surface-alt);
    border-right: 1px solid var(--gt-border);
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    gap: .125rem;
    min-height: 0;
    overflow-y: auto;
    padding: .75rem;
}

.board-tools-nav-item {
    align-items: center;
    background: transparent;
    border: 0;
    border-radius: var(--p-border-radius-md);
    color: var(--bs-body-color);
    display: flex;
    font-size: .9rem;
    gap: .6rem;
    padding: .55rem .7rem;
    text-align: left;
    transition: background .15s, color .15s;
    width: 100%;
}

.board-tools-nav-item i { font-size: 1rem; line-height: 1; opacity: .7; }
.board-tools-nav-label { flex: 1 1 auto; }

.board-tools-nav-count {
    background: var(--gt-surface-deep);
    border-radius: var(--p-border-radius-full);
    color: var(--bs-secondary-color);
    font-size: .72rem;
    min-width: 1.5rem;
    padding: .1rem .4rem;
    text-align: center;
}

.board-tools-nav-item:hover { background: var(--gt-surface-deep); }
.board-tools-nav-item.active { background: var(--p-primary-color); color: var(--p-primary-contrast-color); }
.board-tools-nav-item.active i { opacity: 1; }

.board-tools-nav-item.active .board-tools-nav-count {
    background: color-mix(in srgb, var(--p-primary-contrast-color) 22%, transparent);
    color: var(--p-primary-contrast-color);
}

/* min-height: 0 toglie il minimo automatico dell'elemento di griglia, che
   altrimenti impedisce alla colonna di rimpicciolirsi e quindi di scorrere. */
.board-tools-content { min-height: 0; overflow-y: auto; padding: 1.25rem; }

.board-tool-grid {
    align-items: start;
    display: grid;
    gap: 1rem;
    grid-template-columns: minmax(0, 1fr) minmax(280px, 1fr);
}

/* Ogni blocco di un pannello e una scheda: separa il form dall'elenco */
.board-tool-grid > div,
.board-tool-grid > section,
.board-tool-stack > section {
    background: var(--gt-surface);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-lg);
    padding: 1rem;
}

/* Colonna di schede corte: senza questa la griglia allineerebbe ogni scheda a
   una riga propria, e accanto a una scheda alta resterebbe un vuoto. Il
   contenitore non e una scheda a sua volta: annulla lo sfondo ereditato sopra. */
.board-tool-grid > .board-tool-stack {
    background: none;
    border: 0;
    display: grid;
    gap: 1rem;
    padding: 0;
}

/* Riferimenti tabellari: due colonne strette li renderebbero illeggibili */
.board-tool-grid > .board-tool-card-wide { grid-column: 1 / -1; }

/* Riferimento lungo richiudibile: aperto di default riempirebbe il pannello e
   allontanerebbe i comandi che si usano davvero. */
.board-tool-details > summary {
    cursor: pointer;
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: .25rem .75rem;
}

.board-tool-details > summary:focus-visible {
    border-radius: var(--p-border-radius-sm);
    outline: 2px solid var(--p-focus-ring-color);
    outline-offset: 2px;
}

.board-tool-card-head {
    align-items: center;
    display: flex;
    gap: .75rem;
    justify-content: space-between;
    margin-bottom: .85rem;
}

/* Righe degli stati con colore configurabile */
.board-state-list { display: grid; gap: .5rem; }

.board-state-row {
    align-items: center;
    background: var(--gt-surface);
    border: 1px solid var(--gt-border);
    border-left: 3px solid var(--state-accent, var(--gt-border));
    border-radius: var(--p-border-radius-md);
    display: flex;
    gap: .5rem;
    padding: .5rem .6rem;
}

/* Il colore si salva da solo: durante la richiesta la riga resta smorzata */
.board-state-row.is-saving { opacity: .6; }
.board-state-row.is-saving .board-state-dot { animation: pulseGlow 1s ease-in-out infinite; }

.board-state-grip { color: var(--bs-secondary-color); cursor: grab; display: inline-flex; }
.board-state-grip:active { cursor: grabbing; }

.board-state-form { align-items: center; display: flex; flex-wrap: wrap; gap: .5rem; min-width: 0; }

/* Gli interruttori vanno su una riga propria sotto il nome: in fila con lui
   schiacciavano il campo fino a renderlo illeggibile. */
.board-state-flags {
    display: flex;
    flex: 1 0 100%;
    flex-wrap: wrap;
    gap: .25rem .9rem;
    order: 1;
    /* Allineati al nome, oltre il pallino del colore */
    padding-left: calc(1.4rem + .5rem);
}
.board-state-form .form-control,
.board-state-form .p-inputtext { flex: 1 1 auto; min-width: 0; }

.board-state-count {
    background: var(--gt-surface-alt);
    border-radius: var(--p-border-radius-full);
    color: var(--bs-secondary-color);
    flex: 0 0 auto;
    font-size: .75rem;
    min-width: 1.75rem;
    padding: .15rem .45rem;
    text-align: center;
}

/* Interruttore "colonna di completamento": compatto, accanto al nome */
.board-state-done {
    align-items: center;
    color: var(--bs-secondary-color);
    cursor: pointer;
    display: inline-flex;
    flex: 0 0 auto;
    font-size: .75rem;
    gap: .3rem;
    margin: 0;
    white-space: nowrap;
}
.board-state-done .form-check-input { margin: 0; }
.board-state-done:has(:checked) { color: var(--p-green-600, #16a34a); font-weight: 600; }

.board-state-color { flex: 0 0 auto; position: relative; }

.board-state-dot {
    background: var(--dot, var(--gt-accent));
    border: 2px solid var(--gt-surface);
    border-radius: var(--p-border-radius-full);
    box-shadow: 0 0 0 1px var(--gt-border);
    cursor: pointer;
    display: block;
    height: 1.4rem;
    padding: 0;
    width: 1.4rem;
}

/* Il tratteggio segnala che lo stato usa ancora la palette automatica */
.board-state-dot.is-auto {
    background: repeating-linear-gradient(45deg,
        var(--dot, var(--gt-accent)) 0 3px,
        var(--gt-surface-alt) 3px 6px);
}

.board-state-dot:focus-visible { outline: 2px solid var(--gt-accent); outline-offset: 2px; }

/* Input nativo tenuto visibile ma impercettibile: alcuni browser rifiutano di
   aprire il selettore colore su un elemento a dimensione zero o nascosto */
.board-state-native {
    bottom: 0;
    height: 1px;
    left: 0;
    opacity: 0;
    pointer-events: none;
    position: absolute;
    width: 1px;
}

.board-state-delete { flex: 0 0 auto; }

/* Popover di scelta colore, ancorato al pallino cliccato */
.board-color-popover {
    background: var(--gt-surface);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-lg);
    box-shadow: var(--gt-shadow-md);
    padding: .6rem;
    position: fixed;
    width: 196px;
    z-index: 1080;
}

.board-color-popover-grid { display: grid; gap: .35rem; grid-template-columns: repeat(5, 1fr); }

.board-color-swatch {
    background: var(--swatch);
    border: 2px solid transparent;
    border-radius: var(--p-border-radius-full);
    cursor: pointer;
    height: 26px;
    transition: transform .12s;
    width: 26px;
}

.board-color-swatch:hover { transform: scale(1.15); }

/* Le azioni sono impilate: affiancate, un'etichetta lunga sborderebbe dal popover */
.board-color-popover-actions {
    border-top: 1px solid var(--gt-border);
    display: grid;
    gap: .1rem;
    margin-top: .55rem;
    padding-top: .45rem;
}

.board-color-action {
    background: transparent;
    border: 0;
    border-radius: var(--p-border-radius-sm);
    color: var(--gt-accent);
    font-size: .8125rem;
    padding: .3rem .4rem;
    text-align: left;
    width: 100%;
}

.board-color-action:hover { background: var(--gt-surface-alt); }
.board-color-action:focus-visible { outline: 2px solid var(--gt-accent); outline-offset: -2px; }

/* ── Moduli dei filtri e delle viste ──
   Le colonne fisse di Bootstrap qui non funzionavano: dentro il modale la
   colonna del modulo vale poco piu di 400px, e quattro select affiancate
   tagliavano le etichette a meta ("Tutti gli st…"). La griglia si adatta:
   ogni campo non scende sotto i 190px, e le colonne diventano una, due o
   quattro secondo lo spazio disponibile. */
.board-filter-fields {
    display: grid;
    gap: .75rem;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    margin-bottom: .75rem;
}

.board-filter-field { display: grid; gap: .3rem; min-width: 0; }

.board-filter-field > span {
    color: var(--bs-secondary-color);
    font-size: .8125rem;
    font-weight: 600;
}

/* Nome e descrizione hanno bisogno di piu spazio delle select: occupano due
   colonne dove ce ne sono almeno due, e tutta la riga quando ce n'e una. */
.board-filter-field-wide { grid-column: span 2; }

@media (max-width: 575.98px) {
    .board-filter-field-wide { grid-column: auto; }
}

/* Il testo lungo di un'opzione non deve allargare la select oltre la colonna:
   senza questo la griglia si allarga e il modale scorre in orizzontale. */
.board-filter-field .form-select,
.board-filter-field .form-control { max-width: 100%; min-width: 0; }

.board-filter-legend {
    color: var(--bs-secondary-color);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .04em;
    margin: 1rem 0 .5rem;
    text-transform: uppercase;
}

.board-filter-actions {
    align-items: center;
    border-top: 1px solid var(--gt-border);
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    justify-content: space-between;
    margin-top: .25rem;
    padding-top: .75rem;
}

/* Le due date di un intervallo stanno affiancate quando c'e spazio: impilate
   occupavano il doppio dell'altezza di una select accanto. */
.board-date-pair {
    display: grid;
    gap: .375rem;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
}

.board-date-pair span { color: var(--bs-secondary-color); font-size: .8125rem; }

.board-compact-list { display: grid; gap: .5rem; }

.board-compact-row {
    align-items: center;
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-md);
    display: flex;
    gap: .75rem;
    justify-content: space-between;
    padding: .625rem .75rem;
}

.board-row-actions { display: flex; flex-wrap: wrap; gap: .375rem; justify-content: flex-end; }

/* Pagine aperte da un link di condivisione */
.share-header { background: var(--gt-surface); border-bottom: 1px solid var(--gt-border); padding: .75rem 0; }
.share-password { max-width: 420px; margin-top: 10vh; }
.share-task { max-width: 820px; }
.share-new-task summary { cursor: pointer; list-style: none; }
.share-new-task summary::-webkit-details-marker { display: none; }
.share-link-url { font-family: var(--bs-font-monospace); font-size: .75rem; }

/* Registro consegne di un webhook: una riga per consegna, esito in evidenza */
.webhook-row { align-items: flex-start; }
.webhook-deliveries { display: grid; font-size: .75rem; gap: .25rem; list-style: none; margin: .5rem 0 0; padding: 0; }
.webhook-delivery { align-items: baseline; display: flex; flex-wrap: wrap; gap: .25rem .5rem; }
.webhook-delivery-status {
    border-radius: var(--p-border-radius-full);
    font-weight: 600;
    padding: 0 .4rem;
}
.webhook-delivery.is-success .webhook-delivery-status { background: rgba(34, 197, 94, .15); color: var(--p-green-700, #15803d); }
.webhook-delivery.is-failed .webhook-delivery-status { background: rgba(239, 68, 68, .15); color: var(--p-red-700, #b91c1c); }
.webhook-delivery.is-pending .webhook-delivery-status { background: var(--gt-surface-alt); color: var(--bs-secondary-color); }
.webhook-delivery-error { overflow-wrap: anywhere; }

.board-checkbox-list { display: flex; flex-wrap: wrap; gap: .75rem 1rem; }
.board-checkbox-list label { align-items: center; display: inline-flex; gap: .375rem; margin-bottom: 0; }

.board-view-tabs { display: flex; flex-wrap: wrap; gap: .5rem; }

/* Barra delle azioni di massa.
   Flottante in basso e non sopra la vista: in Kanban la selezione si fa
   scorrendo le colonne, e una barra in cima alla pagina sparirebbe proprio
   mentre si sceglie. */
.bulk-bar {
    align-items: center;
    background: var(--gt-surface);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-lg);
    bottom: 1rem;
    box-shadow: var(--gt-shadow-lg, 0 .5rem 1.5rem rgba(0, 0, 0, .18));
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    left: 50%;
    max-width: calc(100vw - 2rem);
    padding: .6rem .8rem;
    position: fixed;
    transform: translateX(-50%);
    width: max-content;
    z-index: 1040;
}

.bulk-bar .form-select,
.bulk-bar .form-control { width: auto; }
.bulk-param { align-items: center; display: flex; flex-wrap: wrap; gap: .5rem; }
.bulk-bar .bulk-date-value { width: 8.5rem; }
.bulk-date-shift { align-items: center; display: inline-flex; gap: .35rem; }
.bulk-date-shift .form-control { width: 6rem; }
.bulk-bar-actions { align-items: center; display: flex; gap: .25rem; }
.bulk-count { color: var(--bs-secondary-color); font-size: .85rem; margin-right: .25rem; }
.bulk-cell { width: 2.5rem; }
.bulk-cell .form-check-input { cursor: pointer; margin: 0; }

/* Spazio in fondo alla pagina: la barra non deve coprire le ultime card. */
.board-view.has-bulk-selection { padding-bottom: 6rem !important; }

.bulk-picker-toggle { max-width: 14rem; overflow: hidden; text-align: left; text-overflow: ellipsis; white-space: nowrap; }
.bulk-picker-menu { max-height: 16rem; min-width: 12rem; overflow-y: auto; }
.bulk-picker-item { align-items: center; cursor: pointer; display: flex; gap: .5rem; }
.bulk-picker-item .form-check-input { margin: 0; }
.bulk-picker-swatch { border-radius: 50%; display: inline-block; flex-shrink: 0; height: .65rem; width: .65rem; }

/* Caselle su card e righe: fuori dal flusso finché non si entra in
   selezione. Nasconderle solo alla vista (opacity) lascerebbe il loro posto
   vuoto e il titolo spostato a destra; mostrarle al passaggio del mouse
   farebbe saltare il titolo a ogni card sorvolata. Si accendono con il
   pulsante «Seleziona», raggiungibile anche da tastiera. */
.task-card-check,
.bulk-scope,
.board-list-row.has-bulk-check > .bulk-check {
    cursor: pointer;
    display: none;
    margin: .2rem 0 0;
}
.bulk-scope,
.board-list-row.has-bulk-check > .bulk-check { margin: 0; }

/* «Tutta la bacheca»: segue le caselle, compare solo in selezione. */
.bulk-scope-all {
    align-items: center;
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-md, .375rem);
    cursor: pointer;
    display: none;
    font-size: .875rem;
    gap: .4rem;
    margin: 0;
    padding: .375rem .75rem;
    white-space: nowrap;
}
.bulk-scope-all .form-check-input { margin: 0; }
.bulk-scope-all.is-visible,
.is-bulk-selecting .bulk-scope-all,
.has-bulk-selection .bulk-scope-all { display: inline-flex; }

/* La riga della Lista va nominata per intero: la regola che la nasconde ha
   tre classi, e una regola di selezione più corta perderebbe il confronto,
   lasciando la casella invisibile anche in modalità selezione. */
.is-bulk-selecting .task-card-check,
.has-bulk-selection .task-card-check,
.is-bulk-selecting .bulk-scope,
.has-bulk-selection .bulk-scope,
.is-bulk-selecting .board-list-row.has-bulk-check > .bulk-check,
.has-bulk-selection .board-list-row.has-bulk-check > .bulk-check { display: block; }

.is-bulk-selecting .board-list-row.has-bulk-check,
.has-bulk-selection .board-list-row.has-bulk-check {
    grid-template-columns: auto minmax(0, 1fr) 5.5rem 7rem 8.5rem 9.5rem 6rem;
}

/* Contorno e non bordo: il bordo sinistro della card porta la priorità. */
.task-card.is-bulk-selected,
.board-list-row.is-bulk-selected {
    outline: 2px solid var(--p-primary-color, var(--bs-primary));
    outline-offset: 1px;
}
/* Sul telefono la riga va su una colonna: la casella resta a sinistra e il
   resto si impila accanto a lei. */
/* Sotto i 992 punti la riga è una fila flessibile: la casella si mette in
   testa al titolo e il resto scorre sotto, senza colonne da ridefinire. */
@media (max-width: 991.98px) {
    .board-list-row.has-bulk-check > .bulk-check { align-self: start; margin-top: .35rem; }
    .is-bulk-selecting .board-list-row.has-bulk-check .board-list-main,
    .has-bulk-selection .board-list-row.has-bulk-check .board-list-main { flex: 1 1 calc(100% - 2rem); }
}

tr.is-bulk-selected > td { background-color: color-mix(in srgb, var(--p-primary-color, var(--bs-primary)) 8%, transparent); }

@media (max-width: 575.98px) {
    .bulk-bar { align-items: stretch; bottom: .5rem; flex-direction: column; width: calc(100vw - 1rem); max-width: none; }
    .bulk-param { align-items: stretch; flex-direction: column; }
    .bulk-bar .form-select,
    .bulk-bar .form-control,
    .bulk-bar .bulk-date-value,
    .bulk-picker-toggle { max-width: none; width: 100%; }
    .bulk-bar-actions { justify-content: space-between; }
}

/* ============================================================
   List View
   ============================================================ */
.board-list-view { display: grid; gap: .5rem; }

/*
 * Una riga, colonne fisse.
 *
 * Le larghezze da scadenza in poi non dipendono dal contenuto: una task senza
 * assegnatari o senza checklist lascia la sua cella vuota invece di far
 * scorrere le altre, e le colonne restano leggibili dall'alto in basso come
 * in una tabella. Solo il titolo prende quel che avanza.
 */
.board-list-row {
    align-items: center;
    animation: fadeSlideIn .2s ease backwards;
    background: var(--gt-surface);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-lg);
    display: grid;
    gap: .5rem .75rem;
    grid-template-columns: minmax(0, 1fr) 5.5rem 7rem 8.5rem 9.5rem 6rem;
    padding: .6rem 1rem;
    transition: box-shadow .15s;
}

.board-list-row:hover { box-shadow: var(--gt-shadow-sm); }

.board-list-main { min-width: 0; }

.board-list-title-row {
    align-items: baseline;
    display: flex;
    gap: .4rem;
    min-width: 0;
}

.board-list-title {
    color: var(--bs-body-color);
    font-weight: 600;
    overflow: hidden;
    text-decoration: none;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.board-list-title:hover { color: var(--gt-accent); }

.board-list-state {
    align-items: center;
    color: var(--bs-secondary-color);
    display: flex;
    font-size: .78rem;
    gap: .4rem;
    margin-top: .1rem;
}

.board-list-due {
    color: var(--bs-secondary-color);
    font-size: .78rem;
    white-space: nowrap;
}

.board-list-due i { line-height: 0; margin-right: .15rem; }

/* La scadenza passata si legge dal colore: in un elenco lungo la data da sola
   costringe a confrontarla con oggi riga per riga. */
.board-list-due.is-overdue { color: var(--bs-danger-text-emphasis); font-weight: 700; }

.board-list-counts {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
}

.board-list-progress {
    align-items: center;
    display: flex;
    gap: .5rem;
    min-width: 0;
}

.board-list-progress .task-progress { flex: 1; margin-top: 0; }

.board-list-progress-value {
    color: var(--bs-secondary-color);
    font-size: .72rem;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
}

.board-list-people { min-width: 0; }
.board-list-people .task-assignees-names { max-width: 100%; }
.board-list-priority { justify-self: end; }

/* Tablet e telefono: il titolo prende la riga, il resto si dispone sotto in
   una fila che va a capo. A colonne fisse su schermo stretto al titolo
   resterebbero due parole. */
@media (max-width: 991.98px) {
    .board-list-row {
        display: flex;
        flex-wrap: wrap;
        gap: .5rem .75rem;
    }

    .board-list-main { flex: 1 1 100%; }
    .board-list-due,
    .board-list-counts,
    .board-list-people { flex: 0 0 auto; }
    .board-list-progress { flex: 0 1 8rem; }
    .board-list-priority { margin-left: auto; }

    /* In colonna una cella vuota lascerebbe un buco in mezzo alla fila: a
       colonne serviva a tenere l'incolonnamento, qui non ha più niente da
       allineare. */
    .board-list-row .is-empty { display: none; }
}

@media (max-width: 575.98px) {
    .board-list-progress { flex: 1 1 100%; order: 1; }
    .board-list-priority { order: 0; }
}

/* ============================================================
   Calendar View
   ============================================================ */
.board-calendar-view {
    display: block;
    width: 100%;
    overflow-x: auto;
}

.board-calendar-item {
    align-content: start;
    background: var(--gt-surface);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-lg);
    display: grid;
    gap: .5rem;
    min-height: 110px;
    padding: .875rem 1rem;
    animation: fadeSlideIn .2s ease backwards;
    transition: box-shadow .15s;
}
.board-calendar-item:hover { box-shadow: var(--gt-shadow-sm); }

.board-calendar-item time {
    color: var(--gt-accent);
    font-size: .8rem;
    font-weight: 600;
}
.board-calendar-item small { color: var(--bs-secondary-color); display: block; }

/* ============================================================
   Table View
   ============================================================ */
.board-table-view {
    background: var(--gt-surface);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-lg);
    box-shadow: var(--gt-shadow-sm);
    padding: .25rem .75rem;
}
.board-table-view .table { margin-bottom: 0; }
.board-table-view thead th {
    font-size: .8rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--bs-secondary-color);
    border-bottom-color: var(--gt-border);
}

/* Chiave, titolo e contatori nella stessa cella: la chiave serve per citare
   la task altrove, i contatori dicono se dietro al titolo c'è altro lavoro. */
.board-table-task {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    min-width: 0;
}

.board-table-task-title { font-weight: 600; text-decoration: none; }

.board-table-progress {
    align-items: center;
    display: flex;
    gap: .5rem;
    min-width: 7rem;
}

.board-table-progress .task-progress { flex: 1; margin-top: 0; }

.board-table-progress-value {
    color: var(--bs-secondary-color);
    font-size: .72rem;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
}

.board-table-due { white-space: nowrap; }

/* Come nella Lista: la data passata si riconosce dal colore, non dal
   confronto mentale con oggi riga per riga. */
.board-table-due.is-overdue { color: var(--bs-danger-text-emphasis); font-weight: 700; }
.board-table-overdue-mark i { line-height: 0; }

/* La colonna dell'avanzamento è l'ultima a servire quando lo schermo si
   stringe: le altre portano nomi e date, questa una sfumatura. */
@media (max-width: 991.98px) {
    .board-table-view .board-table-progress-col { display: none; }
}


/* ── Indice delle bacheche ──────────────────────────────────────── */

/* Lo stile viveva in un registerCss dentro la vista, dove riscriveva a mano
   pulsanti e occhiello che ora arrivano dai fogli globali. Qui convive con il
   resto dei componenti bacheca e legge le stesse variabili di tema. */

.gt-page-header {
    align-items: flex-start;
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    justify-content: space-between;
}

.gt-page-title {
    font-size: 1.9rem;
    font-weight: 800;
    letter-spacing: -.4px;
    line-height: 1.15;
    margin: 0 0 .2rem;
}

.gt-page-subtitle { color: var(--bs-secondary-color); font-size: .9rem; margin: 0; }

/* ── Barra strumenti ── */

.gt-board-toolbar {
    align-items: center;
    background: var(--gt-surface);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-lg);
    box-shadow: var(--gt-shadow-xs);
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
    margin-bottom: 1.5rem;
    padding: .6rem .75rem;
}

/* L'icona sta dentro il campo: un gruppo Bootstrap avrebbe aggiunto un bordo
   in mezzo che qui non serve. */
.gt-board-search {
    align-items: center;
    display: flex;
    flex: 1 1 240px;
    gap: .5rem;
    position: relative;
}

.gt-board-search > i {
    color: var(--p-form-field-icon-color);
    left: .7rem;
    line-height: 0;
    pointer-events: none;
    position: absolute;
}

.gt-board-search .p-inputtext {
    background: var(--p-content-alt-background);
    border-radius: var(--p-border-radius-md);
    padding-left: 2.2rem;
    padding-right: 2.2rem;
}

.gt-board-search-reset {
    background: transparent;
    border: 0;
    color: var(--p-text-muted-color);
    line-height: 0;
    padding: .25rem;
    position: absolute;
    right: .45rem;
}

.gt-board-search-reset:hover { color: var(--p-text-color); }

.gt-board-density { display: flex; gap: .25rem; }

/* ── Stato vuoto ── */

.gt-empty-hero {
    background: var(--gt-surface-alt);
    border: 1.5px dashed var(--gt-border);
    border-radius: var(--p-border-radius-xl);
    margin: 0 auto 2rem;
    max-width: 460px;
    padding: 3rem 1rem;
    text-align: center;
}

.gt-empty-icon { font-size: 3rem; line-height: 1; margin-bottom: .75rem; opacity: .5; }
.gt-empty-hero h2 { font-size: 1.2rem; font-weight: 700; margin-bottom: .5rem; }
.gt-empty-hero p { color: var(--bs-secondary-color); font-size: .9rem; margin: 0; }

/* ── Sezioni per team ── */

.gt-board-teams { display: flex; flex-direction: column; gap: 1.5rem; }

.gt-team-section {
    animation: fadeSlideIn .25s ease backwards;
    background: var(--gt-surface);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-xl);
    box-shadow: var(--gt-shadow-sm);
    overflow: hidden;
}

.gt-team-section--favorites {
    --team-accent: var(--gt-warning);
    margin-bottom: 1.5rem;
}

.gt-team-section-head {
    align-items: center;
    background: linear-gradient(90deg, color-mix(in srgb, var(--team-accent) 6%, transparent) 0%, transparent 60%);
    border-bottom: 1px solid var(--gt-border);
    border-left: 4px solid var(--team-accent);
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    justify-content: space-between;
    padding: 1rem 1.25rem;
}

.gt-team-section.is-collapsed .gt-team-section-head { border-bottom-color: transparent; }

.gt-team-collapse {
    background: transparent;
    border: 0;
    border-radius: var(--p-border-radius-sm);
    color: var(--bs-secondary-color);
    line-height: 0;
    padding: .25rem;
    transition: background-color .15s ease, transform .15s ease;
}

.gt-team-collapse:hover { background: var(--gt-surface-deep); color: var(--bs-body-color); }
.gt-team-section.is-collapsed .gt-team-collapse { transform: rotate(-90deg); }

.gt-team-mini-avatar {
    align-items: center;
    background: color-mix(in srgb, var(--team-accent) 15%, transparent);
    border-radius: var(--p-border-radius-md);
    color: var(--team-accent);
    display: flex;
    flex-shrink: 0;
    font-size: .95rem;
    font-weight: 800;
    height: 38px;
    justify-content: center;
    width: 38px;
}

.gt-team-mini-avatar--favorites i { line-height: 0; }

.gt-team-section-title { font-size: 1rem; font-weight: 700; margin: 0; }
.gt-team-link { color: var(--bs-body-color); }
.gt-team-link:hover { color: var(--team-accent); }
.gt-team-section-desc { color: var(--bs-secondary-color); font-size: .8rem; margin: .1rem 0 0; }

.gt-count-badge {
    background: color-mix(in srgb, var(--team-accent) 12%, transparent);
    border-radius: var(--p-border-radius-full);
    color: var(--team-accent);
    font-size: .7rem;
    font-weight: 700;
    padding: .15rem .55rem;
    white-space: nowrap;
}

/* ── Ordinamento delle bacheche del team ── */

/* Il pulsante mostra l'icona e il nome dell'ordinamento in uso: si legge
   senza aprire il menu. */
.gt-team-sort {
    align-items: center;
    background: var(--gt-surface-alt);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-full);
    color: var(--bs-secondary-color);
    display: inline-flex;
    font-size: .75rem;
    font-weight: 600;
    gap: .4rem;
    line-height: 1;
    padding: .3rem .55rem .3rem .3rem;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease, box-shadow .15s ease;
}

.gt-team-sort:hover,
.gt-team-sort.is-open {
    border-color: color-mix(in srgb, var(--team-accent) 55%, var(--gt-border));
    color: var(--bs-body-color);
}

.gt-team-sort:focus-visible {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--team-accent) 25%, transparent);
    outline: none;
}

.gt-team-sort-icon {
    align-items: center;
    background: color-mix(in srgb, var(--team-accent) 14%, transparent);
    border-radius: var(--p-border-radius-full);
    color: var(--team-accent);
    display: inline-flex;
    height: 1.4rem;
    justify-content: center;
    width: 1.4rem;
}

.gt-team-sort-icon i { font-size: .75rem; line-height: 0; }
.gt-team-sort-caret { font-size: .8rem; line-height: 0; opacity: .7; transition: transform .15s ease; }
.gt-team-sort.is-open .gt-team-sort-caret { transform: rotate(180deg); }

/* Nell'ordine personalizzato il pulsante prende il colore del team: la
   sezione è in una modalità diversa dalle altre, e le card si spostano. */
.gt-team-sort.is-custom {
    background: color-mix(in srgb, var(--team-accent) 12%, var(--gt-surface-alt));
    border-color: color-mix(in srgb, var(--team-accent) 45%, transparent);
    color: var(--team-accent);
}

.gt-team-sort.is-custom .gt-team-sort-icon { background: var(--team-accent); color: var(--gt-surface); }

.gt-sort-menu {
    background: var(--gt-surface);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-lg);
    box-shadow: var(--gt-shadow-md);
    padding: .35rem;
    position: fixed;
    width: 270px;
    z-index: 1080;
    animation: gtSortMenuIn .14s ease;
}

@keyframes gtSortMenuIn {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: none; }
}

.gt-sort-menu-title {
    color: var(--p-text-muted-color);
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .04em;
    padding: .35rem .5rem .4rem;
    text-transform: uppercase;
}

.gt-sort-option {
    align-items: center;
    background: transparent;
    border: 0;
    border-radius: var(--p-border-radius-md);
    color: var(--bs-body-color);
    display: flex;
    gap: .6rem;
    padding: .45rem .5rem;
    text-align: left;
    width: 100%;
}

.gt-sort-option:hover,
.gt-sort-option:focus-visible {
    background: var(--gt-surface-alt);
    outline: none;
}

.gt-sort-option-icon {
    align-items: center;
    background: var(--gt-surface-alt);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-md);
    color: var(--bs-secondary-color);
    display: inline-flex;
    flex-shrink: 0;
    height: 2rem;
    justify-content: center;
    width: 2rem;
}

.gt-sort-option-icon i { line-height: 0; }

.gt-sort-option-text { display: flex; flex: 1; flex-direction: column; gap: .1rem; min-width: 0; }
.gt-sort-option-text strong { font-size: .8125rem; font-weight: 600; }
.gt-sort-option-text small { color: var(--p-text-muted-color); font-size: .72rem; }

.gt-sort-option-check { color: var(--gt-accent); line-height: 0; visibility: hidden; }

.gt-sort-option[aria-checked="true"] .gt-sort-option-icon {
    background: color-mix(in srgb, var(--gt-accent) 14%, transparent);
    border-color: color-mix(in srgb, var(--gt-accent) 40%, transparent);
    color: var(--gt-accent);
}

.gt-sort-option[aria-checked="true"] .gt-sort-option-check { visibility: visible; }

/* Il suggerimento compare solo nell'ordine personalizzato: dice cosa si può
   fare e, dopo un rilascio, che l'ordine è stato salvato. */
.gt-sort-hint {
    align-items: center;
    background: color-mix(in srgb, var(--team-accent) 8%, transparent);
    border: 1px dashed color-mix(in srgb, var(--team-accent) 40%, transparent);
    border-radius: var(--p-border-radius-md);
    color: var(--bs-secondary-color);
    display: flex;
    font-size: .78rem;
    gap: .5rem;
    margin: 1rem 1.25rem 0;
    padding: .5rem .75rem;
    transition: background-color .2s ease, border-color .2s ease, color .2s ease;
}

.gt-sort-hint[hidden] { display: none; }
.gt-sort-hint i { color: var(--team-accent); line-height: 0; }

.gt-sort-hint.is-saved {
    background: color-mix(in srgb, var(--gt-success) 12%, transparent);
    border-color: color-mix(in srgb, var(--gt-success) 45%, transparent);
    border-style: solid;
    color: var(--gt-success);
}

.gt-sort-hint.is-saved i { color: var(--gt-success); }

/* La maniglia prende il posto dell'icona della card. */
.gt-board-card-grip { display: none; }
.gt-board-card.is-sortable .gt-board-card-glyph { display: none; }
.gt-board-card.is-sortable .gt-board-card-grip { display: inline-block; }

.gt-board-card.is-sortable { cursor: grab; }
.gt-board-card.is-sortable .gt-board-card-icon { transition: background-color .15s ease, color .15s ease, transform .15s ease; }

.gt-board-card.is-sortable:hover .gt-board-card-icon {
    background: var(--board-accent);
    color: var(--gt-surface);
    transform: scale(1.06);
}

.gt-board-card.is-sortable:active { cursor: grabbing; }

/* Durante il trascinamento la card resta nella griglia come segnaposto: un
   riquadro tratteggiato del colore della bacheca nel punto in cui cadrà. */
.gt-boards-grid.is-drag-active .gt-board-card:hover { box-shadow: none; transform: none; }

.gt-board-card.is-dragging {
    background: color-mix(in srgb, var(--board-accent) 8%, transparent);
    border: 2px dashed var(--board-accent);
    box-shadow: none;
    transform: none;
}

.gt-board-card.is-dragging > * { opacity: 0; }

.gt-board-card.is-dropped { animation: gtBoardDropped .6s ease; }

@keyframes gtBoardDropped {
    0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--board-accent) 55%, transparent); }
    100% { box-shadow: 0 0 0 10px transparent; }
}

@media (prefers-reduced-motion: reduce) {
    .gt-sort-menu,
    .gt-board-card.is-dropped { animation: none; }
}

.gt-create-board-form { flex-shrink: 0; }
.gt-create-board-input { max-width: 320px; min-width: 220px; }

.gt-create-board-input .p-inputtext {
    background: var(--p-content-alt-background);
    font-size: var(--p-font-size-sm);
}

/* La messa a fuoco prende il colore del team invece dell'accento globale:
   il modulo appartiene a quella sezione, e il colore lo dice. */
.gt-create-board-input:focus-within {
    border-color: var(--team-accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--team-accent) 20%, transparent);
}

/* ── Griglia ── */

.gt-boards-grid {
    display: grid;
    gap: 1rem;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    padding: 1.25rem;
}

.gt-boards-empty {
    color: var(--bs-secondary-color);
    font-size: .875rem;
    margin: 0;
    padding: 1.5rem;
    text-align: center;
}

/* ── Card della bacheca ── */

/* La card e un blocco, non un collegamento: contiene pulsanti, e un
   collegamento non puo contenerne altri. Il richiamo cliccabile e il titolo,
   steso su tutta la card dallo pseudo-elemento piu sotto. */
.gt-board-card {
    animation: fadeSlideIn .2s ease backwards;
    background: var(--gt-surface-alt);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-xl);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    position: relative;
    transition: border-color .15s ease, box-shadow .18s ease, transform .16s ease;
}

.gt-board-card:hover {
    border-color: var(--board-accent);
    box-shadow: var(--gt-shadow-md);
    transform: translateY(-2px);
}

.gt-board-card.is-archived { opacity: .72; }
.gt-board-card.is-archived:hover { opacity: 1; }

.gt-board-card-stripe { background: var(--board-accent); flex-shrink: 0; height: 3px; }

.gt-board-card-body {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: .55rem;
    padding: .9rem 1rem 1rem;
}

.gt-board-card-top {
    align-items: flex-start;
    display: flex;
    gap: .5rem;
    justify-content: space-between;
}

.gt-board-card-icon {
    align-items: center;
    background: color-mix(in srgb, var(--board-accent) 15%, transparent);
    border-radius: var(--p-border-radius-md);
    color: var(--board-accent);
    display: flex;
    flex-shrink: 0;
    height: 34px;
    justify-content: center;
    width: 34px;
}

.gt-board-card-icon i { line-height: 0; }

/* I pulsanti stanno sopra al collegamento steso, altrimenti sarebbero
   irraggiungibili: il richiamo della card li coprirebbe. */
.gt-board-card-tools {
    display: flex;
    gap: .15rem;
    position: relative;
    z-index: 2;
}

.gt-card-tool {
    align-items: center;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--p-border-radius-md);
    color: var(--bs-secondary-color);
    display: inline-flex;
    height: 1.85rem;
    justify-content: center;
    line-height: 0;
    padding: 0;
    text-decoration: none;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease, opacity .15s ease;
    width: 1.85rem;
}

.gt-card-tool:hover,
.gt-card-tool:focus-visible {
    background: var(--gt-surface);
    border-color: var(--gt-border);
    color: var(--bs-body-color);
    outline: none;
}

.gt-card-tool.is-pending { opacity: .5; pointer-events: none; }

.gt-card-tool--favorite.is-active {
    background: var(--bs-warning-bg-subtle);
    border-color: var(--bs-warning-border-subtle);
    color: var(--bs-warning-text-emphasis);
}

.gt-card-color-dot {
    border-radius: var(--p-border-radius-full);
    box-shadow: 0 0 0 1px var(--gt-border);
    display: block;
    height: 1rem;
    width: 1rem;
}

/* A griglia il contenitore non esiste: i suoi figli — titolo, team,
   contrassegni — restano figli della card e la colonna resta quella di
   prima. A elenco diventa una cella sola (più sotto). */
.gt-board-card-head { display: contents; }

.gt-board-card-title {
    font-size: .95rem;
    font-weight: 700;
    line-height: 1.3;
    margin: 0;
}

.gt-board-card-link { color: var(--bs-body-color); text-decoration: none; }
.gt-board-card-link:hover { color: var(--board-accent); }

/* Il richiamo steso rende cliccabile tutta la card mantenendo un solo
   collegamento nell'ordine di tabulazione. */
.gt-board-card-link::after {
    content: '';
    inset: 0;
    position: absolute;
    z-index: 1;
}

.gt-board-card-team { color: var(--bs-secondary-color); font-size: .75rem; margin: -.3rem 0 0; }

.gt-board-badge {
    align-self: flex-start;
    border-radius: var(--p-border-radius-full);
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .03em;
    padding: .1rem .45rem;
    text-transform: uppercase;
}

.gt-board-badge--archived {
    background: var(--gt-surface-deep);
    color: var(--bs-secondary-color);
}

/* ── Avanzamento ── */

.gt-board-progress-row {
    align-items: center;
    display: flex;
    gap: .5rem;
    margin-top: auto;
}

.gt-board-progress {
    background: var(--gt-surface-deep);
    border-radius: var(--p-border-radius-full);
    flex: 1;
    height: 5px;
    overflow: hidden;
}

.gt-board-progress-bar {
    background: linear-gradient(90deg, color-mix(in srgb, var(--board-accent) 70%, white), var(--board-accent));
    border-radius: var(--p-border-radius-full);
    display: block;
    height: 100%;
    transition: width .4s ease;
}

.gt-board-progress-value {
    color: var(--bs-secondary-color);
    font-size: .72rem;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
}

.gt-board-progress-empty { color: var(--bs-secondary-color); font-size: .75rem; }

/* ── Numeri, scadenze, volti ── */

.gt-board-card-stats {
    align-items: center;
    color: var(--bs-secondary-color);
    display: flex;
    flex-wrap: wrap;
    font-size: .75rem;
    gap: .4rem;
}

.gt-stat-dot {
    background: var(--bs-secondary-color);
    border-radius: var(--p-border-radius-full);
    flex-shrink: 0;
    height: 3px;
    opacity: .5;
    width: 3px;
}

.gt-board-pill {
    align-items: center;
    border-radius: var(--p-border-radius-full);
    display: inline-flex;
    font-size: .7rem;
    font-weight: 700;
    gap: .2rem;
    padding: .1rem .45rem;
}

.gt-board-pill i { line-height: 0; }

.gt-board-pill--overdue {
    background: var(--bs-danger-bg-subtle);
    color: var(--bs-danger-text-emphasis);
}

.gt-board-pill--soon {
    background: var(--bs-warning-bg-subtle);
    color: var(--bs-warning-text-emphasis);
}

.gt-board-card-foot {
    align-items: center;
    display: flex;
    gap: .5rem;
    justify-content: space-between;
}

/* I volti si sovrappongono: quattro affiancati occuperebbero la riga intera. */
.gt-avatar-stack { display: flex; padding-left: .35rem; }

.gt-avatar-chip {
    align-items: center;
    background: var(--gt-surface-deep);
    border: 2px solid var(--gt-surface-alt);
    border-radius: var(--p-border-radius-full);
    color: var(--bs-secondary-color);
    display: flex;
    font-size: .65rem;
    font-weight: 800;
    height: 1.6rem;
    justify-content: center;
    margin-left: -.35rem;
    overflow: hidden;
    width: 1.6rem;
}

.gt-avatar-chip img { height: 100%; object-fit: cover; width: 100%; }

.gt-board-card-activity {
    color: var(--bs-secondary-color);
    font-size: .7rem;
    margin-left: auto;
    white-space: nowrap;
}

/* ── Densità a elenco ── */

/* A elenco la card diventa una riga: sopra la quindicina di bacheche la
   griglia costringe a scorrere per leggere nomi che starebbero in colonna.

   Le colonne sono assegnate una per una e non lasciate al posizionamento
   automatico: la card ha pezzi facoltativi — team, contrassegni, volti — e
   lasciarli scorrere riempirebbe le colonne in un ordine diverso da card a
   card, che è quel che rompeva la riga. Le righe sono dichiarate esplicite
   perché `grid-row: 1 / -1` conta le linee della griglia esplicita: senza
   `grid-template-rows` l'intervallo degenererebbe. */
.board-index.is-list-density .gt-boards-grid { grid-template-columns: 1fr; gap: .5rem; }

.board-index.is-list-density .gt-board-card { flex-direction: row; }
.board-index.is-list-density .gt-board-card:hover { transform: none; }
.board-index.is-list-density .gt-board-card-stripe { height: auto; width: 3px; }

.board-index.is-list-density .gt-board-card-body {
    align-items: center;
    display: grid;
    gap: .35rem .75rem;
    /* Dalla terza colonna in poi le larghezze sono fisse e non dettate dal
       contenuto: numeri, volti e strumenti cambiano da bacheca a bacheca —
       una pillola di scadenza in più, un assegnatario in meno — e con le
       tracce a contenuto ogni riga faceva partire la barra in un punto
       diverso. Fissandole, la colonna del titolo assorbe da sola la
       differenza e le barre restano incolonnate. */
    grid-template-columns:
        auto                /* 1 icona */
        minmax(0, 1fr)      /* 2 titolo, team, contrassegni */
        minmax(0, 11rem)    /* 3 avanzamento e percentuale */
        minmax(0, 14rem)    /* 4 numeri */
        minmax(0, 9.5rem)   /* 5 volti e ultima attività */
        minmax(0, 8rem);    /* 6 strumenti */
    grid-template-rows: auto;
    padding: .55rem 1rem;
}

/* Il contenitore sparisce e i suoi due figli — icona e strumenti — diventano
   celle della riga: stanno ai due capi, non appaiati a sinistra. */
.board-index.is-list-density .gt-board-card-top { display: contents; }

.board-index.is-list-density .gt-board-card-icon { grid-area: 1 / 1 / -1 / 2; }
.board-index.is-list-density .gt-board-card-head { grid-area: 1 / 2 / -1 / 3; }
.board-index.is-list-density .gt-board-progress-row { grid-area: 1 / 3 / -1 / 4; margin: 0; }
.board-index.is-list-density .gt-board-card-stats { grid-area: 1 / 4 / -1 / 5; }
.board-index.is-list-density .gt-board-card-foot { grid-area: 1 / 5 / -1 / 6; }
.board-index.is-list-density .gt-board-card-tools { grid-area: 1 / 6 / -1 / 7; }

.board-index.is-list-density .gt-board-card-head {
    display: flex;
    flex-direction: column;
    gap: .15rem;
    min-width: 0;
}

.board-index.is-list-density .gt-board-card-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.board-index.is-list-density .gt-board-card-team { margin: 0; }
.board-index.is-list-density .gt-board-card-chips { margin-bottom: 0 !important; }

/* I numeri restano su una riga: andando a capo alzerebbero la card e la
   colonna successiva perderebbe l'allineamento con le altre bacheche. */
.board-index.is-list-density .gt-board-card-stats { flex-wrap: nowrap; white-space: nowrap; }
.board-index.is-list-density .gt-board-card-foot { gap: .6rem; justify-content: flex-end; }

/* Colonne a larghezza fissa: quel che contengono si appoggia al bordo
   destro, così il vuoto di una bacheca con meno strumenti o meno volti non
   si apre in mezzo alla riga. */
.board-index.is-list-density .gt-board-card-stats { justify-content: flex-end; }
.board-index.is-list-density .gt-board-card-tools { justify-content: flex-end; }
.board-index.is-list-density .gt-board-card-activity { margin-left: 0; }

/* Tablet in orizzontale e finestre strette: la riga resta una, con meno
   respiro fra le colonne. */
@media (max-width: 1199.98px) {
    .board-index.is-list-density .gt-board-card-body {
        gap: .3rem .6rem;
        grid-template-columns:
            auto
            minmax(0, 1fr)
            minmax(0, 9rem)
            minmax(0, 12rem)
            minmax(0, 8.5rem)
            minmax(0, 8rem);
    }

    .board-index.is-list-density .gt-board-card-stats { font-size: .72rem; }
}

/* Tablet in verticale e telefono in orizzontale: due righe. Sopra il nome
   con gli strumenti, sotto avanzamento, numeri e volti — comprimere tutto su
   una riga lascerebbe al titolo una manciata di caratteri.

   Il limite inferiore è dichiarato: sotto i 768 punti l'elenco è una riga
   stretta, e quella la disegna `responsive.css` insieme alle altre scelte di
   quella soglia. */
@media (min-width: 768px) and (max-width: 991.98px) {
    .board-index.is-list-density .gt-board-card-body {
        gap: .45rem .9rem;
        grid-template-columns: auto minmax(0, 11rem) minmax(0, 1fr) minmax(0, 8rem);
        grid-template-rows: auto auto;
    }

    .board-index.is-list-density .gt-board-card-icon { grid-area: 1 / 1 / -1 / 2; }
    .board-index.is-list-density .gt-board-card-head { grid-area: 1 / 2 / 2 / 4; }
    .board-index.is-list-density .gt-board-card-tools { grid-area: 1 / 4 / 2 / 5; }
    .board-index.is-list-density .gt-board-progress-row { grid-area: 2 / 2 / 3 / 3; }
    /* Qui la colonna è stretta e i numeri possono essere tanti: a capo dentro
       la propria cella, invece di sconfinare su volti e ultima attività. */
    .board-index.is-list-density .gt-board-card-stats {
        flex-wrap: wrap;
        grid-area: 2 / 3 / 3 / 4;
        justify-content: flex-end;
        white-space: normal;
    }
    .board-index.is-list-density .gt-board-card-foot { grid-area: 2 / 4 / 3 / 5; }

    .board-index.is-list-density .gt-board-card-chips { margin-top: .15rem; }
}


/* ── Selettore colore ── */

.gt-color-popover {
    background: var(--gt-surface);
    border: 1px solid var(--gt-border);
    border-radius: var(--p-border-radius-lg);
    box-shadow: var(--gt-shadow-md);
    padding: .6rem;
    position: fixed;
    width: 196px;
    z-index: 1080;
}

.gt-color-popover-grid { display: grid; gap: .35rem; grid-template-columns: repeat(5, 1fr); }

.gt-color-swatch {
    background: var(--swatch);
    border: 2px solid transparent;
    border-radius: var(--p-border-radius-full);
    height: 26px;
    transition: transform .12s ease;
    width: 26px;
}

.gt-color-swatch:hover { transform: scale(1.15); }
.gt-color-swatch:focus-visible { outline: 2px solid var(--gt-accent); outline-offset: 2px; }

.gt-color-popover-actions {
    border-top: 1px solid var(--gt-border);
    margin-top: .55rem;
    padding-top: .45rem;
}

.gt-color-action {
    background: transparent;
    border: 0;
    border-radius: var(--p-border-radius-sm);
    color: var(--gt-accent);
    font-size: .8125rem;
    padding: .3rem .4rem;
    text-align: left;
    width: 100%;
}

.gt-color-action:hover { background: var(--gt-surface-alt); }

/* Conteggi della card: checklist, sotto-task e appartenenza a un padre.
   Stessa forma della pillola di priorita, tinta neutra: sono numeri di
   contesto, non una gravita da segnalare. */
.task-card-count {
    align-items: center;
    background: var(--p-content-alt-background);
    border-radius: var(--p-border-radius-full);
    color: var(--p-text-muted-color);
    display: inline-flex;
    font-size: .68rem;
    font-weight: 600;
    gap: .2rem;
    padding: .1rem .45rem;
}

/* Il menu dei modelli sta nello stesso gruppo del titolo, ma non deve
   rubargli spazio: il titolo resta il campo che si allarga. */
.gt-create-board-template {
    flex: 0 0 auto;
    max-width: 11rem;
}

.gt-create-board-copy {
    align-items: center;
    color: var(--p-text-muted-color);
    display: flex;
    font-size: .78rem;
    gap: .35rem;
    margin-top: .35rem;
}

/* display: flex vincerebbe sull'attributo hidden. */
.gt-create-board-copy[hidden] {
    display: none;
}

.gt-create-board-link {
    color: var(--p-text-muted-color);
    font-size: .78rem;
    margin-top: .35rem;
}
