/* ═══════════════════════════════════════════════════════════════════════════
   Astra OS · astra-patterns.css — la casa dei PATTERN del Command Center
   (sess.10174)

   Il Command Center (docs/design-studio-dashboard.html, servito su /command-center)
   ha applicato in-vivo i pattern del Design Studio — §7 seg control, §10 skeleton
   ed empty state, §13 tabella viva, §19 filtri e menu contestuale, il gate HITL,
   il banner, l'indicatore «in corso». La SPA (static/os.html) li consuma DA QUI,
   non riscrivendoli in coda ai suoi 5.6k: os.html può solo dimagrire (ratchet
   os-html-lines) e ogni copia a mano è un dialetto che invecchia per conto suo
   (audit sess.9057: «evitare il 6° dialetto»).

   Due leggi di questo file, entrambe misurate da tests/test_cc_pattern_trasloco.py:
   • ZERO colori letterali: nessun hex, nessun rgb() di palette. Solo i token
     `:root` di static/os.html (la casa dei token resta quella), composti con
     color-mix(). Un colore che qui non esiste come token non si inventa: si
     promuove prima in os.html.
   • Il Command Center NON linka questo file: è un artefatto single-file e
     self-contained per identità (app.py:command_center_page). La direzione del
     trasloco è dashboard → SPA, mai il contrario.

   Ordine di caricamento: PRIMA dello <style> inline di os.html, così le regole
   specifiche della SPA vincono a parità di specificità.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── §10 skeleton a blocchi — mai una pagina morta (già vivo in os.html dal
      sess.8666, qui la sua casa; classi invariate: .sk, .sk-*, skels()/skelGrid()) ── */
@keyframes sk-shimmer{to{background-position:240% center}}
.sk{position:relative;overflow:hidden;background:var(--panel);border:1.5px solid var(--hair);border-radius:var(--r-sm)}
.sk::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,transparent 0%,color-mix(in srgb,var(--hair) 75%,transparent) 50%,transparent 100%);background-size:220% 100%;animation:sk-shimmer 1.4s ease-in-out infinite}
.sk-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-bottom:18px}
.sk-kpi{height:104px}.sk-band{height:200px}.sk-sec{height:150px}
.sk-line{height:38px;margin-bottom:8px}
.sk-card{height:190px}
.sk-sections{display:grid;grid-template-columns:repeat(2,1fr);gap:18px}
@media(max-width:720px){.sk-grid,.sk-sections{grid-template-columns:1fr}}

/* ── §10 skeleton a velo — il Command Center lo stende su una card VERA mentre
      i dati arrivano: il layout resta, il contenuto si spegne, il velo scorre ── */
.is-loading{pointer-events:none;position:relative}
.is-loading>*{opacity:0}
.is-loading::after{content:"";position:absolute;inset:12px;border-radius:var(--r-xs);background:linear-gradient(100deg,var(--panel2) 30%,color-mix(in srgb,var(--hair) 60%,var(--panel2)) 50%,var(--panel2) 70%);background-size:200% 100%;animation:sk-shimmer 1.3s infinite}

/* ── §10 empty state canonico (sess.9039) — centrato, icona, titolo, hint, via d'uscita ── */
.empty-state{text-align:center;padding:34px 20px;color:var(--dim)}
.empty-state .es-ico{font-size:30px;opacity:.5;margin-bottom:10px}
.empty-state h4{font-family:var(--syne);color:var(--ink);font-size:14px;margin-bottom:6px}
.empty-state p{font-size:11.5px;margin:0 auto 4px;max-width:300px;line-height:1.6}
.empty-state.err .es-ico{opacity:.8}
.empty-state.err h4{color:var(--acc-orange)}
.empty-cta{display:inline-flex;align-items:center;gap:6px;margin-top:10px;padding:6px 12px;font-family:var(--mono);font-size:11px;color:var(--acc-blue);background:transparent;border:1px solid color-mix(in srgb,var(--acc-blue) 38%,transparent);border-radius:var(--r-xs);cursor:pointer;transition:background .2s,border-color .2s,transform .1s}
.empty-cta:hover{background:color-mix(in srgb,var(--acc-blue) 13%,transparent);border-color:var(--acc-blue)}
.empty-cta:active{transform:translateY(1px)}

/* ── toast (sess.8666) — markup di toast() in os.html: [icona][testo], .ok/.warn/.err ── */
.toast-wrap{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);z-index:var(--z-dtip);display:flex;flex-direction:column;gap:8px;align-items:center;pointer-events:none}
.toast{pointer-events:auto;display:flex;align-items:center;gap:9px;background:var(--panel);border:1.5px solid var(--hair);border-left:3px solid var(--acc-teal);border-radius:9px;padding:11px 16px;font-size:13px;color:var(--ink);box-shadow:0 10px 34px rgba(0,0,0,.55);max-width:90vw;animation:toastIn .28s cubic-bezier(.2,.8,.2,1)}
.toast.warn{border-left-color:var(--acc-yellow)}.toast.err{border-left-color:var(--acc-pink)}.toast.ok{border-left-color:var(--acc-teal)}
.toast.out{animation:toastOut .28s forwards}
@keyframes toastIn{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes toastOut{to{opacity:0;transform:translateY(14px)}}

/* ── §7 seg control — una scelta fra pochi valori, sempre visibile ── */
.seg{display:inline-flex;background:var(--panel2);border:1px solid var(--hair);border-radius:var(--r-sm);padding:3px}
.seg button{font:600 11.5px var(--mono);border:0;background:none;color:var(--dim);padding:4px 10px;border-radius:var(--r-xs);cursor:pointer;transition:background var(--t-base),color var(--t-base)}
.seg button.on{background:var(--acc-violet);color:var(--ink)}

/* ── §19 filter chips — filtri componibili, stato aria-pressed ── */
.fchip{display:inline-flex;align-items:center;gap:7px;font:500 12px var(--mono);color:var(--dim);background:var(--surf-2);border:1px solid var(--line);border-radius:var(--r-sm);padding:4px 9px;cursor:pointer;transition:color var(--t-base),border-color var(--t-base),background var(--t-base)}
.fchip:hover{color:var(--ink);border-color:var(--hair)}
.fchip svg.ic{font-size:14px}
.fchip.on{color:var(--ink);border-color:var(--acc-violet);background:color-mix(in srgb,var(--acc-violet) 14%,transparent)}

/* ── §19 menu contestuale — ancorato al suo [data-menu], uno aperto alla volta ── */
.has-menu{position:relative}
.menu{position:absolute;top:44px;right:10px;width:190px;background:color-mix(in srgb,var(--panel) 98%,transparent);backdrop-filter:blur(14px);border:1px solid var(--hair);border-radius:var(--r);box-shadow:var(--elev);padding:6px;z-index:var(--z-dropdown);display:none}
.menu.on{display:block}
.menu a{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:var(--r-sm);font-size:13px;color:var(--ink);cursor:pointer}
.menu a svg.ic{font-size:15px;color:var(--dim)}
.menu a:hover{background:var(--surf-3)}
.menu a.danger,.menu a.danger svg.ic{color:var(--acc-red)}
.menu .sep{height:1px;background:var(--line);margin:6px 4px}

/* ── §13 tabella viva — ordinabile (th.srt), riga selezionabile (tr.sel),
      numeri allineati (.num), persona (.who), azione AI per riga (.btn-ai).
      I selettori sono per RUOLO, non per tabella: valgono su qualunque <table> ── */
th.srt{cursor:pointer;user-select:none}
th.srt:hover{color:var(--ink)}
th.srt::after{content:"";display:inline-block;width:0;height:0;margin-left:6px;vertical-align:middle;border-left:3px solid transparent;border-right:3px solid transparent;border-top:4px solid currentColor;opacity:.32}
th.srt.asc::after{border-top:0;border-bottom:4px solid currentColor;opacity:1}
th.srt.desc::after{opacity:1}
tbody tr.sel{background:color-mix(in srgb,var(--acc-violet) 9%,transparent);box-shadow:inset 2px 0 0 var(--acc-violet)}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}
.who{display:flex;align-items:center;gap:10px}
.who .nm{font:600 13.5px var(--mono);color:var(--ink);line-height:1.2;display:block}
.who .rl{font-size:11px;color:var(--dim);margin-top:1px;display:block}
@keyframes ap-rot{to{transform:rotate(360deg)}}
.btn-ai{font:700 11.5px var(--mono);letter-spacing:.3px;border:1px solid color-mix(in srgb,var(--acc-violet) 40%,transparent);background:color-mix(in srgb,var(--acc-violet) 12%,transparent);color:var(--violet-soft);border-radius:var(--r-sm);padding:6px 11px;cursor:pointer;display:inline-flex;align-items:center;gap:6px;white-space:nowrap;transition:transform var(--t-fast),background var(--t-base),border-color var(--t-base),color var(--t-base)}
.btn-ai:hover{background:color-mix(in srgb,var(--acc-violet) 20%,transparent);border-color:color-mix(in srgb,var(--acc-violet) 62%,transparent);transform:translateY(-1px)}
.btn-ai:active{transform:translateY(0)}
.btn-ai svg.ic{font-size:13px}
.btn-ai.run{pointer-events:none;color:var(--dim);background:var(--surf-2);border-color:var(--line)}
.btn-ai.run svg.ic{animation:ap-rot .7s linear infinite}
.btn-ai.ok{color:var(--acc-teal);background:color-mix(in srgb,var(--acc-teal) 12%,transparent);border-color:color-mix(in srgb,var(--acc-teal) 40%,transparent)}

/* ── indicatore «in corso» — un agente che lavora adesso ── */
@keyframes ap-rpulse{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--acc-teal) 50%,transparent)}70%{box-shadow:0 0 0 7px transparent}100%{box-shadow:0 0 0 0 transparent}}
.run{display:inline-flex;align-items:center;gap:5px;font:600 9px var(--mono);letter-spacing:.5px;text-transform:uppercase;color:var(--acc-teal)}
.run .rd{width:6px;height:6px;border-radius:50%;background:var(--acc-teal);animation:ap-rpulse 1.6s infinite}

/* ── HITL gate — l'ultimo click di Mattia, reso pattern: testata, corpo citato, azioni ── */
.hitl{background:linear-gradient(180deg,color-mix(in srgb,var(--acc-orange) 8%,transparent),transparent);border:1px solid color-mix(in srgb,var(--acc-orange) 32%,var(--line));border-radius:var(--r);padding:14px 16px}
.hitl-h{display:flex;align-items:center;gap:9px;font:600 14px var(--syne);color:var(--ink)}
.hitl-h svg.ic{color:var(--acc-orange);font-size:17px}
.hitl-b{font-size:13px;color:var(--ink);line-height:1.55;margin:9px 0 12px;font-family:var(--mono);background:rgba(0,0,0,.25);border:1px solid var(--line);border-radius:var(--r-sm);padding:10px 12px}
.hitl-a{display:flex;gap:8px}

/* ── banner — un avviso che resta, con la sua spalla arancione ── */
.banner{display:flex;align-items:center;gap:12px;padding:12px 15px;border-radius:var(--r);background:color-mix(in srgb,var(--acc-orange) 7%,transparent);border:1px solid color-mix(in srgb,var(--acc-orange) 28%,transparent);border-left:3px solid var(--acc-orange)}
.banner>svg.ic{font-size:18px;color:var(--acc-orange);flex:none}
.banner .bx{flex:1}
.banner .bx b{font:600 13.5px var(--syne);color:var(--ink)}
.banner .bx p{font-size:12px;color:var(--dim);margin-top:2px}

@media(prefers-reduced-motion:reduce){
  .sk::after,.is-loading::after,.run .rd,.btn-ai.run svg.ic{animation:none}
}
