/* SkillHub: stile applicazione (tema chiaro) */

/* `hidden` deve vincere sempre: senza questa riga un elemento con
   `display: grid` o `flex` dichiarato in un foglio di stile resta visibile
   anche quando lo si nasconde da JavaScript (è la regola dell'autore che
   batte quella del browser). */
[hidden] { display: none !important; }
/* Un filtro live sta chiedendo i risultati (app.js): si dice col puntatore,
   senza smorzare la pagina a ogni lettera. */
html.filtri-in-corso main { cursor: progress; }

:root {
  color-scheme: light;
  /* Ink & chrome (palette dataviz di riferimento) */
  --bg: #f9f9f7;
  --surface: #fcfcfb;
  --ink: #0b0b0b;
  --ink-2: #52514e;
  /* #898781 faceva 3,4:1 sul fondo: sotto il 4,5:1 AA proprio sui testi più
     piccoli (hint, small, meta), che sono quelli che ne hanno più bisogno */
  --ink-3: #6f6d68;
  --grid: #e1e0d9;
  --baseline: #c3c2b7;
  --border: rgba(11, 11, 11, 0.10);
  /* Accent (= slot categorico 1) */
  --accent: #2a78d6;
  --accent-strong: #1c5cab;
  --accent-soft: #e5eefb;
  /* Serie categoriche */
  /* --s1…--s5 e --baseline sono ricopiati in DONUT_COLORS (app/webutils.py):
     il donut è un SVG generato dal server e non legge queste variabili. */
  --s1: #2a78d6; --s2: #eb6834; --s3: #1baf7a; --s4: #eda100;
  --s5: #e87ba4; --s6: #008300; --s7: #4a3aa7; --s8: #e34948;
  /* Rampa sequenziale blu (ordinale, livelli 1..5) */
  --lv1: #86b6ef; --lv2: #5598e7; --lv3: #2a78d6; --lv4: #1c5cab; --lv5: #104281;
  /* Stato */
  --ok-bg: #e7f5e7; --ok-tx: #006300;
  --warn-bg: #fdf3d9; --warn-tx: #8a5a00;
  --bad-bg: #fdeaea; --bad-tx: #b32424;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  background: var(--bg);
  color: var(--ink);
  font-size: 15px;
  line-height: 1.5;
}
a { color: var(--accent-strong); text-decoration: none; }
a:hover { text-decoration: underline; }
h1 { font-size: 24px; font-weight: 650; margin: 0 0 4px; }
h2 { font-size: 17px; font-weight: 650; margin: 0 0 12px; }
h3 { font-size: 14px; font-weight: 650; margin: 0 0 8px; color: var(--ink-2); }

/* ---------------------------------------------------------------- topbar */
.topbar {
  background: #ffffff;
  border-bottom: 1px solid var(--grid);
  position: sticky; top: 0; z-index: 50;
}
.topbar-inner {
  max-width: 1180px; margin: 0 auto; padding: 0 20px;
  display: flex; align-items: center; gap: 22px; height: 56px;
}
.brand { font-size: 18px; font-weight: 700; color: var(--ink); letter-spacing: -0.2px; }
.brand:hover { text-decoration: none; }
.brand span { color: var(--accent); }
.brand small { font-weight: 500; color: var(--ink-3); font-size: 12px; margin-left: 8px; }
/* Il logo dell'installazione, quando c'è: alto quanto la scritta. */
.brand-logo { height: 22px; width: auto; vertical-align: -4px; margin-right: 6px; }
/* Il blocco di destra non si stringe mai: lingua e menu utente hanno una
   larghezza che serve tutta. */
.topbar-right { flex: none; }
.topbar-spazio { flex: 1; }
@media (max-width: 820px) {
  .topbar-inner { gap: 12px; padding: 0 12px; }
}

/* ------------------------------------------------------------ menu laterale */
/* Le pagine di chi è entrato hanno il menu a sinistra e la pagina a destra.
   La barra in alto resta, sottile e senza fondo, per guida, lingua e menu
   utente: le voci di lavoro stanno tutte nel menu laterale. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.con-barra { display: flex; align-items: flex-start; min-height: 100vh; }
.con-barra .pagina { flex: 1; min-width: 0; display: flex; flex-direction: column; min-height: 100vh; }
.con-barra .pagina > .container { flex: 1; width: 100%; }
.con-barra .topbar { background: transparent; border-bottom: none; position: static; }
.con-barra .topbar-inner { max-width: none; height: 56px; padding: 0 24px; }
.con-barra .container { max-width: 1440px; padding-top: 4px; }
.con-barra .nudge-inner { max-width: none; }

.barra {
  --barra-larga: 250px; --barra-stretta: 64px;
  position: sticky; top: 8px; flex: none; z-index: 70;
  width: var(--barra-larga); height: calc(100vh - 16px); margin: 8px 0 8px 8px;
  background: #fff; border: 1px solid var(--grid); border-radius: 14px;
  box-shadow: 0 1px 3px rgba(11, 11, 11, 0.05);
  display: flex; flex-direction: column; overflow: hidden;
  transition: width .18s ease;
}
.barra-testa {
  display: flex; align-items: center; gap: 8px; padding: 12px 10px 10px 14px;
  border-bottom: 1px solid var(--bg); min-height: 58px;
}
.barra-testa .brand { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden;
  display: flex; align-items: center; gap: 6px; font-size: 17px; }
.barra-testa .brand-logo { height: 28px; margin: 0; vertical-align: 0; }
.barra-stringi, .barra-apri {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 8px; border: none; background: none;
  color: var(--ink-3); cursor: pointer;
}
.barra-stringi:hover, .barra-apri:hover { background: var(--bg); color: var(--ink); }
.barra-apri { display: none; }
.barra .ic, .barra-apri .ic, .barra-stringi .ic { width: 19px; height: 19px; flex: none; }

.barra .nav {
  display: flex; flex-direction: column; gap: 1px; flex: 1; min-height: 0;
  overflow-y: auto; overflow-x: hidden; padding: 8px; scrollbar-width: thin;
}
.barra .barra-voce, .barra .gruppo > summary {
  display: flex; align-items: center; gap: 11px; padding: 8px 10px;
  border-radius: 9px; color: var(--ink-2); font-weight: 550; font-size: 14px;
  white-space: nowrap; cursor: pointer; list-style: none; text-decoration: none;
}
.barra .gruppo > summary::-webkit-details-marker { display: none; }
.barra .gruppo > summary::marker { content: ""; }
.barra .barra-voce:hover, .barra .gruppo > summary:hover { background: var(--bg); color: var(--ink); text-decoration: none; }
.barra .barra-voce.primo.active { background: var(--accent-soft); color: var(--accent-strong); }
.barra .gruppo.attivo > summary { color: var(--ink); }
.barra .testo { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.barra .freccia { display: inline-flex; color: var(--ink-3); transition: transform .15s ease; }
.barra .freccia .ic { width: 15px; height: 15px; }
.barra .gruppo[open] > summary .freccia { transform: rotate(180deg); }
.barra .gruppo-voci { display: flex; flex-direction: column; gap: 1px; padding: 2px 0 6px 30px; }
.barra .gruppo-voci .barra-voce { font-weight: 500; font-size: 13.5px; padding: 6px 10px; }
.barra .gruppo-voci .barra-voce.active { background: var(--accent-soft); color: var(--accent-strong); }
.barra .pallino { margin-left: auto; }

/* Compressa: solo le icone. Il clic su un gruppo la riapre (`app.js`): un
   menu a comparsa dentro una barra che scorre verrebbe tagliato. */
html.barra-stretta .barra { width: var(--barra-stretta); }
html.barra-stretta .barra .testo, html.barra-stretta .barra .freccia,
html.barra-stretta .barra .gruppo-voci { display: none; }
html.barra-stretta .barra-testa { flex-direction: column; padding: 12px 0 8px; gap: 6px; }
html.barra-stretta .barra-testa .brand { flex: none; justify-content: center; }
html.barra-stretta .barra .barra-voce, html.barra-stretta .barra .gruppo > summary { justify-content: center; padding: 9px 0; position: relative; }
html.barra-stretta .barra .pallino { position: absolute; top: 2px; right: 6px; margin: 0;
  font-size: 10px; min-width: 16px; padding: 0 4px; }
html.barra-stretta .barra .gruppo.attivo > summary { background: var(--accent-soft); color: var(--accent-strong); }

.barra-velo { display: none; }
/* Sotto i 900px la barra è un pannello sopra la pagina, che si apre dal
   pulsante in alto e si chiude toccando fuori. Compressa o no non conta. */
@media (max-width: 900px) {
  .con-barra { display: block; }
  .barra-apri { display: inline-flex; }
  .barra, html.barra-stretta .barra {
    position: fixed; top: 0; left: 0; bottom: 0; margin: 0; height: 100%;
    width: min(290px, 86vw); border-radius: 0 14px 14px 0;
    transform: translateX(-105%); transition: transform .2s ease;
  }
  html.barra-stretta .barra .testo, html.barra-stretta .barra .freccia { display: revert; }
  html.barra-stretta .barra .gruppo[open] .gruppo-voci { display: flex; }
  html.barra-stretta .barra-testa { flex-direction: row; padding: 12px 10px 10px 14px; }
  html.barra-stretta .barra .barra-voce, html.barra-stretta .barra .gruppo > summary { justify-content: flex-start; padding: 8px 10px; }
  html.barra-aperta .barra { transform: none; box-shadow: 0 16px 48px rgba(11, 11, 11, .22); }
  html.barra-aperta .barra-velo { display: block; position: fixed; inset: 0; z-index: 65;
    background: rgba(11, 11, 11, .28); }
  .barra-stringi { display: none; }
  .con-barra .topbar-inner { padding: 0 12px; }
}
@media (prefers-reduced-motion: reduce) { .barra, .barra .freccia { transition: none; } }
.topbar-right { display: flex; align-items: center; gap: 8px; }

/* la guida del proprio ruolo: stessa forma del selettore di lingua, perché è
   della stessa famiglia (una scelta di lettura, non una voce di menu). Sotto
   gli 820px resta l'icona: il posto va a chi sta cercando una persona, e
   un'icona-libro accanto al menu utente si riconosce lo stesso. */
.guida-btn {
  display: flex; align-items: center; gap: 6px; white-space: nowrap;
  border: 1px solid var(--grid); border-radius: 999px; padding: 4px 11px;
  color: var(--ink-2); font-size: .82rem; font-weight: 600;
}
.guida-btn:hover {
  background: var(--accent-soft); border-color: var(--accent-soft);
  color: var(--accent-strong); text-decoration: none;
}
@media (max-width: 820px) { .guida-btn .guida-txt { display: none; } }
.guida-btn .ic { width: 15px; height: 15px; }
/* Un'icona SVG di `_barra.html` senza una regola sua prende la misura del
   testo intorno, invece dei 300 pixel che il browser darebbe a un SVG nudo. */
.ic { width: 1.1em; height: 1.1em; flex: none; vertical-align: -0.15em; }

/* selettore di lingua: due sigle, quella attiva in evidenza. Sta accanto al
   menu utente e non dentro, perché serve anche a chi non è ancora entrato:
   sulla pagina di accesso il menu utente non c'è. */
.lingua { display: flex; border: 1px solid var(--grid); border-radius: 999px; overflow: hidden; }
.lingua button {
  border: 0; background: none; cursor: pointer; font: inherit;
  font-size: .74rem; font-weight: 700; letter-spacing: .04em;
  padding: 4px 9px; color: var(--ink-3);
}
.lingua button:hover { background: var(--bg); color: var(--ink); }
.lingua button.on { background: var(--accent-soft); color: var(--accent-strong); }
.lingua button.on:hover { background: var(--accent-soft); }
/* Il riassunto della rosa: quante persone per fascia e chi è il più vicino.
   Sta in cima ai risultati perché è la risposta alla domanda con cui si è
   arrivati sulla pagina, e le pastiglie sono ancore alle tre fasce. */
.rosa-sintesi { padding: 12px 16px; margin-bottom: 12px; }
.rosa-conte { display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin: 0 0 6px; }
.rosa-conte .badge { text-decoration: none; }
.rosa-conte .badge b { font-size: 1.05em; }
.rosa-migliore { margin: 0; color: var(--ink-2); display: flex;
  flex-wrap: wrap; gap: 8px; align-items: center; }

/* I nomi degli indispensabili che mancano, nella riga chiusa della scheda:
   è il dato su cui si sceglie fra proporre e scartare. */
.m-manca { color: var(--bad-tx); font-size: .78rem; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* E quelli coperti solo in parte, che sono la ragione per cui una persona
   con tutto coperto resta «adatta» invece che «ideale». Stessa forma della
   riga sopra perché si leggono insieme, tono d'avviso e non di errore: la
   persona quel requisito ce l'ha, solo non al livello che la richiesta
   chiede. */
.m-parziale { color: var(--warn-tx); font-size: .78rem; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* sulla pagina di accesso non c'è la barra: il selettore sta in alto a
   destra, sopra la scheda, dove lo si cerca comunque */
.lingua-login {
  position: absolute; top: 18px; right: 18px; z-index: 2;
  background: var(--card, #fff);
}
.login-body { position: relative; }

/* menu utente (identità Google) */
.usermenu { position: relative; }
.usermenu > summary {
  display: flex; align-items: center; gap: 8px; cursor: pointer;
  padding: 4px 10px 4px 4px; border-radius: 999px; list-style: none;
  border: 1px solid transparent;
}
.usermenu > summary::-webkit-details-marker { display: none; }
.usermenu > summary::marker { content: ""; }
.usermenu > summary:hover { background: var(--bg); border-color: var(--grid); }
.usermenu[open] > summary { background: var(--bg); border-color: var(--grid); }
.usermenu[open] .caret { transform: rotate(180deg); }
.usermenu .avatar {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  background: var(--accent-soft); color: var(--accent-strong);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; letter-spacing: 0.3px;
}
.usermenu .avatar.is-admin { background: var(--accent); color: #fff; }
.usermenu .who { display: flex; flex-direction: column; line-height: 1.15; }
.usermenu .who b { font-size: 13px; font-weight: 600; }
.usermenu .who small { font-size: 11px; color: var(--ink-3); }
.usermenu .caret { color: var(--ink-3); font-size: 11px; transition: transform 0.15s ease; }
.usermenu .menu {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 60;
  min-width: 258px; background: #fff; border: 1px solid var(--grid);
  border-radius: 12px; box-shadow: 0 16px 38px rgba(11, 11, 11, 0.16);
  padding: 6px; display: flex; flex-direction: column;
}
.usermenu .menu-mail {
  font-size: 12px; color: var(--ink-3); padding: 8px 10px 10px;
  border-bottom: 1px solid var(--bg); margin-bottom: 4px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.usermenu .menu a, .usermenu .menu button {
  display: block; text-align: left; padding: 8px 10px; border-radius: 8px;
  color: var(--ink); background: none; border: none; cursor: pointer;
  font: inherit; font-size: 13.5px; line-height: 1.3; width: 100%;
}
.usermenu .menu a:hover, .usermenu .menu button:hover { background: var(--bg); text-decoration: none; }
.usermenu .menu form { margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--bg); }
.usermenu .menu button { color: var(--bad-tx); font-weight: 550; }
.usermenu .menu button:hover { background: var(--bad-bg); }
@media (max-width: 900px) { .usermenu .who { display: none; } }

/* sotto-navigazione (catalogo, analisi, amministrazione) */
.subnav {
  display: flex; gap: 6px; margin-bottom: 16px;
  border-bottom: 1px solid var(--grid);
  /* Come la barra principale: quando le voci non ci stanno la riga scorre,
     invece di mandare a capo l'etichetta e la sua pastiglia in due righe
     scalene. Una voce spezzata a meta' si legge peggio di una voce fuori
     campo, perche' sembra un guasto. */
  overflow-x: auto; scrollbar-width: none;
}
.subnav::-webkit-scrollbar { display: none; }
.subnav a {
  padding: 8px 14px; color: var(--ink-2); font-weight: 550; font-size: 14px;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  white-space: nowrap; flex: none;
}
.subnav a:hover { color: var(--ink); text-decoration: none; }
.subnav a.active { color: var(--accent-strong); border-bottom-color: var(--accent); }
.subnav a span {
  font-size: 11.5px; color: var(--ink-3); background: var(--bg);
  border-radius: 999px; padding: 1px 7px; margin-left: 4px; font-weight: 600;
}

/* ------------------------------------------------- richiamo sulla freschezza */
.nudge {
  background: var(--warn-bg); color: var(--warn-tx);
  border-bottom: 1px solid rgba(138, 90, 0, 0.18);
}
.nudge-inner {
  max-width: 1180px; margin: 0 auto; padding: 10px 20px;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.nudge-ic { font-size: 16px; }
.nudge-txt { flex: 1; min-width: 240px; font-size: 13.5px; }
.nudge-txt b { font-weight: 650; }
.nudge .btn { background: var(--warn-tx); border-color: var(--warn-tx); }
.nudge .btn:hover { background: #6d4700; border-color: #6d4700; }
.nudge .btn-secondary {
  background: #fff; color: var(--warn-tx); border-color: rgba(138, 90, 0, 0.35);
}
.nudge .btn-secondary:hover { background: #fffaf0; border-color: var(--warn-tx); }
.nudge-close { color: var(--warn-tx); }
.nudge-close:hover { background: rgba(138, 90, 0, 0.14); color: var(--warn-tx); }

/* ---------------------------------------------------------------- layout */
.container { max-width: 1180px; margin: 0 auto; padding: 24px 20px 60px; }
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 18px; flex-wrap: wrap; }
.page-head p { margin: 0; color: var(--ink-2); }
.actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.footer {
  border-top: 1px solid var(--grid); color: var(--ink-3); font-size: 13px;
  padding: 16px 20px; text-align: center; background: var(--bg);
}
.grid-2 { display: grid; grid-template-columns: 2fr 1fr; gap: 18px; align-items: start; }
.grid-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); gap: 14px; }
.grid-charts { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 18px; }
.grid-charts .card.wide { grid-column: 1 / -1; }
/* La larghezza delle colonne la decide la griglia, non il loro contenuto. Una
   traccia `fr` ha per minimo il proprio min-content: basta UNA parola che non
   va a capo (il nome di un file di CV, l'URL di una certificazione, una sigla
   incollata da un CV) perche' la colonna che la contiene si allarghi fino a
   contenerla, schiacci l'altra al suo minimo e mandi la pagina in scorrimento
   orizzontale. Il profilo si legge male solo a chi ha quel dato: per tutti gli
   altri la stessa pagina e' a posto, ed e' per questo che in prova non si vede.
   Scritto sul contenitore e non sul singolo caso, vale anche per le colonne che
   verranno. Fuori restano le griglie con tracce `auto` (`.kv`), dove misurarsi
   sul contenuto e' proprio cio' che si vuole. */
.grid-2 > *, .grid-cards > *, .grid-charts > *, .layout-search > * { min-width: 0; }
@media (max-width: 900px) { .grid-2 { grid-template-columns: 1fr; } }

/* Titolo che separa due letture diverse nella stessa pagina */
h2.sezione {
  margin: 26px 0 14px; font-size: 17px; display: flex; align-items: baseline;
  gap: 10px; flex-wrap: wrap; padding-bottom: 8px; border-bottom: 1px solid var(--grid);
}
h2.sezione small { font-weight: 400; font-size: 13px; color: var(--ink-3); }

/* ---------------------------------------------------------------- card */
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; padding: 18px;
  box-shadow: 0 1px 2px rgba(11, 11, 11, 0.04);
  /* Tenuta la colonna, la parola piu' larga di lei va spezzata: senza, uscirebbe
     comunque dal riquadro. Interviene solo quando non ci sta: il testo normale
     continua ad andare a capo fra le parole. */
  overflow-wrap: break-word;
}
/* Distanza sopra una scheda impilata. Due proprietà volute:
   1. vale SOLO nel flusso della pagina: la scheda dev'essere figlia diretta
      di un contenitore semantico, mai di un `<div>` di layout. Dentro griglie
      e colonne flex la distanza la dà `gap`, e questo margine sposterebbe in
      basso tutte le schede tranne la prima: la riga si allunga e la prima
      risulta più alta delle altre. Scritto così il difetto non può tornare in
      una griglia nuova: è già successo tre volte con un elenco di eccezioni
      al posto di questa regola;
   2. non guarda *cosa* c'è sopra: `.card + .card` lasciava attaccata una
      scheda preceduta da un form o da un titolo. Con i margini adiacenti che
      collassano, il risultato è la distanza maggiore fra le due, mai la somma. */
:is(main, form, section, aside, details) > .card:not(:first-child) { margin-top: 14px; }
.card h2 { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.card h2 small { font-weight: 500; color: var(--ink-3); font-size: 12px; }

/* ---------------------------------------------------------------- buttons */
/* `font-family` e `line-height` espliciti: senza, un `<button class="btn">`
   prende il carattere del browser (Arial su Windows) e un'interlinea stretta,
   mentre un `<a class="btn">` eredita quelli della pagina. Stessa classe, due
   pulsanti diversi, 5 px di altezza di scarto: si vedeva appena un link e un
   modulo stavano affiancati, come «Scarica il CV» e «Rileggi il CV» in testa
   alla scheda di una candidatura. L'interlinea è quella che i `<button>`
   avevano già (1.2), non quella della pagina: sono il doppio dei link, e
   stanno accanto ai campi dei moduli, che con 1.5 sarebbero rimasti bassi
   di fianco a un pulsante cresciuto. */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--accent); color: #fff; border: 1px solid var(--accent);
  padding: 8px 14px; border-radius: 8px; font-family: inherit;
  font-size: 14px; font-weight: 550; line-height: 1.2;
  cursor: pointer; text-decoration: none;
}
.btn:hover { background: var(--accent-strong); border-color: var(--accent-strong); text-decoration: none; }
/* Un pulsante spento deve VEDERSI spento. Senza questa regola restava
   identico a uno acceso: il match lo spegne quando c'è già una ricerca in
   corso e la pulizia del catalogo quando manca il modello, e in entrambi i
   casi si continuava a premere un pulsante che non faceva niente. */
.btn:disabled, .btn[disabled] {
  background: var(--grid); border-color: var(--grid); color: var(--ink-3);
  cursor: not-allowed;
}
.btn:disabled:hover, .btn[disabled]:hover {
  background: var(--grid); border-color: var(--grid);
}
.btn-secondary { background: #fff; color: var(--ink); border-color: var(--baseline); }
.btn-secondary:hover { background: var(--bg); border-color: var(--ink-3); }
.btn-danger { background: #fff; color: var(--bad-tx); border-color: var(--bad-tx); }
.btn-danger:hover { background: var(--bad-bg); border-color: var(--bad-tx); }
.btn-sm { padding: 5px 10px; font-size: 13px; }
.btn-ghost { background: none; border: none; color: var(--ink-3); cursor: pointer; font-size: 16px; padding: 4px 8px; border-radius: 6px; }
.btn-ghost:hover { background: var(--bad-bg); color: var(--bad-tx); }

/* ---------------------------------------------------------------- forms */
form { margin: 0; }
.field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
.field label { font-size: 13px; font-weight: 550; color: var(--ink-2); }
.field input, .field select, .field textarea, .row-item input, .row-item select, .row-item textarea {
  padding: 8px 10px; border: 1px solid var(--baseline); border-radius: 8px;
  font: inherit; font-size: 14px; background: #fff; color: var(--ink); width: 100%;
}
.field input:focus, .field select:focus, .field textarea:focus,
.row-item input:focus, .row-item select:focus, .row-item textarea:focus {
  outline: 2px solid var(--accent-soft); border-color: var(--accent);
}
.field textarea { min-height: 90px; resize: vertical; }
.field-row { display: grid; gap: 12px; }
.cols-2 { grid-template-columns: 1fr 1fr; }
.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
.cols-4 { grid-template-columns: 1fr 1fr 1fr 1fr; }
@media (max-width: 700px) { .cols-2, .cols-3, .cols-4 { grid-template-columns: 1fr; } }
.hint { font-size: 12.5px; color: var(--ink-3); margin-top: 2px; }
/* Una casella dentro un .field: `.field input { width: 100% }` la stirerebbe per
   tutta la riga spingendo il testo sotto. `.opt` la riporta a 15px: qui si
   toglie il nowrap, che serve alle barre strumenti e non a una impostazione. */
.field .opt { white-space: normal; align-items: flex-start; }
.field .opt input { flex: none; margin-top: 1px; }

/* righe dinamiche */
.row-list { display: flex; flex-direction: column; gap: 8px; }
.row-item {
  display: grid; gap: 8px; align-items: start;
  padding: 8px; border: 1px solid var(--grid); border-radius: 10px; background: #fff;
}
.row-skill { grid-template-columns: 2fr 130px 90px 36px; }
.row-lang, .row-cert { grid-template-columns: 2fr 150px 36px; }
/* Un'esperienza è la riga più densa del profilo, dodici campi, e va letta
   come una scheda, non come una fila di caselle: due file di campi corti, poi
   i due testi lunghi a tutta larghezza. Le etichette costano una riga a campo
   e la restituiscono tutta: un segnaposto sparisce appena si scrive, e in
   rilettura restavano dodici riquadri pieni di testo e senza nome. */
.row-exp { grid-template-columns: 1fr 36px; padding: 12px; }
.row-exp > .btn-ghost { margin-top: 19px; }   /* in linea con il primo campo, non con la sua etichetta */
.row-exp .exp-corpo { display: grid; gap: 10px; }
.row-exp .exp-fila { display: grid; gap: 10px; align-items: end; }
.row-exp .exp-fila-1 { grid-template-columns: 170px 1fr 1fr 1fr; }
/* anno e mese in coppia, prima l'inizio e poi la fine; l'ultima colonna è
   vuota di proposito, così date e impegno restano della loro misura invece di
   stirarsi per tutta la riga */
.row-exp .exp-fila-2 { grid-template-columns: 100px 150px 110px 150px 130px 1fr; }
.row-item .campo { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.row-item .campo > span { font-size: 12px; font-weight: 550; color: var(--ink-2); }
.row-item .campo > span i { font-style: normal; font-weight: 400; color: var(--ink-3); }
.row-item textarea { resize: vertical; line-height: 1.45; }
.row-tri { grid-template-columns: 2fr 1fr 90px 36px; }
@media (max-width: 800px) {
  .row-skill, .row-lang, .row-cert, .row-tri { grid-template-columns: 1fr 1fr; }
  .row-exp .exp-fila-1, .row-exp .exp-fila-2 { grid-template-columns: 1fr 1fr; }
}
.add-row { margin-top: 10px; }

/* ---------------------------------------------------------------- filtri */
.layout-search { display: grid; grid-template-columns: 270px 1fr; gap: 18px; align-items: start; }
@media (max-width: 900px) { .layout-search { grid-template-columns: 1fr; } }
.filters .field { margin-bottom: 10px; }
.filters select[multiple] { min-height: 150px; }

/* ---------------------------------------------------------------- skill picker */
.skillpicker {
  border: 1px solid var(--baseline); border-radius: 10px; background: #fff;
  display: flex; flex-direction: column; overflow: hidden;
}
.sp-head { display: flex; gap: 6px; padding: 8px; border-bottom: 1px solid var(--grid); align-items: center; }
.sp-search {
  flex: 1; min-width: 0; border: 1px solid var(--grid); border-radius: 7px;
  padding: 6px 9px; font: inherit; font-size: 13px;
}
.sp-search:focus { outline: 2px solid var(--accent-soft); border-color: var(--accent); }
.sp-expand, .sp-close, .sp-chip button {
  border: none; background: none; cursor: pointer; color: var(--ink-3);
  border-radius: 6px; padding: 4px 7px; font-size: 14px; line-height: 1;
}
.sp-expand:hover, .sp-close:hover { background: var(--bg); color: var(--ink); }
.sp-close, .sp-footer { display: none; }
.sp-selected {
  display: none; flex-wrap: wrap; gap: 5px; padding: 8px;
  border-bottom: 1px dashed var(--grid);
}
.sp-selected.has-items { display: flex; }
.sp-chip {
  display: inline-flex; align-items: center; gap: 2px;
  background: var(--accent-soft); color: var(--accent-strong);
  border-radius: 999px; padding: 2px 4px 2px 10px; font-size: 12.5px; font-weight: 550;
}
.sp-chip button { color: var(--accent-strong); font-size: 12px; padding: 2px 6px; border-radius: 999px; }
.sp-chip button:hover { background: rgba(28, 92, 171, 0.15); }
.sp-list { max-height: 230px; overflow-y: auto; padding: 4px 8px 8px; }
.sp-group { break-inside: avoid; }
.sp-cat {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--ink-3); font-weight: 650; margin: 9px 0 3px;
}
.sp-item {
  display: flex; gap: 8px; align-items: center; font-size: 13.5px;
  padding: 3px 5px; border-radius: 6px; cursor: pointer; user-select: none;
}
.sp-item:hover { background: var(--bg); }
.sp-item input { accent-color: var(--accent); width: 15px; height: 15px; margin: 0; flex: none; }
.sp-noresults { color: var(--ink-3); font-size: 13px; padding: 10px 4px; }
/* vista espansa (finestra sopra la pagina, stesso form: nessuna perdita di stato) */
.sp-backdrop { position: fixed; inset: 0; background: rgba(11, 11, 11, 0.45); z-index: 90; }
.skillpicker.sp-expanded {
  position: fixed; z-index: 100; top: 7vh; left: 50%; transform: translateX(-50%);
  width: min(920px, 94vw); max-height: 84vh;
  box-shadow: 0 18px 50px rgba(11, 11, 11, 0.28); border-radius: 14px;
}
.skillpicker.sp-expanded .sp-close { display: inline-flex; }
.skillpicker.sp-expanded .sp-footer {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 14px; border-top: 1px solid var(--grid); background: var(--bg);
}
.sp-count { font-size: 13px; color: var(--ink-2); }
.skillpicker.sp-expanded .sp-list {
  max-height: none; flex: 1; column-width: 240px; column-gap: 22px; padding: 6px 16px 14px;
}
.skillpicker.sp-expanded .sp-head { padding: 12px 14px; }
.skillpicker.sp-expanded .sp-search { font-size: 14px; padding: 8px 11px; }

/* ---------------------------------------------------------------- match */
.match-bar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  padding: 10px 14px; margin-bottom: 12px;
}
.match-bar .sel-count { font-size: 12.5px; color: var(--ink-3); flex: 1; min-width: 180px; }
/* Quanto è costata la ricerca. Una rosa di cinque nomi non dice da quanti
   profili è stata tirata fuori, e senza quel numero sembra il risultato di una
   ricerca per parola chiave: sta sotto i risultati, discreta ma leggibile. */
.riga-lavoro {
  font-size: 13px; color: var(--ink-2); line-height: 1.6;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; padding: 10px 14px; margin: 14px 0 0;
}
.riga-lavoro b { color: var(--ink); font-weight: 650; }
.opt, .opt-anon {
  display: inline-flex; align-items: center; gap: 7px; font-size: 13px;
  color: var(--ink-2); cursor: pointer; user-select: none; white-space: nowrap;
}
.opt input, .opt-anon input { accent-color: var(--accent); width: 15px; height: 15px; margin: 0; }
/* Scheda candidato: chiusa risponde a «chi è, quanto copre, è libero?»,
   aperta mostra requisito per requisito. È un <details>: si apre con un clic
   o da tastiera, senza una riga di JavaScript. */
.match-card { padding: 0; overflow: hidden; }
.match-card > summary {
  list-style: none; cursor: pointer; padding: 13px 15px;
  display: flex; gap: 10px; align-items: flex-start; position: relative;
}
.match-card > summary::-webkit-details-marker { display: none; }
.match-card > summary::after {
  content: "▾"; position: absolute; right: 12px; bottom: 10px;
  color: var(--ink-3); font-size: 11px; transition: transform .15s;
}
.match-card[open] > summary::after { transform: rotate(180deg); }
.match-card > summary:hover { background: var(--bg); }
.match-card > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.match-card:has(input[name="sel"]:checked) {
  border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft);
}
.m-pick { display: flex; align-items: flex-start; padding-top: 2px; cursor: pointer; }
.m-pick input { accent-color: var(--accent); width: 16px; height: 16px; margin: 0; }
.m-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
/* Le righe chiuse sono tutte alte uguali (app.js le pareggia, LLF-003.15.2):
   il corpo occupa tutta l'altezza e «Proponi» va in fondo, alla stessa
   altezza in ogni scheda della fila. */
.match-card > summary > .m-body { align-self: stretch; }
.m-head { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.m-name {
  font-size: 15.5px; font-weight: 650; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.m-score { font-weight: 650; font-size: 14px; color: var(--ink-2); flex: none; }
.m-role {
  color: var(--ink-2); font-size: 12.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Striscia di copertura: un quadretto per requisito. È il segnale che si
   legge senza fermarsi a contare: verde coperto, ambra sotto livello,
   contorno rosso mancante. */
.m-cover { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.pallini { display: inline-flex; gap: 3px; flex-wrap: wrap; }
.pallini i { width: 9px; height: 9px; border-radius: 3px; display: block; }
.pallini i.ok { background: var(--ok-tx); }
.pallini i.pt { background: var(--warn-tx); }
.pallini i.no { background: transparent; border: 1px dashed var(--bad-tx); }
.pallini i.af { background: var(--accent-soft); border: 1px solid var(--accent); }
/* requisito che il profilo non dichiara ma che i progetti provano */
.pallini i.pr { background: var(--ok-bg); border: 1px solid var(--ok-tx); }
.m-cover-n { color: var(--ink-3); white-space: nowrap; }
.m-occ { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; font-size: 12px; }
/* Nella riga chiusa l'occupazione sta su una riga sola: andava a capo per
   «senza data di rilascio», e una scheda sola alta una riga in più rendeva
   più alte tutte le altre (LLF-003.15.2). Quel che non ci sta si accorcia,
   e per intero si legge aprendo la scheda. */
.match-card > summary .m-occ { flex-wrap: nowrap; min-width: 0; overflow: hidden; }
.match-card > summary .m-occ > * { flex: none; }
.match-card > summary .m-occ > .m-free {
  flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.m-sede { color: var(--ink-2); white-space: nowrap; }
.m-free { color: var(--ink-2); }
.m-free.none { color: var(--ink-3); font-style: italic; }
/* «Proponi» sulla riga chiusa (SYS-001 LLF-004.1.1): l'ultima riga della
   scheda, piccola e secondaria, perché la scheda resta una cosa da leggere e
   non un modulo. A destra lascia il posto alla freccia che apre la scheda. */
.m-proponi {
  margin-top: auto;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 12px; padding-right: 16px; cursor: default;
}
.m-proponi .btn-sm { padding: 3px 11px; font-size: 12.5px; }
.m-togli {
  background: none; border: none; padding: 0; cursor: pointer;
  font: inherit; font-size: 12px; color: var(--ink-3); text-decoration: underline;
}
.m-togli:hover { color: var(--bad-tx); }
.m-togli:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
.m-detail { padding: 12px 15px 14px; border-top: 1px dashed var(--grid); }

/* I requisiti della scheda aperta, raccolti per esito e chiusi: l'intestazione
   dice quanti sono e ne anticipa tre, i colori sono gli stessi dei quadretti
   della riga chiusa, tratteggiati dove la copertura non è dichiarata (prove,
   mancanti), come i quadretti corrispondenti. */
.req-gruppi { display: flex; flex-direction: column; }
.req-gruppo > summary {
  list-style: none; cursor: pointer;
  display: flex; flex-wrap: wrap; align-items: baseline;
  /* i nomi vanno a capo sotto il titolo: fra le due righe il respiro è quello
     di una didascalia, non lo stesso spazio che separa titolo e conteggio */
  column-gap: 7px; row-gap: 2px;
  padding: 5px 0; font-size: 12px; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--ink-2);
}
.req-gruppo > summary::-webkit-details-marker { display: none; }
.req-gruppo > summary:hover { color: var(--ink); }
.req-gruppo > summary:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px;
}
.req-gruppo .g-tit {
  padding-left: 9px; border-left: 3px solid var(--tono); --tono: var(--grid);
}
.req-gruppo .g-n {
  font-weight: 700; font-size: 13px; letter-spacing: 0; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
/* «n indispensabili» sta su ogni gruppo, e prende il tono del gruppo: fra i
   coperti è una buona notizia, fra i mancanti un motivo per scartare. Un solo
   rosso per tutti avrebbe fatto sembrare un allarme anche «3 indispensabili»
   scritto accanto ai requisiti coperti al livello richiesto.
   Il blu è quello forte: a 11,5px l'accento normale non arriva al 4,5:1. */
.req-gruppo .g-must {
  text-transform: none; letter-spacing: 0; font-size: 11.5px; color: var(--ink-2);
}
.g-ok .g-must, .g-prova .g-must { color: var(--ok-tx); }
.g-partial .g-must { color: var(--warn-tx); }
.g-related .g-must { color: var(--accent-strong); }
.g-miss .g-must { color: var(--bad-tx); }
.req-gruppo .apri-chiudi {
  margin-left: auto; color: var(--ink-3); font-size: 11px; transition: transform 0.15s;
}
.req-gruppo[open] .apri-chiudi { transform: rotate(180deg); }
/* I tre nomi servono a decidere se aprire: aperto il gruppo ci sono davvero,
   e ripeterli sarebbe la stessa riga scritta due volte. */
.req-gruppo .g-anteprima {
  flex: 1 1 100%; padding-left: 12px; text-transform: none; letter-spacing: 0;
  font-size: 12px; line-height: 1.35; color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.req-gruppo[open] .g-anteprima { display: none; }
.req-gruppo > .chips { padding: 2px 0 9px 12px; }
.req-gruppo .prove-lista { margin-left: 12px; }
.g-ok .g-tit { --tono: var(--ok-tx); }
.g-partial .g-tit { --tono: var(--warn-tx); }
.g-related .g-tit { --tono: var(--accent); }
.g-prova .g-tit { --tono: var(--ok-tx); border-left-style: dashed; }
.g-miss .g-tit { --tono: var(--bad-tx); border-left-style: dashed; }
/* la lettura del profilo riguarda tutta la persona, non un gruppo: staccata */
.m-sintesi { padding-top: 10px; border-top: 1px dashed var(--grid); }
.m-links { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 10px; font-size: 13px; }
.chip.m-ok { background: var(--ok-bg); color: var(--ok-tx); border-color: transparent; }
.chip.m-ok b { color: var(--ok-tx); }
.chip.m-partial { background: var(--warn-bg); color: var(--warn-tx); border-color: transparent; }
.chip.m-partial b { color: var(--warn-tx); }
.chip.m-miss { background: #fff; color: var(--bad-tx); border: 1px dashed var(--bad-tx); }
/* requisito coperto solo da una competenza affine (es. Angular per React) */
.chip.m-related { background: var(--accent-soft); color: var(--accent-strong); border-color: transparent; }
.chip.m-related b { color: var(--accent-strong); }
/* requisito non dichiarato nel profilo ma provato dai progetti */
.chip.m-prova { background: #fff; color: var(--ok-tx); border: 1px solid var(--ok-tx); }
.chip.m-prova b { color: var(--ok-tx); }
/* requisito non dichiarato ma SCRITTO nel profilo (progetti, CV): copre come
   una competenza dichiarata, stesso verde, ma con il bordo tratteggiato, che
   dice da dove viene e che quel profilo andrebbe sistemato */
/* «Avevi cercato…»: l'offerta di riprendere l'ultima ricerca */
.ripresa {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 0 0 14px; padding: 9px 12px; border-radius: 10px;
  background: var(--accent-soft); color: var(--accent-strong); font-size: 13px;
}
/* Perché una persona è finita nei risultati della ricerca libera */
.person-card .perche {
  margin: 8px 0 0; padding: 7px 9px; border-radius: 8px;
  background: var(--accent-soft); font-size: 12px; line-height: 1.45;
}
.perche-dove { color: var(--accent-strong); font-weight: 600; }
.perche-testo { display: block; margin-top: 3px; color: var(--ink-2); }
/* Schede oltre il tetto delle prime venti: già nella pagina, nascoste finché
   non le si chiede. Nessun ricalcolo per vedere la ventunesima persona. */
.oltre-tetto { display: none; }
.oltre-tetto.visibile { display: block; }
/* Mentre si cerca fra le schede contano tutte, anche quelle oltre le prime
   venti, e la riga che parla delle prime venti non ha senso. */
.cercando .oltre-tetto { display: block; }
.cercando .mostra-oltre { display: none; }
/* La ricerca veloce sulle schede (LLF-003.15.1) */
.cerca-schede {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 0 0 12px;
}
.cerca-schede input {
  flex: 0 1 420px; min-width: 0; padding: 8px 12px; font: inherit; font-size: 14px;
  border: 1px solid var(--baseline); border-radius: 8px; background: #fff; color: var(--ink);
}
.cerca-schede input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
/* I profili senza scheda che la ricerca trova lo stesso: sotto il campo, a
   tutta riga, con il loro «Proponi». */
.cerca-altri { flex: 1 0 100%; }
.cerca-altri > p { margin: 0 0 6px; }
.cerca-altri ul { list-style: none; margin: 0; padding: 0; max-width: 620px;
                  border: 1px solid var(--baseline); border-radius: 8px; background: #fff; }
.cerca-altri li { display: flex; align-items: center; justify-content: space-between;
                  gap: 12px; padding: 6px 10px; }
.cerca-altri li + li { border-top: 1px solid var(--baseline); }
.cerca-altri-chi { min-width: 0; overflow-wrap: anywhere; }
.mostra-oltre { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.chip.m-testo { background: var(--ok-bg); color: var(--ok-tx);
                border: 1px dashed var(--ok-tx); }
.chip.m-testo b { color: var(--ok-tx); font-weight: 600; }
/* Scheda di segnalazione nella colonna del profilo: non è un errore, è una
   cosa da guardare, il giallo dell'avviso, non il rosso. */
.card-avviso { border-color: var(--warn-tx); }
/* Le righe proposte nel form del profilo, spiegate prima dell'elenco */
.avviso-proposte {
  background: var(--warn-bg); color: var(--warn-tx); border-radius: 10px;
  padding: 10px 12px; margin-bottom: 10px; font-size: 13px;
}
.avviso-proposte ul { margin: 8px 0 0; padding-left: 18px; }
.avviso-proposte li { margin: 2px 0; }
/* elenco delle prove nella scheda aperta: ognuna cita la propria fonte */
.prove-lista { margin-top: 10px; border-top: 1px dashed var(--grid); padding-top: 10px; }
.prove-lista h4 { margin: 0 0 6px; font-size: 12.5px; color: var(--ink-2); }
.prove-lista .prova { font-size: 12.5px; color: var(--ink-2); padding: 3px 0; }
.prove-lista .prova b { color: var(--ink); }
.prove-lista .fonte { color: var(--ink-3); }
/* Le competenze da confermare (`_proposte.html`): una per riga. In testa il
   nome, i segni da dove viene (AI, dedotta, nuova) e i fatti per scegliere il
   livello; il «non è mia» in fondo alla riga e in tono minore, perché è il
   gesto meno frequente. Sotto, la prova: è la ragione per cui la proposta
   esiste, e chi conferma la legge prima di tutto il resto. */
.proposte-lista { display: grid; gap: 2px; margin: 4px 0 0; }
.proposta { padding: 6px 0; border-bottom: 1px solid var(--bg); font-size: 13px; }
.proposta:last-child { border-bottom: none; }
.proposta-testa { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.proposta-testa .fatti { color: var(--ink-3); font-size: 12.5px; }
.proposta-testa form { margin-left: auto; }
.proposta .prova-testo { color: var(--ink-3); font-size: 12.5px; margin-top: 2px; }
.proposta .btn-ghost, .rifiutate .btn-ghost {
  font-size: 12.5px; text-decoration: underline;
  text-decoration-color: var(--baseline); text-underline-offset: 3px; padding: 0 2px;
}
.proposta .btn-ghost:hover { background: none; color: var(--bad-tx); }
.rifiutate .btn-ghost:hover { background: none; color: var(--accent-strong); }
.rifiutate ul { margin: 6px 0 0; padding-left: 18px; font-size: 12.5px; color: var(--ink-2); }
.rifiutate li form { display: inline; }
.avviso-proposte .proposte-lista { margin-top: 8px; }
.gap-segni { display: inline-flex; gap: 6px; flex-wrap: wrap; margin-left: auto; }
.prove-sintesi { margin-top: 8px; font-size: 13px; color: var(--ink-2); font-style: italic; }
/* I sinonimi che il modello ha trovato per un requisito. Sono la parte che
   distingue questa ricerca da un Ctrl+F, e si vedono: verde come le coperture
   piene, perché è quello che valgono. */
.affini-hint .grafie-hint { color: var(--ok-tx); }
.affini-hint .grafie-hint b { font-weight: 600; }
/* affinità proposte sotto la riga del requisito, nell'editor del match */
.row-skill .affini-hint, .row-cert .affini-hint {
  grid-column: 1 / -1; font-size: 12px; color: var(--ink-3);
  margin: -2px 0 2px 2px;
}

/* documento con più posizioni richieste: si sceglie quale guardare */
.scelta-ruolo { border-left: 3px solid var(--accent); margin-bottom: 16px; }
.scelta-ruolo .field { margin: 0; max-width: 520px; }

/* Salvare la ricerca nello storico, o solo provarla. Un riquadro con le due
   opzioni scritte per esteso e non una casella da spuntare: le conseguenze
   sono diverse (una entra nelle statistiche dell'azienda, l'altra scade da
   sola) e vanno lette tutte e due, non indovinate da un'etichetta sola. */
.scelta-salva {
  border: 1px solid var(--grid); border-radius: 10px;
  padding: 10px 12px; background: var(--surface); gap: 2px;
}
.scelta-salva-titolo {
  font-size: 13px; font-weight: 550; color: var(--ink-2); margin-bottom: 2px;
}
/* Le due voci vanno a capo: la seconda è una frase, non un'etichetta, e con
   il `nowrap` di `.opt` usciva dal riquadro. */
.scelta-salva .opt { white-space: normal; align-items: flex-start; margin-top: 6px; }
.scelta-salva .opt input { flex: none; margin-top: 2px; }
.scelta-salva .hint { margin: 2px 0 0 22px; }
.ruoli-riepilogo { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.ruolo-chip {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  background: var(--bg); border: 1px solid var(--grid); color: var(--ink-2);
  padding: 5px 10px; border-radius: 999px; font-size: 12.5px; font-family: inherit;
}
.ruolo-chip:hover { border-color: var(--accent); }
.ruolo-chip.attivo { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-strong); }
.ruolo-titolo { margin-top: 0; }

/* fasce: il taglio fra «proponibile» e «ripiego» deve vedersi a colpo d'occhio */
.fascia { margin-bottom: 18px; }
.fascia > h3 {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin: 0 0 10px; font-size: 14px; font-weight: 650;
}
.fascia > h3 small { font-weight: 400; color: var(--ink-3); font-size: 12.5px; }
/* `align-items: start` è quel che permette a una scheda di espandersi senza
   allungare le vicine della stessa riga. */
.fascia-cards {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: 12px; align-items: start;
}
.fascia.ideale .match-card { border-left: 3px solid var(--ok-tx); }
.fascia.adatto .match-card { border-left: 3px solid var(--accent); }
.fascia.minimo .match-card { border-left: 3px solid var(--warn-tx); }

/* occupazione: su cosa, con che quota, fino a quando. Un elenco che si
   chiude (nasce aperto), una riga per progetto con quota e fine in colonna,
   poi la frase sul rilascio. `container-type` fa scegliere la forma delle
   righe alla larghezza del riquadro e non a quella dello schermo: lo stesso
   elenco sta a tutta pagina nel profilo e in una scheda stretta nel match. */
.occ {
  display: flex; flex-direction: column; align-items: stretch; gap: 6px;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--grid);
  font-size: 13px; color: var(--ink-2);
  container-type: inline-size;
}
.occ-tit {
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--ink-3);
}
.occ-impegni > summary {
  list-style: none; cursor: pointer; user-select: none;
  display: flex; align-items: baseline; gap: 8px;
  padding: 4px 7px; margin: 0 -7px; border-radius: 8px;
}
.occ-impegni > summary::-webkit-details-marker { display: none; }
/* la stessa freccia di «Perché non è al 100%» */
.occ-impegni > summary::before {
  content: ""; flex: none; align-self: center;
  width: 6px; height: 6px; margin: 0 2px 0 1px;
  border-right: 1.5px solid var(--ink-3); border-bottom: 1.5px solid var(--ink-3);
  transform: rotate(-45deg); transition: transform 0.15s;
}
.occ-impegni[open] > summary::before { transform: rotate(45deg); }
.occ-impegni > summary:hover { background: var(--bg); }
.occ-impegni > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 0; }
.occ-impegni > summary .occ-tit { flex: none; white-space: nowrap; }
.occ-n { flex: none; font-size: 12px; color: var(--ink-3); white-space: nowrap; }
/* Chiuso, l'elenco resta leggibile in una riga: i nomi con la quota. */
.occ-anteprima {
  flex: 1 1 auto; min-width: 0; font-size: 12.5px; color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.occ-impegni[open] .occ-anteprima { display: none; }
/* Le righe condividono le colonne (subgrid): quote e fini si allineano anche
   quando i nomi hanno lunghezze diverse, e la colonna dei nomi non si allarga
   oltre il più lungo, così la quota resta vicina al suo progetto. */
.occ-lista {
  list-style: none; margin: 2px 0 0; padding: 0 0 0 17px;
  display: grid; grid-template-columns: fit-content(62%) auto auto;
  justify-content: start; column-gap: 18px;
}
.occ-lista.numerata { grid-template-columns: auto fit-content(62%) auto auto; column-gap: 12px; padding-left: 15px; }
.occ-voce {
  display: grid; grid-column: 1 / -1; grid-template-columns: subgrid;
  align-items: baseline; padding: 5px 0; border-top: 1px solid var(--bg);
}
.occ-voce:first-child { border-top: none; }
.occ-nome { color: var(--ink); min-width: 0; }
.occ-cliente { color: var(--ink-2); white-space: nowrap; }
.occ-nome .badge { margin-left: 4px; }
.occ-inizio { margin-left: 6px; font-size: 12px; color: var(--warn-tx); white-space: nowrap; }
.occ-quota { text-align: right; font-weight: 650; color: var(--ink); font-variant-numeric: tabular-nums; }
.occ-nd { color: var(--ink-3); font-weight: 500; cursor: help; }
.occ-fine { color: var(--ink-2); white-space: nowrap; }
.occ-fine.aperta { color: var(--ink-3); font-style: italic; }
.occ-offerta { margin: 6px 0 0 17px; font-size: 12.5px; color: var(--ink-3); }
/* Il numero che porta anche il segnalino di fine progetto nella scaletta: la
   stessa pastiglia nei due posti, perché l'occhio le colleghi. */
.occ-num, .sc-fine b {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  background: var(--ink-2); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums;
}
.occ-free { color: var(--ink); }
.occ-free.none { color: var(--ink-3); font-style: italic; }
/* In un riquadro stretto (la scheda del match) la fine va sotto il nome:
   tre colonne in 300px lasciavano al nome una parola per riga. */
@container (max-width: 520px) {
  .occ-lista { grid-template-columns: minmax(0, 1fr) auto; }
  .occ-lista.numerata { grid-template-columns: auto minmax(0, 1fr) auto; }
  .occ-fine { grid-column: -3 / -2; grid-row: 2; font-size: 12px; white-space: normal; }
  .occ-lista.numerata .occ-fine { grid-column: 2 / 3; }
}

/* nessun profilo ideale: cosa manca, e quindi cosa si cerca fuori */
.outsourcing { border-left: 3px solid var(--warn-tx); margin-bottom: 14px; }
.outsourcing > p { color: var(--ink-2); margin: 0 0 12px; }
.tab-copertura { width: 100%; border-collapse: collapse; font-size: 13px; }
.tab-copertura th {
  text-align: left; font-size: 11.5px; text-transform: uppercase;
  letter-spacing: .04em; color: var(--ink-3); font-weight: 600;
  padding: 0 10px 6px 0; border-bottom: 1px solid var(--grid);
}
.tab-copertura td { padding: 7px 10px 7px 0; border-bottom: 1px solid var(--grid); }
.tab-copertura tr.scoperto td { background: var(--bad-bg); }
.tab-copertura tr.scoperto b { color: var(--bad-tx); }
/* Ultima colonna: la ✕ che toglie dai gap un requisito che non lo è.
   Stretta e in fondo alla riga, perché è un gesto raro accanto a una lettura
   che si fa spesso: a portata di mano senza pesare su ogni riga. */
.tab-copertura td.tab-azione { width: 1%; padding-right: 0; text-align: right; }
.tab-copertura td.tab-azione .btn-ghost { font-size: 13px; padding: 2px 6px; }
/* una tabella non deve poter allargare la pagina: scorre dentro il suo riquadro */
.table-scroll { overflow-x: auto; }
/* Stato del motore AI: chi lavora (prima) e chi ha lavorato (dopo) */
.ai-stato {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: 999px; font-size: 12.5px; font-weight: 500;
}
.ai-stato.ok { background: var(--accent-soft); color: var(--accent-strong); }
.ai-stato.off { background: var(--bg); color: var(--ink-2); border: 1px solid var(--grid); }
.ai-stato.bad { background: var(--bad-bg); color: var(--bad-tx); }
.ai-stato b { font-weight: 650; }

/* Configurazione del motore AI */
.ai-form { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--grid); }
/* «Cosa esce da qui»: il testo inviato al modello accanto ai dati trattenuti.
   Le due colonne stanno affiancate perché il confronto è tutto il punto (a
   sinistra quello che parte, a destra quello che resta) e devono partire
   dalla stessa riga anche quando una è molto più alta dell'altra. */
.anteprima-invio { margin-top: 14px; }
.anteprima-invio > summary { font-weight: 650; font-size: 13.5px; }
.due-colonne {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 18px; align-items: start;
}
.due-colonne h4 {
  margin: 0 0 8px; font-size: 12px; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--ink-3);
}
pre.payload {
  white-space: pre-wrap; word-break: break-word; margin: 0;
  background: var(--bg); border: 1px solid var(--grid); border-radius: 10px;
  padding: 12px; font-size: 12px; line-height: 1.55; color: var(--ink-2);
  max-height: 420px; overflow: auto;
}
.ai-griglia { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 14px; }
.ai-griglia + .ai-griglia { margin-top: 14px; }
.ai-griglia .field { margin: 0; }
.ai-griglia label .badge { margin-left: 6px; vertical-align: 1px; }
/* un riquadro per provider: chiave e modello stanno insieme */
.ai-provider {
  border: 1px solid var(--grid); border-radius: 10px; padding: 4px 12px 12px; margin: 0;
}
.ai-provider legend {
  padding: 0 6px; font-size: 12.5px; font-weight: 650; color: var(--ink-2);
}
.ai-provider .field { margin: 0; }
.ai-provider .field + .field { margin-top: 12px; }
/* l'interruttore che cambia cosa esce dal server: sta attaccato alla nota */
.ai-prove {
  border: 1px solid var(--grid); border-left: 3px solid var(--accent-strong);
  border-radius: 10px; padding: 12px 14px; margin: 0 0 14px;
}
.ai-prove h3 { margin: 0 0 6px; }
.ai-prove p { margin: 0 0 10px; font-size: 13.5px; color: var(--ink-2); }
.ai-prove .actions { margin-top: 4px; }
.ai-vertex { margin-top: 14px; }
.ai-vertex > summary { cursor: pointer; font-size: 13.5px; color: var(--ink-2); }
.ai-form input:disabled, .ai-form select:disabled {
  background: var(--bg); color: var(--ink-3); cursor: not-allowed;
}
/* Il confine dei dati verso il modello: si legge PRIMA di incollare una chiave */
.nota-dati {
  border: 1px solid var(--border); border-left: 3px solid var(--ink-3);
  border-radius: 10px; padding: 10px 14px; margin: 0 0 14px; background: var(--bg);
  font-size: 13.5px; color: var(--ink-2);
}
.nota-dati ul { margin: 6px 0 0; padding-left: 18px; }
.nota-dati li + li { margin-top: 4px; }

/* Attesa dichiarata durante le operazioni lente */
.attesa {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
  display: flex; align-items: center; gap: 10px; z-index: 60;
  background: var(--ink); color: #fff; padding: 11px 18px; border-radius: 999px;
  font-size: 13.5px; box-shadow: 0 6px 20px rgba(11, 11, 11, .25);
  max-width: min(560px, 92vw);
}
.attesa .spin {
  width: 15px; height: 15px; flex: none; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .35); border-top-color: #fff;
  animation: gira .7s linear infinite;
}
/* La ✕: un download non cambia pagina e nessun evento dice «finito», chi ha
   già il file deve poter togliere l'annuncio senza aspettare che scada. */
.attesa-chiudi {
  flex: none; border: 0; background: none; color: rgba(255, 255, 255, .75);
  font: inherit; font-size: 13px; padding: 2px 4px; margin-left: 2px;
  cursor: pointer; border-radius: 6px;
}
.attesa-chiudi:hover { color: #fff; background: rgba(255, 255, 255, .18); }
@keyframes gira { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .attesa .spin { animation-duration: 2.4s; } }

.avviso { border-left: 3px solid var(--ink-3); }
.avviso.bad { border-left-color: var(--bad-tx); }
.avviso.info { border-left-color: var(--accent); }

/* La richiesta già analizzata proposta al posto di una seconda analisi.
   Il titolo e la sua riga di contesto da una parte, il pulsante che apre
   dall'altra: è la scelta principale, e deve stare sulla stessa riga di
   ciò che descrive, non in fondo al riquadro insieme a quello opposto. */
.doppione-riga {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap; margin: 10px 0 2px;
  padding: 10px 12px; background: var(--bg);
  border: 1px solid var(--grid); border-radius: 10px;
}
.doppione-titolo { font-weight: 650; font-size: 15px; }
.doppione-altre { margin: 0; padding-left: 18px; font-size: 13.5px; }
.doppione-altre li { margin: 2px 0; }
.jd-file input[type=file] { font-size: 13px; color: var(--ink-2); }

/* ---------------------------------------------------------------- persone */
.person-card { display: flex; flex-direction: column; gap: 8px; }
.person-card .head { display: flex; justify-content: space-between; gap: 8px; align-items: flex-start; }
.person-card .name { font-size: 16px; font-weight: 650; }
.person-card .role { color: var(--ink-2); font-size: 13.5px; }
.person-card .meta { color: var(--ink-3); font-size: 12.5px; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--bg); border: 1px solid var(--grid);
  padding: 3px 9px; border-radius: 999px; font-size: 12.5px; color: var(--ink-2);
}
.chip b { color: var(--ink); font-weight: 550; }

/* I requisiti di una richiesta riaperta, divisi fra indispensabili e gradite.
   L'etichetta sta in una colonna sua, così le due file di pastiglie partono
   dallo stesso margine e si confrontano a occhio: è la differenza che decide
   la fascia di ogni candidato più sotto, e prima stava nel `title` di una
   pastiglia, cioè invisibile a chi non ci passa sopra col mouse.
   Sotto i 620px la colonna sparisce e l'etichetta va sopra le sue pastiglie:
   a quella larghezza un gutter da 120px lascerebbe ai nomi una colonna in
   cui non ci sta nemmeno «Linux Embedded». */
.req-quali { display: grid; grid-template-columns: 120px 1fr; gap: 6px 12px;
  align-items: baseline; }
.req-quali .rq-tit { margin: 0; font-size: 12px; font-weight: 650;
  text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-3); }
/* Indispensabili in evidenza, gradite no: sono la regola e l'eccezione, non
   due categorie alla pari. Nessuno dei colori di copertura (verde, ambra,
   rosso, blu), che qui sotto significano già un'altra cosa sulle schede. */
.req-quali .rq-must { color: var(--ink); }
@media (max-width: 620px) {
  .req-quali { grid-template-columns: 1fr; gap: 2px; }
  .req-quali .rq-tit { margin-top: 8px; }
  .req-quali .rq-tit:empty { display: none; }
}

.dots { display: inline-flex; gap: 2px; }
.dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--grid); }
.dots i.on { background: var(--accent); }

.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: 999px; font-size: 12px; font-weight: 600;
  white-space: nowrap;
}
.badge.ok { background: var(--ok-bg); color: var(--ok-tx); }
.badge.warn { background: var(--warn-bg); color: var(--warn-tx); }
.badge.bad { background: var(--bad-bg); color: var(--bad-tx); }
.badge.neutral { background: var(--bg); color: var(--ink-2); border: 1px solid var(--grid); }
.badge.info { background: var(--accent-soft); color: var(--accent-strong); }
a.badge.info:hover { background: #d5e4f8; text-decoration: none; }

.avail { font-size: 12.5px; color: var(--ink-2); display: flex; align-items: center; gap: 8px; }
.avail .track { flex: 0 0 70px; height: 6px; border-radius: 4px; background: var(--grid); overflow: hidden; }
.avail .fill { height: 100%; background: var(--s3); border-radius: 4px; }

/* ---------------------------------------------------------------- pagine
   La barra sotto un elenco diviso in pagine. Numeri e passi hanno la stessa
   altezza e la stessa area cliccabile (36px, la misura minima comoda con il
   dito): allineati sulla stessa riga, un «Precedente» più alto dei numeri
   fa ballare la riga a ogni cambio di pagina.
   Il riquadro che si sta ricaricando resta VISIBILE e si smorza: sostituirlo
   con un vuoto farebbe saltare la pagina in su di mezzo schermo, che è
   esattamente ciò che il caricamento parziale doveva evitare. */
.risultati-testa { scroll-margin-top: 74px; }
.risultati-testa small { font-weight: 500; color: var(--ink-3); }
.risultati-testa:focus { outline: none; }
.risultati-testa:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
[data-risultati][aria-busy="true"] { opacity: .55; transition: opacity .12s ease-in; }
[data-risultati][aria-busy="true"] .paginazione { pointer-events: none; }

.paginazione {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  flex-wrap: wrap; margin: 18px 0 4px;
}
.pag-numeri { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.paginazione a, .paginazione span {
  min-width: 36px; height: 36px; padding: 0 10px; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13.5px; font-variant-numeric: tabular-nums;
}
.paginazione a {
  color: var(--ink); background: var(--surface); border: 1px solid var(--border);
}
.paginazione a:hover { background: var(--accent-soft); border-color: var(--accent); text-decoration: none; }
.paginazione a:active { transform: translateY(1px); }
.pag-num.corrente {
  background: var(--accent); border: 1px solid var(--accent); color: #fff; font-weight: 650;
}
/* Il passo che non c'è resta al suo posto, spento: toglierlo sposterebbe i
   numeri sotto il cursore proprio mentre si clicca il passo opposto. */
.pag-passo.off { color: var(--ink-3); opacity: .45; border: 1px solid transparent; }
.pag-salto { color: var(--ink-3); min-width: 0; padding: 0 2px; }
@media (max-width: 560px) {
  /* Su schermo stretto contano i due passi: i numeri in mezzo diventerebbero
     due righe di pastiglie sopra il pollice. */
  .pag-numeri { order: 3; width: 100%; justify-content: center; }
}

/* ---------------------------------------------------------------- profilo */
.profile-head { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.profile-head .sub { color: var(--ink-2); margin: 2px 0 8px; }
.profile-head .badges { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.kv { display: grid; grid-template-columns: auto 1fr; gap: 4px 14px; font-size: 13.5px; }
.kv dt { color: var(--ink-3); }
.kv dd { margin: 0; color: var(--ink); }
.skill-line { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 5px 0; border-bottom: 1px solid var(--bg); font-size: 13.5px; }
.skill-line:last-child { border-bottom: none; }
.skill-line .years { color: var(--ink-3); font-size: 12px; }
.exp-item { padding: 10px 0; border-bottom: 1px solid var(--grid); }
.exp-item:last-child { border-bottom: none; }
.exp-item .title { font-weight: 600; }
.exp-item .org { color: var(--ink-2); }
.exp-item .period { color: var(--ink-3); font-size: 12.5px; white-space: nowrap; }
.exp-item .tech { font-size: 12.5px; color: var(--ink-3); margin-top: 3px; }
/* `pre-line` e non `normal`: da quando la descrizione si scrive in un'area di
   testo, gli a capo che una persona ha messo sono una scelta, e collassarli in
   un paragrafo unico è disfare il suo lavoro. */
.exp-item p { margin: 4px 0 0; font-size: 13.5px; color: var(--ink-2); white-space: pre-line; }
/* I progetti dei piani di abgantt nel profilo (SYS-001 MLF-011.12): la stessa
   voce delle esperienze, con sotto le attività della persona, una per riga,
   perché date e quote si confrontano in colonna e non in una frase lunga. */
.dal-piano { margin-bottom: 10px; }
.dal-piano-nota { margin: -2px 0 4px; }
.dal-piano-poi { margin-top: 14px; }
.exp-testa { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.exp-testa .badge { margin-left: 6px; vertical-align: 1px; }
.piano-attivita { width: 100%; border-collapse: collapse; font-size: 12.5px; margin-top: 8px; }
.piano-attivita th { text-align: left; font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--ink-3); padding: 0 10px 4px 0; border-bottom: 1px solid var(--grid); }
.piano-attivita td { padding: 5px 10px 5px 0; border-bottom: 1px solid var(--bg); vertical-align: top; }
.piano-attivita tr:last-child td { border-bottom: none; }
.piano-attivita .quando { color: var(--ink-3); white-space: nowrap; }
.piano-attivita .num { text-align: right; padding-right: 0; font-variant-numeric: tabular-nums; white-space: nowrap; }
.exp-piede { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 6px; font-size: 12.5px; color: var(--ink-3); }
/* «Aggiungi al profilo» su un progetto del piano (LLF-011.12.4) */
.piano-aggiungi { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin-top: 8px; }
.piano-aggiungi form { margin: 0; }
.piano-aggiungi .hint { font-size: 12.5px; }
.meter { height: 8px; background: var(--grid); border-radius: 5px; overflow: hidden; }
.meter .fill { height: 100%; background: var(--accent); border-radius: 5px; }
.hints { margin: 8px 0 0; padding-left: 18px; color: var(--ink-2); font-size: 13px; }
.hints li { margin-bottom: 3px; }

/* Perché la completezza non è al 100%: un `<details>` sotto la barra.
   Chiuso è una riga (quante voci, e sotto quali), aperto è l'elenco con il
   peso di ciascuna. La freccia sta davanti al titolo, disegnata con due bordi:
   il carattere ▾ a quella misura era un puntino, e un riquadro che non dice
   di aprirsi resta chiuso. La colonna del profilo è stretta (un terzo della
   pagina), quindi niente si rifiuta di andare a capo tranne il peso, che è
   corto per natura. */
.motivi { margin-top: 12px; }
.motivi > summary {
  list-style: none; cursor: pointer; user-select: none;
  display: flex; flex-wrap: wrap; align-items: baseline;
  column-gap: 8px; row-gap: 1px;
  padding: 5px 7px; margin: 0 -7px; border-radius: 8px;
  color: var(--ink-3);
}
.motivi > summary::-webkit-details-marker { display: none; }
.motivi > summary::before {
  content: ""; flex: none; align-self: center;
  width: 6px; height: 6px; margin: 0 2px 0 1px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg); transition: transform 0.15s;
}
.motivi[open] > summary::before { transform: rotate(45deg); }
.motivi > summary:hover { background: var(--bg); color: var(--ink); }
.motivi > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 0; }
.motivi-tit { font-size: 13px; font-weight: 600; color: var(--ink-2); }
.motivi > summary:hover .motivi-tit { color: var(--ink); }
.motivi-n { margin-left: auto; font-size: 12px; color: var(--ink-3); white-space: nowrap; }
/* Otto voci non ci stanno in una riga: l'anteprima si tronca, e il conteggio
   in alto dice quante sono. Rientra quanto la freccia, sotto il titolo. */
.motivi-anteprima {
  flex: 1 1 100%; min-width: 0; padding-left: 17px;
  font-size: 12.5px; color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.motivi[open] .motivi-anteprima { display: none; }
.motivi-lista { list-style: none; margin: 4px 0 0; padding: 0; }
.motivo {
  display: flex; align-items: baseline; gap: 10px;
  padding: 7px 0; border-top: 1px solid var(--grid); font-size: 13px; line-height: 1.4;
}
.motivo-testo { flex: 1 1 auto; min-width: 0; color: var(--ink); }
.motivo-testo small { display: block; margin-top: 2px; font-size: 12px; color: var(--ink-3); }
.motivo-punti {
  flex: none; padding: 0 7px; border-radius: 999px; white-space: nowrap;
  background: var(--bg); border: 1px solid var(--grid);
  font-size: 11.5px; font-weight: 650; color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
/* Qualunque elemento puntato dall'indirizzo (`#f-summary`, `#sez-lingue`)
   atterra sotto la barra in alto, non dietro: la barra è fissa e alta 56px, e
   il browser, che scorre fino all'ancora dopo aver eseguito gli script,
   metteva il campo sul bordo della finestra, con l'etichetta coperta. Sui
   campi il margine è più alto perché l'etichetta sta sopra. */
:target { scroll-margin-top: 76px; }
:is(input, select, textarea):target { scroll-margin-top: 112px; }
/* Arrivati da un motivo al modulo, la sezione giusta si fa riconoscere un
   istante. Solo un alone che sfuma: niente che resti acceso e sembri uno
   stato, e niente movimento per chi l'ha chiesto al sistema. */
@media (prefers-reduced-motion: no-preference) {
  .card:has(> h2:target) { animation: approdo 1.8s ease-out; }
  /* tornati da «Proponi», sulla scheda della persona appena proposta */
  .scheda-posto:target > .match-card { animation: approdo 1.8s ease-out; }
}
@keyframes approdo {
  from { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
}

.banner {
  padding: 10px 14px; border-radius: 10px; margin-bottom: 16px; font-size: 14px;
}
.banner.ok { background: var(--ok-bg); color: var(--ok-tx); }
.banner.info { background: var(--accent-soft); color: var(--accent-strong); }
.banner.warn { background: var(--warn-bg); color: var(--warn-tx); }
.banner.bad { background: var(--bad-bg); color: var(--bad-tx); }

/* ---------------------------------------------------------------- analisi */
.kpi-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 14px; margin-bottom: 18px; }
.kpi { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; }
.kpi .value { font-size: 28px; font-weight: 650; letter-spacing: -0.5px; }
.kpi .label { font-size: 12.5px; color: var(--ink-2); margin-top: 2px; }
.kpi.kpi-warn { border-color: var(--warn-tx); background: var(--warn-bg); }
.kpi.kpi-warn .value, .kpi.kpi-warn .label { color: var(--warn-tx); }

.barlist { display: flex; flex-direction: column; gap: 9px; }
.bar-row { display: grid; grid-template-columns: 130px 1fr auto; gap: 10px; align-items: center; font-size: 13px; }
.bar-row .lbl { color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bar-row .track { background: none; height: 16px; display: flex; align-items: center; }
.bar-row .fill { height: 14px; border-radius: 0 4px 4px 0; background: var(--s1); min-width: 2px; }
.bar-row .val { color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.bar-row .val small { color: var(--ink-3); }

.donut-wrap { display: flex; gap: 20px; align-items: center; flex-wrap: wrap; }
.legend { display: flex; flex-direction: column; gap: 6px; font-size: 13px; flex: 1; min-width: 180px; }
.legend .item { display: grid; grid-template-columns: 12px 1fr auto; gap: 8px; align-items: center; }
.legend .swatch { width: 11px; height: 11px; border-radius: 3px; }
.legend .val { color: var(--ink-2); font-variant-numeric: tabular-nums; }

.risk-item { display: flex; justify-content: space-between; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--bg); font-size: 13.5px; align-items: baseline; }
.risk-item:last-child { border-bottom: none; }
.risk-item .who { color: var(--ink-3); font-size: 12.5px; text-align: right; }
.list-plain { display: flex; flex-direction: column; }
.list-plain .item { display: flex; justify-content: space-between; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--bg); font-size: 13.5px; align-items: center; }
.list-plain .item:last-child { border-bottom: none; }

/* ---------------------------------------------------------------- matrice */
/* Il riquadro scorre nelle due direzioni ed è alto quanto lo schermo, di
   proposito: `position: sticky` si àncora al riquadro che scorre, non alla
   pagina, e finché il riquadro era alto quanto la tabella l'intestazione non
   aveva da cosa staccarsi, se ne andava su con la pagina, e a metà elenco
   restavano quaranta pallini senza più il nome della competenza sopra. Il
   numero sottratto è lo spazio che la pagina prende comunque (testata, filtro,
   legenda, piè di pagina) più il margine che tiene il riquadro sotto la barra
   in alto anche a pagina scorsa fino in fondo: così i nomi delle colonne e
   quelli delle persone restano in vista sempre, come in un foglio di calcolo. */
.table-wrap {
  overflow: auto; max-height: calc(100vh - 260px);
  border: 1px solid var(--grid); border-radius: 12px; background: var(--surface);
}
/* `separate` e non `collapse`: con i bordi fusi la riga sotto l'intestazione
   appartiene alla griglia della tabella, che scorre, e scorrendo spariva
   lasciando le celle ferme appoggiate sul vuoto. */
table.matrix { border-collapse: separate; border-spacing: 0; width: 100%; font-size: 13px; }
.matrix th, .matrix td { padding: 7px 9px; border-bottom: 1px solid var(--grid); text-align: center; }
.matrix thead th {
  background: var(--bg); color: var(--ink-2); font-weight: 600; font-size: 12px;
  white-space: nowrap; position: sticky; top: 0; z-index: 2;
}
.matrix td.who, .matrix th.who {
  text-align: left; white-space: nowrap; position: sticky; left: 0;
  background: var(--surface); font-weight: 550; z-index: 1;
}
/* l'angolo in alto a sinistra sta fermo in tutte e due le direzioni, e passa
   sopra a entrambe le file ferme */
.matrix th.who { background: var(--bg); z-index: 3; }
.matrix .cell { display: inline-block; width: 26px; height: 20px; border-radius: 5px; line-height: 20px; font-size: 11.5px; font-weight: 650; }
.cell.lv1 { background: var(--lv1); color: #0b0b0b; }
.cell.lv2 { background: var(--lv2); color: #0b0b0b; }
.cell.lv3 { background: var(--lv3); color: #fff; }
.cell.lv4 { background: var(--lv4); color: #fff; }
.cell.lv5 { background: var(--lv5); color: #fff; }
.cell.empty { background: none; color: var(--baseline); font-weight: 400; }
.matrix-legend { display: flex; gap: 14px; align-items: center; margin-top: 12px; font-size: 12.5px; color: var(--ink-2); flex-wrap: wrap; }
.matrix-legend .cell { width: 22px; }

/* ---------------------------------------------------------------- catalogo
   Il catalogo non è un elenco da leggere dall'inizio alla fine: è una
   tassonomia da manutenere, e le domande vere sono «dov'è questa voce», «quali
   non le usa nessuno», «cosa è arrivato dalle richieste». La pagina è quindi
   una scrivania: barra che cerca e filtra, indice dei gruppi a lato, voci in
   una griglia compatta che si apre solo dove si interviene. Duecento voci
   stanno in una schermata invece che in dieci. */
.subnav-nota { margin: -6px 0 14px; }

.cat-barra {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  padding: 9px 12px; margin-bottom: 14px;
  position: sticky; top: 56px; z-index: 20;
}
.cat-barra input[type=search] {
  flex: 1 1 220px; min-width: 160px; padding: 7px 11px;
  border: 1px solid var(--baseline); border-radius: 8px; font: inherit; font-size: 13.5px;
  background: #fff;
}
.cat-barra input[type=search]:focus { outline: 2px solid var(--accent-soft); border-color: var(--accent); }
.cat-chips { display: flex; gap: 5px; flex-wrap: wrap; }
.cat-chip {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  background: var(--bg); border: 1px solid var(--grid); color: var(--ink-2);
  padding: 5px 11px; border-radius: 999px; font: inherit; font-size: 12.5px; font-weight: 550;
}
.cat-chip:hover { border-color: var(--ink-3); color: var(--ink); }
.cat-chip .conta {
  font-size: 11.5px; font-weight: 650; color: var(--ink-3);
  background: #fff; border-radius: 999px; padding: 0 6px;
}
.cat-chip.attivo { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-strong); }
.cat-chip.attivo .conta { color: var(--accent-strong); }
.cat-chip:disabled { opacity: 0.45; cursor: default; }
.cat-chip:disabled:hover { border-color: var(--grid); color: var(--ink-2); }
/* Il filtro per sede sui risultati (match, richiesta riaperta, bench): le
   stesse pastiglie della scrivania, ma collegamenti veri, perché la sede si
   applica sul server. La sede a zero resta scritta e spenta. */
.sedi { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
.sedi-tit { font-size: 12.5px; font-weight: 600; color: var(--ink-3); margin-right: 4px; }
a.cat-chip { text-decoration: none; }
.cat-chip.spenta { opacity: 0.45; cursor: default; }
.cat-chip.spenta:hover { border-color: var(--grid); color: var(--ink-2); }
.cat-chip.attivo[aria-current] { cursor: default; }
.rosa-sintesi .sedi { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--grid); }
/* I filtri sui risultati del match (services/filtri_match): sede,
   disponibilità, seniority e requisito, una riga ciascuno con il titolo in
   colonna, così le pastiglie delle quattro righe partono dallo stesso punto e
   si leggono come una tabella. Il filetto è del gruppo, non della sede. */
.rosa-sintesi .filtri-match {
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--grid);
  display: grid; gap: 7px;
}
.filtri-match .sedi { margin: 0; padding: 0; border: 0; }
.filtro-riga { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
.filtri-match .sedi-tit, .filtro-tit {
  font-size: 12.5px; font-weight: 600; color: var(--ink-3); margin-right: 4px;
  min-width: 7.5em;
}
/* Scelta multipla: la pastiglia accesa lo dice con la spunta, «Tutte» no. A
   zero, spenta, non si preme: senza JavaScript porterebbe a una pagina vuota. */
.filtro-riga .cat-chip.attivo[data-valore]:not([data-valore=""]):not(.req-scelto)::before { content: "✓"; }
.filtro-riga .cat-chip.spenta { pointer-events: none; }
.filtri-stato { margin-left: 4px; }
.filtri-aiuto { margin: 2px 0 0; }
.filtri-azzera { margin-left: 6px; white-space: nowrap; }
/* Il menù dei requisiti: le caselle si spuntano insieme, ognuna con quanti
   restano aggiungendola. Si apre sopra la pagina, come il menù dei CV. */
.filtro-menu { position: relative; }
.filtro-menu > summary { list-style: none; }
.filtro-menu > summary::-webkit-details-marker { display: none; }
.filtro-menu[open] .cv-caret { transform: rotate(180deg); }
.filtro-pop {
  position: absolute; z-index: 40; top: calc(100% + 6px); left: 0;
  width: 340px; max-width: calc(100vw - 32px); max-height: 60vh; overflow: auto;
  background: #fff; border: 1px solid var(--grid); border-radius: 12px;
  padding: 12px 14px; box-shadow: 0 10px 30px rgba(11, 11, 11, 0.13);
}
.filtro-pop .cv-pop-tit { margin: 0 0 6px; font-size: 11.5px; text-transform: uppercase;
  letter-spacing: 0.5px; color: var(--ink-3); font-weight: 650; }
.filtro-pop .opt { display: flex; align-items: center; gap: 7px; padding: 3px 0; font-size: 13px; }
.filtro-pop .opt + .cv-pop-tit { margin-top: 12px; }
.req-gruppo-tit { margin: 8px 0 2px; font-size: 12px; font-weight: 600; color: var(--ink-2); }
.req-voce .conta {
  margin-left: auto; font-size: 11.5px; font-weight: 650; color: var(--ink-3);
  background: var(--bg); border-radius: 999px; padding: 0 7px;
}
/* Una scheda fuori dai filtri resta fuori anche quando «Mostra tutte» o la
   ricerca scoprono quelle oltre le prime venti. */
.scheda-filtro[hidden] { display: none !important; }
.filtri-card { padding: 12px 16px; scroll-margin-top: 76px; }
.filtri-card .filtri-match { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--grid);
  display: grid; gap: 7px; }
.filtri-nota { margin: 10px 0 0; }
@media (max-width: 560px) {
  .filtri-match .sedi-tit, .filtro-tit { min-width: 0; flex-basis: 100%; }
  /* Sul telefono il menù si apre nella pagina, sotto il pulsante e a tutta
     larghezza: un riquadro sospeso finiva fuori dallo schermo. */
  .filtro-menu[open] { flex-basis: 100%; }
  .filtro-pop { position: static; width: auto; max-width: none; max-height: none;
    margin-top: 8px; box-shadow: none; }
}
.sedi-barra {
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  padding: 9px 12px; margin: 14px 0;
}
.rosa-sintesi, .sedi-barra { scroll-margin-top: 76px; }
.buco-sede { margin: -4px 0 12px; }
.cat-ordine { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--ink-3); }
.cat-ordine select {
  padding: 6px 8px; border: 1px solid var(--baseline); border-radius: 8px;
  font: inherit; font-size: 13px; background: #fff; color: var(--ink);
}
.cat-conta { font-size: 12.5px; color: var(--ink-3); margin-left: auto; white-space: nowrap; }

.cat-lavoro { display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 18px; align-items: start; }
.cat-rail {
  display: flex; flex-direction: column; gap: 1px;
  position: sticky; top: 118px; max-height: calc(100vh - 140px); overflow-y: auto;
}
.cat-rail button {
  display: flex; align-items: center; gap: 8px; justify-content: space-between;
  background: none; border: none; border-radius: 8px; cursor: pointer;
  font: inherit; font-size: 13px; color: var(--ink-2); text-align: left;
  padding: 6px 10px; width: 100%;
}
.cat-rail button:hover { background: var(--surface); color: var(--ink); }
.cat-rail button .nome { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cat-rail button .conta { font-size: 11.5px; color: var(--ink-3); font-variant-numeric: tabular-nums; flex: none; }
.cat-rail button.attivo { background: var(--accent-soft); color: var(--accent-strong); font-weight: 600; }
.cat-rail button.attivo .conta { color: var(--accent-strong); }
.cat-rail button.vuoto { opacity: 0.4; }
.cat-rail .cat-rail-tutte { border-bottom: 1px solid var(--grid); border-radius: 8px 8px 0 0; margin-bottom: 5px; padding-bottom: 8px; }
@media (max-width: 900px) {
  .cat-lavoro { grid-template-columns: 1fr; }
  .cat-rail { position: static; max-height: 168px; }
  .cat-barra { position: static; }
}

.cat-gruppo + .cat-gruppo { margin-top: 18px; }
.cat-gruppo > h3 {
  display: flex; align-items: baseline; gap: 8px; margin: 0 0 8px;
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-3);
}
.cat-gruppo > h3 span { font-weight: 600; color: var(--baseline); letter-spacing: 0; }
.cat-gruppo > h3 .cat-dossier { margin-left: auto; text-transform: none; letter-spacing: 0;
                               font-weight: 500; }
.cat-griglia {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 8px; align-items: start;
}

/* Una voce: chiusa dice nome e quante persone la portano, aperta è il suo
   editor. Aprirne una non allunga le vicine: è `align-items: start` sulla
   griglia a garantirlo. */
.voce {
  border: 1px solid var(--grid); border-radius: 9px; background: var(--surface);
}
.voce > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 7px;
  padding: 7px 10px; border-radius: 8px;
}
.voce > summary::-webkit-details-marker { display: none; }
.voce > summary:hover { background: var(--bg); }
.voce > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.voce[open] { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); background: #fff; }
.voce-nome {
  flex: 1; min-width: 0; font-size: 13.5px; font-weight: 550; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.voce-uso {
  flex: none; font-size: 11.5px; font-weight: 650; color: var(--accent-strong);
  background: var(--accent-soft); border-radius: 999px; padding: 1px 7px;
  font-variant-numeric: tabular-nums;
}
.voce-uso.zero { color: var(--ink-3); background: var(--bg); font-weight: 500; }
.voce-tag { flex: none; font-size: 12px; line-height: 1; }
.voce.spenta .voce-nome { color: var(--ink-3); text-decoration: line-through; text-decoration-color: var(--baseline); }
.voce-corpo { padding: 2px 10px 10px; display: flex; flex-direction: column; gap: 8px; }
.voce-corpo label { display: block; font-size: 11.5px; color: var(--ink-3); margin-bottom: 8px; }
.voce-corpo input, .voce-corpo select {
  display: block; width: 100%; margin-top: 2px; padding: 6px 8px;
  border: 1px solid var(--baseline); border-radius: 7px; font: inherit; font-size: 13px;
  background: #fff; color: var(--ink);
}
.voce-corpo .switch {
  display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px;
  color: var(--ink-2); cursor: pointer; margin-bottom: 8px;
}
.voce-corpo .switch input { width: 15px; height: 15px; margin: 0; accent-color: var(--accent); display: inline-block; }
.voce-piede {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  border-top: 1px dashed var(--grid); padding-top: 8px; font-size: 12.5px;
}
.voce-piede .usage { color: var(--ink-3); }
.voce-piede form { margin-left: auto; }
.voce-piede .badge { font-size: 11px; }

.cat-vuoto { padding: 26px 4px; color: var(--ink-3); font-size: 13.5px; }

/* ---------------------------------------------------------------- import */
.upload-box { border: 2px dashed var(--baseline); border-radius: 12px; padding: 24px; text-align: center; color: var(--ink-2); background: #fff; }
.upload-box input[type=file] { margin-top: 10px; }
details.preview { margin-top: 14px; }
details.preview pre {
  white-space: pre-wrap; background: var(--bg); border: 1px solid var(--grid);
  border-radius: 10px; padding: 12px; font-size: 12px; color: var(--ink-2);
  max-height: 300px; overflow: auto;
}
.ai-note { font-size: 13px; }

/* coda dei CV caricati e non ancora assegnati */
.banner.coda-link { display: flex; align-items: center; gap: 12px; justify-content: space-between; flex-wrap: wrap; }
h1 .conta {
  font-size: 14px; font-weight: 600; vertical-align: middle; margin-left: 6px;
  background: var(--accent-soft); color: var(--accent-strong);
  border-radius: 999px; padding: 2px 10px;
}
.coda-row {
  display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1.2fr) auto auto;
  gap: 10px; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--bg);
}
.coda-row:last-child { border-bottom: none; }
.coda-row b, .coda-row span { display: block; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.coda-row small { display: block; font-size: 12px; color: var(--ink-3); margin-top: 2px; }
.coda-chi .vuoto { color: var(--ink-3); font-style: italic; }
.coda-azioni { display: flex; gap: 6px; align-items: center; justify-content: flex-end; }
.coda-azioni form { display: inline; }
@media (max-width: 800px) {
  .coda-row { grid-template-columns: 1fr; }
  .coda-azioni { justify-content: flex-start; }
}

/* scelta della destinazione nella revisione di un CV */
.target-card .target-form { display: grid; grid-template-columns: 1fr auto; gap: 10px; align-items: end; }
.target-card .field { margin-bottom: 0; }
.target-card .hint { margin-top: 8px; }
@media (max-width: 700px) { .target-card .target-form { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------- amministrazione */
/* La scala degli accessi. Tre pioli, dal più potente al più comune: ognuno
   porta accanto quel che sblocca (era una tabellina staccata, che spiegava i
   ruoli senza toccare nessuna delle persone) e sotto le persone che ci stanno.
   Il filo che tiene insieme barra e pioli è il colore: la rampa ordinale
   --lv5/--lv3 per chi ha accessi in più, il grigio di --baseline per chi ha
   solo il proprio profilo. È una scala, non tre categorie: la rampa dice
   «di più / di meno», la palette categorica direbbe «diversi». */
.ruoli-barra {
  display: flex; height: 10px; border-radius: 999px; overflow: hidden;
  background: var(--grid); margin: 2px 0 8px;
}
/* i segmenti piccoli restano visibili: due amministratori su centoquaranta
   fanno l'1,4%, che sotto i quattro pixel è una riga di niente */
.ruoli-barra .seg { min-width: 4px; }
.ruoli-barra .s-admin { background: var(--lv5); }
.ruoli-barra .s-supervisor { background: var(--lv3); }
.ruoli-barra .s-member { background: var(--baseline); }
.ruoli-sintesi { margin: 0 0 12px; font-size: 13.5px; color: var(--ink-2); }
.ruoli-sintesi b { color: var(--ink); }

/* la barra della scrivania qui sta dentro una scheda: senza fondo, senza
   cornice e senza `sticky`, sarebbe un riquadro dentro un riquadro, appiccicato
   a metà pagina */
.ruoli-desk .cat-barra {
  position: static; background: none; border: none; padding: 0; margin-bottom: 10px;
}
/* L'elenco non cresce mai: qui il numero dei supervisor è destinato a salire (recruiting, capi progetto) e ogni nomina allungava la scheda di una riga.
   Con l'altezza massima e la barra di scorrimento la pagina resta la stessa
   con tre o con trenta, e per trovare qualcuno c'è la ricerca invece dello
   scorrimento a occhio. */
.ruoli-elenco {
  max-height: 292px; overflow-y: auto; overscroll-behavior: contain;
  border: 1px solid var(--grid); border-radius: 10px; padding: 0 10px 8px;
  background: var(--surface);
}
.ruoli-gruppo > summary, .ruoli-gruppo > .testa {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin: 0; padding: 9px 0 6px; border-bottom: 1px solid var(--bg);
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--ink-2);
  /* scorrendo trenta supervisor si deve continuare a sapere in quale livello
     si è: l'intestazione resta in cima al riquadro */
  position: sticky; top: 0; z-index: 1; background: var(--surface);
}
.ruoli-gruppo > summary { cursor: pointer; list-style: none; }
.ruoli-gruppo > summary::-webkit-details-marker { display: none; }
.ruoli-gruppo > summary:hover { color: var(--ink); }
.ruoli-gruppo > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 6px; }
.ruoli-gruppo > summary .apri-chiudi {
  margin-left: auto; color: var(--ink-3); font-size: 14px; line-height: 1;
  transition: transform 0.15s ease;
}
.ruoli-gruppo[open] > summary .apri-chiudi { transform: rotate(180deg); }
.ruoli-gruppo > summary:hover .apri-chiudi { color: var(--ink); }
.ruoli-gruppo > summary .tit, .ruoli-gruppo > .testa .tit {
  padding-left: 9px; border-left: 3px solid var(--tono); --tono: var(--baseline);
}
.ruoli-gruppo.l-admin .tit { --tono: var(--lv5); }
.ruoli-gruppo.l-supervisor .tit { --tono: var(--lv3); }
.ruoli-gruppo .conta {
  font-weight: 700; font-size: 13px; letter-spacing: 0; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.ruoli-gruppo .cosa {
  flex: 1 1 260px; text-transform: none; letter-spacing: 0; font-weight: 400;
  font-size: 12.5px; color: var(--ink-3);
}
/* un livello chiuso non è una riga staccata da quella dopo */
.ruoli-gruppo:not([open]) > summary { border-bottom-color: var(--grid); }
.ruoli-vuoto { margin: 8px 0 4px; font-size: 13px; color: var(--ink-3); }
/* dentro la scheda il messaggio di «niente trovato» non ha una pagina intera
   da riempire: i 26px sopra e sotto lasciavano un riquadro vuoto grande il
   triplo della riga che contiene */
.ruoli-elenco .cat-vuoto { padding: 14px 4px; }

/* Una riga: iniziali, chi, dove, quando è entrato l'ultima volta, cosa farne.
   Una riga sola e non una scheda: una scheda per persona costava sessanta
   pixel a testa, e questo elenco deve poterne contenere trenta. */
.riga-ruolo {
  display: grid; align-items: center; gap: 10px;
  grid-template-columns: auto minmax(140px, 1.1fr) minmax(0, 1.3fr) auto auto;
  padding: 5px 0; border-bottom: 1px solid var(--bg); font-size: 13.5px;
}
.riga-ruolo:last-child { border-bottom: none; }
.riga-ruolo .iniziali {
  width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent-strong);
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.3px;
}
.riga-ruolo .iniziali.forte { background: var(--lv5); color: #fff; }
.riga-ruolo .chi { display: flex; align-items: center; gap: 6px; min-width: 0; }
.riga-ruolo .chi > a {
  font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.riga-ruolo .mail, .riga-ruolo .quando {
  font-size: 12.5px; color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.riga-ruolo .quando { text-align: right; }
.riga-ruolo .quando.allarme { color: var(--warn-tx); }
.riga-ruolo .badge { flex: none; font-size: 11px; }
/* larghezza fissa: le azioni delle righe vicine devono incolonnarsi, e
   «Revoca» e «sei tu» sono larghi diversi */
.riga-ruolo .azione { min-width: 96px; display: flex; justify-content: flex-end; }
/* profilo disattivato ma ruolo ancora addosso: si vede che è un caso da chiudere */
.riga-ruolo.spenta .iniziali { filter: grayscale(1); }
.riga-ruolo.spenta .chi > a { color: var(--ink-2); }

/* il piolo di base: nessun elenco sotto, solo il numero e cosa vuol dire */
.ruoli-base { margin-top: 10px; opacity: 0.8; }
.ruoli-base > .testa { border-bottom: none; padding-bottom: 0; position: static; }
.ruoli-base > .testa a { text-transform: none; letter-spacing: 0; font-size: 12.5px; }

.nomina-band { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--grid); }
.nomina-band .sotto-titolo { margin-bottom: 8px; }
.nomina { display: grid; grid-template-columns: 1fr 200px auto; gap: 10px; align-items: end; }
.nomina .field { margin-bottom: 0; }
.stato-griglia {
  display: grid; grid-template-columns: 1fr auto; gap: 6px 14px;
  font-size: 14px; align-items: baseline;
}
.stato-griglia span { color: var(--ink-2); }
.stato-griglia b { text-align: right; font-variant-numeric: tabular-nums; }
.stato-griglia.conteggi {
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--bg);
}
/* riquadro apribile: l'elenco dei profili è lungo, sta chiuso finché non serve */
.card.apribile { padding-top: 14px; }
.apribile > summary {
  display: flex; align-items: center; gap: 12px; cursor: pointer;
  list-style: none; user-select: none;
}
.apribile > summary::-webkit-details-marker { display: none; }
.apribile > summary h2 { margin: 0; }
.apribile > summary .apri-chiudi {
  margin-left: auto; color: var(--ink-3); font-size: 15px;
  transition: transform 0.15s ease;
}
.apribile[open] > summary { margin-bottom: 12px; }
.apribile[open] > summary .apri-chiudi { transform: rotate(180deg); }
.apribile > summary:hover .apri-chiudi { color: var(--ink); }
.apribile > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 8px; }

/* Il riquadro «occupazione non dichiarata» sopra il bench: è un limite del
   contenuto sotto, non un allarme. Bordo ambra e nient'altro, così si vede
   senza gridare più forte dei numeri che introduce. */
.avviso-occ { border-left: 3px solid var(--warn-tx); }
.avviso-occ > summary .hint { flex: 1 1 auto; min-width: 0; }
.avviso-occ .elenco-fitto { margin-top: 4px; }

.cerca-profili { max-width: 340px; margin: 4px 0 10px; }
/* Il nuovo reparto: campo e pulsante sulla stessa riga, il pulsante della sua
   misura. Sul telefono il campo prende la riga e il pulsante va sotto. */
.nuovo-reparto { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px; margin-top: 12px; }
.nuovo-reparto .field { flex: 0 1 340px; margin: 0; }
.profilo-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 12px;
  align-items: center; padding: 9px 0; border-bottom: 1px solid var(--bg);
}
.profilo-row:last-child { border-bottom: none; }
.profilo-row.is-off { opacity: 0.6; }
.profilo-row small { display: block; font-size: 12.5px; color: var(--ink-3); margin-top: 2px; }
.profilo-row .badge { margin-left: 6px; vertical-align: 1px; }
.profilo-cosa { color: var(--ink-3); white-space: nowrap; }
.profilo-azioni { display: flex; gap: 6px; align-items: center; justify-content: flex-end; min-width: 150px; }
.btn-ghost.elimina:hover { color: var(--bad-tx); background: var(--bad-bg); }
@media (max-width: 800px) {
  .profilo-row { grid-template-columns: 1fr; }
  .profilo-azioni { justify-content: flex-start; min-width: 0; }
  .profilo-cosa { white-space: normal; }
}
@media (max-width: 860px) {
  /* Stretto, la riga va su due piani: chi e cosa farne sopra, indirizzo e
     ultimo accesso sotto. Incolonnati a forza, nome e indirizzo diventavano
     due monconi in ellissi, e in un elenco di permessi l'indirizzo è quello
     che dice *quale* Rossi ha le chiavi. */
  .riga-ruolo { grid-template-columns: auto minmax(0, 1fr) auto; row-gap: 2px; }
  .riga-ruolo .mail { grid-column: 2; }
  .riga-ruolo .quando { grid-column: 3; }
  .riga-ruolo .azione { grid-row: 1; grid-column: 3; }
}
@media (max-width: 700px) {
  .nomina { grid-template-columns: 1fr; }
}

.empty-state { text-align: center; color: var(--ink-3); padding: 40px 20px; }
.empty-state .big { font-size: 34px; margin-bottom: 8px; }

/* form di inserimento rapido (catalogo, clienti) */
.add-form { display: grid; grid-template-columns: 1fr 200px 200px auto; gap: 10px; align-items: end; }
.add-form .field { margin-bottom: 0; }
@media (max-width: 800px) { .add-form { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------- login */
.login-body {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 34px 20px;
  background:
    radial-gradient(1000px 620px at 14% -8%, rgba(42, 120, 214, 0.11), rgba(42, 120, 214, 0) 62%),
    radial-gradient(820px 620px at 96% 108%, rgba(27, 175, 122, 0.09), rgba(27, 175, 122, 0) 58%),
    var(--bg);
}
.login-shell {
  width: min(980px, 100%); display: grid; grid-template-columns: 1fr 396px;
  gap: 60px; align-items: center;
}
/* una scheda sola (il codice del secondo fattore): niente colonna di presentazione */
.login-shell-solo { grid-template-columns: 1fr; max-width: 420px; }
.login-shell-solo .login-logo.compact { display: flex; }
/* istanza demo: i ruoli di prova, uno per riga */
.demo-ruoli { display: grid; gap: 8px; margin-top: 10px; }
.login-logo {
  display: flex; align-items: center; gap: 11px;
  font-size: 23px; font-weight: 600; letter-spacing: -0.4px;
}
.login-logo b { color: var(--accent); font-weight: 750; }
.login-logo.compact { display: none; margin-bottom: 22px; }

.login-pitch h1 {
  font-size: 33px; line-height: 1.22; font-weight: 620; letter-spacing: -0.9px;
  margin: 24px 0 28px;
}
.login-points { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 18px; }
.login-points li { display: grid; grid-template-columns: 36px 1fr; gap: 13px; align-items: start; }
.login-points .ic {
  width: 36px; height: 36px; border-radius: 10px; background: #fff;
  border: 1px solid var(--grid); display: flex; align-items: center;
  justify-content: center; font-size: 16px;
}
.login-points b { display: block; font-size: 14px; font-weight: 620; margin-bottom: 2px; color: var(--ink); }
.login-points div { font-size: 13.5px; color: var(--ink-2); line-height: 1.45; }

.login-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 16px;
  padding: 30px 28px 24px;
  box-shadow: 0 20px 46px rgba(11, 11, 11, 0.10), 0 2px 6px rgba(11, 11, 11, 0.04);
}
.login-card h2 { font-size: 20px; display: block; margin-bottom: 3px; }
.login-sub { color: var(--ink-2); font-size: 13.5px; margin: 0 0 20px; }
.btn-google {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; padding: 12px 16px; border: 1px solid var(--baseline);
  border-radius: 9px; background: #fff; color: var(--ink);
  font-size: 15px; font-weight: 550; cursor: pointer;
  box-shadow: 0 1px 2px rgba(11, 11, 11, 0.05);
}
.btn-google:hover { background: var(--bg); border-color: var(--ink-3); text-decoration: none; }
.btn-google:active { transform: translateY(1px); }
.btn-block { width: 100%; justify-content: center; padding: 11px 16px; font-size: 14.5px; }
.login-or {
  display: flex; align-items: center; gap: 12px; margin: 22px 0 18px;
  color: var(--ink-3); font-size: 12px; text-transform: uppercase; letter-spacing: 0.6px;
}
.login-or::before, .login-or::after { content: ""; flex: 1; height: 1px; background: var(--grid); }
.dev-box { background: var(--bg); border: 1px solid var(--grid); border-radius: 12px; padding: 14px; }
.dev-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--ink-2); margin-bottom: 12px;
}
.dev-box .field { margin-bottom: 10px; }
.dev-box .login-note { margin-bottom: 0; }
.login-note { font-size: 12.5px; color: var(--ink-3); margin: 12px 0 0; line-height: 1.45; }
.login-note code, .banner code {
  background: rgba(11, 11, 11, 0.06); padding: 1px 5px; border-radius: 5px;
  font-size: 11.5px;
}
.login-foot {
  text-align: center; color: var(--ink-3); font-size: 11.5px; line-height: 1.45;
  margin: 20px 0 0; padding-top: 14px; border-top: 1px solid var(--bg);
}
@media (max-width: 900px) {
  .login-shell { grid-template-columns: 1fr; max-width: 420px; gap: 0; }
  .login-pitch { display: none; }
  .login-logo.compact { display: flex; }
}

/* ------------------------------------------------- ultimo uso e aspirazioni */
.uso {
  display: inline-block; font-size: 11px; color: var(--warn-tx);
  background: var(--warn-bg); border-radius: 999px; padding: 1px 7px;
  vertical-align: 1px; white-space: nowrap;
}
.chip .uso { margin-left: 2px; }
.chip i.asp { font-style: normal; font-size: 11px; }
.chip.m-asp { background: var(--accent-soft); color: var(--accent-strong); border-color: transparent; }
.chip.m-asp a { color: inherit; }
.m-prefs { margin-top: 8px; font-size: 12.5px; color: var(--ink-3); }

/* ------------------------------------------------- avvisi gialli */
.avviso.warn { border-left-color: var(--warn-tx); }

/* ------------------------------------------------- pipeline richieste */
.ruolo-stato { display: flex; gap: 8px; align-items: center; }
.ruolo-stato select { width: auto; }
.ruolo-proposti { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.chip.proposto { background: var(--ok-bg); border-color: transparent; }
.chip.proposto a { color: var(--ok-tx); font-weight: 600; }
.chip.proposto small { color: var(--ink-3); }
.chip.proposto form { display: inline; }
.chip.proposto .btn-ghost { padding: 0 2px; font-size: 12px; }
.chip.proposto.doppio { outline: 1.5px dashed var(--warn-tx); }
.doppio-avviso { color: var(--warn-tx); }
.proponi { display: flex; gap: 8px; align-items: center; }
.proponi select { width: auto; max-width: 320px; }

/* ------------------------------------------------- piano formazione
   Ogni gap è una scheda apribile: chiusa dichiara quanto pesa e quante persone
   sono formabili, aperta apre le tre vie con i nomi. La prima parte aperta,
   perché è quella su cui si decide per prima. */
.gap-item > summary { list-style: none; cursor: pointer; border-radius: 8px; margin: -4px; padding: 4px; }
.gap-item > summary::-webkit-details-marker { display: none; }
.gap-item > summary:hover { background: var(--bg); }
.gap-item > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.gap-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.gap-head h2 { margin: 0; }
.gap-head .badge { flex: none; }
.gap-vie { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.gap-vie h3 { margin: 0 0 8px; }
.gap-vie h3 small { display: block; font-weight: 400; color: var(--ink-3); font-size: 11.5px; }
@media (max-width: 900px) { .gap-vie { grid-template-columns: 1fr; } }

/* ------------------------------------------------- bench */
.bench-card { padding: 14px 18px; display: flex; flex-direction: column; gap: 6px; }
.bench-head { display: flex; justify-content: space-between; gap: 10px; align-items: center; flex-wrap: wrap; }
.testo-warn { color: var(--warn-tx); }
.row-asp { grid-template-columns: 1fr 36px; }
/* Il bench sono spesso decine di persone: incolonnate a tutta larghezza sono
   dieci schermate, in griglia sono due.

   Nessun `align-items: start` qui: le schede non si aprono, quindi devono
   riempire la riga e risultare tutte della stessa altezza. Perché ci riescano
   senza sbilanciarsi bastano due accorgimenti: l'elenco degli impegni si
   ferma a due righe (il resto sta nel `title`, e c'è chi ne ha sei), e le
   posizioni aperte vanno in fondo con `margin-top: auto`, così si allineano
   fra schede vicine invece di galleggiare a mezz'aria. */
.bench-griglia {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
  gap: 12px;
}
.bench-impegni {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; margin: 0;
}
.bench-card .chips { margin-top: auto; padding-top: 6px; }

/* ------------------------------------------------- elenchi che non finiscono
   Un riquadro alto quanto l'elenco che contiene non è una lettura: è un muro.
   La regola qui è sempre la stessa: prima la distribuzione (che è
   l'informazione), poi i primi nomi (che sono l'azione), e il resto dietro un
   «vedi tutti» con un'altezza massima e la sua barra di scorrimento. */
.altro { margin-top: 10px; }
.altro > summary {
  cursor: pointer; list-style: none; display: inline-flex; align-items: center;
  gap: 6px; font-size: 12.5px; color: var(--accent-strong); font-weight: 550;
}
.altro > summary::-webkit-details-marker { display: none; }
.altro > summary::before { content: "▸"; font-size: 10px; }
.altro[open] > summary::before { content: "▾"; }
.altro > summary:hover { text-decoration: underline; }
.altro > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 5px; }
/* Aperto mostra *tutto* il resto, ma dentro un'altezza sua: «vedere tutti i
   profili» e «non avere riquadri infiniti» sono due richieste che convivono
   solo così. */
.altro-corpo { max-height: 300px; overflow-y: auto; margin-top: 8px; padding-right: 6px; }
.elenco-fitto {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
  gap: 0 18px;
}
.elenco-fitto .riga {
  display: flex; justify-content: space-between; gap: 8px; align-items: baseline;
  font-size: 13px; padding: 4px 0; border-bottom: 1px solid var(--bg);
}
.elenco-fitto .riga > :first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.elenco-fitto .riga small { color: var(--ink-3); font-size: 11.5px; white-space: nowrap; }
.elenco-fitto .riga .badge { flex: none; font-size: 11px; }

/* ------------------------------------------------- Analisi › abgantt
   I fabbisogni dei piani per progetto (SYS-001 MLF-011.5). Niente elenco a
   colonne strette con l'ellissi: qui ogni nome è l'informazione (la
   competenza che manca, la persona da proporre) e un nome troncato non si
   legge nemmeno col mouse sopra. Le righe vanno a capo, non si tagliano. */
.piani-lettura { margin: -6px 0 14px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.piani-spiega { margin: -4px 0 10px; }
.tab-scoperte td { vertical-align: top; }
.tab-scoperte .num { white-space: nowrap; font-variant-numeric: tabular-nums; }
.tab-scoperte .quando { white-space: nowrap; color: var(--ink-2); }
.tab-scoperte .dove + .dove { margin-top: 2px; }
.piano-progetto { padding-bottom: 8px; }
.pp-testa { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.pp-titolo { min-width: 0; }
.pp-titolo h2 { display: block; margin: 0 0 4px; }
.pp-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; font-size: 13px; color: var(--ink-2); }
.pp-descrizione { margin: 10px 0 0; font-size: 13.5px; color: var(--ink-2); white-space: pre-line; max-width: 80ch; }
.pp-riepilogo { margin: 10px 0 4px; font-size: 13px; color: var(--ink-2); }
.pp-allarme { color: var(--bad-tx); font-weight: 600; }
.fab { margin-top: 6px; }
.fab-riga {
  display: grid; grid-template-columns: minmax(180px, 1.1fr) minmax(170px, 1fr) minmax(260px, 1.5fr);
  gap: 6px 18px; padding: 10px 0; border-top: 1px solid var(--grid); align-items: start;
}
.fab-testa {
  padding: 4px 0 6px; font-size: 11.5px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .04em; color: var(--ink-3); border-top: none; border-bottom: 1px solid var(--grid);
}
.fab-testa + .fab-riga { border-top: none; }
.fab-att b { font-weight: 650; }
.fab-att .hint { margin-top: 1px; }
.fab-candidati { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; }
.fab-candidati li { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 13.5px; }
.fab-candidati .badge { font-size: 11.5px; }
.fab-nessuno { margin: 0; font-size: 13.5px; color: var(--bad-tx); font-weight: 600; }
.fab-nessuno .hint { display: block; font-weight: 400; }
.chip.chip-gradita { border-style: dashed; }
@media (max-width: 820px) {
  .fab-riga { grid-template-columns: 1fr; gap: 6px; }
  .fab-testa { display: none; }
  .fab-testa + .fab-riga { border-top: 1px solid var(--grid); }
}
/* distribuzione compatta (fasce di anzianità, quote): la forma prima dei nomi */
.fasce { display: flex; flex-direction: column; gap: 7px; margin-bottom: 14px; }
.fascia-riga { display: grid; grid-template-columns: 92px 1fr auto; gap: 10px; align-items: center; font-size: 12.5px; }
.fascia-riga .lbl { color: var(--ink-2); white-space: nowrap; }
.fascia-riga .track { height: 14px; display: flex; align-items: center; }
.fascia-riga .fill { height: 13px; border-radius: 0 4px 4px 0; min-width: 2px; background: var(--s4); }
.fascia-riga.grave .fill { background: var(--s8); }
.fascia-riga .val { color: var(--ink-2); font-variant-numeric: tabular-nums; font-weight: 600; }
.sotto-titolo { font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-3); margin: 0 0 6px; }

/* ------------------------------------------------- posizioni, forma compatta
   Una posizione chiusa dice tutto quel che serve per scorrerla; aperta è il
   banco di lavoro (stato, proposte, chi proporre). Le aperte partono aperte:
   sono quelle su cui si agisce. */
.pos { border-top: 1px solid var(--grid); }
.pos > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center;
  gap: 9px; flex-wrap: wrap; padding: 10px 4px; border-radius: 8px;
}
.pos > summary::-webkit-details-marker { display: none; }
.pos > summary:hover { background: var(--bg); }
.pos > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.pos-nome { font-weight: 650; font-size: 14px; }
.pos-conta { margin-left: auto; color: var(--ink-3); font-size: 12.5px; white-space: nowrap; }
.pos-corpo {
  display: flex; gap: 10px 20px; flex-wrap: wrap; align-items: flex-start;
  padding: 2px 4px 14px; border-left: 2px solid var(--accent-soft); margin-left: 4px;
  padding-left: 12px;
}
.pos-corpo .ruolo-stato { flex: none; }
.pos-corpo .ruolo-proposti { flex: 1 1 320px; }
.richiesta-head { display: flex; justify-content: space-between; gap: 10px; align-items: flex-start; }
.richiesta-head .hint { margin-top: 2px; }

/* ------------------------------------------------- revisione AI del profilo
   Prima e dopo affiancati: è l'unico modo di far vedere che cosa cambierebbe
   senza costringere a ricordarsi com'era. La colonna di sinistra è di sola
   lettura e sta su fondo grigio; quella di destra è un campo vero, perché
   correggere una parola prima di accettare è il caso normale. */
.rev-card { padding-top: 12px; }
.rev-scelta {
  display: flex; gap: 9px; align-items: baseline; cursor: pointer;
  padding: 0 0 10px;
}
.rev-scelta input {
  width: 16px; height: 16px; accent-color: var(--accent); margin: 0; flex: none;
}
.rev-scelta .badge { margin-left: 6px; }
.rev-col2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: start; }
@media (max-width: 900px) { .rev-col2 { grid-template-columns: 1fr; } }
.rev-et {
  font-size: 11.5px; font-weight: 650; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: 0.6px; margin-bottom: 5px;
}
.rev-et-ai { color: var(--accent-strong); }
.rev-prima {
  background: var(--bg); border: 1px solid var(--grid); border-radius: 8px;
  padding: 9px 11px; font-size: 13.5px; color: var(--ink-2);
}
.rev-prima .tech { font-size: 12px; color: var(--ink-3); }
.rev-col2 input, .rev-col2 textarea {
  padding: 8px 10px; border: 1px solid var(--baseline); border-radius: 8px;
  font: inherit; font-size: 14px; background: #fff; color: var(--ink);
  width: 100%; margin-bottom: 8px;
}
.rev-col2 textarea { resize: vertical; min-height: 86px; }
.rev-col2 input:focus, .rev-col2 textarea:focus {
  outline: 2px solid var(--accent-soft); border-color: var(--accent);
}
/* La barra delle azioni resta a portata di clic anche a metà di una pagina
   lunga: senza, con dodici esperienze si scorre fino in fondo per applicare. */
.rev-azioni {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  position: sticky; bottom: 14px; box-shadow: 0 6px 20px rgba(11, 11, 11, 0.10);
}
.guida-stile {
  white-space: pre-wrap; font: inherit; font-size: 12.5px; color: var(--ink-2);
  background: var(--bg); border-radius: 8px; padding: 10px 12px; margin: 8px 0 0;
}

/* ------------------------------------------------------- protezione dati */
.reg-tab { width: 100%; border-collapse: collapse; font-size: 13px; }
.reg-tab th {
  text-align: left; font-size: 11.5px; text-transform: uppercase;
  letter-spacing: 0.5px; color: var(--ink-3); padding: 6px 8px;
  border-bottom: 1px solid var(--grid);
}
.reg-tab td { padding: 7px 8px; border-bottom: 1px solid var(--grid); vertical-align: top; }
.reg-tab tr:last-child td { border-bottom: none; }
.reg-quando { color: var(--ink-3); white-space: nowrap; }
.reg-anonimo { color: var(--ink-3); font-style: italic; }
/* Filtri rapidi a pastiglia: lo stesso elenco visto da angolazioni diverse.
   Sono link e non un form, così ogni filtro è un indirizzo che si può mandare
   a un collega o tenere fra i preferiti. */
.filtri-rapidi { display: flex; flex-wrap: wrap; gap: 6px; }
.filtri-rapidi .chip { text-decoration: none; }
.filtri-rapidi .chip:hover { background: #fff; border-color: var(--baseline); }
.chip.on {
  background: var(--accent-soft); border-color: transparent;
  color: var(--accent-strong); font-weight: 600;
}

/* ------------------------------------------------------------- trasparenza AI
   I segni dentro il testo uscito verso il modello: verde dove un dato personale
   è stato tolto, azzurro dove al posto dell'identità c'è l'identificativo
   interno, rosso dove la sentinella ha un riscontro da far giudicare. Sono
   <mark> perché sono davvero evidenziazioni, e il colore da solo non basta:
   il bordo distingue l'allarme anche a chi i colori non li separa. */
mark.seg {
  padding: 0 4px; border-radius: 6px; font-weight: 600; font-style: normal;
  background: var(--bg); color: inherit;
}
mark.seg-rimosso { background: var(--ok-bg); color: var(--ok-tx); }
mark.seg-pseudo { background: var(--accent-soft); color: var(--accent-strong); }
mark.seg-allarme {
  background: var(--bad-bg); color: var(--bad-tx);
  outline: 1px solid var(--bad-tx);
}
.seg-legenda { font-size: 12.5px; color: var(--ink-3); margin: 0 0 10px; }
/* nel dettaglio il testo È la pagina: niente riquadro che scorre a parte */
pre.payload.payload-intera { max-height: none; }

/* ---------------------------------------------------------------- lavori
   Il riquadro dei lavori lunghi, in basso a destra su ogni pagina. Un match
   con l'AI dura decine di secondi: senza, chi cambia pagina non sa più né a
   che punto sia né quando finisce. Vuoto non occupa spazio e non intercetta
   il puntatore, così non copre mai un pulsante per niente. */
.lavori {
  position: fixed; right: 18px; bottom: 18px; z-index: 60;
  display: flex; flex-direction: column; gap: 8px;
  max-width: min(360px, calc(100vw - 36px)); pointer-events: none;
}
.lavori:empty { display: none; }
.lavoro {
  pointer-events: auto; background: var(--surface); border-radius: 12px;
  border: 1px solid var(--grid); box-shadow: 0 8px 26px rgba(0, 0, 0, 0.14);
  padding: 11px 13px; font-size: 13px; animation: lavoro-entra 0.18s ease-out;
}
@keyframes lavoro-entra { from { opacity: 0; transform: translateY(8px); } }
.lavoro-testa { display: flex; align-items: baseline; gap: 8px; }
.lavoro-titolo {
  font-weight: 600; color: var(--ink); flex: 1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lavoro-chiudi {
  border: 0; background: none; cursor: pointer; color: var(--ink-3);
  font-size: 15px; line-height: 1; padding: 0 2px;
}
.lavoro-chiudi:hover { color: var(--ink); }
.lavoro-stato { color: var(--ink-2); margin-top: 3px; }
.lavoro-azioni { display: flex; gap: 10px; margin-top: 8px; align-items: center; }
.lavoro-azioni a { font-weight: 600; }
.lavoro-annulla {
  border: 0; background: none; padding: 0; cursor: pointer;
  color: var(--ink-3); font-size: 12.5px; text-decoration: underline;
}
.lavoro-annulla:hover { color: var(--bad-tx); }
/* La barra è indeterminata finché non si sa quante letture saranno: meglio un
   movimento onesto che una percentuale inventata. */
.lavoro-barra {
  height: 4px; border-radius: 99px; background: var(--grid);
  margin-top: 8px; overflow: hidden;
}
.lavoro-barra i { display: block; height: 100%; background: var(--accent-strong); }
.lavoro-barra.indeterminata i { width: 35%; animation: lavoro-scorre 1.1s ease-in-out infinite; }
@keyframes lavoro-scorre {
  from { transform: translateX(-100%); } to { transform: translateX(300%); }
}
/* La riga di una ricerca ancora in corso, nell'elenco delle proprie */
.reg-tab tr.riga-in-corso td { background: var(--accent-soft); }
/* La scheda appena diventata «pronta» si fa notare una volta sola: chi torna
   dopo dieci minuti la trova ferma, non lampeggiante. */
.lavoro.pronto { animation: lavoro-pronto 1.4s ease-out 2; }
@keyframes lavoro-pronto {
  0%, 100% { box-shadow: 0 8px 26px rgba(0, 0, 0, 0.14); }
  50% { box-shadow: 0 0 0 4px var(--ok-bg), 0 8px 26px rgba(0, 0, 0, 0.14); }
}
/* La vista grande dello stesso lavoro, sulla pagina del match */
.lavoro-attesa .lavoro-fase { color: var(--ink-2); margin: 6px 0 0; }
.lavoro-attesa .lavoro-barra { margin-top: 10px; }
.lavoro-attesa .actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.lavoro-attesa .actions form { margin: 0; }
.lavoro-attesa.fallito, .lavoro-attesa.interrotto { border-color: var(--bad-tx); }
.lavoro.pronto { border-color: var(--ok-tx); }
.lavoro.fallito, .lavoro.interrotto { border-color: var(--bad-tx); }

/* =============================================================== menu del CV
   Le opzioni erano due caselle in fila accanto ai pulsanti, e ogni opzione
   nuova allungava la barra fino a mandarla a capo. Qui diventano un menu: le
   scelte dichiarano insieme CHE DOCUMENTO si vuole, una riga di riepilogo lo
   dice a parole, e i due formati stanno sotto le scelte che li governano,
   invece che accanto, dove sembravano indipendenti da loro. */
.cv-menu { position: relative; }
.cv-menu > summary {
  list-style: none; cursor: pointer; user-select: none;
  display: inline-flex; align-items: center; gap: 6px;
}
.cv-menu > summary::-webkit-details-marker { display: none; }
.cv-caret { font-size: 10px; color: var(--ink-3); transition: transform 0.15s; }
.cv-menu[open] .cv-caret { transform: rotate(180deg); }
.cv-pop {
  position: absolute; z-index: 40; top: calc(100% + 6px); right: 0;
  width: 320px; max-width: calc(100vw - 32px);
  background: #fff; border: 1px solid var(--grid); border-radius: 12px;
  padding: 12px 14px; box-shadow: 0 10px 30px rgba(11, 11, 11, 0.13);
}
.cv-pop-tit {
  margin: 0 0 6px; font-size: 11.5px; text-transform: uppercase;
  letter-spacing: 0.5px; color: var(--ink-3); font-weight: 650;
}
.cv-pop-tit + .cv-pop-tit, .cv-riepilogo + .cv-pop-tit { margin-top: 12px; }
.cv-pop label {
  display: grid; grid-template-columns: auto 1fr; gap: 2px 8px;
  align-items: start; padding: 6px 0; cursor: pointer; font-size: 14px;
}
.cv-pop label input { margin-top: 3px; }
/* La nota sotto ogni voce parte dalla colonna del testo, non da sotto la
   casella: allineata alla casella si legge come una seconda opzione. */
.cv-pop label i {
  grid-column: 2; font-style: normal; font-size: 12px; color: var(--ink-3);
}
.cv-riepilogo {
  margin: 10px 0 0; padding: 8px 10px; border-radius: 8px;
  background: var(--accent-soft); color: var(--accent-strong);
  font-size: 12.5px; font-weight: 600;
}
.cv-pop-btn { display: flex; gap: 8px; flex-wrap: wrap; }

/* ======================================================== storico del profilo
   Due viste dello stesso dato: il riassunto nella scheda del profilo (le
   ultime quattro modifiche, per la domanda «è successo qualcosa?») e la
   pagina intera con i filtri e il ripristino. */
.storico-mini { list-style: none; margin: 0 0 12px; padding: 0; }
.storico-mini li {
  padding: 8px 0; border-bottom: 1px solid var(--grid); font-size: 13.5px;
}
.storico-mini li:last-child { border-bottom: none; }
.st-testa { display: flex; justify-content: space-between; gap: 8px; }
.st-quando { color: var(--ink-3); white-space: nowrap; font-size: 12.5px; }
.st-cosa {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-top: 3px; color: var(--ink-2); font-size: 12.5px;
}
/* I nomi dei campi vanno su una riga sola con i puntini: sono lunghi
   («Backend developer, Portale clienti (2019) · tecnologie») e a capo
   sfonderebbero la colonna della scheda. Nella pagina intera stanno per esteso. */
.st-campi {
  color: var(--ink-3); flex: 1 1 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.st-intestazione {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 10px; flex-wrap: wrap; margin-bottom: 10px;
}
.st-intestazione .badge, .st-intestazione .hint { margin-left: 6px; }
.storico-righe { table-layout: fixed; }
.storico-righe th.st-sel, .storico-righe td.st-sel { width: 34px; text-align: center; }
.storico-righe th:nth-child(2) { width: 34%; }
.st-sezione {
  display: block; font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.4px; color: var(--ink-3);
}
.st-campo { color: var(--ink); }
/* Il prima è quello che si è perso, il dopo è quello che c'è: il colore lo
   dice, il segno non serve. Le due colonne vanno a capo: un valore troncato
   in uno storico è esattamente il valore che si stava cercando. */
.st-prima { color: var(--ink-3); text-decoration: line-through; }
.st-dopo { color: var(--ink); }
.st-prima, .st-dopo { overflow-wrap: anywhere; }
.st-annullata td { background: var(--warn-bg); }
.st-annullata .st-dopo { text-decoration: line-through; color: var(--ink-3); }
.st-azioni {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 10px;
}
.st-azioni .hint { flex: 1 1 240px; }
/* Il ripristino dell'intero salvataggio è la seconda scelta, non un'etichetta:
   con il solo `.btn-ghost` (pensato per le icone) restava indistinguibile dal
   testo che gli sta accanto, e nessuno lo cliccava. */
.st-azioni .btn-ghost {
  font-size: 13px; text-decoration: underline;
  text-decoration-color: var(--baseline); text-underline-offset: 3px;
}
.st-azioni .btn-ghost:hover {
  background: none; color: var(--accent-strong);
  text-decoration-color: currentColor;
}
/* La cancellazione non è il ripristino e non deve sembrargli un fratello: sta
   in fondo alla riga, la nota fra i due fa da distanza, e ne ha il colore.
   Il `:hover` rosso è quello del `.btn-ghost` di base, che la regola qui sopra
   aveva riportato all'accento. */
.st-azioni .st-cancella { margin-left: auto; color: var(--bad-tx); }
.st-azioni .st-cancella:hover { background: var(--bad-bg); color: var(--bad-tx); }
/* Il riquadro della pulizia chiude la pagina. Il bordo lo distingue dai
   salvataggi che gli stanno sopra: sono tutti `.card`, e senza un segno si
   leggerebbe come un'altra modifica invece che come il posto da cui si
   cancella. Stessa idea di `.card-avviso`. */
.st-pulizia { border-color: var(--bad-tx); }
.st-pulizia .hint a { color: inherit; }

/* ==================================================== hardware e strumenti */
/* La riga dell'hardware sotto un'esperienza: stesso corpo delle tecnologie ma
   distinguibile, altrimenti diventano due righe grigie identiche in fila. */
.tech-hw { color: var(--ink-2); }
.tech-hw::first-letter { font-weight: 600; }
/* Suggeritore: pastiglie sotto il campo, filtrate sul pezzo che si sta
   scrivendo. Non è una <datalist> perché quella confronta il valore intero,
   e qui il valore intero è un elenco separato da virgole. */
.hw-sugg { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.hw-chip {
  font: inherit; font-size: 12px; cursor: pointer;
  padding: 2px 8px; border-radius: 99px;
  background: var(--accent-soft); color: var(--accent-strong);
  border: 1px solid transparent;
}
.hw-chip:hover { border-color: var(--accent-strong); }
/* I nomi orfani (scritti nei progetti, assenti dall'anagrafica) */
.banner-orfane { border-left: 3px solid var(--warn-tx); }
.orfane-elenco { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.hw-elimina { display: flex; align-items: center; gap: 8px; }
.hw-anche { font-size: 12px; color: var(--ink-3); white-space: nowrap; }
/* I nomi uniti a una voce: si vedono sotto la voce che li ha assorbiti, e si
   separano di nuovo da lì. Sono pastiglie-pulsante, non etichette: la sola
   azione possibile su un alias è disfarlo. */
.hw-alias { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 6px 0; }
.hw-alias form { margin: 0; }
.hw-alias-chip { font: inherit; font-size: 12px; cursor: pointer; }
.hw-alias-chip:hover { border-color: var(--bad-tx); color: var(--bad-tx); }

/* ============================================ pulizia del catalogo con l'AI */
/* Il riquadro d'avvio sta fra il modulo d'inserimento e la scrivania: è
   manutenzione, come aggiungere una voce, e non deve competere con l'elenco.
   Testo a sinistra, azione a destra: a schermo stretto si incolonna. */
.pulizia-avvio {
  display: grid; grid-template-columns: 1fr auto; gap: 14px 20px;
  align-items: center;
}
.pulizia-avvio h2 { margin: 0 0 4px; }
.pulizia-testo .hint { margin: 0; max-width: 78ch; }
.pulizia-azioni {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  max-width: 30ch;
}
.pulizia-azioni form { margin: 0; }
.pulizia-azioni .hint { margin: 0; }
/* L'elenco lasciato a metà: è la riga che evita di rifare (e ripagare)
   un'analisi già pagata, quindi si vede. */
.pulizia-ripresa {
  grid-column: 1 / -1; margin: 0; padding: 8px 11px; border-radius: 8px;
  background: var(--accent-soft); color: var(--accent-strong); font-size: 13.5px;
}
@media (max-width: 820px) {
  .pulizia-avvio { grid-template-columns: 1fr; }
  .pulizia-azioni { max-width: none; }
}

/* --- la pagina delle proposte */
.pul-card { padding-top: 12px; }
/* Una fusione si legge in una riga sola: che cosa resta, ← , che cosa sparisce.
   La freccia punta verso ciò che resta perché è lì che finiscono i profili. */
.pul-fusione {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 12px;
  align-items: start;
}
.pul-freccia { color: var(--ink-3); font-size: 20px; align-self: center; }
.pul-voce {
  background: var(--bg); border: 1px solid var(--grid); border-radius: 8px;
  padding: 8px 11px; margin-bottom: 6px;
}
.pul-voce b { display: block; font-size: 14px; }
.pul-voce .hint { margin: 2px 0 0; font-size: 12px; }
/* Le voci che spariscono portano il segno di ciò che succede: barrate, come
   nel catalogo per i clienti disattivati. */
.pul-perde b { text-decoration: line-through; text-decoration-color: var(--baseline); }
.pul-perche {
  margin: 10px 0 0; font-size: 13px; color: var(--accent-strong);
}
@media (max-width: 760px) {
  .pul-fusione { grid-template-columns: 1fr; }
  .pul-freccia { transform: rotate(90deg); }
}

/* Gli spostamenti di categoria sono decine: una riga a testa, non una scheda.
   Sono l'operazione reversibile, e vanno scorsi in fretta. */
.pul-elenco { display: flex; flex-direction: column; gap: 2px; }
.pul-riga {
  display: grid; align-items: baseline; gap: 8px; cursor: pointer;
  grid-template-columns: 16px minmax(120px, 1.2fr) minmax(90px, 0.9fr) 12px minmax(90px, 0.9fr) 2fr;
  padding: 5px 6px; border-radius: 7px; font-size: 13.5px;
}
.pul-riga:hover { background: var(--bg); }
.pul-riga input {
  width: 16px; height: 16px; accent-color: var(--accent); margin: 0;
}
.pul-nome { font-weight: 600; }
.pul-da { color: var(--ink-3); text-decoration: line-through;
  text-decoration-color: var(--baseline); }
.pul-verso { color: var(--ink-3); }
.pul-a { color: var(--accent-strong); font-weight: 600; }
.pul-perche-riga { color: var(--ink-3); font-size: 12.5px; }
@media (max-width: 900px) {
  .pul-riga { grid-template-columns: 16px 1fr; }
  .pul-riga .pul-verso { display: none; }
  .pul-riga .pul-da, .pul-riga .pul-a, .pul-riga .pul-perche-riga {
    grid-column: 2; }
}
/* La riga che toglie una voce dal piano: sta in fondo alla scheda aperta, in
   tono minore, perche' e' un'eccezione e non il gesto principale della pagina. */
.gap-togli {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--grid);
}
.gap-togli input[type="text"] {
  flex: 1; min-width: 200px; max-width: 34rem;
  padding: 6px 9px; border: 1px solid var(--baseline); border-radius: 8px;
  font: inherit; font-size: 13px; background: #fff; color: var(--ink);
}
.gap-togli input[type="text"]:focus {
  outline: 2px solid var(--accent-soft); border-color: var(--accent);
}

/* Le righe della revisione del piano formazione: stesso aspetto di quelle
   della pulizia del catalogo, ma senza il «da → a», perche' qui c'e' una voce,
   quanto pesa e il perche'. Ereditare le sei colonne di `.pul-riga` stampava
   il motivo incolonnato, una lettera per riga. Stanno dopo la media query di
   sopra perche' a parita' di specificita' vince l'ultima regola scritta. */
.gap-riga {
  grid-template-columns: 16px minmax(140px, 1fr) minmax(80px, 0.5fr) 2.4fr;
}
/* Le voci gia' tolte dal piano: nessuna spunta (la decisione e' presa) e in
   coda il pulsante che la rimette dentro. */
.gap-riga-esclusa {
  grid-template-columns: minmax(140px, 1fr) 2.4fr auto;
  cursor: default; align-items: center;
}
@media (max-width: 900px) {
  .gap-riga { grid-template-columns: 16px 1fr; }
  .gap-riga > *:not(input) { grid-column: 2; }
  .gap-riga-esclusa { grid-template-columns: 1fr; }
}
/* «Scarta tutto» non è un'azione di pari grado: chiude l'elenco e basta.
   Sta sotto la barra delle azioni, in tono minore e con il suo perché. */
.pul-scarta {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin: 14px 2px 0;
}
.pul-scarta .btn-ghost {
  font-size: 13px; text-decoration: underline;
  text-decoration-color: var(--baseline); text-underline-offset: 3px;
  padding-left: 0;
}
.pul-scarta .btn-ghost:hover { background: none; color: var(--bad-tx); }
.pul-scarta .hint { margin: 0; }

/* ============================================================ candidature
   Le pagine pubbliche (modulo, informativa, conferma) e la scrivania interna.
   Le prime non hanno la barra della piattaforma: chi arriva dal sito aziendale
   non deve vedere la mappa di quello che c'è dentro. */
.pubblica { background: var(--bg); }
.pub-top { background: var(--surface); border-bottom: 1px solid var(--grid); }
.pub-top-inner {
  max-width: 1180px; margin: 0 auto; padding: 12px 20px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.pub-main { padding-top: 28px; }
/* La trappola anti-robot: fuori dallo schermo, non `display:none`, perché
   alcuni robot saltano proprio ciò che è nascosto in quel modo. Non la
   raggiunge nemmeno chi naviga da tastiera (`tabindex="-1"` nel modulo). */
.trappola {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden;
}

/* ------------------------------------------------- scrivania candidature */
/* Il numero accanto alla voce di menu: quante candidature aspettano. Piccolo
   e non allarmante, ma visibile, perche' una coda che non si vede non si
   guarda. */
.pallino {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; margin-left: 4px;
  border-radius: 999px; background: var(--accent); color: #fff;
  font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.cand-scheda { display: flex; flex-direction: column; gap: 8px; }
.cand-testa {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
}
.cand-nome { font-weight: 650; font-size: 15px; }
.cand-ruolo { margin: 0; color: var(--ink-2); }
/* Le segnalazioni: la parte che si legge per prima, e l'unica che dice
   *perche'* questo profilo interessa. Il colore distingue la forza del
   segnale, non un giudizio: rosso = non l'abbiamo affatto, giallo = ce l'ha
   una persona sola, blu = qualcuno ce l'ha chiesta. */
.cand-segnali, .segnali { list-style: none; margin: 0; padding: 0; }
.cand-segnali li, .segnali li {
  font-size: 13px; line-height: 1.5; padding: 4px 0 4px 10px;
  border-left: 3px solid var(--baseline); color: var(--ink-2);
}
.cand-segnali li b, .segnali li b { color: var(--ink); }
.seg-mancante { border-left-color: var(--bad-tx); }
.seg-rara { border-left-color: var(--warn-tx); }
.seg-richiesta { border-left-color: var(--accent); }
.segnali li { display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.segnali li span { color: var(--ink-2); }
/* La riga che sposta la candidatura: pulsante del passo successivo, tendina
   per tutti gli altri, e il perche'. In una riga sola perche' e' un gesto
   solo, e su schermo stretto va a capo invece di stringersi. */
.stato-form {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
  margin-top: 8px;
}
.stato-form + .stato-form { margin-top: 6px; }
/* L'etichetta del perche' e il suo elenco stanno sulla stessa riga del resto,
   e l'elenco prende lo spazio che avanza: le voci sono frasi, non parole. */
.motivo-chiusura {
  display: flex; align-items: center; gap: 6px; flex: 1 1 260px; min-width: 0;
}
.motivo-chiusura > span { color: var(--muted); font-size: 12px; flex: none; }
.motivo-chiusura > select { flex: 1 1 auto; min-width: 0; }
.note-elenco { list-style: none; margin: 12px 0 0; padding: 0; }
.note-elenco > li { padding: 10px 0; border-top: 1px solid var(--grid); }
.riga-parere {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
/* Il motivo di un avviso non partito e' lungo quanto il messaggio del server:
   si spezza nella colonna del testo, e i due pulsanti restano in fila. Senza,
   la colonna del testo non si stringeva e «revoca» finiva sotto «Manda
   l'avviso», con la riga alta il doppio delle altre. */
.riga-parere > span:first-child { min-width: 0; }
.riga-parere > .actions { flex: none; flex-wrap: nowrap; }
.storia { list-style: none; margin: 0; padding: 0; font-size: 13px; }
.storia > li { padding: 8px 0; border-top: 1px solid var(--grid); }
.storia > li:first-child { border-top: 0; padding-top: 0; }
.affinita { list-style: none; margin: 0; padding: 0; }
.affinita > li {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 7px 0; border-top: 1px solid var(--grid);
}
.affinita > li:first-child { border-top: 0; }
.esperienza { padding: 10px 0; border-top: 1px solid var(--grid); }
.esperienza:first-of-type { border-top: 0; }
.esperienza p { margin: 4px 0 0; color: var(--ink-2); font-size: 13.5px; }
.warn-tx { color: var(--warn-tx); }

/* Il bivio fra un collega e un candidato esterno, in cima alle due pagine che
   creano un profilo. Due riquadri e non una tendina: la differenza fra i due
   non e' un'etichetta, e va letta prima di scegliere, non dopo. */
.scelta {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 12px; margin-bottom: 18px;
}
.scelta-voce {
  display: block; padding: 14px 16px; border-radius: 12px;
  background: var(--surface); border: 1px solid var(--border); color: var(--ink);
  text-decoration: none;
}
.scelta-voce:hover { border-color: var(--accent); text-decoration: none; }
.scelta-voce b { display: block; margin-bottom: 4px; font-size: 15px; }
.scelta-voce span { display: block; font-size: 12.5px; color: var(--ink-2); line-height: 1.5; }
/* La voce attiva e' la pagina in cui si e' gia': si distingue senza sembrare
   un pulsante da premere, o si finisce per cliccare dove si e' gia'. */
.scelta-voce.on {
  border-color: var(--accent); background: var(--accent-soft); cursor: default;
}
.scelta-voce.on b { color: var(--accent-strong); }

/* La rimozione di un CV: le due strade negli stessi riquadri del bivio
   collega/candidato, ma qui si sceglie restando sulla pagina, con il bottone
   dentro al riquadro. La voce scelta si accende come la pagina attiva del
   bivio: la differenza fra le due e' un profilo svuotato, e deve vedersi. */
/* Il modulo contiene le schede: la regola delle schede impilate si ferma al
   suo bordo, e senza questa la prima si attaccava all'avviso sopra. */
main > form.rimozione-cv:not(:first-child) { margin-top: 14px; }
.rimozione-scelta .scelta-voce { display: flex; gap: 10px; align-items: flex-start; cursor: pointer; }
.rimozione-scelta .scelta-voce input { flex: none; margin-top: 3px; accent-color: var(--accent); }
.rimozione-scelta .scelta-voce:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.rimozione-scelta .scelta-voce:has(input:checked) b { color: var(--accent-strong); }
.rimozione-conti { margin: 6px 0; padding-left: 18px; font-size: 12.5px; color: var(--ink-2); }
.rimozione-conti li { margin: 1px 0; overflow-wrap: anywhere; }
/* Va a capo come `.field .opt`: la riga porta due valori scritti per esteso, e
   sul telefono usciva dal riquadro. */
.rimozione-sede { margin: 2px 0 0; font-size: 13.5px; white-space: normal; align-items: flex-start; }
.rimozione-sede input { flex: none; margin-top: 2px; }
.rimozione-sede span { min-width: 0; overflow-wrap: anywhere; }

/* I CV allegati sul profilo: il nome a sinistra, «Rimuovi» a destra per chi
   amministra. Un collegamento sobrio e non un pulsante rosso: porta a una
   pagina che chiede che cosa togliere, da solo non toglie niente. */
.cv-allegato {
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  font-size: 13px; margin-bottom: 6px; color: var(--ink-2);
}
.cv-allegato > span:first-child { min-width: 0; overflow-wrap: anywhere; }
.cv-allegato-data { color: var(--ink-3); }
.cv-allegato-togli { flex: none; font-size: 12.5px; color: var(--ink-3); }
.cv-allegato-togli:hover { color: var(--bad-tx); }

/* La correzione a mano sulla scheda del candidato. Sta dentro un `<details>`
   perche' non e' il gesto quotidiano: si apre da sola quando manca il nome o
   l'e-mail, cioe' quando la lettura del CV ha fallito proprio dove serve. */
.correggi { margin-top: 10px; border-top: 1px solid var(--grid); padding-top: 10px; }
.correggi > summary {
  cursor: pointer; font-size: 13px; font-weight: 550; color: var(--accent-strong);
}
.correggi > summary:hover { text-decoration: underline; }
.correggi form { margin-top: 10px; }
.correggi .field { margin-bottom: 8px; }
/* La riga per agganciare una competenza: campo, livello, pulsante. Va a capo
   su schermo stretto invece di stringere il campo a due centimetri. */
.aggiungi-riga {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 8px;
}
.aggiungi-riga input[type="text"] { flex: 1 1 200px; }
/* La crocetta che toglie una competenza: dentro la pastiglia, in tono minore.
   Un pulsante di pari peso accanto a ogni voce avrebbe fatto sembrare la
   rimozione l'azione principale di quell'elenco. */
.chip-togli {
  border: 0; background: none; cursor: pointer; padding: 0 0 0 4px;
  color: var(--ink-3); font-size: 14px; line-height: 1;
}
.chip-togli:hover { color: var(--bad-tx); }

/* Menu a tendina con la ricerca (SYS-001 MLF-014.1): il riquadro che si apre
   al posto dell'elenco del browser, sopra a tutto, attaccato al menu che l'ha
   aperto. Su uno schermo stretto diventa un foglio in cima alla pagina, dove
   la tastiera del telefono non lo copre, con un velo sul resto. */
.tendina {
  position: fixed; z-index: 200;
  display: flex; flex-direction: column;
  width: max-content; max-width: min(480px, calc(100vw - 16px));
  background: #fff; border: 1px solid var(--baseline); border-radius: 10px;
  box-shadow: 0 10px 28px rgba(11, 11, 11, 0.16);
  overflow: hidden; font-size: 14px; line-height: 1.35;
}
.tendina-titolo { display: none; }
.tendina-cerca {
  flex: none; margin: 8px; padding: 7px 10px;
  border: 1px solid var(--baseline); border-radius: 8px;
  font: inherit; color: var(--ink); background: var(--bg);
}
.tendina-cerca:focus { outline: 2px solid var(--accent); outline-offset: -1px; background: #fff; }
/* `position: relative` perché le voci misurino la loro altezza dall'elenco:
   è così che la voce evidenziata da tastiera resta in vista. */
.tendina-lista {
  position: relative; flex: 1 1 auto; min-height: 0; overflow-y: auto;
  overscroll-behavior: contain; list-style: none; margin: 0; padding: 0 0 6px;
}
.tendina-lista li[role="option"] {
  padding: 6px 12px 6px 26px; cursor: pointer; color: var(--ink);
  overflow-wrap: anywhere;
}
.tendina-lista li.attiva { background: var(--accent-soft); color: var(--accent-strong); }
/* la voce scelta adesso, con il segno a sinistra come nei menu del sistema */
.tendina-lista li[aria-selected="true"] { font-weight: 650; }
.tendina-lista li[aria-selected="true"]::before {
  content: "✓"; float: left; width: 0; margin-left: -16px; color: var(--accent-strong);
}
.tendina-lista li[aria-disabled="true"] { color: var(--ink-3); cursor: default; background: none; }
.tendina-gruppo {
  padding: 8px 12px 3px; font-size: 11.5px; font-weight: 650;
  text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-3);
}
.tendina-vuota { margin: 0; padding: 2px 12px 12px; font-size: 13px; color: var(--ink-3); }
.tendina.tendina-foglio {
  top: 12px; left: 12px; right: 12px; bottom: auto; width: auto; max-width: none;
  max-height: min(60vh, 460px);
  box-shadow: 0 0 0 100vmax rgba(11, 11, 11, 0.32), 0 10px 28px rgba(11, 11, 11, 0.25);
}
.tendina-foglio .tendina-titolo {
  display: block; padding: 10px 12px 0; font-size: 13px; font-weight: 650; color: var(--ink-2);
}
.tendina-foglio .tendina-titolo:empty { display: none; }
/* voci alte un dito */
.tendina-foglio .tendina-lista li[role="option"] { padding-top: 11px; padding-bottom: 11px; }

/* Analisi › CV anonimi (SYS-001 LLF-007.2.2): il numero com'è scritto sul CV,
   in evidenza, perché è da lì che si parte; la persona accanto. */
.cv-anonimi { padding-top: 12px; }
.cv-anonimi .cat-barra { top: 56px; }
.tab-anonimi td { vertical-align: middle; padding-top: 9px; padding-bottom: 9px; }
.tab-anonimi td:nth-child(2) a { font-weight: 600; }
.tab-anonimi td.tab-azione { text-align: right; white-space: nowrap; }
.codice-anonimo {
  display: inline-block; padding: 3px 10px; border-radius: 999px; white-space: nowrap;
  background: var(--accent-soft); color: var(--accent-strong);
  font-weight: 650; font-variant-numeric: tabular-nums;
}
/* arrivati con #codice-81 la riga si fa riconoscere un istante */
@media (prefers-reduced-motion: no-preference) {
  .tab-anonimi tr:target td { animation: approdo-riga 1.8s ease-out; }
}
@keyframes approdo-riga { from { background: var(--accent-soft); } }

/* ------------------------------------------------------------ posta inviata
   Il registro di ogni e-mail partita dalla piattaforma. Ogni gruppo di
   destinatari ha un colore suo, lo stesso nella mappa dei tipi, sul bordo di
   ogni riga e nel pallino del tipo: chi scorre l'elenco capisce a chi è
   andata un'e-mail prima ancora di leggerne il nome. Sono colori delle serie
   categoriche e mai quelli di stato: qui verde e rosso dicono «partita» e
   «non partita», e un gruppo verde si leggerebbe come un esito. */
.g-candidati { --gruppo: var(--s2); }
.g-colleghi { --gruppo: var(--s1); }
.g-selezione { --gruppo: var(--s7); }
.g-servizio { --gruppo: var(--baseline); }

/* La ricerca: il campo largo, le due tendine, i pulsanti in fila. */
.posta-filtri-riga {
  display: grid; gap: 12px; align-items: end;
  grid-template-columns: minmax(0, 2.2fr) minmax(0, 1fr) minmax(0, 1fr) auto;
}
.posta-filtri-riga .field { margin: 0; }
.posta-filtri-riga .pf-azioni { flex-wrap: nowrap; }
@media (max-width: 820px) {
  .posta-filtri-riga { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .posta-filtri-riga .pf-cerca, .posta-filtri-riga .pf-azioni { grid-column: 1 / -1; }
}
.posta-attivi { margin-top: 12px; }
.posta-attivi .chip a:not(.chip-togli) { font-weight: 600; }

/* I tipi di messaggio divisi per destinatario: sono il filtro per tipo. */
.posta-mappa-testa {
  display: flex; flex-wrap: wrap; gap: 2px 10px; align-items: baseline;
  margin: 16px 0 10px; padding-top: 14px; border-top: 1px solid var(--grid);
  font-size: 13.5px;
}
.posta-mappa-testa .hint { margin: 0; }
.posta-mappa {
  display: grid; gap: 10px 22px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 1000px) { .posta-mappa { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .posta-mappa { grid-template-columns: minmax(0, 1fr); } }
.posta-gruppo { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.posta-gruppo h3 {
  display: flex; align-items: center; gap: 7px; margin: 0 0 4px;
  font-size: 11.5px; font-weight: 650; text-transform: uppercase;
  letter-spacing: .05em; color: var(--ink-3);
}
.posta-gruppo h3::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: var(--gruppo);
}
.posta-tipo {
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  padding: 5px 9px; margin: 0 -9px; border-radius: 8px;
  border: 1px solid transparent; color: var(--ink);
  font-size: 13.5px; line-height: 1.35;
}
.posta-tipo:hover { background: var(--bg); text-decoration: none; }
.posta-tipo b { font-weight: 600; color: var(--ink-2); font-variant-numeric: tabular-nums; }
/* Un tipo senza e-mail nei filtri di adesso resta al suo posto, smorzato:
   toglierlo farebbe cambiare forma alla mappa a ogni ricerca. */
.posta-tipo.vuoto, .posta-tipo.vuoto b { color: var(--ink-3); font-weight: 500; }
.posta-tipo.attivo {
  background: var(--accent-soft); border-color: var(--accent); color: var(--accent-strong);
}
.posta-tipo.attivo b { color: var(--accent-strong); }

/* L'elenco: righe da bordo a bordo della scheda, come in un programma di
   posta. `clip` e non `hidden`: taglia gli angoli senza diventare un
   contenitore che scorre, e i giorni restano attaccati in cima mentre si
   scende. */
.posta-elenco { padding: 0 0 8px; overflow: clip; scroll-margin-top: 70px; }
.posta-elenco-testa { padding: 16px 18px 8px; margin: 0; }
.posta-giorno {
  position: sticky; top: 56px; z-index: 3;
  display: flex; align-items: baseline; gap: 8px; margin: 0;
  padding: 9px 18px 7px; background: var(--surface);
  border-top: 1px solid var(--grid); border-bottom: 1px solid var(--grid);
  font-size: 12.5px; font-weight: 650; color: var(--ink-2);
}
.posta-giorno small { font-weight: 500; color: var(--ink-3); font-size: 12px; }
.posta-voce + .posta-voce { border-top: 1px solid var(--grid); }
.posta-voce > summary {
  list-style: none; cursor: pointer;
  display: grid; align-items: center; gap: 14px;
  grid-template-columns: 42px minmax(0, 14rem) minmax(0, 1fr) auto auto auto;
  padding: 9px 12px 9px 15px; border-left: 3px solid var(--gruppo);
  font-size: 13.5px;
}
.posta-voce > summary::-webkit-details-marker { display: none; }
.posta-voce > summary::marker { content: ""; }
.posta-voce > summary:hover { background: var(--bg); }
.posta-voce > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* Aperta, la riga diventa una fascia grigia con dentro il foglio bianco. */
.posta-voce[open] { background: var(--bg); padding-bottom: 16px; }
.pv-ora { color: var(--ink-3); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.pv-chi { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.pv-chi b, .pv-chi small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pv-chi b { font-weight: 600; }
.pv-chi small { color: var(--ink-3); font-size: 11.5px; }
.pv-oggetto {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--ink-2);
}
.pv-clip { font-size: 12px; }
.pv-tenue { color: var(--ink-3); font-style: italic; font-weight: 400; }
.pv-tipo, .pf-tipo { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.pv-tipo { font-size: 12px; color: var(--ink-2); }
.pv-tipo::before, .pf-tipo::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: var(--gruppo);
}
/* La «×» che toglie l'e-mail dal registro: in tono minore, come le altre
   crocette della piattaforma, e rossa solo sotto il puntatore. La colonna c'è
   anche quando è vuota (per chi non può eliminare), così le righe di tutti
   restano allineate allo stesso modo. */
.pv-azioni { display: flex; justify-content: flex-end; min-width: 28px; }
.pv-elimina { font-size: 18px; line-height: 1; padding: 3px 8px; }
.pv-elimina:focus-visible { outline: 2px solid var(--bad-tx); outline-offset: 1px; }
@media (max-width: 760px) {
  .posta-voce > summary {
    grid-template-columns: 38px minmax(0, 1fr) auto auto;
    grid-template-areas: "ora chi esito azioni" ". oggetto oggetto oggetto"
                         ". tipo tipo tipo";
    gap: 2px 10px;
  }
  .pv-ora { grid-area: ora; }
  .pv-chi { grid-area: chi; }
  .pv-oggetto { grid-area: oggetto; }
  .pv-tipo { grid-area: tipo; }
  .pv-esito { grid-area: esito; }
  .pv-azioni { grid-area: azioni; }
}

/* Il foglio: il messaggio com'è partito, nell'ordine di un programma di
   posta. Bianco, perché è il documento; tutto intorno è la pagina. */
.posta-foglio {
  margin: 4px 18px 0; background: #fff; overflow: hidden;
  border: 1px solid var(--grid); border-radius: 10px;
  box-shadow: 0 1px 2px rgba(11, 11, 11, 0.04);
}
.grid-2 > section > .posta-foglio { margin: 0; }
.pf-testa {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 3px 16px;
  margin: 0; padding: 12px 18px; background: var(--surface);
  border-bottom: 1px solid var(--grid); font-size: 13px;
}
.pf-testa dt { color: var(--ink-3); }
.pf-testa dd { margin: 0; overflow-wrap: anywhere; }
.pf-testa .pf-oggetto { font-weight: 650; }
/* L'indirizzo va a capo tutto intero, non spezzato con la «>» da sola sotto. */
.pf-indirizzo { display: inline-block; max-width: 100%; }
.pf-allegato { display: inline-flex; gap: 6px; align-items: baseline; margin-right: 10px; }
.pf-fallita {
  margin: 0; padding: 10px 18px; font-size: 13.5px;
  background: var(--bad-bg); color: var(--bad-tx);
  border-bottom: 1px solid rgba(179, 36, 36, 0.16);
}
/* Il testo va a capo dove andava a capo nell'e-mail. Un'e-mail lunga scorre
   dentro il foglio: una sola aperta non deve allungare l'elenco di tre
   schermate. Nella pagina della singola e-mail il testo è la pagina. */
.pf-corpo {
  padding: 16px 18px; white-space: pre-wrap; overflow-wrap: anywhere;
  font-size: 14px; line-height: 1.6; color: var(--ink);
  max-height: 34rem; overflow-y: auto;
}
.grid-2 .pf-corpo { max-height: none; }
.pf-vuoto { margin: 0; padding: 16px 18px; color: var(--ink-3); font-size: 13.5px; font-style: italic; }
.pf-piede {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 18px;
  padding: 9px 18px; border-top: 1px solid var(--grid); background: var(--surface);
  font-size: 12.5px; color: var(--ink-2);
}
.pf-tipo { font-weight: 600; color: var(--ink); }
.pf-apri { margin-left: auto; white-space: nowrap; font-weight: 550; }
/* Il segreto oscurato: una barra, come su un documento, con la spiegazione
   a portata di puntatore. */
mark.seg-oscurato {
  background: var(--ink-2); color: #fff; letter-spacing: .08em; cursor: help;
}
.posta-vuota { padding: 26px 18px 18px; text-align: center; color: var(--ink-2); }
.posta-vuota p { margin: 0 0 8px; }
.posta-elenco .paginazione { padding: 0 18px; }
/* Un numero che è una parola (una casella, una durata) sta nella fila dei
   numeri veri, ma in piccolo: un indirizzo a 28px non ci sta. */
.kpi .value.kpi-testo {
  font-size: 16px; letter-spacing: 0; padding-top: 8px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kpi.kpi-warn .label a { color: inherit; text-decoration: underline; }
/* Sulla scheda di una persona: c'è posta, e dove leggerla. */
.posta-scheda p { margin: 0 0 10px; color: var(--ink-2); font-size: 13.5px; }

/* ---------------------------------------------------------------- grafici
   I grafici disegnati sul server (`templates/_grafici.html`). Scala blu per
   il carico, rosso di stato per la sovrallocazione, grigio per il dato che
   manca; segni sottili, estremità del dato arrotondate a 4px e diritte verso
   la base, 2px di fondo fra due segni che si toccano. */
:root {
  --carico-libero: var(--lv1);
  --carico-parziale: var(--lv3);
  --carico-pieno: var(--lv5);
  --carico-sovra: #d03b3b;        /* stato «critico» della palette */
  --carico-ignoto: var(--baseline);
  --pista: #ecebe6;               /* il tempo libero nella scaletta, un passo sopra la griglia */
  /* La scaletta di una persona dice il tempo occupato in rosso, come il badge
     «Occupato» che le sta sopra. Il rosso è quello «critico» della palette:
     regge il bianco della cifra scritta dentro (4,8:1). Oltre il 100% un rosso
     più scuro, che dal primo si distingue anche per chi non vede i colori
     (ΔE 15 a occhio normale, 13 in deuteranopia), e comunque c'è la cifra. */
  --occupato: #d03b3b;
  --occupato-oltre: #8f1f1f;
}

/* Il suggerimento dei grafici: uno solo per pagina, lo sposta `app.js`. */
.grafico-tip {
  position: fixed; z-index: 200; pointer-events: none;
  max-width: 280px; padding: 6px 9px; border-radius: 6px;
  background: var(--ink); color: #fff; font-size: 12.5px; line-height: 1.35;
  /* una frase per riga: il periodo e il carico, poi i progetti */
  white-space: pre-line;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .18);
}
[data-tip] { cursor: default; }
[data-tip]:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* La scaletta del rilascio, sotto l'elenco «Ora su» nel profilo: una colonna
   per mese, il rosso alto quanto il tempo occupato, la cifra sopra. Le misure
   che i conti di `staffing.scaletta` devono conoscere sono due e stanno anche
   là: la larghezza minima (SC_LARGHEZZA_MINIMA, sotto la quale il grafico
   scorre invece di stringersi) e l'altezza della pista, su cui è tarata la
   soglia oltre la quale la cifra va dentro il rosso (SC_CIFRA_DENTRO). */
.scaletta { margin: 10px 0 0; }
.sc-titolo {
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--ink-3); margin-bottom: 4px;
}
.sc-scorre { overflow-x: auto; padding-bottom: 2px; }
.sc-corpo { min-width: 640px; }
.sc-pista {
  position: relative; height: 44px;
  background: var(--pista); border-radius: 4px; overflow: hidden;
}
.sc-tratto { position: absolute; top: 0; bottom: 0; }
.sc-tratto:hover, .sc-tratto:focus-visible { background: rgba(11, 11, 11, 0.05); }
/* Un progetto senza quota: il tempo che prende non si sa, e il tratteggio lo
   distingue dal grigio del libero, che a occhio gli somiglierebbe troppo. */
.sc-tratto.ignoto {
  background: repeating-linear-gradient(135deg, var(--carico-ignoto) 0 2px, var(--pista) 2px 6px);
}
.sc-occupato { position: absolute; left: 0; right: 0; bottom: 0; background: var(--occupato); }
.sc-occupato.oltre { background: var(--occupato-oltre); }
.sc-tratto:hover .sc-occupato, .sc-tratto:focus-visible .sc-occupato { filter: brightness(1.08); }
/* Lo spazio del colore del fondo fra due mesi e fra due scalini: è lui a fare
   delle colonne, senza tracciare bordi intorno ai segni. */
.sc-sep {
  position: absolute; top: 0; bottom: 0; width: 2px; margin-left: -1px;
  background: var(--surface); pointer-events: none;
}
/* La cifra di uno scalino: sopra il rosso quando c'è posto, dentro in
   bianco quando il rosso arriva quasi in cima (44px di pista, 12px di cifra). */
.sc-cifra {
  position: absolute; bottom: calc(var(--h) + 4px); transform: translateX(-50%);
  font-size: 11.5px; font-weight: 650; line-height: 12px; white-space: nowrap;
  color: var(--ink); pointer-events: none; font-variant-numeric: tabular-nums;
}
.sc-cifra.dentro { bottom: auto; top: calc(100% - var(--h) + 5px); color: #fff; }
.sc-cifra.zero { color: var(--ink-3); font-weight: 500; }
.sc-cifra.ignoto { background: var(--surface); padding: 1px 4px; border-radius: 4px; line-height: 12px; }
/* I segnalini di fine progetto: il numero della riga dell'elenco, su uno
   stelo che scende fino al punto in cui la scaletta cambia. */
.sc-fini { position: relative; height: 26px; }
.sc-fine {
  position: absolute; bottom: 0; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center;
}
.sc-fine::after { content: ""; width: 1px; height: 6px; background: var(--ink-3); }
.sc-fine.inizio { transform: translateX(-9px); align-items: flex-start; }
.sc-fine.inizio::after { margin-left: 8.5px; }
.sc-fine.fine { transform: translateX(calc(-100% + 9px)); align-items: flex-end; }
.sc-fine.fine::after { margin-right: 8.5px; }
.sc-fine:hover b, .sc-fine:focus-visible b { background: var(--ink); }
/* Il nome di ogni mese al centro della sua colonna, l'anno sotto. */
.sc-mesi { position: relative; height: 16px; margin-top: 4px; }
.sc-mesi span {
  position: absolute; top: 0; text-align: center; white-space: nowrap;
  font-size: 11.5px; line-height: 16px; color: var(--ink-2);
}
.sc-anni { position: relative; height: 15px; }
.sc-anni span {
  position: absolute; top: 0; padding-left: 2px; white-space: nowrap;
  font-size: 11px; font-weight: 600; line-height: 15px; color: var(--ink-3);
}
.sc-legenda { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 8px; font-size: 12px; color: var(--ink-2); }
.sc-legenda span { display: inline-flex; align-items: center; gap: 6px; }
.sc-chiave { display: inline-block; width: 12px; height: 10px; border-radius: 2px; }
.sc-chiave.occupato { background: var(--occupato); }
.sc-chiave.libero { background: var(--pista); box-shadow: inset 0 0 0 1px var(--grid); }
.sc-chiave.oltre { background: var(--occupato-oltre); }
.sc-chiave.ignoto { background: repeating-linear-gradient(135deg, var(--carico-ignoto) 0 2px, var(--pista) 2px 5px); }
.sc-chiave.fine { width: 11px; height: 11px; border-radius: 999px; background: var(--ink-2); }

/* ---------------------------------------------------------------- report di allocazione
   Analisi › Allocazione, il confronto e «Da sistemare». I colori degli stati
   sono quelli dei grafici (in cima a questa sezione): scala blu dal libero al
   pieno, rosso di stato per la sovrallocazione, grigio per il dato che manca. */
.st-libera { background: var(--carico-libero); }
.st-parziale { background: var(--carico-parziale); }
.st-piena { background: var(--carico-pieno); }
.st-sovrallocata { background: var(--carico-sovra); }
.st-ignota { background: var(--carico-ignoto); }
.chiave {
  display: inline-block; width: 10px; height: 10px; border-radius: 2px;
  margin-right: 5px; vertical-align: -1px;
}
.chiave-linea { display: inline-block; width: 14px; height: 2px; margin-right: 5px; vertical-align: 3px; border-radius: 1px; }
.chiave-linea.l-tasso { background: var(--carico-pieno); }
.chiave-linea.l-affid { background: var(--s2); }

/* La barra al 100% e le sue sorelle per reparto: 2px di fondo fra un
   segmento e l'altro, estremità arrotondate solo ai capi. */
.barra-stati { margin: 4px 0 0; }
.bs-traccia { display: flex; height: 18px; border-radius: 4px; overflow: hidden; background: var(--bg); }
.bs-seg { display: block; height: 100%; box-shadow: inset -2px 0 0 var(--surface); min-width: 3px; }
.bs-seg:last-child { box-shadow: none; }
.bs-seg:hover, .bs-seg:focus-visible { filter: brightness(1.12); }
.bs-legenda { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 8px; font-size: 12.5px; color: var(--ink-2); }
.bs-legenda span.zero { color: var(--ink-3); }
.bs-legenda b { color: var(--ink); font-variant-numeric: tabular-nums; }

.br-elenco { display: flex; flex-direction: column; gap: 8px; }
.br-riga { display: grid; grid-template-columns: 150px 1fr 34px; gap: 10px; align-items: center; font-size: 13px; }
.br-nome { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.br-nome.vuoto { color: var(--ink-3); font-style: italic; }
.br-traccia { display: block; height: 14px; }
.br-barra { display: flex; height: 14px; border-radius: 0 4px 4px 0; overflow: hidden; min-width: 3px; }
.br-n { color: var(--ink-2); font-variant-numeric: tabular-nums; text-align: right; }

/* Gli indicatori in testa: il numero, la linea dei mesi accanto, la
   differenza sotto, colorata da che cosa vuol dire. */
.kpi-row.tessere { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
.tessera-testa { display: flex; align-items: flex-end; justify-content: space-between; gap: 8px; }
.tessera .value a { color: inherit; }
.tessera .spark { width: 64px; height: 24px; flex: none; overflow: visible; }
.tessera .spark polyline { stroke: var(--baseline); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.delta { font-size: 12px; font-weight: 600; margin-top: 4px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.delta.migliorato { color: var(--ok-tx); }
.delta.peggiorato { color: var(--bad-tx); }
.differenze-da { margin: -10px 0 16px; }
.affidabilita a { margin-left: 6px; font-weight: 600; }

/* L'andamento: colonne impilate alte quanto il perimetro di quel mese. */
.andamento { margin: 0; }
.an-colonne { display: flex; align-items: flex-end; gap: 8px; height: 170px; padding-bottom: 20px; border-bottom: 1px solid var(--baseline); position: relative; }
.an-col { flex: 1 1 0; min-width: 0; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; position: relative; }
.an-pila { width: 100%; max-width: 24px; display: flex; flex-direction: column-reverse; border-radius: 4px 4px 0 0; overflow: hidden; }
.an-pila span { display: block; width: 100%; box-shadow: inset 0 2px 0 var(--surface); }
.an-pila span:last-child { box-shadow: none; }
.an-col:hover .an-pila, .an-col:focus-visible .an-pila { filter: brightness(1.1); }
.an-mese { position: absolute; bottom: -19px; font-size: 11px; color: var(--ink-3); white-space: nowrap; }
.an-linee { display: grid; grid-template-columns: 34px 1fr; gap: 6px; margin-top: 22px; height: 110px; }
.an-asse { display: flex; flex-direction: column; justify-content: space-between; font-size: 11px; color: var(--ink-3); text-align: right; }
.an-piano { position: relative; border-left: 1px solid var(--baseline); border-bottom: 1px solid var(--baseline); }
.an-piano svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.an-piano .griglia { stroke: var(--grid); stroke-width: 1; }
.an-piano polyline { stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.an-piano .l-tasso { stroke: var(--carico-pieno); }
.an-piano .l-affid { stroke: var(--s2); }
.an-bersaglio { position: absolute; top: 0; bottom: 0; }
.an-bersaglio:hover, .an-bersaglio:focus-visible { background: rgba(42, 120, 214, .08); }

/* Tabelle di numeri: il calore (chi si libera, reparto per mese), la matrice
   del confronto e le tabelle che stanno dietro i grafici. */
.calore, .tabella-numeri { border-collapse: collapse; font-size: 13px; width: 100%; font-variant-numeric: tabular-nums; }
.calore th, .calore td, .tabella-numeri th, .tabella-numeri td { padding: 6px 8px; border-bottom: 1px solid var(--grid); text-align: left; }
.calore thead th, .tabella-numeri thead th { font-size: 12px; color: var(--ink-2); font-weight: 600; }
.calore td { text-align: center; min-width: 44px; border-left: 2px solid var(--surface); }
.calore td.lv1 { background: #cde2fb; }
.calore td.lv2 { background: #9ec5f4; }
.calore td.lv3 { background: #2a78d6; color: #fff; font-weight: 600; }
.calore td.lv4 { background: #184f95; color: #fff; font-weight: 600; }
.calore td.tot { color: var(--ink-2); font-weight: 600; }
.calore td.stesso { background: var(--bg); color: var(--ink-3); }
.calore tfoot th, .calore tfoot td { border-bottom: none; }
.tabella-scorre { overflow-x: auto; }

.alloc-due { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 18px; align-items: start; }
@media (max-width: 860px) { .alloc-due { grid-template-columns: 1fr; } }

/* Gli elenchi del report: una riga per persona, con il dato che serve a
   quell'elenco, e il resto dietro «gli altri». */
.sezione-alloc h2 .btn { margin-left: auto; }
/* I motivi dei dati mancanti: etichette lunghe, la colonna si allarga */
.motivi-alloc .fascia-riga { grid-template-columns: minmax(150px, 230px) 1fr auto; }
.motivi-alloc .fascia-riga .lbl { white-space: normal; }
.ap-elenco { display: flex; flex-direction: column; }
.ap-riga {
  display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr) auto; gap: 4px 14px;
  align-items: center; padding: 7px 0; border-bottom: 1px solid var(--bg); font-size: 13.5px;
}
.ap-nome { min-width: 0; }
.ap-nome small { display: block; color: var(--ink-3); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ap-dati small { display: block; color: var(--ink-2); font-size: 12px; }
.ap-grafico { width: 150px; }
.ap-verifica { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; font-size: 12px; color: var(--ink-3); }
.ap-form { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 2px 0 4px; }
.ap-form select, .ap-form input { font-size: 13px; padding: 4px 8px; }
.ap-form input[name="nota"] { flex: 1 1 220px; min-width: 0; }
.barrato { text-decoration: line-through; }
.testo-bad { color: var(--bad-tx); }
p.vuoto { color: var(--ink-3); margin: 6px 0; font-size: 13.5px; }
.scaletta.compatta { margin: 0; }
.scaletta.compatta .sc-pista { height: 14px; }
/* nella riga di un elenco non ci sono i mesi: lo spazio fra due scalini lo fa il tratto */
.scaletta.compatta .sc-tratto { box-shadow: inset -2px 0 0 var(--surface); }
.scaletta.compatta .sc-tratto:last-child { box-shadow: none; }
@media (max-width: 720px) {
  .ap-riga { grid-template-columns: 1fr; }
  .ap-verifica { align-items: flex-start; }
  .ap-grafico { width: 100%; }
}

/* Lo storico dei mesi, in un menu che si apre da sé (niente JavaScript). */
.menu-mesi { position: relative; }
.menu-mesi > summary { list-style: none; cursor: pointer; }
.menu-mesi > summary::-webkit-details-marker { display: none; }
.menu-mesi .conta { font-size: 11px; color: var(--ink-3); margin-left: 4px; }
.menu-mesi-elenco {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 30; min-width: 190px;
  max-height: 320px; overflow-y: auto; background: #fff; border: 1px solid var(--grid);
  border-radius: 10px; box-shadow: 0 8px 24px rgba(0, 0, 0, .10); padding: 6px;
  display: flex; flex-direction: column;
}
.menu-mesi-elenco a { padding: 6px 10px; border-radius: 6px; color: var(--ink); font-size: 13.5px; }
.menu-mesi-elenco a:hover { background: var(--bg); text-decoration: none; }
.menu-mesi-elenco a.attivo { background: var(--accent-soft); color: var(--accent-strong); font-weight: 600; }
form.in-linea { display: inline-flex; margin: 0 0 0 8px; vertical-align: middle; }
.elimina-report { margin-top: 18px; }

/* Il confronto */
.confronto-scelta { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
.confronto-scelta .field { margin: 0; }
.confronto-verdetti .meglio h2 { color: var(--ok-tx); }
.confronto-verdetti .peggio h2 { color: var(--bad-tx); }
.frase-confronto { padding: 6px 0; border-bottom: 1px solid var(--bg); font-size: 13.5px; }
.frase-confronto b { font-weight: 600; }
.confronto-tab td.delta { font-weight: 600; }

/* «Da sistemare» */
.filtri-riga { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; margin-bottom: 6px; }
.filtri-riga .field { margin: 0; }
.sistemare-scheda { scroll-margin-top: 80px; }
.ss-testa { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px 14px; align-items: baseline; }
.ss-motivi { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.ss-stato { margin: 6px 0 10px; font-size: 13px; color: var(--ink-2); }
.ss-progetti { width: 100%; border-collapse: collapse; font-size: 13px; }
.ss-progetti th { text-align: left; font-size: 12px; color: var(--ink-2); font-weight: 600; padding: 4px 8px 6px 0; }
.ss-progetti td { padding: 6px 8px 6px 0; border-top: 1px solid var(--bg); vertical-align: middle; }
.ss-progetti input[type="number"] { width: 5.5rem; padding: 4px 6px; }
.ss-progetti input.manca { border-color: var(--bad-tx); background: var(--bad-bg); }
.ss-quando { color: var(--ink-2); white-space: nowrap; }
.ss-fine { white-space: nowrap; }
.ss-fine select { padding: 4px 6px; }
.ss-reparto { max-width: 320px; margin-top: 10px; }
.ss-azioni { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 12px; }

/* Amministrazione: la scheda del report e il perimetro */
.azioni-riga { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.azioni-riga form { margin: 0; }
.label-like { display: block; font-size: 13px; font-weight: 600; margin-bottom: 6px; }
.dest-elenco { display: flex; flex-direction: column; gap: 4px; max-height: 240px; overflow-y: auto; }
.dest-elenco .opt { align-items: baseline; }
.fuori-pianificazione { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; }
.fuori-pianificazione .field { margin: 0; min-width: 220px; }

/* Il report si porta in riunione stampato: via menu, filtri, moduli e
   bottoni; gli elenchi chiusi si aprono, e niente si spezza a metà. */
@media print {
  .topbar, .subnav, .page-head .actions, .sedi-barra, .ap-form, .elimina-report,
  .banner.info form, .lavori, .nudge { display: none !important; }
  body { background: #fff; }
  .card { break-inside: avoid; box-shadow: none; }
  .altro-corpo { max-height: none; overflow: visible; }
  details.altro > summary { display: none; }
  details.altro > .altro-corpo { display: block !important; }
  .grid-charts { grid-template-columns: 1fr 1fr; }
}

/* ------------------------------------------------- dossier di competenza */
/* Nuovo dossier: le categorie in griglia, ognuna con le sue voci a scomparsa. */
.dos-nuovo { display: flex; flex-direction: column; gap: 12px; margin-top: 8px; }
.dos-categorie { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 8px; }
.dos-cat { border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px; background: var(--surface); }
.dos-cat-testa { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; cursor: pointer; }
.dos-cat-testa .hint { margin: 0; }
.dos-voci summary { font-size: 12.5px; color: var(--ink-3); cursor: pointer; margin-top: 4px; }
.dos-voci-elenco { display: flex; flex-direction: column; gap: 2px; max-height: 220px; overflow-y: auto;
                   margin-top: 6px; font-size: 13px; }
/* L'elenco dei dossier: una riga per dossier, il titolo e com'è messo. */
.dos-elenco { display: flex; flex-direction: column; }
.dos-riga { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; padding: 9px 0;
            border-top: 1px solid var(--bg); color: inherit; text-decoration: none; }
.dos-riga:first-child { border-top: none; }
.dos-riga:hover .dos-riga-titolo { text-decoration: underline; }
.dos-riga-titolo { font-weight: 600; }
.dos-riga > .hint { grid-column: 1; margin: 0; }
.dos-riga-stato { grid-column: 2; grid-row: 1 / span 2; display: flex; flex-direction: column;
                  align-items: flex-end; gap: 2px; }
/* La pagina di lavoro. Il modulo raccoglie più schede: la distanza la dà
   `gap`, perché un `fieldset` non è fra i contenitori della regola delle
   schede impilate. */
.dos-form { margin-top: 14px; }
.dos-campi { border: 0; margin: 0; padding: 0; min-width: 0; display: flex; flex-direction: column; gap: 14px; }
.dos-campi[disabled] { opacity: .6; }
.dos-uscite { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; }
.dos-uscita h3 { margin: 0 0 4px; font-size: 14.5px; }
.dos-bottoni { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.dos-avvertenze { margin: 8px 0 0; padding-left: 18px; display: flex; flex-direction: column; gap: 4px; }
.dos-progetto { border-top: 1px solid var(--bg); padding: 8px 0; }
.dos-progetto > summary { display: flex; align-items: baseline; gap: 10px; cursor: pointer; list-style: none; }
.dos-progetto > summary::-webkit-details-marker { display: none; }
.dos-progetto-titolo { display: flex; flex-direction: column; min-width: 0; }
.dos-progetto-titolo .hint { margin: 0; }
.dos-progetto-corpo { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 16px; margin-top: 10px; }
.dos-fonti p { margin: 0 0 4px; }
.dos-attivita { margin: 6px 0 0; padding: 6px 10px; border-left: 3px solid var(--grid);
                background: var(--bg); font-size: 12.5px; color: var(--ink-2); white-space: pre-line; }
/* Profili chiave e certificazioni affiancati: schede figlie dirette della
   griglia, che le stira alla stessa altezza. */
.dos-due { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 14px; }
.dos-scelta { display: flex; align-items: baseline; gap: 8px; padding: 5px 0; border-top: 1px solid var(--bg); }
.dos-scelta:first-of-type { border-top: none; }
.dos-scelta .hint { margin: 0; }
.dos-salva { display: flex; align-items: center; gap: 12px; position: sticky; bottom: 0;
             background: var(--bg); padding: 10px 0; z-index: 2; }
.dos-conti { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; }
.dos-conti h3 { font-size: 13.5px; margin: 10px 0 4px; }
.dos-lista { list-style: none; margin: 0; padding: 0; columns: 2 180px; font-size: 13px; }
.dos-lista li { padding: 1px 0; break-inside: avoid; }
@media (max-width: 760px) {
  .dos-progetto-corpo { grid-template-columns: 1fr; }
}

/* Revisione UX: le icone SVG al posto delle emoji. Nei riquadri vuoti
   un'icona grigia e calma, come nelle pagine del modulo Persone. */
.big .ic { width: 34px; height: 34px; color: var(--ink-3); stroke-width: 1.6; }
.login-points .ic svg.ic { width: 18px; height: 18px; border: 0; border-radius: 0; background: none;
  display: block; color: var(--accent-strong); }
.chip .ic, .badge .ic, .voce-tag .ic { width: 13px; height: 13px; vertical-align: -2px; }
.asp .ic { color: var(--s2); }
.come-funziona > summary { cursor: pointer; list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.come-funziona > summary::-webkit-details-marker { display: none; }
.come-funziona > summary h2 { margin: 0; }
.come-funziona > summary::after { content: "›"; font-size: 20px; color: var(--ink-3); transition: transform .15s ease; }
.come-funziona[open] > summary::after { transform: rotate(90deg); }
.come-funziona[open] > summary { margin-bottom: 10px; }
.page-head p.sottotitolo-corto { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.sottotitolo-altro { all: unset; cursor: pointer; font-size: 12.5px; font-weight: 600; color: var(--accent-strong); margin-top: 2px; }
.sottotitolo-altro:hover { text-decoration: underline; }
.sottotitolo-altro:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
/* Le tabelle del registro AI scorrono dentro la loro scheda: sul telefono
   allargavano la pagina intera (scorrimento di lato di tutto lo schermo). */
@media (max-width: 620px) {
  .reg-tab { display: block; overflow-x: auto; }
}
