/* =============================================================================
 * SCHEDA PRODOTTO PDF - FRONT OFFICE E BACK OFFICE
 * webroot/css/product-sheet.css
 * -----------------------------------------------------------------------------
 * Il foglio condiviso della scheda prodotto in PDF, caricato dalle pagine che
 * la scaricano o la generano, in tutte e due le aree:
 *
 *   /products/view                          Front Office (pulsante e finestra
 *                                           dei documenti)
 *   /products/admin-view-product            Back Office, riquadro SCHEDA PRODOTTO
 *   /products/admin-edit-product            Back Office, riquadro SCHEDA PRODOTTO
 *   /products/admin-products-list,          Back Office, finestra CREAZIONE
 *   /products/admin-products-list-filtered, MASSIVA DELLE SCHEDE PRODOTTO
 *   /products/admin-search
 *
 * Va insieme a webroot/js/product-sheet.js, che accende e spegne gli stati, e
 * ai due element che portano il markup: products/product_sheet_wait_mask e
 * modals/products-bo/generate_products_sheets_ranges.
 *
 * I COLORI. Il foglio vive in due aree con due fogli generali diversi, quindi
 * non si appoggia ai gettoni di nessuna pagina: il colore d'accento e' la
 * variabile --primary-color del portale, con il ripiego #16688B, che e' lo
 * stesso blu d'accento del Front Office e dei pulsanti del Back Office.
 * I prefissi delle classi - ps- per la maschera, psg- per la generazione
 * massiva - non si sovrappongono a nessun foglio del portale.
 *
 * LE MISURE SONO IN PIXEL: il corpo base del Front Office non e' 16px ma
 * circa 10 (font-size: 62.5%), quello del Back Office si': le misure in rem
 * darebbero due maschere di grandezza diversa.
 * ========================================================================== */


/* =============================================================================
 * 1. LA MASCHERA D'ATTESA DELLO SCARICO
 * -----------------------------------------------------------------------------
 * La generazione della scheda impiega qualche secondo, e prima il navigatore
 * apriva una scheda nera e vuota. Adesso resta la pagina, velata, e al centro
 * un riquadro con la rotella e la scritta GENERAZIONE DELLA SCHEDA PRODOTTO IN
 * CORSO. La accende e la spegne generateProductSheet().
 *
 * STA SOPRA TUTTO: le finestre di Bootstrap stanno fra 1040 e 1050, le testate
 * del portale sotto le finestre. 20000 lascia margine a qualunque livello, e la
 * maschera copre anche la finestra dei documenti quando il clic parte da li'.
 *
 * DUE STATI, UNA SOLA MASCHERA. .ps-mask-on la accende con la rotella; se la
 * generazione fallisce lo script aggiunge .ps-mask-ko, e al posto della rotella
 * compaiono il messaggio d'errore e il pulsante CHIUDI.
 * ========================================================================== */

.ps-mask {
    position: fixed;
    inset: 0;
    z-index: 20000;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background-color: rgba(17, 42, 70, 0.42);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
    /* Un doppio clic sul pulsante non seleziona la scritta della maschera (17/10/2026). */
    -webkit-user-select: none;
    user-select: none;
}

.ps-mask.ps-mask-on {
    display: flex;
}

.ps-mask-box {
    box-sizing: border-box;
    width: 100%;
    /* 480 e non meno: la scritta dell'attesa, in maiuscolo e spaziata, ci sta
       su una riga sola; su un telefono va a capo, e va a capo bilanciata */
    max-width: 480px;
    padding: 26px 26px 24px;
    background-color: #ffffff;
    border-radius: 12px;
    box-shadow: 0 2px 6px rgba(17, 42, 70, 0.10), 0 16px 44px rgba(17, 42, 70, 0.22);
    color: #112A46;
    text-align: center;
}

.ps-mask-attesa,
.ps-mask-errore {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
}

.ps-mask-errore { display: none; }
.ps-mask-ko .ps-mask-attesa { display: none; }
.ps-mask-ko .ps-mask-errore { display: flex; }

/* La rotella: un cerchio con un quarto di bordo di colore diverso che gira.
   La prima dichiarazione del bordo e' il ripiego per i navigatori senza
   color-mix. */
.ps-ruota {
    flex: 0 0 auto;
    box-sizing: border-box;
    width: 44px;
    height: 44px;
    border: 4px solid rgba(22, 104, 139, 0.18);
    border: 4px solid color-mix(in srgb, var(--primary-color, #16688B) 18%, transparent);
    border-top-color: var(--primary-color, #16688B);
    border-radius: 50%;
    animation: ps-gira 0.8s linear infinite;
}

@keyframes ps-gira {
    to { transform: rotate(360deg); }
}

.ps-mask-testo {
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 0.04em;
    line-height: 1.45;
    text-wrap: balance;
}

.ps-mask-attesa .ps-mask-testo {
    color: var(--primary-color, #16688B);
}

/* Il messaggio d'errore e' una frase, non un titolo: niente maiuscolo largo. */
.ps-mask-errore .ps-mask-testo {
    font-weight: 600;
    letter-spacing: 0;
}

.ps-mask-errore > i {
    color: #d0342c;
    font-size: 30px;
}

.ps-mask-chiudi {
    min-width: 120px;
    padding: 8px 18px;
    background-color: var(--primary-color, #16688B);
    border: 0;
    border-radius: 7px;
    color: #ffffff;
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: 0.03em;
    cursor: pointer;
    transition: box-shadow 0.16s ease;
}

.ps-mask-chiudi:hover,
.ps-mask-chiudi:focus-visible {
    outline: 0;
    box-shadow: 0 0 0 3px rgba(22, 104, 139, 0.28);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary-color, #16688B) 28%, transparent);
}

/* Chi ha chiesto meno animazioni vede la rotella ferma: a dire che si sta
   lavorando e' la scritta. */
@media (prefers-reduced-motion: reduce) {
    .ps-ruota { animation: none; }
}


/* =============================================================================
 * 2. LA GENERAZIONE MASSIVA CON LA BARRA DI AVANZAMENTO
 * -----------------------------------------------------------------------------
 * Nella finestra CREAZIONE MASSIVA DELLE SCHEDE PRODOTTO. La finestra ha sei
 * stati, scritti come classe da productSheetsGenerationState():
 *
 *   psg-idle      prima dell'avvio: spiegazione e casella di ripartenza
 *   psg-running   in corso: barra, contatore, ultimo codice, tempo stimato
 *   psg-stopping  interruzione chiesta: si attende la fine del blocco in corso
 *   psg-done      finita
 *   psg-stopped   interrotta
 *   psg-failed    fermata da un errore di comunicazione
 *   psg-busy      non partita: un altro operatore ha una generazione in corso
 *
 * Le parti del corpo portano una classe per ogni stato in cui compaiono
 * (psg-per-idle, psg-per-running, ...): una parte e' nascosta finche' la
 * finestra non e' in uno dei suoi stati. Il resoconto degli errori compare
 * solo se ce ne sono (psg-con-errori).
 * ========================================================================== */

.psg-parte { display: none; }

.psg-idle     .psg-per-idle,
.psg-running  .psg-per-running,
.psg-stopping .psg-per-stopping,
.psg-done     .psg-per-done,
.psg-stopped  .psg-per-stopped,
.psg-failed   .psg-per-failed,
.psg-busy     .psg-per-busy {
    display: block;
}

/* Le frasi che cambiano con la modalita': la finestra porta psg-mode-all o
   psg-mode-stale, e ciascuna frase compare solo nella sua. */
.psg-mode-all   .psg-solo-stale,
.psg-mode-stale .psg-solo-all {
    display: none;
}

.psg-errori { display: none; }
.psg-con-errori:not(.psg-idle):not(.psg-running):not(.psg-stopping) .psg-errori { display: block; }

.psg-corpo {
    color: #112A46;
    font-size: 12px;
    line-height: 1.5;
    text-align: left;
}

.psg-corpo p {
    margin: 0 0 10px;
}

/* Dimensioni dei caratteri della finestra (17/10/2026: tutte 1px piu' piccole di prima).
 * Il tema del Back Office porta a 14px ogni paragrafo dentro .text-content-modal: con
 * l'id della finestra queste regole vincono e la gerarchia resta quella voluta -
 * testo e titoli 13px, note 12px. */
#modal_products_sheet_generation_ranges .psg-corpo p { font-size: 13px; }
#modal_products_sheet_generation_ranges .psg-corpo .psg-avviso-titolo,
#modal_products_sheet_generation_ranges .psg-corpo .psg-opzione-titolo { font-size: 13px; }
#modal_products_sheet_generation_ranges .psg-corpo .psg-nota,
#modal_products_sheet_generation_ranges .psg-corpo .psg-posizione-oltre { font-size: 12px; }

/* --- L'avviso in testa ---------------------------------------------------------
 * Giallo come gli avvisi di Bootstrap, ma con il suo disegno: un'icona grande
 * a sinistra e il testo a destra, perche' e' la prima cosa da leggere e deve
 * staccarsi dalle due modalita' che seguono. */
.psg-avviso {
    display: flex;
    gap: 14px;
    margin-bottom: 16px;
    padding: 14px 16px;
    background-color: #fff6e0;
    border: 1px solid #f0d58a;
    border-left: 5px solid #e0a800;
    border-radius: 8px;
    color: #5c4300;
}

.psg-avviso-icona {
    flex: 0 0 auto;
    margin-top: 2px;
    color: #5c4300;
    font-size: 26px;
}

/* Il tema del Back Office colora di bianco le icone della finestra: senza questa
 * regola, piu' forte, il triangolo e' bianco sul giallo e non si vede (17/10/2026).
 * Ha il colore scuro della scritta. */
#modal_products_sheet_generation_ranges .psg-avviso .psg-avviso-icona {
    color: #5c4300 !important;
}

.psg-avviso p {
    margin: 0 0 8px;
}

.psg-avviso .psg-avviso-titolo {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.02em;
}

/* --- Le due modalita' ----------------------------------------------------------
 * Due riquadri uguali, uno sotto l'altro: titolo, spiegazione, i due numeri
 * che contano (prodotti e tempo) e il pulsante. */
.psg-opzione {
    margin-bottom: 14px;
    padding: 14px 16px;
    background-color: #ffffff;
    border: 1px solid #e0e7ed;
    border-left: 4px solid var(--primary-color, #16688B);
    border-radius: 8px;
}

.psg-opzione-titolo {
    color: var(--primary-color, #16688B);
    font-size: 13px;
    font-weight: 700;
}

.psg-dati {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 24px;
    margin: 0 0 10px;
    padding: 8px 10px;
    background-color: #f5f8fa;
    border-radius: 6px;
}

.psg-dati strong {
    color: var(--primary-color, #16688B);
}

.psg-opzione .btn {
    margin-top: 4px;
}

/* Il conteggio non riuscito: il motivo, sotto le due modalita'. */
.psg-conteggio-errore { display: none; }
.psg-conteggio-ko .psg-conteggio-errore {
    display: block;
    margin-bottom: 12px;
    padding: 8px 12px;
    background-color: #fdecea;
    border-radius: 6px;
    color: #8a1f17;
    font-size: 11.5px;
}

/* --- La casella di ripartenza ---------------------------------------------- */
.psg-ripartenza {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    margin: 14px 0 4px;
}

.psg-ripartenza label {
    margin: 0;
    font-weight: 600;
}

.psg-start-position {
    width: 110px;
    padding: 5px 8px;
    border: 1px solid #cfd9e1;
    border-radius: 6px;
    font-size: 12px;
}

.psg-nota {
    color: #5b7488;
    font-size: 11px;
}

/* Posizione oltre i prodotti da trattare (17/10/2026): l'avviso compare sotto la casella
 * solo quando lo script accende psg-posizione-ko sulla finestra, e la casella si colora. */
.psg-posizione-oltre { display: none; }
.psg-posizione-ko .psg-posizione-oltre {
    display: block;
    margin: 6px 0 0;
    color: #8a1f17;
    font-size: 11px;
}
.psg-posizione-ko .psg-start-position {
    border-color: #d9534f;
}

/* --- La barra ----------------------------------------------------------------
 * Una pista grigia e un riempimento in colore d'accento, con una striscia
 * chiara che scorre finche' si lavora: dice che la pagina e' viva anche
 * quando un blocco impiega qualche secondo e la barra non si muove. */
.psg-avanzamento {
    margin: 4px 0 14px;
}

.psg-barra {
    position: relative;
    overflow: hidden;
    height: 14px;
    background-color: #eef2f5;
    border: 1px solid #e0e7ed;
    border-radius: 7px;
}

.psg-barra-piena {
    position: relative;
    width: 0;
    height: 100%;
    overflow: hidden;
    background-color: var(--primary-color, #16688B);
    border-radius: 7px;
    transition: width 0.4s ease;
}

.psg-running .psg-barra-piena::after,
.psg-stopping .psg-barra-piena::after {
    content: "";
    position: absolute;
    inset: 0;
    background-image: linear-gradient(90deg, transparent 0, rgba(255, 255, 255, 0.35) 50%, transparent 100%);
    background-size: 120px 100%;
    background-repeat: no-repeat;
    animation: psg-scorre 1.4s linear infinite;
}

@keyframes psg-scorre {
    from { background-position: -120px 0; }
    to   { background-position: calc(100% + 120px) 0; }
}

.psg-numeri {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 4px 16px;
    margin-top: 8px;
    font-size: 11.5px;
}

.psg-numeri strong {
    color: var(--primary-color, #16688B);
}

.psg-percento {
    font-weight: 700;
}

/* La posizione nel catalogo (17/10/2026): sotto i numeri, piu' piccola, solo nella generazione
 * completa; serve per riprendere dopo un'interruzione. */
.psg-catalogo {
    margin: 4px 0 0;
}
.psg-catalogo strong {
    color: inherit;
}

/* --- Il resoconto ------------------------------------------------------------ */
.psg-esito {
    margin-bottom: 14px;
    padding: 10px 12px;
    border-radius: 7px;
    font-size: 12px;
}

.psg-esito-ok      { background-color: #e8f5ec; color: #1a5c2e; }
.psg-esito-avviso  { background-color: #fff6e0; color: #6b4e00; }
.psg-esito-errore  { background-color: #fdecea; color: #8a1f17; }

.psg-errori {
    margin: -4px 0 16px;
}

.psg-errori-elenco {
    max-height: 120px;
    overflow-y: auto;
    padding: 8px 10px;
    background-color: #f5f8fa;
    border: 1px solid #e0e7ed;
    border-radius: 6px;
    font-family: Consolas, "Courier New", monospace;
    font-size: 11px;
    word-break: break-word;
}

/* --- I pulsanti della finestra (17/10/2026) --------------------------------------
 * Avvia, Aggiorna, Interrompi e Chiudi hanno una veste propria, uguale in tutti i
 * portali: le classi btn-success, btn-primary e btn-danger nel tema del Back Office
 * hanno stili incompleti (btn-primary e' bianco su bianco, btn-success e btn-danger
 * restano con il bordo e i margini di serie del navigatore). Restano le pillole
 * del gestionale (.btn: bordi arrotondati, 12px); il selettore con l'id della
 * finestra vince sulle regole del tema. */
#modal_products_sheet_generation_ranges .psg-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 10px 18px !important;
    border: 0 !important;
    border-radius: 20px !important;
    color: #ffffff !important;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: 0.02em;
    box-shadow: 0 1px 2px rgba(17, 42, 70, 0.15);
    transition: background-color 0.15s ease, box-shadow 0.15s ease;
}

#modal_products_sheet_generation_ranges .psg-btn i {
    margin: 0 !important;
    color: #ffffff !important;
    font-size: 11px;
}

#modal_products_sheet_generation_ranges .psg-btn:hover:not(:disabled) {
    box-shadow: 0 2px 6px rgba(17, 42, 70, 0.25);
}

#modal_products_sheet_generation_ranges .psg-btn:focus {
    outline: 0;
    box-shadow: 0 0 0 3px rgba(22, 104, 139, 0.3);
}

#modal_products_sheet_generation_ranges .psg-btn:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

#modal_products_sheet_generation_ranges .psg-btn-verde { background-color: #1cc88a !important; }
#modal_products_sheet_generation_ranges .psg-btn-verde:hover:not(:disabled) { background-color: #17a673 !important; }
#modal_products_sheet_generation_ranges .psg-btn-blu { background-color: var(--primary-color, #16688B) !important; }
#modal_products_sheet_generation_ranges .psg-btn-blu:hover:not(:disabled) { background-color: #11506b !important; }
#modal_products_sheet_generation_ranges .psg-btn-rosso { background-color: #e74a3b !important; }
#modal_products_sheet_generation_ranges .psg-btn-rosso:hover:not(:disabled) { background-color: #c9301f !important; }
#modal_products_sheet_generation_ranges .psg-btn-grigio { background-color: #5b7488 !important; }
#modal_products_sheet_generation_ranges .psg-btn-grigio:hover:not(:disabled) { background-color: #465c6d !important; }

/* --- I pulsanti del piede ------------------------------------------------------
 * INTERROMPI solo durante. I pulsanti di chiusura restano visibili ma spenti
 * mentre si lavora: lo script li disabilita. I due pulsanti d'avvio stanno nei
 * riquadri delle modalita', che durante il lavoro sono nascosti. Le regole portano
 * l'id della finestra per vincere su quella di .psg-btn, che rende i pulsanti visibili. */
#modal_products_sheet_generation_ranges .psg-interrompi { display: none; }
#modal_products_sheet_generation_ranges.psg-running .psg-interrompi,
#modal_products_sheet_generation_ranges.psg-stopping .psg-interrompi { display: inline-flex; }

@media (prefers-reduced-motion: reduce) {
    .psg-running .psg-barra-piena::after,
    .psg-stopping .psg-barra-piena::after { animation: none; }
    .psg-barra-piena { transition: none; }
}
