/* =========================================================================
   ESPACE DE GESTION — templates/access-portal.php
   Prolongement direct du tableau de bord : mêmes tokens --ueb-*, mêmes
   polices, même coque (.admin-shell / .admin-sidebar / .admin-topbar /
   .admin-tbtn / .admin-table / .admin-skeleton, définis dans
   admin-dashboard.css, chargé avant celui-ci). Ce fichier n'ajoute QUE ce
   qui est propre au portail.

   Parti pris de la vue d'ensemble : un seul chiffre domine l'écran, tout le
   reste est son contexte. Le Recteur ouvre la page et lit le total avant
   d'avoir décidé de lire quoi que ce soit.

   Sommaire
     1.  Base du portail
     2.  Bandeau à chiffre dominant
     3.  Cartes d'établissement
     4.  Classement et panneaux
     5.  Barre d'outils, filtres, tableau
     6.  Rôles, comptes, établissements
     7.  Assistant de création de rôle
     8.  Dialogues
     9.  Écran de connexion
     10. Mouvement
     11. Responsive
     12. Mouvement réduit et impression
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. BASE DU PORTAIL
   ------------------------------------------------------------------------- */
.ueb-portal {
    margin: 0;
    background: var(--ueb-bg);
    color: var(--ueb-text);
    font-family: 'Inter', system-ui, sans-serif;
    font-size: .95rem;
    line-height: 1.6;
}
.ueb-portal *,
.ueb-portal *::before,
.ueb-portal *::after { box-sizing: border-box; }
.ueb-portal [hidden] { display: none !important; }

/* Resets enveloppés dans :where() — spécificité nulle.
   Sans cela, « .ueb-portal a » (0,1,1) écrase « .admin-tbtn--primary »
   (0,1,0) et le bouton principal se retrouve en texte vert sur fond vert.
   Même piège que la refonte du compte à rebours : tout reset de base du
   portail passe par :where(), et chaque composant garde la main. */
:where(.ueb-portal) :where(h1, h2, h3) {
    font-family: 'Sora', sans-serif;
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: -.01em;
    color: inherit;
    margin: 0;
}
:where(.ueb-portal) :where(p) { margin: 0; color: var(--ueb-text-soft); }
:where(.ueb-portal) :where(a) { color: var(--ueb-primary); text-underline-offset: 3px; }
:where(.ueb-portal) :where(button, input, select, textarea) {
    font-family: inherit;
    font-size: inherit;
    color: inherit;
}
:where(.ueb-portal) :where(button, select) { cursor: pointer; }

/* Focus homogène avec le tableau de bord. */
.ueb-portal :focus-visible {
    outline: 2px solid var(--ueb-accent);
    outline-offset: 2px;
    border-radius: 4px;
}

.portal-skip {
    position: fixed;
    left: 1rem;
    top: -6rem;
    z-index: 100;
    padding: .75rem 1.25rem;
    background: var(--ueb-surface);
    border: 1px solid var(--ueb-border-strong);
    border-radius: var(--ueb-radius-sm);
    text-decoration: none;
    transition: top var(--ueb-fast) var(--ueb-ease);
}
.portal-skip:focus { top: 1rem; }

/* Une seule colonne de contenu, large mais bornée : au-delà, l'œil perd la
   ligne entre le libellé de gauche et le chiffre de droite. */
.portal-main { max-width: 1560px; }

/* En-tête : établissement consulté + rôle. */
.portal-topbar-context {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
    margin-top: .3rem;
}
.portal-role-tag {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .2rem .55rem;
    border: 1px solid var(--ueb-border);
    border-radius: 999px;
    background: var(--ueb-surface-2);
    color: var(--ueb-text-soft);
    font-size: .74rem;
    font-weight: 600;
}

/* Message global. Bordure complète : pas de filet latéral décoratif, c'est
   la convention du projet. */
.portal-notice {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    padding: .85rem 1rem;
    margin-bottom: 1.25rem;
    border: 1px solid var(--ueb-border-strong);
    border-radius: var(--ueb-radius-sm);
    background: var(--ueb-surface);
    color: var(--ueb-text);
    font-size: .88rem;
}
.portal-notice .admin-icon { margin-top: .12rem; color: var(--ueb-accent); }
.portal-notice--error { border-color: var(--ueb-danger); background: var(--ueb-danger-wash); }
.portal-notice--error .admin-icon { color: var(--ueb-danger); }
.portal-notice--ok { border-color: var(--ueb-success); }
.portal-notice--ok .admin-icon { color: var(--ueb-success); }

/* Compléments à la coque admin-* réutilisée ici.
   La barre latérale du tableau de bord bascule entre des onglets (<button>) ;
   le portail navigue entre des pages (<a>). Même apparence, même état actif,
   mais il faut neutraliser le soulignement des liens. */
.admin-sidebar-nav a.admin-tab-btn { text-decoration: none; color: var(--ueb-nav-text); }
.admin-sidebar-nav a.admin-tab-btn:hover { color: var(--ueb-nav-text-hi); }
.admin-sidebar-nav a.admin-tab-btn.active { color: var(--ueb-nav-active-tx); }
.ueb-portal .admin-sidebar-logout { color: var(--ueb-nav-text); }
.ueb-portal .admin-sidebar-logout:hover { color: #ffffff; }
.admin-sidebar-nav a.admin-tab-btn.active::before { background: var(--ueb-nav-active-bg); }

/* Variante destructive : n'existe que dans le portail (suppression d'un rôle). */
.admin-tbtn--danger {
    background: var(--ueb-danger);
    border-color: var(--ueb-danger);
    color: #fff;
}
.admin-tbtn--danger:hover { background: #93231d; border-color: #93231d; color: #fff; }
.ueb-portal a.admin-tbtn { text-decoration: none; }
.admin-topbar-actions .portal-hint { display: inline-flex; align-items: center; gap: .35rem; white-space: nowrap; }

.portal-footer {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 3rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--ueb-border);
    font-size: .76rem;
    color: var(--ueb-text-muted);
}

/* -------------------------------------------------------------------------
   2. BANDEAU À CHIFFRE DOMINANT
   Volontairement différent d'une carte : pas d'ombre, une bordure franche,
   un fond plein. C'est le socle de la page, pas un élément parmi d'autres.
   ------------------------------------------------------------------------- */
.portal-headline {
    display: grid;
    grid-template-columns: minmax(0, auto) minmax(0, 1fr);
    align-items: end;
    gap: 1.5rem 3rem;
    padding: 1.9rem 2rem 1.6rem;
    border: 1px solid var(--ueb-border-strong);
    border-radius: var(--ueb-radius-lg);
    background: var(--ueb-surface);
    margin-bottom: 1.5rem;
}
.portal-headline-label {
    display: block;
    font-size: .82rem;
    font-weight: 600;
    color: var(--ueb-text-soft);
    margin-bottom: .1rem;
}
.portal-headline-value {
    display: block;
    font-family: 'Sora', sans-serif;
    font-weight: 600;
    font-size: clamp(3.4rem, 7.5vw, 6rem);
    line-height: .95;
    letter-spacing: -.045em;
    /* toLocaleString('fr-FR') sépare les milliers par une espace fine ;
       à 6rem elle creuse un trou entre « 11 » et « 480 ». */
    word-spacing: -.2em;
    font-variant-numeric: tabular-nums;
    color: var(--ueb-text);
}
.portal-headline-delta {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    margin-top: .7rem;
    font-size: .85rem;
    font-weight: 600;
}
.portal-delta--up   { color: var(--ueb-success); }
.portal-delta--down { color: var(--ueb-danger); }
.portal-delta--flat { color: var(--ueb-text-muted); }

/* Courbe des 30 jours, collée au chiffre : la tendance se lit sans aller
   chercher le graphique plus bas. */
.portal-headline-spark {
    display: block;
    width: 100%;
    height: 78px;
    color: var(--ueb-primary);
    align-self: end;
}
.portal-headline-spark-caption {
    display: block;
    text-align: right;
    font-size: .76rem;
    color: var(--ueb-text-soft);
    margin-top: .3rem;
}

/* Satellites : séparés par des filets, jamais par des cartes — ils sont une
   lecture du même chiffre, pas quatre informations concurrentes. */
.portal-satellites {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    gap: 0 2.5rem;
    margin-top: .4rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--ueb-border);
}
.portal-satellite {
    display: flex;
    align-items: baseline;
    gap: .55rem;
    padding: .35rem 2.5rem .35rem 0;
    border-right: 1px solid var(--ueb-border);
}
.portal-satellite:last-child { border-right: 0; padding-right: 0; }
.portal-satellite-value {
    font-family: 'Sora', sans-serif;
    font-weight: 600;
    font-size: 1.45rem;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
    color: var(--ueb-text);
}
.portal-satellite-label {
    font-size: .82rem;
    color: var(--ueb-text-soft);
}

/* -------------------------------------------------------------------------
   3. CARTES D'ÉTABLISSEMENT
   ------------------------------------------------------------------------- */
.portal-section {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin: 2.25rem 0 1rem;
}
.portal-section h2 { font-size: 1.15rem; }
.portal-section p { font-size: .85rem; margin-top: .15rem; }

.portal-est-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(248px, 100%), 1fr));
    gap: 1rem;
}
.portal-est-card {
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    padding: 1.15rem 1.25rem 1rem;
    border: 1px solid var(--ueb-border);
    border-radius: var(--ueb-radius);
    background: var(--ueb-surface);
    box-shadow: var(--ueb-shadow-sm);
    transition: transform var(--ueb-normal) var(--ueb-ease),
                box-shadow var(--ueb-normal) var(--ueb-ease),
                border-color var(--ueb-normal) var(--ueb-ease);
}
.ueb-portal a.portal-est-card { color: inherit; text-decoration: none; }
.ueb-portal a.portal-est-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--ueb-shadow);
    border-color: var(--ueb-border-strong);
}
a.portal-est-card:hover .portal-est-go { color: var(--ueb-primary); transform: translateX(2px); }

/* Les sceaux des facultés sont des dessins foncés et détaillés : posés
   directement sur le vert nuit ou sur une pastille or, ils deviennent
   illisibles. Ils gardent donc toujours leur propre fond blanc, dans les
   deux thèmes, et le sigle reste écrit à côté — à 38 px, c'est lui qu'on
   lit, le logo ne fait que confirmer. */
.portal-est-id { display: flex; align-items: center; gap: .55rem; min-width: 0; }
.portal-est-logo {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    padding: 3px;
    border-radius: 10px;
    background: #ffffff;
    border: 1px solid var(--ueb-border);
    flex-shrink: 0;
}
.portal-est-logo img { width: 100%; height: 100%; object-fit: contain; display: block; }
.portal-est-logo--sm { width: 30px; height: 30px; padding: 2px; border-radius: 8px; }
.portal-est-code {
    font-family: 'Sora', sans-serif;
    font-weight: 700;
    font-size: .84rem;
    letter-spacing: .02em;
    color: var(--ueb-text);
}
.portal-est-row { display: flex; align-items: center; gap: .6rem; min-width: 0; }

/* Barre latérale : même traitement pour le sceau de l'université. */
.admin-sidebar-logo--image {
    background: #ffffff;
    padding: 3px;
    border: 1px solid rgba(255, 255, 255, .25);
}
.admin-sidebar-logo--image img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* En-tête d'un établissement : le logo a ici la place d'être vraiment lu. */
.portal-title-block { display: flex; align-items: flex-start; gap: .9rem; min-width: 0; }
.portal-title-logo {
    display: grid;
    place-items: center;
    width: 48px;
    height: 48px;
    padding: 4px;
    border-radius: 12px;
    background: #ffffff;
    border: 1px solid var(--ueb-border);
    flex-shrink: 0;
}
.portal-title-logo img { width: 100%; height: 100%; object-fit: contain; display: block; }

.portal-est-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .6rem;
    margin-bottom: .7rem;
}
/* Même pastille que le logo de la barre latérale : le sigle est le repère
   que l'équipe utilise déjà à l'oral. */
.portal-est-sigle {
    display: grid;
    place-items: center;
    min-width: 38px;
    height: 38px;
    padding: 0 .5rem;
    border-radius: 10px;
    background: var(--ueb-accent-bright);
    color: var(--ueb-on-accent);
    font-family: 'Sora', sans-serif;
    font-weight: 700;
    font-size: .8rem;
    letter-spacing: .02em;
}
.portal-est-go {
    color: var(--ueb-text-muted);
    transition: transform var(--ueb-fast) var(--ueb-ease), color var(--ueb-fast) var(--ueb-ease);
}
.portal-est-name {
    font-family: 'Inter', sans-serif;
    font-size: .84rem;
    font-weight: 500;
    line-height: 1.4;
    color: var(--ueb-text-soft);
    margin-bottom: .55rem;
    /* Hauteur fixe, pas min-height : sinon un nom sur deux lignes décale son
       chiffre et la rangée de cartes perd sa ligne de lecture. */
    height: 2.8em;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.portal-est-value {
    font-family: 'Sora', sans-serif;
    font-weight: 600;
    font-size: 2.1rem;
    line-height: 1.1;
    letter-spacing: -.03em;
    font-variant-numeric: tabular-nums;
}
.portal-est-delta {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    margin-top: .2rem;
    font-size: .78rem;
    font-weight: 600;
}
.portal-est-spark {
    display: block;
    width: 100%;
    height: 40px;
    margin-top: .6rem;
    color: var(--ueb-primary);
}
.portal-est-card--off { border-style: dashed; }
.portal-est-off {
    display: inline-block;
    margin-left: .4rem;
    font-size: .7rem;
    font-weight: 600;
    color: var(--ueb-text-muted);
}

/* -------------------------------------------------------------------------
   4. CLASSEMENT ET PANNEAUX
   ------------------------------------------------------------------------- */
.portal-grid-2 {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
    gap: 1.25rem;
    margin-top: 1.25rem;
    align-items: start;
}
.portal-grid-3 {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr) minmax(0, 1fr);
    gap: 1.25rem;
    margin-top: 1.25rem;
    align-items: start;
}
.portal-panel {
    min-width: 0;
    padding: 1.35rem 1.5rem 1.5rem;
    border: 1px solid var(--ueb-border);
    border-radius: var(--ueb-radius);
    background: var(--ueb-surface);
    box-shadow: var(--ueb-shadow-sm);
}
.portal-panel-head { margin-bottom: 1.1rem; }
.portal-panel-head h2 { font-size: 1rem; }
.portal-panel-head p { font-size: .8rem; margin-top: .1rem; }

.portal-rank { display: grid; gap: .95rem; }
.portal-rank-row { display: grid; gap: .35rem; }
.portal-rank-line {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    font-size: .82rem;
}
/* Le nom absorbe la place restante et tronque ; la valeur ne bouge jamais,
   sinon les chiffres du classement sortent du panneau. */
.portal-rank-name { display: flex; align-items: baseline; gap: .45rem; flex: 1 1 auto; min-width: 0; }
.portal-rank-sigle {
    flex: 0 0 auto;
    font-family: 'Sora', sans-serif;
    font-weight: 700;
    font-size: .78rem;
    color: var(--ueb-text);
}
.portal-rank-full {
    color: var(--ueb-text-soft);
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.portal-rank-value {
    flex: 0 0 auto;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.portal-track {
    height: 8px;
    border-radius: 4px;
    background: var(--ueb-surface-hover);
    overflow: hidden;
}
.portal-track span {
    display: block;
    height: 100%;
    border-radius: 4px;
    background: var(--ueb-primary);
    transform-origin: left center;
    animation: portal-fill 650ms var(--ueb-ease) both;
    animation-delay: var(--delay, 0ms);
}
/* Le premier du classement porte l'or : un seul élément accentué. */
.portal-rank-row:first-child .portal-track span { background: var(--ueb-accent-bright); }

.portal-chart { position: relative; height: 260px; }
.portal-chart--small { height: 210px; }

.portal-figures { margin-top: 1rem; }
.portal-figures summary {
    cursor: pointer;
    font-size: .8rem;
    color: var(--ueb-text-soft);
    padding: .35rem 0;
}
.portal-figures summary:hover { color: var(--ueb-text); }

.portal-legend {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem 1.1rem;
    margin-top: .9rem;
    font-size: .8rem;
}
.portal-legend span { display: inline-flex; align-items: center; gap: .4rem; }
.portal-legend i {
    width: 9px; height: 9px;
    border-radius: 3px;
    flex-shrink: 0;
}

.portal-empty {
    display: grid;
    justify-items: center;
    gap: .5rem;
    padding: 2.75rem 1.25rem;
    text-align: center;
    color: var(--ueb-text-muted);
}
.portal-empty .admin-icon { width: 30px; height: 30px; opacity: .5; }
.portal-empty strong { font-family: 'Sora', sans-serif; font-size: .95rem; color: var(--ueb-text); }
.portal-empty p { font-size: .85rem; max-width: 42ch; }

/* -------------------------------------------------------------------------
   5. BARRE D'OUTILS, FILTRES, TABLEAU
   ------------------------------------------------------------------------- */
.portal-toolbar {
    display: flex;
    align-items: center;
    gap: .7rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
}
.portal-toolbar-spacer { margin-left: auto; }

.portal-switcher {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .3rem .3rem .3rem .75rem;
    border: 1px solid var(--ueb-border-strong);
    border-radius: 999px;
    background: var(--ueb-surface);
    font-size: .82rem;
}
.portal-switcher label { color: var(--ueb-text-muted); }
.portal-switcher select {
    border: 0;
    background: transparent;
    padding: .35rem 1.75rem .35rem .3rem;
    min-height: 34px;
    font-weight: 600;
    max-width: 16rem;
}

.portal-filters {
    display: flex;
    align-items: flex-end;
    gap: .7rem;
    flex-wrap: wrap;
    padding: 1rem 0 1.15rem;
    border-bottom: 1px solid var(--ueb-border);
    margin-bottom: .25rem;
}
.portal-field { display: grid; gap: .35rem; min-width: 0; }
.portal-field > span {
    font-size: .76rem;
    font-weight: 600;
    color: var(--ueb-text-soft);
}
.portal-field--grow { flex: 1 1 15rem; }

/* Filtres détaillés : le bouton se range avec les autres champs, le panneau
   s'ouvre sur toute la largeur en dessous, en grille de champs égaux. */
.portal-more-toggle { min-height: 42px; }
.portal-more-toggle .admin-filter-badge { margin-left: .1rem; }
.portal-more-toggle[aria-expanded="true"] {
    border-color: var(--ueb-primary);
    background: var(--ueb-primary-wash);
}
/* Qualifié par .ueb-portal : le reset `.ueb-portal fieldset` (0,1,1), plus
   bas dans ce fichier, écrasait sinon la marge et la bordure du panneau. */
.ueb-portal .portal-more {
    flex: 1 1 100%;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(12.5rem, 1fr));
    gap: .85rem .9rem;
    min-width: 0;
    margin: .15rem 0 0;
    padding: 1rem 1.05rem 1.05rem;
    background: var(--ueb-surface-2);
    border: 1px solid var(--ueb-border);
    border-radius: var(--ueb-radius);
}
.ueb-portal .portal-more[hidden] { display: none; }
.ueb-portal .portal-more select,
.ueb-portal .portal-more input { width: 100%; }
.portal-more-actions { display: flex; align-items: flex-end; }
.portal-more-reset {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    min-height: 42px;
    padding: .4rem .7rem;
    background: none;
    border: none;
    border-radius: var(--ueb-radius-sm);
    font-size: .84rem;
    font-weight: 600;
    color: var(--ueb-text-soft);
    cursor: pointer;
    transition: color var(--ueb-fast) var(--ueb-ease), background var(--ueb-fast) var(--ueb-ease);
}
.portal-more-reset:hover { color: var(--ueb-primary); background: var(--ueb-surface-hover); }
.portal-more-reset[hidden] { display: none; }

.portal-search { position: relative; display: flex; align-items: center; }
.portal-search .admin-icon {
    position: absolute;
    left: .85rem;
    color: var(--ueb-text-muted);
    pointer-events: none;
}

.ueb-portal input:not([type="checkbox"]):not([type="radio"]),
.ueb-portal select,
.ueb-portal textarea {
    min-height: 42px;
    padding: .5rem .7rem;
    border: 1px solid var(--ueb-border-strong);
    border-radius: var(--ueb-radius-sm);
    background: var(--ueb-surface);
    color: var(--ueb-text);
    min-width: 0;
    max-width: 100%;
    transition: border-color var(--ueb-fast) var(--ueb-ease),
                box-shadow var(--ueb-fast) var(--ueb-ease);
}
.ueb-portal input:focus,
.ueb-portal select:focus,
.ueb-portal textarea:focus {
    border-color: var(--ueb-primary);
    box-shadow: 0 0 0 3px var(--ueb-primary-wash);
}
/* Le reset ci-dessus vaut (0,3,1) à cause de ses deux :not() : ce sélecteur
   reprend les mêmes :not() pour le dépasser (0,4,1). Sans cela, le raccourci
   `padding` du reset écrase le retrait réservé à l'icône, et la loupe se
   pose sur les premières lettres du texte d'aide. */
.ueb-portal .portal-search input:not([type="checkbox"]):not([type="radio"]) {
    padding-left: 2.5rem;
    width: 100%;
}

.ueb-portal input[type="checkbox"] {
    width: 17px; height: 17px;
    accent-color: var(--ueb-primary);
    flex-shrink: 0;
}
.portal-check {
    display: flex;
    align-items: center;
    gap: .55rem;
    min-height: 40px;
    font-size: .86rem;
    cursor: pointer;
}

.portal-table-wrap {
    border: 1px solid var(--ueb-border);
    border-radius: var(--ueb-radius);
    background: var(--ueb-surface);
    overflow: hidden;
    margin-top: 1.1rem;
}
.portal-table-scroll { overflow-x: auto; }
.portal-table {
    width: 100%;
    border-collapse: collapse;
    font-size: .85rem;
    text-align: left;
}
.portal-table th {
    padding: .7rem .9rem;
    background: var(--ueb-surface-2);
    border-bottom: 1px solid var(--ueb-border);
    font-size: .76rem;
    font-weight: 600;
    color: var(--ueb-text-soft);
    white-space: nowrap;
}
.portal-table td {
    padding: .8rem .9rem;
    border-bottom: 1px solid var(--ueb-border);
    vertical-align: middle;
}
.portal-table tbody tr:last-child td { border-bottom: 0; }
.portal-table tbody tr { transition: background var(--ueb-fast) var(--ueb-ease); }
.portal-table tbody tr:hover { background: var(--ueb-surface-2); }
/* Ligne cliquable dans toute sa largeur (dossiers, comptes, établissements) :
   le clic est délégué en JS vers l'action principale de la ligne. */
.portal-table tbody tr.portal-row-clickable { cursor: pointer; }
.portal-table strong { font-weight: 600; }
.portal-table small { display: block; font-size: .76rem; color: var(--ueb-text-muted); }
.portal-num { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* En-tête triable : le tri est une action, donc un bouton. */
.portal-sort {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    font-weight: 600;
    color: inherit;
    cursor: pointer;
}
.portal-sort .admin-icon { width: 13px; height: 13px; opacity: .35; transition: opacity var(--ueb-fast); }
.portal-sort:hover .admin-icon { opacity: .7; }
.portal-table th[aria-sort] .portal-sort .admin-icon { opacity: 1; color: var(--ueb-primary); }
.portal-table th[aria-sort] .portal-sort { color: var(--ueb-primary); }

.portal-status {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .2rem .55rem;
    border-radius: 999px;
    border: 1px solid var(--ueb-border-strong);
    font-size: .74rem;
    font-weight: 600;
    white-space: nowrap;
}
.portal-status::before {
    content: '';
    width: 6px; height: 6px;
    border-radius: 50%;
    background: currentColor;
}
.portal-status--soumis { color: var(--ueb-success); border-color: color-mix(in srgb, var(--ueb-success) 35%, transparent); }
.portal-status--brouillon { color: var(--ueb-text-muted); }

.portal-row-open {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    background: none;
    border: 0;
    padding: .25rem;
    color: var(--ueb-text-muted);
    cursor: pointer;
    border-radius: var(--ueb-radius-sm);
    transition: color var(--ueb-fast), background var(--ueb-fast);
}
.portal-row-open:hover { color: var(--ueb-primary); background: var(--ueb-surface-hover); }

.portal-pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 1rem;
    font-size: .83rem;
    color: var(--ueb-text-soft);
}
.portal-pagination-actions { display: flex; gap: .5rem; }

/* Squelettes : même trame que le tableau de bord. */
.portal-skeleton {
    border-radius: var(--ueb-radius);
    background: var(--ueb-border);
    animation: portal-pulse 1.15s ease-in-out infinite alternate;
}
.portal-skeleton--headline { height: 232px; margin-bottom: 1.5rem; }
.portal-skeleton--card { height: 186px; }
.portal-skeleton--panel { height: 300px; }
.portal-skeleton--row { height: 52px; margin-bottom: .45rem; }

/* -------------------------------------------------------------------------
   6. RÔLES, COMPTES, ÉTABLISSEMENTS
   ------------------------------------------------------------------------- */
.portal-split {
    display: grid;
    grid-template-columns: minmax(0, 1.5fr) minmax(300px, .85fr);
    gap: 1.25rem;
    align-items: start;
}
.portal-role-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
    gap: 1rem;
}
.portal-role-card { display: flex; flex-direction: column; gap: .75rem; }
.portal-role-card h3 { font-size: 1.05rem; }
.portal-role-meta {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
}
.portal-tag {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .2rem .55rem;
    border: 1px solid var(--ueb-border);
    border-radius: 999px;
    background: var(--ueb-surface-2);
    font-size: .74rem;
    font-weight: 600;
    color: var(--ueb-text-soft);
}
.portal-tag--scope { background: var(--ueb-primary-wash); color: var(--ueb-primary); border-color: transparent; }
.portal-tag--locked { background: var(--ueb-accent-wash); color: var(--ueb-on-accent); border-color: transparent; }
:root[data-ueb-theme="dark"] .portal-tag--locked { color: var(--ueb-accent); }

.portal-role-perms {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: .3rem;
    font-size: .82rem;
    color: var(--ueb-text-soft);
}
.portal-role-perms li { display: flex; align-items: flex-start; gap: .45rem; }
.portal-role-perms .admin-icon { width: 14px; height: 14px; margin-top: .2rem; color: var(--ueb-success); }
.portal-role-actions {
    display: flex;
    gap: .5rem;
    flex-wrap: wrap;
    margin-top: auto;
    padding-top: .9rem;
    border-top: 1px solid var(--ueb-border);
}

.portal-form { display: grid; gap: 1rem; }
:where(.portal-form) :where(label) { display: grid; gap: .35rem; font-size: .8rem; font-weight: 600; color: var(--ueb-text-soft); }
.portal-form label input,
.portal-form label select { font-weight: 400; color: var(--ueb-text); }
.portal-form .portal-check { font-weight: 400; color: var(--ueb-text); }
.portal-hint { font-size: .78rem; color: var(--ueb-text-muted); }
/* Portée à tout le portail, pas seulement à .portal-form : les étapes de
   l'assistant sont des fieldsets hors de ce conteneur et récupéraient
   sinon la bordure native du navigateur. */
.ueb-portal fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }

/* -------------------------------------------------------------------------
   7. ASSISTANT DE CRÉATION DE RÔLE
   ------------------------------------------------------------------------- */
.portal-steps {
    display: flex;
    gap: .5rem;
    list-style: none;
    margin: 0 0 1.5rem;
    padding: 0;
    counter-reset: portal-step;
}
.portal-steps li {
    flex: 1;
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .6rem 0 .7rem;
    border-bottom: 2px solid var(--ueb-border);
    font-size: .82rem;
    color: var(--ueb-text-muted);
    transition: border-color var(--ueb-normal) var(--ueb-ease), color var(--ueb-normal) var(--ueb-ease);
}
.portal-steps li::before {
    counter-increment: portal-step;
    content: counter(portal-step);
    display: grid;
    place-items: center;
    width: 22px; height: 22px;
    border-radius: 50%;
    border: 1px solid currentColor;
    font-size: .72rem;
    font-weight: 700;
    flex-shrink: 0;
}
.portal-steps li[aria-current] {
    border-bottom-color: var(--ueb-primary);
    color: var(--ueb-primary);
    font-weight: 600;
}
.portal-steps li[data-done] { color: var(--ueb-success); border-bottom-color: var(--ueb-success); }
.portal-steps li[data-done]::before { content: '✓'; background: var(--ueb-success); border-color: var(--ueb-success); color: #fff; }

.portal-wizard { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: 1.75rem; align-items: start; }
.portal-wizard legend {
    font-family: 'Sora', sans-serif;
    font-weight: 600;
    font-size: 1.05rem;
    color: var(--ueb-text);
    margin-bottom: 1rem;
    padding: 0;
}

.portal-scope-choices { display: grid; gap: .6rem; margin-bottom: 1.1rem; }
.portal-scope-option {
    display: flex;
    align-items: flex-start;
    gap: .7rem;
    padding: .85rem 1rem;
    border: 1px solid var(--ueb-border-strong);
    border-radius: var(--ueb-radius-sm);
    cursor: pointer;
    transition: border-color var(--ueb-fast) var(--ueb-ease), background var(--ueb-fast) var(--ueb-ease);
}
.portal-scope-option:hover { background: var(--ueb-surface-hover); }
.portal-scope-option:has(input:checked) { border-color: var(--ueb-primary); background: var(--ueb-primary-wash); }
.portal-scope-option input { margin-top: .2rem; accent-color: var(--ueb-primary); }
.portal-scope-option span { display: block; font-size: .87rem; font-weight: 600; color: var(--ueb-text); }
.portal-scope-option small { display: block; font-size: .78rem; font-weight: 400; color: var(--ueb-text-soft); }

.portal-choice-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr));
    gap: .2rem 1.25rem;
    max-height: 15rem;
    overflow-y: auto;
    padding: .25rem;
}

.portal-perm-groups { display: grid; gap: 1.35rem; }
.portal-perm-group h3 {
    font-size: .82rem;
    font-weight: 700;
    color: var(--ueb-text-soft);
    padding-bottom: .45rem;
    border-bottom: 1px solid var(--ueb-border);
    margin-bottom: .35rem;
}
.portal-perm-group > div {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(230px, 100%), 1fr));
    gap: 0 1.25rem;
}
.portal-perm-groups details > summary {
    cursor: pointer;
    font-size: .82rem;
    font-weight: 700;
    color: var(--ueb-text-soft);
    padding: .55rem 0;
    border-top: 1px solid var(--ueb-border);
    border-bottom: 1px solid var(--ueb-border);
}

/* Aperçu : une maquette de la barre latérale que verra le titulaire, pas une
   phrase à lire. On montre l'interface, on ne la décrit pas. */
.portal-preview {
    position: sticky;
    top: 0;
    border: 1px solid var(--ueb-border-strong);
    border-radius: var(--ueb-radius);
    overflow: hidden;
    background: var(--ueb-surface-2);
}
.portal-preview-head {
    padding: .7rem .9rem;
    border-bottom: 1px solid var(--ueb-border);
    font-size: .76rem;
    font-weight: 700;
    color: var(--ueb-text-soft);
}
.portal-preview-screen { background: var(--ueb-nav-bg); padding: .8rem .7rem; }
.portal-preview-name {
    display: block;
    font-family: 'Sora', sans-serif;
    font-size: .85rem;
    font-weight: 700;
    color: #fff;
    padding: 0 .45rem .65rem;
    border-bottom: 1px solid var(--ueb-nav-border);
    margin-bottom: .55rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.portal-preview-nav { display: grid; gap: .15rem; }
.portal-preview-nav span {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .4rem .45rem;
    border-radius: 6px;
    font-size: .78rem;
    font-weight: 600;
    color: var(--ueb-nav-text);
    animation: portal-in 220ms var(--ueb-ease) both;
}
.portal-preview-nav span:first-child { background: var(--ueb-accent-bright); color: var(--ueb-nav-active-tx); }
.portal-preview-foot {
    padding: .7rem .9rem;
    font-size: .76rem;
    color: var(--ueb-text-soft);
    border-top: 1px solid var(--ueb-border);
}
.portal-preview-foot strong { color: var(--ueb-text); font-weight: 600; }

/* -------------------------------------------------------------------------
   8. DIALOGUES
   ------------------------------------------------------------------------- */
.portal-dialog {
    margin: auto;
    width: min(900px, calc(100% - 2rem));
    max-height: 90dvh;
    padding: 0;
    border: 1px solid var(--ueb-border);
    border-radius: var(--ueb-radius-lg);
    background: var(--ueb-surface);
    color: var(--ueb-text);
    box-shadow: var(--ueb-shadow-lg);
    overflow: hidden;
}
.portal-dialog--small { width: min(520px, calc(100% - 2rem)); }
.portal-dialog::backdrop { background: rgba(9, 29, 18, .55); backdrop-filter: blur(3px); }
.portal-dialog[open] { animation: portal-in var(--ueb-slow) var(--ueb-ease) both; }
.portal-dialog-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.35rem 1.6rem 1.1rem;
    border-bottom: 1px solid var(--ueb-border);
}
.portal-dialog-head h2 { font-size: 1.15rem; }
.portal-dialog-head p { font-size: .83rem; margin-top: .15rem; }
.portal-dialog-body {
    padding: 1.5rem 1.6rem;
    overflow-y: auto;
    max-height: calc(90dvh - 13rem);
}
.portal-dialog-actions {
    display: flex;
    justify-content: flex-end;
    gap: .6rem;
    flex-wrap: wrap;
    padding: 1rem 1.6rem;
    border-top: 1px solid var(--ueb-border);
    background: var(--ueb-surface-2);
}
.portal-dialog-actions .portal-spacer { margin-right: auto; }

/* Détail d'un dossier : listes de définitions, pas un tableau. */
.portal-detail-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr));
    gap: 1.25rem;
}
.portal-detail-block h3 {
    font-size: .8rem;
    font-weight: 700;
    color: var(--ueb-text-soft);
    padding-bottom: .4rem;
    border-bottom: 1px solid var(--ueb-border);
    margin-bottom: .6rem;
}
.portal-detail-block dl { margin: 0; display: grid; gap: .5rem; }
.portal-detail-block dt { font-size: .75rem; color: var(--ueb-text-muted); }
.portal-detail-block dd { margin: 0; font-size: .87rem; font-weight: 500; overflow-wrap: anywhere; }

/* -------------------------------------------------------------------------
   9. ÉCRAN DE CONNEXION
   Cadre flottant et verre dépoli, adaptés à la palette institutionnelle.
   Tokens locaux : le thème mémorisé du dashboard ne modifie pas la connexion.
   ------------------------------------------------------------------------- */
@font-face {
    font-family: 'Crimson Pro';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('../fonts/crimson-pro-500.woff2') format('woff2');
}

.ueb-portal--auth {
    --auth-night: #0b2417;
    --auth-green: #123a24;
    --auth-forest: #1a4a2e;
    --auth-gold: #c9a227;
    --auth-gold-light: #e5cc7b;
    --auth-white: #ffffff;
    --auth-muted: #e1e9e3;
    min-height: 100vh;
    min-height: 100svh;
    display: flex;
    align-items: center;
    justify-content: center;
    --auth-frame-space: clamp(12px, 4svh, 60px);
    padding: var(--auth-frame-space) clamp(24px, 6vw, 88px);
    background: linear-gradient(115deg, rgba(6, 24, 14, .4), rgba(6, 24, 14, .1)),
                url('../svg/access-pattern.svg') center / cover,
                var(--auth-night);
}
.portal-auth {
    position: relative;
    isolation: isolate;
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    width: 100%;
    max-width: 1240px;
    min-height: min(660px, calc(100svh - 2 * var(--auth-frame-space)));
    overflow: hidden;
    color: var(--auth-white);
    background: url('../svg/access-pattern.svg') center / cover,
                linear-gradient(118deg, var(--auth-green), var(--auth-forest) 68%, #1c4029);
    border: 1px solid rgba(208, 221, 211, .09);
    border-radius: 3px;
    box-shadow: 0 36px 90px -20px rgba(0, 0, 0, .65), 0 8px 24px rgba(0, 0, 0, .24);
}
.portal-auth-brand {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 3rem;
    min-width: 0;
    padding: 3rem 0 2.75rem clamp(2rem, 4.5vw, 4.25rem);
}
.portal-auth-logo {
    display: inline-flex;
    align-items: center;
    gap: .85rem;
    color: var(--auth-white);
    text-decoration: none;
}
.portal-auth-logo img {
    width: 54px;
    height: 54px;
    flex-shrink: 0;
    object-fit: contain;
    padding: 3px;
    background: var(--auth-white);
    border-radius: 50%;
}
.portal-auth-logo span {
    font-family: 'Sora', sans-serif;
    font-size: .9rem;
    font-weight: 600;
    line-height: 1.6;
}
.portal-auth-logo small {
    display: block;
    color: var(--auth-muted);
    font-family: 'Inter', sans-serif;
    font-size: .75rem;
    font-weight: 400;
}
.portal-auth-statement { margin-block: auto; }
.portal-auth-statement h1 {
    font-family: 'Crimson Pro', Georgia, serif;
    font-size: clamp(3.3rem, 6vw, 5.25rem);
    line-height: 1.03;
    letter-spacing: -.025em;
    font-weight: 500;
}
.portal-auth-line { display: block; overflow: hidden; }
.portal-auth-line > span { display: block; padding-bottom: .06em; }
.portal-auth-rule {
    display: block;
    width: 3rem;
    height: 2px;
    margin: 1.7rem 0;
    background: var(--auth-gold-light);
    transform-origin: left center;
}
.portal-auth-lede {
    max-width: 35ch;
    color: var(--auth-muted);
    font-size: .9rem;
    line-height: 1.85;
}
.portal-auth-public {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .6rem;
    min-height: 44px;
    margin-top: 1.8rem;
    padding: .6rem 1.15rem;
    border: 1px solid rgba(229, 204, 123, .65);
    border-radius: 999px;
    background: rgba(201, 162, 39, .07);
    color: var(--auth-gold-light);
    font-size: .8rem;
    text-decoration: none;
    transition: background 180ms ease, color 180ms ease;
}
.portal-auth-public:hover { background: var(--auth-gold-light); color: var(--auth-green); }
.portal-auth-motto { color: var(--auth-muted); font-size: .75rem; letter-spacing: .1em; }
.portal-auth-panel {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    padding: 3rem clamp(2rem, 4vw, 3.5rem) 3rem 1.5rem;
}
.portal-auth-inner {
    width: 100%;
    max-width: 420px;
    padding: 2.65rem 2.2rem 2rem;
    color: var(--auth-white);
    background: linear-gradient(135deg, rgba(255, 255, 255, .13), rgba(255, 255, 255, .065));
    border: 1px solid rgba(255, 255, 255, .2);
    border-radius: 3px;
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    box-shadow: 0 18px 45px -22px rgba(0, 0, 0, .35), inset 0 1px 0 rgba(255, 255, 255, .08);
}
.portal-auth-inner h2 {
    color: var(--auth-white);
    text-align: center;
    font-size: 1.9rem;
    font-weight: 700;
    letter-spacing: -.04em;
    margin-bottom: .65rem;
}
.portal-auth-inner > p:not(.portal-auth-trust) {
    color: var(--auth-muted);
    text-align: center;
    font-size: .83rem;
    line-height: 1.7;
    margin-bottom: 1.8rem;
}
.portal-auth-inner .portal-form { gap: 1.15rem; }
.portal-auth-inner .portal-form :where(label) { color: var(--auth-white); font-size: .8rem; }
.ueb-portal .portal-auth-inner .portal-form input:not([type='checkbox']) {
    min-height: 48px;
    padding: .7rem 1.1rem;
    border: 1px solid rgba(255, 255, 255, .6);
    border-radius: 999px;
    background: rgba(9, 35, 21, .3);
    color: var(--auth-white);
    font-size: 1rem;
    caret-color: var(--auth-gold-light);
    transition: background 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
}
.ueb-portal .portal-auth-inner .portal-form input:not([type='checkbox']):hover { border-color: var(--auth-muted); }
.ueb-portal .portal-auth-inner .portal-form input:not([type='checkbox']):focus {
    border-color: var(--auth-gold-light);
    background: rgba(9, 35, 21, .55);
    box-shadow: 0 0 0 3px rgba(229, 204, 123, .18);
    outline: 2px solid transparent;
    outline-offset: 2px;
}
.ueb-portal .portal-auth-inner .portal-password input { padding-right: 3.25rem; }
.portal-auth-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .25rem .65rem;
}
.portal-auth-row .portal-check { min-height: 44px; font-size: .75rem; gap: .45rem; }
.portal-auth-inner .portal-check input { accent-color: var(--auth-gold-light); width: 17px; height: 17px; }
.portal-auth-row a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    color: var(--auth-gold-light);
    font-size: .75rem;
}
.portal-auth-row a:hover { color: var(--auth-white); }
.portal-auth-inner .portal-auth-submit {
    width: 100%;
    min-height: 48px;
    margin-top: .15rem;
    padding: .8rem 1.1rem;
    border: 1px solid var(--auth-gold);
    border-radius: 999px;
    color: var(--auth-night);
    background: linear-gradient(110deg, var(--auth-gold-light), var(--auth-gold));
    font-size: .9rem;
    font-weight: 600;
    box-shadow: 0 8px 20px -10px rgba(201, 162, 39, .5);
    transition: box-shadow 180ms ease, filter 180ms ease;
}
.portal-auth-inner .portal-auth-submit:hover { filter: brightness(1.08); box-shadow: 0 8px 24px -8px rgba(201, 162, 39, .5); }
.portal-auth-inner .portal-auth-submit:active { filter: brightness(.95); }
.portal-auth-back {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    min-height: 44px;
    margin-top: 1rem;
    color: var(--auth-muted);
    font-size: .8rem;
    text-decoration: none;
}
.portal-auth-back:hover { color: var(--auth-gold-light); }
.portal-auth-inner .portal-auth-trust {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    gap: .5rem;
    margin: 1.5rem 0 0;
    padding-top: 1.15rem;
    border-top: 1px solid rgba(255, 255, 255, .18);
    color: var(--auth-muted);
    font-size: .75rem;
    line-height: 1.65;
}
.portal-auth-trust .admin-icon { flex-shrink: 0; margin-top: .1rem; color: var(--auth-gold-light); }
.portal-auth .portal-notice { color: #14201a; background: #fff1ee; border-color: #c67b70; }
.portal-auth .portal-notice--ok { background: #ecf6ee; border-color: #6ca17a; }
.portal-auth .portal-notice--error .admin-icon { color: #b3261e; }
.portal-auth .portal-notice--ok .admin-icon { color: #1f6f43; }
.portal-auth :focus-visible { outline-color: var(--auth-gold-light); }

/* Révélation du mot de passe : bouton natif, nommé et accessible au toucher. */
.portal-password { position: relative; display: flex; align-items: center; }
.portal-password input { width: 100%; padding-right: 3rem; }
.portal-password button {
    position: absolute;
    right: .35rem;
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border: 0;
    border-radius: var(--ueb-radius-sm);
    color: var(--ueb-text-muted);
    background: transparent;
}
.portal-password button:hover { color: var(--ueb-text); background: var(--ueb-surface-hover); }
.portal-auth .portal-password button { right: .2rem; width: 44px; height: 44px; border-radius: 50%; color: var(--auth-muted); }
.portal-auth .portal-password button:hover { color: var(--auth-white); background: rgba(255, 255, 255, .12); }

/* -------------------------------------------------------------------------
   10. MOUVEMENT
   Durées et courbes du tableau de bord (--ueb-*), cascade de 45 ms, plafonnée
   à 8 éléments : au-delà, les derniers paraissent en retard.
   ------------------------------------------------------------------------- */
@keyframes portal-in {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}
@keyframes portal-rise {
    from { transform: translateY(110%); }
    to   { transform: translateY(0); }
}
@keyframes portal-draw { to { stroke-dashoffset: 0; } }
@keyframes portal-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes portal-pulse { from { opacity: .45; } to { opacity: .85; } }
@keyframes portal-pop {
    0%   { opacity: 0; transform: scale(.9); }
    70%  { transform: scale(1.02); }
    100% { opacity: 1; transform: scale(1); }
}
.portal-reveal {
    animation: portal-in 420ms var(--ueb-ease) both;
    animation-delay: var(--delay, 0ms);
}
/* Seul le dernier <path> porte le tracé : dans la courbe du chiffre
   dominant, le premier est l'aire remplie, qui ne doit pas se dessiner. */
.portal-spark path:last-child,
.portal-headline-spark path:last-child {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    animation: portal-draw 850ms var(--ueb-ease) 180ms forwards;
}

/* Séquence d'ouverture de la connexion : un seul enchaînement, 0 → 700 ms. */
.portal-auth-logo      { animation: portal-pop 460ms var(--ueb-spring) both; }
.portal-auth-line > span { animation: portal-rise 640ms var(--ueb-ease) both; }
.portal-auth-line:nth-child(1) > span { animation-delay: 140ms; }
.portal-auth-line:nth-child(2) > span { animation-delay: 220ms; }
.portal-auth-rule      { animation: portal-fill 520ms var(--ueb-ease) 380ms both; }
.portal-auth-lede      { animation: portal-in 420ms var(--ueb-ease) 460ms both; }
.portal-auth-motto     { animation: portal-in 320ms var(--ueb-ease) 720ms both; }
.portal-auth-inner     { animation: portal-in 480ms var(--ueb-ease) 300ms both; }
.portal-auth-trust     { animation: portal-in 380ms var(--ueb-ease) 820ms both; }
/* -------------------------------------------------------------------------
   11. RESPONSIVE
   ------------------------------------------------------------------------- */
@media (max-width: 1240px) {
    .portal-grid-2,
    .portal-grid-3,
    .portal-split { grid-template-columns: minmax(0, 1fr); }
    .portal-wizard { grid-template-columns: minmax(0, 1fr); }
    .portal-preview { position: static; }
}

@media (max-width: 1024px) {
    .portal-headline { grid-template-columns: minmax(0, 1fr); align-items: start; }
    .portal-headline-spark { height: 62px; }
}

@media (max-width: 900px) {
    /* Le portail compte jusqu'à huit entrées de menu, contre trois onglets
       pour le tableau de bord : la rangée doit défiler horizontalement au
       lieu de se casser en trois lignes illisibles. */
    .ueb-portal .admin-sidebar { gap: .75rem; }
    .ueb-portal .admin-sidebar-nav {
        flex-wrap: nowrap;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        scrollbar-width: thin;
        padding-bottom: .2rem;
    }
    .ueb-portal .admin-sidebar-nav a.admin-tab-btn {
        /* width:auto annule le width:100% de la version colonne, sinon la
           première entrée occupe toute la largeur et cache les suivantes. */
        width: auto;
        flex: 0 0 auto;
        white-space: nowrap;
        padding: .55rem .8rem;
        font-size: .84rem;
    }
    .portal-main { padding: 1.25rem 1.25rem 2.5rem; }
    .portal-headline { padding: 1.5rem 1.35rem 1.35rem; }
    .portal-satellites { gap: 0 1.5rem; }
    .portal-satellite { padding-right: 1.5rem; }
}

@media (max-width: 620px) {
    .portal-main { padding: 1.1rem 1rem 2.5rem; }
    .portal-headline { padding: 1.35rem 1.1rem 1.2rem; border-radius: var(--ueb-radius); }
    .portal-headline-value { font-size: clamp(3rem, 16vw, 4rem); }
    .portal-satellites {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: .35rem 1rem;
    }
    .portal-satellite { border-right: 0; padding-right: 0; }
    .portal-satellite-value { font-size: 1.2rem; }
    .portal-est-grid { grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr)); }
    .portal-est-value { font-size: 1.7rem; }
    .portal-panel { padding: 1.1rem 1rem 1.2rem; }
    .portal-filters { gap: .6rem; }
    .portal-field--grow { flex-basis: 100%; }
    .portal-switcher { width: 100%; }
    .portal-switcher select { flex: 1; max-width: none; }
    .portal-dialog-body { padding: 1.15rem 1.1rem; }
    .portal-dialog-head { padding: 1.1rem 1.1rem .9rem; }
    .portal-dialog-actions { padding: .9rem 1.1rem; }
    .portal-dialog-actions .portal-spacer { margin-right: 0; width: 100%; }
    .portal-steps li span { display: none; }

}

/* Connexion : garder deux colonnes seulement si le formulaire respire. */
@media (max-width: 1100px) {
    .ueb-portal--auth { padding-inline: 2rem; }
    .portal-auth-brand { padding-left: 2.5rem; }
    .portal-auth-panel { padding-right: 2rem; }
    .portal-auth-inner { padding-inline: 1.6rem; }
}
@media (max-width: 800px) {
    .ueb-portal--auth { --auth-frame-space: 12px; padding-inline: 12px; }
    .portal-auth { grid-template-columns: minmax(0, 1fr); min-height: auto; max-width: 580px; background-position: 58% top; }
    .portal-auth-brand { padding: 1rem 1.5rem 0; gap: .75rem; }
    .portal-auth-logo img { width: 44px; height: 44px; }
    .portal-auth-statement h1 { font-size: clamp(1.65rem, 6vw, 2rem); }
    .portal-auth-line, .portal-auth-line > span { display: inline; }
    .portal-auth-statement { margin: 0; }
    .portal-auth-rule,
    .portal-auth-lede,
    .portal-auth-motto,
    .portal-auth-inner .portal-auth-trust,
    .portal-auth--login .portal-auth-inner > p { display: none; }
    .portal-auth-public { min-height: 44px; margin-top: .25rem; padding: .35rem 0; border: 0; background: transparent; }
    .portal-auth-panel { padding: .5rem 1rem 1rem; }
    .portal-auth-inner { max-width: none; padding: 1rem; }
    .portal-auth-inner h2 { font-size: 1.5rem; margin-bottom: .75rem; }
    .portal-auth-inner .portal-form { gap: .75rem; }
    .portal-auth-inner > p:not(.portal-auth-trust) { margin-bottom: 1rem; }
}
@media (max-width: 420px) {
    .ueb-portal--auth { --auth-frame-space: 8px; padding-inline: 8px; }
    .portal-auth-brand { padding: .75rem 1rem 0; }
    .portal-auth-logo { gap: .65rem; }
    .portal-auth-logo span { font-size: .78rem; }
    .portal-auth-logo small { font-size: .75rem; }
    .portal-auth-panel { padding: .5rem; }
    .portal-auth-inner { padding: .75rem; }
}

/* Les écrans courts réduisent les espacements avant les contrôles.
   Pas de blocage du scroll : zoom, clavier virtuel et erreurs restent accessibles. */
@media (max-height: 800px) and (min-width: 801px) {
    .portal-auth-brand { padding-block: 1.5rem; gap: 1.5rem; }
    .portal-auth-panel { padding-block: 1.25rem; }
    .portal-auth-inner { padding-block: 1.5rem; }
    .portal-auth-inner > p:not(.portal-auth-trust) { margin-bottom: 1rem; }
    .portal-auth-inner .portal-form { gap: .75rem; }
    .portal-auth-inner .portal-auth-trust { margin-top: 1rem; padding-top: .75rem; }
    .portal-auth-rule { margin-block: 1.25rem; }
    .portal-auth-public { margin-top: 1rem; }
}
@media (max-height: 650px) {
    .ueb-portal--auth { --auth-frame-space: 8px; }
    .portal-auth-inner { padding-block: .75rem; }
    .portal-auth-inner h2 { font-size: 1.4rem; margin-bottom: .6rem; }
    .portal-auth-inner .portal-form { gap: .5rem; }
    .portal-auth-inner .portal-auth-trust,
    .portal-auth--login .portal-auth-inner > p,
    .portal-auth-motto { display: none; }
    .portal-auth-panel { padding-block: .5rem; }
    .portal-auth-statement h1 { font-size: clamp(1.65rem, 4.6vw, 3.25rem); }
    .portal-auth-brand { gap: .75rem; }
    .portal-auth .portal-notice { padding: .5rem .75rem; margin-bottom: .75rem; }
}
@media (max-height: 650px) and (max-width: 800px) {
    .portal-auth--reset .portal-auth-logo,
    .portal-auth:has(.portal-notice) .portal-auth-logo { display: none; }
}
@media (max-height: 500px) and (min-width: 600px) {
    .ueb-portal--auth { padding-inline: 12px; }
    .portal-auth { grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); max-width: 1240px; }
    .portal-auth-brand { padding: 1rem 1.5rem; }
    .portal-auth-logo { display: inline-flex; }
    .portal-auth-statement { margin-block: auto; }
    .portal-auth-line, .portal-auth-line > span { display: block; }
    .portal-auth-rule, .portal-auth-lede { display: none; }
    .portal-auth-panel { padding-inline: .5rem; }
    .portal-auth-inner {
        padding-inline: .85rem;
        animation: none;
        /* Sans flou, les messages positionnés se rattachent au cadre global. */
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }
    .portal-auth-back { margin-top: .25rem; }
    .portal-auth--login:has(.portal-notice) .portal-auth-brand,
    .portal-auth--reset:not(:has(.portal-notice)) .portal-auth-brand { padding-bottom: 7rem; }
    .portal-auth--login .portal-notice,
    .portal-auth--reset:not(:has(.portal-notice)) .portal-auth-inner > p:not(.portal-auth-trust) {
        position: absolute;
        bottom: 1rem;
        left: 1.5rem;
        width: calc(100% / 2.2 - 3rem);
        margin: 0;
        text-align: left;
    }
}

/* -------------------------------------------------------------------------
   12. MOUVEMENT RÉDUIT ET IMPRESSION
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .ueb-portal *,
    .ueb-portal *::before,
    .ueb-portal *::after {
        animation-duration: 1ms !important;
        animation-delay: 0ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 1ms !important;
        scroll-behavior: auto !important;
    }
    .portal-spark path:last-child,
    .portal-headline-spark path:last-child { stroke-dashoffset: 0; }
}

@media print {
    .admin-sidebar,
    .portal-toolbar,
    .portal-filters,
    .portal-pagination,
    .admin-topbar-actions { display: none !important; }
    .portal-panel,
    .portal-headline,
    .portal-est-card { box-shadow: none; break-inside: avoid; }
}
