/* =========================================================
   Admin page - reuses tokens from /css/app.css
   Single-view studio: prompt | code | preview.
   ========================================================= */
.admin-body {
  min-height: 100vh;
  background: var(--vs-bg);
}
body.is-admin-page { min-height: 100vh; background: var(--vs-bg); }

/* =========================================================
   STUDIO LAYOUT - top: code | preview - bottom: prompt bar
   ========================================================= */
.admin-studio {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: minmax(0, 1fr) auto;
  grid-template-areas:
    "code preview"
    "prompt prompt";
  gap: 12px;
  padding: 12px 18px;
  height: calc(100vh - 56px - 46px); /* admin-nav (56) + admin-bench-toolbar (~46) */
  box-sizing: border-box;
  min-height: 0;
}

/* Bench sub-toolbar (sous le admin-nav, sur /admin uniquement) */
.admin-bench-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 24px;
  background: var(--vs-surface-1);
  border-bottom: 1px solid var(--vs-border);
  font-size: var(--vs-fs-sm);
}
.admin-bench-toolbar__pill {
  padding: 3px 8px;
  background: var(--vs-text);
  color: #fff;
  border-radius: 2px;
  font-family: var(--vs-font-pixel);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  border: 0;
}
.admin-bench-toolbar__hint {
  color: var(--vs-text-muted);
  flex: 1;
  font-size: 12px;
}
.admin-bench-toolbar__actions {
  display: flex;
  gap: 6px;
  align-items: center;
}
/* CTA "Charger un modèle" : visuellement saillant pour qu'on le voie tout de suite. */
.admin-bench-toolbar__cta {
  background: var(--vs-accent-low);
  color: var(--vs-accent-hi);
  border: 1px solid var(--vs-accent);
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.admin-bench-toolbar__cta:hover:not(:disabled) {
  background: var(--vs-accent);
  color: #fff;
  border-color: var(--vs-accent);
}
@media (max-width: 720px) {
  .admin-bench-toolbar { padding: 8px 14px; }
  .admin-bench-toolbar__hint { display: none; }
  .admin-studio { height: calc(100vh - 56px - 46px); padding: 8px; }
}
.admin-studio__col--code    { grid-area: code; }
.admin-studio__col--preview { grid-area: preview; }
.admin-studio__col--prompt  { grid-area: prompt; }

@media (max-width: 900px) {
  .admin-studio {
    grid-template-columns: 1fr;
    grid-template-rows: minmax(320px, 1fr) minmax(320px, 1fr) auto;
    grid-template-areas:
      "code"
      "preview"
      "prompt";
    height: auto;
    min-height: calc(100vh - 60px);
  }
}

.admin-studio__col {
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  padding: 12px 14px;
  display: flex; flex-direction: column;
  gap: 9px;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
}

/* Bottom prompt bar - auto-height, capped so it doesn't eat the top half */
.admin-studio__col--prompt {
  max-height: 38vh;
  overflow: auto;
}

.admin-studio__head {
  display: flex; flex-direction: column; gap: 3px;
  flex-shrink: 0;
}
.admin-studio__head--row {
  flex-direction: row; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 10px;
}
.admin-studio__head h2 {
  margin: 0;
  font-size: 13px; font-weight: 600;
  color: var(--vs-text);
  letter-spacing: 0.01em;
}
.admin-studio__head h2 code {
  font-family: var(--vs-font-pixel);
  background: rgba(15,23,42,0.06);
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 10px;
  font-weight: 500;
  color: var(--vs-text-muted);
}
.admin-studio__hint {
  margin: 0;
  font-size: 11px;
  color: var(--vs-text-dim);
  line-height: 1.45;
}
.admin-studio__hint--inline {
  display: inline; margin-left: 4px; font-weight: 400;
}
.admin-studio__hint kbd {
  display: inline-block;
  padding: 1px 5px;
  background: var(--vs-surface-3);
  border: 1px solid var(--vs-border);
  border-radius: 3px;
  font-size: 10px;
  font-family: var(--vs-font-pixel);
  color: var(--vs-text);
}

/* =========================================================
   PROMPT BAR (bottom, full-width)
   ========================================================= */
.admin-mode-bar {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
}
@media (max-width: 1100px) {
  .admin-mode-bar { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
}
.admin-mode-btn {
  position: relative;
  display: grid;
  grid-template-rows: auto auto auto;
  align-content: start;
  gap: 6px;
  padding: 12px 12px 11px;
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  color: var(--vs-text);
  min-width: 0;
  transition:
    border-color 120ms var(--vs-ease),
    background 120ms var(--vs-ease),
    transform 120ms var(--vs-ease),
    box-shadow 120ms var(--vs-ease);
}
.admin-mode-btn:hover:not(.is-active) {
  border-color: var(--vs-border-strong);
}
.admin-mode-btn.is-active {
  background: var(--vs-accent-low);
  border-color: var(--vs-accent);
}
.admin-mode-btn.is-active::after {
  /* Coche en haut à droite : confirmation visuelle de la sélection. */
  content: '';
  position: absolute;
  top: 8px;
  right: 8px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--vs-accent);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6 9 17 4 12'/></svg>");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 9px 9px;
}
.admin-mode-btn__icon {
  display: inline-grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: var(--vs-r-sm);
  background: var(--vs-surface-2);
  color: var(--vs-text-muted);
  flex-shrink: 0;
  transition: background 120ms var(--vs-ease), color 120ms var(--vs-ease);
}
.admin-mode-btn__icon svg { width: 16px; height: 16px; }
.admin-mode-btn:hover .admin-mode-btn__icon {
  background: var(--vs-surface-3);
}
.admin-mode-btn.is-active .admin-mode-btn__icon {
  background: var(--vs-accent);
  color: #fff;
}
.admin-mode-btn__tier {
  position: absolute;
  top: 12px;
  right: 12px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--vs-text-dim);
  background: var(--vs-surface-2);
  padding: 2px 7px;
  border-radius: var(--vs-r-pill);
  border: 1px solid var(--vs-border);
  line-height: 1;
}
.admin-mode-btn.is-active .admin-mode-btn__tier {
  /* Sur card active, la coche prend le coin haut droit → on cache le tier
     pour pas surcharger. */
  display: none;
}
.admin-mode-btn__title {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--vs-text);
  letter-spacing: -0.01em;
  line-height: 1.25;
  margin-top: 2px;
}
.admin-mode-btn.is-active .admin-mode-btn__title { color: var(--vs-accent-hi); }
.admin-mode-btn__sub {
  font-size: 11px;
  color: var(--vs-text-muted);
  line-height: 1.35;
}

/* ---- Prompt block (toolbar + textarea row) ---------------------------- */
.admin-prompt {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Toolbar : sélecteur de modèle à gauche, attach à droite. */
.admin-prompt__toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 6px 8px;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
}
.admin-prompt__model {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 auto;
  min-width: 0;
}
.admin-prompt__model-icon {
  display: inline-grid;
  place-items: center;
  width: 22px; height: 22px;
  color: var(--vs-text-muted);
  flex-shrink: 0;
}
.admin-prompt__model-icon svg { width: 14px; height: 14px; }
.admin-prompt__model-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--vs-text-muted);
  flex-shrink: 0;
}
.admin-prompt__model-select,
.admin-prompt__model-custom {
  flex: 1 1 220px;
  min-width: 160px;
  max-width: 360px;
  height: 32px;
  padding: 0 10px;
  font-size: 12.5px;
  font-family: inherit;
  color: var(--vs-text);
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-sm);
  outline: none;
  cursor: pointer;
  transition: border-color 120ms, box-shadow 120ms;
}
.admin-prompt__model-custom {
  font-family: 'JetBrains Mono', 'SF Mono', Menlo, ui-monospace, monospace;
  font-size: 12px;
  cursor: text;
}
.admin-prompt__model-select:hover,
.admin-prompt__model-custom:hover { border-color: var(--vs-border-strong); }
.admin-prompt__model-select:focus,
.admin-prompt__model-custom:focus { border-color: var(--vs-border-focus); box-shadow: var(--vs-glow); }
.admin-prompt__toolbar .admin-prompt__attach {
  align-self: center;
  flex-shrink: 0;
  margin-left: auto;
  padding: 0;
}

.admin-prompt__row {
  display: flex; align-items: stretch; gap: 10px;
}
.admin-prompt__row textarea {
  flex: 1; width: 100%;
  min-height: 56px; max-height: 140px;
  padding: 10px 12px;
  font-size: 13px; font-family: inherit;
  line-height: 1.5;
  background: var(--vs-bg);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  color: var(--vs-text);
  resize: none;
  outline: none;
  transition: border-color 120ms, box-shadow 120ms;
  box-sizing: border-box;
}
.admin-prompt__row textarea:focus { border-color: var(--vs-border-focus); box-shadow: var(--vs-glow); }
.admin-prompt__row textarea::placeholder { color: var(--vs-text-dim); }

@media (max-width: 720px) {
  .admin-prompt__toolbar { padding: 8px; }
  .admin-prompt__model { flex-wrap: wrap; }
  .admin-prompt__model-select,
  .admin-prompt__model-custom { flex-basis: 100%; max-width: none; }
  .admin-prompt__row { flex-direction: column; }
}

.admin-vision-banner {
  padding: 8px 12px;
  background: var(--vs-accent-low);
  border: 1px solid var(--vs-accent-line);
  border-radius: var(--vs-r-sm);
  font-size: 11px; line-height: 1.5;
  color: var(--vs-text-muted);
  font-family: 'JetBrains Mono', 'SF Mono', Menlo, ui-monospace, monospace;
  white-space: pre-wrap; word-break: break-word;
  max-height: 120px; overflow: auto;
}
.admin-vision-banner.is-error {
  background: var(--vs-danger-low);
  border-color: rgba(220, 38, 38, 0.35);
  color: var(--vs-danger);
}

.admin-extras { display: flex; flex-direction: column; gap: 8px; }
.admin-extras__row { display: flex; flex-direction: column; gap: 5px; }
.admin-extras__row[hidden] { display: none; }
.admin-extras__row > label {
  font-size: 11px; font-weight: 600; color: var(--vs-text-muted);
}
.admin-extras__row textarea {
  width: 100%;
  padding: 8px 10px;
  font-size: 11.5px;
  font-family: 'JetBrains Mono', 'SF Mono', Menlo, ui-monospace, monospace;
  background: var(--vs-bg);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-sm);
  color: var(--vs-text);
  outline: none;
  resize: vertical; min-height: 60px;
  line-height: 1.4;
  transition: border-color 120ms, box-shadow 120ms;
  box-sizing: border-box;
}
.admin-extras__row textarea:focus { border-color: var(--vs-border-focus); box-shadow: var(--vs-glow); }
.admin-extras__hint {
  font-size: 10px; color: var(--vs-text-dim);
  font-weight: 500; font-family: inherit;
}
.admin-extras__hint.is-set { color: var(--vs-success); }
.admin-extras__hint.is-warn { color: var(--vs-warn); }
.admin-extras__actions {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}

/* Status pill below the Generate button - communicates spinner / OK / error */
.admin-status {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-sm);
  font-size: 11.5px;
  color: var(--vs-text-muted);
  font-variant-numeric: tabular-nums;
  line-height: 1.4;
  word-break: break-word;
  min-height: 38px;
  box-sizing: border-box;
}
.admin-status .dim { color: var(--vs-text-dim); }
.admin-status strong { color: var(--vs-text); font-weight: 600; }
.admin-status svg { width: 14px; height: 14px; flex: 0 0 auto; }
.admin-status.is-pending {
  background: rgba(98, 68, 255, 0.08);
  border-color: var(--vs-accent-line);
  color: var(--vs-accent-hi);
}
.admin-status.is-ok {
  background: var(--vs-success-low);
  border-color: rgba(22, 163, 74, 0.30);
  color: var(--vs-success);
}
.admin-status.is-ok svg { color: var(--vs-success); }
.admin-status.is-error {
  background: var(--vs-danger-low);
  border-color: rgba(220, 38, 38, 0.35);
  color: var(--vs-danger);
}
.admin-status.is-error svg { color: var(--vs-danger); }

.admin-spinner {
  width: 12px; height: 12px;
  border-radius: 50%;
  border: 2px solid var(--vs-border-strong);
  border-top-color: var(--vs-accent);
  animation: admin-spin 800ms linear infinite;
  display: inline-block;
  flex: 0 0 auto;
}
@keyframes admin-spin { to { transform: rotate(360deg); } }

/* =========================================================
   COL 2 - CODE EDITOR (sandbox)
   ========================================================= */
.admin-studio__col--code .sandbox-editor__actions {
  display: flex; gap: 6px; flex-shrink: 0; flex-wrap: wrap;
}
.admin-studio__col--code .sandbox-code,
.sandbox-code {
  flex: 1;
  min-height: 0;
  width: 100%;
  resize: none;
  padding: 12px 14px;
  background: var(--vs-bg);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  color: var(--vs-text);
  font-family: 'JetBrains Mono', 'SF Mono', Menlo, ui-monospace, monospace;
  font-size: 12px;
  line-height: 1.55;
  white-space: pre;
  overflow: auto;
  outline: none;
  transition: border-color 120ms var(--vs-ease), box-shadow 120ms var(--vs-ease);
  box-sizing: border-box;
}
.sandbox-code:focus {
  border-color: var(--vs-accent);
}
.sandbox-error {
  padding: 10px 12px;
  background: var(--vs-danger-low);
  border: 1px solid rgba(220, 38, 38, 0.35);
  border-radius: var(--vs-r-sm);
  color: var(--vs-danger);
  font-family: 'JetBrains Mono', 'SF Mono', Menlo, ui-monospace, monospace;
  font-size: 11.5px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 160px;
  overflow: auto;
  flex-shrink: 0;
}

/* =========================================================
   COL 3 - PREVIEW
   ========================================================= */
.sandbox-canvas {
  flex: 1;
  min-height: 0;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  overflow: hidden;
  position: relative;
}
.sandbox-canvas canvas { display: block; }
.sandbox-info {
  display: flex; flex-direction: column; gap: 6px;
  font-family: var(--vs-font-pixel);
  font-size: 11px;
  color: var(--vs-text-muted);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
  max-height: 110px;
  overflow: auto;
}
.sandbox-info__row {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
.sandbox-info__row strong { color: var(--vs-text); font-weight: 600; }
.sandbox-info__row .dim { color: var(--vs-text-dim); }
.sandbox-info__anims {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding-top: 4px;
  border-top: 1px solid var(--vs-border);
}

/* Animation switcher (reused from old preview) */
.admin-preview-play {
  display: grid; place-items: center;
  width: 28px; height: 28px;
  flex: 0 0 auto;
  background: var(--vs-accent);
  color: #fff;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  transition: background 120ms var(--vs-ease);
}
.admin-preview-play:hover { background: var(--vs-accent-hi); }
.admin-preview-play svg { width: 12px; height: 12px; }

.admin-preview-anim {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px;
  background: var(--vs-bg);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-pill);
  color: var(--vs-text-muted);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  transition: background 160ms var(--vs-ease), color 160ms var(--vs-ease),
              border-color 160ms var(--vs-ease), box-shadow 160ms var(--vs-ease),
              transform 160ms var(--vs-ease);
  font-family: inherit;
}
.admin-preview-anim:hover {
  background: var(--vs-surface-3);
  color: var(--vs-text);
  border-color: var(--vs-border-strong);
  transform: translateY(-1px);
}
.admin-preview-anim.is-active {
  background: var(--vs-green);
  color: #fff;
  border-color: transparent;
  box-shadow: 0 2px 8px rgba(22, 163, 74, 0.28);
  transform: translateY(-1px);
}
.admin-preview-anim .dim { font-weight: 500; opacity: 0.8; }

/* =========================================================
   PUBLISH BUTTON + DIALOG
   ========================================================= */
.vs-btn.vs-btn--publish {
  background: var(--vs-success);
  color: #fff;
  border: 1px solid #15803d;
  font-weight: 600;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0 14px;
  height: 30px;
  font-size: 12px;
  border-radius: var(--vs-r-sm);
  cursor: pointer;
  transition: background 120ms var(--vs-ease), transform 80ms;
}
.vs-btn.vs-btn--publish:hover { background: #15803d; }
.vs-btn.vs-btn--publish:active { transform: scale(0.97); }
.vs-btn.vs-btn--publish:disabled {
  background: var(--vs-surface-3); color: var(--vs-text-dim);
  border-color: var(--vs-border);
  cursor: not-allowed;
}

.admin-dialog--publish {
  width: min(680px, 94vw);
  max-height: 88vh;
  display: flex; flex-direction: column;
  gap: 14px;
}
.admin-dialog__sub {
  font-size: 11px;
  font-weight: 500;
  color: var(--vs-text-dim);
  margin-left: 6px;
}

/* =========================================================
   DIALOG (prompt viewer)
   ========================================================= */
.admin-dialog-backdrop {
  position: fixed; inset: 0;
  background: rgba(15, 23, 42, 0.45);
  backdrop-filter: blur(6px);
  display: grid; place-items: center;
  z-index: 100;
  opacity: 0; pointer-events: none;
  transition: opacity 200ms;
}
.admin-dialog-backdrop.is-open { opacity: 1; pointer-events: auto; }
.admin-dialog {
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border-strong);
  border-radius: var(--vs-r-lg);
  padding: 22px;
  width: min(420px, 92vw);
  display: flex; flex-direction: column; gap: 14px;
  box-shadow: var(--vs-shadow-3);
}
.admin-dialog h3 { font-size: 14px; font-weight: 600; margin: 0; }
.admin-dialog__actions { display: flex; justify-content: flex-end; gap: 8px; }

.admin-dialog--wide {
  width: min(960px, 94vw);
  max-height: 88vh;
  display: flex; flex-direction: column;
  gap: 12px;
}
.admin-dialog__head {
  display: flex; align-items: center; justify-content: space-between;
}
.admin-dialog__head h3 { font-size: 15px; font-weight: 600; }
.admin-dialog__close {
  width: 28px; height: 28px;
  display: grid; place-items: center;
  background: transparent;
  border: none;
  font-size: 22px;
  line-height: 1;
  color: var(--vs-text-dim);
  cursor: pointer;
  border-radius: var(--vs-r-sm);
  transition: all 120ms;
}
.admin-dialog__close:hover { background: var(--vs-surface-3); color: var(--vs-text); }
.admin-dialog__meta {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: 8px 12px;
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-sm);
  font-size: 11px;
  color: var(--vs-text-muted);
  font-variant-numeric: tabular-nums;
}
.admin-dialog__meta strong { color: var(--vs-text); font-weight: 600; }
.admin-dialog__meta .dim { color: var(--vs-text-dim); }

.admin-prompt-tabs {
  display: flex; flex-wrap: wrap;
  gap: 2px;
  padding: 3px;
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
}
.admin-prompt-tabs button {
  padding: 6px 12px;
  background: transparent;
  border: none;
  border-radius: var(--vs-r-sm);
  color: var(--vs-text-dim);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  transition: all 120ms var(--vs-ease);
  font-family: inherit;
}
.admin-prompt-tabs button:hover:not(.is-active) {
  background: var(--vs-surface-3);
  color: var(--vs-text);
}
.admin-prompt-tabs button.is-active {
  background: var(--vs-accent-low);
  color: var(--vs-accent-hi);
  border-color: var(--vs-accent);
}
.admin-prompt-view {
  flex: 1;
  margin: 0;
  padding: 14px 16px;
  font-family: 'JetBrains Mono', 'SF Mono', Menlo, ui-monospace, monospace;
  font-size: 12px;
  line-height: 1.55;
  color: var(--vs-text-muted);
  background: var(--vs-bg);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 60vh;
  min-height: 240px;
}

/* =========================================================
   ADMIN - header partagé `_admin_nav.php`
   Même langage que la nav publique : mark voxel multicolore,
   liens actifs marqués par un soulignement à l'accent (au
   lieu de pill colorée), bouton user en noir solide.
   On garde un accent par défaut côté admin (rouge - c'est le
   back-office, ça signale l'autorité) que tu peux changer en
   posant data-accent="..." sur <body class="admin-body">.
   ========================================================= */
.admin-body { --vs-accent: var(--vs-red); --vs-accent-hi: #be123c; --vs-accent-low: rgba(225, 29, 72, 0.10); --vs-accent-line: rgba(225, 29, 72, 0.28); }

.admin-nav {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 28px;
  padding: 12px 24px;
  height: 56px;
  background: var(--vs-surface-1);
  border-bottom: 1px solid var(--vs-border);
}
.admin-nav__brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--vs-text);
  font-weight: 700;
  letter-spacing: -0.015em;
  flex-shrink: 0;
}
/* Mark voxel - même cube pixelisé que sur le front, en plus grand
   (24px). Quatre cellules : noir / rouge / bleu / jaune, comme la
   nav publique. */
.admin-nav__logo {
  width: 22px; height: 22px;
  display: inline-grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 1px;
  flex: 0 0 auto;
  background: transparent;
  border-radius: 0;
  place-items: stretch;
}
.admin-nav__logo > i { display: block; }
.admin-nav__logo > i:nth-child(1) { background: var(--vs-text); }
.admin-nav__logo > i:nth-child(2) { background: var(--vs-red); }
.admin-nav__logo > i:nth-child(3) { background: var(--vs-blue); }
.admin-nav__logo > i:nth-child(4) { background: var(--vs-yellow); }
/* fallback si un ancien <svg> survit dans le markup */
.admin-nav__logo svg { display: none; }

.admin-nav__title { font-size: 15px; }
/* Pill "Admin" - uppercase mono, fond gris, vraiment éditorial */
.admin-nav__pill {
  padding: 3px 8px;
  background: var(--vs-text);
  color: #fff;
  border-radius: 2px;
  font-family: var(--vs-font-pixel);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  border: 0;
}
.admin-nav__links {
  display: flex;
  gap: 4px;
  flex: 1;
  margin-left: 4px;
}
.admin-nav__link {
  position: relative;
  padding: 8px 12px;
  border-radius: 0;
  color: var(--vs-text-muted);
  font-size: var(--vs-fs-lg);
  font-weight: 500;
  text-decoration: none;
  transition: color 120ms var(--vs-ease);
  background: transparent;
}
.admin-nav__link:hover { color: var(--vs-text); background: transparent; }
.admin-nav__link.is-active {
  color: var(--vs-text);
  background: transparent;
  font-weight: 600;
}
.admin-nav__link--support { display: inline-flex; align-items: center; gap: 6px; }
.admin-nav__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  border-radius: 999px;
  background: var(--vs-red, #e11d48);
  color: #fff;
}
.admin-nav__badge[hidden] { display: none; }
.admin-nav__link.is-active::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 2px;
  height: 2px;
  background: var(--vs-accent);
}
.admin-nav__right {
  display: flex;
  align-items: center;
  gap: 8px;
}
.admin-nav__back,
.admin-nav__user {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border-radius: var(--vs-r-md);
  font-size: var(--vs-fs-md);
  font-weight: 500;
  text-decoration: none;
  border: 1px solid var(--vs-border-strong);
  transition: background 120ms var(--vs-ease), border-color 120ms var(--vs-ease), color 120ms var(--vs-ease);
}
.admin-nav__back {
  color: var(--vs-text-muted);
  background: transparent;
}
.admin-nav__back:hover { color: var(--vs-text); background: var(--vs-surface-3); border-color: var(--vs-text); }
.admin-nav__user {
  background: var(--vs-text);
  color: #fff;
  border-color: var(--vs-text);
  font-weight: 600;
}
.admin-nav__user:hover { background: #1f1f1f; border-color: #1f1f1f; }

/* ---------- Mobile burger admin (≤720px) ----------
   Même pattern que .vs-c-nav du site public : drawer { display: contents }
   sur desktop pour disparaître ; en mobile, toggle visible et drawer en
   absolute sous le header. */
.admin-nav__drawer { display: contents; }
.admin-nav__toggle {
  display: none;
  position: relative;
  width: 38px;
  height: 38px;
  margin-left: auto;
  background: transparent;
  border: 1px solid var(--vs-border-strong);
  border-radius: var(--vs-r-md);
  cursor: pointer;
  padding: 0;
  flex: 0 0 auto;
  transition: border-color 120ms var(--vs-ease), background 120ms var(--vs-ease);
}
.admin-nav__toggle:hover { border-color: var(--vs-text); background: var(--vs-surface-2); }
.admin-nav__toggle:focus-visible { outline: 2px solid var(--vs-accent); outline-offset: 2px; }
.admin-nav__burger,
.admin-nav__burger::before,
.admin-nav__burger::after {
  display: block;
  position: absolute;
  width: 18px;
  height: 2px;
  background: var(--vs-text);
  border-radius: 1px;
  transition: transform 200ms var(--vs-ease), top 200ms var(--vs-ease), background 200ms var(--vs-ease);
}
.admin-nav__burger { top: 50%; left: 50%; transform: translate(-50%, -50%); }
.admin-nav__burger::before,
.admin-nav__burger::after { content: ''; left: 0; }
.admin-nav__burger::before { top: -6px; }
.admin-nav__burger::after  { top:  6px; }
.admin-nav__toggle[aria-expanded="true"] .admin-nav__burger { background: transparent; }
.admin-nav__toggle[aria-expanded="true"] .admin-nav__burger::before { top: 0; transform: rotate(45deg); }
.admin-nav__toggle[aria-expanded="true"] .admin-nav__burger::after  { top: 0; transform: rotate(-45deg); }

@media (max-width: 720px) {
  .admin-nav { padding: 10px 14px; gap: 12px; position: relative; }
  .admin-nav__title { display: none; }
  .admin-nav__toggle { display: inline-grid; place-items: center; }
  .admin-nav__drawer {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    background: var(--vs-surface-1);
    border-bottom: 1px solid var(--vs-border);
    padding: 12px 14px 14px;
    gap: 6px;
    z-index: 49;
    box-shadow: 0 12px 32px -16px rgba(10,10,10,0.18);
  }
  .admin-nav__drawer.is-open { display: flex; }
  .admin-nav__links {
    flex-direction: column;
    gap: 0;
    margin: 0;
    flex: 0 0 auto;
    width: 100%;
    overflow: visible;  /* annule le overflow-x: auto desktop pour le drawer vertical */
  }
  .admin-nav__link {
    padding: 10px 8px;
    font-size: var(--vs-fs-xl);
    border-bottom: 1px solid var(--vs-border);
  }
  .admin-nav__link:last-child { border-bottom: 0; }
  .admin-nav__link.is-active::after {
    left: 0;
    right: auto;
    top: 8px;
    bottom: 8px;
    width: 2px;
    height: auto;
  }
  .admin-nav__link.is-active { padding-left: 12px; }
  .admin-nav__right {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    gap: 8px;
    padding-top: 10px;
    border-top: 1px solid var(--vs-border);
  }
  .admin-nav__back { display: inline-flex; justify-content: center; }
  .admin-nav__user { justify-content: center; }
}

/* =========================================================
   ADMIN - pages tabular (Logs, Users)
   ========================================================= */
.admin-page {
  max-width: 1400px;
  margin: 0 auto;
  width: 100%;
  padding: 24px;
  box-sizing: border-box;
}
.admin-page__head {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}
.admin-page__title {
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  color: var(--vs-text);
  letter-spacing: -0.01em;
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.admin-page__count {
  font-size: 13px;
  color: var(--vs-text-muted);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.admin-tabs {
  display: inline-flex;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  padding: 3px;
  gap: 2px;
  margin-left: auto;
}
.admin-tabs__btn {
  padding: 7px 16px;
  border-radius: var(--vs-r-sm);
  color: var(--vs-text-muted);
  text-decoration: none;
  font-size: var(--vs-fs-md);
  font-weight: 500;
  transition: background 120ms var(--vs-ease), color 120ms var(--vs-ease);
  font-family: inherit;
  background: transparent;
  border: none;
  cursor: pointer;
}
.admin-tabs__btn:hover:not(.is-active) { color: var(--vs-text); }
.admin-tabs__btn.is-active {
  background: var(--vs-accent);
  color: #fff;
  font-weight: 600;
}

.admin-card {
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-lg);
  padding: 14px 16px;
  margin-bottom: 16px;
  box-shadow: var(--vs-shadow-1);
}
.admin-card--filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  /* flex-end : tous les contrôles (input, btn, checkbox) s'alignent par le bas
     pour que le bouton "Filtrer" soit aligné avec la baseline des inputs même
     quand des fields ont un label au-dessus et d'autres pas. */
  align-items: flex-end;
}
.admin-card__field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.admin-card__field--grow   { flex: 1 1 220px; min-width: 220px; }
.admin-card__field--wide   { flex: 1 1 240px; min-width: 240px; }
.admin-card__field--narrow { width: 110px; flex: 0 0 110px; }
.admin-card__field > span {
  font-size: 10px;
  font-weight: 600;
  color: var(--vs-text-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.admin-card__field input,
.admin-card__field select {
  height: 34px;
  padding: 0 10px;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-sm);
  color: var(--vs-text);
  font-size: var(--vs-fs-md);
  font-family: inherit;
  outline: none;
  transition: border-color 120ms, box-shadow 120ms;
}
.admin-card__field input:focus,
.admin-card__field select:focus {
  border-color: var(--vs-border-focus);
  box-shadow: var(--vs-glow);
}
.admin-card__check {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 34px;
  font-size: var(--vs-fs-md);
  color: var(--vs-text-muted);
  cursor: pointer;
  user-select: none;
}
.admin-card__check input { cursor: pointer; }
.admin-card__btn {
  height: 34px;
  padding: 0 18px;
  background: var(--vs-accent);
  color: #fff;
  border: none;
  border-radius: var(--vs-r-sm);
  font-size: var(--vs-fs-md);
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  /* inline-flex pour que les <a class="admin-card__btn"> avec icône+label
     s'alignent proprement sans styles inline. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-decoration: none;
  line-height: 1;
  white-space: nowrap;
  transition: background 120ms;
}
.admin-card__btn:hover { background: var(--vs-accent-hi); }
.admin-card__btn .vs-icon { width: 14px; height: 14px; flex: 0 0 auto; }
.admin-card__btn--ghost {
  background: transparent;
  color: var(--vs-text-muted);
  border: 1px solid var(--vs-border-strong);
}
.admin-card__btn--ghost:hover { background: var(--vs-surface-2); color: var(--vs-text); }

/* Wrapper scroll-x autour des tables admin : sur écrans étroits, la table
   peut faire >1000px (logs.php gen a 10 colonnes). Sans ce wrap, elle force
   un scroll horizontal sur toute la page. */
.admin-data-wrap {
  width: 100%;
  overflow-x: auto;
  border-radius: var(--vs-r-lg);
  border: 1px solid var(--vs-border);
  background: var(--vs-surface-1);
  box-shadow: var(--vs-shadow-1);
}
.admin-data-wrap > .admin-data {
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
.admin-data {
  width: 100%;
  border-collapse: collapse;
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-lg);
  overflow: hidden;
  font-size: 12.5px;
  box-shadow: var(--vs-shadow-1);
}
.admin-data thead th {
  background: var(--vs-surface-2);
  color: var(--vs-text-muted);
  font-weight: 600;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 10px 12px;
  text-align: left;
  border-bottom: 1px solid var(--vs-border);
}
.admin-data tbody td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--vs-border);
  vertical-align: middle;
  color: var(--vs-text);
}
.admin-data tbody tr:last-child td { border-bottom: 0; }
.admin-data tbody tr:hover td { background: var(--vs-surface-2); }
.admin-data .dim { color: var(--vs-text-dim); }
.admin-data .err { color: var(--vs-danger); }
.admin-data code {
  font-family: var(--vs-font-pixel);
  font-size: 11px;
  background: var(--vs-surface-2);
  padding: 1px 6px;
  border-radius: 4px;
}
.admin-data__row-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: var(--vs-r-sm);
  color: var(--vs-accent-hi);
  text-decoration: none;
  background: var(--vs-accent-low);
  border: 1px solid var(--vs-accent-line);
  transition: background 120ms, color 120ms, border-color 120ms;
}
.admin-data__row-action:hover {
  background: var(--vs-accent);
  color: #fff;
  border-color: var(--vs-accent);
}
.admin-data__row-action svg { width: 14px; height: 14px; }
/* Cellule payload (logs activité) : json brut potentiellement long, on cap
   la largeur et on autorise le wrap pour ne pas exploser la table. */
.admin-data__payload {
  display: inline-block;
  max-width: 360px;
  font-family: 'JetBrains Mono', 'SF Mono', Menlo, ui-monospace, monospace;
  font-size: 11px;
  color: var(--vs-text-muted);
  background: transparent;
  padding: 0;
  white-space: pre-wrap;
  word-break: break-word;
  vertical-align: top;
}
.admin-data__empty {
  text-align: center;
  color: var(--vs-text-muted);
  padding: 32px;
  font-size: var(--vs-fs-md);
  font-style: italic;
}

.admin-data__inline-form { display: inline-flex; gap: 4px; align-items: center; margin: 0; }
.admin-data__inline-form input[type=number],
.admin-data__inline-form select {
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  color: var(--vs-text);
  border-radius: 6px;
  padding: 5px 8px;
  font-size: 12px;
  font-family: inherit;
  width: 70px;
}
.admin-data__inline-form button {
  background: var(--vs-surface-2);
  color: var(--vs-text-muted);
  border: 1px solid var(--vs-border);
  border-radius: 6px;
  padding: 5px 10px;
  font-size: 12px;
  cursor: pointer;
  font-family: inherit;
  transition: background 120ms, color 120ms;
}
.admin-data__inline-form button:hover { background: var(--vs-surface-3); color: var(--vs-text); }
.admin-data__inline-form button.is-primary {
  background: var(--vs-accent);
  color: #fff;
  border-color: transparent;
}
.admin-data__inline-form button.is-primary:hover { background: var(--vs-accent-hi); }
.admin-data__inline-form button.is-danger { color: var(--vs-danger); border-color: rgba(220, 38, 38, 0.3); }
.admin-data__inline-form button.is-danger:hover { background: var(--vs-danger-low); }

/* Éléments d'action posés directement dans une td (sans wrapper
   .admin-data__inline-form) - même look pour rester cohérent avec le reste
   de la table. Pattern utilisé par /admin/users (set-role, verify, delete). */
.admin-data tbody td > select,
.admin-data tbody td > button[data-act] {
  background: var(--vs-surface-2);
  color: var(--vs-text);
  border: 1px solid var(--vs-border);
  border-radius: 6px;
  padding: 5px 10px;
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
  transition: background 120ms, color 120ms, border-color 120ms;
  vertical-align: middle;
}
.admin-data tbody td > select { padding: 4px 8px; }
.admin-data tbody td > select:hover,
.admin-data tbody td > select:focus { border-color: var(--vs-accent); outline: none; }
.admin-data tbody td > button[data-act] { color: var(--vs-text-muted); }
.admin-data tbody td > button[data-act]:hover { background: var(--vs-surface-3); color: var(--vs-text); }
.admin-data tbody td > button[data-act].is-danger {
  color: var(--vs-danger);
  border-color: rgba(220, 38, 38, 0.3);
}
.admin-data tbody td > button[data-act].is-danger:hover { background: var(--vs-danger-low); }
.admin-data tbody td > .admin-data__inline-form + button[data-act],
.admin-data tbody td > button[data-act] + button[data-act] { margin-left: 6px; }

.admin-pill {
  display: inline-block;
  padding: 2px 9px;
  border-radius: var(--vs-r-pill);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.admin-pill--ok    { background: var(--vs-success-low); color: var(--vs-success); }

.admin-pagination {
  display: flex;
  gap: 4px;
  margin-top: 18px;
  flex-wrap: wrap;
  align-items: center;
}
.admin-pagination a {
  padding: 7px 12px;
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  color: var(--vs-text-muted);
  border-radius: var(--vs-r-sm);
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  transition: background 120ms;
}
.admin-pagination a:hover { background: var(--vs-surface-2); color: var(--vs-text); }
.admin-pagination a.is-active {
  background: var(--vs-accent);
  color: #fff;
  border-color: transparent;
  font-weight: 600;
}

.admin-flash {
  padding: 11px 14px;
  border-radius: var(--vs-r-md);
  font-size: var(--vs-fs-md);
  margin-bottom: 16px;
  border: 1px solid transparent;
}
.admin-flash--success { background: var(--vs-success-low); color: var(--vs-success); border-color: rgba(22, 163, 74, 0.2); }
.admin-flash--error   { background: var(--vs-danger-low);  color: var(--vs-danger);  border-color: rgba(220, 38, 38, 0.25); }

/* Detail pane (logs.php - vue détail d'une génération) */
.admin-detail {
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-lg);
  padding: 18px 20px;
  margin-bottom: 16px;
  box-shadow: var(--vs-shadow-1);
}
.admin-detail__head {
  font-size: 16px;
  font-weight: 600;
  color: var(--vs-text);
  margin: 0 0 14px;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
}
.admin-detail__head-meta {
  font-size: 13px;
  font-weight: 400;
  color: var(--vs-text-muted);
}
.admin-detail__close {
  margin-top: 14px;
  display: inline-flex;
}
.admin-detail__close .vs-icon { width: 14px; height: 14px; }
.admin-detail__grid {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 6px 14px;
  margin-bottom: 14px;
  font-size: 13px;
}
.admin-detail__grid b { color: var(--vs-text-muted); font-weight: 500; }
.admin-detail__sub {
  font-size: 11px;
  font-weight: 700;
  color: var(--vs-text-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 18px 0 6px;
}
.admin-detail pre {
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-sm);
  padding: 12px 14px;
  overflow: auto;
  max-height: 320px;
  font-size: 12px;
  color: var(--vs-text);
  font-family: 'JetBrains Mono', 'SF Mono', Menlo, ui-monospace, monospace;
  margin: 0;
}

/* =========================================================
   ADMIN - Import picker modal (charger un modèle public dans le bench)
   ========================================================= */
.admin-import {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 16px;
}
.admin-import__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 23, 42, 0.45);
  backdrop-filter: blur(6px);
  cursor: pointer;
}
.admin-import__panel {
  position: relative;
  width: min(960px, 100%);
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border-strong);
  border-radius: var(--vs-r-lg);
  box-shadow: var(--vs-shadow-3);
  overflow: hidden;
}
.admin-import__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  border-bottom: 1px solid var(--vs-border);
}
.admin-import__head h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--vs-text);
}
.admin-import__close {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border: none;
  background: transparent;
  color: var(--vs-text-muted);
  border-radius: var(--vs-r-sm);
  cursor: pointer;
  transition: background 120ms;
}
.admin-import__close:hover { background: var(--vs-surface-2); color: var(--vs-text); }
.admin-import__close svg { width: 16px; height: 16px; }

.admin-import__filters {
  display: flex;
  gap: 12px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--vs-border);
  background: var(--vs-surface-2);
}
.admin-import__search {
  flex: 1;
  position: relative;
  display: flex;
  align-items: center;
}
.admin-import__search svg {
  position: absolute;
  left: 12px;
  width: 14px;
  height: 14px;
  color: var(--vs-text-dim);
  pointer-events: none;
}
.admin-import__search input {
  width: 100%;
  height: 36px;
  padding: 0 12px 0 34px;
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  color: var(--vs-text);
  font-size: 14px;
  font-family: inherit;
  outline: none;
  transition: border-color 120ms, box-shadow 120ms;
}
.admin-import__search input:focus {
  border-color: var(--vs-border-focus);
  box-shadow: var(--vs-glow);
}
.admin-import__sort {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.admin-import__sort > span {
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--vs-text-dim);
}
.admin-import__sort select {
  height: 36px;
  padding: 0 28px 0 10px;
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  color: var(--vs-text);
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
}

.admin-import__grid {
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 12px;
  align-content: start;
}
.admin-import__loading,
.admin-import__empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: 48px 16px;
  color: var(--vs-text-muted);
  font-size: 14px;
}

.admin-import__card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  cursor: pointer;
  font-family: inherit;
  text-align: left;
  transition: border-color 120ms, opacity 120ms;
}
.admin-import__card:hover {
  border-color: var(--vs-accent);
}
.admin-import__card.is-loading {
  opacity: 0.5;
  cursor: wait;
}
.admin-import__thumb {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  background: var(--vs-surface-1);
  border-radius: var(--vs-r-sm);
}
.admin-import__thumb.is-placeholder {
  display: grid;
  place-items: center;
  color: var(--vs-text-dim);
  font-size: 32px;
}
.admin-import__card-body {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 2px 4px 4px;
  min-width: 0;
}
.admin-import__card-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--vs-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.admin-import__card-author {
  font-size: 11px;
  color: var(--vs-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.admin-import__card-meta {
  font-size: 10px;
  color: var(--vs-text-dim);
  font-weight: 500;
  letter-spacing: 0.02em;
}

.admin-import__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 20px;
  border-top: 1px solid var(--vs-border);
  background: var(--vs-surface-2);
  flex-wrap: wrap;
}
.admin-import__hint {
  font-size: 12px;
  color: var(--vs-text-muted);
}
.admin-import__pager {
  display: flex;
  align-items: center;
  gap: 6px;
}
.admin-import__pager-btn {
  height: 30px;
  width: 30px;
  display: grid;
  place-items: center;
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-sm);
  color: var(--vs-text-muted);
  cursor: pointer;
  font-family: inherit;
  font-size: 14px;
  transition: background 120ms, color 120ms;
}
.admin-import__pager-btn:not([disabled]):hover {
  background: var(--vs-surface-3);
  color: var(--vs-text);
}
.admin-import__pager-btn[disabled] { opacity: 0.4; cursor: not-allowed; }
.admin-import__pager-pos {
  font-size: 12px;
  color: var(--vs-text-muted);
  font-variant-numeric: tabular-nums;
  min-width: 50px;
  text-align: center;
}

@media (max-width: 600px) {
  .admin-import__filters { flex-direction: column; gap: 8px; }
  .admin-import__sort { flex-direction: row; align-items: center; gap: 8px; }
  .admin-import__grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); padding: 12px; gap: 8px; }
}

/* =========================================================
   BenchTest page - /admin/bench-test
   Pipeline 2-step (mesh / animate), onglets retrieval + Logs.
   Réutilise l'AdminPreview Three.js et le ScriptRunner.
   ========================================================= */

.bench-page {
  max-width: 1480px;
  margin: 0 auto;
  padding: 16px 20px 64px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.bench-header {
  background: var(--vs-surface);
  border: 1px solid var(--vs-border);
  border-radius: 10px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.bench-header__title h1 {
  font-size: 18px;
  margin: 0;
  font-weight: 700;
}
.bench-header__sub {
  font-size: 13px;
  font-weight: 400;
  color: var(--vs-text-dim);
  margin-left: 8px;
}
.bench-header__row {
  display: flex;
  gap: 10px;
  align-items: stretch;
}
.bench-header__prompt {
  flex: 1;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  padding: 10px 12px;
  font-family: inherit;
  font-size: 14px;
  color: var(--vs-text);
  resize: vertical;
  min-height: 56px;
}
.bench-header__buttons {
  display: flex;
  gap: 8px;
  align-items: stretch;
  flex-shrink: 0;
}
.bench-header__models {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)) auto;
  gap: 10px;
  align-items: end;
}
.bench-header__model {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 11px;
  color: var(--vs-text-dim);
}
.bench-header__model > span {
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.bench-header__select {
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: 6px;
  padding: 6px 8px;
  font-size: 13px;
  color: var(--vs-text);
  font-family: inherit;
}

/* ---------- Multi-select chips (step1/2/3) ----------
 * Chaque step accepte 1 à 4 modèles, distribués round-robin sur les 4
 * candidats parallèles (cf. distributeModelsAcrossSlots). 1 modèle = comportement
 * historique (4 candidats du même modèle). 2+ modèles = comparaison.
 * --------------------------------------------------- */
.bench-header__model--multi > span em {
  font-style: normal;
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
}
.bench-header__multi {
  position: relative;  /* ancrage du menu dropdown */
}
.bench-model-multi {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  padding: 4px;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: 6px;
  min-height: 32px;
}
.bench-model-multi__chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 4px 3px 8px;
  background: var(--vs-accent-low, rgba(98,68,255,0.10));
  border: 1px solid var(--vs-accent-line, rgba(98,68,255,0.25));
  border-radius: 4px;
  font-size: 12px;
  font-weight: 500;
  color: var(--vs-text);
  white-space: nowrap;
  max-width: 100%;
}
.bench-model-multi__chip-label {
  text-overflow: ellipsis;
  overflow: hidden;
  max-width: 220px;
}
.bench-model-multi__chip-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--vs-text-muted);
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  border-radius: 3px;
  font-family: inherit;
}
.bench-model-multi__chip-x:hover:not(:disabled) {
  background: var(--vs-danger, #dc2626);
  color: #fff;
}
.bench-model-multi__chip-x:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.bench-model-multi__add {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  background: transparent;
  border: 1px dashed var(--vs-border-strong, var(--vs-border));
  border-radius: 4px;
  color: var(--vs-text-muted);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  font-family: inherit;
  white-space: nowrap;
  transition: all 120ms ease;
}
.bench-model-multi__add:hover:not(:disabled) {
  background: var(--vs-surface-1);
  color: var(--vs-text);
  border-style: solid;
  border-color: var(--vs-accent, #6244ff);
}
.bench-model-multi__add:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.bench-model-multi__add-plus {
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
}

/* Menu dropdown - apparaît sous le composant */
.bench-model-multi__menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 100;
  max-height: 320px;
  overflow-y: auto;
  background: var(--vs-surface, #fff);
  border: 1px solid var(--vs-border);
  border-radius: 6px;
  box-shadow: 0 12px 28px rgba(0,0,0,0.18);
  padding: 4px;
}
.bench-model-multi__menu-group {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--vs-text-dim);
  padding: 6px 8px 2px;
}
.bench-model-multi__menu-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 6px 8px;
  background: transparent;
  border: none;
  font-size: 13px;
  color: var(--vs-text);
  cursor: pointer;
  border-radius: 4px;
  font-family: inherit;
}
.bench-model-multi__menu-item:hover {
  background: var(--vs-accent-low, rgba(98,68,255,0.10));
  color: var(--vs-accent-hi, #6244ff);
}
.bench-model-multi__menu-empty {
  padding: 10px 8px;
  font-size: 12px;
  color: var(--vs-text-dim);
  font-style: italic;
  text-align: center;
}

/* Hint de distribution sous le composant : "Slots : #1 Gemma  #2 Minimax …" */
.bench-model-multi__hint {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  padding: 4px 2px 0;
  font-size: 11px;
  color: var(--vs-text-dim);
  border-top: 1px dashed var(--vs-border);
}
.bench-model-multi__hint-prefix {
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 10px;
  color: var(--vs-text-muted);
}
.bench-model-multi__hint-slot {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 6px;
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: 3px;
  font-size: 11px;
  color: var(--vs-text);
  white-space: nowrap;
}
.bench-header__total {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  padding: 8px 12px;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  min-width: 140px;
}
.bench-header__total-label {
  font-size: 10px;
  color: var(--vs-text-dim);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.bench-header__total-value {
  font-size: 18px;
  font-weight: 700;
  font-family: 'JetBrains Mono', monospace;
  color: var(--vs-text);
}
.bench-header__total-hint {
  font-size: 11px;
  color: var(--vs-text-dim);
}
.bench-header__runid {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  color: var(--vs-text-dim);
}
.bench-header__runid code {
  background: var(--vs-surface-2);
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 11px;
  font-family: 'JetBrains Mono', monospace;
}

/* Cheat-sheet pricing/tiers - panel <details> replié par défaut entre le
   header et les tabs. Note technique pour l'admin (lui-même) qu'on relit
   avant de calibrer crédits / lancer une promo. Cf. bench-test.php. */
.bench-pricing-notes {
  margin: 12px 0 16px;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  padding: 0;
  overflow: hidden;
}
.bench-pricing-notes > summary {
  cursor: pointer;
  padding: 10px 14px;
  font-weight: 600;
  font-size: 13px;
  color: var(--vs-text);
  list-style: none;
  user-select: none;
}
.bench-pricing-notes > summary::-webkit-details-marker { display: none; }
.bench-pricing-notes > summary::before {
  content: "▸";
  display: inline-block;
  margin-right: 8px;
  color: var(--vs-text-muted);
  transition: transform 120ms var(--vs-ease);
}
.bench-pricing-notes[open] > summary::before { transform: rotate(90deg); }
.bench-pricing-notes__hint {
  font-weight: 400;
  color: var(--vs-text-muted);
  font-size: 12px;
}
.bench-pricing-notes__body {
  padding: 4px 18px 16px;
  border-top: 1px solid var(--vs-border);
  font-size: 13px;
  line-height: 1.55;
  color: var(--vs-text);
}
.bench-pricing-notes__body p { margin: 12px 0; }
.bench-pricing-notes__body code {
  background: var(--vs-surface-3);
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 12px;
  font-family: 'JetBrains Mono', monospace;
}
.bench-pricing-notes__body a { color: var(--vs-accent); }
.bench-pricing-notes__table {
  width: 100%;
  border-collapse: collapse;
  margin: 8px 0;
  font-size: 12px;
}
.bench-pricing-notes__table th,
.bench-pricing-notes__table td {
  padding: 6px 8px;
  border: 1px solid var(--vs-border);
  text-align: left;
  vertical-align: top;
}
.bench-pricing-notes__table th {
  background: var(--vs-surface-3);
  font-weight: 600;
}
.bench-pricing-notes__small {
  font-size: 12px;
  color: var(--vs-text-muted);
}
.bench-pricing-notes__meta {
  font-size: 11px;
  color: var(--vs-text-dim);
  border-top: 1px dashed var(--vs-border);
  padding-top: 10px;
  margin-top: 16px;
}

.bench-tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--vs-border);
}
.bench-tab {
  display: flex;
  align-items: center;
  gap: 8px;
  background: transparent;
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: 8px 8px 0 0;
  padding: 8px 14px;
  cursor: pointer;
  font-family: inherit;
  font-size: 13px;
  color: var(--vs-text-dim);
  transition: background 120ms, color 120ms, border-color 120ms;
}
.bench-tab:hover {
  background: var(--vs-surface-2);
  color: var(--vs-text);
}
.bench-tab.is-active {
  background: var(--vs-surface);
  border-color: var(--vs-border);
  border-bottom-color: var(--vs-surface);
  color: var(--vs-text);
  margin-bottom: -1px;
}
.bench-tab__num {
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  border-radius: 50%;
  background: var(--vs-surface-2);
  color: var(--vs-text);
}
.bench-tab.is-active .bench-tab__num {
  background: #d33;
  color: white;
}
.bench-tab__title { font-weight: 600; }
.bench-tab__status {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--vs-text-dim);
  padding: 2px 6px;
  border-radius: 3px;
  background: var(--vs-surface-2);
}
.bench-tab__status[data-state="running"] {
  background: var(--vs-surface-2);
  color: var(--vs-text-dim);
  animation: bench-pulse 1.4s ease-in-out infinite;
}
.bench-tab__status[data-state="done"]  { background: rgba(40, 180, 90, 0.18); color: #2a8c4a; }
.bench-tab__status[data-state="error"] { background: rgba(220, 40, 40, 0.18); color: #c33; }

@keyframes bench-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}

.bench-panels { position: relative; }
.bench-panel {
  background: var(--vs-surface);
  border: 1px solid var(--vs-border);
  border-radius: 0 10px 10px 10px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.bench-panel[hidden] { display: none; }
.bench-panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.bench-panel__head-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.bench-panel__head-info strong {
  font-size: 14px;
  font-weight: 700;
}
.bench-panel__hint {
  font-size: 12px;
  color: var(--vs-text-dim);
}
.bench-panel__head-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.bench-panel__metrics {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  color: var(--vs-text-dim);
  margin-right: 6px;
}
.bench-metric {
  background: var(--vs-surface-2);
  padding: 3px 8px;
  border-radius: 4px;
  font-family: 'JetBrains Mono', monospace;
}
.bench-metric strong { color: var(--vs-text); font-weight: 600; }
.bench-metric--cost  { color: #2a8c4a; font-weight: 600; }
.bench-metric--model { color: var(--vs-text-dim); }
.bench-metric.is-running   { color: var(--vs-text-dim); }
.bench-metric.is-error     { background: rgba(220, 40, 40, 0.12); color: #c33; }
.bench-metric.is-cancelled { background: rgba(120, 120, 120, 0.10); color: var(--vs-text-dim); font-style: italic; }

.bench-panel__body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  min-height: 420px;
}
.bench-panel__preview {
  position: relative;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  min-height: 420px;
  overflow: hidden;
}
.bench-panel__animbar {
  position: absolute;
  bottom: 8px;
  left: 8px;
  right: 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  z-index: 2;
}
.bench-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  font-size: 11px;
  font-weight: 500;
  background: rgba(0,0,0,0.5);
  color: white;
  border: 1px solid rgba(255,255,255,0.16);
  border-radius: 12px;
  cursor: pointer;
  font-family: inherit;
  backdrop-filter: blur(6px) saturate(1.2);
  -webkit-backdrop-filter: blur(6px) saturate(1.2);
  transition: background 160ms var(--vs-ease), border-color 160ms var(--vs-ease),
              box-shadow 160ms var(--vs-ease), transform 160ms var(--vs-ease);
}
.bench-pill:hover {
  background: rgba(0,0,0,0.65);
  border-color: rgba(255,255,255,0.28);
  transform: translateY(-1px);
}
.bench-pill.is-active {
  background: var(--vs-green);
  border-color: transparent;
  font-weight: 600;
  box-shadow: 0 2px 10px rgba(0,0,0,0.4), 0 0 0 1px rgba(22, 163, 74, 0.28);
}
.bench-pill--play {
  width: 24px;
  height: 24px;
  padding: 0;
  justify-content: center;
}
.bench-pill--play svg { width: 11px; height: 11px; }
.bench-pill .dim { opacity: 0.7; }

.bench-panel__code-wrap {
  display: flex;
  flex-direction: column;
  min-height: 420px;
}
.bench-panel__code {
  flex: 1;
  width: 100%;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  padding: 10px 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  line-height: 1.45;
  color: var(--vs-text);
  resize: none;
  overflow: auto;
  white-space: pre;
}

.bench-panel__error {
  background: rgba(220, 40, 40, 0.08);
  border: 1px solid rgba(220, 40, 40, 0.4);
  color: #c33;
  padding: 10px 12px;
  border-radius: 6px;
  font-size: 12px;
  font-family: 'JetBrains Mono', monospace;
}

.bench-logs {
  max-height: 480px;
  overflow: auto;
  background: #0e0f12;
  color: #d6dadf;
  padding: 12px 14px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  line-height: 1.55;
  border-radius: 8px;
  border: 1px solid var(--vs-border);
  white-space: pre-wrap;
  word-break: break-word;
}

/* Step 0 - Retrieval panel : pas de preview 3D, juste chips + reasoning */
.bench-retrieval {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 14px 16px;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  min-height: 220px;
}
.bench-retrieval__empty {
  font-size: 13px;
  color: var(--vs-text-dim);
  text-align: center;
  padding: 40px 12px;
}
.bench-retrieval__title {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--vs-text-dim);
}
.bench-retrieval__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.bench-retrieval__card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  background: var(--vs-surface);
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  min-width: 200px;
  flex: 1 1 240px;
  max-width: 360px;
  text-decoration: none;
  color: var(--vs-text);
  transition: border-color 120ms, transform 120ms;
}
.bench-retrieval__card:hover {
  border-color: #f5a623;
  transform: translateY(-1px);
}
.bench-retrieval__card-name {
  font-weight: 600;
  font-size: 14px;
}
.bench-retrieval__card-desc {
  font-size: 12px;
  color: var(--vs-text-dim);
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.bench-retrieval__card-tags {
  font-size: 11px;
  color: var(--vs-text-dim);
  font-family: 'JetBrains Mono', monospace;
}
.bench-retrieval__reasoning {
  background: rgba(245, 166, 35, 0.08);
  border-left: 3px solid #f5a623;
  padding: 8px 12px;
  font-size: 13px;
  font-style: italic;
  color: var(--vs-text);
  line-height: 1.55;
  border-radius: 4px;
}
.bench-retrieval__none {
  background: rgba(220, 40, 40, 0.06);
  border: 1px dashed rgba(220, 40, 40, 0.3);
  border-radius: 8px;
  padding: 14px;
  font-size: 13px;
  color: var(--vs-text);
}
.bench-retrieval__none strong { color: #c33; display: block; margin-bottom: 4px; }
.bench-retrieval__none .dim   { font-size: 12px; color: var(--vs-text-dim); }

.bench-panel--retrieval { min-height: 280px; }
.bench-panel--retrieval .bench-panel__body { display: none; }

/* ---- Step 1 et Step 2 : 4 candidats en GRID 2×2, chacun son propre canvas ----
 *
 * Refonte 2026-05-02 : avant on avait 1 seul canvas WebGL partagé qui
 * rendait les 4 voxels alignés sur X (BenchMultiStage). UX confuse - on
 * voyait "une scène de 4 voxels" au lieu de "4 candidats indépendants".
 * Maintenant chaque carte (1 par candidat) a son propre canvas WebGL.
 *
 * Layout : .bench-grid (CSS grid) → 4 .bench-candidate--card en 2×2.
 * Chaque carte = header + canvas-host + error + anims + actions + code.
 *
 * Coût en contextes WebGL : 4 par panel actif (vs 1 avant). Avec step1 +
 * step2 ouverts simultanément (CSS-hidden quand inactif), on est à 8 max.
 * Sous la limite Chrome ~16 même avec d'autres onglets voxel ouverts.
 */
.bench-panel--multi .bench-panel__body { display: none; }

.bench-grid {
  display: grid;
  gap: 12px;
}
.bench-grid--2x2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
/* 2x1 : 2 candidats côte à côte (cas slotCount=2 dans MultiPanel).
   Empile en colonne sur mobile. */
.bench-grid--2x1 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.bench-grid--single {
  grid-template-columns: 1fr;
}

/* Carte candidat : look mono clean (1px border, surface neutre). Les états
   ne se manifestent plus par changement de couleur de bordure (l'overlay
   LoadingProgress signale le running ; l'errorEl signale l'erreur), seule
   la sélection ressort visuellement avec un ring accent. */
.bench-candidate {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: 10px;
  transition: border-color 140ms ease, box-shadow 140ms ease, background 140ms ease;
}
.bench-candidate.is-running   { border-color: var(--vs-border); }
.bench-candidate.is-done      { border-color: var(--vs-border); }
.bench-candidate.is-error     { border-color: rgba(220, 40, 40, 0.45); background: rgba(220, 40, 40, 0.03); }
.bench-candidate.is-cancelled { border-color: var(--vs-border); opacity: 0.55; }
.bench-candidate.is-selected {
  border-color: #2a8c4a;
  box-shadow: 0 0 0 2px rgba(42, 140, 74, 0.16);
}

.bench-candidate__canvas-host {
  position: relative;
  background:
    repeating-conic-gradient(#eef1f7 0% 25%, #f8fafc 0% 50%) 50% / 14px 14px;
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  height: 220px;
  overflow: hidden;
}
.bench-candidate__canvas-host canvas { display: block; width: 100%; height: 100%; }
.bench-grid--single .bench-candidate__canvas-host { height: 320px; }

.bench-candidate__header {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 12px;
  /* Cartes 2×2 : le header est INSIDE la card, donc pas besoin de border/bg
     supplémentaires (la card en a déjà). Les classes is-running/is-done…
     restent en fallback pour rétro-compat si du code legacy les met. */
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 0;
  transition: none;
}
.bench-candidate--card .bench-candidate__header {
  /* Override explicite si une page applique encore les anciennes classes
     d'état au header - on neutralise les bordures/box-shadow pour qu'on
     ait UN SEUL outline (celui de la card). */
  border: none !important;
  box-shadow: none !important;
  background: transparent !important;
}
.bench-candidate__title {
  font-weight: 700;
  font-size: 14px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--vs-surface);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
}
.bench-candidate__model {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--vs-text-dim);
  padding: 2px 6px;
  background: var(--vs-surface);
  border-radius: 3px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 180px;
}
.bench-candidate__metrics {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.bench-candidate__anims {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.bench-candidate__anims[hidden] { display: none; }

/* --- Rating thumb up / thumb down (icônes SVG, plus d'emoji) ---
   Bouton compact avec icône pouce + numéro optionnel + indicateur de notes.
   États :
     - inactif : icône en gris, opacité réduite, hover = colore selon polarité
     - is-active "1" → vert (good), affiche num /10
     - is-active "-1" → rouge (bad), affiche num /10
     - .vs-rate-btn__note-mark visible quand des notes texte sont attachées
   Le sub-span .vs-rate-btn__num est rempli/masqué par JS (setRating). */
.bench-candidate__rate {
  display: inline-flex;
  gap: 4px;
  margin-left: 4px;
}
.vs-rate-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: transparent;
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-sm, 6px);
  padding: 4px 8px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  color: var(--vs-text-muted);
  cursor: pointer;
  transition: color 120ms var(--vs-ease), background 120ms var(--vs-ease),
              border-color 120ms var(--vs-ease), transform 80ms var(--vs-ease);
}
.vs-rate-btn .vs-icon { width: 14px; height: 14px; }
.vs-rate-btn:hover:not(:disabled) {
  background: var(--vs-surface-2);
  border-color: var(--vs-border-strong);
  color: var(--vs-text);
}
.vs-rate-btn:active:not(:disabled) { transform: translateY(1px); }
.vs-rate-btn--up:hover:not(:disabled)   { color: rgb(40, 165, 90); }
.vs-rate-btn--down:hover:not(:disabled) { color: rgb(210, 70, 70); }

.vs-rate-btn.is-active.vs-rate-btn--up {
  background: rgba(40, 180, 90, 0.14);
  border-color: rgba(40, 180, 90, 0.55);
  color: rgb(28, 140, 75);
}
.vs-rate-btn.is-active.vs-rate-btn--down {
  background: rgba(220, 60, 60, 0.12);
  border-color: rgba(220, 60, 60, 0.5);
  color: rgb(190, 50, 50);
}
.vs-rate-btn__num {
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  letter-spacing: -0.01em;
}
.vs-rate-btn__num[hidden] { display: none; }
.vs-rate-btn__note-mark {
  display: inline-flex;
  align-items: center;
  margin-left: 1px;
  opacity: 0.85;
}
.vs-rate-btn__note-mark[hidden] { display: none; }
.vs-rate-btn__note-mark .vs-icon { width: 11px; height: 11px; }
.vs-rate-btn:disabled {
  cursor: not-allowed;
  opacity: 0.35;
}
.bench-candidate__error {
  background: rgba(220, 40, 40, 0.08);
  border: 1px solid rgba(220, 40, 40, 0.4);
  color: #c33;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 11px;
  font-family: 'JetBrains Mono', monospace;
  word-break: break-word;
}
.bench-candidate__code {
  font-size: 12px;
}
.bench-candidate__code summary {
  cursor: pointer;
  color: var(--vs-text-dim);
  padding: 4px 0;
  user-select: none;
}
.bench-candidate__code summary:hover { color: var(--vs-text); }
.bench-candidate__code-area {
  width: 100%;
  height: 200px;
  margin-top: 6px;
  background: var(--vs-surface);
  border: 1px solid var(--vs-border);
  border-radius: 4px;
  padding: 8px 10px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  line-height: 1.45;
  resize: vertical;
  overflow: auto;
  white-space: pre;
}
.bench-candidate__actions {
  display: flex;
  gap: 6px;
  margin-top: auto;
  flex-wrap: wrap;
}
.bench-candidate__actions [data-act="choose"] {
  flex: 1;
  min-width: 140px;
}

/* ---- Banner de décision step 2 → step 3 - look mono clean.
   On signale "décision en attente" par une simple barre accent verticale
   à gauche (border-left) plutôt que par un fond orange agressif. */
.bench-decision {
  position: relative;
  margin-top: 14px;
  padding: 14px 16px 14px 18px;
  background: var(--vs-surface);
  border: 1px solid var(--vs-border);
  border-left: 3px solid var(--vs-text);
  border-radius: 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
  justify-content: space-between;
}
.bench-decision__msg {
  font-size: 13px;
  line-height: 1.5;
  flex: 1;
  min-width: 280px;
}
.bench-decision__msg strong { color: var(--vs-text); }
.bench-decision__msg .dim { color: var(--vs-text-dim); font-size: 12px; }
.bench-decision__actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

@media (max-width: 900px) {
  .bench-panel__body { grid-template-columns: 1fr; }
  /* Sur petit écran on passe en 1×4 vertical pour que chaque candidat ait
     toute la largeur (sinon le canvas devient minuscule et illisible). */
  .bench-grid--2x2 { grid-template-columns: 1fr; }
  .bench-grid--2x1 { grid-template-columns: 1fr; }
  .bench-candidate__canvas-host { height: 200px; }
  .bench-grid--single .bench-candidate__canvas-host { height: 240px; }
}

/* ============================================================
 * /admin/sandbox - bac à sable JS pour tester du code voxel à la main.
 * Layout : textarea à gauche (full height), preview à droite. Réutilise
 * .bench-page / .bench-header pour le shell. AdminPreview gère le canvas.
 * ============================================================ */
.sandbox-page { padding-bottom: 24px; }

.sandbox-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 16px;
  margin-top: 16px;
}

.sandbox-editor {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;   /* permet au textarea flex de prendre la hauteur dispo */
}
.sandbox-editor__label {
  font-size: 12px;
  color: var(--vs-text-dim);
  font-weight: 600;
}
.sandbox-editor__area {
  flex: 1;
  min-height: 480px;
  background: var(--vs-surface);
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  padding: 12px 14px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  line-height: 1.5;
  resize: vertical;
  overflow: auto;
  white-space: pre;
  color: var(--vs-text);
}
.sandbox-editor__area:focus {
  outline: 2px solid var(--vs-accent);
  outline-offset: 1px;
}
.sandbox-editor__error {
  background: rgba(220, 40, 40, 0.08);
  border: 1px solid rgba(220, 40, 40, 0.4);
  color: #c33;
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 12px;
  font-family: 'JetBrains Mono', monospace;
  word-break: break-word;
}

.sandbox-preview {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.sandbox-preview__canvas {
  position: relative;
  background: #eef1f7;
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  height: 480px;
  overflow: hidden;
}
.sandbox-preview__canvas canvas { display: block; width: 100%; height: 100%; }
.sandbox-preview__meta {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  padding: 8px 12px;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: 6px;
  font-size: 12px;
}

@media (max-width: 900px) {
  .sandbox-body { grid-template-columns: 1fr; }
  .sandbox-editor__area { min-height: 280px; }
  .sandbox-preview__canvas { height: 360px; }
}

/* ============================================================
 * /admin/bench-ratings - design system aligné (admin-card / admin-data /
 * admin-detail) + composants spécifiques :
 *   .bench-ratings__pill       badge 0-10 coloré (zero/bad/good/reviewed)
 *   .bench-ratings__stat       carte modèle (avg + bar good/bad + counts)
 *   .bench-ratings__detail-*   layout 2-cols preview canvas + code
 *   .bench-ratings__check      checkbox custom "Traité"
 * ============================================================ */

.bench-ratings__section { margin-top: 24px; }
.bench-ratings__section-title {
  margin: 0 0 12px 0;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--vs-text-dim);
  display: flex;
  align-items: center;
  gap: 10px;
}
.bench-ratings__section-sub {
  font-size: 11px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--vs-text-muted);
}
.bench-ratings__section-sub code {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  background: var(--vs-surface-2);
  padding: 1px 6px;
  border-radius: 3px;
}

.bench-ratings__empty {
  background: var(--vs-surface-1);
  border: 1px dashed var(--vs-border);
  border-radius: var(--vs-r-lg);
  padding: 28px;
  text-align: center;
  color: var(--vs-text-dim);
  font-size: 13px;
}
.bench-ratings__empty a { color: var(--vs-accent); text-decoration: none; font-weight: 600; }
.bench-ratings__empty a:hover { text-decoration: underline; }

/* ---------- Pills rating 0..10 ---------- */
.bench-ratings__pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border-radius: var(--vs-r-pill);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  border: 1px solid transparent;
}
.bench-ratings__pill .vs-icon { width: 13px; height: 13px; flex-shrink: 0; }
.bench-ratings__pill strong {
  font-weight: 700;
  font-size: 13px;
}
.bench-ratings__pill small {
  font-size: 10px;
  font-weight: 500;
  opacity: 0.65;
  margin-left: -2px;
}
.bench-ratings__pill--zero {
  background: var(--vs-surface-2);
  color: var(--vs-text-dim);
  border-color: var(--vs-border);
}
.bench-ratings__pill--bad {
  background: rgba(220, 60, 60, 0.10);
  color: #a82020;
  border-color: rgba(220, 60, 60, 0.28);
}
.bench-ratings__pill--good {
  background: rgba(40, 180, 90, 0.12);
  color: #1f6e36;
  border-color: rgba(40, 180, 90, 0.32);
}
.bench-ratings__pill--reviewed,
.bench-ratings__pill--reviewed-mini {
  background: rgba(99, 102, 241, 0.10);
  color: #4338ca;
  border-color: rgba(99, 102, 241, 0.28);
  font-size: 10.5px;
  font-weight: 600;
}
.bench-ratings__pill--reviewed-mini {
  padding: 2px 8px;
  font-size: 10px;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
}

/* ---------- Step pill (mesh / anim / add anim / modify) ---------- */
.bench-ratings__step-pill {
  display: inline-block;
  padding: 1px 8px;
  font-size: 10.5px;
  font-weight: 600;
  font-family: 'JetBrains Mono', monospace;
  background: var(--vs-surface-2);
  color: var(--vs-text-muted);
  border: 1px solid var(--vs-border);
  border-radius: 4px;
  letter-spacing: 0.02em;
}

/* ---------- Stats par modèle ---------- */
.bench-ratings__stats {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
}
.bench-ratings__stat {
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-lg);
  padding: 14px 16px;
  box-shadow: var(--vs-shadow-1);
  transition: transform 120ms var(--vs-ease), box-shadow 120ms var(--vs-ease), border-color 120ms;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.bench-ratings__stat:hover {
  transform: translateY(-1px);
  border-color: var(--vs-border-strong, var(--vs-border));
  box-shadow: 0 6px 18px rgba(15, 23, 42, 0.08);
}
.bench-ratings__stat-head {
  display: flex;
  align-items: center;
  gap: 10px;
  justify-content: space-between;
}
.bench-ratings__stat-model {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11.5px;
  color: var(--vs-text);
  background: transparent;
  padding: 0;
  word-break: break-all;
  font-weight: 500;
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bench-ratings__stat-avg {
  display: inline-flex;
  align-items: baseline;
  gap: 1px;
  font-variant-numeric: tabular-nums;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.01em;
  flex: 0 0 auto;
}
.bench-ratings__stat-avg small {
  font-size: 11px;
  font-weight: 500;
  opacity: 0.55;
  margin-left: 1px;
}
.bench-ratings__stat-avg.is-good { color: #1f6e36; }
.bench-ratings__stat-avg.is-mid  { color: #c08820; }
.bench-ratings__stat-avg.is-bad  { color: #a82020; }
.bench-ratings__stat-bar {
  display: flex;
  height: 6px;
  border-radius: 3px;
  overflow: hidden;
  background: var(--vs-surface-2);
}
.bench-ratings__stat-bar > .good { background: linear-gradient(90deg, #28b45a, #1f9a48); }
.bench-ratings__stat-bar > .bad  { background: linear-gradient(90deg, #d83434, #b81e1e); }
.bench-ratings__stat-meta {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: var(--vs-text-muted);
  font-variant-numeric: tabular-nums;
}
.bench-ratings__stat-meta .is-good,
.bench-ratings__stat-meta .is-bad {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-weight: 600;
}
.bench-ratings__stat-meta .vs-icon { width: 12px; height: 12px; }
.bench-ratings__stat-meta .is-good { color: #1f6e36; }
.bench-ratings__stat-meta .is-bad  { color: #a82020; }

/* ---------- Filter bar : champ recherche stylé avec icône loupe ---------- */
.admin-card__field--search { position: relative; }
.admin-card__field--search input {
  padding-left: 34px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='11' cy='11' r='7'/><line x1='21' y1='21' x2='16.65' y2='16.65'/></svg>");
  background-repeat: no-repeat;
  background-position: 10px center;
  background-size: 14px 14px;
}

/* ---------- Table : on ré-utilise .admin-data + ajustements perso ---------- */
.bench-ratings__table { font-size: 12.5px; }
.bench-ratings__table .bench-ratings__th-rating  { width: 110px; }
.bench-ratings__table .bench-ratings__th-meta    { width: 200px; white-space: nowrap; }
.bench-ratings__table .bench-ratings__th-reviewed { width: 80px; text-align: center; }
.bench-ratings__table tbody tr.is-good { background: rgba(40,180,90,0.05); }
.bench-ratings__table tbody tr.is-bad  { background: rgba(220,60,60,0.04); }
.bench-ratings__table tbody tr.is-good:hover td { background: rgba(40,180,90,0.10); }
.bench-ratings__table tbody tr.is-bad:hover  td { background: rgba(220,60,60,0.07); }
.bench-ratings__table tbody tr.is-reviewed {
  opacity: 0.55;
}
.bench-ratings__table tbody tr.is-reviewed td {
  text-decoration: none;
  color: var(--vs-text-muted);
}
.bench-ratings__table tbody tr.is-reviewed:hover { opacity: 0.85; }
.bench-ratings__table .bench-ratings__model {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10.5px;
  color: var(--vs-text-muted);
  background: var(--vs-surface-2);
  padding: 2px 6px;
  border-radius: 3px;
  white-space: nowrap;
  display: inline-block;
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: middle;
}
.bench-ratings__table .bench-ratings__cell-prompt {
  max-width: 360px;
  word-break: break-word;
  font-size: 12.5px;
  line-height: 1.45;
}
.bench-ratings__notes-badge {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  margin-top: 6px;
  padding: 3px 8px;
  background: rgba(245, 166, 35, 0.10);
  border: 1px solid rgba(245, 166, 35, 0.32);
  color: #8a5b00;
  border-radius: 4px;
  font-size: 11px;
  line-height: 1.4;
  cursor: help;
  max-width: 100%;
}
.bench-ratings__notes-preview {
  font-style: italic;
  word-break: break-word;
}
.bench-ratings__table .bench-ratings__cell-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  white-space: nowrap;
}
.bench-ratings__table .bench-ratings__cell-reviewed { text-align: center; }

/* ---------- Custom checkbox "Traité" (visuel cohérent avec design admin) ---------- */
.bench-ratings__check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  position: relative;
  width: 22px;
  height: 22px;
}
.bench-ratings__check input {
  appearance: none;
  position: absolute;
  inset: 0;
  margin: 0;
  cursor: pointer;
  opacity: 0;
}
.bench-ratings__check-mark {
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--vs-border-strong, var(--vs-border));
  border-radius: 4px;
  background: var(--vs-surface-1);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background 100ms, border-color 100ms;
  position: relative;
}
.bench-ratings__check input:hover + .bench-ratings__check-mark {
  border-color: var(--vs-accent);
}
.bench-ratings__check input:focus-visible + .bench-ratings__check-mark {
  outline: 2px solid var(--vs-accent);
  outline-offset: 2px;
}
.bench-ratings__check input:checked + .bench-ratings__check-mark {
  background: var(--vs-accent);
  border-color: var(--vs-accent);
}
.bench-ratings__check-mark::after {
  content: '';
  position: absolute;
  width: 5px;
  height: 9px;
  border-right: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(45deg) translateY(-1px);
  opacity: 0;
  transition: opacity 80ms;
}
.bench-ratings__check input:checked + .bench-ratings__check-mark::after { opacity: 1; }
.bench-ratings__check input:disabled { cursor: not-allowed; }
.bench-ratings__check input:disabled + .bench-ratings__check-mark {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ---------- Bulk action bar (utilisé sur bench-ratings et gen-choices) ----------
   Reproduit le pattern de community.css mais déclaré ici pour rester
   chargé sur les pages admin qui n'importent pas community.css.
   Visible quand au moins une checkbox bulk est cochée. */
.vs-admin-mod__bulk {
  position: fixed;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  padding: 10px 14px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18), 0 2px 6px rgba(0, 0, 0, 0.08);
}
.vs-admin-mod__bulk[hidden] { display: none; }
.vs-admin-mod__bulk-count {
  font-weight: 600;
  font-size: var(--vs-fs-sm);
  padding-right: 4px;
  border-right: 1px solid var(--vs-border);
  margin-right: 4px;
}
@media (max-width: 720px) {
  .vs-admin-mod__bulk {
    left: 12px;
    right: 12px;
    transform: none;
    flex-wrap: wrap;
    justify-content: center;
  }
}

/* Accents couleur par action sur la barre bulk : aide à scanner visuellement
   les actions positives (review = vert), warning (archive = ambre),
   restauration (unarchive = bleu) et destructive (delete = rouge plein).
   On override juste les classes vs-c-btn--ghost via [data-bulk] pour rester
   compat avec les fonds neutres au repos et n'apporter de couleur qu'au
   hover/focus - sinon la barre devient un sapin de Noël illisible. */
.vs-admin-mod__bulk [data-bulk="review"] {
  color: var(--vs-green);
  border-color: var(--vs-accent-line);
}
.vs-admin-mod__bulk [data-bulk="review"]:hover {
  background: var(--vs-green-low);
  color: var(--vs-accent-hi);
  border-color: var(--vs-green);
}
.vs-admin-mod__bulk [data-bulk="archive"] {
  color: var(--vs-orange);
  border-color: rgba(234, 88, 12, 0.28);
}
.vs-admin-mod__bulk [data-bulk="archive"]:hover {
  background: var(--vs-orange-low);
  color: #c2410c;
  border-color: var(--vs-orange);
}
.vs-admin-mod__bulk [data-bulk="unarchive"] {
  color: var(--vs-blue);
  border-color: rgba(37, 99, 235, 0.28);
}
.vs-admin-mod__bulk [data-bulk="unarchive"]:hover {
  background: var(--vs-blue-low);
  color: #1d4ed8;
  border-color: var(--vs-blue);
}
.vs-admin-mod__bulk [data-bulk="delete"] {
  background: var(--vs-red);
  border-color: var(--vs-red);
  color: #fff;
}
.vs-admin-mod__bulk [data-bulk="delete"]:hover {
  background: #be123c;
  border-color: #be123c;
}
/* Compteur "N sélectionné" : un peu plus marqué que dim, avec une
   pastille colorée pour signaler que la barre est en mode action. */
.vs-admin-mod__bulk .vs-admin-mod__bulk-count {
  color: var(--vs-text);
  position: relative;
  padding-left: 18px;
}
.vs-admin-mod__bulk .vs-admin-mod__bulk-count::before {
  content: '';
  position: absolute;
  left: 4px;
  top: 50%;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--vs-accent);
  transform: translateY(-50%);
  box-shadow: 0 0 0 3px var(--vs-accent-low);
}

/* Cellules / colonnes de la nouvelle barre d'actions par ligne. */
.bench-ratings__th-bulk,
.bench-ratings__cell-bulk { width: 32px; padding-left: 8px; padding-right: 0; }
.bench-ratings__th-actions { width: 1%; white-space: nowrap; }
.bench-ratings__cell-actions {
  display: flex;
  gap: 4px;
  align-items: center;
}
/* Badge "archivé" inline dans la cellule prompt - discret pour ne pas
   gêner la lecture mais visible. */
.bench-ratings__archived-badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--vs-text-muted);
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: 4px;
  padding: 1px 5px;
  margin-left: 6px;
  vertical-align: middle;
}
/* Row archivée : opacité réduite pour la dégrader visuellement sans
   la cacher (le filtre 'Archive: Actifs' la cache vraiment). */
.bench-ratings__table tr.is-archived td { opacity: 0.55; }
.bench-ratings__table tr.is-archived:hover td { opacity: 0.85; }

/* ---------- Detail panel ---------- */
.bench-ratings__detail .admin-detail__head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.bench-ratings__detail-id {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  font-weight: 700;
  color: var(--vs-text);
  background: var(--vs-surface-2);
  padding: 2px 8px;
  border-radius: 4px;
}
.bench-ratings__runid {
  font-size: 10.5px;
  color: var(--vs-text-muted);
  word-break: break-all;
}
.bench-ratings__detail-layout {
  display: grid;
  grid-template-columns: 320px minmax(0, 1fr);
  gap: 18px;
  margin-top: 12px;
}
.bench-ratings__detail-col { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.bench-ratings__detail-col--preview { gap: 8px; }
.bench-ratings__preview {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
  background: #eef1f7;
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  overflow: hidden;
  box-shadow: var(--vs-shadow-1);
}
.bench-ratings__preview canvas { display: block; width: 100%; height: 100%; }
.bench-ratings__preview-error {
  position: absolute; inset: 0;
  padding: 12px;
  font-size: 11px;
  color: #c33;
  background: rgba(220, 40, 40, 0.06);
  font-family: 'JetBrains Mono', monospace;
  overflow: auto;
  border-radius: inherit;
}
.bench-ratings__preview-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  font-size: 11px;
}
.bench-ratings__preview-meta .bench-metric {
  background: var(--vs-surface-2);
  padding: 3px 8px;
  border-radius: 4px;
  color: var(--vs-text-muted);
}
/* Pills d'anims sous le canvas (Mesh + chaque animation). Pattern repris de
   .vs-c-anim-pills (community) mais en classe admin pour éviter une
   dépendance sur community.css que cette page ne charge pas. */
.bench-ratings__anim-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.bench-ratings__anim-pills:empty { display: none; }
.bench-ratings__anim-pill {
  font-size: 11.5px;
  font-weight: 500;
  padding: 4px 10px;
  background: var(--vs-surface-2);
  color: var(--vs-text-muted);
  border: 1px solid var(--vs-border);
  border-radius: 999px;
  cursor: pointer;
  transition: background 160ms var(--vs-ease), color 160ms var(--vs-ease),
              border-color 160ms var(--vs-ease), box-shadow 160ms var(--vs-ease),
              transform 160ms var(--vs-ease);
}
.bench-ratings__anim-pill:hover {
  color: var(--vs-text);
  background: var(--vs-surface-hi);
  border-color: var(--vs-border-strong);
  transform: translateY(-1px);
}
.bench-ratings__anim-pill.is-active {
  background: var(--vs-green);
  color: #fff;
  border-color: transparent;
  font-weight: 600;
  box-shadow: 0 2px 8px rgba(22, 163, 74, 0.28);
  transform: translateY(-1px);
}
.bench-ratings__anim-pill[data-anim="__mesh__"] {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.bench-ratings__anim-pill[data-anim="__mesh__"]::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--vs-accent);
  flex: 0 0 auto;
  transition: background 160ms var(--vs-ease);
}
.bench-ratings__anim-pill[data-anim="__mesh__"].is-active::before {
  background: #fff;
}
.bench-ratings__detail-prompt,
.bench-ratings__detail-code {
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  padding: 10px 12px;
  border-radius: var(--vs-r-md);
  font-size: 11.5px;
  font-family: 'JetBrains Mono', monospace;
  line-height: 1.5;
  max-height: 220px;
  overflow: auto;
  margin: 0 0 12px 0;
  white-space: pre-wrap;
  word-break: break-word;
}
.bench-ratings__detail-code {
  max-height: 420px;
  white-space: pre;
  word-break: normal;
}

/* ---------- Modale "Voir le détail" ----------
   Refonte UX 2026-05-02 : remplace le panneau inline par une modale qui
   réutilise la coquille `admin-dialog--wide` (z-index 100, backdrop blur).
   Le body scroll en interne pour que le code long ne pousse pas le header
   hors écran. */
.bench-ratings__detail-backdrop { z-index: 200; }
.bench-ratings__detail-modal {
  width: min(1040px, 96vw);
  max-height: 92vh;
  padding: 16px 18px;
  gap: 10px;
}
.bench-ratings__detail-modal .admin-dialog__head { gap: 12px; align-items: flex-start; }
.bench-ratings__detail-modal .admin-dialog__head h3 {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  flex: 1 1 auto; min-width: 0;
  font-size: 14px; font-weight: 600;
}
.bench-ratings__detail-modal .admin-detail__head-meta {
  font-size: 12px; font-weight: 400;
  color: var(--vs-text-muted);
}
.bench-ratings__detail-modal-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  padding-right: 4px;
}
.bench-ratings__detail-modal .admin-detail__grid { margin-bottom: 10px; }
.bench-ratings__detail-modal .bench-ratings__detail-prompt { max-height: 180px; }
.bench-ratings__detail-modal .bench-ratings__detail-code { max-height: none; }
.bench-ratings__detail-loading,
.bench-ratings__detail-error {
  padding: 18px 12px;
  font-size: 12px;
  text-align: center;
  color: var(--vs-text-muted);
  font-family: 'JetBrains Mono', monospace;
}
.bench-ratings__detail-error {
  color: var(--vs-danger);
  background: var(--vs-danger-low);
  border: 1px solid rgba(220, 38, 38, 0.35);
  border-radius: var(--vs-r-sm);
  text-align: left;
  white-space: pre-wrap;
}
body.is-modal-open { overflow: hidden; }

/* ---------- Légende sous la table ----------
   Markup : <p.bench-ratings__legend><svg/><span.bench-ratings__legend-text>...</span></p>
   Le wrapper <span> est CRITIQUE : sans lui, les text nodes deviennent des
   flex items anonymes séparés (un par run de texte entre <strong>/<code>) et
   forcent une seule ligne non-wrappable, qui déborde sur mobile. Ici on a
   donc exactement 2 items flex : l'icône (taille fixe) + le span texte qui
   prend tout le reste et wrap normalement. */
.bench-ratings__legend {
  margin-top: 14px;
  padding: 10px 14px;
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  color: var(--vs-text-muted);
  font-size: 12px;
  line-height: 1.55;
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.bench-ratings__legend .vs-icon {
  width: 14px; height: 14px;
  flex: 0 0 auto;
  margin-top: 2px;
  color: var(--vs-accent);
}
.bench-ratings__legend-text {
  flex: 1 1 auto;
  min-width: 0;            /* permet au <code> de wrap au lieu de déborder */
}
.bench-ratings__legend code {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  background: var(--vs-surface-2);
  padding: 1px 6px;
  border-radius: 3px;
  /* Le <code> long sans espaces (ex: {prompt, code, meta:{...}}) doit
     pouvoir casser au milieu sur mobile, sinon il sort du conteneur. */
  overflow-wrap: anywhere;
  word-break: break-word;
}
.bench-ratings__legend strong { color: var(--vs-text); }

@media (max-width: 800px) {
  .bench-ratings__detail-layout { grid-template-columns: 1fr; }
  .bench-ratings__stats { grid-template-columns: 1fr; }
  .bench-ratings__table .bench-ratings__cell-prompt { max-width: none; }
}

/* ============================================================
 * /admin/sitemap - dashboard de génération sitemap.xml
 *
 * 4 blocs : sub-titre page, stats grid (3+1 tuiles), card actions
 * (état fichier + boutons), card aperçu (3 collapsibles).
 * ============================================================ */

.admin-page__sub {
  margin: 4px 0 0;
  color: var(--vs-text-muted);
  font-size: 13px;
  line-height: 1.5;
  max-width: 720px;
}
.admin-page__sub code {
  font-family: var(--vs-font-pixel);
  font-size: 11.5px;
  background: var(--vs-surface-2);
  padding: 1px 6px;
  border-radius: 4px;
}

/* Card primary button + warn pill (extension du système existant). */
.admin-card__btn--primary {
  background: var(--vs-success, #2a8c4a);
}
.admin-card__btn--primary:hover { background: var(--vs-success-hi, #1f6c38); }
.admin-card__btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.admin-pill--warn {
  background: var(--vs-warning-low, #fff4d6);
  color: var(--vs-warning, #b07900);
}

/* Card title + hint + empty state - extension du composant admin-card. */
.admin-card__title {
  margin: 0 0 6px;
  font-size: 15px;
  font-weight: 700;
  color: var(--vs-text);
}
.admin-card__hint {
  margin: 0 0 14px;
  color: var(--vs-text-muted);
  font-size: 12.5px;
  line-height: 1.5;
}
.admin-card__hint code {
  font-family: var(--vs-font-pixel);
  font-size: 11.5px;
  background: var(--vs-surface-2);
  padding: 1px 6px;
  border-radius: 4px;
}
.admin-card__empty {
  margin: 12px 0 0;
  padding: 20px;
  text-align: center;
  color: var(--vs-text-muted);
  font-style: italic;
  background: var(--vs-surface-2);
  border-radius: var(--vs-r-md, 8px);
}

/* Stats grid : 4 tuiles responsive (1 par row sous 600px). La tuile --total
   se distingue par un accent coloré pour bien lire la somme d'un coup. */
.admin-stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 18px;
}
.admin-stat-card {
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-lg);
  padding: 16px 18px;
  box-shadow: var(--vs-shadow-1);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.admin-stat-card__label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--vs-text-muted);
  font-weight: 600;
}
.admin-stat-card__value {
  font-size: 28px;
  font-weight: 700;
  color: var(--vs-text);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.admin-stat-card__hint {
  font-size: 11.5px;
  color: var(--vs-text-dim);
  margin-top: 2px;
}
.admin-stat-card--total {
  background: var(--vs-accent-low);
  border-color: var(--vs-accent-line);
}
.admin-stat-card--total .admin-stat-card__value { color: var(--vs-accent-hi); }

/* ============================================================
 * /admin/logs - barre d'actions bulk delete / purge complète
 * ============================================================ */

.admin-logs-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 12px 14px;
  margin-bottom: 12px;
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md, 8px);
}
.admin-logs-actions__left,
.admin-logs-actions__right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.admin-logs-actions__count {
  font-size: 12.5px;
  color: var(--vs-text-muted);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  padding: 0 4px;
}
.admin-logs-actions__feedback {
  font-size: 12.5px;
  font-weight: 500;
  padding: 6px 10px;
  border-radius: var(--vs-r-sm);
  min-height: 1em;
}
.admin-logs-actions__feedback:empty { display: none; }
.admin-logs-actions__feedback.is-success {
  background: var(--vs-success-low);
  color: var(--vs-success);
}
.admin-logs-actions__feedback.is-error {
  background: var(--vs-danger-low);
  color: var(--vs-danger);
}

/* Variants danger sur le composant admin-card__btn (utilisés ici par les
   boutons "Supprimer la sélection" / "Tout purger"). */
.admin-card__btn--danger {
  background: var(--vs-danger);
  color: #fff;
}
.admin-card__btn--danger:hover:not(:disabled) {
  background: var(--vs-danger-hi, #b91c1c);
}
.admin-card__btn--danger-ghost {
  background: transparent;
  color: var(--vs-danger);
  border: 1px solid var(--vs-danger);
}
.admin-card__btn--danger-ghost:hover:not(:disabled) {
  background: var(--vs-danger-low);
}

/* Cellule checkbox dans les tables logs : compacte, centrée. La checkbox
   master du <thead> et celles du tbody partagent ce style. */
.admin-data__check-cell {
  width: 32px;
  text-align: center;
  padding-left: 8px !important;
  padding-right: 0 !important;
}
.admin-data__check-cell input[type="checkbox"] {
  cursor: pointer;
  width: 14px;
  height: 14px;
  accent-color: var(--vs-accent);
}

@media (max-width: 720px) {
  .admin-logs-actions { flex-direction: column; align-items: stretch; }
  .admin-logs-actions__left,
  .admin-logs-actions__right { justify-content: space-between; }
}

/* Hero CTA : la card principale "Générer le sitemap". 2 colonnes : à gauche
   le titre + desc + boutons d'action, à droite un panneau état rapide
   (statut, dernière géné, taille). Visuel : surface accent very-low avec
   bordure accent-line pour ressortir comme l'action principale de la page. */
.sitemap-hero {
  display: grid;
  grid-template-columns: 1.7fr 1fr;
  gap: 0;
  background: linear-gradient(135deg, var(--vs-accent-low) 0%, var(--vs-surface-1) 70%);
  border: 1px solid var(--vs-accent-line);
  border-radius: var(--vs-r-lg);
  overflow: hidden;
  margin-bottom: 18px;
  box-shadow: var(--vs-shadow-1);
}
.sitemap-hero__main {
  padding: 22px 26px 22px 26px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.sitemap-hero__eyebrow {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--vs-accent-hi);
}
.sitemap-hero__title {
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  color: var(--vs-text);
  letter-spacing: -0.01em;
}
.sitemap-hero__desc {
  margin: 0 0 4px;
  color: var(--vs-text-muted);
  font-size: 13px;
  line-height: 1.55;
  max-width: 560px;
}
.sitemap-hero__desc code {
  font-family: var(--vs-font-pixel);
  font-size: 11.5px;
  background: var(--vs-surface-2);
  padding: 1px 6px;
  border-radius: 4px;
}
.sitemap-hero__actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 4px;
}
.sitemap-hero__btn {
  height: 40px;
  padding: 0 22px;
  border-radius: var(--vs-r-sm);
  font-size: 13.5px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  border: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  line-height: 1;
  white-space: nowrap;
  transition: background 120ms, color 120ms, border-color 120ms, transform 80ms;
}
.sitemap-hero__btn:active:not(:disabled) { transform: translateY(1px); }
.sitemap-hero__btn--primary {
  background: var(--vs-accent);
  color: #fff;
}
.sitemap-hero__btn--primary:hover:not(:disabled) { background: var(--vs-accent-hi); }
.sitemap-hero__btn--ghost {
  background: var(--vs-surface-1);
  color: var(--vs-text-muted);
  border: 1px solid var(--vs-border-strong);
}
.sitemap-hero__btn--ghost:hover { background: var(--vs-surface-2); color: var(--vs-text); }
.sitemap-hero__btn:disabled { opacity: 0.55; cursor: not-allowed; }

.sitemap-hero__feedback {
  margin: 8px 0 0;
  padding: 9px 12px;
  font-size: 12.5px;
  border-radius: var(--vs-r-sm);
  font-weight: 500;
  min-height: 1em;
}
.sitemap-hero__feedback:empty { display: none; }
.sitemap-hero__feedback.is-success {
  background: var(--vs-success-low);
  color: var(--vs-success);
  border: 1px solid var(--vs-success);
}
.sitemap-hero__feedback.is-error {
  background: var(--vs-danger-low);
  color: var(--vs-danger);
  border: 1px solid var(--vs-danger);
}

.sitemap-hero__state {
  padding: 22px 26px;
  background: var(--vs-surface-1);
  border-left: 1px solid var(--vs-border);
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.sitemap-hero__state-row {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.sitemap-hero__state-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--vs-text-muted);
  font-weight: 600;
}
.sitemap-hero__state-value {
  font-size: 14px;
  font-weight: 600;
  color: var(--vs-text);
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
}
.sitemap-hero__state-sub {
  font-size: 11px;
  font-weight: 400;
  color: var(--vs-text-dim);
  font-family: var(--vs-font-pixel);
  font-variant-numeric: tabular-nums;
}
.sitemap-hero__state-empty {
  font-style: italic;
  color: var(--vs-text-dim);
  font-weight: 400;
  font-size: 13px;
}

/* Card "Détails du fichier" : URL publique + chemin disque. Plus discret que
   la hero, juste une référence rapide pour debug/copier le path. */
.sitemap-file {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 18px;
}
.sitemap-file__row {
  display: grid;
  grid-template-columns: 140px 1fr;
  align-items: center;
  gap: 14px;
}
.sitemap-file__label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--vs-text-muted);
  font-weight: 600;
}
.sitemap-file__link {
  color: var(--vs-accent-hi);
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 500;
  word-break: break-all;
}
.sitemap-file__link:hover { text-decoration: underline; }
.sitemap-file__path {
  font-family: var(--vs-font-pixel);
  font-size: 11px;
  color: var(--vs-text-muted);
  background: var(--vs-surface-2);
  padding: 5px 9px;
  border-radius: 5px;
  word-break: break-all;
  display: inline-block;
  justify-self: start;
}

@media (max-width: 720px) {
  .admin-stats-grid { grid-template-columns: repeat(2, 1fr); }
  .sitemap-hero { grid-template-columns: 1fr; }
  .sitemap-hero__state {
    border-left: none;
    border-top: 1px solid var(--vs-border);
  }
  .sitemap-file__row { grid-template-columns: 1fr; gap: 4px; }
}

/* Détails collapsibles (3 sections d'aperçu URLs). */
.admin-sitemap-details {
  margin-top: 12px;
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md, 8px);
  background: var(--vs-surface-1);
  overflow: hidden;
}
.admin-sitemap-details > summary {
  padding: 11px 14px;
  cursor: pointer;
  font-weight: 600;
  font-size: 13.5px;
  color: var(--vs-text);
  background: var(--vs-surface-2);
  user-select: none;
  display: flex;
  align-items: center;
  gap: 10px;
  list-style: none;
}
.admin-sitemap-details > summary::-webkit-details-marker { display: none; }
.admin-sitemap-details > summary::before {
  content: '▸';
  font-size: 11px;
  color: var(--vs-text-muted);
  transition: transform 140ms ease;
  display: inline-block;
}
.admin-sitemap-details[open] > summary::before { transform: rotate(90deg); }
.admin-sitemap-details > summary:hover { background: var(--vs-surface-3, var(--vs-surface-2)); }
.admin-sitemap-details__count {
  margin-left: auto;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 9px;
  border-radius: var(--vs-r-pill);
  background: var(--vs-accent-low);
  color: var(--vs-accent-hi);
  font-variant-numeric: tabular-nums;
}
.admin-sitemap-details > .admin-data-wrap,
.admin-sitemap-details > p {
  margin: 0;
  border-radius: 0;
  border: none;
  border-top: 1px solid var(--vs-border);
  box-shadow: none;
}

/* Variant scroll-Y pour les listes longues (community/sprites peuvent
   compter des centaines d'entrées). Cap à ~50 lignes visibles. */
.admin-data-wrap--scroll {
  max-height: 480px;
  overflow-y: auto;
}

/* Table sitemap : URLs en mono, colonnes priorité/changefreq compactes. */
.admin-sitemap-table td:first-child a {
  font-family: var(--vs-font-pixel);
  font-size: 11.5px;
  color: var(--vs-accent-hi);
  text-decoration: none;
  word-break: break-all;
}
.admin-sitemap-table td:first-child a:hover { text-decoration: underline; }
.admin-sitemap-table th:nth-child(2),
.admin-sitemap-table td:nth-child(2),
.admin-sitemap-table th:nth-child(3),
.admin-sitemap-table td:nth-child(3) {
  white-space: nowrap;
  width: 1px;
  font-variant-numeric: tabular-nums;
}

/* =========================================================
   ADMIN - Logs page (KPIs, badges, sparkline, range chips, sticky table)
   Refonte 2026-05-12 - cf. /admin/logs.
   ========================================================= */

/* ----- KPI cards strip ----- */
.admin-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}
.admin-kpi {
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-lg);
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-height: 72px;
  box-shadow: var(--vs-shadow-1);
}
.admin-kpi__label {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--vs-text-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.admin-kpi__value {
  font-size: 22px;
  font-weight: 700;
  color: var(--vs-text);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.admin-kpi__value--small { font-size: 13px; font-weight: 600; }
.admin-kpi__value--small code {
  background: var(--vs-surface-2);
  padding: 2px 7px;
  border-radius: 4px;
  font-family: var(--vs-font-pixel);
  font-size: 11.5px;
  color: var(--vs-text);
}
.admin-kpi__hint {
  font-size: 11px;
  color: var(--vs-text-muted);
}
.admin-kpi.is-ok    .admin-kpi__value { color: var(--vs-success); }
.admin-kpi.is-warn  .admin-kpi__value { color: var(--vs-warn); }
.admin-kpi.is-bad   .admin-kpi__value { color: var(--vs-danger); }

/* Sparkline KPI - 24h volume + erreurs */
.admin-kpi--spark { min-width: 200px; }
.admin-kpi__spark { display: block; margin: 4px 0 2px; max-width: 100%; }
.admin-kpi__spark-bar { fill: var(--vs-accent); opacity: 0.85; }
.admin-kpi__spark-err { fill: var(--vs-danger); opacity: 0.95; }

/* ----- Period range chips ----- */
.admin-range {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0 0 10px;
  font-size: 12px;
}
.admin-range__label {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--vs-text-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-right: 4px;
}
.admin-range__chip {
  padding: 5px 11px;
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  color: var(--vs-text-muted);
  border-radius: var(--vs-r-pill);
  text-decoration: none;
  font-size: 12px;
  font-weight: 500;
  transition: background 120ms var(--vs-ease), color 120ms var(--vs-ease);
}
.admin-range__chip:hover { background: var(--vs-surface-2); color: var(--vs-text); }
.admin-range__chip.is-active {
  background: var(--vs-accent);
  color: #fff;
  border-color: transparent;
  font-weight: 600;
}
.admin-range__current {
  margin-left: 6px;
  color: var(--vs-text-muted);
}
.admin-range__current b { color: var(--vs-text); font-weight: 600; }

/* ----- Badges (mode, endpoint, action, latence) ----- */
.admin-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: var(--vs-r-pill);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  font-family: var(--vs-font-pixel);
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
  border: 1px solid transparent;
}
.admin-badge--num     { font-family: inherit; font-size: 11px; }
.admin-badge--ok      { background: var(--vs-success-low);  color: var(--vs-success); border-color: rgba(22, 163, 74, 0.20); }
.admin-badge--info    { background: var(--vs-blue-low);     color: var(--vs-blue);    border-color: rgba(37, 99, 235, 0.20); }
.admin-badge--warn    { background: var(--vs-warn-low);     color: var(--vs-warn);    border-color: rgba(234, 88, 12, 0.20); }
.admin-badge--danger  { background: var(--vs-danger-low);   color: var(--vs-danger);  border-color: rgba(220, 38, 38, 0.25); }
.admin-badge--accent  { background: var(--vs-purple-low);   color: var(--vs-purple);  border-color: rgba(124, 58, 237, 0.20); }
.admin-badge--pink    { background: rgba(225, 29, 72, 0.10); color: #be185d; border-color: rgba(225, 29, 72, 0.20); }
.admin-badge--neutral { background: var(--vs-surface-2);    color: var(--vs-text-muted); border-color: var(--vs-border); }

/* Dot indicator (image jointe) */
.admin-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--vs-accent);
}

/* ----- Sticky table header (logs) ----- */
.admin-data-wrap--sticky { max-height: calc(100vh - 220px); overflow: auto; }
.admin-data-wrap--sticky thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  /* Re-déclare le bg : sinon le sticky devient transparent. */
  background: var(--vs-surface-2);
}

/* Cellule date 2 lignes (jour + heure) */
.admin-data__date {
  white-space: nowrap;
  line-height: 1.25;
}
.admin-data__date-day {
  display: block;
  font-variant-numeric: tabular-nums;
  font-size: 11.5px;
  color: var(--vs-text);
}
.admin-data__date-time {
  display: block;
  font-size: 10.5px;
  color: var(--vs-text-muted);
  font-variant-numeric: tabular-nums;
}

/* Prompt cellule : truncate à la largeur du colonne, tooltip natif via title */
.admin-data__prompt {
  max-width: 280px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.admin-data__err {
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.admin-data__center { text-align: center; }

/* Row erreur : teinte rouge très subtile sur fond pour repérer en un coup d'œil */
.admin-data tr.is-err td { background: rgba(220, 38, 38, 0.04); }
.admin-data tr.is-err:hover td { background: rgba(220, 38, 38, 0.08); }

/* En-tête triable */
.admin-data__sort {
  color: inherit;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 2px;
}
.admin-data__sort:hover { color: var(--vs-text); }
.admin-data__sort.is-active { color: var(--vs-accent); }
.admin-data__sort-arrow { font-size: 10px; opacity: 0.8; }

/* Payload activity : pretty-printed JSON dépliable */
.admin-data__payload-toggle {
  display: block;
  max-width: 360px;
}
.admin-data__payload-toggle summary {
  cursor: pointer;
  list-style: none;
}
.admin-data__payload-toggle summary::-webkit-details-marker { display: none; }
.admin-data__payload-toggle[open] summary code { color: var(--vs-text-muted); }
.admin-data__payload-full {
  margin: 6px 0 0;
  padding: 8px 10px;
  background: var(--vs-surface-2);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-sm);
  font-family: 'JetBrains Mono', 'SF Mono', Menlo, ui-monospace, monospace;
  font-size: 11px;
  color: var(--vs-text);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 240px;
  overflow: auto;
}

/* Pagination info "page N / M" */
.admin-pagination__info {
  margin-left: 8px;
  font-size: 12px;
  color: var(--vs-text-muted);
}

/* =========================================================
   ADMIN - Analytics page (chart, dwell buckets, bar lists, grids)
   Posé 2026-05-12 - cf. /admin/analytics.
   ========================================================= */

/* Section title dans .admin-card */
.admin-card__title {
  margin: 0 0 12px;
  font-size: 11px;
  font-weight: 700;
  color: var(--vs-text-dim);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}

/* Grilles 2/3 colonnes pour aligner les cartes "top X" */
.admin-grid-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
  gap: 12px;
  margin-bottom: 14px;
}
.admin-grid-3 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 12px;
  margin-bottom: 14px;
}

/* Variante compacte de admin-data (top tables, padding plus serré) */
.admin-data--compact thead th { padding: 7px 10px; font-size: 10px; }
.admin-data--compact tbody td { padding: 6px 10px; font-size: 12px; }

/* Chart timeseries */
.admin-chart {
  display: block;
  width: 100%;
  height: 220px;
}

/* Dwell buckets : 5 barres horizontales proportionnelles */
.admin-dwell-bars {
  display: flex;
  width: 100%;
  height: 64px;
  border-radius: var(--vs-r-md);
  overflow: hidden;
  gap: 2px;
  background: var(--vs-surface-2);
}
.admin-dwell-bar {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 1px;
  min-width: 40px;
  padding: 4px 6px;
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  transition: opacity 120ms;
}
.admin-dwell-bar:hover { opacity: 0.9; }
.admin-dwell-bar__label { font-size: 10px; opacity: 0.9; font-weight: 500; letter-spacing: 0.04em; }
.admin-dwell-bar__pct   { font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; }
.admin-dwell-bar__n     { font-size: 9px; opacity: 0.75; font-variant-numeric: tabular-nums; }

.admin-dwell-bar--danger { background: var(--vs-red); }
.admin-dwell-bar--warn   { background: var(--vs-orange); }
.admin-dwell-bar--info   { background: var(--vs-blue); }
.admin-dwell-bar--ok     { background: var(--vs-green); }
.admin-dwell-bar--accent { background: var(--vs-purple); }

/* Bar list horizontale - device breakdown / browsers / sections */
.admin-bar-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12px;
}
.admin-bar-list li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) auto;
  align-items: center;
  gap: 10px;
}
.admin-bar-list__k {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--vs-text);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11.5px;
}
.admin-bar-list__bar {
  display: block;
  height: 8px;
  background: var(--vs-surface-2);
  border-radius: var(--vs-r-pill);
  overflow: hidden;
}
.admin-bar-list__bar > span {
  display: block;
  height: 100%;
  background: var(--vs-accent);
  border-radius: inherit;
  transition: width 200ms var(--vs-ease);
}
.admin-bar-list__v {
  font-variant-numeric: tabular-nums;
  color: var(--vs-text-muted);
  font-size: 11.5px;
}

/* =========================================================
   ADMIN - Logs : Charts dashboard (refonte 2026-05-12 v2)
   Rendu par /app/components/_admin_chart.php → classes .admin-graph*
   (le namespace .admin-chart est déjà pris par /admin/analytics).
   ========================================================= */

/* ----- View toggle (charts only / table only / both) ----- */
.admin-view-toggle {
  display: inline-flex;
  gap: 0;
  margin-left: auto;
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  overflow: hidden;
}
.admin-view-toggle__btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 11px;
  color: var(--vs-text-muted);
  text-decoration: none;
  font-size: 12px;
  font-weight: 500;
  border-left: 1px solid var(--vs-border);
  transition: background 120ms var(--vs-ease), color 120ms var(--vs-ease);
}
.admin-view-toggle__btn:first-child { border-left: 0; }
.admin-view-toggle__btn:hover:not(.is-active) { background: var(--vs-surface-2); color: var(--vs-text); }
.admin-view-toggle__btn.is-active { background: var(--vs-accent); color: #fff; }
.admin-view-toggle__btn .vs-icon { width: 14px; height: 14px; flex: 0 0 auto; }

/* ----- Filter chips (filtres actifs supprimables d'un clic) ----- */
.admin-filter-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: -4px 0 12px;
  font-size: 12px;
}
.admin-filter-chips__label {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--vs-text-dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-right: 4px;
}
.admin-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 9px 4px 11px;
  background: var(--vs-accent-low);
  color: var(--vs-accent-hi);
  border: 1px solid var(--vs-accent-line);
  border-radius: var(--vs-r-pill);
  text-decoration: none;
  font-weight: 500;
  transition: background 120ms var(--vs-ease), color 120ms var(--vs-ease), border-color 120ms var(--vs-ease);
  max-width: 100%;
}
.admin-filter-chip:hover { background: var(--vs-accent); color: #fff; border-color: transparent; }
.admin-filter-chip__txt {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 280px;
}
.admin-filter-chip__x { font-size: 14px; line-height: 1; font-weight: 700; opacity: 0.7; }
.admin-filter-chip:hover .admin-filter-chip__x { opacity: 1; }
.admin-filter-chip--reset {
  background: transparent;
  color: var(--vs-text-muted);
  border-color: var(--vs-border);
}
.admin-filter-chip--reset:hover {
  background: var(--vs-surface-2);
  color: var(--vs-text);
  border-color: var(--vs-border);
}

/* ----- Charts grid ----- */
.admin-charts {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 16px;
}
.admin-charts__row {
  display: grid;
  gap: 12px;
}
.admin-charts__row--full { grid-template-columns: 1fr; }
.admin-charts__row--half { grid-template-columns: 1fr 1fr; }
@media (max-width: 880px) {
  .admin-charts__row--half { grid-template-columns: 1fr; }
}

.admin-graph {
  background: var(--vs-surface-1);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-lg);
  padding: 12px 14px 14px;
  box-shadow: var(--vs-shadow-1);
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.admin-graph__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 6px 12px;
}
.admin-graph__title {
  margin: 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--vs-text);
  letter-spacing: 0.02em;
}
.admin-graph__hint {
  margin: 0;
  font-size: 11px;
  color: var(--vs-text-muted);
}
.admin-graph__legend {
  list-style: none;
  margin: 0;
  padding: 0;
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  font-size: 11px;
  color: var(--vs-text-muted);
}
.admin-graph__legend li { display: inline-flex; align-items: center; gap: 5px; }
.admin-graph__legend-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 2px;
  flex: 0 0 auto;
}
.admin-graph__empty {
  text-align: center;
  padding: 24px 0 12px;
  color: var(--vs-text-muted);
  font-size: 12px;
  font-style: italic;
}

/* SVG : columns / columns_stacked */
.admin-graph__svg {
  width: 100%;
  height: auto;
  display: block;
  overflow: visible;
}
.admin-graph__grid {
  stroke: var(--vs-border);
  stroke-width: 1;
  stroke-dasharray: 2 3;
  opacity: 0.7;
}
.admin-graph__y-tick,
.admin-graph__x-tick {
  font: 500 10px 'JetBrains Mono', ui-monospace, monospace;
  fill: var(--vs-text-muted);
  letter-spacing: 0.02em;
}
.admin-graph__bar { transition: opacity 120ms var(--vs-ease); }
.admin-graph__bar:hover { opacity: 0.75; cursor: pointer; }

/* Horizontal bars (top lists) */
.admin-graph__hbars {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  display: grid;
  gap: 5px;
}
.admin-graph__hbar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 2fr auto;
  align-items: center;
  gap: 10px;
  font-size: 12px;
}
.admin-graph__hbar-label {
  color: var(--vs-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.admin-graph__hbar-track {
  position: relative;
  height: 14px;
  background: var(--vs-surface-2);
  border-radius: var(--vs-r-pill);
  overflow: hidden;
}
.admin-graph__hbar-fill {
  position: absolute;
  inset: 0 auto 0 0;
  height: 100%;
  border-radius: var(--vs-r-pill);
  transition: width 220ms var(--vs-ease);
}
.admin-graph__hbar-err {
  position: absolute;
  inset: 0 auto 0 0;
  height: 100%;
  border-radius: var(--vs-r-pill);
  opacity: 0.95;
}
.admin-graph__hbar-value {
  color: var(--vs-text-muted);
  font-variant-numeric: tabular-nums;
  font-size: 11.5px;
  font-weight: 600;
}

/* Donut chart */
.admin-graph__donut-wrap {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 14px;
  padding-top: 2px;
}
.admin-graph__donut { display: block; width: 160px; height: 160px; }
.admin-graph__donut-seg { transition: opacity 120ms var(--vs-ease); }
.admin-graph__donut-seg:hover { opacity: 0.78; cursor: pointer; }
.admin-graph__donut-total {
  font: 700 18px 'JetBrains Mono', ui-monospace, monospace;
  fill: var(--vs-text);
  font-variant-numeric: tabular-nums;
}
.admin-graph__donut-sub {
  font: 500 9px 'JetBrains Mono', ui-monospace, monospace;
  fill: var(--vs-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.admin-graph__donut-legend {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 4px;
  min-width: 0;
}
.admin-graph__donut-legend li {
  display: grid;
  grid-template-columns: 12px minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 8px;
  font-size: 12px;
}
.admin-graph__donut-legend-label {
  color: var(--vs-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.admin-graph__donut-legend-val {
  color: var(--vs-text);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  font-size: 11.5px;
}
.admin-graph__donut-legend-val small {
  color: var(--vs-text-muted);
  font-weight: 500;
  margin-left: 2px;
}
@media (max-width: 520px) {
  .admin-graph__donut-wrap { grid-template-columns: 1fr; justify-items: center; }
}

