/* ============================================================
   @arthur-sim/ui — couche COMPOSANTS
   Ces classes ne référencent QUE des variables sémantiques
   (--ax-*), jamais une primitive (--ax-p-*) et jamais une
   valeur en dur. Violer ça casse le theming en silence.
   ============================================================ */

@layer arfex.components {
  /* Réservé aux lecteurs d'écran. Retiré du flux visuel sans être
     retiré de l'arbre d'accessibilité — `display: none` le cacherait
     aussi aux lecteurs, ce qui est l'inverse du but. */
  .ax-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  /* ─── L'ARÊTE ────────────────────────────────────────────
     La signature de la maison. Une colonne dans la couleur de
     l'outil, sur toute la hauteur, à l'extrême gauche. C'est le
     « quel instrument ai-je en main », lisible du coin de l'œil. */
  .ax-spine {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    width: 3px;
    background: var(--ax-accent);
    z-index: 100;
    pointer-events: none;
  }

  /* ─── MISE EN PAGE ───────────────────────────────────────
     Un écran s'assemble avec ces cinq primitives. Une
     application ne doit avoir aucune raison d'écrire du CSS. */
  .ax-page {
    min-height: 100svh;
    padding: var(--ax-space-8) var(--ax-space-8) var(--ax-space-16);
    padding-inline-start: calc(var(--ax-space-8) + var(--ax-space-1));
    max-width: 1600px;
  }

  .ax-section {
    display: block;
    margin-block-end: var(--ax-space-10);
  }

  .ax-section > header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--ax-space-4);
    margin-block-end: var(--ax-space-4);
    padding-block-end: var(--ax-space-2);
    border-block-end: 1px solid var(--ax-line);
  }

  .ax-stack {
    display: flex;
    flex-direction: column;
    gap: var(--ax-gap, var(--ax-space-4));
  }

  .ax-row {
    display: flex;
    align-items: var(--ax-align, center);
    gap: var(--ax-gap, var(--ax-space-3));
    flex-wrap: wrap;
  }

  .ax-grid {
    display: grid;
    gap: var(--ax-gap, var(--ax-space-4));
    grid-template-columns: repeat(var(--ax-cols, 3), minmax(0, 1fr));
  }

  @media (max-width: 1100px) {
    .ax-grid {
      grid-template-columns: repeat(min(var(--ax-cols, 3), 2), minmax(0, 1fr));
    }
  }

  @media (max-width: 700px) {
    .ax-grid {
      grid-template-columns: minmax(0, 1fr);
    }
    .ax-page {
      padding: var(--ax-space-5) var(--ax-space-4) var(--ax-space-12);
    }
  }

  /* ─── VOIX TYPOGRAPHIQUES ────────────────────────────────
     Deux registres tirés d'une seule famille : l'étiquette
     chuchote, le chiffre parle. */
  .ax-eyebrow {
    font-size: var(--ax-p-text-eyebrow);
    font-weight: var(--ax-p-weight-label);
    letter-spacing: var(--ax-p-track-eyebrow);
    text-transform: uppercase;
    color: var(--ax-label-tertiary);
  }

  .ax-title {
    font-size: var(--ax-p-text-title);
    font-weight: 600;
  }

  .ax-metric {
    font-size: var(--ax-p-text-metric);
    font-weight: var(--ax-p-weight-metric);
    line-height: 1;
    letter-spacing: var(--ax-p-track-metric);
    color: var(--ax-label);
  }

  .ax-metric-unit {
    font-size: 0.45em;
    font-weight: var(--ax-p-weight-label);
    letter-spacing: 0;
    color: var(--ax-label-tertiary);
    margin-inline-start: 0.15em;
  }

  /* ─── CARTE ──────────────────────────────────────────────── */
  .ax-card {
    background: var(--ax-surface);
    border: 1px solid var(--ax-line);
    border-radius: var(--ax-radius-card);
    padding: var(--ax-space-5);
  }

  .ax-card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--ax-space-3);
    margin-block-end: var(--ax-space-4);
  }

  /* ─── INDICATEUR ─────────────────────────────────────────
     Le repère de seuil est le second dispositif de la maison :
     il dit où se situe la référence, donc si le chiffre est bon.
     Il n'apparaît que s'il y a vraiment une référence. */
  .ax-kpi {
    display: flex;
    flex-direction: column;
    gap: var(--ax-space-3);
  }

  .ax-kpi-value {
    display: flex;
    align-items: baseline;
    gap: var(--ax-space-2);
  }

  /* La flèche vient de `data-dir` — un FAIT sur le nombre.
     La couleur vient de `data-intent` — un JUGEMENT du domaine.
     Les confondre revient à écrire « qui monte est bon », ce qui est
     faux d'un coût, d'un taux de rebond ou d'un délai. Sans intention
     déclarée, l'écart reste neutre : on ne devine pas à sa place. */
  .ax-kpi-delta {
    font-size: var(--ax-p-text-caption);
    font-weight: 600;
    color: var(--ax-label-tertiary);
    white-space: nowrap;
  }

  .ax-kpi-delta[data-intent="good"] {
    color: var(--ax-positive);
  }
  .ax-kpi-delta[data-intent="bad"] {
    color: var(--ax-negative);
  }

  /* Pourquoi la donnée manque, posé contre le tiret qui la remplace. */
  .ax-kpi-pending {
    font-size: var(--ax-p-text-caption);
    color: var(--ax-label-tertiary);
  }

  /* Pousse la jauge et ce qui la suit en bas de carte : dans une
     grille d'indicateurs, les cartes s'égalisent et les jauges
     doivent s'aligner entre elles, pas flotter. */
  .ax-kpi > .ax-gauge {
    margin-block-start: auto;
  }

  .ax-gauge {
    position: relative;
    height: 4px;
    border-radius: var(--ax-p-radius-full);
    background: var(--ax-fill);
    overflow: visible;
  }

  .ax-gauge-fill {
    height: 100%;
    border-radius: inherit;
    background: var(--ax-accent);
    width: var(--ax-value, 0%);
  }

  .ax-gauge-threshold {
    position: absolute;
    inset-block: -3px;
    inline-size: 2px;
    inset-inline-start: var(--ax-threshold, 50%);
    background: var(--ax-label);
    border-radius: 1px;
  }

  /* ─── PASTILLE ───────────────────────────────────────────── */
  .ax-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--ax-space-1);
    padding: 2px var(--ax-space-2);
    border-radius: var(--ax-p-radius-full);
    font-size: var(--ax-p-text-eyebrow);
    font-weight: 600;
    letter-spacing: 0.02em;
    background: var(--ax-fill);
    color: var(--ax-label-secondary);
    white-space: nowrap;
  }

  .ax-badge[data-tone="accent"] {
    background: var(--ax-accent-soft);
    color: var(--ax-accent-text);
  }
  .ax-badge[data-tone="positive"] {
    background: color-mix(in oklab, var(--ax-positive) 14%, var(--ax-surface));
    color: var(--ax-positive);
  }
  .ax-badge[data-tone="negative"] {
    background: color-mix(in oklab, var(--ax-negative) 14%, var(--ax-surface));
    color: var(--ax-negative);
  }
  .ax-badge[data-tone="caution"] {
    background: color-mix(in oklab, var(--ax-caution) 16%, var(--ax-surface));
    color: var(--ax-caution);
  }

  /* ─── BOUTON ─────────────────────────────────────────────
     L'action principale est NEUTRE. Neuf outils ont neuf
     accents ; un bouton encre reste lisible partout et fait
     tenir la suite ensemble. L'accent porte l'identité, pas
     l'action. */
  .ax-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--ax-space-2);
    min-height: 32px;
    padding: 0 var(--ax-space-4);
    border: 1px solid transparent;
    border-radius: var(--ax-radius-control);
    background: var(--ax-fill);
    color: var(--ax-label);
    font-size: var(--ax-p-text-body);
    font-weight: 550;
    transition:
      background var(--ax-p-dur-1) var(--ax-p-ease),
      color var(--ax-p-dur-1) var(--ax-p-ease);
  }

  .ax-btn:hover {
    background: var(--ax-fill-strong);
  }

  .ax-btn[data-variant="primary"] {
    background: var(--ax-ink);
    color: var(--ax-on-ink);
  }
  .ax-btn[data-variant="primary"]:hover {
    background: color-mix(in oklab, var(--ax-ink) 84%, var(--ax-canvas));
  }

  .ax-btn[data-variant="quiet"] {
    background: transparent;
    color: var(--ax-label-secondary);
  }
  .ax-btn[data-variant="quiet"]:hover {
    background: var(--ax-fill);
    color: var(--ax-label);
  }

  .ax-btn[data-variant="accent"] {
    background: var(--ax-accent);
    color: var(--ax-on-accent);
  }

  .ax-btn[disabled] {
    opacity: 0.4;
    cursor: not-allowed;
  }

  /* Cible tactile de 44 px sur mobile, sans grossir le dessin. */
  @media (pointer: coarse) {
    .ax-btn {
      min-height: 44px;
    }
  }

  /* ─── CHAMP ──────────────────────────────────────────────── */
  .ax-field {
    display: flex;
    flex-direction: column;
    gap: var(--ax-space-1);
  }

  .ax-field > label {
    font-size: var(--ax-p-text-caption);
    font-weight: 550;
    color: var(--ax-label-secondary);
  }

  .ax-field input,
  .ax-field select,
  .ax-field textarea {
    min-height: 32px;
    padding: 0 var(--ax-space-3);
    background: var(--ax-surface);
    border: 1px solid var(--ax-line-strong);
    border-radius: var(--ax-radius-control);
    color: var(--ax-label);
  }

  .ax-field-hint {
    font-size: var(--ax-p-text-caption);
    color: var(--ax-label-tertiary);
  }

  .ax-field-error {
    font-size: var(--ax-p-text-caption);
    color: var(--ax-negative);
  }

  .ax-field[data-invalid="true"] input,
  .ax-field[data-invalid="true"] select,
  .ax-field[data-invalid="true"] textarea {
    border-color: var(--ax-negative);
  }

  /* ─── ÉTATS ──────────────────────────────────────────────
     Un seul contrat pour chargement / vide / erreur / en
     attente. `pending` existe parce qu'un chiffre absent ne
     s'affiche jamais comme un zéro. */
  .ax-state {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ax-space-2);
    padding-block: var(--ax-space-3);
    color: var(--ax-label-tertiary);
    font-size: var(--ax-p-text-body);
  }

  .ax-state-title {
    color: var(--ax-label-secondary);
    font-weight: 550;
  }

  .ax-skeleton {
    background: linear-gradient(
      90deg,
      var(--ax-fill) 25%,
      var(--ax-fill-strong) 37%,
      var(--ax-fill) 63%
    );
    background-size: 400% 100%;
    animation: ax-shimmer 1.4s ease infinite;
    border-radius: var(--ax-radius-control);
    height: var(--ax-h, 12px);
    width: var(--ax-w, 100%);
  }

  @keyframes ax-shimmer {
    from {
      background-position: 100% 50%;
    }
    to {
      background-position: 0 50%;
    }
  }

  /* ─── DIALOGUE ───────────────────────────────────────────
     <dialog> natif : Baseline Widely, zéro dépendance.
     Deux pièges traités côté composant : le retour du focus au
     déclencheur, et le verrou de défilement sur iOS Safari. */
  .ax-dialog {
    border: 1px solid var(--ax-line);
    border-radius: var(--ax-radius-panel);
    background: var(--ax-surface);
    color: var(--ax-label);
    padding: var(--ax-space-6);
    max-inline-size: min(560px, calc(100vw - var(--ax-space-8)));
    box-shadow: var(--ax-shadow-2);
  }

  .ax-dialog::backdrop {
    background: rgb(0 0 0 / 0.4);
  }

  .ax-dialog-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--ax-space-4);
    margin-block-end: var(--ax-space-4);
  }

  .ax-dialog-foot {
    display: flex;
    justify-content: flex-end;
    gap: var(--ax-space-2);
    margin-block-start: var(--ax-space-6);
  }

  .ax-dialog,
  .ax-dialog::backdrop {
    opacity: 0;
    transition:
      opacity var(--ax-p-dur-2) var(--ax-p-ease),
      overlay var(--ax-p-dur-2) allow-discrete,
      display var(--ax-p-dur-2) allow-discrete;
  }

  .ax-dialog[open],
  .ax-dialog[open]::backdrop {
    opacity: 1;
  }

  @starting-style {
    .ax-dialog[open],
    .ax-dialog[open]::backdrop {
      opacity: 0;
    }
  }

  /* ─── SÉLECTEUR D'OUTILS ─────────────────────────────────
     Ce qui fait sentir la suite. Chaque outil porte son arête ;
     alignées, elles montrent l'écosystème. La couleur n'est
     jamais seule à identifier : le nom est toujours là. */
  .ax-switcher {
    display: grid;
    gap: var(--ax-space-1);
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  }

  .ax-switcher-item {
    display: flex;
    align-items: center;
    gap: var(--ax-space-3);
    padding: var(--ax-space-2) var(--ax-space-3);
    border-radius: var(--ax-radius-control);
    color: var(--ax-label);
    text-decoration: none;
    border: 1px solid transparent;
  }

  .ax-switcher-item:hover {
    background: var(--ax-surface-hover);
    border-color: var(--ax-line);
  }

  .ax-switcher-item[aria-current="page"] {
    background: var(--ax-fill);
  }

  .ax-switcher-mark {
    inline-size: 3px;
    block-size: 20px;
    border-radius: 2px;
    background: var(--ax-tool, var(--ax-label-quiet));
    flex: none;
  }

  .ax-switcher-name {
    font-weight: 550;
  }

  /* La note suit le nom, elle n'est pas repoussée à droite : un
     élément de sélecteur doit se lire d'un bloc. */
  .ax-switcher-note {
    color: var(--ax-label-tertiary);
    font-size: var(--ax-p-text-caption);
  }

  /* ─── TABLEAU ────────────────────────────────────────────── */
  .ax-table th {
    text-align: start;
    font-size: var(--ax-p-text-eyebrow);
    font-weight: 600;
    letter-spacing: var(--ax-p-track-eyebrow);
    text-transform: uppercase;
    color: var(--ax-label-tertiary);
    padding: var(--ax-space-2) var(--ax-space-3);
    border-block-end: 1px solid var(--ax-line);
    white-space: nowrap;
  }

  .ax-table td {
    padding: var(--ax-space-3);
    border-block-end: 1px solid var(--ax-line);
  }

  .ax-table td[data-align="end"],
  .ax-table th[data-align="end"] {
    text-align: end;
  }

  .ax-table tbody tr:hover {
    background: var(--ax-surface-hover);
  }

  .ax-table-wrap {
    overflow-x: auto;
  }
}
