/*
 * Le système de style de L'Escale, repris de la maquette livrée
 * (docs/Maquette L'Escale complète-handoff.zip, écran « style »).
 *
 * UNE FEUILLE, PAS UNE CHAÎNE D'OUTILS, ET ELLE RESTE HORS DE L'ASSET MAP.
 * Reproduire la maquette ne demande pas Tailwind : elle est elle-même écrite en
 * CSS littéral, sans classe utilitaire. Depuis le sous-projet « fiche
 * moderne », le dépôt A une pile front — AssetMapper et Stimulus — mais cette
 * feuille n'y entre PAS, et c'est délibéré : elle est chargée par un `<link>` en
 * chemin littéral. L'y faire passer la rendrait dépendante
 * d'`asset-map:compile`, si bien qu'un déploiement qui oublie cette étape
 * servirait des pages SANS UNE SEULE RÈGLE CSS au lieu de ne coûter que les
 * puces et le recadrage. Mesuré : sans `public/assets/`, la page rend 200, cette
 * feuille 200, le JavaScript 404. NE LA « RANGEZ » PAS DANS `assets/`.
 *
 * LES POLICES SONT HÉBERGÉES ICI, jamais appelées chez un tiers. La maquette
 * les charge depuis Google Fonts ; ce serait transmettre l'adresse IP de
 * chaque visiteur hors UE à chaque page, alors que le pied de page affirme un
 * hébergement en France (constat I6 de la revue finale du socle). Figtree et
 * Newsreader sont sous licence SIL OFL 1.1, donc redistribuables : les deux
 * fichiers variables vivent dans `public/fonts/`.
 *
 * DEUX COULEURS SONT THÉMATISABLES et ne doivent jamais être écrites en dur :
 * `--color-primary` et `--color-secondary`, posées par
 * `tenant_theme_style()` d'après la charte de l'organisation. Les valeurs de
 * la maquette (#1f5f6b, #d98a3d) n'en sont que les défauts. Tout le reste de
 * la palette — encre, sables, bordures — est constant d'un espace à l'autre :
 * c'est ce qui fait tenir la marque blanche sans que chaque espace ait l'air
 * d'un thème différent.
 */

@font-face {
    font-family: 'Figtree';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('/fonts/figtree.woff2') format('woff2');
}

@font-face {
    font-family: 'Newsreader';
    font-style: normal;
    font-weight: 400 600;
    font-display: swap;
    src: url('/fonts/newsreader.woff2') format('woff2');
}

:root {
    /*
     * Les deux couleurs thématisables, avec les défauts de la maquette.
     * `tenant_theme_style()` les écrase pour chaque espace ; les poser ici
     * rend la feuille autonome — la console de l'éditeur, sur le domaine
     * racine, n'a aucun tenant et rendrait sinon des boutons sans fond.
     */
    --color-primary: #1f5f6b;
    --color-secondary: #d98a3d;
    --ink: #16232e;
    --ink-soft: #3a4750;
    --muted: #5c6b74;
    --faint: #8a97a0;
    --sand: #e9e3d8;
    --sand-light: #f5f1ea;
    --paper: #fff;
    --line: #ece6da;
    --line-strong: #d9d0c1;
    --side: #16232e;
    --side-admin: #12303a;
    --side-text: #cdd6d3;
    --side-faint: #8fa0a8;
    --ui: Figtree, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --display: Newsreader, Georgia, 'Times New Roman', serif;
}

* {
    box-sizing: border-box;
}

html,
body {
    margin: 0;
}

body {
    background: var(--sand-light);
    color: var(--ink);
    font-family: var(--ui);
    font-size: 15px;
    line-height: 1.5;
}

a {
    color: var(--color-primary);
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

::selection {
    background: rgba(217, 138, 61, .28);
}

input,
textarea,
select,
button {
    font-family: var(--ui);
}

/* ---------- Coque ---------- */

.esc-shell {
    display: flex;
    min-height: 100vh;
}

.esc-side {
    width: 246px;
    flex: none;
    background: var(--side);
    color: #fff;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 20px 16px;
    position: sticky;
    top: 0;
    height: 100vh;
}

.esc-side--admin {
    background: var(--side-admin);
}

.esc-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 6px 18px;
}

.esc-brand__mark {
    width: 38px;
    height: 38px;
    border-radius: 10px;
    background: var(--color-secondary);
    color: var(--ink);
    display: flex;
    align-items: center;
    justify-content: center;
    font: 600 19px var(--display);
    flex: none;
    overflow: hidden;
}

.esc-brand__mark img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.esc-brand__name {
    font: 600 18px var(--display);
    line-height: 1.1;
}

.esc-brand__sub {
    font-size: 11px;
    color: var(--side-faint);
}

.esc-nav {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.esc-nav a {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 13px;
    border-radius: 10px;
    border: 1px solid transparent;
    color: var(--side-text);
    font: 500 14.5px var(--ui);
}

.esc-nav a:hover {
    background: rgba(255, 255, 255, .07);
    text-decoration: none;
}

.esc-nav a.is-on {
    background: rgba(255, 255, 255, .13);
    color: #fff;
    border-color: rgba(255, 255, 255, .15);
}

.esc-nav__label {
    font-size: 11px;
    letter-spacing: .08em;
    color: var(--side-faint);
    padding: 10px 8px 4px;
}

.esc-side__foot {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding-top: 14px;
}

.esc-side__foot .esc-nav a {
    border: 1px dashed rgba(255, 255, 255, .16);
    color: var(--side-faint);
}

.esc-me {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 8px;
    margin-top: 4px;
    border-top: 1px solid rgba(255, 255, 255, .09);
}

.esc-me__avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--color-primary);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font: 600 13px var(--ui);
    flex: none;
}

.esc-me__id {
    line-height: 1.15;
    flex: 1;
    min-width: 0;
}

.esc-me__name {
    font: 600 13px var(--ui);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.esc-me__role {
    font-size: 11px;
    color: var(--side-faint);
}

.esc-me a {
    color: var(--side-faint);
    font-size: 11px;
}

.esc-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    background: var(--sand-light);
}

.esc-content {
    padding: 28px 30px 40px;
    flex: 1;
    animation: esc-fade .3s ease;
}

@keyframes esc-fade {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
}

.esc-topbar,
.esc-tabs {
    display: none;
}

.esc-foot {
    padding: 0 30px 24px;
    font-size: 12px;
    color: var(--muted);
}

/* ---------- Titres ---------- */

.esc-title {
    font: 500 24px var(--display);
    margin: 0;
}

.esc-title--lg {
    font-size: 25px;
}

.esc-lede {
    color: var(--muted);
    font-size: 14px;
    margin: 2px 0 0;
}

.esc-h2 {
    font: 600 16px var(--display);
    margin: 0 0 8px;
}

.esc-head {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: flex-end;
    justify-content: space-between;
    margin: 0 0 18px;
}

/* ---------- Surfaces ---------- */

.esc-card {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 16px;
}

.esc-card--pad {
    padding: 20px;
}

.esc-stack {
    display: flex;
    flex-direction: column;
    gap: 18px;
}

.esc-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 14px;
}

.esc-cols {
    display: flex;
    flex-wrap: wrap;
    gap: 18px;
    align-items: flex-start;
}

.esc-cols__main {
    flex: 2;
    min-width: 300px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.esc-cols__side {
    flex: 1;
    min-width: 230px;
}

.esc-empty {
    background: #faf7f1;
    border: 1px dashed var(--line-strong);
    border-radius: 14px;
    padding: 20px;
    text-align: center;
    color: var(--faint);
    font-size: 13.5px;
    line-height: 1.5;
}

.esc-alert {
    margin: 0 0 16px;
    padding: 12px 14px;
    border-radius: 10px;
    background: #f7e7e2;
    color: #b4482f;
    font-size: 14px;
}

.esc-flash {
    margin: 0 0 16px;
    padding: 12px 14px;
    border-radius: 10px;
    background: #e9f0ef;
    color: #16474f;
    font-size: 14px;
}

/* ---------- Fragments ---------- */

.esc-avatar {
    width: 46px;
    height: 46px;
    border-radius: 12px;
    background: var(--color-primary);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font: 600 17px var(--display);
    flex: none;
    overflow: hidden;
}

.esc-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.esc-avatar--lg {
    width: 78px;
    height: 78px;
    border-radius: 18px;
    font-size: 30px;
    border: 4px solid var(--paper);
}

.esc-pill {
    background: #e9f0ef;
    color: var(--color-primary);
    font: 600 12.5px var(--ui);
    padding: 5px 11px;
    border-radius: 999px;
    display: inline-block;
}

.esc-pill--warn {
    background: #f7ede0;
    color: #b57226;
}

.esc-meta {
    font-size: 12.5px;
    color: var(--faint);
}

/* Pastille de non-lus, reprise de la maquette (écran « messagerie ») : fond
   d'accent, encre sombre — c'est le seul élément du produit qui doit
   attraper l'œil sans crier. `min-width` plutôt que `width` : un compteur à
   deux chiffres s'élargit au lieu de déborder. */
.esc-badge {
    flex: none;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--color-secondary);
    color: var(--ink);
    font: 700 11px var(--ui);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Une ligne de la liste des conversations. Le séparateur est en `border-top`
   pour que la première ligne, collée au bord haut de la carte, n'en porte
   pas — même geste que `.esc-table td`. */
.esc-convo {
    display: flex;
    gap: 11px;
    align-items: center;
    padding: 12px 16px;
    border-top: 1px solid var(--line);
}

.esc-convo:first-child {
    border-top: none;
}

/* Depuis la tâche 5, la ligne est un LIEN vers le fil de son correspondant.
   `color: inherit` et `text-decoration: none` : la ligne entière est
   cliquable, mais elle ne doit pas se peindre en lien — le nom, l'extrait et
   la date gardent chacun la couleur que leur donne le gabarit. */
.esc-convo,
.esc-convo:hover {
    color: inherit;
    text-decoration: none;
}

.esc-convo:hover {
    background: var(--sand-light);
}

/* L'extrait du dernier message : jamais plus d'une ligne. La troncature
   visuelle double celle du gabarit (90 caractères), qui, elle, borne ce qui
   part sur le réseau. */
.esc-convo__last {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 12.5px;
    color: var(--faint);
}

/* L'en-tête du fil : pastille, nom, métier, et le lien « Voir la fiche »
   quand le correspondant est encore là. Séparé du fil par un filet, comme
   dans la maquette (écran « messagerie »). */
.esc-thread-head {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 13px 16px;
    border-bottom: 1px solid var(--line);
}

/* Le fil lui-même. Fond sable, pour que les bulles blanches du correspondant
   s'en détachent — sur du blanc, elles disparaîtraient.

   AUCUN ARRONDI BAS : depuis la tâche 6, le fil n'est plus jamais le dernier
   élément de sa carte — le pied (formulaire d'envoi ou bandeau) le suit
   TOUJOURS, l'un ou l'autre. Un arrondi laisserait deux échancrures blanches
   entre le fond sable et le filet du pied. */
.esc-thread {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 18px 16px;
    background: var(--sand-light);
}

/* Le pied du fil, dans les deux cas : le champ d'envoi, ou le bandeau qui le
   remplace quand le correspondant n'est plus là (design §3.5). Même conteneur
   pour les deux, pour que le passage de l'un à l'autre ne déplace rien. */
.esc-composer {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 12px 14px;
    border-top: 1px solid var(--line);
}

.esc-composer .esc-input {
    flex: 1;
    min-width: 0;
}

.esc-composer .esc-btn {
    flex: none;
}

.esc-thread__empty {
    margin: 0;
    text-align: center;
    font-size: 13.5px;
    color: var(--faint);
}

/* Ce que les deux bulles partagent. La distinction entre « mienne » et
   « sienne » est portée par les deux modificateurs ci-dessous, et par eux
   SEULS : aucune n'hérite de l'apparence de l'autre, si bien qu'aucune ne
   peut se retrouver à ressembler à l'autre par omission. */
.esc-bubble {
    max-width: 78%;
    padding: 10px 13px;
    font-size: 14px;
    line-height: 1.45;
}

.esc-bubble--theirs {
    align-self: flex-start;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 14px 14px 14px 4px;
    color: var(--ink);
}

.esc-bubble--mine {
    align-self: flex-end;
    background: var(--color-primary);
    border-radius: 14px 14px 4px 14px;
    color: #fff;
}

.esc-bubble__time {
    margin-top: 3px;
    font-size: 10.5px;
    opacity: .72;
}

.esc-bubble--mine .esc-bubble__time {
    text-align: right;
}

.esc-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.esc-chip {
    padding: 6px 12px;
    border-radius: 999px;
    font: 600 12.5px var(--ui);
    border: 1px solid var(--line-strong);
    color: var(--muted);
    background: var(--paper);
    cursor: pointer;
    display: inline-block;
}

.esc-chip:hover {
    text-decoration: none;
    border-color: var(--color-primary);
}

.esc-chip.is-on {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

.esc-chips__label {
    font: 600 12px var(--ui);
    color: var(--faint);
    letter-spacing: .04em;
    align-self: center;
    margin-right: 2px;
}

/* Une ligne de la liste des notifications, reprise de la maquette (écran
   « notifications »). Même famille que `.esc-convo` — filet en `border-top`
   pour que la première ligne, collée au bord haut de la carte, n'en porte pas
   — mais `align-items: flex-start` : la phrase peut tenir deux lignes, et
   l'icône doit rester en haut plutôt que de flotter au milieu. */
.esc-notif {
    display: flex;
    gap: 13px;
    align-items: flex-start;
    padding: 15px 17px;
    border-top: 1px solid var(--line);
    background: var(--paper);
}

.esc-notif:first-child {
    border-top: none;
}

.esc-notif,
.esc-notif:hover {
    color: inherit;
    text-decoration: none;
}

/* `a.esc-notif`, JAMAIS `.esc-notif` : une ligne dont la cible ne s'ouvrirait
   pas est rendue en `<div>` (voir `NotificationController::openableRequestIds()`
   — une demande close, ou dont l'auteur est parti, mènerait à un 404). Elle ne
   doit donc PAS s'éclairer au survol : ce serait promettre un clic qui ne fait
   rien. Le sélecteur porte le contrat, et pas seulement l'apparence. */
a.esc-notif:hover {
    background: var(--sand-light);
}

/* LE FOND SABLE MARQUE LA NON-LUE, comme dans la maquette (`n.bg`). C'est le
   seul signal qui survit à l'absence de couleur (impression, mode contraste
   élevé) ; la puce ci-dessous le double pour l'œil. */
.esc-notif--unread {
    background: #fbf6ee;
}

/* Le carré d'icône. La teinte dépend du TYPE, et les trois valeurs viennent de
   la maquette. Elles ne sont PAS thématisables : ce sont des repères de sens
   — bleu pour un message, ambre pour une demande, teal pour une annonce —, et
   les faire suivre la charte de l'organisation les rendrait indiscernables
   chez qui a choisi une couleur proche. Même parti pris que `.esc-pill--warn`
   et que les trois niveaux d'alerte du back-office. */
.esc-notif__icon {
    width: 38px;
    height: 38px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.esc-notif__icon--message_received {
    background: #eef2f7;
    color: #4a6fa5;
}

.esc-notif__icon--request_answered,
.esc-notif__icon--request_published {
    background: #f7ede0;
    color: #b57226;
}

/* DEUX SÉLECTEURS, UNE SEULE DÉCLARATION, et c'est ce qui évite un troisième
   hexadécimal : l'ouverture d'un droit d'export relève du même registre qu'une
   annonce — ce n'est pas un échange entre membres, c'est l'organisation qui agit —
   et partage donc sa teinte. Sans règle du tout, le carré du type nouveau serait
   transparent (voir le commentaire de `templates/notification/index.html.twig`).
   La valeur reste littérale ici comme les deux règles au-dessus : elle appartient
   à la planche de style de la maquette et n'est PAS thématisable — seules la
   primaire et la secondaire passent par les variables de thème du tenant, et
   `color` les respecte. */
.esc-notif__icon--announcement_published,
.esc-notif__icon--data_exported {
    background: #e9f0ef;
    color: var(--color-primary);
}

.esc-notif__text {
    display: block;
    font-size: 14.5px;
    line-height: 1.4;
    color: var(--ink);
}

/* LA PUCE DE NON-LUE, ET PAS LA PASTILLE CHIFFRÉE DE LA NAVIGATION : ici il
   n'y a rien à compter, une ligne est lue ou ne l'est pas. `--color-secondary`
   plutôt que la valeur de la maquette : c'est la couleur d'accent de l'espace,
   la même que celle des pastilles. */
.esc-notif__dot {
    flex: none;
    width: 9px;
    height: 9px;
    margin-top: 6px;
    border-radius: 50%;
    background: var(--color-secondary);
}

/* ---------- Formulaires ---------- */

.esc-field {
    display: block;
    margin: 0 0 16px;
}

.esc-label {
    display: block;
    margin: 0 0 6px;
    font-size: 14px;
    color: var(--muted);
}

/* Une ligne « libellé à gauche, case à droite », reprise de l'écran « profil »
   de la maquette. Le `<label>` enveloppe la case, si bien que TOUTE la ligne
   est cliquable — y compris la phrase d'explication —, sans qu'un attribut
   `for` doive s'accorder à un `id`.

   `align-items: center` et non `flex-start` : le libellé peut tenir deux
   lignes sur mobile, et la case doit rester à sa hauteur. */
.esc-switch {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 12px 0;
    border-top: 1px solid #f2ede4;
    font-size: 14px;
    cursor: pointer;
}

.esc-switch input {
    flex: none;
    width: 20px;
    height: 20px;
    accent-color: var(--color-primary);
}

.esc-input,
.esc-select,
.esc-textarea {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--line-strong);
    border-radius: 10px;
    font-size: 15px;
    background: var(--paper);
    color: var(--ink);
}

.esc-textarea {
    resize: vertical;
    font-family: inherit;
}

.esc-input:focus,
.esc-select:focus,
.esc-textarea:focus {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

.esc-search {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--sand-light);
    border: 1px solid #e6ded1;
    border-radius: 11px;
    padding: 11px 14px;
}

.esc-search input {
    border: none;
    background: transparent;
    flex: 1;
    font-size: 15px;
    outline: none;
    color: var(--ink);
    min-width: 0;
}

.esc-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    background: var(--color-primary);
    color: #fff;
    border: none;
    border-radius: 10px;
    padding: 12px 20px;
    font: 600 14.5px var(--ui);
    cursor: pointer;
}

.esc-btn:hover {
    text-decoration: none;
    filter: brightness(1.08);
}

.esc-btn--block {
    width: 100%;
}

.esc-btn--ghost {
    background: var(--paper);
    border: 1px solid var(--line-strong);
    color: var(--ink);
}

.esc-btn--soft {
    background: var(--sand-light);
    border: 1px solid #e6ded1;
    color: var(--ink);
    font-size: 13.5px;
    padding: 9px 14px;
}

.esc-btn--danger {
    background: #b4482f;
}

/* ---------- Tableaux ---------- */

.esc-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

.esc-table th {
    text-align: left;
    font: 600 12px var(--ui);
    letter-spacing: .04em;
    color: var(--faint);
    padding: 0 10px 10px;
}

.esc-table td {
    padding: 12px 10px;
    border-top: 1px solid var(--line);
    vertical-align: middle;
}

/* ---------- Écran de connexion ---------- */

.esc-gate {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 26px;
    background: linear-gradient(140deg, var(--color-primary), #153f47);
}

.esc-gate__card {
    width: 100%;
    max-width: 380px;
    background: var(--paper);
    border-radius: 18px;
    padding: 30px 26px;
    box-shadow: 0 30px 70px -30px rgba(15, 25, 34, .55);
}

/* ---------- Mobile ---------- */

@media (max-width: 900px) {
    .esc-side {
        display: none;
    }

    .esc-topbar {
        position: sticky;
        top: 0;
        z-index: 20;
        display: flex;
        align-items: center;
        gap: 12px;
        padding: 13px 18px;
        background: rgba(245, 241, 234, .92);
        backdrop-filter: blur(8px);
        border-bottom: 1px solid #e6ded1;
    }

    .esc-topbar__mark {
        width: 30px;
        height: 30px;
        border-radius: 8px;
        background: var(--color-primary);
        color: #fff;
        display: flex;
        align-items: center;
        justify-content: center;
        font: 600 15px var(--display);
        flex: none;
        overflow: hidden;
    }

    .esc-topbar__mark img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    .esc-topbar__title {
        font: 600 17px var(--display);
        flex: 1;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .esc-content {
        padding: 18px 16px 26px;
    }

    .esc-foot {
        padding: 0 16px 20px;
    }

    .esc-tabs {
        position: sticky;
        bottom: 0;
        z-index: 20;
        display: flex;
        justify-content: space-around;
        background: var(--paper);
        border-top: 1px solid #e6ded1;
        padding: 8px 6px 10px;
    }

    .esc-tabs a {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 3px;
        font: 600 10px var(--ui);
        color: #9aa6ac;
        /* Repère de la pastille ci-dessous, qui sort du flux. */
        position: relative;
    }

    /* LA PASTILLE DE NON-LUS SUR UN ONGLET (tâche 7 du sous-projet
       « messagerie privée »). LA MAQUETTE N'EN DESSINE PAS ICI : sa barre
       d'onglets ne porte qu'icône et libellé, et elle ne pouvait donc servir
       de modèle. C'est le design §4.5 qui l'impose aux DEUX navigations, parce
       que la barre latérale est masquée sous ce même seuil (BNF-13) : sans
       cette règle, le compteur serait absent précisément des écrans qui
       justifient sa présence.

       ELLE DOIT SORTIR DU FLUX. `.esc-tabs a` est une COLONNE centrée : posée
       telle quelle, la pastille deviendrait un TROISIÈME bloc, sous le
       libellé, au lieu de coiffer l'icône. `position: absolute` la retire donc
       du flux, et l'ancre relative ci-dessus lui sert de repère.

       LE DÉCALAGE EST CALCULÉ SUR L'ICÔNE, pas sur l'ancre : l'icône fait
       22 px et est centrée, donc son bord droit tombe à `50% + 11px`. La
       pastille démarre 7 px avant, ce qui la fait chevaucher l'angle
       supérieur droit — le geste habituel d'un badge de notification, et le
       seul qui reste juste quel que soit le libellé (« Messagerie » est le
       plus long de la barre, un libellé plus court déplacerait un décalage
       exprimé depuis la droite de l'ancre).

       ELLE EST PLUS PETITE QUE CELLE DE LA BARRE LATÉRALE (16 px contre 20,
       10 px de texte contre 11) : posée sur un onglet de 10 px de haut de
       texte, la taille du menu latéral déborderait sur l'icône voisine. */
    .esc-tabs .esc-badge {
        position: absolute;
        top: -3px;
        left: calc(50% + 4px);
        min-width: 16px;
        height: 16px;
        padding: 0 4px;
        font-size: 10px;
    }

    .esc-tabs a:hover {
        text-decoration: none;
    }

    /* SEPT ENTRÉES DEPUIS « NOTIFICATIONS » (tâche 8 du sous-projet
       « notifications »), et c'est le libellé le PLUS LONG de la barre. À
       10 px, les sept libellés demandent environ 325 px de large : ils tiennent
       sur un écran de 360 px, mais se toucheraient sur les plus étroits. La
       taille descend donc d'un point sous ce seuil, plutôt que d'abréger un
       libellé dans une barre et pas dans l'autre — la maquette, elle, n'a que
       cinq onglets et renvoie les notifications vers une cloche posée dans sa
       barre supérieure, un troisième emplacement que le design n'a pas retenu
       (§4.4 : les deux barres, et elles seules). */
    @media (max-width: 379px) {
        .esc-tabs {
            padding-left: 2px;
            padding-right: 2px;
        }

        .esc-tabs a {
            font-size: 9px;
        }
    }

    .esc-tabs a.is-on {
        color: var(--color-primary);
    }

    .esc-cols__main,
    .esc-cols__side {
        flex-basis: 100%;
    }
}

/* --- Champ logo (partiel `templates/_logo_field.html.twig`) -------------- */
/* Reprend au pixel près les styles en ligne que les cinq écrans portaient
   chacun de leur côté avant que le partiel ne les réunisse. */

.esc-logofield__row {
    display: flex;
    gap: 16px;
    align-items: center;
    flex-wrap: wrap;
}

.esc-logofield__preview {
    width: 74px;
    height: 74px;
    border-radius: 16px;
    font-size: 26px;
}

.esc-logofield__controls {
    flex: 1;
    min-width: 180px;
}

/* --- Recadrage du logo (assets/controllers/logo_crop_controller.js) ------ */
/* Ces règles ne servent QUE lorsque le JavaScript a démarré : le contrôleur
   pose `.esc-logofield--live` sur la racine et construit le reste. Sans lui,
   rien ici ne s'applique et le champ reste l'`<input type="file">` nu. */

.esc-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.esc-drop__zone {
    display: block;
    margin-top: 8px;
    cursor: pointer;
}

.esc-drop {
    display: flex;
    flex-direction: column;
    gap: 2px;
    align-items: center;
    text-align: center;
    padding: 16px;
    border: 1.5px dashed var(--line-strong);
    border-radius: 12px;
    background: var(--sand-light);
    transition: border-color .15s ease, background .15s ease;
}

/* Le champ de fichier est visuellement caché mais reste focalisable : ce
   contour rend son focus visible sur le bloc qui l'habille. */
.esc-logofield__controls input[type="file"]:focus-visible + .esc-drop__zone .esc-drop,
.esc-drop__zone:hover .esc-drop,
.esc-drop.is-over {
    border-color: var(--color-primary);
    background: var(--paper);
}

.esc-drop__title {
    font: 600 13.5px var(--ui);
    color: var(--ink);
}

.esc-drop__hint {
    font-size: 12px;
    color: var(--muted);
}

.esc-crop {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: flex-start;
    margin-top: 16px;
}

.esc-crop__frame {
    position: relative;
    width: 240px;
    height: 240px;
    flex: none;
    overflow: hidden;
    border-radius: 18px;
    background: var(--sand);
    cursor: grab;
    touch-action: none;
}

.esc-crop__frame.is-dragging {
    cursor: grabbing;
}

.esc-crop__frame:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.esc-crop__image {
    position: absolute;
    top: 0;
    left: 0;
    max-width: none;
    transform-origin: 0 0;
    user-select: none;
    -webkit-user-drag: none;
}

.esc-crop__tools {
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-width: 180px;
    flex: 1;
}

.esc-crop__zoom {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font: 600 13px var(--ui);
}

.esc-crop__zoom input {
    width: 100%;
    accent-color: var(--color-primary);
}

.esc-crop__note {
    flex-basis: 100%;
    margin: 0;
}

/* --- Champ de puces (assets/controllers/chips_controller.js) ------------- */
/* Comme le recadreur, ces règles ne servent que si le JavaScript a démarré :
   sans lui, il n'y a qu'un `<textarea>` visible et rien de tout ceci n'existe
   dans le DOM. `.esc-chips` et `.esc-chip` préexistent — ce sont les pastilles
   de filtre de l'annuaire, des `<a>` ; le modificateur `--entry` distingue les
   puces de SAISIE, qui sont des `<li>`. */

.esc-chipfield__box {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    padding: 8px;
    min-height: 46px;
    border: 1px solid var(--line-strong);
    border-radius: 10px;
    background: var(--paper);
    cursor: text;
}

.esc-chipfield__box:focus-within {
    border-color: var(--color-primary);
}

/* Le `<ul>` réutilise la disposition de `.esc-chips` mais doit perdre les
   marges et la puce que le navigateur pose sur une liste. */
.esc-chipfield__box .esc-chips {
    margin: 0;
    padding: 0;
    list-style: none;
}

.esc-chip--entry {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: default;
    color: var(--ink);
    background: var(--sand-light);
}

.esc-chip--entry:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

/* Le premier Retour arrière ARME la dernière puce et doit le MONTRER : sans
   retour visible, le second appui semblerait effacer au hasard. */
.esc-chip--entry.is-armed {
    border-color: var(--color-primary);
    background: #e9f0ef;
    color: var(--color-primary);
}

.esc-chip__remove {
    border: none;
    background: none;
    padding: 0;
    line-height: 1;
    font-size: 15px;
    color: var(--muted);
    cursor: pointer;
}

.esc-chip__remove:hover {
    color: var(--ink);
}

.esc-chipfield__entry {
    flex: 1;
    min-width: 140px;
    border: none;
    outline: none;
    background: none;
    padding: 5px 4px;
    font: 400 14.5px var(--ui);
    color: var(--ink);
}
