/* @grammaire v2
 *
 * SUIVI D'UNE DEMANDE — la coquille publique, le fil, la reponse.
 *
 * Trois gabarits la chargent, et c'est deliberé : `layouts/tracking.html.twig`
 * (la coquille de `/suivi/{token}`), `member/tickets/index` et
 * `member/tickets/show`. Les deux dernieres vivent dans l'espace de travail et
 * n'ont pas la coquille, mais elles rendent le MEME fil et le MEME formulaire.
 *
 * ─── Ce que la refonte du 2026-09-02 a retire ───
 *
 * La feuille portait `.support-tracking__badge--*`, SIX pastilles maison — une
 * par valeur de `TicketStatus` — avec leurs propres fonds, leur propre
 * typographie et leurs propres arrondis, a cote de `ui-pill` qui rend
 * exactement ce motif pour tout le site. Elles sont mortes : les trois surfaces
 * passent par `support/_status_pill`, qui traduit le statut metier en l'un des
 * cinq tons du vocabulaire ferme de la grammaire.
 *
 * Idem pour `.support-tracking__alert--{error,success}`, une grammaire d'alerte
 * qui n'existait que sur cette page alors que `ui-message` et `_flashes` la
 * portent partout ailleurs.
 *
 * PREFIXE `sup-` pour ce qui reste, et `tracking-shell-` pour la coquille : les
 * deux ne vivent pas ensemble, la seconde ne sert qu'a `/suivi`.
 */

/* ══ LA COQUILLE PUBLIQUE ═════════════════════════════════════════════
   Le visiteur arrive par un lien recu par courriel : tout ce qui compte est SA
   demande, pas la decouverte du site. D'ou l'absence de megamenu, de recherche
   et de fil d'Ariane — cf. l'en-tete de `layouts/tracking.html.twig`. */

.tracking-body {
    background: var(--color-bg-light);
}

.tracking-shell {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

/* LE LOGO SEUL, a la hauteur que la grammaire declare pour la marque.
   `--brand-logo-h` valait 7 rem dans `root.css` et n'etait employe NULLE PART :
   cette barre posait 3,25 rem a la main, a cote d'un slogan sur deux lignes.

   Le slogan est parti avec : le visiteur arrive par un lien recu par courriel
   pour voir SA demande, pas pour decouvrir ce que fait l'association. */
/* AUCUN FOND PROPRE : la barre laisse voir le plateau de la page. Elle peignait
   du blanc au-dessus du gris froid du corps, ce qui posait une bande claire en
   haut de l'ecran et une frontiere que rien ne justifiait — le logo n'est pas
   dans une barre, il est SUR la page. Un seul fond, declare une fois sur
   `.tracking-body`, et plus rien a tenir en accord. */
.tracking-shell__topbar {
    /* LA BARRE VAUT LE LOGO PLUS SON AIR, soit 8 rem — elle n'est pas egale au
       logo. Posee a `--brand-logo-h` tout rond, elle forcait le logo a 96 px
       pour tenir dans son rembourrage, et `header.css` dit exactement pourquoi
       c'est faux : « 96 px ce texte n'est plus lisible. 112 px est le plancher
       de lisibilite — il ne descend pas en dessous ». L'ecusson porte le nom de
       l'association ecrit dedans.

       Derivee et non ecrite « 8rem » : si le jeton bouge, la barre suit. */
    min-height: calc(var(--brand-logo-h) + 2 * var(--spacing-sm));
    display: flex;
    align-items: center;
    padding-block: var(--spacing-sm);
}

.tracking-shell__topbar-inner {
    display: flex;
    align-items: center;
    width: 100%;
}

.tracking-shell__brand {
    display: inline-flex;
    align-items: center;
    text-decoration: none;
    color: inherit;
}

/* LE PLANCHER, pas une deduction : 7 rem est la valeur que le site public rend
   sur `.navbar__logo`, et sous laquelle le nom de l'association cesse d'etre
   lisible dans l'ecusson. `width: auto` preserve le rapport de l'image. */
.tracking-shell__logo {
    width: auto;
    height: var(--brand-logo-h);
}

/* COLLANTE : la demande reste identifiee pendant tout le defilement du fil,
   comme la barre condensee du site public. Le plan d'empilement est NOMME —
   un nombre nu ne se relit pas, et il n'est jamais faux au moment ou on
   l'ecrit : il le devient quand une couche se glisse au-dessus. */
.tracking-shell__ticketbar {
    position: sticky;
    top: 0;
    z-index: var(--z-navbar);
    background: var(--color-navy);
    color: var(--color-on-navy);
    box-shadow: var(--shadow-md);
}

.tracking-shell__ticketbar-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-sm) var(--spacing-lg);
    padding-block: var(--spacing-sm);
}

.tracking-shell__ticketbar-id,
.tracking-shell__ticketbar-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--spacing-sm) var(--spacing-md);
    min-width: 0;
}

.tracking-shell__ticketbar-label {
    font-family: var(--font-sans);
    font-size: var(--eyebrow-size);
    font-weight: var(--eyebrow-weight);
    letter-spacing: var(--eyebrow-tracking);
    text-transform: uppercase;
    color: var(--color-on-navy-muted);
}

/* La reference est une VALEUR, pas de la prose : chasse fixe, comme partout
   ailleurs dans le depot ou une reference se lit et se recopie. */
.tracking-shell__ticketbar-ref {
    font-family: var(--font-data);
    font-size: var(--font-size-sm);
    font-weight: 600;
}

.tracking-shell__ticketbar-activity {
    font-size: var(--font-size-xs);
    color: var(--color-on-navy-muted);
}

.tracking-shell__copy {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-2xs);
    padding: var(--spacing-2xs) var(--spacing-sm);
    font-family: var(--font-sans);
    font-size: var(--font-size-xs);
    font-weight: 600;
    color: var(--color-on-navy);
    background: transparent;
    border: 1px solid var(--rule-on-dark);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

.tracking-shell__copy:hover {
    background: var(--veil-on-dark);
}

/* L'ECART SOUS LE LOGO ETAIT DE 56 PX, mesures. La marque et la demande ne sont
   pas deux blocs sans rapport : c'est la meme page, et `--rhythm-block` separe
   ce qui n'est pas de meme nature. La barre porte deja son propre air. */
.tracking-shell__main {
    flex: 1;
    padding-top: var(--spacing-lg);
    padding-bottom: var(--rhythm-block);
}

/* Meme raison que la barre du haut : pas de bande blanche. Le filet suffit a
   detacher le pied, sur un plateau uniforme il est meme plus lisible. */
.tracking-shell__footer {
    border-top: 1px solid var(--color-border);
    padding-block: var(--spacing-lg);
}

.tracking-shell__footer-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-sm);
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
}

.tracking-shell__footer-inner nav {
    display: flex;
    gap: var(--spacing-lg);
}

.tracking-shell__footer-note {
    margin: 0;
}

/* ══ L'EN-TETE D'UNE DEMANDE ══════════════════════════════════════════
   `_content_header` borne son titre a 24ch et son chapo a 62ch. C'est juste
   pour un titre EDITORIAL — « Nous ecrire », « Contacter un CESU » — que
   quelqu'un a ecrit court expres. Ici le titre est l'OBJET DU TICKET, saisi par
   l'utilisateur : « Demande de renseignements sur la formation AFGSU 2 pour
   notre etablissement » passe a la ligne au bout de vingt-quatre signes et
   s'empile sur quatre lignes dans une carte large de mille cinq cents pixels.

   Un MODIFICATEUR, jamais une correction de la brique : ses trente autres
   appelants sont des pages editoriales, et la borne y est le bon reglage.
   C'est ce que sa docblock dit — « le defaut etait dans la brique, le corriger
   page par page l'aurait fige » vaut dans l'autre sens aussi. */

.content-header--subject .content-header__title {
    max-width: 42ch;
}

.content-header--subject .content-header__lead {
    max-width: 78ch;
}

/* ══ LA FRISE D'AVANCEMENT ════════════════════════════════════════════
   Le manque principal de l'ancienne page : elle disait un ETAT, jamais un
   CHEMIN. « Ouvert » sans echelle se lit « rien ne bouge ». */

.sup-progress {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--spacing-sm);
    list-style: none;
    margin: var(--rhythm-section) 0 0;
    padding: 0;
    counter-reset: none;
}

@media (width >= 48em) {
    .sup-progress {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: var(--spacing-md);
    }
}

/* Chaque etape porte son TRAIT au-dessus, pas une ligne continue traversant
   la frise : un trait par etape se colore independamment, et il n'y a aucun
   segment a masquer aux extremites. */
.sup-progress__step {
    display: flex;
    align-items: flex-start;
    gap: var(--spacing-sm);
    padding-top: var(--spacing-sm);
    border-top: 3px solid var(--color-border);
    min-width: 0;
}

.sup-progress__step.is-done {
    border-top-color: var(--color-success);
}

.sup-progress__step.is-current {
    border-top-color: var(--color-primary);
}

/* L'attente n'est pas un progres : elle reprend le ton d'attention, sur
   l'etape courante, sans faire avancer la frise. */
.sup-progress__step.is-waiting {
    border-top-color: var(--color-warning);
}

.sup-progress__marker {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: var(--radius-pill);
    font-family: var(--font-data);
    font-size: var(--font-size-xs);
    font-weight: 700;
    color: var(--color-text-light);
    background: var(--color-bg-light);
}

.sup-progress__step.is-done .sup-progress__marker {
    color: var(--color-on-primary);
    background: var(--color-success);
}

.sup-progress__step.is-current .sup-progress__marker {
    color: var(--color-on-primary);
    background: var(--color-primary);
}

.sup-progress__step.is-waiting .sup-progress__marker {
    color: var(--color-text);
    background: var(--color-warning);
}

.sup-progress__body {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-2xs);
    min-width: 0;
}

.sup-progress__label {
    font-family: var(--font-sans);
    font-size: var(--font-size-sm);
    font-weight: 600;
    line-height: var(--line-height-tight);
    color: var(--color-text-light);
}

.sup-progress__step.is-done .sup-progress__label,
.sup-progress__step.is-current .sup-progress__label {
    color: var(--color-text);
}

.sup-progress__hint {
    font-size: var(--font-size-xs);
    line-height: var(--line-height-base);
    color: var(--color-text-light);
}

/* ══ LES DEUX COLONNES ════════════════════════════════════════════════
   Meme grille que `/contact` et les parcours d'adhesion, aux memes valeurs :
   un visiteur qui a ecrit par le formulaire de contact arrive ici, les deux
   pages doivent se ressembler.

   Ce qu'elle corrige au passage : la carte des echanges prenait toute la
   largeur, et une conversation d'un seul message y laissait 700 px de blanc a
   gauche de la bulle. */

.sup-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--card-gap);
    align-items: start;
}

.sup-layout__main,
.sup-layout__aside {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--card-gap);
}

@media (width >= 64em) {
    .sup-layout {
        grid-template-columns: minmax(0, 1fr) 21.25rem;
        gap: var(--card-gap);
    }

    /* COLLANTE : le recapitulatif et le lien restent atteignables pendant tout
       le defilement du fil. Le `top` degage le bandeau collant, qui est
       au-dessus. */
    /* `--spacing-2xl` et non une valeur qui degageait le bandeau navy : il
       n'existe plus, l'appui n'a plus rien a passer dessous. Meme valeur que
       `/contact` et les parcours d'adhesion. */
    .sup-layout__aside {
        position: sticky;
        top: var(--spacing-2xl);
    }
}

/* Le geste SANS RETOUR, separe de ce qui precede par un filet : c'est la forme
   qui doit dire qu'on ne revient pas de la. */
.sup-recap__final {
    margin-top: var(--spacing-md);
    padding-top: var(--spacing-md);
    border-top: 1px solid var(--color-border);
}

/* ══ LA PAGE ══════════════════════════════════════════════════════════ */

.sup-page {
    display: flex;
    flex-direction: column;
    gap: var(--card-gap);
    /* L'en-tete en surface carte porte deja son rembourrage bas : la page ne
       doit pas en ajouter un second. Mesure faite sur `/contact` et sur les
       deux parcours d'adhesion, qui rendent 0 px a cet endroit. */
    margin-bottom: var(--rhythm-block);
}

/* Dans l'espace de travail, l'enveloppe porte deja son propre rembourrage :
   la page ne doit pas en ajouter un second. */
.sup-page--member {
    gap: var(--card-gap);
}

.sup-page__intro {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-2xs);
}

.sup-page__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--spacing-md);
}

.sup-page__title {
    font-family: var(--font-title);
    font-size: var(--font-size-2xl);
    font-weight: 700;
    line-height: var(--line-height-tight);
    color: var(--color-text);
    margin: 0;
}

.sup-page__subject {
    font-size: var(--font-size-lg);
    line-height: var(--line-height-base);
    color: var(--color-text);
    margin: 0;
}

.sup-page__meta {
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
    margin: 0;
}

.sup-page__note {
    display: flex;
    align-items: flex-start;
    gap: var(--spacing-sm);
    font-size: var(--font-size-sm);
    line-height: var(--line-height-base);
    color: var(--color-text-light);
    margin: 0;
}

.sup-page__note svg {
    flex: none;
    margin-top: 0.15rem;
}

.sup-page__closed p {
    margin: 0;
}

/* ══ « L'EQUIPE A REPONDU » ═══════════════════════════════════════════
   Rendu masque, decouvert par la sonde. `hidden` fait le travail : pas de
   regle d'affichage ici, seulement la forme. */

.sup-update {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--spacing-md);
    padding: var(--spacing-md) var(--spacing-lg);
    background: var(--tint-info);
    border-radius: var(--radius-md);
    color: var(--color-primary-dark);
}

.sup-update__text {
    flex: 1;
    min-width: 0;
    font-weight: 600;
}

/* ══ LE FIL ═══════════════════════════════════════════════════════════ */

.sup-thread {
    display: flex;
    flex-direction: column;
    gap: var(--rhythm-section);
}

.sup-thread__head,
.sup-reply__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--spacing-md);
}

.sup-thread__title,
.sup-reply__title {
    font-family: var(--font-title);
    font-size: var(--font-size-lg);
    font-weight: 700;
    line-height: var(--line-height-tight);
    color: var(--color-text);
    margin: 0;
}

/* L'aide passe A LA LIGNE sous le titre tant que la rangee ne tient pas :
   `margin-left: auto` la collait contre lui sur telephone, ou les deux se
   lisaient comme une seule phrase coupee. Elle ne se pousse a droite qu'au
   palier ou il y a la place. */
.sup-reply__hint {
    margin: 0;
    flex: 1 0 100%;
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
}

@media (width >= 48em) {
    .sup-reply__hint {
        flex: 0 1 auto;
        margin-left: auto;
        text-align: right;
    }
}

.sup-thread__empty {
    margin: 0;
    max-width: var(--measure-prose);
    color: var(--color-text-light);
}

.sup-thread__list {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-lg);
    list-style: none;
    margin: 0;
    padding: 0;
}

/* LE CAMP DECIDE DU COTE, et c'est tout ce qui le decide : ce que j'ai ecrit
   va a droite, ce que l'equipe repond reste a gauche. La borne a 88 % laisse
   voir qu'une colonne existe en face — a 100 % les deux camps se confondent. */
.sup-thread__item {
    padding: var(--spacing-md) var(--spacing-lg);
    border-radius: var(--radius-md);
    max-width: 88%;
}

.sup-thread__item--submitter {
    background: var(--color-primary-light);
    margin-left: auto;
}

.sup-thread__item--agent {
    background: var(--color-bg-light);
    border: 1px solid var(--color-border);
}

/* Le systeme n'est pas un interlocuteur : ni camp, ni bulle pleine, ni pleine
   largeur de lecture. Un trait discontinu et du centre, comme une mention de
   journal. */
.sup-thread__item--system {
    max-width: 100%;
    text-align: center;
    background: transparent;
    border: 1px dashed var(--color-border);
    color: var(--color-text-light);
    font-style: italic;
}

.sup-thread__item-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--spacing-xs) var(--spacing-md);
    margin-bottom: var(--spacing-xs);
}

.sup-thread__sender {
    font-size: var(--font-size-sm);
    font-weight: 700;
    color: var(--color-text);
}

.sup-thread__time {
    font-family: var(--font-data);
    font-size: var(--font-size-xs);
    color: var(--color-text-light);
}

.sup-thread__body {
    font-size: var(--font-size-base);
    line-height: var(--line-height-base);
}

.sup-thread__body > :first-child { margin-top: 0; }
.sup-thread__body > :last-child { margin-bottom: 0; }

/* ── Les pieces jointes d'un message ── */

.sup-thread__files {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-2xs);
    list-style: none;
    margin: var(--spacing-md) 0 0;
    padding: 0;
}

.sup-thread__file {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    padding: var(--spacing-xs) var(--spacing-sm);
    text-decoration: none;
    color: var(--color-text);
    background: var(--surface-1);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    transition: border-color var(--transition-fast);
}

.sup-thread__file:hover {
    border-color: var(--color-primary);
}

.sup-thread__file-name {
    flex: 1;
    /* Un nom de fichier long doit CEDER, pas pousser la ligne : `min-width: 0`
       est ce qui l'autorise a descendre sous la largeur de son contenu. */
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--font-size-sm);
    font-weight: 600;
}

.sup-thread__file-size {
    flex: none;
    font-family: var(--font-data);
    font-size: var(--font-size-xs);
    color: var(--color-text-light);
}

.sup-thread__file-icon {
    flex: none;
    color: var(--color-primary);
}

/* ══ LA REPONSE ═══════════════════════════════════════════════════════ */

.sup-reply__form {
    gap: var(--spacing-lg);
}

/* Le composeur riche vit dans un shadow root : sa hauteur se pilote par son
   attribut `min-height-rem`, pas d'ici. Ne reste que sa place dans le flux. */
.sup-reply__editor {
    display: block;
    width: 100%;
}

/* Le champ de fichier est une ZONE DE DEPOT, pas un bouton : le trait
   discontinu le dit sans un mot. */
.sup-reply__file {
    display: block;
    position: relative;
    padding: var(--spacing-md) var(--spacing-lg);
    background: var(--color-bg-light);
    border: 1.5px dashed var(--color-border);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: border-color var(--transition-fast), background-color var(--transition-fast);
}

.sup-reply__file:hover {
    border-color: var(--color-primary);
}

/* Une piece retenue n'est plus une invitation : le trait devient plein. */
.sup-reply__file--filled {
    border-style: solid;
    border-color: var(--color-primary);
    background: var(--surface-1);
}

/* Le controle natif reste ATTEIGNABLE AU CLAVIER — `display: none` le sortirait
   de l'ordre de tabulation, et la zone ne serait plus qu'un decor pour qui
   n'emploie pas de souris. Il est transparent et etendu sur toute la zone. */
.sup-reply__file-input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}

.sup-reply__file-prompt,
.sup-reply__file-chosen {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
}

.sup-reply__file-prompt small,
.sup-reply__file-chosen small {
    display: block;
    font-size: var(--font-size-xs);
    color: var(--color-text-light);
}

.sup-reply__file-chosen strong {
    display: block;
    color: var(--color-text);
}

/* AU-DESSUS du champ transparent, sans quoi le clic sur « retirer » ouvrirait
   le selecteur de fichier au lieu de vider le champ. */
.sup-reply__file-clear {
    position: relative;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    margin-left: auto;
    width: 1.75rem;
    height: 1.75rem;
    color: var(--color-text-light);
    background: transparent;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    cursor: pointer;
    transition: color var(--transition-fast), border-color var(--transition-fast);
}

.sup-reply__file-clear:hover {
    color: var(--color-danger);
    border-color: var(--color-danger);
}

.sup-reply__actions {
    display: flex;
    justify-content: flex-end;
}

/* ══ CLORE LE DOSSIER ═════════════════════════════════════════════════ */

.sup-lifecycle {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--spacing-md) var(--spacing-lg);
}

.sup-lifecycle__lead {
    margin: 0;
    font-weight: 600;
    color: var(--color-text);
}

.sup-lifecycle__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
    margin-left: auto;
}

.sup-lifecycle__confirm {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-sm);
    padding: var(--spacing-md);
    max-width: var(--measure-prose);
    background: var(--surface-1);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}

.sup-lifecycle__confirm p {
    margin: 0;
    font-size: var(--font-size-sm);
    line-height: var(--line-height-base);
    color: var(--color-text-light);
}

.sup-lifecycle__confirm-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
}

/* ══ RETROUVER SON LIEN (`/suivi/retrouver`) ══════════════════════════
   Un formulaire a UN champ n'a pas de colonne d'appui : il n'y a rien a
   appuyer. La page se borne et se centre, comme la confirmation de `/contact`
   — sans borne, un champ de courriel courrait sur 1 400 px. */

/* 62 REM DE CONTENU, pas 62 rem de conteneur.

   `content-header--narrow` borne le CORPS de l'en-tete a 62 rem, a l'interieur
   d'un `.container` qui porte deja sa gouttiere. Ici la borne porte sur le
   conteneur lui-meme, et `box-sizing: border-box` fait que la gouttiere se
   prend DEDANS : a `62rem` tout rond, le contenu tombait a 944 px contre 992
   pour l'en-tete, et le bord gauche se decalait de 24 px d'un bloc a l'autre.

   La gouttiere s'ajoute donc a la borne. Meme calcul que les blocs de rebond
   des fiches (`design-system.md`, « un bloc de rebond s'aligne sur la colonne
   de lecture, pas sur le conteneur »). */
.sup-page--narrow,
.sup-header > .container {
    max-width: calc(62rem + 2 * var(--spacing-md));
}

.sup-recover {
    display: flex;
    flex-direction: column;
    gap: var(--rhythm-section);
}

/* Le widget ALTCHA se pose entre le champ et le bouton : il fait partie de
   l'envoi, pas de la saisie. */
.sup-recover__captcha {
    min-width: 0;
}

.sup-recover__actions {
    display: flex;
    justify-content: flex-end;
}

/* ══ LE PLANCHER TACTILE, SOUS 48EM ═══════════════════════════════════
   `--touch-target-min` vaut 2,75 rem (44 px) et c'est le minimum de la charte.
   `.btn--sm` mesure 2,125 rem (34 px) : c'est deliberé pour une rangee dense au
   pointeur, et insuffisant au doigt.

   Mesure a 320 px avant correction : « Copier le lien », « Ma demande est
   resolue », « Clore definitivement » et les deux boutons de confirmation
   tombaient tous a 34 px. Ce sont les SEULS gestes de la colonne d'appui, et
   sur telephone cette colonne est en pleine largeur sous le formulaire — donc
   la ou l'on agit.

   Meme forme que `year-switch.css`, qui a tranche la meme question : on releve
   au palier tactile, on ne change pas la taille au pointeur. */
@media (width < 48em) {
    .sup-layout__aside .btn,
    .sup-lifecycle__confirm .btn,
    .sup-reply__actions .btn {
        min-height: var(--touch-target-min);
    }

    /* La croix qui retire la piece jointe est une cible CARREE : lui donner une
       hauteur sans largeur la laisserait a 28 px de large. */
    .sup-reply__file-clear {
        width: var(--touch-target-min);
        height: var(--touch-target-min);
    }
}

/* ══ « MES DEMANDES » — la liste ══════════════════════════════════════ */

.member-tickets {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-md);
}

.member-tickets__back {
    margin: 0 0 var(--spacing-lg);
    font-size: var(--font-size-sm);
}

.member-tickets__back a {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-2xs);
    color: var(--color-primary);
    text-decoration: none;
    font-weight: 600;
}

.member-tickets__back a:hover { text-decoration: underline; }

.member-tickets__card {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-xs);
    padding: var(--spacing-lg);
    text-decoration: none;
    background: var(--surface-1);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.member-tickets__card:hover {
    border-color: var(--color-primary);
    box-shadow: var(--shadow-sm);
}

.member-tickets__card-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--spacing-sm) var(--spacing-md);
}

.member-tickets__ref {
    font-family: var(--font-data);
    font-size: var(--font-size-xs);
    color: var(--color-text-light);
}

.member-tickets__subject {
    font-family: var(--font-title);
    font-size: var(--font-size-base);
    font-weight: 700;
    line-height: var(--line-height-tight);
    color: var(--color-text);
}

.member-tickets__meta {
    font-size: var(--font-size-sm);
    color: var(--color-text-light);
}
