:root {
  --portal-blue: #373cf5;
  --portal-ink: #0a1551;
  --portal-muted: #68708d;
  --portal-border: #e5e7f0;
  --portal-surface: #fff;
}

body {
  margin: 0;
  color: var(--portal-ink);
  background: #f5f6fb;
  font-family: var(--cci-font-family, "Fira Sans", "Segoe UI", Arial, sans-serif);
  -webkit-font-smoothing: antialiased;
}

button,
input,
select {
  font: inherit;
}

.cci-brand-monogram {
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: -.04em;
}

.portal-library {
  min-width: 320px;
  background: #f7f8fc;
}

.portal-library-header {
  position: sticky;
  z-index: 20;
  top: 0;
  border-bottom: 1px solid var(--portal-border);
  background: rgba(255, 255, 255, .97);
}

.portal-library-header-inner {
  display: flex;
  width: min(100% - 48px, 1240px);
  min-height: 76px;
  gap: 28px;
  align-items: center;
  justify-content: space-between;
  margin: 0 auto;
}

.portal-library-brand {
  display: inline-flex;
  flex: 0 0 auto;
  gap: 11px;
  align-items: center;
  color: var(--portal-ink);
  text-decoration: none;
}

.portal-library-brandmark {
  display: inline-grid;
  width: 42px;
  height: 42px;
  place-items: center;
  border-radius: 11px;
  color: #fff;
  background: var(--portal-blue);
}

.portal-library-brandmark img,
.portal-login-brandmark img {
  display: block;
  width: 24px;
  height: 28px;
}

.portal-library-brandcopy {
  display: grid;
  line-height: 1.12;
}

.portal-library-brandcopy strong {
  font-size: 17px;
  font-weight: 700;
}
.portal-library-brandcopy small {
  margin-top: 3px;
  color: var(--portal-muted);
  font-size: 11px;
}

.portal-library-nav {
  display: flex;
  align-self: stretch;
  align-items: center;
}

.portal-library-nav a {
  display: inline-flex;
  height: 100%;
  align-items: center;
  border-bottom: 3px solid transparent;
  color: #4f5774;
  font-size: 14px;
  font-weight: 700;
  text-decoration: none;
}

.portal-library-nav a.active {
  border-bottom-color: var(--portal-blue);
  color: var(--portal-ink);
}

.portal-library-account {
  display: flex;
  min-width: 0;
  gap: 10px;
  align-items: center;
}

.portal-library-admin,
.portal-library-logout {
  display: inline-flex;
  min-height: 36px;
  align-items: center;
  justify-content: center;
  padding: 7px 11px;
  border: 1px solid var(--portal-border);
  border-radius: 9px;
  color: var(--portal-ink);
  background: #fff;
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

/* L'administration doit se reconnaître au premier coup d'œil, qu'elle soit
   globale ici ou propre à un outil sur sa carte. Ce bloc reprend donc
   l'apparence de .cci-tool-admin-link : même capsule, même bleu clair, même
   bordure, même bouclier. */
.portal-library-admin {
  gap: 7px;
  padding: 8px 14px;
  border-color: #cfd2ff;
  border-radius: var(--cci-radius-pill, 999px);
  color: #272bbb;
  background: var(--portal-blue-soft, #eeefff);
}

.portal-library-admin svg {
  width: 15px;
  height: 15px;
  flex: 0 0 15px;
  fill: currentColor;
}

.portal-library-admin:hover {
  color: #171b94;
  background: #e4e5ff;
}

.portal-library-logout:hover { background: #f0f1f7; }

.portal-library-avatar {
  display: inline-grid;
  width: 36px;
  height: 36px;
  flex: 0 0 36px;
  place-items: center;
  border-radius: 50%;
  color: #fff;
  background: #11183b;
  font-size: 11px;
  font-weight: 700;
}

.portal-library-identity {
  display: grid;
  min-width: 0;
  max-width: 190px;
  line-height: 1.2;
}

.portal-library-identity strong,
.portal-library-identity small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.portal-library-identity strong { font-size: 12px; }
.portal-library-identity small {
  margin-top: 3px;
  color: var(--portal-muted);
  font-size: 10px;
}

.portal-library-account form { margin: 0; }
.portal-compact-label { display: none; }

.portal-library-main {
  width: min(100% - 48px, 1240px);
  min-height: calc(100vh - 164px);
  margin: 0 auto;
  padding: 52px 0 64px;
}

.portal-library-hero {
  max-width: 790px;
  padding: 18px 0 44px;
}

.portal-library-eyebrow {
  display: block;
  margin-bottom: 13px;
  color: var(--portal-blue);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.portal-library-hero h1 {
  margin: 0;
  color: var(--portal-ink);
  font-size: clamp(34px, 5vw, 54px);
  line-height: 1.02;
  letter-spacing: -.045em;
}

.portal-library-hero p {
  max-width: 720px;
  margin: 18px 0 0;
  color: var(--portal-muted);
  font-size: 17px;
  line-height: 1.62;
}

.portal-library-hero p strong {
  color: var(--portal-ink);
  font-weight: 600;
}

.portal-library-section-header {
  display: flex;
  gap: 24px;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 20px;
}

.portal-library-section-header h2 {
  margin: 0;
  font-size: 24px;
  letter-spacing: -.025em;
}

.portal-library-section-header p {
  margin: 5px 0 0;
  color: var(--portal-muted);
  font-size: 14px;
}

.portal-library-count {
  flex: 0 0 auto;
  color: var(--portal-muted);
  font-size: 13px;
  font-weight: 700;
}

.portal-catalogue {
  display: grid;
  gap: 42px;
}

.portal-category-header {
  display: flex;
  gap: 16px;
  align-items: center;
  margin-bottom: 15px;
}

.portal-category-header::after {
  height: 1px;
  flex: 1;
  background: var(--portal-border);
  content: "";
}

.portal-category-header h3 {
  margin: 0;
  color: var(--portal-ink);
  font-size: 16px;
  letter-spacing: -.015em;
}

.portal-category-header span {
  order: 3;
  color: var(--portal-muted);
  font-size: 11px;
  font-weight: 600;
}

.portal-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 18px;
}

.portal-tool-card {
  position: relative;
  display: flex;
  min-height: 330px;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--portal-border);
  border-radius: 16px;
  background: var(--portal-surface);
  box-shadow: 0 1px 3px rgba(10, 21, 81, .04);
  transition: transform 160ms ease;
}

.portal-tool-card:hover {
  border-color: #d4d7e8;
  box-shadow: 0 14px 32px rgba(10, 21, 81, .07);
  transform: translateY(-2px);
}

.portal-tool-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  padding: 22px;
}

.portal-tool-topline {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  justify-content: space-between;
}

.portal-tool-icon {
  display: block;
  width: 56px;
  height: 56px;
  flex: 0 0 56px;
}

.portal-tool-icon img {
  display: block;
  width: 100%;
  height: 100%;
}

.portal-tool-copy { margin-top: 22px; }

.portal-tool-card h4 {
  margin: 0;
  color: var(--portal-ink);
  font-size: 20px;
  letter-spacing: -.025em;
}

.portal-tool-card p {
  margin: 10px 0 0;
  color: var(--portal-muted);
  font-size: 14px;
  line-height: 1.55;
}

.portal-tool-permission {
  display: grid;
  gap: 3px;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid #eff0f6;
  color: #353c5e;
  font-size: 12px;
  font-weight: 700;
}

.portal-tool-permission small {
  color: var(--portal-muted);
  font-size: 11px;
  font-weight: 500;
}

.portal-tool-actions {
  display: flex;
  gap: 13px;
  align-items: flex-start;
  flex-direction: column;
  margin-top: auto;
  padding-top: 22px;
}

.portal-tool-actions .cci-tool-admin-link {
  width: auto;
  min-width: 0;
  padding: 8px 14px;
}

.portal-tool-actions .cci-tool-admin-link span { display: inline; }

.portal-badge {
  display: inline-flex;
  min-height: 26px;
  align-items: center;
  padding: 4px 9px;
  border: 1px solid #d7daf1;
  border-radius: 7px;
  color: #394061;
  background: #f6f7fb;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}

.portal-badge.admin {
  border-color: #cfd2ff;
  color: #272bbb;
  background: #eeefff;
}

/* Un outil ouvert et un outil à venir ne doivent pas se ressembler : la couleur
   porte l'information, et le libellé la confirme pour qui ne la distingue pas.
   Jetons repris du design system commun (cci-front.css). */
.portal-badge.available {
  border-color: #b7e3c6;
  color: var(--cci-success, #18733b);
  background: var(--cci-success-soft, #e8f7ee);
}

.portal-badge.soon {
  border-color: #f0dca8;
  color: var(--cci-warning, #815900);
  background: var(--cci-warning-soft, #fff4d5);
}

.portal-library-footer {
  display: flex;
  width: min(100% - 48px, 1240px);
  min-height: 88px;
  align-items: center;
  justify-content: space-between;
  margin: 0 auto;
  border-top: 1px solid var(--portal-border);
  color: var(--portal-muted);
  font-size: 12px;
}

.portal-library-footer a { color: var(--portal-muted); text-decoration: underline; }
.portal-library-footer a:hover { color: var(--portal-blue); }

.portal-btn {
  display: inline-flex;
  min-height: 42px;
  align-items: center;
  justify-content: center;
  padding: 9px 16px;
  border: 1px solid transparent;
  border-radius: 999px;
  color: #fff !important;
  background: var(--portal-blue);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

.portal-btn:hover { background: #292ed2; }
.portal-btn.secondary {
  border-color: var(--portal-border);
  color: var(--portal-ink) !important;
  background: #fff;
}
.portal-btn.secondary:hover { background: #f4f5fa; }
.portal-btn.danger { background: #a32626; }
.portal-btn.small { min-height: 34px; padding: 6px 11px; font-size: 13px; }
.portal-btn.block { width: 100%; }
.portal-btn[aria-disabled="true"] {
  color: #858ca7 !important;
  background: #eceef5;
  cursor: not-allowed;
  pointer-events: none;
}

.portal-tool-primary {
  gap: 16px;
  min-width: 156px;
  justify-content: space-between;
  box-shadow: 0 6px 16px rgba(55, 60, 245, .16);
}

.portal-btn-arrow {
  font-size: 19px;
  font-weight: 400;
  line-height: 1;
  transition: transform 160ms ease;
}

.portal-tool-primary:hover .portal-btn-arrow {
  transform: translateX(2px);
}

/* Reprend l'ambre de l'étiquette « Bientôt disponible » : les deux marques
   d'une même carte disent la même chose et doivent le dire de la même façon. */
.portal-coming-soon {
  display: inline-flex;
  min-height: 34px;
  gap: 8px;
  align-items: center;
  color: var(--cci-warning, #815900);
  font-size: 13px;
  font-weight: 600;
}

.portal-coming-soon-dot {
  width: 7px;
  height: 7px;
  border-radius: 2px;
  background: var(--cci-warning, #815900);
}

.portal-panel {
  overflow: hidden;
  border: 1px solid var(--portal-border);
  border-radius: 16px;
  background: #fff;
  box-shadow: 0 1px 3px rgba(10, 21, 81, .05);
}

.portal-panel + .portal-panel { margin-top: 20px; }

.portal-panel-header {
  display: flex;
  gap: 20px;
  align-items: flex-start;
  justify-content: space-between;
  padding: 22px 24px;
  border-bottom: 1px solid var(--portal-border);
}

/* L'action de droite ne doit pas se comprimer : sans cela, un libellé un peu
   long comme « Synchroniser maintenant » se replie sur deux lignes. */
.portal-panel-header > div { min-width: 0; }

.portal-panel-header > form,
.portal-panel-header > a,
.portal-panel-header > .portal-btn { flex: 0 0 auto; }

.portal-panel-header h2,
.portal-panel-header h3 { margin: 0; font-size: 20px; }
.portal-panel-header p { margin: 6px 0 0; color: var(--portal-muted); line-height: 1.5; }
.portal-panel-body { padding: 24px; }

/* Les titres et textes posés directement dans un panneau, entre deux tableaux,
   doivent s'aligner sur le rembourrage de celui-ci plutôt que toucher ses
   bords. */
.portal-panel > h3,
.portal-panel > p { margin: 22px 24px 10px; }
.portal-panel > h3 { font-size: 15px; color: var(--portal-ink); }

.portal-table-wrap { overflow-x: auto; }
.portal-table { width: 100%; border-collapse: collapse; }
.portal-table th,
.portal-table td {
  padding: 15px 18px;
  border-bottom: 1px solid var(--portal-border);
  text-align: left;
  vertical-align: middle;
}
.portal-table th {
  color: var(--portal-muted);
  background: #fafaff;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
}
.portal-table tr:last-child td { border-bottom: 0; }
.portal-table strong { color: var(--portal-ink); }
.portal-subtext { display: block; margin-top: 3px; color: var(--portal-muted); font-size: 12px; }
.portal-nowrap { white-space: nowrap; }

.portal-form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
}

.portal-field { min-width: 0; }
.portal-field.full { grid-column: 1 / -1; }
.portal-field label {
  display: block;
  margin-bottom: 5px;
  color: var(--portal-ink);
  font-size: 12px;
  font-weight: 600;
}

/* Ces valeurs reprennent exactement celles du socle `cci-admin.css`. La
   répétition est voulue : les écrans de connexion, de code et de mot de passe
   utilisent ces champs sans être dans un `.cci-admin`, et n'auraient donc
   aucune mise en forme. Toute retouche se fait des deux côtés — un écart de
   deux pixels sur la bordure ou le rayon suffit à rendre l'ensemble
   disparate. */
.portal-field input,
.portal-field select {
  width: 100%;
  min-height: 38px;
  padding: 8px 11px;
  border: 1px solid #d8dce8;
  border-radius: 8px;
  font-size: 14px;
  color: var(--portal-ink);
  background: #fff;
}
.portal-field input:focus,
.portal-field select:focus {
  outline: none;
  border-color: var(--portal-blue);
  box-shadow: 0 0 0 3px var(--cci-primary-soft, rgba(55, 60, 245, .13));
}

@media (pointer: coarse) {
  .portal-field input,
  .portal-field select { min-height: 44px; padding: 10px 12px; }
}
.portal-help { display: block; margin-top: 6px; color: var(--portal-muted); font-size: 12px; line-height: 1.45; }

/* Les périmètres alignent parfois huit établissements les uns sous les autres :
   la même densité que les champs évite d'en faire une colonne interminable. */
.portal-check {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  min-height: 34px;
  padding: 7px 11px;
  border: 1px solid var(--portal-border);
  border-radius: 8px;
}
.portal-check input {
  flex: 0 0 16px;
  width: 16px;
  min-height: 0;
  height: 16px;
  margin: 2px 0 0;
  padding: 0;
}
.portal-check span { font-size: 13px; line-height: 1.4; }

/* Barre d'état d'un écran : une propriété rarement modifiée et les liens de
   navigation, tenus hors des panneaux. Leur donner un panneau entier les
   mettrait au même niveau que le sujet de la page. */
.portal-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
  padding: 14px 18px;
  border: 1px solid var(--portal-border);
  border-radius: 12px;
  background: #fff;
}

.portal-toolbar-state {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  min-width: 0;
}

.portal-toolbar-state .portal-hint { margin: 0; }

.portal-toolbar-actions {
  display: flex;
  flex: 0 0 auto;
  gap: 8px;
  align-items: center;
}

/* Barre d'action refermant un panneau : elle suit un tableau, d'où le trait
   de séparation et l'absence de marge propre. */
.portal-panel-body.portal-form-actions {
  margin-top: 0;
  border-top: 1px solid var(--portal-border);
}

.portal-panel-body.portal-panel-body-separee {
  border-top: 1px solid var(--portal-border);
}

.portal-access-list { display: grid; gap: 12px; }
.portal-access-action { display: flex; align-items: end; }

/* Le périmètre occupe sa propre ligne : coincé dans une quatrième colonne, il
   comprimerait le nom et le rôle, et ses cases deviendraient illisibles. */
.portal-access-scope {
  grid-column: 1 / -1;
  padding-top: 12px;
  border-top: 1px solid var(--portal-border);
}
.portal-access-row {
  display: grid;
  grid-template-columns: minmax(170px, 1fr) minmax(220px, 1.2fr) minmax(180px, 1fr);
  gap: 14px;
  align-items: end;
  padding: 16px;
  border: 1px solid var(--portal-border);
  border-radius: 12px;
}
.portal-access-name strong { display: block; margin-bottom: 4px; }
.portal-access-name small { color: var(--portal-muted); }

.portal-form-actions {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-top: 22px;
}

.portal-alert {
  margin-bottom: 18px;
  padding: 13px 15px;
  border: 1px solid transparent;
  border-radius: 10px;
  line-height: 1.45;
}
.portal-alert-success { border-color: #bee2ca; color: #125c31; background: #e8f7ee; }
.portal-alert-danger { border-color: #efc5c5; color: #8a2020; background: #fdecec; }
.portal-alert-warning { border-color: #f0dba5; color: #725000; background: #fff4d5; }

.portal-login-shell {
  display: grid;
  min-height: 100vh;
  grid-template-columns: minmax(280px, .9fr) minmax(420px, 1.1fr);
}

.portal-login-brand {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: clamp(32px, 6vw, 72px);
  color: #fff;
  background: #11183b;
}
.portal-login-brandmark {
  display: inline-grid;
  width: 54px;
  height: 54px;
  place-items: center;
  border-radius: 14px;
  background: var(--portal-blue);
}

.portal-login-brandmark img {
  width: 31px;
  height: 34px;
}
/* Le nom du site, pas le titre de la page : celui-ci est dans la carte, avec
   la tâche demandée. D'où un paragraphe mis en forme plutôt qu'un `h1`, qui
   aurait disputé la première place au vrai titre. */
.portal-login-name {
  max-width: 530px;
  margin: 42px 0 12px;
  font-size: clamp(34px, 5vw, 62px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.05em;
}
.portal-login-signature {
  max-width: 500px;
  margin: 0;
  color: #bfc6df;
  font-size: 17px;
  line-height: 1.6;
}

.portal-login-points {
  max-width: 460px;
  margin: 34px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 18px;
}

.portal-login-points li {
  padding-left: 15px;
  border-left: 2px solid rgba(255, 255, 255, .16);
}

.portal-login-points strong {
  display: block;
  margin-bottom: 3px;
  color: #fff;
  font-size: 14px;
  font-weight: 600;
}

.portal-login-points span {
  color: #98a2c4;
  font-size: 13.5px;
  line-height: 1.55;
}

.portal-login-brand small { color: #838dae; }

.portal-login-main {
  display: grid;
  place-items: center;
  padding: 30px;
  background: #f5f6fb;
}
.portal-login-card {
  /* Les écrans d'entrée ne chargeaient que la typographie du socle, pas sa
     règle `box-sizing: border-box` : cette carte a donc été dessinée en
     modèle de boîte natif, sa largeur s'entendant hors rembourrage. Depuis
     que la feuille unique s'applique partout, la conserver telle quelle
     demande de le dire explicitement — sans quoi la carte perdrait d'un coup
     la largeur de ses deux rembourrages, soit environ 85 px. */
  box-sizing: content-box;
  width: min(100%, 440px);
  padding: clamp(26px, 5vw, 42px);
  border: 1px solid var(--portal-border);
  border-radius: 18px;
  background: #fff;
  box-shadow: 0 18px 50px rgba(10, 21, 81, .09);
}
.portal-login-card h1 { margin: 0 0 8px; font-size: 28px; letter-spacing: -.03em; }
.portal-login-intro { margin: 0 0 26px; color: var(--portal-muted); line-height: 1.5; }
.portal-login-card .portal-alert { margin-bottom: 22px; }
/* Le focus posé par `auth.js` ne doit pas dessiner de cadre autour d'un texte
   qu'on ne peut pas atteindre au clavier : il sert à faire lire, pas à
   désigner une cible. */
.portal-login-card .portal-alert:focus { outline: none; }
.portal-login-card .portal-field + .portal-field { margin-top: 16px; }
.portal-login-card .portal-btn { margin-top: 22px; }

.portal-ds-intro,
.portal-ds-section,
.portal-ds-section-heading,
.portal-ds-component-row,
.portal-ds-form-grid,
.portal-ds-swatches,
.portal-ds-type {
  min-width: 0;
}

.portal-ds-intro,
.portal-ds-section-heading {
  display: flex;
  gap: 20px;
  align-items: flex-start;
  justify-content: space-between;
}

.portal-ds-intro {
  margin-bottom: 22px;
  padding: 24px;
  border: 1px solid var(--portal-border);
  border-radius: 16px;
  background: #fff;
}

.portal-ds-intro h2,
.portal-ds-section h2,
.portal-ds-type h3 { margin: 0; color: var(--portal-ink); }
.portal-ds-intro p,
.portal-ds-type p { margin: 8px 0 0; color: var(--portal-muted); line-height: 1.5; }

.portal-ds-kicker {
  display: block;
  margin-bottom: 5px;
  color: var(--portal-blue);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.portal-ds-note { color: var(--portal-muted); font-size: 12px; }

.portal-ds-section {
  margin-bottom: 22px;
  padding: 24px;
  border: 1px solid var(--portal-border);
  border-radius: 16px;
  background: #fff;
}

.portal-ds-section-heading { margin-bottom: 22px; }
.portal-ds-section h2 { font-size: 19px; }

.portal-ds-swatches {
  display: grid;
  grid-template-columns: repeat(4, minmax(130px, 1fr));
  gap: 12px;
}

.portal-ds-swatch {
  display: grid;
  min-width: 0;
  gap: 5px;
  color: var(--portal-ink);
  font-size: 12px;
}

/* La teinte de chaque pastille venait d'un `--swatch` posé en attribut `style`,
   dans le gabarit. Or le portail sert ses pages avec `style-src 'self'` : le
   navigateur ignorait purement et simplement l'attribut, et cette page — celle
   qui présente la palette — affichait quatre carrés vides. Personne ne l'a vu,
   parce qu'un carré sans couleur ne ressemble pas à une erreur.

   Les classes ci-dessous désignent les **jetons** plutôt que des valeurs
   recopiées : la page montre désormais la charte réelle, et suivrait un
   changement de teinte au lieu d'afficher une valeur périmée. */
.portal-ds-swatch > span {
  height: 64px;
  border: 1px solid var(--portal-border);
  border-radius: 12px;
}

.portal-ds-swatch-clair > span       { background: var(--cci-primary-clair); }
.portal-ds-swatch-primaire > span    { background: var(--cci-primary); }
.portal-ds-swatch-fonce > span       { background: var(--cci-primary-fonce); }
.portal-ds-swatch-nuit-charte > span { background: var(--cci-primary-nuit); }
.portal-ds-swatch-nuit > span        { background: var(--cci-sidebar); }
.portal-ds-swatch-fond > span        { background: var(--cci-canvas); }
.portal-ds-swatch-filet > span       { background: var(--cci-border); }
.portal-ds-swatch-second > span      { background: var(--cci-muted); }
.portal-ds-swatch-encre > span       { background: var(--cci-ink); }

.portal-ds-sous-titre {
  margin: 22px 0 10px;
  color: var(--cci-ink);
  font-size: 14px;
  font-weight: 700;
}

.portal-ds-sous-titre:first-of-type { margin-top: 4px; }

/* La règle qui accompagne chaque famille. Une page de design system qui montre
   des couleurs sans dire ce qu'on en fait laisse chacun deviner — et c'est en
   devinant qu'on écrit un nom de service dans une teinte à 2,19 de contraste. */
.portal-ds-regle {
  max-width: 62ch;
  margin: 10px 0 0;
  color: var(--portal-muted);
  font-size: 13px;
  line-height: 1.55;
}

.portal-ds-metiers {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Chaque ligne métier se montre telle qu'elle doit servir : un aplat, avec un
   texte qui n'est pas de sa couleur. */
.portal-ds-metier {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px 5px 8px;
  border: 1px solid var(--cci-border);
  border-radius: var(--cci-radius-pill);
  color: var(--cci-ink);
  font-size: 12.5px;
  font-weight: 600;
}

.portal-ds-metier::before {
  content: "";
  width: 14px;
  height: 14px;
  border-radius: 4px;
  background: var(--m, var(--cci-primary));
}

.portal-ds-swatch small { color: var(--portal-muted); }

.portal-ds-type {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  margin-top: 22px;
}

.portal-ds-type > div {
  padding-top: 18px;
  border-top: 1px solid var(--portal-border);
}

.portal-ds-type > div > span { color: var(--portal-muted); font-size: 11px; }
.portal-ds-type h3 { margin-top: 8px; font-size: 23px; }

.portal-ds-component-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}

.portal-ds-component-row + .portal-ds-component-row { margin-top: 20px; }

.portal-ds-form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  margin-bottom: 18px;
}

.portal-ds-section .portal-alert:last-child { margin-bottom: 0; }
.portal-ds-section .table-scroll { margin-bottom: 18px; }
.portal-ds-section .cci-empty-state p { margin: 7px 0 0; }

@media (max-width: 760px) {
  .portal-ds-intro,
  .portal-ds-section-heading { display: grid; }
  .portal-ds-swatches { grid-template-columns: repeat(2, minmax(120px, 1fr)); }
  .portal-ds-type,
  .portal-ds-form-grid { grid-template-columns: 1fr; }
}
.portal-quiet { color: var(--portal-muted); }

@media (max-width: 900px) {
  .portal-library-identity { display: none; }
  .portal-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .portal-access-row { grid-template-columns: 1fr 1fr; }
  .portal-access-name { grid-column: 1 / -1; }
  .portal-login-shell { grid-template-columns: 1fr; }
  .portal-login-brand { min-height: 270px; }
  .portal-login-brand small { margin-top: 36px; }
  /* La colonne passe au-dessus du formulaire : garder les trois repères
     repousserait le champ email hors de l'écran. Sur une page de connexion,
     l'action doit rester immédiate ; le contexte est un confort. */
  .portal-login-points { display: none; }
}

@media (max-width: 760px) {
  .portal-library-header { position: static; }
  .portal-library-header-inner {
    display: grid;
    width: min(100% - 32px, 1240px);
    min-height: 0;
    grid-template-columns: 1fr auto;
    gap: 12px 10px;
    padding: 14px 0 0;
  }
  .portal-library-brandcopy small { display: none; }
  .portal-library-brandmark {
    width: 38px;
    height: 38px;
  }
  .portal-library-account { gap: 7px; }
  .portal-library-account {
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
  }
  .portal-library-avatar { display: none; }
  .portal-library-admin,
  .portal-library-logout {
    min-height: 34px;
    padding: 6px 9px;
    font-size: 11px;
  }
  .portal-full-label { display: none; }
  .portal-compact-label { display: inline; }
  .portal-library-nav {
    grid-column: 1 / -1;
    grid-row: 2;
    min-height: 42px;
  }
  .portal-library-nav a {
    width: 100%;
    justify-content: center;
  }
  .portal-library-main {
    width: min(100% - 32px, 1240px);
    min-height: 0;
    padding: 30px 0 48px;
  }
  .portal-library-hero { padding: 8px 0 34px; }
  .portal-library-hero p { font-size: 15px; }
  .portal-library-section-header { align-items: flex-start; }
  .portal-grid { grid-template-columns: 1fr; }
  .portal-tool-card { min-height: 280px; }
  .portal-tool-actions { align-items: flex-start; flex-direction: column; }
  .portal-tool-actions .portal-btn { width: auto; max-width: 100%; }
  .portal-admin-link { min-height: 40px; justify-content: center; }
  .portal-library-footer {
    width: min(100% - 32px, 1240px);
    min-height: 92px;
    gap: 6px;
    align-items: flex-start;
    flex-direction: column;
    justify-content: center;
  }
  .portal-form-grid,
  .portal-access-row { grid-template-columns: 1fr; }
  .portal-field.full,
  .portal-access-name { grid-column: auto; }
  .portal-panel-header { flex-direction: column; padding: 19px; }
  .portal-panel-body { padding: 19px; }
  .portal-form-actions { align-items: stretch; flex-direction: column; }
  .portal-form-actions .portal-btn { width: 100%; }
  .portal-login-brand { padding: 32px 24px; }
  .portal-login-main { padding: 18px; }
  .portal-login-card { padding: 25px 20px; }
  .portal-filters { grid-template-columns: 1fr; }
  .portal-filters-actions { justify-content: stretch; }
}

/* ── Invitation depuis la fiche d'un compte ───────────────────────────────── */

.portal-invite {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
  margin-top: 24px;
  padding: 18px 20px;
  border: 1px solid var(--portal-border);
  border-radius: 14px;
  background: #fff;
}

.portal-invite .portal-help { margin-top: 4px; }

/* ── Renvois sous un formulaire de connexion ──────────────────────────────── */

.portal-login-aside {
  display: grid;
  gap: 3px;
  margin: 18px 0 0;
  text-align: center;
}

.portal-login-aside a { color: var(--portal-blue); font-size: 14px; font-weight: 600; }
.portal-login-aside span { color: var(--portal-muted); font-size: 12.5px; }

/* Six chiffres se lisent et se vérifient mieux espacés, en chasse fixe. */
.portal-code-input {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 22px;
  letter-spacing: 8px;
  text-align: center;
}

/* ── Sortie de secours d'un écran obligatoire ─────────────────────────────── */
/* Le changement de mot de passe bloque tout le reste : la déconnexion doit
   rester possible, sans concurrencer l'action attendue. D'où un lien discret
   plutôt qu'un second bouton. */

.portal-login-secondary { margin-top: 18px; text-align: center; }

.portal-link-button {
  padding: 6px 4px;
  border: 0;
  background: none;
  color: var(--portal-muted);
  font: inherit;
  font-size: 13px;
  text-decoration: underline;
  cursor: pointer;
}

.portal-link-button:hover { color: var(--portal-blue); }

/* ── Recherche et pagination d'une longue liste ───────────────────────────── */
/* L'annuaire dépasse la centaine de comptes : on ne parcourt plus une liste,
   on cherche dedans. Le filtre est traité côté serveur, sans quoi la page
   chargerait tout pour n'en montrer qu'une partie. */

.portal-filters {
  display: grid;
  gap: 16px;
  align-items: end;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) auto;
}

.portal-filters-actions {
  display: flex;
  gap: 10px;
  align-items: center;
}

.portal-hint { color: var(--portal-muted); font-size: 13px; line-height: 1.5; }

/* Sept réglages d'espacement vivaient en attribut `style` dans les gabarits
   d'administration. Le portail servant ses pages avec `style-src 'self'`, le
   navigateur les ignorait : ces écrans s'affichaient avec la marge par défaut
   du paragraphe, soit seize pixels de trop, sans que rien ne le signale.

   La marge n'est pas retirée de `.portal-hint` elle-même : cinq de ses onze
   usages la veulent, ceux qui suivent un titre et ont besoin d'en être
   détachés. Ce sont donc des variantes, et chacune dit ce qu'elle fait. */
.portal-hint-sans-marge { margin: 0; }
.portal-hint-espacee { margin: 16px 0 0; }
.portal-help-collee { margin-top: 0; }
.portal-access-list-espacee { margin-top: 16px; }

/* La pagination du portail a rejoint le socle : `cci-pagination`, avec ses
   numéros de page. Elle était ici une définition concurrente de plus. */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    scroll-behavior: auto !important;
    transition-duration: .01ms !important;
  }
}

/* ── Cloche de notifications ──────────────────────────────────────────────── */
/* Ce qui a bougé dans les outils, dans l'en-tête du portail. Le panneau double
   les courriels sans en remplacer aucun : il fait gagner le trajet vers la
   boîte mail, il n'est le seul canal de rien. */

.portal-bell { position: relative; }

.portal-bell-trigger {
  display: inline-flex;
  min-height: 36px;
  gap: 7px;
  align-items: center;
  justify-content: center;
  padding: 7px 11px;
  border: 1px solid var(--portal-border);
  border-radius: 9px;
  color: var(--portal-ink);
  background: #fff;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.portal-bell-trigger:hover { background: #f0f1f7; }

.portal-bell-trigger svg {
  width: 16px;
  height: 16px;
  flex: 0 0 16px;
  fill: currentColor;
}

/* La pastille accompagne le libellé au lieu de se poser sur l'icône : le
   nombre exact est affiché, sans plafond, et un compte à trois chiffres
   déborderait d'un disque calibré pour un seul. */
.portal-bell-count {
  min-width: 20px;
  padding: 1px 6px;
  border-radius: var(--cci-radius-pill, 999px);
  color: #fff;
  background: var(--portal-blue);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  line-height: 18px;
  text-align: center;
}

.portal-bell-panel {
  position: absolute;
  z-index: 30;
  top: calc(100% + 10px);
  right: 0;
  overflow-y: auto;
  width: min(380px, calc(100vw - 32px));
  max-height: min(70vh, 520px);
  padding: 6px 0 8px;
  border: 1px solid var(--portal-border);
  border-radius: 12px;
  background: var(--portal-surface);
  box-shadow: 0 18px 40px rgba(10, 21, 81, .16);
}

.portal-bell-head {
  display: flex;
  gap: 12px;
  align-items: baseline;
  justify-content: space-between;
  padding: 10px 16px 12px;
  border-bottom: 1px solid var(--portal-border);
}

.portal-bell-head strong { font-size: 14px; }
.portal-bell-head form { margin: 0; }

.portal-bell-empty {
  margin: 0;
  padding: 18px 16px;
  color: var(--portal-muted);
  font-size: 13px;
  line-height: 1.55;
}

.portal-bell-group {
  margin: 0;
  padding: 14px 16px 6px;
  color: var(--portal-muted);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.portal-bell-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.portal-bell-item {
  display: grid;
  gap: 2px;
  padding: 9px 16px 10px;
  border-left: 3px solid transparent;
  color: var(--portal-ink);
  text-decoration: none;
}

.portal-bell-item:hover { background: #f5f6fb; }

/* Non lue : le seul repère qui distingue ce qui vient d'arriver de ce qu'on a
   déjà vu. Une couleur de texte n'y suffirait pas — le liseré se voit du coin
   de l'œil, en parcourant la liste. */
.portal-bell-item.is-unread {
  border-left-color: var(--portal-blue);
  background: var(--portal-blue-soft, #eeefff);
}

.portal-bell-item.is-unread:hover { background: #e4e5ff; }

.portal-bell-tool {
  color: var(--portal-blue);
  font-size: 11px;
  font-weight: 700;
}

.portal-bell-title { font-size: 13px; line-height: 1.45; }

.portal-bell-when {
  color: var(--portal-muted);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
}

/* ── Journal d'administration ─────────────────────────────────────────────
   Le journal existait depuis toujours et n'avait aucun écran : il était écrit
   et jamais lu. Ces règles habillent celui qui le rend enfin consultable. */

.portal-journal-sous-titre {
  color: var(--portal-muted);
  font-size: 13px;
}

/* La note explique ce que le journal garantit et ce qu'il ne garantit pas.
   Elle est en tête parce que c'est la première question qu'on pose en la
   voyant, et qu'une réponse écrite ailleurs n'est jamais lue. */
.portal-journal-note { margin-bottom: 18px; }

.portal-journal-note h2 {
  margin: 0 0 10px;
  font-size: 16px;
}

.portal-journal-note p {
  margin: 0 0 10px;
  max-width: 70ch;
  color: var(--portal-muted);
  font-size: 13.5px;
  line-height: 1.55;
}

.portal-journal-details {
  margin-top: 14px;
  font-size: 13px;
}

.portal-journal-details summary {
  color: var(--portal-blue);
  cursor: pointer;
  font-weight: 600;
}

.portal-journal-roles {
  font-family: ui-monospace, Consolas, monospace;
  font-size: 12px;
}

/* Les trois filtres vivent dans un seul formulaire, hors de la zone remplacée :
   c'est ce qui leur permet de garder leur contenu et leur focus. */
.portal-journal-filtres {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
}

.portal-journal-champ { min-width: 220px; }

.portal-journal-compte {
  margin: 0;
  padding: 16px 28px;
  border-bottom: 1px solid var(--portal-border, #e5e7f0);
  color: var(--portal-muted);
  font-size: 13px;
}

.portal-journal-compte strong { color: var(--portal-ink, #0a1551); }

/* Une auto-attribution est le cas qui a motivé cet écran : elle ne doit pas se
   confondre avec le reste des lignes. */
.portal-journal-alerte { background: #fdecec; }

.portal-journal-automate {
  color: var(--portal-muted);
  font-style: italic;
}

.portal-journal-details-ligne {
  color: var(--portal-muted);
  font-family: ui-monospace, Consolas, monospace;
  font-size: 11.5px;
  word-break: break-word;
}

/* Un fait d'une ligne de journal : son étiquette, puis sa valeur. Ils étaient
   affichés bruts — `tool=organigrammes;role=tool_super_admin` —, ce qui
   demandait au lecteur de connaître les identifiants techniques du projet. */
.portal-journal-fait {
  display: block;
  color: var(--portal-muted);
  font-size: 12.5px;
  line-height: 1.5;
}

/* `min-width` seul suffisait tant que l'étiquette restait courte. « Super-
   administrateur » la dépassait, et la valeur venait se coller au mot :
   « Super-administrateuraccordé ». La gouttière est désormais une marge, qui
   ne dépend pas de la longueur. */
.portal-journal-etiquette {
  display: inline-block;
  min-width: 76px;
  margin-right: 8px;
  color: var(--portal-ink, #0a1551);
  font-weight: 600;
}
