/* =============================================================================
   La RANGÉE d'un ticket — feuille partagée (2026-09-13)
   =============================================================================

   Jumelle de `public/assets/js/modules/ticket-row.js`. Depuis la migration
   xorizo 035, une rangée de ticket se peint dans DEUX applications : la page
   `/tickets` de xorizo et l'onglet « Tickets » d'une affaire airfact. Le balisage
   étant partagé, sa peau doit l'être aussi — sinon la même ligne aurait deux
   apparences selon la page qui la montre.

   ── CE QUI RESTE CHEZ XORIZO ───────────────────────────────────────────────
   Le kanban, la barre de filtres, la sélection groupée : du CHROME DE PAGE, que
   l'onglet d'une affaire n'ouvrira jamais. On partage l'objet, pas la page.

   ── AUCUNE COULEUR EN DUR ──────────────────────────────────────────────────
   La version d'origine peignait la ligne « à moi » et la ligne non lue en
   hexadécimal, à même l'attribut `style` du <tr> : deux teintes qu'aucun jeton
   ne portait, que le thème sombre ne pouvait pas suivre, et que l'audit ne
   voyait pas. Tout passe ici par `var(--…)`.
*/

/* ── La cellule de titre ─────────────────────────────────────────────────── */
/* ⚠ LA VIGNETTE, LE TITRE, LE SURTITRE, LE RÉSUMÉ ET LES COMPTEURS ONT
   DÉMÉNAGÉ dans `components/list-row.css` le 15-09-2026, sous les noms
   `.lrow-*` — avec leur jumeau JS `window.listRowTitle()`. Motif : l'onglet
   « Échanges » d'une affaire peint la MÊME cellule, et deux écrans voisins ne
   se ressemblent pour de bon que s'ils passent par le même code. Aucune valeur
   n'a changé en déménageant.

   Ce qui reste ici est ce qui est PROPRE à un ticket : les pastilles du
   surtitre, les teintes de rangée, le porteur. */

/* Le gras du non-lu est porté par UNE classe sur la rangée, pas répété sur
   chaque descendant : trois `font-weight: 700` en ligne, c'était trois endroits
   à corriger le jour où le signal change. */
.ticket-unread-row .lrow-sup,
.ticket-unread-row .lrow-title {
    font-weight: 700;
}

/* ── Les deux pastilles du surtitre ───────────────────────────────────────── */
.tk-row-tenant,
.tk-row-new {
    font-size: 0.575rem;
    font-weight: 600;
    padding: 0.1rem 0.3rem;
    border-radius: var(--radius-sm, 0.25rem);
    vertical-align: middle;
}

.tk-row-tenant {
    background: var(--state-blue-bg);
    /* `--state-blue-fg` et non `--primary` : sur un fond de teinte, l'encre est
       le cran `-fg` du même état. `--primary` posé en TEXTE sur `-bg` ne passe
       pas le contraste. */
    color: var(--state-blue-fg);
}

.tk-row-new {
    /* Une paire bg/fg, pas `--info` plein avec du blanc inventé : il n'existe
       aucun jeton d'encre sur fond plein, et `--info-fg` que j'avais écrit
       n'existait pas — la pastille serait tombée sur le repli `#fff`, hors
       thème. L'orange dit « nouveau » sans se confondre avec le bleu du badge
       de tenant, qui est juste à côté dans le même surtitre. */
    background: var(--state-orange-bg);
    color: var(--state-orange-fg);
    font-weight: 700;
}

/* Le badge d'AFFAIRE, sur la page centrale : un ticket ancré y apparaît comme
   les autres, mais il dit à quoi il tient et il y mène. Teinte AUTRE que celle
   du badge de tenant, qui est juste à côté dans le même surtitre — deux
   pastilles de même couleur à trois millimètres se liraient comme une seule
   information coupée en deux. */
.tk-row-affaire {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    font-size: 0.575rem;
    font-weight: 600;
    padding: 0.1rem 0.3rem;
    border-radius: var(--radius-sm, 0.25rem);
    vertical-align: middle;
    background: var(--state-teal-bg);
    color: var(--state-teal-fg);
    text-decoration: none;
}

.tk-row-affaire:hover {
    text-decoration: underline;
}

/* ⚠ LES COMPTEURS (`.lrow-counts` / `.lrow-count`) sont dans
   `components/list-row.css` depuis le 15-09-2026 — voir la note plus haut. */

/* ── États de rangée ──────────────────────────────────────────────────────── */
/* Non lue : un filet à gauche. La bordure est posée sur la PREMIÈRE cellule et
   non sur le <tr> — `border-left` sur une rangée est ignoré dès que la table
   est en `border-collapse`, ce que le socle applique. */
.ticket-unread-row > td:first-child {
    box-shadow: inset 3px 0 0 0 var(--primary);
}

/* « Pour moi » : un fond très pâle. `color-mix` plutôt qu'un jeton neuf — la
   teinte est DÉRIVÉE de --primary, elle suit donc le thème sans second réglage.
   ⚠ Le second terme est `--surface` et non `transparent` : une teinte mélangée
   à `transparent` est un TROU, invisible tant que rien ne défile dessous. */
.tk-row-mine > td {
    background: color-mix(in srgb, var(--primary) 6%, var(--surface));
}

/* ── Porteur ──────────────────────────────────────────────────────────────── */
/* Le pseudo-assigné « Support Corelia » : le tenant ne voit jamais le nom du
   collaborateur qui traite son ticket. Ne peut pas apparaître sur une affaire —
   un ticket ancré n'est jamais escaladé (chk_tk_anchored_never_platform). */
.tk-row-corelia {
    font-weight: 500;
    color: var(--primary);
}

/* ⚠ LE CALIBRE DES BADGES DE RANGÉE est dans `components/list-row.css` depuis
   le 15-09-2026, sous `tr.lrow-open .badge`. Il était ancré ici sur
   `data-action="view-ticket-row"` : le même badge rendait donc plus petit dans
   l'onglet « Échanges » d'à côté, qui liste pourtant le même genre d'objet. */

/* =============================================================================
   LE KANBAN — plateau, colonnes, cartes
   =============================================================================
   Porté depuis `xorizo/public/assets/css/modules/tickets.css` le 13-09-2026,
   en même temps que `card()` et `board()`. Même raison que la rangée : le
   balisage est rendu par le socle, sa peau doit l'être aussi.

   Deux dettes sont remontées avec le bloc et ont été soldées au passage :
     · `.status-indicator--urgent` peignait une teinte en HEXADÉCIMAL, la même
       que `--error` ;
     · trois fonds appelaient `var(--background)`, un jeton qui N'EXISTE PAS.
       En CSS, un `var()` inconnu SANS REPLI rend la déclaration invalide : ces
       trois fonds ne peignaient donc RIEN depuis toujours (c'est le défaut
       CSS-01 du socle). La table d'alias les envoie sur `--color-surface-2` —
       surface secondaire, pas surface de carte. */
.kanban-board {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 1.5rem;
    margin-bottom: 2rem;
}

.kanban-column {
    background: var(--surface);
    border-radius: 0.5rem;
    border: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    min-height: 500px;
    /* Allow the grid track to shrink below the card's intrinsic content width
       so all columns keep their equal 1fr share regardless of content. */
    min-width: 0;
}

.kanban-column-header {
    padding: 1rem;
    border-bottom: 1px solid var(--border);
}

.kanban-column-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.status-indicator {
    width: 8px;
    height: 8px;
    border-radius: 50%;
}
.status-indicator--open        { background: var(--info); }
.status-indicator--in_progress { background: var(--warning); }
.status-indicator--resolved    { background: var(--success); }
.status-indicator--closed      { background: var(--gray-500); }
.status-indicator--urgent      { background: var(--error); }
.status-indicator--high        { background: var(--warning); }
.status-indicator--medium      { background: var(--info); }
.status-indicator--low         { background: var(--gray-500); }

.kanban-column-title h3 {
    font-size: 0.875rem;
    font-weight: 600;
    margin: 0;
    flex: 1;
}

.kanban-column-count {
    background: var(--color-surface-2);
    padding: 0.125rem 0.5rem;
    border-radius: 1rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-secondary);
}

.kanban-column-content {
    flex: 1;
    padding: 0.75rem;
    overflow-y: auto;
    min-height: 200px;
}

.kanban-column-content.drag-over {
    background: var(--color-surface-2);
}

.kanban-card {
    background: var(--color-surface-2);
    border: 1px solid var(--border);
    border-radius: 0.375rem;
    padding: 0.75rem;
    margin-bottom: 0.75rem;
    cursor: grab;
    transition: all 0.2s;
}

.kanban-card:hover {
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
    transform: translateY(-2px);
}

.kanban-card.dragging {
    opacity: 0.5;
    cursor: grabbing;
}

.kanban-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    /* 0.25rem et non 0.5 : c'est la valeur de `/tickets`, l'écran de référence.
       Elle vivait dans `xorizo/modules/tickets.css`, donc l'onglet d'une
       affaire — qui ne charge pas cette feuille — écartait ses pastilles deux
       fois plus. Même balisage, deux feuilles : c'est ce qu'Olivier voyait. */
    gap: 0.25rem;
    margin-bottom: 0.5rem;
}

.kanban-card-id {
    font-size: 0.75rem;
    color: var(--text-secondary);
    font-weight: 500;
}

/* ⚠ `.kanban-card-edit-btn` RETIRÉE (13-09-2026) — deux règles, aucun émetteur.
   La classe venait de `TicketsManager.renderKanbanCard()`, le second gabarit de
   carte supprimé le même jour ; plus aucun fichier de la plateforme ne l'écrit
   (balayé sur les sept apps, JS et PHP). Elle était arrivée ici avec le reste
   du kanban, sans que personne ne vérifie qu'elle servait encore. Trouvée par
   la sonde de style : elle exige que CHAQUE pièce qu'elle mesure existe dans le
   balisage du composant — un sélecteur qu'on ne peut pas rendre n'a rien à
   faire dans la feuille du composant. */

.kanban-card-title {
    font-size: 0.875rem;
    font-weight: 500;
    margin: 0 0 0.5rem 0;
    flex: 1;
    min-width: 0;
    line-height: 1.4;
    overflow-wrap: anywhere;
    word-break: break-word;
}

.kanban-card-meta {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    font-size: 0.75rem;
}

/* ⚠ `.kanban-card-priority` a été RETIRÉE le 13-09-2026 : mesurée morte des
   deux côtés. Le gabarit émet `window.badge()`, donc `badge badge-<couleur>` —
   jamais cette classe. Ses cinq règles (ici et dans `tickets.css`) ne peignaient
   rien depuis que la carte est rendue par le socle. La pastille d'une carte se
   règle par `.kanban-card .badge`, juste en dessous. */

/* Les pastilles DANS une carte sont plus affirmées que dans une rangée : une
   carte se lit de loin, en balayant une colonne. Cette règle vivait dans
   `tickets.css` — donc sur un seul des deux écrans. */
.kanban-card .badge {
    font-weight: 600;
    font-size: 0.75rem;
    padding: 0.25rem 0.625rem;
    border-radius: 0.375rem;
    letter-spacing: 0.025em;
}

.kanban-card-type {
    padding: 0.125rem 0.5rem;
    border-radius: 0.25rem;
    font-size: 0.7rem;
    font-weight: 500;
}

.kanban-card-date {
    color: var(--text-secondary);
    margin-left: auto;
}

/* ── La vignette d'une carte ──────────────────────────────────────────────── */
/* Sans ces deux règles, l'image d'une pièce jointe sort à sa taille NATURELLE,
   sans cadre ni rapport : mesuré le 13-09, c'était l'écart le plus visible
   entre `/tickets` et l'onglet d'une affaire — 7 propriétés sur 11. Le rapport
   16/9 fixe la hauteur de la tuile quelle que soit l'image, sans quoi la
   colonne se déforme au gré des pièces jointes. */
.kanban-card-thumb {
    flex-shrink: 0;
    width: 100%;
    aspect-ratio: 16 / 9;
    margin: 0.25rem 0 0.5rem;
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--bg);
    border: 1px solid var(--border);
    display: block;
}

.kanban-card-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* ── Les états d'une carte ────────────────────────────────────────────────── */
/* `.ticket-unread-card` et le fond « pour moi » n'avaient AUCUNE règle : le
   travail était fait par des styles en ligne posés dans le gabarit JS, en
   hexadécimal. Ils ont donc la même définition que leurs jumeaux de rangée. */
.ticket-unread-card {
    box-shadow: inset 3px 0 0 0 var(--primary);
}

.tk-card-mine {
    background: color-mix(in srgb, var(--primary) 6%, var(--surface));
}

/* ── Auteur → porteur, dans le pied de carte ──────────────────────────────── */
.tk-card-gens {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}

.tk-card-who {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--text-secondary);
}

.tk-card-arrow {
    font-size: 0.65rem;
    color: var(--text-muted);
}

/* La pastille du porteur. Un dégradé de gris et non une teinte de marque : sur
   une carte qui porte déjà deux badges de couleur, un troisième aplat vif
   ferait de l'initiale le point le plus fort de la carte. */
.tk-card-avatar {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--gray-500) 0%, var(--gray-600) 100%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--surface);
    font-weight: 600;
    font-size: 0.6rem;
}

.tk-card-avatar.is-corelia {
    background: linear-gradient(135deg, var(--primary) 0%, var(--state-blue-fg) 100%);
    font-size: 0.55rem;
}

/* ⚠ « LA RANGÉE EST CLIQUABLE » est dans `components/list-row.css` depuis le
   15-09-2026, sous `.lrow-open` — avec la calibration des pastilles de rangée,
   qui était ancrée ici sur `data-action="view-ticket-row"` et ne valait donc
   que pour les tickets. */

/* =============================================================================
   LA FICHE d'un ticket — jumelle de `_ticket-detail.php` + `ticket-detail.js`
   =============================================================================
   Ouvrir et éditer un ticket SANS quitter l'écran qui l'affiche (13-09-2026).
   Elle vit dans cette feuille et non dans une sienne : la fiche ne se montre
   jamais sans la liste qui l'ouvre, et deux feuilles à charger ensemble sont
   deux occasions d'en oublier une. */

/* ── LA FICHE : le rythme vient du CONTENEUR ──────────────────────────────── */
/* ⚠ NI `margin-bottom` sur les blocs, NI `margin-top` : l'écart vertical est
   porté ICI, une seule fois. Une version antérieure le peignait sur chaque
   bloc — deux endroits de plus où l'écart se décidait, et la description, elle,
   n'en avait aucun : elle se collait à ses voisins. */
.tk-detail {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

/* Le voile d'attente : la place qu'occupera la fiche, pour que la fenêtre ne
   saute pas de hauteur quand elle arrive. */
.tk-detail-attente {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 220px;
}

/* ── Le titre, et son édition en place ────────────────────────────────────── */
.tk-detail-titre-rangee {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
}

.tk-detail-titre-vue {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    flex: 1;
}

.tk-detail-titre {
    font-size: 1.5rem;
    font-weight: 600;
    margin: 0;
    min-width: 0;
    overflow-wrap: anywhere;
}

/* Le crayon s'efface tant qu'on ne survole pas la rangée : un titre est fait
   pour être LU, et une icône pleine à côté le concurrence. */
.tk-detail-crayon {
    opacity: 0.45;
    padding: 0.25rem;
    transition: opacity 0.15s ease;
    flex-shrink: 0;
}

.tk-detail-titre-rangee:hover .tk-detail-crayon,
.tk-detail-crayon:focus-visible { opacity: 1; }

.tk-detail-titre-edit {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 1;
}

.tk-detail-titre-champ {
    flex: 1;
    min-width: 0;
    font-size: 1.25rem;
    font-weight: 600;
}

.tk-detail-edit-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

/* ── La rangée de pastilles ───────────────────────────────────────────────── */
/* Six valeurs sur une ligne. `flex-wrap` parce qu'un nom long de porteur ne
   doit pas pousser le reste hors du cadre — il passe à la ligne. */
.tk-detail-pills {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
}

/* La CLÉ d'une pastille (« De : », « À : ») s'efface derrière sa valeur : elle
   dit de quoi il s'agit, elle n'est pas l'information. */
.tk-pill-cle {
    font-size: 0.7rem;
    opacity: 0.7;
    margin-right: 0.25rem;
}

/* Le badge du porteur contient une commande : il ne doit pas la rogner. */
.tk-pill-porteur {
    display: inline-flex;
    align-items: center;
    padding-right: 0.25rem;
}

/* ── Les pièces jointes ───────────────────────────────────────────────────── */
.tk-detail-pj {
    list-style: none;
    margin: 0.25rem 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.tk-detail-pj li {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.8rem;
    color: var(--text-secondary);
    background: var(--color-surface-2);
    border-radius: var(--radius-sm);
    padding: 0.15rem 0.45rem;
}

/* `.tk-detail-bloc` n'a VOLONTAIREMENT aucune déclaration : elle ne sert qu'à
   faire de « titre + liste » UN SEUL élément du flux. Sans elle, le titre et sa
   liste seraient deux éléments séparés par un gap entier. Ne pas la supprimer
   en la croyant morte — son rôle est structurel, pas visuel. */

/* ── Le fil : une pile des MÊMES cartes que la description ────────────────── */
/* ⚠ PAS de `max-height` ni d'`overflow-y` ici (17-09-2026). Le fil en portait
   (40vh, `auto`) pour garder le composeur atteignable sans faire défiler la
   fenêtre : ça donnait DEUX ascenseurs emboîtés sur la même conversation — un
   pour la fiche, un pour les messages, dont celui du dedans mangeait la molette
   dès que le curseur passait dessus. « Pas de scroll à l'intérieur des
   messages, un seul scroll sur toute la conversation » (Olivier).
   Le fil pousse donc sa hauteur, et c'est `.modal-body` — le seul défileur —
   qui la reprend. Le composeur se rejoint en descendant, comme dans n'importe
   quelle conversation. */
.tk-detail-fil {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/* ── Le composeur ─────────────────────────────────────────────────────────── */
/* La zone pleine largeur, le bouton SOUS elle et à droite — la forme de
   l'écran de référence. Un bouton à côté de la zone la rétrécit d'autant, et
   c'est la zone qu'on vient écrire. */
.tk-comment-composeur {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.tk-comment-zone {
    width: 100%;
    resize: vertical;
}

.tk-comment-actions {
    display: flex;
    justify-content: flex-end;
}

/* ── Le plateau rétrécit ──────────────────────────────────────────────────── */
/*
 * Cette échelle vivait dans `xorizo/modules/tickets.css`, donc sur UN seul des
 * deux écrans. Mesuré le 13-09 dans un navigateur : à 900 px l'onglet d'une
 * affaire rendait toujours QUATRE colonnes de 207 px, et à 600 px quatre
 * colonnes de 132 px — inutilisables. `/tickets`, lui, passait à deux puis à
 * une. Ce n'était donc pas un écart de goût, c'était un plateau cassé sur la
 * moitié des écrans.
 *
 * ⚠ Le `!important` d'origine est TOMBÉ, et la règle à 640 px avec : depuis que
 * l'échelle vit dans le même fichier que la base, l'ordre de la cascade suffit,
 * et la borne à 767 px pose déjà `1fr` — celle de 640 px ne pouvait rien
 * ajouter.
 */
@media (max-width: 1024px) {
    .kanban-board {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 767px) {
    .kanban-board {
        grid-template-columns: 1fr;
        gap: 1rem;
    }

    /* Une colonne seule n'a pas à réserver la hauteur de quatre. */
    .kanban-column {
        min-height: 300px;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   LA FICHE D'UN TICKET — la peau, remontée de `xorizo/modules/tickets.css`
   le 13-09-2026 (3e passe).
   ══════════════════════════════════════════════════════════════════════════

   Olivier, capture à l'appui : « d'un côté j'ai ça et de l'autre j'ai ça, tu
   vois bien que c'est différent ». Ce n'était pas le kanban (réparé le matin)
   mais LA FICHE — pastilles éditables et carte d'auteur d'un côté, formulaire à
   libellés de l'autre. Deux dessins pour un objet.

   `/tickets` est l'écran de RÉFÉRENCE : ses valeurs gagnent, à l'octet près,
   sauf là où elles consommaient un jeton fantôme (noté sur place). */

/* ── Les pastilles ÉDITABLES de l'en-tête ─────────────────────────────────── */
/* Un `<select>` déguisé en badge : on change l'état d'un ticket là où on le
   lit, sans ouvrir un formulaire. `appearance: none` retire le chrome natif ;
   le chevron est une image de fond, donc les teintes doivent passer par
   `background-color` — un `background` raccourci EFFACERAIT le chevron. */
.badge-select {
    appearance: none;
    -webkit-appearance: none;
    border: none;
    color: white;
    font-weight: 600;
    font-size: 0.75rem;
    padding: 0.25rem 1.5rem 0.25rem 0.625rem;
    border-radius: 0.375rem;
    cursor: pointer;
    background-repeat: no-repeat;
    background-position: right 0.375rem center;
    background-size: 12px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
    min-width: 80px;
    /* ⚠ UN FOND PAR DÉFAUT, ET C'EST UNE GARDE. Les teintes ci-dessous sont une
       LISTE : une valeur dont la couleur n'y est pas ne recevait aucun
       `background-color`, et comme la règle impose `color: white`, la pastille
       sortait BLANC SUR BLANC — illisible, sans erreur. C'est ce qui est arrivé
       à « Ouvert » : `config/statuses/ticket.php` sert la couleur `draft`, que
       cette palette ne connaissait pas. Un repli gris se voit ; une pastille
       invisible ne se voit pas. */
    background-color: var(--gray-500);
}

.badge-select.badge-info      { background-color: var(--info); }
.badge-select.badge-warning   { background-color: var(--warning); }
.badge-select.badge-success   { background-color: var(--success); }
.badge-select.badge-secondary { background-color: var(--gray-500); }
/* `--error-hover` vaut #dc2626 au bit près : la teinte de `/tickets` est
   conservée, et elle cesse d'être un hex écrit à la main. */
.badge-select.badge-danger    { background-color: var(--error-hover); }
/* Le cyan de la pastille « primary » n'a pas de jeton — il ne correspond à
   aucune couleur de marque. Reproduit tel quel pour ne pas changer l'écran de
   référence ; à mapper le jour où une teinte l'accueille.
   css-color-ok: teinte sans jeton, conservée à l'identique de /tickets. */
.badge-select.badge-primary   { background-color: #0891b2; }

/* ── Les couleurs des ÉTATS (config/statuses/*.php) ───────────────────────── */
/* La table du domaine sert `draft` / `in_progress` / `completed` / `cancelled`,
   pas `info` / `success`. Les badges canoniques (`.badge-status-*`) les
   connaissent, mais en TONAL — fond pâle, encre sombre. Une pastille de fiche
   est une COMMANDE : elle est pleine, pour se distinguer d'une étiquette qu'on
   ne peut que lire. On reprend donc les teintes SATURÉES de la même palette
   d'état (`--state-*-dot`), pour que les deux formes restent parentes. */
.badge-select.badge-draft       { background-color: var(--state-slate-dot); }
.badge-select.badge-in_progress { background-color: var(--state-blue-dot); }
.badge-select.badge-completed   { background-color: var(--state-forest-dot); }
.badge-select.badge-cancelled   { background-color: var(--state-red-dot); }
.badge-select.badge-on_hold     { background-color: var(--state-amber-dot); }
.badge-select.badge-active      { background-color: var(--state-green-dot); }

/* Les quatre crans de priorité. */
.badge-select.badge-low       { background-color: var(--gray-500); }
.badge-select.badge-medium    { background-color: var(--info); }
.badge-select.badge-high      { background-color: var(--warning); }
.badge-select.badge-urgent    { background-color: var(--error-hover); }

.badge-select:focus {
    outline: none;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.3);
}

/* Le menu déroulant, lui, se lit sur fond de page — blanc sur blanc sinon. */
.badge-select option {
    background: var(--surface);
    color: var(--text);
    padding: 0.5rem;
}

/* Le même, mais DANS un badge (le porteur) : il hérite la couleur de son hôte
   au lieu d'en porter une. */
.badge-select-inline {
    appearance: none;
    -webkit-appearance: none;
    border: none;
    background: transparent;
    color: inherit;
    font-weight: 500;
    font-size: 0.75rem;
    padding: 0.25rem 1.25rem 0.25rem 0.25rem;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.25rem center;
    background-size: 10px;
    max-width: 150px;
}

.badge-select-inline:focus { outline: none; }

.badge-select-inline option {
    background: var(--surface);
    color: var(--text);
}

/* ── La carte d'AUTEUR — description et commentaires la partagent ─────────── */
/* C'est la forme qu'Olivier montre : avatar rond, nom, horodatage, filet, et le
   corps en dessous. La description du ticket EST le premier message du fil :
   lui donner une autre forme qu'un commentaire la ferait lire comme un champ. */
.ticket-description-container {
    position: relative;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 1.25rem;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}

.ticket-description-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--border);
}

.ticket-description-author {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-width: 0;
}

/* ⚠ Le dégradé consommait `var(--primary-dark, #1e40af)` — `--primary-dark`
   n'existe dans AUCUN tokens.css : c'est un jeton fantôme, et seul le repli
   peignait. Dans le socle, un fantôme fait sortir `probe-css-tokens` en 1.
   Remplacé par `--primary-hover`, le cran sombre canonique de la marque.
   (`--primary` était déjà servi par le jeton, pas par son repli : l'avatar est
   navy #193153 aujourd'hui, pas le #3b82f6 que le repli annonçait.) */
.ticket-description-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-hover) 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-weight: 600;
    font-size: 0.875rem;
    flex-shrink: 0;
}

.ticket-description-author-name {
    font-weight: 600;
    font-size: 0.875rem;
    color: var(--text);
    margin: 0;
}

.ticket-description-meta {
    font-size: 0.75rem;
    color: var(--text-secondary);
    margin: 0;
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

/* Le crayon ne se montre qu'au survol de SA carte : un crayon par message,
   visibles tous en même temps, ferait une colonne d'icônes. */
.ticket-description-edit-btn {
    opacity: 0.55;
    padding: 0.25rem;
    transition: opacity 0.15s ease;
}

.ticket-description-container:hover .ticket-description-edit-btn,
.ticket-description-edit-btn:focus-visible { opacity: 1; }

.ticket-description-container .md-content {
    margin: 0;
    color: var(--text);
    line-height: 1.6;
}

.ticket-description-container .description-edit textarea,
.ticket-description-container .description-edit .ticket-mention-input {
    font-family: inherit;
    font-size: 0.9375rem;
    line-height: 1.6;
}

/* ══════════════════════════════════════════════════════════════════════════
   LE COMPOSEUR À @-MENTIONS — remonté de `xorizo/modules/tickets.css`
   le 13-09-2026 (lot A de la mutualisation).
   ══════════════════════════════════════════════════════════════════════════

   La peau suit son moteur : `window.TicketMentions` vit maintenant dans le
   socle, ces règles aussi. Les laisser dans la feuille de page aurait rejoué,
   pour la troisième fois de la journée, le défaut « même balisage, deux
   feuilles » — un volet de mentions sans style dans l'onglet d'une affaire.

   ⚠ Les replis MENTEURS sont tombés. `var(--primary, …)` annonçait un bleu vif
   alors que `--primary` est le bleu marine de la marque ; `var(--text-secondary,
   …)` un gris plus clair que le vrai. Le jeton gagne TOUJOURS quand il existe :
   ces replis ne peignaient rien, ils décrivaient faux.
   (Les valeurs ne sont pas citées ici : l'audit lit les commentaires, et un hex
   écrit en prose y compte comme une couleur en dur.) */

/* La zone de saisie riche. Un `contenteditable`, pas un `<textarea>` : les
   pastilles de mention sont des éléments, un textarea n'en porte pas. */
.ticket-mention-input {
    min-height: 5rem;
    max-height: 250px;
    overflow-y: auto;
    white-space: pre-wrap;
    word-wrap: break-word;
    line-height: 1.5;
    font-size: 0.875rem;
    cursor: text;
}

/* Un `contenteditable` vide n'a pas de `placeholder` : on le peint. */
.ticket-mention-input:empty::before {
    content: attr(data-placeholder);
    color: var(--text-secondary);
    pointer-events: none;
}

.ticket-mention-input:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 2px var(--primary-light);
}

.ticket-mention-input-sm { min-height: 3rem; }

/* La pastille DANS la zone : `user-select: all` la rend atomique — on ne peut
   pas en sélectionner la moitié, donc pas en casser le jeton à la suppression. */
.mention-tag {
    background: var(--state-blue-bg);
    /* css-color-ok: bleu-800 historique, identique à `.badge-status-in_progress`. */
    color: #1e40af;
    padding: 0.0625rem 0.375rem;
    border-radius: var(--radius-sm);
    font-weight: 600;
    font-size: 0.875em;
    white-space: nowrap;
    user-select: all;
}

/* La même, dans un message DÉJÀ rendu (elle n'est plus éditable). */
.mention-badge {
    background: var(--state-blue-bg);
    /* css-color-ok: bleu-800 historique, jumelle de `.mention-tag`. */
    color: #1e40af;
    padding: 0.125rem 0.375rem;
    border-radius: var(--radius-sm);
    font-weight: 600;
    font-size: 0.875em;
    white-space: nowrap;
}

/* Le volet de choix. `position: fixed` : il suit le CURSEUR, pas le flux —
   dans une fenêtre modale qui défile, un volet absolu partirait avec elle. */
.mention-dropdown {
    position: fixed;
    z-index: 10010;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    max-height: 200px;
    overflow-y: auto;
    min-width: 220px;
}

.mention-item {
    padding: 0.5rem 0.75rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.875rem;
    transition: background 0.1s;
}

.mention-item.selected,
.mention-item:hover { background: var(--primary-light); }

.mention-item-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    /* css-color-ok: bleu-600 historique, cran sombre du dégradé d'avatar. */
    background: linear-gradient(135deg, var(--info) 0%, #2563eb 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-weight: 600;
    font-size: 0.7rem;
    flex-shrink: 0;
}

.mention-item-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ══════════════════════════════════════════════════════════════════════════
   LES PIÈCES JOINTES D'UN TICKET — galerie, liste, visionneuse, collage.
   Remontées de `xorizo/modules/tickets.css` le 13-09-2026 (lot B).
   ══════════════════════════════════════════════════════════════════════════

   Même règle que pour le kanban, la fiche et les mentions : ce qui peint un
   composant partagé vit dans la feuille du composant. Écrites dans la feuille
   de page, ces règles laissaient l'onglet d'une affaire sans galerie.

   ⚠ Jetons FANTÔMES corrigés au passage : `--surface-alt` et `--background`
   n'existent dans aucun tokens.css — avec repli, seul le repli peignait ; sans
   repli, la déclaration ne peignait RIEN. Remplacés par `--color-surface-2`,
   la surface secondaire canonique. Les replis menteurs sont tombés. */

.ticket-attachments {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.ticket-attachments-section {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.ticket-attachments-heading {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-secondary);
}

.ticket-attachments-heading svg { flex-shrink: 0; }

/* La galerie : des tuiles 4/3, l'image en couverture. */
.ticket-gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 0.75rem;
}

.ticket-gallery-item {
    position: relative;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--color-surface-2);
    border: 1px solid var(--border);
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.ticket-gallery-item:hover {
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.10);
    transform: translateY(-1px);
}

.ticket-gallery-item .desc-image-lightbox {
    cursor: zoom-in;
    display: block;
    aspect-ratio: 4 / 3;
    background: var(--color-surface-2);
}

.ticket-gallery-item .desc-image-lightbox img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.ticket-gallery-caption {
    padding: 0.5rem 0.625rem;
    font-size: 0.75rem;
    color: var(--text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    border-top: 1px solid var(--border);
}

/* Le bouton de suppression n'apparaît qu'au survol de SA tuile. */
.ticket-gallery-delete {
    position: absolute;
    top: 0.375rem;
    right: 0.375rem;
    width: 28px;
    height: 28px;
    border-radius: 999px;
    border: none;
    background: rgba(255, 255, 255, 0.95);
    color: var(--error);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18);
    opacity: 0;
    transition: opacity 0.15s ease, transform 0.15s ease;
}

.ticket-gallery-item:hover .ticket-gallery-delete,
.ticket-gallery-delete:focus-visible { opacity: 1; }

.ticket-gallery-delete:hover { transform: scale(1.05); }

/* Les fichiers qui ne sont pas des images : une liste, pas des tuiles. */
.ticket-files {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

.ticket-file {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.5rem 0.625rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    transition: border-color 0.15s ease, background 0.15s ease;
}

.ticket-file:hover {
    border-color: var(--primary);
    background: var(--color-surface-2);
}

.ticket-file-icon {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--primary-light);
    color: var(--primary);
    border-radius: var(--radius-sm);
}

.ticket-file-link {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    text-decoration: none;
    color: inherit;
}

.ticket-file-name {
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ticket-file-link:hover .ticket-file-name { color: var(--primary); }

.ticket-file-meta {
    font-size: 0.6875rem;
    color: var(--text-secondary);
}

.ticket-file-delete {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    border-radius: var(--radius-sm);
    border: none;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s ease, color 0.15s ease;
}

.ticket-file-delete:hover {
    background: var(--state-red-bg);
    color: var(--error);
}

/* ── Les images COLLÉES, en attente d'envoi ───────────────────────────────── */
/* Une image collée dans le composeur n'est envoyée qu'avec le message : d'ici
   là elle attend sous la zone, avec sa croix. Ces règles remplacent les
   `style.cssText` que `tickets.js` posait à la main (grille, tuile, bouton). */
.tk-collage {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.tk-collage-tuile {
    position: relative;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--surface);
}

.tk-collage-tuile img {
    width: 100%;
    height: 100px;
    object-fit: cover;
    display: block;
}

.tk-collage-nom {
    padding: 0.375rem;
    font-size: 0.6875rem;
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-secondary);
}

.tk-collage-retirer {
    position: absolute;
    top: 0.25rem;
    right: 0.25rem;
    background: rgba(255, 255, 255, 0.95);
    border: none;
    border-radius: var(--radius-sm);
    padding: 0.25rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
    color: var(--error);
}

/* ── Les images DANS un message rendu ─────────────────────────────────────── */
/* `markdown.js` émet `<img class="md-image">` pour `[img:…]` : sans cadre, une
   capture d'écran de 3000 px déborderait de la carte. */
.md-content .md-image {
    max-width: 100%;
    max-height: 420px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    cursor: zoom-in;
    display: block;
    margin: 0.5rem 0;
}

/* ── La visionneuse ───────────────────────────────────────────────────────── */
/* Plein cadre, sur fond sombre. Les commandes sont FIXES (elles ne suivent
   pas l'image quand elle défile), et sortent du flux de la fenêtre. Ces règles
   remplacent onze `style="position: fixed; …"` en ligne dans la vue. */
.tk-visionneuse .modal {
    max-width: 95vw;
    max-height: 95vh;
    background: transparent;
    box-shadow: none;
}

.tk-visionneuse-cadre {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    max-width: 90vw;
    max-height: 85vh;
}

.tk-visionneuse-cadre img {
    max-width: 100%;
    max-height: 85vh;
    object-fit: contain;
    border-radius: var(--radius);
}

.tk-visionneuse-cmd {
    position: fixed;
    background: rgba(0, 0, 0, 0.7);
    color: white;
    border: none;
    border-radius: 50%;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10002;
}

.tk-visionneuse-fermer { top: 1rem; right: 1rem; width: 44px; height: 44px; font-size: 1.5rem; }
.tk-visionneuse-prec   { left: 1rem;  top: 50%; transform: translateY(-50%); width: 50px; height: 50px; }
.tk-visionneuse-suiv   { right: 1rem; top: 50%; transform: translateY(-50%); width: 50px; height: 50px; }

.tk-visionneuse-info {
    position: fixed;
    bottom: 1rem;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(0, 0, 0, 0.7);
    color: white;
    padding: 0.5rem 1rem;
    border-radius: var(--radius);
    font-size: 0.875rem;
    z-index: 10002;
    text-align: center;
}

.tk-visionneuse-nom {
    display: block;
    margin-top: 0.25rem;
    opacity: 0.8;
}


/* ── La BARRE du composant (13-09, harmonisation des trois hauts) ─────────────
   Les puces-filtres de `window.Tickets` — `renderMsDropdown` en variante chip,
   la même que les en-têtes de liste et le tableau de bord. Elles vivent au bord
   DROIT de la barre : un panneau ancré à gauche de sa puce sortirait du cadre,
   d'où l'ancrage à droite (même règle que `.jv-chips` du tableau de bord). */
.tk-puces { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.tk-puces .ms-panel { left: auto; right: 0; }
/* Un panneau doit passer DEVANT le plateau : les colonnes du kanban sont des
   contextes d'empilement (elles ont un fond et un `overflow`). */
.tk-puces .ms-panel { z-index: 30; }


/* ── Les gestes d'UN message du fil (17-09-2026) ─────────────────────────────
   Corriger et retirer son propre message. Discrets au repos — ce sont des
   gestes de RATTRAPAGE, pas l'objet de la carte : les peindre en boutons pleins
   ferait deux appels à l'action par message, au-dessus du texte qu'on vient
   d'écrire. Ils ne sont rendus que sur SES messages (`can_edit`, décidé par le
   serveur), donc leur absence n'est jamais un vide à expliquer. */
.tk-msg-gestes {
    display: flex;
    gap: 4px;
    justify-content: flex-end;
    margin-bottom: 4px;
}

.tk-msg-geste {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 6px;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-muted);
    font-size: 0.75rem;
    cursor: pointer;
}

.tk-msg-geste:hover        { background: var(--color-surface-2); color: var(--text); }
.tk-msg-geste:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.tk-msg-geste--danger:hover { color: var(--error); }

.tk-msg-edit {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.tk-msg-edit-pied {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
}
