/* ==========================================================================
   EKBANKING — ADMIN PANEL · feuille COMPLÉMENTAIRE
   --------------------------------------------------------------------------
   Le langage visuel (palette vert forêt + crème, Montserrat, titres légers,
   boutons pilule, cartes à plat, tableaux, badges, modale, topbar verte)
   vient INTÉGRALEMENT de /shared/theme.css, qui doit être chargé AVANT ce
   fichier sur chaque page :

       <link rel="stylesheet" href="/shared/theme.css" />
       <link rel="stylesheet" href="style.css" />
       ... et <body class="admin"> pour la topbar vert plein.

   Ici : UNIQUEMENT ce qui est propre au back-office et absent du socle.
   Règle absolue : aucun token de couleur en dur, tout passe par var(--ek-*).
   L'ancien thème brun/or a été entièrement supprimé.
   ========================================================================== */


/* ==========================================================================
   1. ÉCRAN DE CONNEXION STAFF (login.html)
   Plus sobre et plus « service interne » que le login client : fond crème,
   bandeau vert forêt en tête de page, carte posée dessus.
   ========================================================================== */

body.admin.auth-page {
  background: var(--ek-cream);
}

/* Bandeau vert plein derrière la carte : signale la zone back-office
   exactement comme le fait la topbar sur les pages internes. */
.staff-band {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 210px;
  background: var(--ek-green);
  border-bottom: 1px solid var(--ek-green-press);
  z-index: 0;
}

body.admin.auth-page .auth-container {
  position: relative;
  z-index: 1;
  margin-top: 88px;
  border-top-width: 3px;
  box-shadow: var(--ek-shadow-lift);
}

/* Sur-titre « Back-office administrateur » */
.staff-kicker {
  margin: var(--ek-sp-2) 0 0;
  color: var(--ek-mint-ink);
  font-size: var(--ek-fs-xs);
  font-weight: 600;
  letter-spacing: var(--ek-track-caps);
  text-transform: uppercase;
}

/* Filet crème de séparation avant le formulaire */
.staff-rule {
  margin: var(--ek-sp-5) 0 0;
  border: 0;
  border-top: 1px solid var(--ek-line);
}

/* Mention légale de bas de carte */
.staff-note {
  margin-top: var(--ek-sp-5);
  padding-top: var(--ek-sp-4);
  border-top: 1px solid var(--ek-line-soft);
  text-align: center;
  font-size: var(--ek-fs-xs);
  line-height: 1.6;
}

@media (max-width: 720px) {
  .staff-band { height: 150px; }
  body.admin.auth-page .auth-container { margin-top: 56px; }
}


/* ==========================================================================
   2. EN-TÊTE DE PAGE (dashboard) — titre + action à droite
   ========================================================================== */

.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--ek-sp-4);
  flex-wrap: wrap;
  margin-bottom: var(--ek-sp-6);
}
.page-head h1 { margin: 0 0 var(--ek-sp-1); }
.page-head .lead {
  margin: 0;
  color: var(--ek-gray);
  font-size: var(--ek-fs-sm);
}


/* ==========================================================================
   3. FILES D'ATTENTE — .card contenant .section-title + le conteneur JS
   Le socle place .section-title entre deux sections de page (grande marge
   haute) ; en tête de carte il doit être collé au bord.
   ========================================================================== */

.card > .section-title:first-child {
  margin: 0 0 var(--ek-sp-4);
  padding-bottom: var(--ek-sp-3);
  align-items: center;
}

/* Le titre de carte descend d'un cran par rapport à un titre de page. */
.card > .section-title h2 {
  font-size: var(--ek-fs-h3);
  font-weight: 600;
  letter-spacing: 0;
}

/* Compteur d'éléments en attente : badge du socle, chiffres à chasse fixe. */
.queue-count {
  font-variant-numeric: tabular-nums;
  min-width: 34px;
  text-align: center;
}

/* Espace entre deux files */
.queue + .queue { margin-top: var(--ek-sp-5); }


/* ==========================================================================
   4. TABLEAUX DE TRAITEMENT — colonne d'actions alignée à droite
   ========================================================================== */

th.col-actions,
td.actions { text-align: right; }

td.actions > button:last-child,
td.actions > .btn:last-child { margin-right: 0; }

/* La colonne « Motif » reste secondaire et ne doit pas écraser la ligne. */
td.note-cell {
  max-width: 260px;
  white-space: normal;
  color: var(--ek-gray);
}


/* ==========================================================================
   5. DENSITÉ DES KPI DU BACK-OFFICE
   Le socle définit .kpi-grid / .kpi / .value / .label ; on ne règle ici que
   la tuile « Total des soldes », plus large et au contenu textuel.
   ========================================================================== */

.kpi-grid { margin-bottom: var(--ek-sp-7); }


/* ==========================================================================
   6. ÉCRAN « SITE WEB » (site.html)
   Administration du contenu public : identité, hero, images, pied de page.
   Tout est construit sur les classes du socle (.card, .actions, .msg, .badge,
   .empty, .hint, .modal) ; ici, uniquement ce qui manque.
   ========================================================================== */

/* --- Onglets ------------------------------------------------------------
   Segmenté posé sur la ligne crème : l'onglet actif est un aplat vert.
   Les <button> sont des pilules par défaut (socle) : on les neutralise. */
.tabs {
  display: flex;
  gap: var(--ek-sp-2);
  flex-wrap: wrap;
  margin-bottom: var(--ek-sp-5);
  padding-bottom: var(--ek-sp-3);
  border-bottom: 1px solid var(--ek-line);
}

.tabs .tab {
  padding: 9px 20px;
  background: transparent;
  border: 1px solid var(--ek-line-strong);
  border-radius: var(--ek-r-pill);
  color: var(--ek-ink-soft);
  font-size: var(--ek-fs-xs);
  font-weight: 600;
  letter-spacing: var(--ek-track-caps);
  text-transform: uppercase;
}
.tabs .tab:hover {
  background: var(--ek-green-soft);
  border-color: var(--ek-green);
  color: var(--ek-green);
}
.tabs .tab.active,
.tabs .tab.active:hover {
  background: var(--ek-green);
  border-color: var(--ek-green);
  color: var(--ek-on-green);
}

/* Filet de sécurité : un panneau masqué doit l'être quoi qu'il arrive. */
.tab-panel[hidden] { display: none !important; }
.tab-panel:focus-visible { outline: 3px solid var(--ek-focus); outline-offset: 4px; }

/* Le premier titre d'un panneau est déjà précédé de la barre d'onglets. */
.tab-panel > .section-title:first-child { margin-top: var(--ek-sp-2); }


/* --- Aperçu en direct du logotype --------------------------------------- */
.preview-box {
  display: flex;
  align-items: center;
  gap: var(--ek-sp-4);
  flex-wrap: wrap;
  margin: var(--ek-sp-4) 0 0;
  padding: var(--ek-sp-4) var(--ek-sp-5);
  background: var(--ek-cream-soft);
  border: 1px dashed var(--ek-line-strong);
  border-radius: var(--ek-r-card);
}
.preview-label {
  color: var(--ek-gray-strong);
  font-size: var(--ek-fs-xs);
  font-weight: 600;
  letter-spacing: var(--ek-track-caps);
  text-transform: uppercase;
}
.preview-box .brand { font-size: 1.5rem; }


/* --- Champ « image » : aperçu + boutons + URL --------------------------- */
.media-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--ek-sp-5);
  margin-top: var(--ek-sp-4);
}

.media-field { min-width: 0; }
.media-field + .media-field { margin-top: 0; }

.field-label {
  display: block;
  margin-bottom: 6px;
  color: var(--ek-ink-soft);
  font-size: var(--ek-fs-sm);
  font-weight: 500;
}

.media-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 120px;
  padding: var(--ek-sp-3);
  background: var(--ek-cream-soft);
  border: 1px solid var(--ek-line);
  border-radius: var(--ek-r-card);
}
.media-preview img { max-height: 140px; width: auto; }

.media-none {
  color: var(--ek-gray-strong);
  font-size: var(--ek-fs-sm);
}

.media-field .actions { margin-top: var(--ek-sp-3); }
.media-field .actions button { padding: 7px 16px; font-size: var(--ek-fs-xs); }

.media-url {
  overflow-wrap: anywhere;
  font-family: var(--ek-font-mono);
  font-size: var(--ek-fs-xs);
}


/* --- Médiathèque (dans la modale) --------------------------------------- */
.modal.modal-wide { max-width: 760px; }

.upload-row { margin-top: var(--ek-sp-4); }
.upload-row .actions { align-items: center; }
.upload-row input[type="file"] { flex: 1 1 220px; min-width: 180px; }

.upload-progress {
  height: 8px;
  margin-top: var(--ek-sp-3);
  background: var(--ek-green-soft);
  border: 1px solid var(--ek-line);
  border-radius: var(--ek-r-pill);
  overflow: hidden;
}
.upload-progress > i {
  display: block;
  width: 0;
  height: 100%;
  background: var(--ek-mint);
  transition: width var(--ek-t);
}

.media-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--ek-sp-4);
  margin-top: var(--ek-sp-3);
}

/* État vide / erreur de la médiathèque : il occupe TOUTE la largeur de la
   grille, sinon il est comprimé dans une colonne de vignette. */
.media-grid > .empty { grid-column: 1 / -1; }

.media-item {
  display: flex;
  flex-direction: column;
  gap: var(--ek-sp-2);
  min-width: 0;
}

/* Vignette cliquable : un <button> qu'il faut sortir du style pilule. */
.media-item .media-pick {
  display: block;
  width: 100%;
  padding: var(--ek-sp-3);
  background: var(--ek-white);
  border: 1px solid var(--ek-line);
  border-radius: var(--ek-r-card);
  color: var(--ek-ink);
  font-size: var(--ek-fs-xs);
  font-weight: 400;
  letter-spacing: 0;
  text-align: left;
  white-space: normal;
}
.media-item .media-pick:hover {
  background: var(--ek-cream-soft);
  border-color: var(--ek-green);
  color: var(--ek-ink);
}
.media-item.selected .media-pick {
  border-color: var(--ek-green);
  box-shadow: inset 0 0 0 2px var(--ek-mint);
}

.media-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 88px;
  margin-bottom: var(--ek-sp-2);
  background: var(--ek-cream-soft);
  border-radius: var(--ek-r-field);
  overflow: hidden;
}
.media-thumb img { max-height: 84px; width: auto; }

.media-name {
  display: block;
  overflow-wrap: anywhere;
  font-weight: 600;
}
.media-meta {
  display: block;
  margin-top: 2px;
  color: var(--ek-gray-strong);
  font-size: var(--ek-fs-xs);
}

.media-item .media-del {
  align-self: flex-start;
  padding: 5px 14px;
  font-size: var(--ek-fs-xs);
}


/* --- Éditeurs répétés (diapositives, images) ---------------------------- */
.card.editor { border-top: 3px solid var(--ek-line-strong); }
.card.editor.create { border-top-color: var(--ek-mint); }

.editor-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ek-sp-4);
  flex-wrap: wrap;
  margin-bottom: var(--ek-sp-4);
  padding-bottom: var(--ek-sp-3);
  border-bottom: 1px solid var(--ek-line);
}
.editor-title {
  display: flex;
  align-items: center;
  gap: var(--ek-sp-3);
  flex-wrap: wrap;
}
.editor-title h3 { margin: 0; font-size: var(--ek-fs-h3); font-weight: 600; }

.editor-body { display: grid; gap: var(--ek-sp-4); }
.editor-body .media-preview { min-height: 110px; }
.editor-body .field > label { margin-top: 0; }

/* Titre de groupe de section (images) */
.group-title { margin-top: var(--ek-sp-6); align-items: center; }
.group-title h3 { margin: 0; font-size: 1.05rem; font-weight: 600; color: var(--ek-green); }

/* Barre d'enregistrement d'un bloc : alignée à droite, détachée du contenu. */
.form-actions {
  margin-top: var(--ek-sp-5);
  padding-top: var(--ek-sp-4);
  border-top: 1px solid var(--ek-line-soft);
  justify-content: flex-end;
}

@media (max-width: 720px) {
  .tabs .tab { flex: 1 1 auto; }
  .editor-head { align-items: flex-start; }
  .media-grid { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
}


/* ==========================================================================
   7. ZONES À CONSÉQUENCE (fiche client, cartes)
   Trois niveaux de gravité, tous bâtis sur les jetons d'état du socle :
     .zone-warn   — action réversible mais à expliquer (devise, IBAN)
     .zone-danger — action IRRÉVERSIBLE et sans trace côté client (registre)
   Ce sont des <fieldset> : le socle leur donne déjà bordure et légende.
   ========================================================================== */

fieldset.zone-warn {
  background: var(--ek-warn-bg);
  border-color: var(--ek-warn-line);
  border-left: 3px solid var(--ek-gold-warm);
}
fieldset.zone-warn > legend { color: var(--ek-warn-ink); }

fieldset.zone-danger {
  background: var(--ek-bad-bg);
  border-color: var(--ek-bad-line);
  border-left: 3px solid var(--ek-red);
}
fieldset.zone-danger > legend { color: var(--ek-bad-ink); }

/* Avertissement court posé au-dessus d'un tableau ou d'un formulaire.
   Reprend exactement les jetons de .msg, sans en être un (aria-live). */
.zone-note {
  margin: 0 0 var(--ek-sp-4);
  padding: 10px 14px;
  border: 1px solid var(--ek-bad-line);
  border-left: 3px solid var(--ek-red);
  border-radius: var(--ek-r-field);
  background: var(--ek-bad-bg);
  color: var(--ek-bad-ink);
  font-size: var(--ek-fs-sm);
  line-height: 1.55;
}
.zone-note.soft {
  border-color: var(--ek-warn-line);
  border-left-color: var(--ek-gold-warm);
  background: var(--ek-warn-bg);
  color: var(--ek-warn-ink);
}


/* ==========================================================================
   8. IBAN — valeur en chasse fixe, groupée par blocs de 4
   ========================================================================== */

.iban-value {
  display: inline-block;
  font-family: var(--ek-font-mono);
  font-size: 0.95rem;
  letter-spacing: 0.08em;
  overflow-wrap: anywhere;
  color: var(--ek-ink);
}
.iban-none {
  color: var(--ek-gray-strong);
  font-size: var(--ek-fs-sm);
  font-style: italic;
}
.iban-row {
  display: flex;
  align-items: center;
  gap: var(--ek-sp-3);
  flex-wrap: wrap;
}
/* Saisie manuelle : le champ doit accueillir 34 caractères sans se replier. */
.iban-input {
  font-family: var(--ek-font-mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}


/* ==========================================================================
   9. RÉVÉLATION DE CARTE — numéro + CVV affichés 60 secondes
   Aucun secret n'est jamais rendu dans une liste : ce bloc n'existe dans le
   DOM que le temps de la consultation, et se vide tout seul.
   ========================================================================== */

.secret-box {
  margin-top: var(--ek-sp-3);
  padding: var(--ek-sp-4);
  background: var(--ek-green-050);
  border: 1px solid var(--ek-line-strong);
  border-left: 3px solid var(--ek-green);
  border-radius: var(--ek-r-card);
}
.secret-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--ek-sp-4);
}
.secret-label {
  display: block;
  color: var(--ek-gray-strong);
  font-size: var(--ek-fs-xs);
  font-weight: 600;
  letter-spacing: var(--ek-track-caps);
  text-transform: uppercase;
}
.secret-value {
  display: block;
  margin-top: 2px;
  font-family: var(--ek-font-mono);
  font-size: 1.05rem;
  letter-spacing: 0.05em;
  color: var(--ek-ink);
  overflow-wrap: anywhere;
}
.secret-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ek-sp-3);
  flex-wrap: wrap;
  margin-top: var(--ek-sp-4);
  padding-top: var(--ek-sp-3);
  border-top: 1px solid var(--ek-line);
}
.countdown {
  color: var(--ek-gray-strong);
  font-size: var(--ek-fs-xs);
  font-variant-numeric: tabular-nums;
}


/* ==========================================================================
   10. LIGNE D'ÉDITION DÉPLIÉE DANS UN TABLEAU (cartes, registre)
   Une <tr> supplémentaire portant un formulaire : elle ne doit pas réagir au
   survol comme une ligne de données.
   ========================================================================== */

tr.row-editor:hover { background: transparent; }
tr.row-editor > td {
  padding-top: var(--ek-sp-4);
  padding-bottom: var(--ek-sp-5);
  background: var(--ek-cream-soft);
}
tr.row-editor .row > * { flex: 1 1 160px; min-width: 150px; }

/* Le contenu d'une ligne dépliée reste collé au bord gauche du scrollport du
   tableau : quelle que soit la position du défilement horizontal, le
   formulaire (ou le panneau de secrets) est entièrement visible. Sa largeur
   est posée en pixels par cards.html, qui seul connaît le scrollport. */
tr.row-editor > td > .row-editor-body {
  position: sticky;
  left: 0;
  max-width: 100%;
}

/* Boutons de fin de ligne : plus compacts que la pilule standard. */
td.actions button { padding: 7px 16px; font-size: var(--ek-fs-xs); }

@media (max-width: 720px) {
  .secret-grid { grid-template-columns: 1fr; }
}


/* ==========================================================================
   11. ÉCRAN « CONFIGURATION » (config.html)
   Envoi d'e-mails (SMTP), modèles d'e-mails, notifications Telegram.
   Tout repose sur le socle (.card, .tabs, .msg, .badge, .hint, .modal) ; on
   n'ajoute ici que ce qui n'existe nulle part ailleurs.
   ========================================================================== */

/* --- Liste de cases à cocher (événements notifiés) ----------------------
   Sans cette classe, chaque ligne était habillée en style inline. Surtout,
   on n'utilise PAS .row : le socle y pose flex:1 1 220px sur chaque enfant,
   ce qui étirerait chaque case sur 220 pixels de large. */
.check-list > .check-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: var(--ek-sp-3);
}
.check-list > .check-row > input[type="checkbox"] { flex: 0 0 auto; margin-top: 3px; }
.check-list > .check-row > div { min-width: 0; }
.check-list > .check-row label { margin: 0; font-weight: 400; }
.check-list > .check-row .hint { margin: 2px 0 0; }
/* Un événement verrouillé (e-mail indispensable) reste lisible mais inerte. */
.check-list > .check-row.locked label { color: var(--ek-gray-strong); }

/* --- Champ + bouton collé (mot de passe, adresse d'essai) ---------------- */
.field-inline {
  display: flex;
  gap: var(--ek-sp-3);
  align-items: center;
  flex-wrap: wrap;
}
.field-inline > input { flex: 1 1 240px; min-width: 0; }
.field-inline > button { flex: 0 0 auto; }

/* --- Résumé « ce que le serveur utilisera réellement » ------------------- */
.cfg-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--ek-sp-4);
  margin: var(--ek-sp-4) 0 0;
  padding: var(--ek-sp-4);
  background: var(--ek-cream-soft);
  border: 1px solid var(--ek-line-strong);
  border-left: 3px solid var(--ek-green);
  border-radius: var(--ek-r-card);
}
.cfg-summary.unset { border-left-color: var(--ek-gold-warm); }
.cfg-summary dt {
  color: var(--ek-gray-strong);
  font-size: var(--ek-fs-xs);
  font-weight: 600;
  letter-spacing: var(--ek-track-caps);
  text-transform: uppercase;
}
.cfg-summary dd {
  margin: 2px 0 0;
  color: var(--ek-ink);
  font-size: var(--ek-fs-sm);
  overflow-wrap: anywhere;
}

/* --- Modèles d'e-mails --------------------------------------------------- */
.tpl-card { border-top: 3px solid var(--ek-line-strong); }
.tpl-card.off { border-top-color: var(--ek-gold-warm); }

.tpl-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ek-sp-3);
  flex-wrap: wrap;
}
.tpl-head h3 { margin: 0; font-size: var(--ek-fs-h3); font-weight: 600; }
.tpl-badges { display: flex; gap: var(--ek-sp-2); flex-wrap: wrap; }

/* Corps HTML : c'est du code, il se lit en chasse fixe. */
textarea.code {
  font-family: var(--ek-font-mono);
  font-size: 0.9rem;
  line-height: 1.6;
  white-space: pre;
  overflow-wrap: normal;
  overflow-x: auto;
}

/* Variables insérables : une pastille cliquable par variable. */
.var-chips { display: flex; gap: var(--ek-sp-2); flex-wrap: wrap; margin-top: var(--ek-sp-2); }
.var-chip {
  padding: 5px 12px;
  background: var(--ek-green-050);
  border: 1px solid var(--ek-line-strong);
  border-radius: var(--ek-r-pill);
  color: var(--ek-green);
  font-family: var(--ek-font-mono);
  font-size: var(--ek-fs-xs);
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
}
.var-chip:hover { background: var(--ek-green); border-color: var(--ek-green); color: var(--ek-on-green); }

/* --- Aperçu d'un modèle -------------------------------------------------
   Le HTML affiché est saisi par un administrateur : il est rendu dans une
   iframe CLOISONNÉE (sandbox vide = ni script, ni formulaire, ni navigation),
   jamais par innerHTML — sans quoi un modèle mal saisi s'exécuterait dans le
   back-office, avec la session administrateur. */
.preview-frame {
  display: block;
  width: 100%;
  height: 60vh;
  min-height: 320px;
  border: 1px solid var(--ek-line-strong);
  border-radius: var(--ek-r-field);
  background: #ffffff;
}

@media (max-width: 720px) {
  .cfg-summary { grid-template-columns: 1fr; }
  .preview-frame { height: 55vh; min-height: 260px; }
}


/* ==========================================================================
   12. RESPONSIVE DU BACK-OFFICE — 320 → 1440 px
   --------------------------------------------------------------------------
   UNE SEULE stratégie de tableau, appliquée à TOUS les tableaux du
   back-office sans exception :

       le tableau reste un VRAI tableau et défile HORIZONTALEMENT dans son
       propre conteneur `.table-scroll`, focalisable au clavier
       (tabindex="0" + role="region" + aria-label).

   Pourquoi pas la bascule « cartes empilées » : les 5 tableaux portent une
   colonne d'actions (approuver / rejeter / bloquer / piloter) dont la lecture
   dépend de la ligne entière ; l'empilement casse la comparaison ligne à
   ligne dont vit une file de validation. Le défilement conserve l'alignement
   des colonnes et le modèle de table natif (WCAG 1.3.1), et le conteneur
   focalisable satisfait WCAG 2.1.1 (défilement atteignable au clavier).

   RÈGLE DE MARKUP : chaque <table> est le SEUL enfant de son .table-scroll,
   et aucun conteneur parent ne porte plus tabindex — un tableau, un seul
   arrêt de tabulation.
   ========================================================================== */

.table-scroll {
  width: 100%;
  max-width: 100%;
  /* Bloc conteneur des descendants en position:absolute — concrètement les
     <span class="visually-hidden">Actions</span> des en-têtes de colonne.
     Sans lui, leur bloc conteneur reste la .card (position:relative) : ils
     échappent au rognage de CE conteneur, la carte se croit trop étroite et
     affiche une SECONDE barre de défilement sous celle du tableau. */
  position: relative;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  /* Le défilement du tableau ne doit jamais « emporter » la page derrière lui. */
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--ek-line-strong) transparent;
}
.table-scroll:focus-visible {
  outline: 3px solid var(--ek-focus);
  outline-offset: 2px;
}

/* Largeur plancher du tableau : au-dessous, il défile au lieu d'écraser ses
   colonnes. Réglée par tableau via --tbl-min (le nombre de colonnes varie de
   4 à 8 selon l'écran). Cette règle vient APRÈS le socle, elle remplace donc
   le `.card table { min-width: 560px }` de /shared/theme.css. */
.table-scroll > table {
  min-width: var(--tbl-min, 600px);
  /* La barre de défilement ne colle pas au filet de la dernière ligne. */
  margin-bottom: 2px;
}

#transfers        .table-scroll { --tbl-min: 940px; }  /* 8 colonnes */
#beneficiaries    .table-scroll { --tbl-min: 820px; }  /* 6 colonnes bavardes */
#cards            .table-scroll { --tbl-min: 780px; }  /* 6 colonnes */
#clients          .table-scroll { --tbl-min: 700px; }  /* 5 colonnes */
#pending-transfers .table-scroll { --tbl-min: 720px; }
#pending-users    .table-scroll { --tbl-min: 660px; }
#pending-cards    .table-scroll { --tbl-min: 600px; }
[data-ledger]     .table-scroll { --tbl-min: 740px; }  /* fiche client, registre */
[data-cards]      .table-scroll { --tbl-min: 520px; }  /* fiche client, cartes  */

/* Le socle met td.actions en nowrap. Quand la cellule porte DEUX boutons
   bavards (« Voir la fiche » + « Lien de confirmation »), la table réclame
   ~1000px et défile même sur un écran de 1440. On l'autorise à passer sur
   deux lignes, en bornant sa largeur pour qu'un bouton ne se retrouve pas
   seul par ligne. */
#clients td.actions { white-space: normal; min-width: 170px; max-width: 210px; }

/* Colonne de date : sans nowrap, « 6 août 2026, 10:33 » se replie sur trois
   lignes dès que la colonne est serrée et double la hauteur des rangées. Le
   tableau défile déjà — quelques pixels de large ne coûtent rien. */
[data-ledger] .table-scroll tbody td:first-child,
#pending-users .table-scroll tbody td:nth-child(3),
#pending-cards .table-scroll tbody td:nth-child(3) { white-space: nowrap; }


/* --- Cibles tactiles : 44 × 44 px minimum -------------------------------
   Sur pointeur grossier ET sur petit écran (pour que la règle soit
   vérifiable en redimensionnant). Les cases à cocher et les boutons radio
   sont exclus : leur agrandissement les déformerait. */
@media (pointer: coarse), (max-width: 900px) {
  body.admin button,
  body.admin .btn,
  body.admin input[type="submit"],
  body.admin input[type="button"] { min-height: 44px; }

  /* Le socle rabote les boutons de cellule et de barre d'actions à 7px/11px :
     on leur rend une hauteur de doigt sans toucher à leur graisse. */
  body.admin .actions button,
  body.admin .actions .btn,
  body.admin td.actions button,
  body.admin td.actions .btn,
  body.admin .media-field .actions button,
  body.admin .media-item .media-del {
    min-height: 44px;
    padding-top: 9px;
    padding-bottom: 9px;
  }

  body.admin .icon-btn { width: 44px; height: 44px; }

  /* Liens de texte isolés : « Voir la fiche » d'une cellule, « ← Retour aux
     clients » en tête de fiche. Autour de 18px de haut, ils sont intouchables
     au doigt. */
  body.admin td a,
  body.admin .hint > a,
  body.admin .container > p > a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  body.admin input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
  body.admin select,
  body.admin textarea { min-height: 44px; }

  body.admin .tabs .tab { min-height: 44px; }
  body.admin .media-item .media-pick { min-height: 44px; }
  /* La barre de navigation est traitée par /shared/theme.css (repli en
     « icônes seules » sous 520px + plancher de 44px) : on n'y touche pas. */
}


/* --- 1024 px : tablette paysage / petit portable ------------------------ */
@media (max-width: 1024px) {
  .page-head { align-items: flex-start; }
}


/* --- 900 px : les en-têtes de page passent en colonne ------------------- */
@media (max-width: 900px) {
  /* Titre + filtre de statut : le <select> ne doit pas être plaqué contre le
     titre sur une ligne trop courte. */
  .container > .section-title { align-items: flex-start; }
  .container > .section-title > div:last-child { width: 100%; }
  .container > .section-title select { flex: 1 1 200px; }
}


/* --- 720 px : téléphone ------------------------------------------------- */
@media (max-width: 720px) {
  .page-head { gap: var(--ek-sp-3); margin-bottom: var(--ek-sp-5); }
  .page-head .actions { width: 100%; }

  /* Barre d'onglets (site.html) : elle se REPLIE, elle ne déborde jamais.
     Un onglet supplémentaire (Telegram) rentre donc sans réglage. */
  .tabs {
    gap: var(--ek-sp-2);
    margin-bottom: var(--ek-sp-4);
  }
  .tabs .tab {
    flex: 1 1 auto;
    min-width: 0;
    max-width: 100%;
    padding: 9px 14px;
    /* Le socle met les boutons en nowrap : un libellé long déborderait de la
       page. Ici il a le droit de passer à la ligne. */
    white-space: normal;
    overflow-wrap: anywhere;
    text-align: center;
  }

  /* Modale : elle occupe l'écran plutôt que de flotter dans un timbre-poste. */
  .modal.modal-wide { max-width: 100%; }

  /* Aperçus et médiathèque */
  .preview-box { padding: var(--ek-sp-3) var(--ek-sp-4); }
  .media-fields { grid-template-columns: 1fr; gap: var(--ek-sp-4); }
  .media-preview { min-height: 96px; }

  /* Barre d'enregistrement d'un bloc : les boutons prennent la largeur. */
  .form-actions { justify-content: stretch; }
  .form-actions > button,
  .form-actions > .btn { flex: 1 1 160px; }

  /* Les zones à conséquence perdent leur marge interne superflue. */
  fieldset.zone-warn,
  fieldset.zone-danger { padding-left: var(--ek-sp-4); padding-right: var(--ek-sp-4); }

  /* Motif de rejet : sur une seule colonne, la borne de 260px n'a plus de sens. */
  td.note-cell { max-width: 220px; }

  /* Révélation de carte : le pied du panneau s'empile proprement. */
  .secret-foot { align-items: stretch; }
  .secret-foot .countdown { order: 2; }

  /* § 10 pose `flex: 1 1 160px` sur les champs d'une ligne dépliée. Une fois
     l'axe passé en colonne (voir .row du socle), cette base de 160px devient
     une HAUTEUR imposée : chaque champ traînait 120px de vide sous lui. */
  tr.row-editor .row > * { flex: 0 0 auto; min-width: 0; }
}


/* --- 420 px : petits téléphones (320 / 375 px) -------------------------- */
@media (max-width: 420px) {
  .tabs .tab { flex: 1 1 100%; }

  .page-head .actions > button,
  .page-head .actions > .btn { flex: 1 1 auto; }

  /* L'en-tête de carte (titre + compteur) reste sur une ligne lisible. */
  .card > .section-title:first-child { gap: var(--ek-sp-2); }

  .media-grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }

  /* IBAN : 34 caractères en chasse fixe ne tiennent pas sur 320px de large. */
  .iban-value { font-size: 0.85rem; letter-spacing: 0.04em; }
  .secret-value { font-size: 0.95rem; }
}


/* --- Mouvement réduit --------------------------------------------------
   Le socle neutralise déjà transitions et animations globalement ; on ajoute
   ici ce qu'il ne couvre pas : le défilement programmé (scrollIntoView des
   bandeaux de message) et le lissage du défilement des tableaux. */
@media (prefers-reduced-motion: reduce) {
  .table-scroll { scroll-behavior: auto; }
  .upload-progress > i { transition: none; }
}
