/* ═══════════════════════════════════════════════════════════════════════════
   ELEMENTI — NON MODIFICARE
   Fa parte di uicore/core: al prossimo riallineamento questo file viene
   sovrascritto.
   ═══════════════════════════════════════════════════════════════════════════

   I mattoni che compaiono in ogni pagina: card, riquadri icona, badge di
   stato, avatar, schede e controllo segmentato.

   Sono superfici PIENE, non di vetro: il vetro sta sul guscio, qui c'è il
   contenuto e deve leggersi sempre allo stesso modo.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Card ─────────────────────────────────────────────────────────────────── */
.ui-card {
    background: var(--ui-panel);
    border: 1px solid var(--bs-border-color);
    border-radius: var(--ui-radius-lg);
    box-shadow: var(--ui-shadow-md);
    padding: var(--ui-space-5);
}

/* Solo le card che si possono aprire reagiscono al puntatore. Farlo fare a
   tutte promette un'interazione che non esiste. */
.ui-card-link {
    display: block;
    color: inherit;
    text-decoration: none;
    transition:
        transform var(--ui-duration-base) var(--ui-ease-spring),
        box-shadow var(--ui-duration-base) var(--ui-ease);
}
.ui-card-link:hover {
    transform: translateY(-2px);
    box-shadow: var(--ui-shadow-lg);
    color: inherit;
}

.ui-card-head {
    display: flex;
    align-items: flex-start;
    gap: var(--ui-space-3);
    margin-bottom: var(--ui-space-4);
}
.ui-card-title {
    font-family: var(--ui-font-display);
    font-weight: var(--ui-weight-bold);
    font-size: var(--ui-text-md);
    letter-spacing: var(--ui-tracking-tight);
    margin: 0;
}
.ui-card-sub {
    font-size: var(--ui-text-xs);
    color: var(--ui-ink-muted);
    margin: 2px 0 0;
}
.ui-card-actions { margin-left: auto; display: flex; gap: var(--ui-space-2); }

/* ── Riquadro icona ───────────────────────────────────────────────────────── */
.ui-tile {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    display: grid;
    place-items: center;
    border-radius: var(--ui-radius-sm);
    background: var(--bs-primary-bg-subtle);
    color: var(--ui-brand);
}
.ui-tile-lg { width: 52px; height: 52px; border-radius: var(--ui-radius-md); font-size: var(--ui-text-lg); }
.ui-tile-sm { width: 32px; height: 32px; border-radius: var(--ui-radius-xs); font-size: var(--ui-text-sm); }
.ui-tile-solid { background: var(--ui-brand); color: var(--ui-brand-contrast); }
.ui-tile-success { background: var(--bs-success-bg-subtle); color: var(--ui-success); }
.ui-tile-warning { background: var(--bs-warning-bg-subtle); color: var(--ui-warning); }
.ui-tile-danger  { background: var(--bs-danger-bg-subtle);  color: var(--ui-danger); }
.ui-tile-neutral { background: color-mix(in oklab, var(--ui-ink) 7%, transparent); color: var(--ui-ink-muted); }

/* ── KPI ──────────────────────────────────────────────────────────────────
   Il valore NON va mai a capo: "48.320 €" spezzato su due righe fa crescere
   la card e sfalsa la fila accanto. Il numero e' il dato, quindi non si
   tronca nemmeno: si rimpicciolisce.

   La misura si adatta alla larghezza della CARD, non della finestra: tre
   card affiancate su un portatile sono strette quanto una card su un
   telefono, e un punto di rottura legato allo schermo non se ne accorge. */
.ui-kpi {
    display: flex;
    align-items: center;
    gap: var(--ui-space-3);
    container-type: inline-size;
}
.ui-kpi > *:not(.ui-tile) { min-width: 0; }

.ui-kpi-label {
    font-size: var(--ui-text-2xs);
    text-transform: uppercase;
    letter-spacing: var(--ui-tracking-wide);
    color: var(--ui-ink-muted);
    /* L'etichetta invece si puo' troncare: e' una descrizione, non un dato. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.ui-kpi-value {
    font-family: var(--ui-font-display);
    font-weight: var(--ui-weight-black);
    font-size: var(--ui-text-2xl);
    line-height: var(--ui-leading-tight);
    white-space: nowrap;
    /* Cifre a larghezza fissa: senza, un numero che si aggiorna fa ballare
       tutta la riga a ogni cambio. */
    font-variant-numeric: tabular-nums;
}
.ui-kpi-delta {
    font-size: var(--ui-text-xs);
    font-weight: var(--ui-weight-semibold);
    white-space: nowrap;
}

@container (max-width: 260px) {
    .ui-kpi-value { font-size: var(--ui-text-xl); }
}
@container (max-width: 210px) {
    .ui-kpi-value { font-size: var(--ui-text-lg); }
    .ui-kpi-delta { font-size: var(--ui-text-2xs); }
}
@container (max-width: 170px) {
    .ui-kpi-value { font-size: var(--ui-text-md); }
}
.ui-kpi-delta-up { color: var(--ui-success); }
.ui-kpi-delta-down { color: var(--ui-danger); }

/* ── Badge ────────────────────────────────────────────────────────────────
   A pastiglia e in tinta tenue: leggibili senza gridare. Il rettangolo
   pieno si tiene per i casi che devono davvero fermare l'occhio. */
.ui-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: .28em .72em;
    border-radius: var(--ui-radius-pill);
    font-size: var(--ui-text-2xs);
    font-weight: var(--ui-weight-bold);
    line-height: 1.5;
    /* Un badge è una parola o due, e `nowrap` serve a non spezzare «In
       attesa» su due righe. Ma un testo lungo — arriva sempre, da un dato
       o da una traduzione tedesca — con `nowrap` e basta sfonda il
       contenitore e porta con sé lo scorrimento orizzontale di tutta la
       pagina. `max-width` lo tiene dentro e i puntini dicono che è tagliato. */
    white-space: nowrap;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    background: color-mix(in oklab, var(--ui-ink) 8%, transparent);
    color: var(--ui-ink-muted);
}
.ui-badge-brand   { background: var(--bs-primary-bg-subtle); color: var(--bs-primary-text-emphasis); }
.ui-badge-success { background: var(--bs-success-bg-subtle); color: var(--bs-success-text-emphasis); }
.ui-badge-warning { background: var(--bs-warning-bg-subtle); color: var(--bs-warning-text-emphasis); }
.ui-badge-danger  { background: var(--bs-danger-bg-subtle);  color: var(--bs-danger-text-emphasis); }

/* Pallino di stato: quando il colore da solo dovrebbe bastare, ma non basta
   mai — chi non distingue rosso e verde legge comunque l'etichetta. */
.ui-badge-dot::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
}

/* ── Avatar ───────────────────────────────────────────────────────────────── */
.ui-avatar {
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    overflow: hidden;
    background: var(--ui-brand);
    color: var(--ui-brand-contrast);
    font-size: var(--ui-text-xs);
    font-weight: var(--ui-weight-bold);
    text-transform: uppercase;
}
.ui-avatar img { width: 100%; height: 100%; object-fit: cover; }
.ui-avatar-sm { width: 28px; height: 28px; font-size: var(--ui-text-2xs); }
.ui-avatar-lg { width: 56px; height: 56px; font-size: var(--ui-text-md); }

/* Gruppo sovrapposto: il bordo della stessa tinta del fondo è ciò che li
   separa visivamente, senza disegnare una linea. */
.ui-avatar-group { display: flex; }
.ui-avatar-group .ui-avatar {
    border: 2px solid var(--ui-panel);
    margin-left: -10px;
}
.ui-avatar-group .ui-avatar:first-child { margin-left: 0; }

/* Le schede stavano qui come strip solo-CSS, senza niente che le facesse
   funzionare. Ora sono un componente vero in `components/tabs.css`, con la
   scheda aperta nell'indirizzo e la navigazione da tastiera. Tenere due
   definizioni della stessa classe in due file è il modo più rapido di
   ritrovarsi due aspetti diversi per la stessa cosa: qui ne resta una. */

/* ── Controllo segmentato ─────────────────────────────────────────────────
   Per due o tre scelte che si escludono: più rapido di una tendina, e le
   opzioni restano visibili senza doverle aprire. */
.ui-segmented {
    display: inline-flex;
    padding: 3px;
    border-radius: var(--ui-radius-pill);
    background: color-mix(in oklab, var(--ui-ink) 7%, transparent);
}
.ui-segmented-item {
    padding: 6px var(--ui-space-4);
    border: none;
    border-radius: var(--ui-radius-pill);
    background: transparent;
    color: var(--ui-ink-muted);
    font-size: var(--ui-text-sm);
    font-weight: var(--ui-weight-semibold);
    transition:
        background var(--ui-duration-base) var(--ui-ease),
        color var(--ui-duration-base) var(--ui-ease);
}
.ui-segmented-item.is-active {
    background: var(--ui-panel);
    color: var(--ui-ink);
    box-shadow: var(--ui-shadow-sm);
}

/* ── Comparsa dei contenuti ───────────────────────────────────────────────
   Salita di pochi pixel con dissolvenza. La distanza è volutamente breve:
   oltre i 10px sembra che la pagina si stia montando pezzo per pezzo, e su
   una lista lunga diventa fastidioso. */
.ui-appear {
    animation: uiAppear var(--ui-duration-slow) var(--ui-ease) both;
}
@keyframes uiAppear {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}
/* Ritardo progressivo per gli elementi di un elenco. Si ferma al sesto:
   far aspettare mezzo secondo la ventesima riga non è eleganza, è lentezza. */
.ui-appear-stagger > * { animation: uiAppear var(--ui-duration-slow) var(--ui-ease) both; }
.ui-appear-stagger > :nth-child(1) { animation-delay: 0ms; }
.ui-appear-stagger > :nth-child(2) { animation-delay: 40ms; }
.ui-appear-stagger > :nth-child(3) { animation-delay: 80ms; }
.ui-appear-stagger > :nth-child(4) { animation-delay: 120ms; }
.ui-appear-stagger > :nth-child(5) { animation-delay: 160ms; }
.ui-appear-stagger > :nth-child(n+6) { animation-delay: 200ms; }

@media (prefers-reduced-motion: reduce) {
    .ui-appear, .ui-appear-stagger > * { animation: none; }
}

/* ── Pulsante icona ───────────────────────────────────────────────────────
   Il pulsante tondo con la sola icona: barra in alto, intestazioni di
   pannello, azioni di riga. Stava in `shell.css` perché la barra in alto è
   il posto in cui si vede di più — ma un pulsante icona non è mobilio del
   guscio, e chi ne metteva uno in una pagina senza guscio (la styleguide,
   per prima) si ritrovava un rettangolo col bordo di sistema. */
.ui-icon-btn {
    position: relative;
    width: var(--ui-touch-target);
    height: var(--ui-touch-target);
    display: grid;
    place-items: center;
    border: none;
    border-radius: var(--ui-radius-pill);
    background: transparent;
    color: inherit;
    font-family: inherit;
    cursor: pointer;
    opacity: .7;
    transition:
        background var(--ui-duration-fast) var(--ui-ease),
        opacity var(--ui-duration-fast) var(--ui-ease),
        transform var(--ui-duration-fast) var(--ui-ease-spring);
}
.ui-icon-btn:hover {
    opacity: 1;
    background: color-mix(in oklab, var(--ui-ink) 8%, transparent);
    transform: translateY(-1px);
}

/* Il pallino "c'è qualcosa di nuovo". `position: relative` sul pulsante lo
   ancora davvero: prima si appoggiava al primo antenato posizionato che
   trovava, che nella barra in alto andava bene per caso. */
.ui-icon-btn .ui-dot {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--ui-danger);
}

/* ── Visibilità per larghezza ─────────────────────────────────────────────
   Due classi, non `display: none` scritto a mano ogni volta: la soglia è una
   sola e cambiarla deve valere ovunque. Stavano in `shell.css` e servivano
   anche fuori. */
@media (min-width: 768px) {
    .ui-only-mobile { display: none !important; }
}
@media (max-width: 767.98px) {
    .ui-only-desktop { display: none !important; }
}

/* ── Barra di quota ───────────────────────────────────────────────────────
   Quanto di un limite è stato consumato: crediti, spazio, minuti, chiamate
   API. Un numero da solo («3.240») non dice niente finché non si sa su
   quanto; la barra lo dice prima ancora di leggere le cifre.

   Il colore cambia da solo alle soglie — `is-warn` sopra il 75%, `is-over`
   sopra il 90% — perché una barra sempre dello stesso colore costringe a
   leggere le cifre per capire se c'è un problema, che è esattamente ciò che
   la barra dovrebbe evitare. Le soglie le applica chi la disegna: qui ci
   sono solo i due stati.

       <div class="ui-meter is-warn">
         <div class="ui-meter-head"><span>Crediti</span><span>3.240 / 4.000</span></div>
         <div class="ui-meter-track"><div class="ui-meter-fill" style="width:81%"></div></div>
       </div> */
.ui-meter { min-width: 0; }
.ui-meter-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--ui-space-2);
    margin-bottom: 5px;
    font-size: var(--ui-text-xs);
}
.ui-meter-head > :first-child {
    overflow: hidden;
    color: var(--ui-ink-muted);
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ui-meter-head > :last-child {
    flex-shrink: 0;
    font-weight: var(--ui-weight-semibold);
    font-variant-numeric: tabular-nums;
}
.ui-meter-track {
    height: 8px;
    border-radius: var(--ui-radius-pill);
    background: color-mix(in oklab, var(--ui-ink) 9%, transparent);
    overflow: hidden;
}
.ui-meter-fill {
    height: 100%;
    border-radius: inherit;
    background: var(--ui-brand);
    transition: width var(--ui-duration-slow) var(--ui-ease);
}
.ui-meter.is-warn .ui-meter-fill { background: var(--ui-warning); }
.ui-meter.is-over .ui-meter-fill { background: var(--ui-danger); }
.ui-meter.is-over .ui-meter-head > :last-child { color: var(--ui-danger); }

@media (prefers-reduced-motion: reduce) {
    .ui-meter-fill { transition: none; }
}
