/* RedDesk Control — compléments (consomment les tokens de style.css). */

/* Badges de plan / statut */
.badge-lite     { background: var(--neutral-bg); color: var(--neutral); border-color: #DDD8CF; }
.badge-basic    { background: var(--info-bg);    color: var(--info);    border-color: #CBD7E6; }
.badge-avance   { background: var(--success-bg); color: var(--success); border-color: #CCDCC9; }
.badge-expert   { background: var(--warning-bg); color: var(--warning); border-color: #E8D3B4; }
.badge-actif    { background: var(--success-bg); color: var(--success); border-color: #CCDCC9; }
.badge-suspendu { background: var(--danger-bg);  color: var(--danger);  border-color: var(--red-border); }

/* Jauge usage / plafond */
.rk-usage { display: flex; flex-direction: column; gap: 0.4rem; }
.rk-usage-head { display: flex; justify-content: space-between; align-items: baseline; gap: 0.6rem; }
.rk-usage-head .lbl { font-size: 0.8rem; color: var(--text-muted); }
.rk-usage-head .val { font-family: var(--serif); font-weight: 600; font-size: 0.85rem; }
.rk-usage-head .val .faint { color: var(--text-muted); font-weight: 500; }
.rk-usage-track { height: 0.53333rem; border-radius: 66rem; background: var(--paper-deep); box-shadow: var(--nm-inset-sm); overflow: hidden; }
.rk-usage-fill { height: 100%; border-radius: 66rem; transition: width 0.3s var(--ease); }
.rk-usage-fill.ok { background: var(--success); }
.rk-usage-fill.warning { background: var(--warning); }
.rk-usage-fill.danger { background: var(--danger); }

/* Grilles */
.rk-grid { display: grid; gap: 1.2rem; }
.rk-grid-usage { grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }
.rk-grid-plans { grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); }

/* Repartition par plan : des NOMBRES, pas des champs de saisie. Elle utilisait
   `.rk-grid-usage`, dont le `minmax(14rem)` est taille pour un <input> : sur
   telephone une seule colonne tenait, et quatre chiffres occupaient 530 px de
   haut. Ici 7rem suffisent a un nombre et son libelle — deux par ligne sur
   telephone, tous alignes des que la carte s'elargit. `auto-fit` plutot qu'un
   compte fige : un cinquieme plan se rangerait tout seul. */
.rk-repartition { display: grid; gap: 1rem 1.2rem; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); }
.rk-repartition .stat-value { font-size: 1.8rem; }

/* Liste de fonctionnalités */
.rk-feat { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: 0.5rem; }
.rk-feat-item { display: flex; align-items: center; gap: 0.5rem; font-size: 0.9rem; }
.rk-feat-item.off { color: var(--text-muted); }
.rk-feat-item .lu-check { color: var(--success); }
.rk-feat-item .lu-minus { color: var(--border-strong); }

/* Divers */
.rk-section-title { font-family: var(--serif); font-weight: 700; font-size: 1rem; margin: 0 0 0.9rem; }
.rk-actions { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.rk-field { display: flex; flex-direction: column; gap: 0.4rem; margin-bottom: 1rem; }
/* Un champ qui prend toute la rangee : le texte « A propos » d'un site tient
   sur plusieurs lignes, et une colonne de 14 rem le rend illisible a la
   saisie. Ajoute avec la page Sites (15.09.2026). */
.rk-field-wide { grid-column: 1 / -1; }
.rk-field textarea {
    font: inherit; padding: 0.55rem 0.7rem; border: 1px solid var(--border, #D6DBE2);
    border-radius: 0.5rem; resize: vertical; background: inherit; color: inherit;
}
.rk-field > label { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.07em; font-weight: 600; color: var(--text-muted); }
.rk-inline-form { display: flex; gap: 0.6rem; align-items: flex-end; flex-wrap: wrap; }
.rk-muted { color: var(--text-muted); }

/* Un compteur qu'on n'a PAS PU lire. Il se distingue d'un vrai zero : grise,
   en italique, avec son triangle. Sans cette nuance, « 0 bien » se lisait
   comme une agence vide alors que la requete avait echoue — voir
   usage_scalar() dans includes/plans.php. */
.faint { color: var(--text-muted); font-weight: 500; }
.rk-usage.est-inconnu .val { color: var(--warning); font-style: italic; }
.rk-usage.est-inconnu .val i { margin-right: 0.3rem; font-style: normal; }
.acc-metric .v .faint { font-style: italic; font-size: 0.9em; }
.rk-history-row { display: flex; gap: 0.8rem; align-items: baseline; padding: 0.4rem 0; border-bottom: 0.06667rem solid var(--border); }
.rk-history-row:last-child { border-bottom: 0; }
.rk-history-date { font-family: var(--serif); font-variant-numeric: tabular-nums; color: var(--text-muted); min-width: 6rem; font-size: 0.85rem; }
.rk-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.2rem; }
.rk-temp-pass { font-family: var(--serif); font-size: 1.4rem; font-weight: 700; letter-spacing: 0.08em; color: var(--red); }
.rk-back { display: inline-flex; align-items: center; gap: 0.4rem; color: var(--text-muted); font-size: 0.85rem; margin-bottom: 1rem; }
.rk-back:hover { color: var(--red); }

/* ── Page Comptes : cockpit (stats) + grille de cartes agences ── */
.stat-value-unit { font-size: 1rem; font-weight: 600; }

.acc-create { margin-bottom: 1.2rem; }
.acc-create > summary { display: inline-flex; align-items: center; gap: 0.4rem; width: auto; list-style: none; cursor: pointer; }
.acc-create > summary::-webkit-details-marker { display: none; }
.acc-create > summary::marker { content: ""; }
.acc-create[open] > summary { margin-bottom: 1rem; }
.acc-create-form { margin: 0; }

.acc-toolbar { display: flex; gap: 0.8rem; align-items: flex-end; flex-wrap: wrap; margin-bottom: 1.2rem; }
.acc-toolbar .rk-field, .acc-toolbar .iselect { min-width: 11rem; }
/* Dans une barre de filtres, le champ ne porte pas la marge basse qu'il a
   dans un formulaire : c'est la barre qui espace. Cette regle remplace le
   `style="margin:0"` que chaque page repetait a la main. */
.acc-toolbar .rk-field { margin-bottom: 0; }
.acc-toolbar-end { margin-left: auto; display: flex; gap: 0.6rem; align-items: center; }

/* Sur telephone, un filtre par ligne, pleine largeur. A deux par ligne les
   champs prenaient des largeurs differentes selon leur contenu et le bouton
   se retrouvait colle au second : c'est ce qui donnait cet aspect ferraille.
   Le bloc de droite (compteur, reinitialisation) passe sur sa propre ligne. */
@media (max-width: 620px) {
    .acc-toolbar { display: grid; grid-template-columns: 1fr; }
    .acc-toolbar .rk-field,
    .acc-toolbar .iselect,
    .acc-toolbar .btn { min-width: 0; width: 100%; }
    .acc-toolbar-end { margin-left: 0; justify-content: space-between; }
}

.acc-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr)); gap: 1rem; }
.acc-card {
    background: var(--paper); border: 0.1rem solid var(--line-ink); padding: 1.1rem 1.2rem;
    display: flex; flex-direction: column; gap: 0.9rem;
    transition: box-shadow 0.15s var(--ease), transform 0.15s var(--ease);
}
.acc-card:hover { box-shadow: var(--nm-shadow-lg); transform: translateY(-0.1rem); }
.acc-card.is-suspended { opacity: 0.72; }
.acc-card-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.6rem; }
.acc-card-name { font-family: var(--serif); font-weight: 700; font-size: 1.05rem; color: var(--text); }
.acc-card-name:hover { color: var(--red); }
.acc-card-city { font-size: 0.8rem; color: var(--text-muted); margin-top: 0.1rem; display: flex; align-items: center; gap: 0.3rem; }
.acc-card-city i { font-size: 0.7rem; }
.acc-card-metrics { display: flex; gap: 1.4rem; align-items: flex-end; }
.acc-metric.grow { flex: 1; }
.acc-metric .k { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); }
.acc-metric .v { font-family: var(--serif); font-weight: 700; font-size: 1.15rem; color: var(--text); line-height: 1.2; }
.acc-metric .v small { color: var(--text-muted); font-weight: 500; font-size: 0.7rem; }
.acc-card-foot { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; border-top: 0.06667rem solid var(--border); padding-top: 0.8rem; }
.acc-mrr { font-family: var(--serif); font-weight: 700; color: var(--red); }
.acc-mrr.faint { color: var(--text-muted); }

/* Raccourci « Effacer » d'une agence suspendue : discret par défaut, il ne
   s'affirme qu'au survol. Une action irréversible ne doit pas attirer l'œil
   dans une liste, mais rester trouvable sans fouiller la fiche. */
.acc-card-purge {
    display: inline-flex; align-items: center; gap: 0.3rem;
    font-size: 0.72rem; font-weight: 600; text-decoration: none;
    color: var(--text-muted); border: 0.06667rem solid var(--border);
    border-radius: 0.4rem; padding: 0.2rem 0.5rem;
    transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.acc-card-purge:hover { color: #fff; background: #B91C1C; border-color: #B91C1C; }

/* ── Page Plans : liste des plans + panneau d'édition ── */
.pd { display: grid; grid-template-columns: 17rem minmax(0, 1fr); gap: 1.2rem; align-items: start; }
.pd-list { display: flex; flex-direction: column; gap: 0.5rem; position: sticky; top: 1rem; }
.pd-item {
    display: flex; align-items: center; gap: 0.7rem; padding: 0.8rem 0.9rem;
    background: var(--paper); border: 0.1rem solid var(--line-ink); color: var(--text);
    transition: background 0.15s var(--ease);
}
.pd-item:hover { background: var(--red-soft); text-decoration: none; }
.pd-item.is-active { background: var(--red); border-color: var(--red); }
.pd-item.is-active .pd-item-name,
.pd-item.is-active .pd-item-sub,
.pd-item.is-active .pd-item-price { color: #FDF7F6; }
.pd-item-body { min-width: 0; }
.pd-item-name { font-family: var(--serif); font-weight: 700; font-size: 0.95rem; display: block; }
.pd-item-sub { font-size: 0.75rem; color: var(--text-muted); }
.pd-item-price { margin-left: auto; font-family: var(--serif); font-weight: 700; color: var(--red); white-space: nowrap; }

.pd-main { min-width: 0; }
.pd-impact {
    display: flex; align-items: center; gap: 0.6rem; padding: 0.7rem 0.9rem; margin-bottom: 1rem;
    background: var(--warning-bg); color: var(--warning); border-radius: var(--radius); font-size: 0.85rem;
}
.pd-impact.is-quiet { background: var(--paper-deep); color: var(--text-muted); }

.pd-field {
    display: grid; grid-template-columns: 13rem minmax(0, 1fr); gap: 0.8rem; align-items: center;
    padding: 0.55rem 0; border-bottom: 0.06667rem solid var(--border);
}
.pd-field:last-child { border-bottom: 0; }
.pd-field > label {
    font-size: 0.85rem; color: var(--text-muted); text-transform: none; letter-spacing: 0; font-weight: 500;
}
.pd-field > label i { width: 1.2rem; text-align: center; color: var(--red-accent); margin-right: 0.35rem; }
.pd-field input[type="text"],
.pd-field input[type="number"] { max-width: 11rem; }
.pd-field input:disabled { background: var(--paper-deep); color: var(--text-muted); }

.pd-input-unit { display: inline-flex; align-items: center; gap: 0.5rem; }
.pd-unit { font-size: 0.78rem; color: var(--text-muted); white-space: nowrap; }
.pd-limit { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.pd-unl {
    display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.78rem;
    color: var(--text-muted); text-transform: none; letter-spacing: 0; cursor: pointer; font-weight: 500;
}

.pd-feat { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 0.5rem; }
.pd-feat-item {
    display: flex; align-items: center; gap: 0.6rem; padding: 0.55rem 0.7rem;
    background: var(--paper-deep); border-radius: var(--radius); font-size: 0.88rem;
    cursor: pointer; text-transform: none; letter-spacing: 0; color: var(--text); font-weight: 500;
}
.pd-feat-item i { color: var(--red-accent); width: 1.1rem; text-align: center; }
.pd-actions { display: flex; justify-content: flex-end; gap: 0.6rem; margin-top: 1.2rem; flex-wrap: wrap; }

/* Interrupteur (illimité / fonctionnalité incluse) */
.sw { position: relative; display: inline-block; width: 2.1rem; height: 1.15rem; flex-shrink: 0; }
.sw > input { position: absolute; opacity: 0; width: 0; height: 0; }
.sw > span { position: absolute; inset: 0; background: var(--border-strong); border-radius: 66rem; transition: background 0.2s var(--ease); }
.sw > span::before {
    content: ""; position: absolute; height: 0.85rem; width: 0.85rem; left: 0.15rem; bottom: 0.15rem;
    background: #fff; border-radius: 50%; transition: transform 0.2s var(--ease);
}
.sw > input:checked + span { background: var(--success); }
.sw > input:checked + span::before { transform: translateX(0.95rem); }
.sw > input:focus-visible + span { box-shadow: 0 0 0 0.2rem rgba(192, 57, 43, 0.18); }

@media (max-width: 900px) {
    .pd { grid-template-columns: 1fr; }
    .pd-list { position: static; }
    .pd-field { grid-template-columns: 1fr; gap: 0.35rem; }
}

/* ── Fiche compte : 2 colonnes (main + rail synthèse sticky) ── */
.fa-grid { display: grid; grid-template-columns: minmax(0, 1fr) 20rem; gap: 1.2rem; align-items: start; }
.fa-main { display: flex; flex-direction: column; gap: 1.2rem; min-width: 0; }
.fa-rail { position: sticky; top: 1rem; display: flex; flex-direction: column; gap: 1rem; }
.fa-rail-top { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; margin-bottom: 0.8rem; }
.fa-rail-price { font-family: var(--serif); font-weight: 800; font-size: 2rem; color: var(--red); line-height: 1; margin-bottom: 1rem; }
.fa-rail-price small { font-size: 0.9rem; font-weight: 600; color: var(--text-muted); }
.fa-kv { display: flex; justify-content: space-between; gap: 0.6rem; padding: 0.5rem 0; border-bottom: 0.06667rem solid var(--border); font-size: 0.88rem; }
.fa-kv:last-child { border-bottom: 0; }
.fa-kv .k { color: var(--text-muted); flex-shrink: 0; }
.fa-kv .v { text-align: right; overflow-wrap: anywhere; }
.fa-rail-actions { display: flex; flex-direction: column; gap: 0.6rem; margin-top: 1rem; }
.fa-rail-actions form { display: flex; flex-direction: column; gap: 0.5rem; }
.fa-rail-actions .btn { width: 100%; }
.fa-rail .iselect { width: 100%; }
.uv { display: flex; flex-direction: column; gap: 0.9rem; }
@media (max-width: 900px) { .fa-grid { grid-template-columns: 1fr; } .fa-rail { position: static; } }

/* ── Login : repli code de secours (anti-lockout) ── */
.lg-backup { margin: 0.9rem 0 0.2rem; }
.lg-backup > summary {
    cursor: pointer; font-size: 0.82rem; color: var(--text-muted);
    list-style: none; text-align: center;
}
.lg-backup > summary::-webkit-details-marker { display: none; }
.lg-backup > summary::marker { content: ""; }
.lg-backup > summary:hover { color: var(--red); }
.lg-backup-input {
    width: 100%; margin-top: 0.7rem; text-align: center;
    font-family: var(--serif); font-size: 1.05rem; letter-spacing: 0.12em;
    text-transform: uppercase;
}
.lg-backup-hint { font-size: 0.76rem; color: var(--text-muted); margin: 0.45rem 0 0; text-align: center; }

/* ============================================================
   Demandes de démonstration (page /requests)
   Boîte de réception commerciale : une carte par demande,
   les nouvelles se distinguent par un liseré rouge.
   ============================================================ */
.dr-count { font-size: 0.85rem; color: var(--text-muted); }

.dr-empty { text-align: center; padding: 3rem 1.5rem; }
.dr-empty i { font-size: 2rem; color: var(--red-soft-strong); margin-bottom: 0.8rem; }
.dr-empty p { margin: 0.3rem 0; }

.dr-list { display: grid; gap: 1rem; }

.dr-card {
    position: relative;
    display: grid;
    gap: 0.9rem;
    padding: 1.3rem 1.4rem;
    border-radius: var(--nm-radius);
    background: var(--paper);
    box-shadow: var(--nm-shadow);
}
/* Une demande non traitée doit sauter aux yeux dans la pile. */
.dr-card.is-new::before {
    content: "";
    position: absolute;
    left: 0; top: 1.1rem; bottom: 1.1rem;
    width: 0.2rem;
    border-radius: 0 0.2rem 0.2rem 0;
    background: var(--red);
}

.dr-head { display: flex; gap: 1rem; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; }
.dr-agence { font-family: var(--serif); font-size: 1.15rem; margin: 0 0 0.35rem; }
.dr-meta { display: flex; flex-wrap: wrap; gap: 0.35rem 1rem; font-size: 0.8rem; color: var(--text-muted); }
.dr-meta i { margin-right: 0.3rem; }

.dr-contact { display: flex; flex-wrap: wrap; gap: 0.5rem 1.2rem; font-size: 0.88rem; }
.dr-contact i { margin-right: 0.4rem; color: var(--text-muted); }
.dr-contact a { color: var(--red); font-weight: 500; }

.dr-message {
    margin: 0;
    padding: 0.85rem 1rem;
    border-radius: var(--radius);
    background: var(--paper-deep);
    box-shadow: var(--nm-inset-sm);
    font-size: 0.9rem;
    line-height: 1.6;
}

.dr-note > summary {
    display: inline-flex; align-items: center; gap: 0.5rem;
    cursor: pointer; list-style: none;
    font-size: 0.82rem; font-weight: 600; color: var(--text-muted);
}
.dr-note > summary::-webkit-details-marker { display: none; }
.dr-note-form { display: flex; gap: 0.6rem; align-items: flex-end; margin-top: 0.6rem; flex-wrap: wrap; }
.dr-note-form textarea {
    flex: 1 1 18rem; min-height: 3.2rem; resize: vertical;
    font-family: var(--sans); font-size: 0.88rem;
}

.dr-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.dr-actions form { margin: 0; }
.dr-actions .dr-create { margin-left: auto; }

@media (max-width: 620px) {
    .dr-actions .dr-create { margin-left: 0; width: 100%; justify-content: center; }
}

/* Pastilles d'étape : mêmes couleurs de statut que le reste de l'app. */
.badge-info    { background: var(--info-bg);    color: var(--info); }
.badge-success { background: var(--success-bg); color: var(--success); }
.badge-warning { background: var(--warning-bg); color: var(--warning); }
.badge-neutral { background: var(--neutral-bg); color: var(--neutral); }
.badge i { margin-right: 0.35rem; }
.dr-del { color: var(--danger); }
.dr-del:hover { color: var(--danger); background: var(--danger-bg); }

/* ------------------------------------------------------------------
   Journal d'audit — liste + panneau de détail
   ------------------------------------------------------------------
   Le tableau précédent donnait une colonne « Détail » écrasée sur quatre
   lignes à côté d'une colonne de dates presque vide : le détail va de 5 à
   106 caractères, et 4 lignes sur 10 n'ont pas de cible. Ici la liste ne
   porte que ce qui tient sur une ligne, le reste vit dans le panneau. */

.audit-filtres {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem 0.9rem;
    margin-bottom: var(--pile, 1.2rem);
}
.audit-pastilles { display: flex; flex-wrap: wrap; gap: 0.35rem; }
/* Séparateur discret entre les deux jeux de filtres : ils ne se combinent pas
   dans la tête de l'utilisateur s'ils se touchent. */
.audit-periode { padding-left: 0.9rem; border-left: 0.06667rem solid var(--border); }

.audit-pastille {
    display: inline-block;
    padding: 0.36rem 0.8rem;
    border: 0.06667rem solid var(--border-strong);
    border-radius: 999px;
    background: var(--paper);
    color: var(--text-muted);
    font-size: 0.82rem;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.audit-pastille:hover { color: var(--text); border-color: var(--text-muted); text-decoration: none; }
.audit-pastille.is-on {
    background: var(--red);
    border-color: var(--red);
    color: #FDF7F6;
    font-weight: 600;
}
.audit-pastille.is-on:hover { background: var(--red-hover); color: #FDF7F6; }
.audit-pastille-fine { font-size: 0.78rem; padding: 0.3rem 0.7rem; }
.audit-pastille:focus-visible { outline: 2px solid var(--red); outline-offset: 2px; }

.audit-compte { margin: 0 0 0 auto; font-size: 0.8rem; color: var(--text-muted); white-space: nowrap; }

.audit-duo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 20rem);
    gap: var(--pile, 1.2rem);
    align-items: start;
}

/* La liste porte ses propres séparations : pas de rembourrage de carte, sinon
   la première et la dernière ligne flottent. */
.audit-liste { padding: 0; overflow: hidden; }

/* ⚠ QUATRE COLONNES DEPUIS LE 15.09.2026, ET NON DEUX.
   La ligne ne portait que l'heure et l'action : tout le reste de la
   largeur restait vide, et il fallait SÉLECTIONNER chaque entrée pour
   savoir qui l'avait faite et ce qu'elle disait. Un journal d'audit se
   parcourt du regard ; « qui » et « détail » sont donc dans la ligne.
   Les deux dernières colonnes se tronquent plutôt que de passer à la
   ligne : c'est le panneau de droite qui porte le texte entier. */
.audit-rang {
    display: grid;
    grid-template-columns: 5.4rem minmax(0, 18rem) minmax(0, 8rem) minmax(0, 1fr);
    gap: 0.7rem;
    align-items: center;
    width: 100%;
    padding: 0.62rem 0.9rem;
    border: 0;
    border-top: 0.06667rem solid var(--border);
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.audit-rang:first-child { border-top: 0; }
.audit-rang:hover { background: var(--paper-deep); }
.audit-rang.is-on { background: var(--danger-bg); }
.audit-rang:focus-visible { outline: 2px solid var(--red); outline-offset: -2px; }

.audit-rang-h {
    font-size: 0.78rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;   /* les heures s'alignent en colonne */
    white-space: nowrap;
}
/* Une seule ligne, jamais deux : c'est tout l'intérêt d'avoir sorti le détail.
   `min-width: 0` est indispensable — sans lui, une grille refuse de rétrécir
   son enfant et l'ellipse ne se déclenche jamais. */
.audit-rang-t {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
}
.audit-rang-cible {
    font-size: 0.84rem;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
}

.audit-etiq {
    display: inline-block;
    flex: none;
    padding: 0.16rem 0.5rem;
    border-radius: 0.33333rem;
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
}
.audit-etiq-neutre  { background: var(--paper-deep); color: var(--text-muted); }
.audit-etiq-success { background: var(--success-bg); color: var(--success); }
.audit-etiq-info    { background: var(--info-bg);    color: var(--info); }
.audit-etiq-warning { background: var(--warning-bg); color: var(--warning); }
.audit-etiq-danger  { background: var(--danger-bg);  color: var(--danger); }

.audit-panneau {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    position: sticky;
    top: 1.2rem;   /* le détail reste visible pendant qu'on parcourt la liste */
}
.audit-pan-etiq { align-self: flex-start; }
.audit-pan-champ { display: flex; flex-direction: column; gap: 0.15rem; }
/* Champ sans valeur : masqué plutôt qu'affiché avec un tiret. */
.audit-pan-champ.est-vide { display: none; }
.audit-pan-l {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.audit-pan-v { font-size: 0.87rem; line-height: 1.5; overflow-wrap: anywhere; }

@media (max-width: 900px) {
    /* Le panneau passe sous la liste et cesse de coller : sur un écran étroit,
       une colonne collante mange la moitié de la hauteur utile. */
    .audit-duo { grid-template-columns: 1fr; }
    .audit-panneau { position: static; }
    .audit-compte { margin-left: 0; width: 100%; }
    .audit-periode { padding-left: 0; border-left: 0; }

    /* Cibles tactiles : 32 px au doigt, c'est trop petit. On remonte à ~44 px
       sans toucher à la taille du texte. */
    .audit-pastille,
    .audit-pastille-fine {
        display: inline-flex;
        align-items: center;
        min-height: 2.66667rem;
        padding-top: 0;
        padding-bottom: 0;
    }
}

/* ------------------------------------------------------------------
   Santé de l'application cible (pages/sante.php)
   ------------------------------------------------------------------
   Une pastille dit l'essentiel avant la lecture : joignable ou non. Le reste
   se lit en mesures alignées, pas en paragraphes — on vient ici pour vérifier
   quelque chose, pas pour lire. */
.sante-tete { display: flex; align-items: center; gap: 0.9rem; margin-bottom: 1.1rem; }
.sante-pastille {
    flex: none; width: 2.4rem; height: 2.4rem; border-radius: 50%;
    display: flex; align-items: center; justify-content: center; font-size: 1rem;
}
.sante-pastille.est-ok { background: var(--success-bg); color: var(--success); }
.sante-pastille.est-ko { background: var(--danger-bg);  color: var(--danger); }
.sante-titre { min-width: 0; }

.sante-grille { display: grid; gap: 1rem 1.4rem; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
.sante-mesure .k { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.07em; color: var(--text-muted); font-weight: 600; }
.sante-mesure .v { font-family: var(--serif); font-weight: 700; font-size: 1.15rem; margin: 0.15rem 0 0.1rem; }
.sante-mesure .s { font-size: 0.78rem; color: var(--text-muted); line-height: 1.45; }
/* Le trait de gauche, et non un fond teinté : une mesure en alerte reste une
   mesure, pas une action à confirmer. */
.sante-mesure.est-alerte { padding-left: 0.7rem; border-left: 0.2rem solid var(--warning); }
.sante-mesure.est-alerte .v { color: var(--warning); }

/* Tâches planifiées : une puce compacte par tâche, lues dans rk-cron.log.
   Volontairement dense — six tâches par environnement tiennent sur une ligne
   ou deux, et c'est un état qu'on balaie du regard, pas qu'on étudie. */
.sante-taches { display: flex; flex-wrap: wrap; gap: 0.4rem 0.55rem; margin-top: 1rem; }
.sante-tache {
    display: inline-flex; align-items: baseline; gap: 0.4rem;
    padding: 0.3rem 0.6rem; border: 0.06667rem solid var(--border);
    border-radius: 0.4rem; background: var(--paper-deep); font-size: 0.78rem;
}
.sante-tache > .lu { align-self: center; color: var(--success); font-size: 0.85rem; }
.sante-tache .n { font-weight: 600; }
.sante-tache .q { color: var(--text-muted); }
.sante-tache .d { color: var(--danger); font-weight: 600; }
.sante-tache.est-alerte { border-color: var(--warning); }
.sante-tache.est-alerte > .lu { color: var(--warning); }
.sante-tache.est-ko { border-color: var(--danger); }
.sante-tache.est-ko > .lu { color: var(--danger); }

.sante-journal { margin-top: 1.1rem; border-top: 0.06667rem solid var(--border); padding-top: 0.8rem; }
.sante-journal > summary {
    list-style: none; cursor: pointer;
    font-size: 0.82rem; font-weight: 600; color: var(--red-ink);
    display: flex; align-items: center; gap: 0.45rem;
}
.sante-journal > summary::-webkit-details-marker { display: none; }
.sante-journal ul { margin: 0.7rem 0 0; padding: 0; list-style: none; display: grid; gap: 0.45rem; }
.sante-journal li {
    font-family: ui-monospace, "Cascadia Mono", monospace;
    font-size: 0.74rem; line-height: 1.5; color: var(--text-muted);
    background: var(--paper-deep); padding: 0.5rem 0.65rem; border-radius: var(--radius);
    overflow-wrap: anywhere;
}

/* ------------------------------------------------------------------
   Confirmation d'une action sensible (<dialog>, voir includes/footer.php)
   ------------------------------------------------------------------
   Le bouton porte le NOM du geste — « Effacer définitivement », pas « OK ».
   C'est la seule chose qu'on lit vraiment avant de cliquer. */
.rk-confirm {
    border: 0;
    padding: 1.6rem 1.7rem 1.3rem;
    border-radius: var(--nm-radius);
    background: var(--paper);
    box-shadow: var(--nm-shadow);
    max-width: 28rem;
    color: var(--text);
}
.rk-confirm::backdrop { background: rgba(16, 24, 40, 0.45); }
.rk-confirm p { margin: 0 0 1.3rem; font-size: 0.95rem; line-height: 1.6; }
.rk-confirm-actions { display: flex; gap: 0.6rem; justify-content: flex-end; flex-wrap: wrap; }

@media (max-width: 480px) {
    /* Les deux boutons prennent la largeur : viser au pouce sur une action
       irréversible ne doit pas être un exercice d'adresse. */
    .rk-confirm-actions { flex-direction: column-reverse; }
    .rk-confirm-actions .btn { width: 100%; justify-content: center; }
}

/* Trois motifs qui se repetaient en `style=""` d'un ecran a l'autre. Les
   valeurs uniques restent en ligne : une classe a usage unique deplace le
   probleme sans le resoudre. */
.rk-mt { margin-top: 1rem; }
.rk-note { font-size: 0.8rem; margin-top: 0.5rem; }
.rk-depli { cursor: pointer; font-weight: 600; }

/* ═══════════════════════════════════════════════════════════════════════════
   RANGEMENT ET STRUCTURE — 15.09.2026
   ═══════════════════════════════════════════════════════════════════════════

   ⚠ CE BLOC NE TOUCHE PAS À LA DIRECTION ARTISTIQUE, ET C'EST TOUT SON OBJET.
   Une première tentative avait remplacé la feuille entière par un « design
   system » : typographie plus petite, cartes redessinées, palette réagencée.
   Tiago l'a arrêtée le jour même — il demandait du rangement et de la
   structure, pas une autre identité. Les couleurs, les rondeurs, les ombres,
   les tailles de police et les composants d'origine sont donc INTACTS : ce
   qui suit ne corrige que des problèmes de MISE EN PAGE, et réutilise les
   classes existantes partout où elles existent déjà.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ---------- 1. La largeur perdue ----------
   .content plafonnait à 117.33rem (1760 px) et se centrait. Sur un écran de
   1920 la zone utile tombait à 1664 px, dont 60 % restaient vides. Une
   console d'exploitation doit occuper l'écran qu'on lui donne. */
.content { max-width: none; }

/* ⚠ AUCUN BLOC DE LA PAGE NE RÉTRÉCIT. .content est une colonne flex de
   hauteur fixe (elle défile), et un enfant qui porte `overflow: hidden` —
   .tableau-enveloppe, les cartes du comparatif — perd sa hauteur minimale
   automatique : sur une fenêtre basse il se tassait jusqu'à 2 px, et ce
   qu'il contenait disparaissait comme coupé au ciseau (page Sites, ligne
   dépliée ; page Plans, carte des fonctionnalités — signalé par Tiago le
   24.09.2026). Chaque bloc garde sa hauteur ; c'est .content qui défile. */
.content > * { flex-shrink: 0; }

/* ---------- 2. La tuile orpheline ----------
   .stats-grid était figée à TROIS colonnes. Quatre tuiles donnaient donc
   3 + 1 : la dernière seule sur sa ligne, large d'un tiers d'écran, avec un
   « 2 » dedans. En flex, elles se partagent la ligne quel que soit leur
   nombre — l'apparence de chaque tuile, elle, ne change pas d'un pixel. */
.stats-grid { display: flex; flex-wrap: wrap; }
.stats-grid > .stat-card { flex: 1 1 11rem; min-width: 0; }

/* ---------- 3. Les rubriques de navigation ----------
   Sept entrées à plat se lisaient comme une liste de courses. Le titre de
   rubrique reprend le registre des libellés de la console (--text-muted,
   graisse 600), en plus petit. */
.nav-groupe-titre {
    font-family: var(--sans);
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    padding: 0.9rem 1.2rem 0.3rem;
    white-space: nowrap;
}
.sidebar-nav > .nav-groupe-titre:first-child { padding-top: 0.3rem; }

/* ---------- 4. Le tableau prend la place des grilles de cartes ----------
   .data-table existe déjà et porte la D.A. : on ne la redessine pas. Il lui
   manquait seulement une enveloppe et un défilement horizontal pour les
   écrans étroits. */
.tableau-enveloppe {
    background: var(--paper);
    border: 0.1rem solid var(--line-ink);
    border-radius: var(--radius);
    overflow: hidden;
    margin-bottom: 1.2rem;
}
.tableau-defile { overflow-x: auto; }
.data-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.data-table .actions { text-align: right; white-space: nowrap; }

/* En-tête de colonne cliquable. ⚠ La flèche n'apparaît QUE sur la colonne
   active : sept flèches grises en permanence font croire que rien n'est trié. */
.data-table th a { color: inherit; display: inline-flex; align-items: center; gap: 0.25rem; }
.data-table th a:hover { color: var(--red-ink); text-decoration: none; }
.data-table th[aria-sort] a { color: var(--red-ink); font-weight: 700; }

/* ---------- 5. Deux colonnes : principal + contexte ----------
   La colonne de droite est FIXE. L'inverse ferait varier la largeur d'un
   encart de méta selon la taille de l'écran. */
.grille-duo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 21rem;
    gap: 1.2rem;
    align-items: start;
}
@media (max-width: 1100px) { .grille-duo { grid-template-columns: 1fr; } }

/* ---------- 6. Petits utilitaires ----------
   Aucun n'a d'identité propre : ils placent, ils ne décorent pas. */
.rk-row  { display: flex; align-items: center; gap: 0.5rem; }
.rk-col  { display: flex; flex-direction: column; gap: 0.5rem; }
.rk-wrap { flex-wrap: wrap; }
.rk-push { margin-left: auto; }
.rk-tronque { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rk-mono { font-family: ui-monospace, "SFMono-Regular", Consolas, monospace; font-size: 0.85em; }
.rk-visuellement-cache {
    position: absolute; width: 0.06667rem; height: 0.06667rem;
    padding: 0; margin: -0.06667rem; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Titre de carte avec ses actions à droite. */
.card-tete { display: flex; align-items: center; gap: 0.7rem; margin-bottom: 0.9rem; }
.card-tete > :last-child:not(:first-child) { margin-left: auto; }

/* Pastille d'état. ⚠ ELLE NE PORTE JAMAIS SEULE L'INFORMATION : un libellé
   l'accompagne toujours. Huit pour cent des hommes ne distinguent pas le
   rouge du vert, et « en ligne / hors ligne » est exactement ce couple-là. */
.pastille { width: 0.5rem; height: 0.5rem; border-radius: 50%; display: inline-block; flex-shrink: 0; background: var(--neutral); }
.pastille-ok     { background: var(--success); }
.pastille-alerte { background: var(--warning); }
.pastille-ko     { background: var(--danger); }

/* Bouton discret, pour les liens « Détail » et « Ouvrir » d'un tableau :
   même géométrie que les autres boutons, sans fond ni bordure. */
.btn-ghost { background: none; border-color: transparent; color: var(--text-muted); }
.btn-ghost:hover { background: var(--paper-deep); color: var(--text); }

/* Décompte de résultats, à droite de la barre de filtres. */
.compte-resultats { font-size: 0.82rem; color: var(--text-muted); white-space: nowrap; margin-left: auto; }

/* Les colonnes chiffrées ne se coupent pas en deux lignes.
   ⚠ style.css fait absorber tout l'espace restant par la PREMIÈRE colonne
   (règle « La 1re colonne absorbe l'espace restant »). Sans contrepartie, les
   colonnes de droite sont comprimées au minimum : « 1 / illimité » passait sur
   deux lignes et l'en-tête « CHF / mois » aussi. Mesuré le 15.09.2026. */
.data-table .num,
.data-table th.num,
.data-table .actions { white-space: nowrap; }
.data-table th { white-space: nowrap; }

/* ---------- 7. Liste de sites dépliable ----------
   Même grille pour l'en-tête et pour chaque ligne : les colonnes restent
   alignées sans recourir à un <table>, dont on ne peut pas faire déborder une
   ligne d'édition proprement. */
.site-entete,
.site-ligne > summary {
    display: grid;
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 1.4fr) 8rem 5rem;
    gap: 0.8rem;
    align-items: center;
    padding: 0.73333rem 1.2rem;
}
.site-entete {
    background: var(--paper-deep);
    border-bottom: 0.1rem solid var(--line-ink);
    font-size: 0.68rem;
    font-weight: 500;
    color: var(--text-muted);
}
.site-ligne { border-bottom: 0.06667rem solid var(--border); }
.site-ligne:last-child { border-bottom: 0; }
.site-ligne > summary {
    cursor: pointer;
    list-style: none;
    transition: background 0.12s;
}
.site-ligne > summary::-webkit-details-marker { display: none; }
.site-ligne > summary:hover { background: var(--red-soft); }
.site-nom { font-weight: 600; }
.site-nom small { display: block; font-weight: 400; font-size: 0.78rem; }
.site-slug { font-size: 0.85rem; color: var(--text-muted); }
.site-fin { display: flex; align-items: center; justify-content: flex-end; gap: 0.4rem; }
.site-chevron { color: var(--text-muted); transition: transform 0.15s var(--ease); }
.site-ligne[open] > summary { background: var(--paper-deep); }
.site-ligne[open] .site-chevron { transform: rotate(180deg); }

/* Le corps d'édition : légèrement en retrait, pour qu'on voie d'un coup d'œil
   qu'il appartient à la ligne ouverte au-dessus. */
.site-corps {
    padding: 1.2rem;
    border-top: 0.06667rem solid var(--border);
    background: var(--paper);
}
/* La suppression se détache du formulaire d'édition : dans le même, un appui
   sur Entrée dans un champ pourrait la déclencher. */
.site-suppr {
    margin-top: 1.2rem;
    padding-top: 0.9rem;
    border-top: 0.06667rem solid var(--border);
}
.site-suppr .btn { color: var(--danger); border-color: var(--danger-bg); }
.site-suppr .btn:hover { background: var(--danger-bg); }

@media (max-width: 820px) {
    .site-entete { display: none; }
    .site-ligne > summary { grid-template-columns: minmax(0, 1fr) 5rem; row-gap: 0.3rem; }
    .site-slug { grid-column: 1 / -1; }
}


/* Les deux colonnes ajoutées au journal d'audit. */
.audit-rang-qui {
    font-size: 0.78rem;
    color: var(--text-muted);
    text-align: left;
}
.audit-rang-d {
    font-size: 0.78rem;
    color: var(--text-muted);
    text-align: left;
}
@media (max-width: 1100px) {
    /* Sous cette largeur, le détail sort de la ligne : le tronquer à trois mots
       ne dit plus rien, et le panneau est juste en dessous. */
    .audit-rang { grid-template-columns: 5.4rem minmax(0, 1fr) minmax(0, 8rem); }
    .audit-rang-d { display: none; }
}
@media (max-width: 760px) {
    .audit-rang { grid-template-columns: 5.4rem minmax(0, 1fr); }
    .audit-rang-qui { display: none; }
}
/* ---------- 8. Comparatif des plans ----------
   La première colonne porte le nom de la caractéristique : alignée à gauche,
   dans le registre des libellés. Les autres sont des valeurs. */
.plans-comparatif th[scope="row"] {
    text-align: left;
    background: var(--paper);
    font-size: 0.82rem;
    color: var(--text);
    font-weight: 500;
    white-space: normal;
}
.plans-comparatif thead th.num a { color: var(--text); font-weight: 700; }
.plans-comparatif thead th.num a:hover { color: var(--red-ink); text-decoration: none; }
/* La colonne du plan en cours d'édition reste identifiable pendant qu'on
   compare : c'est elle qu'on modifie juste en dessous. */
.plans-comparatif .est-courant { background: var(--red-soft); }
.plans-comparatif thead th.est-courant a { color: var(--red-ink); }

/* ⚠ LARGEURS FIXES ICI, ET C'EST NÉCESSAIRE. style.css fait absorber tout
   l'espace restant par la première colonne : celle des libellés prenait 1 000
   px et les quatre plans se serraient sur la droite. Or dans un comparatif,
   ce sont les COLONNES COMPARÉES qui doivent être larges et égales. */
.plans-comparatif { table-layout: fixed; }
.plans-comparatif thead th:first-child,
.plans-comparatif th[scope="row"] { width: 20rem; }

/* ---------- 9. Fiche agence : densité ----------
   Les jauges d'usage s'empilaient en colonne unique dans une carte pleine
   largeur : quatre lignes de barre, et les trois quarts de la carte vides.
   Deux colonnes dès qu'il y a la place. */
/* ⚠ DEUX COLONNES, PAS « auto-fit ». Avec auto-fit la carte en produisait
   QUATRE sur un grand ecran, et chaque jauge s'etirait : son libelle et sa
   valeur, separes par un space-between, se retrouvaient a 300 px l'un de
   l'autre. Une jauge se lit d'un coup d'oeil ou ne se lit pas. */
.uv { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.9rem 2.5rem; }
@media (max-width: 700px) { .uv { grid-template-columns: 1fr; } }

/* Le slug du site dans le rail : il se tronque plutot que de passer a la
   ligne, la colonne ne faisant que 20rem. */
.fa-kv .v a { overflow-wrap: normal; }

/* ⚠ UNE JAUGE A UNE LARGEUR MAXIMALE. .rk-usage-head sépare son libellé et sa
   valeur par un space-between — règle écrite pour une carte étroite. Dans une
   colonne de 590 px, « Utilisateurs » et « 5 / illimité » se retrouvaient aux
   deux bouts, et l'œil devait traverser le vide pour relier les deux. */
.uv > * { max-width: 26rem; }

/* ═══════════════════════════════════════════════════════════════════════════
   SURVOL : LE BON JETON SUR LA BONNE SURFACE — 15.09.2026
   ═══════════════════════════════════════════════════════════════════════════

   Signalé par Tiago : « cet effet hover gris sur gris faut arrêter ». Il avait
   raison, et ce n'était pas une affaire de goût mais une erreur de jeton.

   style.css déclare deux teintes, et leur commentaire d'origine dit tout :

     --red-soft: #E6D6D3   « tint rouge doux SUR LA PLAQUE GRISE »
     --red-tint: #FBEEEC   « rouge TRÈS pâle : le fond d'un élément actif.
                             Assez présent pour se voir SUR DU BLANC. »

   Or `--red-soft` sert de fond au survol dans 29 règles, y compris sur des
   lignes de tableau BLANCHES. Une teinte calculée pour se détacher du gris de
   la page, posée sur du blanc, ne se lit plus comme une surbrillance : elle se
   lit comme de la saleté. C'est exactement ce qu'on voyait sur la liste des
   agences.

   ⚠ ON NE TOUCHE PAS À style.css. C'est la copie de la feuille de RedDesk, et
   la modifier creuserait l'écart entre les deux — la maladie qui a déjà coûté
   iselect.js et l'œil de l'écran de connexion. On corrige ici, dans la feuille
   de Control, et uniquement pour les surfaces que Control affiche vraiment.
   Les 20 autres règles concernent des écrans de RedDesk (l'éditeur de PDF, la
   galerie, la messagerie) que cette console ne montre jamais.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Lignes de tableau — posées sur du blanc. */
.data-table tbody tr:hover { background: var(--red-tint); }

/* Options d'un sélecteur à icônes — menu blanc. */
.iselect-opt:hover { background: var(--red-tint); }

/* Liste des plans, et lignes de la page Sites — cartes blanches. */
.pd-item:hover { background: var(--red-tint); }
/* ⚠ LE PLAN SÉLECTIONNÉ GARDE SON FOND AU SURVOL. La règle ci-dessus pèse
   autant que .pd-item.is-active et vient après : survolé, le plan choisi
   passait en rose pâle sous un texte blanc — illisible (signalé par Tiago le
   24.09.2026). Le texte suit --red-on, qui reste lisible quelle que soit la
   couleur d'accent choisie dans Réglages. */
.pd-item.is-active:hover { background: var(--red-hover); }
.pd-item.is-active .pd-item-name,
.pd-item.is-active .pd-item-sub,
.pd-item.is-active .pd-item-price { color: var(--red-on); }
.site-ligne > summary:hover { background: var(--red-tint); }

/* Bouton au trait : son fond est blanc, pas la plaque. */
.btn-outline:hover { background: var(--red-tint); }

/* ⚠ LA LIGNE SÉLECTIONNÉE DOIT RESTER PLUS MARQUÉE QUE LA LIGNE SURVOLÉE.
   Sinon on ne sait plus laquelle on regarde et laquelle on a choisie. Le
   journal d'audit garde donc --danger-bg pour `.is-on` et n'emprunte le
   survol qu'aux lignes non sélectionnées. */
.audit-rang:hover { background: var(--red-tint); }
.audit-rang.is-on:hover { background: var(--danger-bg); }

/* ⚠ DEUX CLASSES DANS CES SÉLECTEURS, ET C'EST NÉCESSAIRE.
   style.css pose `.btn:not(.lg-btn) { background: var(--paper) }` — soit
   (0,2,0) — et `.btn:not(.lg-btn):hover { background: var(--paper-deep) }`,
   soit (0,3,0). Un `.btn-ghost` (0,1,0) ou un `.btn-outline:hover` (0,2,0) ne
   pèsent pas assez : ils ne s'appliquaient JAMAIS.

   Conséquences visibles, constatées le 15.09.2026 sur la maquette : le bouton
   « Ouvrir » d'un tableau sortait en pastille BLANCHE sur la ligne survolée —
   c'est ce qui se voyait sur la capture de Tiago — et tous les boutons au
   trait viraient au gris au survol au lieu de prendre la teinte de marque.

   Le dépôt connaît déjà ce piège : style.css le commente pour
   `.prop-card-map-btn` et `.confirm-actions .btn`, avec la même explication. */
.btn.btn-ghost {
    background: none;
    border-color: transparent;
    color: var(--text-muted);
}
.btn.btn-ghost:hover { background: var(--red-tint); color: var(--red-ink); }
.btn.btn-outline:hover { background: var(--red-tint); border-color: var(--red); color: var(--red-ink); }

/* ═══════════════════════════════════════════════════════════════════════════
   PORTEFEUILLE D'AGENCES — 15.09.2026
   ═══════════════════════════════════════════════════════════════════════════
   Version C, choisie par Tiago sur maquette. Une fiche par agence, mais DENSE :
   rien à voir avec les anciennes cartes, qui portaient quatre chiffres dans
   beaucoup de vide. Chacune montre ce qui décide d'une action — consommation,
   site, alerte — et porte ses raccourcis.

   ⚠ AUCUNE COULEUR NOUVELLE. Tout vient des jetons existants. Ce bloc place
   et espace ; il ne redécore pas.

   ⚠ LIMITE CONNUE ET ASSUMÉE. Une grille de fiches tient jusqu'à une douzaine
   d'agences ; au-delà elle devient un mur. Control en compte deux. Le jour où
   la liste dépasse la quinzaine, c'est la version tableau qu'il faudra
   reprendre — sa maquette est archivée dans /srv/maquettes/control-agences/.
   ═══════════════════════════════════════════════════════════════════════════ */

.portefeuille {
    display: grid;
    /* auto-fill et non auto-fit : à deux agences, deux fiches de 21rem plutôt
       que deux fiches étirées sur toute la largeur de l'écran. */
    grid-template-columns: repeat(auto-fill, minmax(21rem, 1fr));
    gap: 1.2rem;
}

.pf-carte {
    background: var(--paper);
    border: 0.1rem solid transparent;
    border-radius: var(--radius);
    padding: 1.06667rem 1.2rem 1.2rem;
    display: flex;
    flex-direction: column;
}
/* Une agence en tension se repère à sa bordure, SANS lire un seul chiffre.
   C'est tout l'intérêt de cette vue par rapport au tableau. */
.pf-carte.est-warning { border-color: var(--warning); }
.pf-carte.est-danger  { border-color: var(--danger); }
/* Une agence suspendue s'efface sans disparaître : elle ne facture plus, mais
   elle reste dans la liste et on doit pouvoir la rouvrir. */
.pf-carte.est-suspendue { opacity: 0.72; }
.pf-carte.est-suspendue:hover { opacity: 1; }

.pf-tete {
    display: flex; align-items: center; justify-content: space-between;
    gap: 0.6rem; margin-bottom: 0.5rem;
}
.pf-nom { margin: 0; font-family: var(--serif); font-size: 1rem; font-weight: 700; }
.pf-nom a { color: var(--text); }
.pf-nom a:hover { color: var(--red-ink); text-decoration: none; }
.pf-meta {
    font-size: 0.8rem; color: var(--text-muted);
    margin: 0.1rem 0 0.9rem; overflow-wrap: anywhere;
}

.pf-jauges { display: flex; flex-direction: column; gap: 0.6rem; margin-bottom: 0.9rem; }
.pf-alerte { font-size: 0.78rem; padding: 0.35rem 0.6rem; margin-bottom: 0.8rem; }

.pf-lignes { margin-top: auto; }
.pf-lignes .fa-kv { padding: 0.35rem 0; font-size: 0.84rem; }
.pf-lignes .fa-kv:last-child { border-bottom: 0; }

.pf-actions {
    display: flex; gap: 0.4rem; flex-wrap: wrap;
    margin-top: 0.9rem; padding-top: 0.8rem;
    border-top: 0.06667rem solid var(--border);
}

/* Le sélecteur de tri et son bouton de sens se collent : ils forment un seul
   réglage, et un espace entre eux les ferait lire comme deux. */
.acc-toolbar .btn-outline.btn-sm { padding: 0 0.6rem; min-height: 2.375rem; }

/* ---------- Barre d'outils : filtres + création + décompte ----------
   ⚠ UNE ENVELOPPE, PARCE QU'IL Y A DEUX FORMULAIRES. Les filtres sont un
   <form method="get"> et la création un <form method="post"> : HTML interdit
   de les imbriquer, et les navigateurs cassent le second en silence. Cette
   enveloppe flex les pose sur la même ligne sans les emboîter. */
.acc-barre {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.8rem;
    margin-bottom: 1.2rem;
}
/* ⚠ display: contents SUR LE FORMULAIRE, ET C'EST LA CLÉ DE TOUTE LA BARRE.
   En simple élément flex, le <form> se dimensionnait sur son propre contenu
   puis se repliait tout seul : le sélecteur de tri sautait à la ligne pendant
   que le bouton de création flottait au milieu du vide. Constaté le
   15.09.2026, premier essai.

   `display: contents` fait disparaître la BOÎTE du formulaire sans toucher au
   formulaire : ses champs deviennent des enfants directs de l'enveloppe et
   s'alignent avec le bouton et le décompte, tout en continuant d'être soumis
   ensemble. C'est exactement ce à quoi cette propriété sert. */
.acc-barre > .acc-toolbar { display: contents; }
.acc-barre > .compte-resultats { margin-left: auto; padding-bottom: 0.6rem; }

/* Création d'agence : un bouton qui déplie une carte.
   ⚠ list-style + ::marker + ::-webkit-details-marker : les trois sont
   nécessaires pour faire disparaître le triangle du <summary> selon le
   navigateur. Sans eux, le bouton porte une flèche noire à sa gauche. */
.creer-agence > summary { cursor: pointer; list-style: none; width: fit-content; }
.creer-agence > summary::marker { content: ''; }
.creer-agence > summary::-webkit-details-marker { display: none; }
.creer-agence > form { margin: 0; }

/* ⚠ FERMÉ, IL TIENT SA PLACE DANS LA LIGNE ; OUVERT, IL PREND LA SIENNE.
   `flex-basis: 100%` le fait passer sur une ligne à lui seul, et `order`
   l'envoie APRÈS le décompte — sinon la carte dépliée s'insérerait entre les
   filtres et les chiffres, qui sauteraient à la ligne suivante. */
.creer-agence[open] { flex-basis: 100%; order: 9; }
.creer-agence[open] > summary { margin-bottom: 0.8rem; }

/* ---------- 10. La rondeur manquante ----------
   ⚠ .pd-item ÉTAIT LA SEULE SURFACE À ANGLES VIFS DE TOUTE LA CONSOLE.
   Signalé par Tiago le 15.09.2026 : « c'est bizarre que tout soit légèrement
   arrondi mais pas les 4 cards des plans ». Vérifié en mesurant le
   border-radius calculé de chaque élément visible des huit écrans — la liste
   des plans sortait seule. Les autres surfaces signalées par la mesure
   (.audit-rang, .site-entete, .fa-kv, .pf-actions) sont des LIGNES à
   l'intérieur d'un conteneur déjà arrondi, qui les rogne : les arrondir
   individuellement produirait des angles dans les angles.

   Une seule rondeur pour tout, c'est la règle posée par style.css : « l'ancien
   système en avait deux et l'écart se voyait dès qu'un bouton touchait une
   carte ». Un item carré au milieu de cartes arrondies est le même défaut. */
.pd-item { border-radius: var(--radius); }

/* Le lien d'évitement flotte au-dessus de la page quand il reçoit le focus :
   il est une pastille, pas un bandeau. */
.skip-link { border-radius: var(--radius); }

/* ═══════════════════════════════════════════════════════════════════════════
   FICHE AGENCE : EN-TÊTE ET CHRONOLOGIE — 15.09.2026
   ═══════════════════════════════════════════════════════════════════════════
   Version D, choisie par Tiago sur maquette. La fiche montrait l'état PRÉSENT
   et jamais le chemin parcouru ; elle raconte désormais ce qui s'est passé.

   ⚠ AUCUNE COULEUR NOUVELLE. Tout vient des jetons existants.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Les actions montent dans l'en-tête. Elles étaient en bas d'un rail de
   droite, à deux écrans de défilement du nom de l'agence. */
.fiche-entete {
    display: flex; align-items: flex-start; gap: 1.2rem;
    flex-wrap: wrap; margin-bottom: 1.2rem;
}
.fiche-titre {
    margin: 0; font-family: var(--serif); font-size: 1.5rem;
    display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
}
.fiche-sous { margin: .3rem 0 0; font-size: .86rem; }
/* ⚠ CE SONT DES FORMULAIRES, PAS DES LIENS. Suspendre et réinitialiser sont
   des POST : chacun est un <form> à part, sans quoi un appui sur Entrée
   quelque part déclencherait le premier bouton de la page. D'où le flex ici
   plutôt qu'un simple espacement de boutons. */
.fiche-actions { margin-left: auto; display: flex; gap: .5rem; flex-wrap: wrap; }
.fiche-actions form { margin: 0; }

/* ---------- Chronologie ---------- */
.chrono { display: flex; flex-direction: column; }
.chrono-item {
    display: flex; align-items: flex-start; gap: .7rem;
    padding: .6rem 0; border-bottom: .06667rem solid var(--border);
}
.chrono-item:last-child { border-bottom: 0; }
.chrono-pastille {
    width: 1.7rem; height: 1.7rem; flex-shrink: 0;
    display: grid; place-items: center; border-radius: 50%;
    background: var(--paper-deep); color: var(--text-muted); font-size: .85rem;
}
/* Trois tons seulement, et jamais seuls : le libellé dit toujours ce qui
   s'est passé. La couleur accélère la lecture, elle ne la porte pas. */
.chrono-pastille.est-success { background: var(--success-bg); color: var(--success); }
.chrono-pastille.est-warning { background: var(--warning-bg); color: var(--warning); }
.chrono-pastille.est-danger  { background: var(--danger-bg);  color: var(--danger); }
.chrono-quoi { font-size: .88rem; font-weight: 600; }
.chrono-detail { font-size: .8rem; overflow-wrap: anywhere; }
.chrono-date { margin-left: auto; font-size: .78rem; white-space: nowrap; padding-left: .5rem; }

@media (max-width: 620px) {
    .fiche-actions { margin-left: 0; width: 100%; }
    .fiche-actions .btn { width: 100%; }
}

/* ------------------------------------------------------------------ *
 * 12. LA FICHE D'UNE AGENCE — barre contextuelle et liste d'accès
 *
 * Ce bloc ne touche pas à la direction artistique : mêmes couleurs, mêmes
 * rayons, mêmes boutons. Il range.
 * ------------------------------------------------------------------ */

/* ---- La barre du haut porte l'agence (variante B) ----
   Le nom n'est plus écrit deux fois : la barre l'annonce, la page ne le
   répète plus. Les actions y restent atteignables au défilement, la barre
   étant déjà `position: sticky`. */
.tb-ctx { display: flex; align-items: center; gap: .5rem; min-width: 0; }
/* ⚠ SANS CECI, LE TITRE MANGE TOUTE LA BARRE : .topbar-title porte flex: 1
   dans style.css, ce qui repousserait badges et actions hors de l'écran. */
.tb-ctx .topbar-title { flex: 0 1 auto; }
.tb-ctx .badge { flex: none; }

.tb-retour {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2rem; height: 2rem; flex: none;
    border: 0.1rem solid var(--border); border-radius: var(--radius);
    background: var(--card-bg, #fff); color: var(--text-muted);
}
.tb-retour:hover { color: var(--red); border-color: var(--red); }

.tb-actions { display: flex; align-items: center; gap: .4rem; margin-left: auto; }
.tb-actions form { margin: 0; }

/* La barre a une hauteur fixe : rien ne peut y passer à la ligne. Sous
   1200 px on garde les icônes et on retire les mots — chaque bouton porte
   déjà son `title`. */
@media (max-width: 1200px) {
    .tb-lbl { position: absolute; width: 0.1rem; height: 0.1rem; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
    /* ⚠ SAUF LA DESTRUCTRICE. « Suspendre » coupe la connexion de toute une
       agence : c'est precisement l'action qui ne doit pas se retrouver reduite
       a un pictogramme rouge, indiscernable des deux voisines au premier coup
       d'oeil. Elle garde son mot a toutes les largeurs. */
    .tb-actions .btn-danger .tb-lbl,
    .tb-actions .btn-primary .tb-lbl {
        position: static; width: auto; height: auto; clip-path: none;
    }
}
@media (max-width: 480px) {
    .tb-ctx .badge { display: none; }
}

/* ---- La liste des accès (variante D) ---- */
.u-outils { display: flex; gap: .4rem; margin-left: auto; }

.u-liste { display: flex; flex-direction: column; }
.u-ligne {
    display: flex; align-items: center; gap: .8rem;
    padding: .55rem .3rem; border-bottom: 0.1rem solid var(--border);
}
.u-ligne:last-child { border-bottom: 0; }
/* ⚠ --red-tint ET NON --red-soft : --red-soft est prévu pour la plaque grise,
   et donne un gris-sur-gris illisible sur une carte blanche. */
.u-ligne:hover { background: var(--red-tint); }

.u-ini {
    flex: none; width: 2.1rem; height: 2.1rem; border-radius: 50%;
    background: var(--red-tint); color: var(--red);
    display: flex; align-items: center; justify-content: center;
    font-size: .76rem; font-weight: 600;
}
.u-qui { min-width: 0; flex: 1 1 auto; }
.u-nom { font-weight: 600; font-size: .9rem; }
.u-id  { font-size: .78rem; color: var(--text-muted); }
.u-actes { display: flex; gap: .35rem; flex: none; }

/* ---- Les volets de création / rattachement ----
   Ouverts par :target, sans une ligne de JavaScript. */
.u-volet { display: none; margin-top: 1rem; padding-top: .9rem; border-top: 0.1rem solid var(--border); }
.u-volet:target, .u-volet.est-ouvert { display: block; }
/* La barre du haut est collante : sans cette marge, le volet visé se range
   dessous et on croit que le clic n'a rien fait. */
.u-volet { scroll-margin-top: 6rem; }
.u-volet-tete { display: flex; align-items: center; gap: .6rem; margin-bottom: .7rem; }

@media (max-width: 620px) {
    .u-ligne { flex-wrap: wrap; }
    .u-actes { width: 100%; }
    .u-outils { width: 100%; margin-left: 0; }
    .u-outils .btn { flex: 1 1 auto; }
}

/* La photo d'agence du mini CMS : une vignette qui se regarde, pas un lien à
   deviner. ⚠ Hauteur bornée et object-fit : une photo verticale déposée telle
   quelle poussait le formulaire sur trois écrans. */
.site-illu { display: flex; align-items: flex-start; gap: 1rem; margin-bottom: .6rem; }
.site-illu img {
  width: 160px; height: 110px; object-fit: cover;
  border: 1px solid var(--line, #d9d9d9); border-radius: 4px; background: var(--paper, #fff);
}
.site-illu-retirer { display: flex; align-items: center; gap: .4rem; font-size: .875rem; }
.site-illu-retirer input { width: auto; }

/* Le champ de dépôt : le bouton natif porte un texte imposé par le navigateur
   (« Choose File »), que le CSS ne sait pas changer. On l'escamote et on passe
   par son <label>.
   ⚠ PAS display:none NI visibility:hidden : le champ doit rester focalisable au
   clavier et annonçable par un lecteur d'écran. Il est réduit à un point, pas
   retiré de la page. */
.rk-fichier { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
.rk-fichier input[type="file"] {
  position: absolute; width: 1px; height: 1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.rk-fichier label { cursor: pointer; margin: 0; }
/* Le champ escamoté ne peut pas porter son propre halo de focus : c'est le
   label qui le montre, sans quoi la navigation au clavier devient invisible. */
.rk-fichier input[type="file"]:focus-visible + label {
  outline: 2px solid var(--red, #c1121f); outline-offset: 2px;
}

/* ------------------------------------------------------------------
 * 13. LA CONSOLE À SA MAIN — 24.09.2026
 *
 * Ce bloc ne touche pas à la direction artistique : il reprend les jetons,
 * les rayons, les boutons et les cartes existants. Il place les outils de
 * personnalisation (menu, tableau de bord, palette) et les cache quand on
 * ne s'en sert pas.
 * ------------------------------------------------------------------ */

/* ---- Menu : rubriques repliables ----
   Le titre de rubrique devient un bouton. Il garde exactement l'allure de
   l'ancien titre (petites capitales grises) ; seul un chevron discret dit
   qu'il se replie. */
.sidebar-nav .nav-groupe { display: flex; flex-direction: column; gap: var(--pile-liste); }
.sidebar-nav .nav-groupe-liens { display: flex; flex-direction: column; gap: var(--pile-liste); }
button.nav-groupe-titre {
    display: flex; align-items: center; gap: 0.4rem; width: 100%;
    background: none; border: 0; cursor: pointer; text-align: left;
    border-radius: var(--radius);
}
button.nav-groupe-titre:hover { color: var(--text); }
button.nav-groupe-titre:focus-visible { outline: 2px solid var(--red); outline-offset: -2px; }
.nav-groupe-chevron { margin-left: auto; font-size: 0.8rem; opacity: 0; transition: opacity 0.15s, transform 0.15s var(--ease); }
button.nav-groupe-titre:hover .nav-groupe-chevron,
button.nav-groupe-titre:focus-visible .nav-groupe-chevron,
.nav-groupe.est-replie .nav-groupe-chevron { opacity: 1; }
.nav-groupe.est-replie .nav-groupe-chevron { transform: rotate(-90deg); }
.nav-groupe.est-replie .nav-groupe-liens { display: none; }
.sidebar-nav .nav-groupe:first-child .nav-groupe-titre { padding-top: 0.3rem; }
div.nav-groupe-titre { display: flex; align-items: center; gap: 0.4rem; }

/* ---- Menu : entrées, épinglées, masquées ---- */
.nav-item { position: relative; display: flex; align-items: center; }
.nav-item > .nav-link { flex: 1; min-width: 0; }
.nav-outils { display: none; gap: 0.15rem; padding-left: 0.2rem; }
.nav-outil {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.8rem; height: 1.8rem; border: 0; border-radius: var(--radius);
    background: transparent; color: var(--text-muted); cursor: pointer;
}
.nav-outil:hover { background: var(--paper-deep); color: var(--red-ink); }
.nav-outil[aria-pressed="true"] { color: var(--red-ink); }
.nav-outil:focus-visible { outline: 2px solid var(--red); outline-offset: 1px; }

/* Hors réglage : une entrée masquée disparaît, une rubrique vide aussi. */
.sidebar:not(.est-perso) .nav-item.est-masque:not(:has(.nav-link.active)) { display: none; }
.sidebar:not(.est-perso) .nav-groupe.est-vide { display: none; }

/* Pendant le réglage : les outils apparaissent, tout est déplié, et une
   entrée masquée se voit en retrait pour qu'on puisse la rendre. */
.sidebar.est-perso .nav-outils { display: inline-flex; }
.sidebar.est-perso .nav-groupe-liens { display: flex !important; }
.sidebar.est-perso .nav-item.est-masque > .nav-link { opacity: 0.45; text-decoration: line-through; }

/* Le bouton « Personnaliser le menu » : une icône au bout de la ligne du nom. */
.sidebar-perso { margin-left: auto; flex: none; }
.sidebar.est-perso .sidebar-perso { background: var(--red-tint); color: var(--red-ink); }

/* L'aide du réglage, en tête du menu. */
.nav-perso-aide { display: none; }
.sidebar.est-perso .nav-perso-aide {
    display: flex; flex-direction: column; gap: 0.6rem;
    padding: 0.8rem 0.9rem; margin-bottom: 0.4rem;
    border-radius: var(--radius); background: var(--paper-deep);
}
.nav-perso-aide p { margin: 0; font-size: 0.78rem; line-height: 1.5; color: var(--text-muted); }
.nav-perso-aide p i { color: var(--text); }
.nav-perso-aide .btn { align-self: flex-start; }

/* Un lien du menu reste sur une ligne : l'icône à gauche, le libellé tronqué. */
.nav-item > .nav-link { display: flex; align-items: center; min-width: 0; }
.nav-item > .nav-link span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- Barre du haut : raccourci clavier et loupe ---- */
.topbar-kbd {
    position: absolute; right: 0.55rem;
    font-family: var(--sans); font-size: 0.68rem; font-weight: 600;
    color: var(--text-muted); background: var(--paper);
    border: 0.06667rem solid var(--border); border-radius: 0.3rem;
    padding: 0.05rem 0.35rem; pointer-events: none;
}
.topbar-search input { padding-right: 3.6rem; }
.topbar-loupe { display: none; margin-left: auto; }
@media (max-width: 640px) {
    .topbar-loupe:not([hidden]) { display: inline-flex; }
}

/* ---- Palette de commandes ---- */
.rk-palette {
    width: min(38rem, calc(100vw - 2rem));
    max-height: min(32rem, calc(100vh - 6rem));
    margin: 12vh auto auto;
    padding: 0;
    border: 0.06667rem solid var(--border);
    border-radius: var(--radius);
    background: var(--paper);
    color: var(--text);
    box-shadow: 0 1.2rem 3rem rgba(16, 24, 40, 0.22);
    overflow: hidden;
}
.rk-palette[open] { display: flex; flex-direction: column; }
.rk-palette::backdrop { background: rgba(16, 24, 40, 0.35); }
.rk-palette-tete {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.8rem 1rem; border-bottom: 0.06667rem solid var(--border);
}
.rk-palette-tete > i { color: var(--text-muted); }
.rk-palette-champ {
    flex: 1; min-width: 0; border: 0; background: transparent; color: var(--text);
    font: inherit; font-size: 1rem; padding: 0.3rem 0;
}
.rk-palette-champ:focus { outline: none; }
/* ⚠ (0,2,1) exprès : la règle générale des champs (hauteur 44 px, filet,
   halo au focus) pèse (0,1,1). Ici le champ EST la tête de la palette. */
.rk-palette input.rk-palette-champ,
.rk-palette input.rk-palette-champ:focus {
    height: auto; border: 0; box-shadow: none; background: transparent; padding: 0.3rem 0;
}
.rk-palette kbd, .dash-astuce kbd {
    font-family: var(--sans); font-size: 0.68rem; font-weight: 600;
    color: var(--text-muted); background: var(--paper-deep);
    border: 0.06667rem solid var(--border); border-radius: 0.3rem;
    padding: 0.05rem 0.35rem;
}
.rk-palette-liste { overflow-y: auto; padding: 0.4rem; flex: 1; }
.rk-palette-groupe {
    font-size: 0.68rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--text-muted); padding: 0.6rem 0.7rem 0.25rem;
}
.rk-palette-item {
    display: flex; align-items: center; gap: 0.75rem; width: 100%;
    padding: 0.55rem 0.7rem; border: 0; border-radius: var(--radius);
    background: transparent; color: var(--text); cursor: pointer; text-align: left;
    font: inherit;
}
.rk-palette-item > i { width: 1.2rem; text-align: center; color: var(--text-muted); flex: none; }
.rk-palette-item.is-on { background: var(--red-tint); }
.rk-palette-item.is-on > i, .rk-palette-item.is-on .rk-palette-t { color: var(--red-ink); }
.rk-palette-txt { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.rk-palette-t { font-size: 0.9rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rk-palette-s { font-size: 0.76rem; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rk-palette-g { font-size: 0.72rem; color: var(--text-muted); flex: none; }
.rk-palette-vide { padding: 1rem; margin: 0; color: var(--text-muted); font-size: 0.86rem; }
.rk-palette-pied {
    display: flex; gap: 1.2rem; flex-wrap: wrap;
    padding: 0.55rem 1rem; border-top: 0.06667rem solid var(--border);
    font-size: 0.74rem; color: var(--text-muted); background: var(--paper-deep);
}
@media (max-width: 640px) {
    .rk-palette { margin-top: 1rem; max-height: calc(100vh - 2rem); }
    .rk-palette-pied { display: none; }
}

/* ---- Bandeau « Enregistré » ---- */
.rk-bandeau {
    position: fixed; left: 50%; bottom: 1.4rem; z-index: 200;
    transform: translate(-50%, 1rem); opacity: 0; pointer-events: none;
    background: var(--text); color: var(--paper);
    padding: 0.55rem 1rem; border-radius: var(--radius);
    font-size: 0.86rem; font-weight: 500;
    box-shadow: 0 0.6rem 1.6rem rgba(16, 24, 40, 0.25);
    transition: opacity 0.18s, transform 0.18s var(--ease);
    max-width: calc(100vw - 2rem);
}
.rk-bandeau.est-visible { opacity: 1; transform: translate(-50%, 0); }
.rk-bandeau.est-erreur { background: var(--danger); color: #fff; }

/* ---- Tableau de bord à la carte ---- */
.dash-outils { display: none; }
.dash-tuile-oeil { display: none; }
.dash-carte:not(.est-perso) .dash-bloc.est-masque,
.dash-carte:not(.est-perso) [data-tuile].est-masque { display: none; }

.dash-carte.est-perso .dash-bloc {
    outline: 0.1rem dashed var(--border-strong);
    outline-offset: 0.2rem;
}
.dash-carte.est-perso .dash-bloc[draggable="true"] { cursor: grab; }
.dash-carte.est-perso .dash-bloc.est-glisse { opacity: 0.5; }
.dash-carte.est-perso .dash-outils {
    display: flex; align-items: center; gap: 0.5rem;
    margin: -0.3rem 0 0.9rem; padding-bottom: 0.6rem;
    border-bottom: 0.06667rem solid var(--border);
}
.dash-poignee { color: var(--text-muted); }
.dash-outils-titre { font-size: 0.8rem; font-weight: 600; color: var(--text-muted); display: inline-flex; align-items: center; gap: 0.35rem; min-width: 0; }
.dash-outils-btns { display: inline-flex; gap: 0.3rem; margin-left: auto; }
.dash-outils-btns .card-icon-btn { width: 2rem; height: 2rem; font-size: 0.85rem; }
.dash-outils-btns [aria-pressed="true"] { color: var(--red-ink); }
/* Un bloc masqué, pendant le réglage : son en-tête seul, en retrait. */
.dash-carte.est-perso .dash-bloc.est-masque { opacity: 0.55; }
.dash-carte.est-perso .dash-bloc.est-masque .dash-outils { margin-bottom: -0.3rem; border-bottom: 0; padding-bottom: 0; }
/* Une colonne vide doit rester une cible de dépôt. */
.dash-carte.est-perso .dash-col { min-height: 6rem; }

.dash-carte.est-perso [data-tuile] { position: relative; }
.dash-carte.est-perso .dash-tuile-oeil {
    /* À la place de l'icône décorative (en haut à droite), jamais sur le texte. */
    display: inline-flex; position: absolute; right: 0.6rem; top: 0.6rem;
    width: 2rem; height: 2rem; font-size: 0.85rem;
}
.dash-carte.est-perso [data-tuile].est-masque { opacity: 0.45; }
.dash-carte.est-perso [data-tuile].est-masque .dash-tuile-oeil { color: var(--red-ink); }
/* Sur la carte, l'icône décorative laisse la place à l'œil. */
.dash-carte.est-perso [data-tuile] .stat-icon { visibility: hidden; }

/* Raccourcis : une grille de boutons à deux colonnes, sans orphelin. */
.dash-raccourcis { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
.dash-raccourci {
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.6rem 0.7rem; border-radius: var(--radius);
    background: var(--paper-deep); color: var(--text);
    font-size: 0.84rem; font-weight: 500;
}
.dash-raccourci i { color: var(--red-ink); }
.dash-raccourci span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dash-raccourci-large { grid-column: 1 / -1; }
.dash-raccourci:hover { background: var(--red-tint); color: var(--red-ink); text-decoration: none; }
.dash-astuce { font-size: 0.78rem; margin: 0.8rem 0 0; }
.dash-agences td { vertical-align: middle; }
/* ⚠ minmax(0, 1fr), PAS 1fr. Une piste « 1fr » ne descend pas sous la largeur
   de son contenu : le tableau des agences élargissait toute la colonne, et
   sur téléphone chaque carte sortait de l'écran par la droite — sans barre
   de défilement, .content cachant ce qui déborde. */
.dash-grille > .dash-col { min-width: 0; }
@media (max-width: 1100px) { .dash-grille { grid-template-columns: minmax(0, 1fr); } }

/* ---- Page Réglages ---- */
.reglages-duo { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1.2rem; }
@media (max-width: 620px) { .reglages-duo { grid-template-columns: 1fr; } }
.reglages-erreur { color: var(--danger); font-size: 0.8rem; }
.reglages-logo { display: flex; align-items: center; gap: 1rem; margin-bottom: 0.4rem; }
.reglages-logo-cadre { width: 3.6rem; height: 3.6rem; flex: none; }
.reglages-logo-cadre .sidebar-logo { width: 100%; height: 100%; object-fit: contain; }

/* Les teintes : une grille régulière, chaque pastille avec son nom dessous.
   Le bouton radio reste dans le flux (clavier, lecteur d'écran) mais c'est
   la pastille qu'on voit ; l'anneau dit laquelle est choisie. */
.reglages-teintes {
    border: 0; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(auto-fill, minmax(4.6rem, 1fr)); gap: 0.8rem 0.5rem;
}
.reglages-teinte { display: flex; flex-direction: column; align-items: center; gap: 0.35rem; cursor: pointer; }
.reglages-teinte input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.reglages-pastille {
    width: 2.4rem; height: 2.4rem; border-radius: 50%;
    box-shadow: 0 0 0 0.2rem var(--paper), 0 0 0 0.3rem transparent;
    display: inline-flex; align-items: center; justify-content: center;
    transition: box-shadow 0.15s var(--ease);
}
.reglages-pastille-libre { background: var(--paper-deep); color: var(--text-muted); border: 0.06667rem dashed var(--border-strong); }
.reglages-teinte input:checked + .reglages-pastille { box-shadow: 0 0 0 0.2rem var(--paper), 0 0 0 0.33rem var(--text); }
.reglages-teinte input:focus-visible + .reglages-pastille { outline: 2px solid var(--text); outline-offset: 5px; }
.reglages-teinte-nom { font-size: 0.74rem; color: var(--text-muted); text-align: center; }
.reglages-teinte input:checked ~ .reglages-teinte-nom { color: var(--text); font-weight: 600; }
.reglages-pick { width: 2.9rem; height: 2.9rem; padding: 0.15rem; border-radius: var(--radius); border: 0.06667rem solid var(--border-strong); background: var(--paper); cursor: pointer; }

.reglages-apercu-marque { display: flex; align-items: center; gap: 0.7rem; padding-bottom: 0.9rem; border-bottom: 0.06667rem solid var(--border); margin-bottom: 0.9rem; }
.reglages-apercu-marque .sidebar-logo-wrap { width: 2.4rem; height: 2.4rem; }
.reglages-apercu-marque .sidebar-logo { width: 100%; height: 100%; object-fit: contain; }
.reglages-apercu-lien {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.6rem 0.8rem; border-radius: var(--radius);
    background: var(--red-tint); color: var(--red-ink); font-weight: 600; font-size: 0.9rem;
}
.reglages-apercu .btn-primary { background: var(--red); border-color: var(--red); pointer-events: none; }
.reglages-apercu-chiffre { font-family: var(--serif); font-weight: 700; font-size: 1.6rem; color: var(--red); margin-left: auto; }

/* ---- Page Plans : création, copie, archive ---- */
/* Nom, prix, modèle et bouton sur UNE rangée, bords bas alignés : le bouton
   tombe sur la ligne des champs, pas sur celle de leurs libellés. */
.plan-nouveau-form {
    display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1.2fr) auto;
    gap: 0 1rem; align-items: end;
}
.plan-nouveau-form .rk-field { margin-bottom: 0; }
@media (max-width: 900px) {
    .plan-nouveau-form { grid-template-columns: 1fr 1fr; gap: 1rem; }
    .plan-nouveau-btn { grid-column: 1 / -1; }
}
@media (max-width: 560px) { .plan-nouveau-form { grid-template-columns: 1fr; } }
.plan-outils { display: flex; align-items: center; gap: 0.5rem; margin-left: auto; flex-wrap: wrap; justify-content: flex-end; }
.pd-item.est-archive:not(.is-active) { opacity: 0.6; }

/* ---- Fiche agence : options par-dessus le plan ----
   Le rail est étroit : libellé au-dessus, contrôle pleine largeur, même bord
   gauche pour tout. Une exception se signale par son libellé en couleur
   d'accent, pas par un cadre de plus. */
.opt-form { display: flex; flex-direction: column; gap: 0.5rem; }
/* Libellé à gauche, contrôle à droite, largeur fixe : toutes les listes
   tombent sur le même bord, quelle que soit la longueur du libellé. */
.opt-ligne { display: grid; grid-template-columns: minmax(0, 1fr) 7.9rem; align-items: center; gap: 0.6rem; }
/* La coche se cale sur la PREMIÈRE ligne du libellé, pas sur le milieu d'un
   libellé qui passerait sur deux lignes. */
.opt-lib { display: flex; align-items: flex-start; gap: 0.45rem; font-size: 0.84rem; line-height: 1.35; font-weight: 500; color: var(--text); min-width: 0; }
.opt-lib i { width: 1rem; text-align: center; flex: none; line-height: inherit; }
.opt-ligne.est-exception > .opt-lib { color: var(--red-ink); font-weight: 600; }
.opt-titre { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.07em; font-weight: 600; color: var(--text-muted); margin: 0.7rem 0 0.1rem; }
/* Plafond : le libellé garde sa colonne, le nombre et « illimité » se
   partagent la seconde, élargie. */
.opt-ligne-plafond { grid-template-columns: minmax(0, 1fr) 11.2rem; }
.opt-plafond { display: flex; align-items: center; gap: 0.6rem; }
.opt-plafond input[type="number"] { flex: 1; min-width: 0; }
.opt-form .rk-note { margin: 0; }

/* ---- Page Sites : tableau des accès ----
   L'adresse d'un site ne se coupe jamais : « /agence-test-claude » sur trois
   lignes se lit mal et déforme la rangée. L'agence prend la place qui reste. */
.acces-sites td:nth-child(2) { white-space: nowrap; }
.acces-sites th:first-child, .acces-sites td:first-child { width: 100%; }
