/* L'ACCENTO non e' cablato: si legge da `--brand-50…900`, e i valori qui sotto
 * sono esattamente l'arancio di sempre. Un clone che dichiara `BRAND_ACCENT`
 * riceve dal server un `<style>` che li riscrive (app/core.py::stile_brand),
 * e tutta l'interfaccia lo segue. Senza, non cambia niente. */
:root{
  --brand-50:255 247 237;
  --brand-100:255 237 213;
  --brand-200:254 215 170;
  --brand-300:253 186 116;
  --brand-400:251 146 60;
  --brand-500:249 115 22;
  --brand-600:234 88 12;
  --brand-700:194 65 12;
  --brand-800:154 52 18;
  --brand-900:124 45 18;
}

/* posta.css — SOLO ciò che Tailwind non esprime con utility di classe:
 * la build vendorizzata (/vendor/tailwind.css) copre il resto. Niente CDN,
 * nessuna variante dark (la piattaforma Hub è solo light). */

/* Le icone sono inserite come markup <svg> grezzo via v-html (static/js/icons.js):
 * questa regola le fa riempire il contenitore su cui si mettono le utility
 * di dimensione (es. class="svg-fit w-4 h-4"), un selettore discendente non
 * esprimibile con una classe Tailwind stock. */
.svg-fit > svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Scrollbar sottile e coerente con la palette neutra dell'Hub (solo webkit;
 * su Firefox resta lo scrollbar di sistema, degrado accettabile). */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
::-webkit-scrollbar-thumb {
  background: #e2e8f0;
  border-radius: 9999px;
}
::-webkit-scrollbar-track {
  background: transparent;
}

/* ── Canvas Automazioni (grafo di blocchi con diramazione) ──────────────
 * Sfondo a puntini + linee connettore animate, stesso principio visivo del
 * canvas "Automazione" di ekomlab-hub/messages-app.html (bg-grid/
 * connection-line) ma qui i connettori si calcolano da next/si_next/
 * no_next del grafo, non dalla sola posizione nell'array. ⚠️ Il
 * trascinamento è mousedown/mousemove/mouseup (non touch): su schermi
 * touch il canvas resta visibile/zoomabile ma il riposizionamento libero
 * dei blocchi richiede desktop — stesso limite già noto per il canvas
 * dell'Hub. */
.automz-grid {
  background-size: 22px 22px;
  background-image: radial-gradient(circle, #e2e8f0 1.5px, transparent 1.5px);
}
.automz-connline {
  animation: automz-dash 25s linear infinite;
}
@keyframes automz-dash {
  to { stroke-dashoffset: -500; }
}

/* ── Editor WYSIWYG (Quill.js, sostituisce il textarea Markdown) ─────────
 * Ridisegnato nella palette Hub (bordo arancio in focus come ogni altro
 * campo del form, angoli arrotondati coerenti con gli input Tailwind). Il
 * contenitore .posta-quill è quello passato a EditorHtml.monta(); Quill vi
 * inietta da sé la sua toolbar (.ql-toolbar) e l'area editabile
 * (.ql-container/.ql-editor) — qui si adattano solo dimensioni e cornice. */
.posta-quill .ql-toolbar {
  border-color: #cbd5e1;
  border-top-left-radius: 0.5rem;
  border-top-right-radius: 0.5rem;
  background: #f8fafc;
}
.posta-quill .ql-container {
  border-color: #cbd5e1;
  border-bottom-left-radius: 0.5rem;
  border-bottom-right-radius: 0.5rem;
  font-family: inherit;
  font-size: 0.875rem;
}
.posta-quill .ql-editor {
  min-height: 160px;
  max-height: 360px;
  overflow-y: auto;
}
.posta-quill.posta-quill--sm .ql-editor {
  min-height: 110px;
  max-height: 240px;
}
.posta-quill:focus-within .ql-toolbar,
.posta-quill:focus-within .ql-container {
  border-color: rgb(var(--brand-600));
  box-shadow: 0 0 0 1px rgb(var(--brand-600));
}

/* ── Le parole di Quill, nella lingua di chi guarda ──────────────────────────
   Quill scrive i testi della sua barra e del suo suggerimento per i link con
   `content:` nel suo CSS (`vendor/quill.snow.css`): Normal, Heading 1-3, Small,
   Large, Huge, Visit URL:, Enter link:, Save, Edit, Remove. Sono INGLESI anche in
   un pannello italiano, e cosi' restano (italiano e inglese: l'italiano di oggi e'
   questo). Spagnolo e russo li riscrivono qui, con le stesse regole del vendor sotto
   `html[lang|=...]`: `EkLingua.imposta` scrive la lingua in `<html lang>`, e il
   selettore piu' specifico vince qualunque sia l'ordine dei file.
   ⚠️ Non sono classi Tailwind (il build e' purgato e non le conoscerebbe): sono
   regole nostre, e il vendor non si tocca.
   ⚠️ Le rese di partenza le rileggono i revisori insieme alle altre traduzioni. */
/* Spagnolo */
html[lang|="es"] .ql-snow .ql-picker.ql-header .ql-picker-label::before,
html[lang|="es"] .ql-snow .ql-picker.ql-header .ql-picker-item::before { content: 'Normal'; }
html[lang|="es"] .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
html[lang|="es"] .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before { content: 'Título 1'; }
html[lang|="es"] .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
html[lang|="es"] .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before { content: 'Título 2'; }
html[lang|="es"] .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
html[lang|="es"] .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before { content: 'Título 3'; }
html[lang|="es"] .ql-snow .ql-picker.ql-size .ql-picker-label::before,
html[lang|="es"] .ql-snow .ql-picker.ql-size .ql-picker-item::before { content: 'Normal'; }
html[lang|="es"] .ql-snow .ql-picker.ql-size .ql-picker-label[data-value=small]::before,
html[lang|="es"] .ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before { content: 'Pequeño'; }
html[lang|="es"] .ql-snow .ql-picker.ql-size .ql-picker-label[data-value=large]::before,
html[lang|="es"] .ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before { content: 'Grande'; }
html[lang|="es"] .ql-snow .ql-picker.ql-size .ql-picker-label[data-value=huge]::before,
html[lang|="es"] .ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before { content: 'Enorme'; }
html[lang|="es"] .ql-snow .ql-tooltip::before { content: 'Visitar URL:'; }
html[lang|="es"] .ql-snow .ql-tooltip a.ql-action::after { content: 'Editar'; }
html[lang|="es"] .ql-snow .ql-tooltip a.ql-remove::before { content: 'Quitar'; }
html[lang|="es"] .ql-snow .ql-tooltip.ql-editing a.ql-action::after { content: 'Guardar'; }
html[lang|="es"] .ql-snow .ql-tooltip[data-mode=link]::before { content: 'Introduce el enlace:'; }

/* Russo */
html[lang|="ru"] .ql-snow .ql-picker.ql-header .ql-picker-label::before,
html[lang|="ru"] .ql-snow .ql-picker.ql-header .ql-picker-item::before { content: 'Обычный'; }
html[lang|="ru"] .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
html[lang|="ru"] .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before { content: 'Заголовок 1'; }
html[lang|="ru"] .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
html[lang|="ru"] .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before { content: 'Заголовок 2'; }
html[lang|="ru"] .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
html[lang|="ru"] .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before { content: 'Заголовок 3'; }
html[lang|="ru"] .ql-snow .ql-picker.ql-size .ql-picker-label::before,
html[lang|="ru"] .ql-snow .ql-picker.ql-size .ql-picker-item::before { content: 'Обычный'; }
html[lang|="ru"] .ql-snow .ql-picker.ql-size .ql-picker-label[data-value=small]::before,
html[lang|="ru"] .ql-snow .ql-picker.ql-size .ql-picker-item[data-value=small]::before { content: 'Мелкий'; }
html[lang|="ru"] .ql-snow .ql-picker.ql-size .ql-picker-label[data-value=large]::before,
html[lang|="ru"] .ql-snow .ql-picker.ql-size .ql-picker-item[data-value=large]::before { content: 'Крупный'; }
html[lang|="ru"] .ql-snow .ql-picker.ql-size .ql-picker-label[data-value=huge]::before,
html[lang|="ru"] .ql-snow .ql-picker.ql-size .ql-picker-item[data-value=huge]::before { content: 'Огромный'; }
html[lang|="ru"] .ql-snow .ql-tooltip::before { content: 'Перейти по ссылке:'; }
html[lang|="ru"] .ql-snow .ql-tooltip a.ql-action::after { content: 'Изменить'; }
html[lang|="ru"] .ql-snow .ql-tooltip a.ql-remove::before { content: 'Удалить'; }
html[lang|="ru"] .ql-snow .ql-tooltip.ql-editing a.ql-action::after { content: 'Сохранить'; }
html[lang|="ru"] .ql-snow .ql-tooltip[data-mode=link]::before { content: 'Введите ссылку:'; }

/* Le parole sono piu' lunghe, e la barra e il suggerimento devono reggere.
   - In russo «Заголовок 1» (77px) non entra nei 68px che la tendina lascia prima della
     freccia (98px - margini - 18px di freccia) e la coprirebbe: si allarga la tendina,
     solo in russo («Огромный», 67px, ci sta ma per un soffio: allargata anche lei).
   - 🔴 Il suggerimento dei link (il campo, e poi l'indirizzo con «Modifica» e «Rimuovi») e'
     `nowrap` e largo fino a 420-550px: su un telefono usciva dallo schermo (misurato a 390px: in
     italiano l'anteprima, 418px; in spagnolo e russo anche il campo, 416 e 422, e l'anteprima
     fino a 547). Sotto i 480px puo' andare a capo ed e' largo al piu' quanto l'editor: vale per
     OGNI lingua, e corregge anche il difetto che l'italiano aveva gia'. */
html[lang|="ru"] .ql-snow .ql-picker.ql-header { width: 114px; }
html[lang|="ru"] .ql-snow .ql-picker.ql-size { width: 108px; }
@media (max-width: 480px) {
  .ql-snow .ql-tooltip { white-space: normal; max-width: 100%; }
}

/* ── Contatti: la barra dei tre bottoni (Esporta CSV, Importa CSV, Crea contatto) ──
   Con le parole di un'altra lingua (+40% in prova) i tre bottoni non entrano piu' in
   una riga a 390px e uscivano dallo schermo di 2px: possono andare a capo. Senza
   toccare il markup (le classi sono quelle fotografate dal banco): la barra e' il
   secondo figlio della riga in cima alla scheda. In italiano entrano in una riga,
   e non cambia niente. */
@media (max-width: 480px) {
  [data-isola="contatti"] > .p-6 > .flex-wrap > .flex.items-center.gap-2 { flex-wrap: wrap; }
}

/* ── Marca del CLIENTE sulla schermata di accesso ────────────────────────────
   Le stesse tre classi delle due pagine pubbliche (disiscrizione, iscrizione):
   il markup lo genera `core.intestazione_pubblica()` in un posto solo, quindi
   qui servono solo le regole — il build Tailwind e' purgato e non le
   conoscerebbe.
   ⚠️ Compaiono solo se il clone ha configurato PUB_BRAND/PUB_LOGO_URL: senza,
   il server non sostituisce niente e questi selettori non trovano nulla. */
.pub-testata { margin-bottom: 14px; }
.pub-logo { max-height: 40px; max-width: 190px; object-fit: contain; display: block; }
.pub-marca { font-size: 15px; font-weight: 700; color: #0f172a; letter-spacing: -0.01em; }

/* ══ RIGA MOBILE DENTRO L'HUB ══
   Sotto i 900px la testata dell'Hub sparisce e la striscia dell'azione
   contestuale diventa l'UNICA riga in alto: il ☰ chiede all'Hub di aprire il
   menu principale, la ⚙ il foglio delle sezioni di questa app (che l'elenco
   ce l'ha gia', dichiarato). Fuori dall'Hub non esistono: li' la barra
   laterale c'e' ancora, e non c'e' nessun Hub da aprire. */
.ek-mob { display: none; }
@media (max-width: 900px) {
  body.dentro-hub .ek-mob {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.25rem; height: 2.25rem; margin: 0.5rem 0;
    border-radius: 0.5rem; border: 1px solid #e2e8f0;
    background: #fff; color: #475569;
  }
  /* La striscia si stringe ai bordi: con 24px per lato i due bottoni piu'
     l'azione contestuale non entrano su uno schermo da 360. */
  body.dentro-hub .striscia-azione { padding-left: 0.6rem; padding-right: 0.6rem; }
}

/* ══ ELENCO E LETTURA SI ALTERNANO, NON SI AFFIANCANO (sotto i 900px) ══
   🔴 Il pannello lista e' largo 380px FISSI e il pannello di lettura gli sta
   accanto: su uno schermo da 362 il primo esce dal bordo e il secondo e'
   interamente fuori. Non e' un difetto del menu — questa casella non ha MAI
   funzionato su un telefono — ma e' lo stesso «balla a destra e sinistra»,
   quindi si chiude qui.
   ⚠️ Allargare la lista al 100% da solo NON basta, e sarebbe la mezza cura
   peggiore: il pannello di lettura resta li' a larghezza zero e il suo
   contenuto viene disegnato oltre il bordo — cioe' si apre un messaggio e non
   lo si vede. I due pannelli si ALTERNANO: niente selezionato → l'elenco,
   qualcosa aperto → la lettura.
   ⚠️ Il gate NON e' `body.dentro-hub`: due pannelli affiancati non ci stanno
   nemmeno quando l'app e' aperta da sola su un telefono. */
@media (max-width: 900px) {
  section.w-\[380px\] { width: 100%; min-width: 0; max-width: 100%; }
  /* Lo stato vuoto e' il segnale che non c'e' niente da leggere: e' l'unico
     figlio diretto di <main> in quel caso, e lo dichiara il markup con la sua
     classe invece di farlo indovinare a un selettore.
     ⚠️ La domanda si fa al CONTENITORE dei due pannelli, non al pannello:
     `:has()` non si puo' annidare dentro un altro `:has()` (la regola viene
     scartata INTERA, in silenzio — sembra che il selettore non combaci),
     mentre dentro un `:not()` si puo'. */
  .pannelli-doppi:has(> main > .pannello-vuoto) > main { display: none; }
  .pannelli-doppi:not(:has(> main > .pannello-vuoto)) > section { display: none; }
}

/* Il ritorno all'elenco. Senza, si entra in un messaggio e non si esce piu':
   la lista, li', non e' piu' a schermo. */
.ek-indietro { display: none; }
@media (max-width: 900px) {
  main > .ek-indietro {
    display: inline-flex; align-items: center; gap: 0.4rem;
    align-self: flex-start; flex: none;
    margin: 0.5rem 0.75rem 0; padding: 0.4rem 0.7rem;
    border-radius: 0.5rem; border: 1px solid #e2e8f0; background: #fff;
    color: #475569; font-size: 13px; font-weight: 500;
  }
}


/* Le azioni di un messaggio aperto (Rispondi, Archivia, Elimina) stanno sulla riga del titolo e sono `shrink-0`:
   in una lingua piu' lunga dell'italiano (la lingua finta del banco ne aggiunge il 40%) a 390px uscivano dal bordo
   di 6px. Il tetto e' la larghezza della riga: dove le azioni ci stanno (l'italiano) non scatta e il disegno e'
   quello di sempre; dove non ci stanno vanno a capo invece di uscire.
   ⚠️ Sta qui e non in Tailwind: il build e' purgato, e `max-w-full`/`flex-wrap` non basterebbero senza toccare le
   classi del markup (che l'italiano di prima non ha: il banco le confronta). */
.pannelli-doppi > main .flex.items-start.justify-between > .shrink-0.flex.items-center {
  max-width: 100%; flex-wrap: wrap; justify-content: flex-end;
}

/* ── Sola visualizzazione ─────────────────────────────────────────────────
   I comandi che SCRIVONO spariscono. La difesa vera e' il 403 di
   `app/deps.py::require_auth` — questo serve a non offrire una porta che poi
   non si apre, e a non far sembrare rotto cio' che e' solo ristretto.
   ⚠️ Sta qui e non in Tailwind: quel build e' purgato, come gia' per `.ek-mob`. */
body.com-sola-lettura [data-scrittura] { display: none !important; }

/* ── LA BARRA DEI SELEZIONATI SU UN TELEFONO ──────────────────────────────
   In cima ci sono gia' ☰, ⚙ e «Nuovo messaggio»: a 390px alla barra restano
   ~100px, e i suoi quattro pezzi si impilano UNO PER RIGA — misurato togliendo
   queste regole una per volta: 4 righe e 218-230px di striscia, un terzo dello
   schermo prima di vedere un messaggio. Con una riga tutta sua sono 2 righe e
   162px.
   ⚠️ `flex-wrap` sulla striscia serve comunque: senza, cio' che non ci sta
   esce dal bordo e viene tagliato — e il taglio NON allarga `scrollWidth`,
   quindi non lo vede nessuna misura sullo scorrimento della pagina.
   ⚠️ Sta qui e non in Tailwind: quel build e' purgato e non ha le varianti
   responsive, come gia' per `.ek-mob`. */
@media (max-width: 900px) {
  .striscia-azione { flex-wrap: wrap; }
  .striscia-azione > .azioni-selezionati {
    /* 🔴 `flex-basis` NON e' decorativo e NON e' `auto`: `flex-1` di Tailwind
       vale `1 1 0%`, quindi senza questa riga la barra resta larga zero e
       schiacciata di fianco a «Nuovo messaggio» — misurato: 4 righe e 230px
       di striscia contro 2 righe e 162px. ⚠️ La prima mutazione la metteva a
       `auto` e sembrava inerte: `auto` e `100%` qui fanno la stessa cosa, e
       una mutazione che non distingue non prova niente. */
    flex-basis: 100%;
    justify-content: flex-start;
    margin-top: 0;
  }
}

/* ══ LA TESTATA DEL DETTAGLIO DI UNA CAMPAGNA SU UN TELEFONO ══
   🔴 Il titolo e i comandi stanno su UNA riga, e il gruppo dei comandi non si
   stringe (`shrink-0`): a 390px «Aggiorna», «Vedi email inviate», «Duplica» e
   «Programma invio» (o «Annulla») sono ~470px, quindi l'ultimo usciva dal
   bordo e veniva TAGLIATO — gia' in italiano, per una bozza (misurato con la
   lingua finta: e in una lingua piu' lunga usciva anche «Duplica» di una
   campagna conclusa). Il taglio NON allarga `scrollWidth`: non lo vede nessuna
   misura sullo scorrimento della pagina.
   ⚠️ Il selettore e' per STRUTTURA e non per classe nuova: il banco
   dell'italiano fotografa anche le classi, e una classe in piu' sarebbe una
   differenza dell'italiano. `> div >` e' la radice della vista (il dettaglio),
   non l'elenco: l'elenco ha la sua riga dentro un `div.p-6`. */
@media (max-width: 900px) {
  [data-isola="campagne"] > div > .border-b.justify-between { flex-wrap: wrap; }
  [data-isola="campagne"] > div > .border-b.justify-between > .shrink-0 { flex-wrap: wrap; flex-shrink: 1; max-width: 100%; }
}

/* ══ I COMANDI IN FONDO ALLA PROCEDURA GUIDATA DELLE CAMPAGNE, SU UN TELEFONO ══
   🔴 «Annulla» e il gruppo «← Indietro / Salva bozza / Programma» stanno su una
   riga e i bottoni si stringono: a 390px, gia' in italiano, ognuno del gruppo
   andava a capo su DUE righe di testo e l'ultimo sporgeva dal bordo bianco
   della finestra (misurato nel passo 6); in una lingua piu' lunga usciva dallo
   schermo. Il gruppo diventa trasparente (`display: contents`): i quattro
   bottoni sono tutti figli della riga, che va a capo da sola dove non ci stanno
   — in italiano due righe da due bottoni, ciascuno su una riga di testo.
   ⚠️ Il selettore parte da `#finestre-campagna`: e' il punto dove si monta la
   procedura (non la finestra «Nuovo gruppo» del guscio, che sta dopo). */
@media (max-width: 900px) {
  #finestre-campagna .border-t.mt-4.justify-between { flex-wrap: wrap; }
  #finestre-campagna .border-t.mt-4.justify-between > .flex { display: contents; }
}

/* Il punto dove si monta un'isola Vue (`<Isola>`, docs/vue.md): non deve
   contare per il flex o la griglia di chi lo contiene — la vista deve stare
   dove stava. */
.isola { display: contents; }

/* ══ LA BARRA LATERALE SU UN TELEFONO, FUORI DALL'HUB ══
   🔴 Sotto i 900px la barra (240px) restava sempre aperta: su un telefono da
   390 si mangiava piu' di meta' dello schermo, e la vista ci stava nel resto.
   Diventa un CASSETTO: chiuso di serie, si apre dal ☰ della striscia (lo
   stesso bottone che dentro l'Hub apre il menu dell'Hub), si chiude toccando
   fuori o scegliendo una voce. Il velo esiste solo a cassetto aperto, e sta
   PRIMA della barra: la regola `.velo-menu ~ aside` la apre senza toccarne il
   markup.
   ⚠️ La ⚙ resta solo dentro l'Hub: fuori non c'e' nessun foglio delle sezioni
   da aprire.
   🔴 Il ☰ si riconosce dal POSTO (il primo bottone della striscia), mai dal suo
   `title`: il `title` e' un testo tradotto («Menu», «Menú», «Меню»), e con un
   selettore `[title="Menu"]` il ☰ spariva in ogni lingua che non scrive
   esattamente «Menu» — sotto i 900px la barra e' gia' nascosta, quindi su un
   telefono fuori dall'Hub non restava nessun modo di aprire il menu. */
@media (max-width: 900px) {
  body:not(.dentro-hub) aside { display: none; }
  body:not(.dentro-hub) .striscia-azione > .ek-mob:first-child {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.25rem; height: 2.25rem; margin: 0.5rem 0;
    border-radius: 0.5rem; border: 1px solid #e2e8f0;
    background: #fff; color: #475569;
  }
  body:not(.dentro-hub) .striscia-azione { padding-left: 0.6rem; padding-right: 0.6rem; }
  .velo-menu { position: fixed; inset: 0; z-index: 30; background: rgb(15 23 42 / 0.3); }
  /* ⚠️ Con lo stesso `body:not(.dentro-hub)` della regola che la nasconde:
     senza, quella e' piu' specifica e il cassetto resta chiuso (misurato). */
  body:not(.dentro-hub) .velo-menu ~ aside {
    display: flex; position: fixed; top: 0; bottom: 0; left: 0; z-index: 31;
    box-shadow: 0 10px 25px rgb(15 23 42 / 0.15);
  }
}
