/* Styles globaux Pythie — externalisés de base.html (chantier « CSP stricte » : plus aucun
   bloc <style> inline). Chargé après oracle.tokens.css dans le <head> de base.html.
   Le bloc ci-dessous est déplacé VERBATIM depuis l'ancien <style> de base.html. */

    * { box-sizing: border-box; }
    /* Lien d'évitement : hors écran au repos, révélé au focus clavier — évite de tabuler
       les ~10 items du rail sur chaque page avant d'atteindre le contenu. */
    .skip-link {
      position: absolute; left: -9999px; top: 0; z-index: 30;
      background: var(--py-surface-raised, #fff); color: var(--py-primary, #4f46e5);
      padding: 10px 16px; border-radius: 0 0 var(--py-radius-md, 10px) 0;
      border: 1px solid var(--py-border, #e5e3ef); font-weight: var(--py-weight-medium, 500);
      text-decoration: none;
    }
    .skip-link:focus { left: 0; outline: 2px solid var(--py-indigo-400, #818cf8); outline-offset: 2px; }
    body {
      margin: 0; font-family: var(--py-font-sans, system-ui, sans-serif);
      color: var(--py-text, #1e1b2e); background: var(--py-surface, #f6f5fb);
      display: flex; min-height: 100vh;
    }

    /* --- Rail latéral (menu) --- */
    #rail {
      position: sticky; top: 0; height: 100vh; flex-shrink: 0;
      display: flex; flex-direction: column; width: 228px;
      background: var(--py-surface-raised, #fff); border-right: 1px solid var(--py-border, #e5e3ef);
      padding: var(--py-space-4, 16px) var(--py-space-3, 12px) var(--py-space-4, 16px);
      transition: width .18s ease;
    }
    html.rail-reduit #rail { width: 68px; padding-left: 10px; padding-right: 10px; }
    #rail .toggle {
      position: absolute; right: -12px; top: 24px; width: 24px; height: 24px; padding: 0;
      border-radius: 50%; background: var(--py-surface-raised, #fff);
      border: 1px solid var(--py-border, #e5e3ef); color: var(--py-text-muted, #6e6b85);
      cursor: pointer; display: flex; align-items: center; justify-content: center; z-index: 3;
    }
    #rail .toggle:hover { color: var(--py-primary, #4f46e5); border-color: var(--py-indigo-300, #a5b4fc); }
    #rail .toggle:focus-visible { outline: 2px solid var(--py-indigo-400, #818cf8); outline-offset: 2px; }
    #rail .toggle svg {
      width: 13px; height: 13px; stroke: currentColor; stroke-width: 2; fill: none;
      stroke-linecap: round; stroke-linejoin: round; transition: transform .18s ease;
    }
    html.rail-reduit #rail .toggle svg { transform: rotate(180deg); }
    #rail .brand {
      display: flex; align-items: center; gap: 10px;
      padding: 0 10px var(--py-space-4, 16px); text-decoration: none;
    }
    #rail .logo { height: 26px; width: auto; flex-shrink: 0; }
    #rail .word {
      font-family: var(--py-font-display, var(--py-font-sans)); font-weight: 700;
      font-size: 17.5px; letter-spacing: .01em; color: var(--py-primary-hover, #4338ca);
    }
    html.rail-reduit #rail .brand { justify-content: center; padding-left: 0; padding-right: 0; }
    /* Rail réduit : les libellés (.word, .label, eyebrows) sont retirés VISUELLEMENT mais
       restent dans l'arbre d'accessibilité (un display:none priverait chaque lien de nav de
       son nom accessible — data-label n'est pas exposé aux lecteurs d'écran). */
    html.rail-reduit #rail .word,
    html.rail-reduit #rail .label,
    html.rail-reduit #rail .eyebrow span {
      position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
      overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
    }
    #rail .eyebrow {
      font-size: var(--py-text-xs, 11px); font-weight: var(--py-weight-semibold, 600);
      text-transform: uppercase; letter-spacing: .08em; color: var(--py-ink-400, #a29fb8);
      margin: var(--py-space-4, 16px) 12px 6px;
    }
    #rail .eyebrow:first-child { margin-top: 0; }
    html.rail-reduit #rail .eyebrow { height: 1px; background: var(--py-border, #e5e3ef); margin: 14px 8px 10px; }
    #rail nav a {
      position: relative; display: flex; align-items: center; gap: 10px;
      padding: var(--py-space-2, 8px) 10px; border-radius: 8px;
      color: var(--py-text-secondary, #524f68); text-decoration: none;
      font-size: 14px; font-weight: var(--py-weight-medium, 500);
      transition: background .15s ease, color .15s ease;
    }
    #rail nav a:hover { background: var(--py-ink-100, #eeedf6); color: var(--py-text, #1e1b2e); }
    #rail nav a.active { background: var(--py-indigo-50, #eef2ff); color: var(--py-primary-strong, #3730a3); }
    #rail nav a.active::before {
      content: ""; position: absolute; left: 0; top: 7px; bottom: 7px; width: 3px;
      border-radius: 3px; background: var(--py-accent, #e3a53e);
    }
    #rail nav a:focus-visible { outline: 2px solid var(--py-indigo-400, #818cf8); outline-offset: -2px; }
    #rail .ic {
      width: 19px; height: 19px; flex-shrink: 0; stroke: currentColor; stroke-width: 1.7;
      fill: none; stroke-linecap: round; stroke-linejoin: round;
    }
    /* Badge « runs en cours » de l'item Runs. Poussé à droite du label (margin-left:auto). Masqué
       tant que le compteur est inconnu ou nul (rail_live.js pose/retire l'attribut `hidden`). En
       menu réduit, se replie en coin d'icône. Valeurs statiques (CSP stricte). */
    #rail nav a .badge {
      margin-left: auto; min-width: 19px; height: 19px; padding: 0 5px;
      display: inline-flex; align-items: center; justify-content: center;
      background: var(--py-primary, #4f46e5); color: #fff;
      font-size: 11px; font-weight: var(--py-weight-bold, 700); line-height: 1;
      border-radius: var(--py-radius-pill, 999px); font-variant-numeric: tabular-nums;
    }
    #rail nav a .badge[hidden] { display: none; }
    html.rail-reduit #rail nav a .badge {
      position: absolute; top: 2px; right: 6px; margin-left: 0;
      min-width: 16px; height: 16px; padding: 0 4px; font-size: 10px;
      border: 2px solid var(--py-surface-raised, #fff);
    }
    html.rail-reduit #rail nav a { justify-content: center; padding-left: 0; padding-right: 0; }
    html.rail-reduit #rail [data-label]:hover::after {
      content: attr(data-label); position: absolute; left: calc(100% + 12px); top: 50%;
      transform: translateY(-50%); background: var(--py-ink-900, #1e1b2e); color: #fff;
      font-size: var(--py-text-sm, 12.5px); font-weight: var(--py-weight-medium, 500);
      padding: 5px 10px; border-radius: 7px; white-space: nowrap; pointer-events: none; z-index: 5;
    }
    #rail .user-block {
      position: relative; margin-top: auto; display: flex; align-items: center; gap: 10px;
      border-top: 1px solid var(--py-border, #e5e3ef); padding: 14px 10px 0;
    }
    #rail .avatar {
      width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
      background: var(--py-indigo-100, #e0e7ff); color: var(--py-primary-strong, #3730a3);
      font-size: 12px; font-weight: var(--py-weight-semibold, 600);
      display: flex; align-items: center; justify-content: center;
    }
    #rail .user-meta { display: flex; flex-direction: column; min-width: 0; }
    #rail .email {
      font-size: 12px; color: var(--py-text-muted, #6e6b85);
      overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    #rail .logout {
      padding: 0; border: 0; background: none; cursor: pointer; text-align: left;
      font: inherit; font-size: var(--py-text-sm, 12.5px); font-weight: var(--py-weight-medium, 500);
      color: var(--py-primary, #4f46e5);
    }
    #rail .logout:hover { color: var(--py-primary-strong, #3730a3); }
    #rail .logout:focus-visible { outline: 2px solid var(--py-indigo-400, #818cf8); outline-offset: 2px; }
    html.rail-reduit #rail .user-block { justify-content: center; padding-left: 0; padding-right: 0; }
    html.rail-reduit #rail .user-meta { display: none; }
    @media (prefers-reduced-motion: reduce) { #rail, #rail .toggle svg { transition: none; } }

    /* --- Contenu --- */
    main { flex: 1; min-width: 0; max-width: 980px; margin: 0 auto; padding: var(--py-space-6, 24px); }
    h1 { font-family: var(--py-font-display, var(--py-font-sans)); font-size: 1.5rem; }
    .card {
      background: var(--py-surface-raised, #fff); border: 1px solid var(--py-border, #e5e3ef);
      border-radius: var(--py-radius-lg, 14px); padding: var(--py-space-6, 24px); margin-bottom: var(--py-space-4, 16px);
    }
    table { width: 100%; border-collapse: collapse; }
    th, td { text-align: left; padding: var(--py-space-2, 8px) var(--py-space-3, 12px); border-bottom: 1px solid var(--py-border, #e5e3ef); }
    th { color: var(--py-text-secondary, #524f68); font-size: .8rem; text-transform: uppercase; letter-spacing: .03em; }
    input, select {
      padding: var(--py-space-2, 8px); border: 1px solid var(--py-border, #e5e3ef);
      border-radius: var(--py-radius-md, 10px); font: inherit; width: 100%;
    }
    label { display: block; font-size: .85rem; color: var(--py-text-secondary, #524f68); margin: var(--py-space-3, 12px) 0 var(--py-space-1, 4px); }
    .btn {
      display: inline-block; padding: var(--py-space-2, 8px) var(--py-space-4, 16px); border: 0; cursor: pointer;
      background: var(--py-primary, #4f46e5); color: #fff; border-radius: var(--py-radius-md, 10px); font: inherit;
    }
    .btn.secondary { background: transparent; color: var(--py-primary, #4f46e5); border: 1px solid var(--py-border, #e5e3ef); }
    /* Pills de statut : dialecte fond-pâle/texte-sombre (le même que costs.css et
       admin_runs.css). L'ancien aplat vert (.ok blanc sur #16a34a) contrastait à 3,3:1
       — sous le seuil WCAG AA pour du texte de .78rem. */
    .pill { display: inline-block; padding: 2px 10px; border-radius: 999px; font-size: .78rem; }
    .pill.ok { background: var(--py-success-bg, #dcfce7); color: var(--py-success-text, #166534); }
    .pill.off { background: var(--py-ink-100, #eeedf6); color: var(--py-text-secondary, #524f68); }
    .error { color: var(--py-danger, #dc2626); margin: var(--py-space-2, 8px) 0; }
    .muted { color: var(--py-text-secondary, #524f68); font-size: .9rem; }
    .banner {
      padding: var(--py-space-3, 12px) var(--py-space-4, 16px); border-radius: var(--py-radius-md, 10px);
      border: 1px solid transparent; margin-bottom: var(--py-space-4, 16px); font-size: .95rem;
    }
    .banner .banner-title { font-weight: 600; }
    .banner.info    { background: var(--py-info-bg, #E0E7FF);    color: var(--py-info-text, #3730A3);    border-color: var(--py-info, #4F46E5); }
    .banner.success { background: var(--py-success-bg, #DCFCE7); color: var(--py-success-text, #166534); border-color: var(--py-success, #16A34A); }
    .banner.warning { background: var(--py-warning-bg, #FFEDD5); color: var(--py-warning-text, #9A3412); border-color: var(--py-warning, #EA580C); }
    .banner.danger  { background: var(--py-danger-bg, #FEE2E2);  color: var(--py-danger-text, #991B1B);  border-color: var(--py-danger, #DC2626); }
    .banner.neutral { background: var(--py-surface, #f6f5fb);    color: var(--py-text-secondary, #524f68);   border-color: var(--py-border, #e5e3ef); }

    /* --- Actions de tableau en pictos ---------------------------------------
       Colonne « Actions » : rangée horizontale de boutons-icônes alignée à
       droite. Chaque bouton porte un aria-label (lecteurs d'écran) et un
       data-label (infobulle CSS, même pattern que le rail réduit, étendu au
       focus clavier). Zéro JS — compatible CSP stricte. */
    th.actions, td.actions { text-align: right; }
    .actions-row { display: inline-flex; align-items: center; gap: 4px; vertical-align: middle; }
    .act {
      position: relative; display: inline-flex; align-items: center; justify-content: center;
      width: 32px; height: 32px; padding: 0; border: 0; background: transparent;
      color: var(--py-text-muted, #6e6b85); border-radius: 8px; cursor: pointer; font: inherit;
    }
    .act svg {
      width: 18px; height: 18px; stroke: currentColor; stroke-width: 1.7; fill: none;
      stroke-linecap: round; stroke-linejoin: round; display: block;
    }
    .act:hover { background: var(--py-indigo-50, #eef2ff); color: var(--py-primary, #4f46e5); }
    .act.danger:hover { background: var(--py-danger-bg, #fee2e2); color: var(--py-danger, #dc2626); }
    .act:focus-visible { outline: 2px solid var(--py-indigo-400, #818cf8); outline-offset: 2px; }
    .act[data-label]:hover::after, .act[data-label]:focus-visible::after {
      content: attr(data-label); position: absolute; left: 50%; bottom: calc(100% + 7px);
      transform: translateX(-50%); background: var(--py-ink-900, #1e1b2e); color: #fff;
      font-size: var(--py-text-sm, 12.5px); font-weight: var(--py-weight-medium, 500);
      padding: 5px 10px; border-radius: 7px; white-space: nowrap; pointer-events: none; z-index: 5;
    }
    /* Le picto « Modifier » est un <summary> : neutraliser le marqueur natif,
       et signaler l'état ouvert. */
    summary.act { list-style: none; }
    summary.act::-webkit-details-marker { display: none; }
    details[open] > summary.act { background: var(--py-indigo-50, #eef2ff); color: var(--py-primary, #4f46e5); }
    /* Formulaire d'édition : panneau flottant ancré au picto (la colonne
       Actions est trop étroite pour le dépliage dans la cellule). */
    .actions-row details { position: relative; }
    .edit-pop {
      position: absolute; right: 0; top: calc(100% + 6px); z-index: 10;
      width: 340px; max-width: calc(100vw - 32px); background: var(--py-surface-raised, #fff);
      border: 1px solid var(--py-border, #e5e3ef); border-radius: var(--py-radius-md, 10px);
      padding: var(--py-space-2, 8px) var(--py-space-4, 16px) var(--py-space-4, 16px);
      box-shadow: 0 8px 24px rgba(30, 27, 46, .12); text-align: left;
    }
    /* Modale native <dialog> (édition d'un compte) : carte centrée dans le top layer,
       ouverte via showModal() (admin_users.js — la position DOM dans la cellule est
       sans effet). Mêmes matériaux que .card, voile ::backdrop. */
    dialog.modale {
      width: 380px; max-width: calc(100vw - 32px); background: var(--py-surface-raised, #fff);
      border: 1px solid var(--py-border, #e5e3ef); border-radius: var(--py-radius-lg, 14px);
      padding: var(--py-space-6, 24px); box-shadow: 0 12px 32px rgba(30, 27, 46, .18);
      text-align: left; color: var(--py-text, #1e1b2e);
    }
    dialog.modale::backdrop { background: rgba(30, 27, 46, .45); }
    dialog.modale h2 { margin-top: 0; }

/* ============================================================================
   Classes utilitaires — remplacent les anciens attributs style="" inline
   (chantier « CSP stricte »). Toutes les valeurs sont STATIQUES et transposées
   à l'identique ; elles réutilisent les variables --py-* déjà en place.
   ============================================================================ */

/* Titre de section : ancien style="font-size:1.1rem" sur les <h2> de cartes */
.titre-section { font-size: 1.1rem; }

/* Marges simples (une seule propriété) */
.u-m0 { margin: 0; }
.u-mt-8 { margin-top: 8px; }
.u-mt-3 { margin-top: var(--py-space-3, 12px); }
.u-mt-4 { margin-top: var(--py-space-4, 16px); }
.u-mt-neg8 { margin-top: -8px; }

/* Paragraphes muted collés sous un titre : marge haute + reste à plat (shorthand)
   — distinct de .u-mt-8/.u-mt-4 qui, eux, ne remettent pas à zéro la marge basse. */
.u-mt-8-flush { margin: 8px 0 0; }
.u-mt-4-flush { margin: 4px 0 0; }

/* Flex composable (rangées de formulaires) */
.u-flex { display: flex; }
.u-items-center { align-items: center; }
.u-items-end { align-items: end; }
.u-gap-2 { gap: var(--py-space-2, 8px); }
.u-gap-3 { gap: var(--py-space-3, 12px); }
.u-wrap { flex-wrap: wrap; }
.u-flex-1 { flex: 1; }

/* Largeurs fixes de champs (surchargent le width:100% par défaut des input/select) */
.u-w-120 { width: 120px; }
.u-w-140 { width: 140px; }
.u-w-160 { width: 160px; }
.u-w-220 { width: 220px; }

/* Liste de checklist sans puce (onboarding) */
.u-list-plain { list-style: none; padding: 0; line-height: 2; }

/* Carte de connexion centrée (login) — placée APRÈS .card pour gagner la marge */
.login-card { max-width: 420px; margin: 8vh auto; }

/* Coûts par utilisateur (admin_costs) : deux branches de la cellule du jour.
   .cost-over = dépassement du plafond ; .cost-ok = branche neutre (aucun style,
   rendu identique à la cellule par défaut) pour éviter tout style="" conditionnel. */
.cost-over { color: var(--py-danger, #dc2626); font-weight: 600; }
.cost-ok { /* branche normale : pas de mise en forme particulière */ }

/* ============================================================================
   Adaptation mobile (≤720px) et tactile — le shell n'avait aucun breakpoint :
   sur téléphone, le rail en flux (228px) laissait ~160px au contenu.
   ============================================================================ */

/* Conteneur de défilement des tables larges : NEUTRE en desktop (un overflow
   permanent clipperait les infobulles ::after des .act), scrollable en mobile
   (pas de hover au toucher, le clip y est sans victime). payloads.css garde sa
   variante scoped `.payloads .table-scroll` à overflow permanent (tables d'URLs
   larges même en desktop) — plus spécifique, elle prime. */
@media (max-width: 720px) {
  .table-scroll { overflow-x: auto; }

  /* Le rail sort du flux : colonne d'icônes fixe (rail.js pose .rail-reduit au
     boot mobile), et son déploiement RECOUVRE le contenu (surcouche ombrée)
     au lieu de le pousser. Le body réserve la colonne réduite. */
  #rail { position: fixed; left: 0; top: 0; height: 100dvh; z-index: 20; }
  html:not(.rail-reduit) #rail { box-shadow: 4px 0 24px rgba(30, 27, 46, .12); }
  body { padding-left: 68px; }
  main { padding: var(--py-space-4, 16px); }
}

/* Cibles tactiles ≥ 44px (pointeur grossier uniquement : la densité desktop
   au pointeur fin reste inchangée). Le toggle du rail garde son visuel 24px ;
   sa zone de frappe est étendue par pseudo-élément. */
@media (pointer: coarse) {
  .act { width: 44px; height: 44px; }
  #rail .toggle::before { content: ""; position: absolute; inset: -10px; }
  #rail nav a { min-height: 44px; }
  #rail .logout { min-height: 44px; display: inline-flex; align-items: center; }
  /* Chips-liens des toolbars (statut + avis) : des <a> inline par défaut, donc
     le min-height exige un display en boîte. Le gap restitue l'espace
     emoji/libellé que le flex avale (nœud texte blanc ignoré). */
  .statut-chips .chip { display: inline-flex; align-items: center; gap: 4px; min-height: 44px; }
}
