﻿/* ==========================================================================
   Okodo — feuille de style unique
   Toutes les couleurs sont des variables définies sur :root.

   **Le site est en clair.** Le mode sombre ne subsiste que dans l'espace candidat de l'Entretien IA
   (décision de Salim du 17/10/2026), où un entretien d'une heure se passe souvent le soir : il s'applique
   sous [data-theme="dark"], et sous [data-theme="auto"] au seul navigateur qui demande du sombre. Le
   serveur rend « light » partout ailleurs (voir App.razor), donc aucune de ces règles n'y porte.
   ========================================================================== */

/* ========== Palette : mode clair (défaut) ========== */
:root {
  color-scheme: light;

  /* ----- Surfaces -----
     Des gris **neutres et froids**, et non des gris violets. Le site entier baignait dans le lavande :
     fond teinté de violet, panneaux violets, filets violets, et jusqu'au halo derrière le titre. Tout
     se ressemblait, et aucune couleur ne voulait plus rien dire (remarque de Salim du 18/10/2026). */
  --bg: #FFFFFF;
  --bg-panel: #F7F8FB;
  --bg-panel-2: #EDF0F7;
  --border: #DCE2EC;

  --text: #1C2340;
  --text-dim: #5A6480;

  /* ----- La marque -----
     Le violet reste la couleur d'Okodo : le logo, la sphère de l'entretien et les emails en vivent.
     Il cesse en revanche d'être la seule couleur du site, et il ne se dégrade plus : un aplat, et un
     ton plus sombre pour le survol. */
  --accent: #7B3FE4;
  --accent-2: #6330C2;
  --accent-soft: rgba(123, 63, 228, 0.10);
  --accent-ring: rgba(123, 63, 228, 0.22);
  --on-accent: #FFFFFF;
  --illustration-stroke: #1C2340;

  /* ----- Les cinq teintes -----
     Elles ne décorent pas, elles disent quelque chose, et toujours la même chose d'une page à l'autre :
     le bleu pour l'Entretien Expert et le domaine IT, la sarcelle pour la Préparation Expert et pour ce
     qui est acquis, l'ambre pour la Finance de marché et pour ce qui attend, le rose pour ce qu'on met
     en avant, le rouge pour ce qui a échoué. Chacune tient le contraste de 4,5 sur fond blanc. */
  --bleu: #1D6FE0;
  --sarcelle: #0B7A6D;
  --ambre: #B45C00;
  --rose: #C8126B;
  --rouge: #C53030;

  /* Anciens noms, conservés : tout le site les emploie déjà. */
  --good: var(--sarcelle);
  --error: var(--rouge);
  --warn: var(--ambre);

  /* La teinte d'un bloc. Chaque carte peut la redéfinir (.t-bleu, .t-sarcelle…), et tout ce qui la lit
     suit : le liséré du haut, le filet au survol, le lien de pied de carte. */
  --teinte: var(--accent);

  /* ----- Formes et ombres -----
     Le style est **plat** (remarque de Salim du 18/10/2026, qui préfère l'allure de programiz.com) :
     des angles à peine adoucis, des aplats, et des ombres qu'on ne remarque pas. Plus aucune ombre
     colorée, nulle part : une ombre violette sous une carte violette sur un fond violet. */
  --r-carte: 6px;
  --r-champ: 4px;
  --r-mini: 3px;
  --ombre: 0 1px 2px rgba(28, 35, 64, .06);
  --ombre-flottante: 0 6px 20px rgba(28, 35, 64, .14);

  --dot-red: #FF5F57;
  --dot-yellow: #FFBD2E;
  --dot-green: #28C840;

  --font-sans: 'Inter', sans-serif;
  --font-mono: 'JetBrains Mono', monospace;
}

/* ========== Palette : mode sombre ========== */
@media (prefers-color-scheme: dark) {
  :root[data-theme="auto"] {
    color-scheme: dark;

    --bg: #14161F;
    --bg-panel: #1D202C;
    --bg-panel-2: #262A38;
    --border: #363B4C;

    --text: #E9ECF5;
    --text-dim: #9AA2BA;

    --accent: #A970FF;
    --accent-2: #8E57F0;
    --accent-soft: rgba(169, 112, 255, 0.14);
    --accent-ring: rgba(169, 112, 255, 0.24);
    --on-accent: #FFFFFF;
    --illustration-stroke: #FFFFFF;

    /* Les mêmes teintes, éclaircies pour tenir le contraste sur fond sombre. */
    --bleu: #6CA8FF;
    --sarcelle: #4FD1C5;
    --ambre: #F5A34A;
    --rose: #FF7AB6;
    --rouge: #F87171;

    --good: var(--sarcelle);
    --error: var(--rouge);
    --warn: var(--ambre);

    --teinte: var(--accent);

    --ombre: 0 1px 2px rgba(0, 0, 0, .35);
    --ombre-flottante: 0 6px 20px rgba(0, 0, 0, .45);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: #14161F;
  --bg-panel: #1D202C;
  --bg-panel-2: #262A38;
  --border: #363B4C;

  --text: #E9ECF5;
  --text-dim: #9AA2BA;

  --accent: #A970FF;
  --accent-2: #8E57F0;
  --accent-soft: rgba(169, 112, 255, 0.14);
  --accent-ring: rgba(169, 112, 255, 0.24);
  --on-accent: #FFFFFF;
  --illustration-stroke: #FFFFFF;

  /* Les mêmes teintes, éclaircies pour tenir le contraste sur fond sombre. */
  --bleu: #6CA8FF;
  --sarcelle: #4FD1C5;
  --ambre: #F5A34A;
  --rose: #FF7AB6;
  --rouge: #F87171;

  --good: var(--sarcelle);
  --error: var(--rouge);
  --warn: var(--ambre);

  --teinte: var(--accent);

  --ombre: 0 1px 2px rgba(0, 0, 0, .35);
  --ombre-flottante: 0 6px 20px rgba(0, 0, 0, .45);
}

/* ========== Base (reprise de legacy/index.html) ========== */
* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  line-height: 1.6;
}
h1, h2, h3 { font-family: var(--font-sans); font-weight: 700; margin: 0; color: var(--text); }
h1:focus { outline: none; }
.mono { font-family: var(--font-mono); }
.wrap { max-width: 1080px; margin: 0 auto; padding: 0 28px; }
a { color: inherit; }

/* ========== En-tête ========== */
/* Un filet sous l'en-tête, et le bandeau d'accueil sur un aplat : c'est ce qui donne sa tenue
   à une page plate, là où le halo violet s'en chargeait avant. */
header { padding: 28px 0; border-bottom: 1px solid var(--border); }
.header-row { display: flex; justify-content: space-between; align-items: center; gap: 28px; }
.wordmark {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 1.15rem;
  display: flex;
  align-items: center;
  gap: 10px;
  text-transform: uppercase;
  text-decoration: none;
  color: inherit;
}
.wordmark svg { display: block; flex-shrink: 0; }
.accent-letter { color: var(--accent); }

.header-nav { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; flex: 1; justify-content: center; }
.header-nav a { color: var(--text-dim); text-decoration: none; font-size: 0.88rem; font-weight: 500; transition: color .15s; display: inline-flex; align-items: center; gap: 6px; }
.header-nav a:hover, .header-nav a.active { color: var(--accent); }
.nav-badge { display: inline-block; min-width: 18px; padding: 0 6px; border-radius: var(--r-champ); background: var(--warn); color: var(--bg); font-family: var(--font-mono); font-size: 0.72rem; font-weight: 600; line-height: 18px; text-align: center; }

.header-account { display: flex; align-items: center; gap: 18px; }
.header-account > a:not(.btn-primary) { color: var(--text-dim); text-decoration: none; font-size: 0.88rem; font-weight: 500; transition: color .15s; }
.header-account > a:not(.btn-primary):hover { color: var(--accent); }
.nav-button { background: none; border: 0; padding: 0; font: inherit; cursor: pointer; }

/* Menu compte */
.account-menu { position: relative; }
.account-menu > summary { list-style: none; cursor: pointer; }
.account-menu > summary::-webkit-details-marker { display: none; }
.account-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  font-family: var(--font-mono); font-size: 0.8rem; font-weight: 700;
  border: 2px solid transparent;
  transition: box-shadow .15s;
}
.account-menu[open] .account-avatar, .account-trigger:hover .account-avatar { box-shadow: 0 0 0 3px var(--accent-ring); }
.account-panel {
  position: absolute; right: 0; top: calc(100% + 8px);
  min-width: 240px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--r-carte);
  padding: 6px;
  box-shadow: var(--ombre-flottante);
  z-index: 50;
}
.account-email { padding: 10px 12px; font-size: 0.82rem; color: var(--text-dim); border-bottom: 1px solid var(--border); margin-bottom: 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
a.account-item { text-decoration: none; }
.account-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 12px; border-radius: var(--r-champ); font-size: 0.9rem; color: var(--text); margin: 0; }
.account-item:hover { background: var(--accent-soft); }
.account-item .nav-button { width: 100%; text-align: left; color: var(--text); }
.account-item .nav-button:hover { color: var(--accent); }
.account-theme span { color: var(--text-dim); }

/* ----- Sélecteur clair / sombre / auto -----
   Il ne vit que dans l'en-tête de l'espace candidat (ThemeChoix.razor). Trois boutons dans une même
   goutttière, celui qui est retenu en accent : un interrupteur à deux états ne pouvait pas dire
   « comme mon système », qui est justement le réglage par défaut. */
.theme-choix {
  display: inline-flex; align-items: center; gap: 2px; padding: 2px;
  border: 1px solid var(--border); border-radius: var(--r-champ); background: var(--bg-panel);
}
.theme-choix button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0;
  border: 0; border-radius: var(--r-champ); background: none; color: var(--text-dim);
  cursor: pointer; transition: background .15s, color .15s;
}
.theme-choix button:hover { color: var(--accent); background: var(--accent-soft); }
.theme-choix button[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); }
.theme-choix svg { width: 16px; height: 16px; display: block; }


/* ========== Contenu / pied de page ========== */
main { flex: 1; }
.page-content { padding: 24px 28px 64px; }

/* En-tête de la page candidat de l'Entretien IA : la marque et le thème, rien d'autre. */
.entretien-entete { padding: 18px 0; border-bottom: 1px solid var(--border); }
footer { padding: 28px 0 48px; border-top: 1px solid var(--border); color: var(--text-dim); font-size: 0.82rem; }
.footer-row { display: flex; flex-direction: column; gap: 14px; }
.footer-nav { display: flex; flex-wrap: wrap; gap: 8px 22px; }
.footer-nav a { color: var(--text-dim); text-decoration: none; }
.footer-nav a:hover { color: var(--accent); }
.footer-copyright { color: var(--text-dim); }

/* ========== Boutons ========== */
.btn-primary {
  display: inline-block;
  text-align: center;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
  padding: 14px 26px;
  border: 0;
  border-radius: var(--r-champ);
  text-decoration: none;
  font-size: 0.98rem;
  cursor: pointer;
  transition: background .15s;
}
.btn-primary:hover { background: var(--accent-2); }
.btn-primary.btn-compact { margin-top: 0; padding: 10px 18px; font-size: 0.88rem; }
.hero .btn-primary, .cta-final .btn-primary { margin-top: 30px; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }
.hero-actions .btn-primary { margin-top: 0; }

.btn-secondary {
  display: inline-block;
  text-align: center;
  background: transparent;
  font-family: var(--font-sans);
  border: 1px solid var(--border);
  border-radius: var(--r-champ);
  padding: 12px 20px;
  text-decoration: none;
  color: var(--text);
  font-size: 0.92rem;
  font-weight: 600;
  transition: border-color .15s, color .15s;
}
/* Meme boite que .btn-primary.btn-compact : sans cette regle le bouton secondaire gardait la pleine
   hauteur et les deux boutons d'une meme rangee n'etaient pas alignes. */
.btn-secondary.btn-compact { margin-top: 0; padding: 10px 18px; font-size: 0.88rem; }
.btn-secondary:hover { border-color: var(--accent); color: var(--accent); }

/* ----- Un bouton bloqué doit se voir bloqué -----
   Remarque de Salim du 11/10/2026 : tant que les deux cases d'accord ne sont pas cochées, « Commencer
   l'entretien » refuse le clic, mais il gardait son violet et son relief, donc rien ne disait pourquoi le
   clic ne faisait rien. Il est désormais gris, sans ombre, et le curseur l'annonce avant même le clic.
   La règle vaut pour tous les boutons du site, et pour les deux styles. */
button:disabled, .btn-primary:disabled, .btn-secondary:disabled {
  cursor: not-allowed;
  background: var(--bg-panel-2);
  color: var(--text-dim);
  border-color: var(--border);
  box-shadow: none;
  transform: none;
  opacity: .75;
}
.btn-primary:disabled:hover, .btn-secondary:disabled:hover {
  box-shadow: none; transform: none; border-color: var(--border); color: var(--text-dim);
}

/* ========== Les teintes d'un bloc ==========
   Une classe pose la teinte, et tout ce qui la lit suit : le liséré du haut d'une carte, le filet au
   survol, le lien de son pied, la puce d'une liste. Les mêmes trois couleurs désignent partout les mêmes
   trois prestations, d'une page à l'autre : violet pour l'Entretien IA, bleu pour l'Entretien Expert,
   sarcelle pour la Préparation Expert. C'est ce qui rend la couleur utile plutôt que décorative
   (remarque de Salim du 18/10/2026). */
.t-violet   { --teinte: var(--accent); }
.t-bleu     { --teinte: var(--bleu); }
.t-sarcelle { --teinte: var(--sarcelle); }
.t-ambre    { --teinte: var(--ambre); }
.t-rose     { --teinte: var(--rose); }

/* Un fond teinté très pâle, obtenu de la teinte elle-même : une seule déclaration à maintenir, et les
   deux thèmes en vivent. Un navigateur qui ignorerait « color-mix » garde le fond de panneau, qui est
   posé avant : rien ne disparaît. */
.teinte-fond { background: color-mix(in srgb, var(--teinte) 10%, var(--bg)); }

/* ========== Accueil : hero ========== */
.hero-outer { padding: 64px 0 88px; background: var(--bg-panel); border-bottom: 1px solid var(--border); }
.hero { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(300px, 0.7fr); gap: 48px; align-items: center; }
.hero h1 { font-size: clamp(1.6rem, 3vw, 2.1rem); line-height: 1.25; }
.hero p.lede { margin-top: 22px; font-size: 1.05rem; color: var(--text-dim); max-width: 46ch; }

.terminal { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte); overflow: hidden; }
.terminal-bar { display: flex; gap: 6px; padding: 12px 16px; border-bottom: 1px solid var(--border); }
.terminal-bar span { width: 10px; height: 10px; border-radius: 50%; }
.terminal-bar span:nth-child(1) { background: var(--dot-red); }
.terminal-bar span:nth-child(2) { background: var(--dot-yellow); }
.terminal-bar span:nth-child(3) { background: var(--dot-green); }
.terminal-body { padding: 22px 20px; font-size: 0.86rem; line-height: 1.9; white-space: nowrap; overflow: hidden; }
.terminal-body .prompt { color: var(--accent); }
.terminal-body .ok { color: var(--good); }
.terminal-body .dim { color: var(--text-dim); }

/* ========== Accueil : atouts ========== */
section.value-props { padding: 40px 0; border-top: 1px solid var(--border); }
.value-props-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; text-align: center; }
.value-prop { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte); padding: 32px 22px; color: var(--text); position: relative; overflow: hidden; transition: border-color .15s; }
.value-prop::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: var(--teinte); }
.value-prop:hover { border-color: var(--teinte); }
.value-prop svg { display: block; margin: 0 auto 16px; }
.value-prop-title { font-size: 1.2rem; font-weight: 700; line-height: 1.35; }
.value-prop p { margin: 10px 0 0; font-size: 0.88rem; font-weight: 400; color: var(--text-dim); line-height: 1.5; }

/* ========== Accueil : profils ========== */
.profils { padding: 36px 0 56px; border-top: 1px solid var(--border); }
.profils .label { color: var(--text-dim); font-size: 0.85rem; margin-bottom: 16px; }
.tags { display: flex; flex-wrap: wrap; gap: 10px; }
.tag {
  background: color-mix(in srgb, var(--teinte) 10%, var(--bg));
  border: 1px solid color-mix(in srgb, var(--teinte) 28%, var(--bg));
  border-radius: var(--r-champ); padding: 8px 16px; font-size: 0.88rem;
  color: color-mix(in srgb, var(--teinte) 72%, var(--text));
}

/* ========== Accueil : pourquoi / rapport ========== */
section.pourquoi { padding: 56px 0; border-top: 1px solid var(--border); }
.split-block { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 48px; align-items: center; }
.split-block.split-reverse { grid-template-columns: 0.9fr 1.1fr; }
.split-illustration { display: flex; justify-content: center; align-items: center; }
section.pourquoi h2, section.rapport h2 { font-size: 1.6rem; margin-bottom: 16px; max-width: 28ch; }
section.pourquoi p, section.rapport p { color: var(--text-dim); max-width: 52ch; font-size: 1rem; }
section.rapport { padding: 56px 0; border-top: 1px solid var(--border); }
/* Les deux domaines ont leur couleur partout sur le site : le bleu pour IT, l'ambre pour la Finance. */
.venn-it { fill: color-mix(in srgb, var(--bleu) 14%, transparent); stroke: var(--bleu); }
.venn-finance { fill: color-mix(in srgb, var(--ambre) 14%, transparent); stroke: var(--ambre); }
.illustration-text { fill: var(--text); }
.illustration-check { stroke: var(--illustration-stroke); }
.illustration-sheet { fill: var(--bg-panel); stroke: var(--border); }
.illustration-line { stroke: var(--text-dim); }

/* ========== Accueil : les trois prestations ========== */
section.prestations { padding: 56px 0; border-top: 1px solid var(--border); }
.prestations h2 { font-size: 1.6rem; margin-bottom: 28px; }
/* Trois cartes de même niveau et de même hauteur, lien aligné en bas (spec § 6.2). Aucune numérotation. */
.prestations-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; align-items: stretch; }
.prestation-carte { display: flex; flex-direction: column; background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte); padding: 26px 22px; position: relative; overflow: hidden; transition: border-color .15s; }
.prestation-carte::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: var(--teinte); }
.prestation-carte:hover { border-color: var(--teinte); }
.prestation-carte h3 { font-size: 1.2rem; margin: 0 0 12px; }
.prestation-quoi { margin: 0 0 10px; font-size: 0.92rem; color: var(--text); line-height: 1.55; }
.prestation-pour { margin: 0; font-size: 0.9rem; color: var(--text-dim); line-height: 1.5; }
.prestation-delai { margin: 14px 0 0; font-size: 0.85rem; font-weight: 600; color: var(--teinte); }
.prestation-lien { margin-top: auto; padding-top: 18px; color: var(--teinte); font-weight: 600; text-decoration: none; font-size: 0.92rem; }
.prestation-lien:hover { text-decoration: underline; }
.combinables { margin: 28px 0 0; padding: 18px 22px; border-radius: var(--r-carte); background: var(--bg-panel); border: 1px solid var(--border); color: var(--text-dim); font-size: 0.95rem; line-height: 1.6; max-width: none; }
.combinables strong { color: var(--text); }

/* ========== Accueil : profils couverts (générés depuis le référentiel) ========== */
.profils-domaines { display: grid; grid-template-columns: 1fr 1fr; gap: 32px; }
.profils-domaines h3 { font-size: 1rem; margin: 0 0 12px; }
.profils-perimetres { margin: 14px 0 0; color: var(--text-dim); font-size: 0.88rem; }

/* ========== Accueil : méthode et garantie ========== */
section.methode { padding: 56px 0; border-top: 1px solid var(--border); }
.methode h2 { font-size: 1.6rem; margin-bottom: 28px; }
section.garantie { padding: 48px 0; border-top: 1px solid var(--border); }
/* La garantie rassure : elle porte la sarcelle, et non le violet de la marque sous un halo. */
.garantie-bloc { display: flex; align-items: center; justify-content: space-between; gap: 32px; padding: 26px 28px; background: var(--bg-panel); border: 1px solid var(--border); border-left: 3px solid var(--sarcelle); border-radius: var(--r-carte); }
.garantie-bloc h2 { font-size: 1.25rem; margin: 0 0 8px; }
.garantie-bloc p { margin: 0; color: var(--text-dim); font-size: 0.95rem; max-width: 60ch; }
.garantie-bloc .btn-secondary { flex-shrink: 0; }

/* ========== Page Notre offre ========== */
.offre-page { padding: 24px 0 64px; }
.offre-page h1 { font-size: 1.9rem; margin-bottom: 12px; }
.offre-page .lede { color: var(--text-dim); font-size: 1.05rem; margin: 0 0 8px; }
.offre-prestation { margin-top: 36px; padding: 26px 28px; background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte); position: relative; overflow: hidden; }
.offre-prestation::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: var(--teinte); }
.offre-prestation h2 { font-size: 1.35rem; margin: 0 0 12px; }
.offre-prestation > p { margin: 0 0 18px; color: var(--text); font-size: 0.98rem; line-height: 1.6; }
.offre-details { margin: 0; display: grid; gap: 12px; }
.offre-details div { display: grid; grid-template-columns: 180px 1fr; gap: 16px; align-items: baseline; }
.offre-details dt { font-size: 0.78rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--text-dim); }
.offre-details dd { margin: 0; font-size: 0.94rem; color: var(--text); line-height: 1.55; }
.offre-details a { color: var(--accent); }
.offre-combinables { margin-top: 36px; }
.offre-combinables h2 { font-size: 1.3rem; margin: 0 0 10px; }
.offre-combinables p { color: var(--text-dim); font-size: 0.98rem; line-height: 1.6; }
.offre-combinables strong { color: var(--text); }
.offre-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 32px; }
.offre-actions .btn-primary { margin-top: 0; }

/* Tableau des tarifs */
.tarifs { width: 100%; border-collapse: collapse; background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte); overflow: hidden; }
.tarifs th, .tarifs td { text-align: left; padding: 16px 18px; vertical-align: top; border-bottom: 1px solid var(--border); }
.tarifs thead th { font-size: 0.78rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--text-dim); background: var(--bg-panel-2); }
.tarifs tbody tr:last-child td { border-bottom: 0; }
.tarifs th:nth-child(n+2), .tarifs td:nth-child(n+2) { white-space: nowrap; }
/* Chaque ligne porte la couleur de sa prestation, la même que sur l'accueil et sur Notre offre : on
   retrouve l'Entretien IA, l'Entretien Expert et la Préparation Expert sans relire les intitulés. */
.tarifs tbody tr > td:first-child { border-left: 4px solid var(--teinte); }
.tarif-prestation strong { display: block; font-size: 1.02rem; margin-bottom: 4px; }
.tarif-prestation p { margin: 0; color: var(--text-dim); font-size: 0.88rem; max-width: 52ch; }
.tarif-catalogue { color: var(--text-dim); font-size: 1rem; }
.tarif-catalogue s { text-decoration-color: var(--text-dim); }
/* La colonne de l'offre de lancement porte le rose, comme le bloc de l'offre plus bas : c'est la même proposition. */
.tarif-lancement { color: var(--rose); font-size: 1.15rem; font-weight: 600; }
.tarif-lancement-col { color: var(--rose) !important; }
.tarifs-bandeau { margin: 20px 0 0; padding: 14px 18px; border-radius: var(--r-champ); background: var(--bg-panel); border: 1px solid var(--border); border-left: 3px solid var(--bleu); color: var(--text); font-weight: 600; font-size: 0.98rem; }
.tarifs-garantie { margin: 12px 0 0; color: var(--text); font-size: 0.92rem; }
.tarifs-facturation { margin: 12px 0 0; color: var(--text-dim); font-size: 0.9rem; }

/* ----- Grille de dégressivité de l'Entretien IA (docs/offre-commerciale.md § 3 bis) -----
   Trois paliers par rang dans le mois civil. Un paragraphe ne les disait pas (demande de Salim du
   19/10/2026) : trois lignes et deux colonnes se lisent d'un coup d'œil, et le prix reste le chiffre
   qui porte. La remise est un **acquis de volume**, donc sarcelle, la teinte de ce qui est acquis. */
.degressif-titre { margin: 30px 0 6px; font-size: 1.05rem; }
.degressif-lede { margin: 0 0 14px; color: var(--text-dim); font-size: 0.92rem; }
.degressif th[scope="row"] { color: var(--text); font-weight: 600; white-space: nowrap; }
.degressif tbody tr > th:first-child { border-left: 4px solid var(--teinte); }
.degressif strong.mono { font-size: 1.12rem; }
.degressif-remise {
  display: inline-block; margin-left: 8px; padding: 1px 7px; border-radius: var(--r-mini);
  font-size: 0.78rem; font-weight: 600; color: var(--sarcelle);
  background: color-mix(in srgb, var(--sarcelle) 12%, var(--bg));
  border: 1px solid color-mix(in srgb, var(--sarcelle) 30%, var(--bg));
}
.degressif-note { margin: 12px 0 0; color: var(--text-dim); font-size: 0.9rem; }

/* Les motifs d'un contrôle qualité arrivent un par ligne : les laisser se recoller ferait une bouillie. */
.motifs-controle { display: block; white-space: pre-line; font-size: 0.9rem; }

/* Bloc offre de lancement */
/* L'offre de lancement est ce qu'on met en avant : c'est la teinte rose, la seule du site a ce role. */
.lancement { --teinte: var(--rose); margin-top: 28px; background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte); padding: 26px 28px; position: relative; overflow: hidden; }
.lancement::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: var(--teinte); }
.lancement h3 { font-size: 1.15rem; margin: 0 0 8px; }
.lancement-lede { color: var(--text-dim); margin: 0 0 16px; }
.lancement ul { margin: 0 0 22px; padding-left: 0; list-style: none; color: var(--text); font-size: 0.95rem; }
.lancement li { margin-bottom: 8px; padding-left: 22px; position: relative; }
.lancement li::before { content: '✓'; position: absolute; left: 0; color: var(--teinte); font-weight: 700; }
.lancement .btn-primary { margin-top: 0; }

/* ========== Accueil : expertise / contact ========== */
section.expertise { padding: 48px 0; border-top: 1px solid var(--border); }
.expertise p { max-width: 62ch; color: var(--text-dim); font-size: 1rem; }
.expertise strong { color: var(--text); font-weight: 600; }
section.contact { padding: 64px 0; border-top: 1px solid var(--border); }
.contact-wrap { display: grid; grid-template-columns: 1fr 1.4fr; gap: 48px; align-items: start; }
.contact h2 { font-size: 1.5rem; margin-bottom: 14px; }
.contact-lede { color: var(--text-dim); margin: 0; }
.contact-lede a { color: var(--accent); }
.contact-form { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte); padding: 24px; }
.contact-form .btn-primary { margin-top: 6px; }
.contact-form select { appearance: auto; }

/* Pages légales (/cgv, /mentions-legales, /confidentialite, /cookies) */
.conditions { max-width: 72ch; }
.conditions h1 { font-size: 1.6rem; margin-bottom: 8px; }
.conditions h2 { font-size: 1.1rem; margin: 28px 0 10px; }
.conditions p, .conditions li { color: var(--text); font-size: 0.95rem; }
.conditions ul { padding-left: 22px; margin: 0 0 12px; }
.conditions li { margin-bottom: 4px; }
.conditions a { color: var(--accent); }
.conditions-retour { margin-top: 32px; }
.conditions code { font-family: var(--font-mono); font-size: 0.88em; }
.mentions { margin: 0 0 16px; display: grid; gap: 8px; }
.mentions div { display: grid; grid-template-columns: 240px 1fr; gap: 12px; }
.mentions dt { color: var(--text-dim); font-size: 0.88rem; }
.mentions dd { margin: 0; font-size: 0.95rem; }
.cookies th, .cookies td { white-space: normal !important; }
.cookies td { font-size: 0.92rem; }
.value-prop p a { color: var(--accent); }

/* ========== Panneaux ========== */
.panel { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte); padding: 22px 24px; position: relative; overflow: hidden; }
.panel::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; background: var(--teinte); }

/* ========== Formulaires ========== */
label { font-size: 0.85rem; color: var(--text-dim); margin-bottom: 4px; display: block; }
input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
select,
textarea {
  width: 100%;
  background: var(--bg-panel-2);
  border: 1px solid var(--border);
  border-radius: var(--r-champ);
  color: var(--text);
  padding: 11px 12px;
  font-family: var(--font-sans);
  font-size: 0.95rem;
  transition: border-color .15s, box-shadow .15s;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
input::placeholder, textarea::placeholder { color: var(--text-dim); opacity: 0.7; }
.field { margin-bottom: 14px; }
.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

/* Validation Blazor */
.valid.modified:not([type="checkbox"]) { border-color: var(--good); }
.invalid { border-color: var(--error); }
.validation-message, .text-danger { color: var(--error); }
.validation-errors { margin: 0 0 14px; padding-left: 20px; color: var(--error); font-size: 0.9rem; }

/* ========== Pages Identity : connexion, mot de passe ========== */
.page-content h1 { font-size: 1.6rem; margin-bottom: 16px; }
.page-content h2 { font-size: 1.1rem; margin-bottom: 12px; }
.page-content a { color: var(--accent); }
.auth-card { max-width: 440px; margin: 24px auto 0; }
.auth-card h1 { margin-bottom: 6px; }
.auth-card .hint { margin-bottom: 22px; }
.auth-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; font-size: 0.88rem; margin: 4px 0 18px; }
.auth-links { margin: 18px 0 0; font-size: 0.9rem; }
.check-inline { display: inline-flex; align-items: center; gap: 8px; margin: 0; color: var(--text-dim); font-size: 0.88rem; cursor: pointer; }
.check-inline input { accent-color: var(--accent); }
.btn-block { display: block; width: 100%; }

/* Champ mot de passe avec bouton œil */
.password-field { position: relative; }
.password-field input { padding-right: 44px; }
.toggle-password {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 0; border-radius: var(--r-champ);
  color: var(--text-dim); cursor: pointer;
}
.toggle-password:hover { color: var(--accent); background: var(--accent-soft); }
.toggle-password svg { width: 18px; height: 18px; }
.toggle-password .icon-eye-off { display: none; }
.password-field.is-visible .icon-eye { display: none; }
.password-field.is-visible .icon-eye-off { display: block; }

.alert { padding: 12px 16px; border: 1px solid var(--border); border-radius: var(--r-champ); margin-bottom: 16px; background: var(--bg-panel); }
.alert-success { --teinte: var(--sarcelle); }
.alert-danger { --teinte: var(--rouge); }
.alert-warn-box { --teinte: var(--ambre); }
.alert-success, .alert-danger, .alert-warn-box {
  color: var(--teinte);
  background: color-mix(in srgb, var(--teinte) 8%, var(--bg));
  border-color: color-mix(in srgb, var(--teinte) 32%, var(--bg));
}
.alert strong { color: inherit; }

/* Prestation momentanement arretee, annoncee sur les pages publiques (EntretienIaSuspendu.razor). Ambre,
   la teinte de ce qui attend, posee en local : le bloc qui l'accueille porte deja sa propre teinte. */
.offre-suspendue {
  --teinte: var(--ambre);
  margin: 0 0 16px; padding: 12px 16px; border-radius: var(--r-champ);
  font-size: 0.95rem; color: color-mix(in srgb, var(--teinte) 72%, var(--text));
  background: color-mix(in srgb, var(--teinte) 10%, var(--bg));
  border: 1px solid color-mix(in srgb, var(--teinte) 32%, var(--bg));
}
.offre-suspendue strong { color: color-mix(in srgb, var(--teinte) 85%, var(--text)); }
.auth-card-wide { max-width: 560px; }

/* Page Devenir expert : conteneur standard, texte à gauche, arguments en colonnes, formulaire en pleine largeur */
.expert-page { margin-top: 8px; }
.expert-page h1 { font-size: 1.9rem; margin-bottom: 10px; }
.expert-page h2 { font-size: 1.05rem; margin: 28px 0 12px; }
.expert-accroche { font-size: 1.3rem; font-weight: 600; color: var(--accent); margin: 0 0 12px; }
.expert-lede { color: var(--text-dim); max-width: 70ch; margin: 0 0 28px; font-size: 1rem; }
.expert-args { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 32px; }
.expert-arg { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte); padding: 18px 20px; }
.expert-arg strong { display: block; margin-bottom: 6px; }
.expert-arg p { margin: 0; color: var(--text-dim); font-size: 0.9rem; line-height: 1.5; max-width: 70ch; }
.expert-form { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte); padding: 24px; }
.expert-form h2:first-of-type { margin-top: 20px; }
.expert-page .alert-success { max-width: 70ch; }
.expert-page .hint { max-width: 70ch; }
.hint-small { font-size: 0.82rem; margin: -6px 0 14px; }
.text-secondary { color: var(--text-dim); }

/* ========== Espace Admin ========== */
.admin-shell { display: grid; grid-template-columns: 200px 1fr; gap: 36px; align-items: start; padding-bottom: 48px; }
.admin-nav { display: flex; flex-direction: column; gap: 4px; position: sticky; top: 24px; }
.admin-nav a { display: flex; align-items: center; gap: 8px; text-decoration: none; color: var(--text-dim); padding: 8px 12px; border-radius: var(--r-champ); font-size: 0.92rem; font-weight: 600; transition: color .15s, background .15s; }
.admin-nav a:hover, .admin-nav a.active { color: var(--accent); background: var(--accent-soft); }
.admin-main { min-width: 0; }
.admin-main h1 { font-size: 1.5rem; margin-bottom: 20px; }
.admin-main h2 { font-size: 1.05rem; margin: 32px 0 12px; }
.admin-main a { color: var(--accent); }
.admin-main a.btn-primary { color: var(--on-accent); }
.admin-main a.btn-secondary { color: var(--text); }
.admin-main a.btn-secondary:hover { color: var(--accent); }
.breadcrumb { font-size: 0.85rem; color: var(--text-dim); margin: 0 0 6px; }
.breadcrumb a { text-decoration: none; }

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 14px; }
.stat { display: block; background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte); padding: 16px 18px; text-decoration: none; color: inherit !important; transition: border-color .15s; }
/* Cinq teintes qui se succèdent : un tableau de bord tout en violet ne distinguait aucun chiffre d'un
   autre, et l'oeil n'avait aucun repère pour retrouver celui qu'il cherchait. */
.stats > .stat:nth-child(5n+1) { --teinte: var(--accent); }
.stats > .stat:nth-child(5n+2) { --teinte: var(--bleu); }
.stats > .stat:nth-child(5n+3) { --teinte: var(--sarcelle); }
.stats > .stat:nth-child(5n+4) { --teinte: var(--rose); }
.stats > .stat:nth-child(5n+5) { --teinte: var(--ambre); }
.stat { border-top: 2px solid var(--teinte); }
/* Ce qui demande une attention porte l'ambre, quelle que soit sa place dans la rangée. */
.stats > .stat.stat-attention { --teinte: var(--ambre); }
.stat:hover { border-color: var(--teinte); }
.stat-value { font-family: var(--font-mono); font-size: 1.7rem; font-weight: 600; color: var(--teinte); line-height: 1.2; }
.stat-attention .stat-value { color: var(--warn); }
.stat-label { font-size: 0.85rem; color: var(--text-dim); }

.table { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.table th, .table td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.table th { color: var(--text-dim); font-weight: 600; font-size: 0.78rem; text-transform: uppercase; letter-spacing: .04em; }
.table td.mono { font-size: 0.85rem; white-space: nowrap; }

/* Une étiquette d'état se lit d'un coup d'oeil dans un tableau : un aplat pâle de sa teinte, le mot
   dans la teinte pleine. Contournée d'un simple filet, elle se confondait avec les autres cellules. */
.badge { display: inline-block; padding: 2px 10px; border-radius: var(--r-champ); font-size: 0.78rem; font-weight: 600; border: 1px solid var(--border); background: var(--bg-panel-2); color: var(--text-dim); white-space: nowrap; }
.badge-warn { --teinte: var(--ambre); }
.badge-good { --teinte: var(--sarcelle); }
.badge-error { --teinte: var(--rouge); }
.badge-info { --teinte: var(--bleu); }
.badge-warn, .badge-good, .badge-error, .badge-info {
  color: var(--teinte);
  background: color-mix(in srgb, var(--teinte) 12%, var(--bg));
  border-color: color-mix(in srgb, var(--teinte) 30%, var(--bg));
}
.table td.badges { white-space: nowrap; }
.table td.badges { display: table-cell; }
.table td.badges .badge { display: block; width: fit-content; margin: 0; }
.table td.badges .badge + .badge { margin: 4px 0 0; }
.table td.actions { display: table-cell; }
.table td.actions > * { vertical-align: middle; }
.btn-tiny { font-size: 0.78rem; }
.btn-warn { color: var(--warn) !important; border-color: var(--warn); }
.btn-warn:hover { background: var(--warn); color: var(--bg) !important; }
.btn-danger { color: var(--error) !important; border-color: var(--error); }
.btn-danger:hover { background: var(--error); color: var(--on-accent) !important; }
.btn-primary.btn-danger-solid { background: var(--error); }
.btn-primary.btn-danger-solid:hover { background: #A12525; }
.admin-head { display: flex; justify-content: space-between; align-items: center; gap: 16px; margin-bottom: 24px; flex-wrap: wrap; }
.admin-head h1 { margin: 0; }
.admin-head .actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.admin-head .actions form { margin: 0; display: flex; }
h1 .badge { vertical-align: middle; margin-left: 8px; }
.table td.actions form + a, .table td.actions a + form { margin-left: 6px; }
.consequences { margin: 12px 0 20px; padding-left: 20px; }
.consequences li { margin-bottom: 6px; }

.filter-bar { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.filter-bar a { text-decoration: none; color: var(--text-dim) !important; background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-champ); padding: 6px 14px; font-size: 0.85rem; font-weight: 600; transition: color .15s, border-color .15s; }
.filter-bar a:hover { color: var(--accent) !important; border-color: var(--accent); }
.filter-bar a.active { color: var(--on-accent) !important; background: var(--accent); border-color: var(--accent); }

.empty { color: var(--text-dim); font-style: italic; margin: 8px 0; }
.hint { color: var(--text-dim); font-size: 0.9rem; margin: 0 0 12px; }
.form-card { max-width: 560px; }
.form-actions { margin-top: 4px; }
/* Petits boutons : même boîte pour <a> et <button>, centres alignés */
.btn-small, .btn-primary.btn-small { display: inline-flex; align-items: center; justify-content: center; padding: 6px 12px; font-size: 0.8rem; line-height: 1.4; font-family: var(--font-sans); cursor: pointer; }
.table td.actions form { display: inline-flex; vertical-align: middle; }
.table td.actions > a { vertical-align: middle; }
.table form { margin: 0; display: inline-block; }
.table td.actions { white-space: nowrap; }
.table td.actions form + form { margin-left: 6px; }
.table .badge + .badge { margin-left: 6px; }
.alert-warn { color: var(--warn); margin-top: 8px; }
.invitation-link { margin-top: 10px; color: var(--text); font-size: 0.9rem; }
.invitation-link a { display: block; word-break: break-all; font-size: 0.85rem; margin-top: 4px; }

/* ========== Formulaires publics ========== */
.page-content .lede { color: var(--text-dim); max-width: 62ch; margin: 0 0 24px; }
fieldset.checks { border: 1px solid var(--border); border-radius: var(--r-champ); padding: 12px 16px 6px; }
fieldset.checks legend { font-size: 0.85rem; color: var(--text-dim); padding: 0 6px; }
fieldset.checks label { display: flex; align-items: center; gap: 8px; color: var(--text); font-size: 0.95rem; margin-bottom: 8px; }
fieldset.checks input { accent-color: var(--accent); }
/* Spécialités : étiquettes allumées / éteintes (case à cocher masquée) */
fieldset.chips { border: 0; padding: 0; margin: 0 0 14px; }
fieldset.chips legend { font-size: 0.85rem; color: var(--text-dim); margin-bottom: 8px; padding: 0; }
.chip { position: relative; display: inline-flex; align-items: center; margin: 0 8px 8px 0; cursor: pointer; }
.chip input { position: absolute; opacity: 0; width: 0; height: 0; margin: 0; }
.chip span {
  display: inline-block;
  padding: 7px 14px;
  border-radius: var(--r-champ);
  border: 1px solid var(--border);
  background: var(--bg-panel);
  color: var(--text-dim);
  font-size: 0.88rem;
  font-weight: 500;
  transition: color .15s, border-color .15s, background .15s, box-shadow .15s;
}
.chip:hover span { border-color: var(--accent); color: var(--text); }
.chip input:checked + span {
  background: var(--accent);
  border-color: transparent;
  color: var(--on-accent);
}
.chip input:focus-visible + span { box-shadow: 0 0 0 3px var(--accent-ring); }

/* Cases d'accord du candidat (docs/spec-entretien-ia.md § 3.5) : **de vraies cases à cocher**, et non des
   pastilles « .chip » qui s'allument en accent. Une pastille cochée ressemble à un bouton, et on n'accepte
   pas un traitement de données en cliquant sur ce qui ressemble à un bouton : la case doit se voir comme une
   case, et la phrase se lire à côté. Remarque de Salim du 11/10/2026. */
.accords { border: 0; margin: 0 0 4px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.accord {
  display: flex; align-items: flex-start; gap: 12px; cursor: pointer;
  padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--r-champ);
  background: var(--bg-panel); transition: border-color .15s, background .15s;
}
.accord:hover { border-color: var(--accent); background: var(--bg-panel-2); }
.accord input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  position: relative; flex: 0 0 auto; width: 22px; height: 22px; margin: 1px 0 0;
  border: 2px solid var(--text-dim); border-radius: var(--r-mini); background: var(--bg);
  cursor: pointer; transition: border-color .15s, background .15s;
}
.accord:hover input[type="checkbox"] { border-color: var(--accent); }
.accord input[type="checkbox"]:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
.accord input[type="checkbox"]:checked { background: var(--accent); border-color: var(--accent); }
/* La coche est dessinée en bordures, pas écrite : aucune police à charger, et elle suit la couleur du texte
   posé sur l'accent. */
.accord input[type="checkbox"]:checked::after {
  content: ''; position: absolute; left: 5px; top: 1px; width: 6px; height: 11px;
  border: solid var(--on-accent); border-width: 0 2.5px 2.5px 0; transform: rotate(45deg);
}
.accord > span { color: var(--text-dim); line-height: 1.45; }
.accord input[type="checkbox"]:checked ~ span { color: var(--text); font-weight: 500; }

/* Champ piège anti-robots : hors écran, jamais display:none pour ne pas être ignoré par les robots. */
.hp { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }

/* ========== Espaces Business Manager et Expert ========== */
.cell-sub { color: var(--text-dim); font-size: 0.82rem; }
.stat-text { font-size: 0.95rem; font-weight: 600; margin-top: 4px; }
.stat-text a { color: var(--accent); }
.table-kv th { width: 180px; text-transform: none; letter-spacing: 0; font-size: 0.88rem; color: var(--text-dim); }
.profil-fixe { margin-bottom: 8px; }
.auth-card h2, .form-card h2 { font-size: 1.05rem; margin: 28px 0 12px; }
.table-dispos td { padding: 6px 8px 6px 0; border-bottom: 0; vertical-align: middle; }
.table-dispos td:last-child { width: 1%; padding-right: 0; }
.table-dispos .btn-small { padding: 8px 10px; line-height: 1; }
.table-dispos th { padding-left: 0; }
.table-dispos input { padding: 8px 10px; }
.form-wide { max-width: 720px; }
.form-wide h2 { margin-top: 28px; }
.form-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
input[type="file"] { padding: 8px 10px; font-size: 0.88rem; }
input[type="file"]::file-selector-button {
  background: var(--bg-panel); color: var(--text); border: 1px solid var(--border); border-radius: var(--r-champ);
  padding: 6px 12px; margin-right: 10px; font: inherit; font-size: 0.85rem; cursor: pointer;
}
fieldset.checks input[type="radio"] { accent-color: var(--accent); }

/* ========== Erreurs Blazor ========== */
#blazor-error-ui {
  display: none;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 1000;
  background: var(--bg-panel);
  border-top: 2px solid var(--error);
  color: var(--text);
  padding: 0.7rem 1.25rem;
}
#blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 0.75rem; top: 0.5rem; }
.blazor-error-boundary { background: var(--error); color: var(--on-accent); padding: 1rem 1.25rem; border-radius: var(--r-champ); }
.blazor-error-boundary::after { content: "Une erreur est survenue."; }

/* ========== Responsive (reprise de legacy/index.html) ========== */
@media (max-width: 760px) {
  .header-row { flex-wrap: wrap; gap: 16px; }
  .header-nav { order: 3; flex-basis: 100%; justify-content: flex-start; gap: 14px; }
  .hero-outer { padding: 44px 0 56px; }
  .hero { grid-template-columns: 1fr; gap: 36px; }
  .split-block, .split-block.split-reverse { grid-template-columns: 1fr; gap: 28px; }
  .split-illustration { order: 2; }
  .prestations-grid { grid-template-columns: 1fr; gap: 20px; }
  .expert-args { grid-template-columns: 1fr; }
  .profils-domaines { grid-template-columns: 1fr; gap: 24px; }
  .garantie-bloc { flex-direction: column; align-items: flex-start; }
  .offre-details div { grid-template-columns: 1fr; gap: 4px; }
  .mentions div { grid-template-columns: 1fr; gap: 2px; }
  .value-props-grid { grid-template-columns: 1fr; gap: 20px; }
  .contact-wrap { grid-template-columns: 1fr; gap: 24px; }
  .tarifs-apercu { grid-template-columns: 1fr; }
  .row2 { grid-template-columns: 1fr; }
  .admin-shell { grid-template-columns: 1fr; gap: 20px; }
  .admin-nav { flex-direction: row; flex-wrap: wrap; position: static; }
}

/* Tarifs : sous 640 px, chaque ligne devient une carte */
@media (max-width: 640px) {
  .tarifs, .tarifs tbody, .tarifs tr, .tarifs td { display: block; }
  .tarifs thead { display: none; }
  .tarifs tr { border-bottom: 1px solid var(--border); padding: 6px 0; }
  .tarifs tbody tr:last-child { border-bottom: 0; }
  .tarifs td { border-bottom: 0; padding: 8px 18px; white-space: normal; }
  .tarifs td.tarif-prestation { padding-top: 16px; }
  .tarifs td[data-label] { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
  .tarifs td[data-label]::before { content: attr(data-label); font-size: 0.78rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-dim); font-weight: 600; }
  .tarifs td.tarif-lancement::before { color: var(--rose); }
  .tarifs td.tarif-lancement { padding-bottom: 16px; }
  /* La grille de dégressivité passe en cartes comme le reste : le palier fait le titre de la carte,
     et chaque prix porte son intitulé de colonne. Sans cette règle, l'en-tête de ligne restait une
     cellule de tableau au milieu de blocs. */
  .degressif th[scope="row"] { display: block; padding: 14px 18px 2px; border-bottom: 0; }
  .degressif tbody tr > th:first-child { border-left: 4px solid var(--teinte); }
  .degressif td:last-child { padding-bottom: 14px; }
  .lancement { padding: 22px 18px; }
}

/* Bandeau de revue du contenu initial, en tete de /admin/ressources */
.panel-revue { margin-bottom: 28px; }
.panel-revue h2 { font-size: 1.05rem; margin: 0 0 8px; }
.panel-revue .hint { margin-bottom: 12px; }

/* ========== Mobile (docs/spec-interface.md, « Mobile ») ==========
   Largeur de référence 390 px, et 360 px pour les petits écrans, dans les deux thèmes.
   Trois exigences : aucun défilement horizontal de la page, texte courant à 16 px, zones
   cliquables de 44 px. Tout est ici, sans style en ligne et sans JavaScript de page. */
@media (max-width: 760px) {
  /* Gouttière latérale : 16 px au minimum, sur les pages publiques comme dans les espaces. */
  .wrap { padding: 0 18px; }

  /* Texte courant à 16 px : lisible sans zoom. Les intitulés de colonnes et les mentions
     secondaires restent plus petits, sans descendre sous 14 px. */
  body { font-size: 1rem; }
  label, .hint, p, li { font-size: 1rem; }
  .hint-small { font-size: 0.875rem; }
  .table { font-size: 1rem; }
  .table th { font-size: 0.875rem; letter-spacing: .02em; }
  .table td.mono { font-size: 0.9375rem; }
  .badge { font-size: 0.8125rem; }

  /* Champs de formulaire à 16 px : en dessous, iOS zoome tout seul à la saisie. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
  select,
  textarea,
  input[type="file"] { font-size: 1rem; }
  input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
  select { min-height: 44px; }

  /* Zones cliquables : 44 px de haut au doigt, sur les boutons, les liens de navigation et
     les etiquettes a cocher. Un lien au fil du texte garde sa hauteur de ligne. */
  .header-nav a,
  .header-account > a:not(.btn-primary),
  .footer-nav a,
  .admin-nav a,
  .filter-bar a,
  .account-item,
  .account-trigger,
  .wordmark,
  .nav-button,
  summary { min-height: 44px; }
  .header-nav a, .header-account > a:not(.btn-primary), .footer-nav a,
  .nav-button, summary { display: inline-flex; align-items: center; }
  .filter-bar a { padding: 10px 16px; font-size: 0.9375rem; }
  /* 44 px de zone cliquable sur téléphone, comme tout le reste (docs/spec-interface.md, « Mobile »). */
  .theme-choix button { width: 40px; height: 40px; }
  .theme-choix svg { width: 18px; height: 18px; }
  .chip span { min-height: 44px; }
  .btn-primary, .btn-secondary, .btn-primary.btn-compact, .btn-secondary.btn-compact,
  .btn-run, .btn-run.btn-compact { min-height: 44px; }
  .btn-small, .btn-primary.btn-small, .btn-secondary.btn-small { min-height: 44px; padding: 8px 14px; font-size: 0.875rem; }
  .toggle-password { width: 44px; height: 44px; }

  /* Mentions secondaires : on ne descend pas sous 14 px. */
  footer { font-size: 0.9375rem; }
  .profils .label, .prestation-delai, .breadcrumb, .stat-label,
  .cell-sub, .hint-inline, .account-email, .invitation-link a { font-size: 0.9375rem; }

  /* Un tableau trop large défile seul dans son cadre, jamais la page entière. */
  .table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  /* Les cellules ne se replient pas : sinon le tableau se tasse a la largeur de l'ecran et
     les lignes deviennent enormes. Il garde sa largeur naturelle et defile dans son cadre. */
  .table th, .table td { white-space: nowrap; }
  .table td.badges .badge { display: inline-block; }
  .table td.badges .badge + .badge { margin: 0 0 0 4px; }

  /* Formulaires sur une colonne, champs à pleine largeur. */
  .form-actions { flex-wrap: wrap; }
  .form-actions > * { flex: 1 1 auto; }

  /* Menu latéral des espaces : il reste visible en haut de page, en une rangée de liens
     qui passe à la ligne, et ne recouvre jamais le contenu (arbitrage du 24/09/2026). */
  .admin-nav { gap: 6px 8px; }
  .admin-nav a { padding: 10px 14px; background: var(--bg-panel); border: 1px solid var(--border); }
  .admin-nav a:hover, .admin-nav a.active { border-color: var(--accent); }
}

/* Très petits écrans : 360 px de large. */
@media (max-width: 400px) {
  .wrap { padding: 0 16px; }
  header { padding: 18px 0; }
  .header-row { gap: 12px; }
  .admin-main h1 { font-size: 1.35rem; }
}

/* ========== Documents imprimables (compte rendu en PDF) ========== */
.impression-page { max-width: 860px; margin: 0 auto; padding: 24px 28px 48px; }
.impression-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 24px; }
.impression-entete { display: flex; align-items: center; gap: 24px; padding-bottom: 16px; margin-bottom: 20px; border-bottom: 1px solid var(--border); }
.impression-entete .wordmark { text-decoration: none; }
.impression-titre h1 { font-size: 1.4rem; margin: 0 0 4px; }
.impression-titre p { margin: 0; color: var(--text-dim); }
.impression-pied { margin-top: 32px; padding-top: 12px; border-top: 1px solid var(--border); color: var(--text-dim); font-size: 0.8rem; }
@media print {
  :root, :root[data-theme="dark"], :root[data-theme="auto"] { --bg: #FFFFFF; --bg-panel: #FFFFFF; --bg-panel-2: #F5F5F5; --text: #000000; --text-dim: #444444; --border: #BBBBBB; }
  body { background: #FFFFFF; color: #000000; }
  .impression-page { max-width: none; padding: 0; }
  .impression-actions, #blazor-error-ui { display: none !important; }
  .impression-entete .accent-letter { color: #000000; }
  a { color: inherit; text-decoration: none; }
  table { page-break-inside: auto; }
  tr { page-break-inside: avoid; }
  h2, h3 { page-break-after: avoid; }
}

/* Rapport d'entretien : séparation entre l'en-tête et les compétences */
.rapport-section { font-size: 1.05rem; margin: 28px 0 6px; }
.rapport-section + .hint { margin-bottom: 12px; }

/* Verdict : les deux choix gardent leur couleur une fois cochés */
.chip.chip-valide input:checked + span { background: var(--good); border-color: var(--good); color: var(--on-accent); box-shadow: none; }
.chip.chip-non-valide input:checked + span { background: var(--error); border-color: var(--error); color: var(--on-accent); box-shadow: none; }
.chip.chip-valide:hover span { border-color: var(--good); }
.chip.chip-non-valide:hover span { border-color: var(--error); }

/* Note sur 10 du compte rendu */
.note-field { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.note-field input[type="number"] { width: 6rem; font-family: var(--font-mono); font-size: 1.1rem; }
.note-field label { margin: 0; }

/* ========== Enregistrements d'entretien ========== */
.enregistrement-video { display: block; width: 100%; max-width: 900px; max-height: 70vh; background: #000; border-radius: var(--r-carte); margin: 12px 0 8px; }
.synthese-bloc { margin: 0 0 24px; }
.synthese-auto { white-space: pre-wrap; background: var(--bg-panel); border: 1px solid var(--accent); border-radius: var(--r-carte); padding: 18px 20px; font-size: 0.92rem; line-height: 1.6; max-height: 50vh; overflow: auto; }
.synthese-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.enregistrement-transcription { white-space: pre-wrap; background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte); padding: 18px 20px; font-size: 0.92rem; line-height: 1.6; max-height: 60vh; overflow: auto; }

/* ========== Page d'entretien (visioconférence) ========== */
.visio-page { position: fixed; inset: 0; background: var(--bg); color: var(--text); overflow: hidden; }
.visio-frame { position: absolute; inset: 0; }
.visio-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.visio-attente {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  margin: 0; padding: 0 16px; text-align: center; color: var(--text-dim); font-size: 0.95rem;
}
.visio-frame.is-joined .visio-attente { display: none; }
.visio-information { position: absolute; top: 12px; left: 50%; transform: translateX(-50%); z-index: 2; max-width: 720px; margin: 0; padding: 8px 14px; border-radius: var(--r-champ); background: var(--bg-panel); border: 1px solid var(--border); color: var(--text-dim); font-size: 0.8rem; text-align: center; }
.visio-frame.is-joined .visio-information { display: none; }
.visio-frame.is-error .visio-attente { color: var(--error); z-index: 1; background: var(--bg); padding: 12px 16px; border-radius: var(--r-champ); }
.visio-message {
  max-width: 520px; margin: 12vh auto 0; padding: 0 16px; text-align: center;
}

/* ----- Page d'écoute des voix, /admin/voix (docs/spec-entretien-ia.md § 17.10 A) ----- */
.voix-retenue { padding: 10px 14px; border-left: 3px solid var(--accent); background: var(--bg-panel); }
.voix-phrases { display: flex; flex-direction: column; gap: 8px; }
.voix-phrases .accord span { font-size: 0.92rem; }
.voix-remarque { display: block; margin-top: 2px; font-size: 0.8rem; color: var(--text-dim); }
.voix-table td { vertical-align: top; }

/* ----- Antichambre et panneau latéral de la conversation -----
   docs/visio-enregistrement-synthese.md, « Messagerie de l'entretien ». L'antichambre défile, contrairement
   à la salle : on peut y lire une conversation longue. La salle, elle, reste fixe, et la conversation s'y
   ouvre en panneau par-dessus la vidéo. */
.visio-antichambre {
  max-width: 640px; margin: 0 auto; padding: 24px 16px 48px; text-align: center;
  max-height: 100vh; overflow-y: auto;
}
.visio-antichambre h1 { font-size: 1.4rem; margin: 20px 0 8px; }
.visio-antichambre .messagerie { margin-top: 28px; text-align: left; }

.visio-salle { position: absolute; inset: 0; }
.visio-cote { position: absolute; top: 12px; right: 12px; z-index: 3; display: flex; flex-direction: column;
  align-items: flex-end; gap: 8px; max-width: min(380px, 92vw); }
.messagerie-bascule { position: relative; }
.messagerie-pastille {
  display: inline-block; min-width: 20px; margin-left: 8px; padding: 1px 6px; border-radius: var(--r-champ);
  background: var(--accent); color: var(--on-accent); font-size: 0.72rem; font-weight: 700; text-align: center;
}

/* Libellé réservé aux lecteurs d'écran : la zone de saisie a besoin d'une étiquette, l'œil s'en passe. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ----- La conversation elle-même ----- */
.messagerie { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.messagerie-titre { margin: 0; font-size: 0.95rem; color: var(--accent); }
.messagerie-fil {
  margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px;
  max-height: 46vh; overflow-y: auto;
}
.message {
  padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--r-champ); background: var(--bg-panel);
}
/* Le message que l'on vient d'écrire se distingue sans crier : un liseré, pas une couleur de fond. */
.message-moi { border-left: 3px solid var(--accent); }
.message-masque { opacity: .6; font-style: italic; }
.message-entete { margin: 0 0 2px; display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; }
.message-nom { font-weight: 600; font-size: 0.88rem; }
.message-role { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--accent); }
.message-heure { margin-left: auto; font-size: 0.75rem; color: var(--text-dim); }
.message-texte { margin: 0; font-size: 0.92rem; line-height: 1.5; white-space: pre-wrap; word-break: break-word; }
.message-actions { margin-top: 6px; }
.messagerie-rapides { display: flex; flex-wrap: wrap; gap: 8px; }
.messagerie-rappel { margin: 0; }
.messagerie-saisie { display: flex; gap: 10px; align-items: flex-end; }
.messagerie-saisie textarea { flex: 1 1 auto; min-width: 0; resize: vertical; }

/* Le panneau de la salle se pose par-dessus la vidéo, et se replie sur son seul bouton. */
.messagerie-panneau {
  width: min(380px, 92vw); padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--r-carte);
  background: var(--bg-panel); box-shadow: var(--ombre-flottante);
}
.messagerie-panneau .messagerie-fil { max-height: 40vh; }
.messagerie-repliee { display: none; }
.visio-message h1 { font-size: 1.4rem; margin: 24px 0 12px; }
.visio-message p { margin: 0 0 12px; }
.visio-message a { color: var(--accent); }
.visio-message a.btn-primary { color: var(--on-accent); }

/* ========== Référentiel de compétences ========== */
.badge-muted { color: var(--text-dim); }
.verdict-valide { color: var(--good); }
.verdict-non-valide { color: var(--error); }
.hint-inline { font-size: 0.82rem; font-weight: 400; color: var(--text-dim); }
.chip span small { font-weight: 400; opacity: 0.8; }
[data-profil-entretien] h3 { margin: 24px 0 8px; font-size: 1rem; }
.competences-groupe { margin-bottom: 12px; padding: 10px 14px; border: 1px solid var(--border); border-radius: var(--r-champ); background: var(--bg-panel); }
.competences-groupe legend { font-weight: 600; padding: 0 6px; }
.table-competences { margin: 0; }
.table-competences td { padding: 4px 8px; border-bottom: 1px solid var(--border); }
.table-competences tr:last-child td { border-bottom: 0; }
.table-competences label { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.table-competences input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--accent); }
.competence-niveau { width: 190px; }
.competence-niveau select { width: 100%; padding: 4px 8px; font-size: 0.85rem; }
.table-competences-vue td:first-child .hint-inline { display: block; }
/* « 3 · Maîtrise » tient sur une ligne : les colonnes de niveau ne se coupent jamais, le commentaire absorbe la largeur. */
.table-competences-vue td:nth-child(2), .table-competences-vue td:nth-child(3), .table-competences-vue th:nth-child(2), .table-competences-vue th:nth-child(3), .table-cr td:nth-child(2) { white-space: nowrap; }
.table-competences-vue td:nth-child(4) { width: 40%; }
.referentiel-groupe { margin-bottom: 8px; }
.referentiel-groupe summary { cursor: pointer; padding: 8px 0; font-weight: 600; }
select[data-filiere] { width: 100%; }
[hidden] { display: none !important; }

/* ========== Experts : argumentaire, facturation ========== */
.liste-simple { margin: 0 0 16px 20px; padding: 0; }
.liste-simple li { margin-bottom: 8px; }
.argumentaire { margin-bottom: 24px; }
.field.checks label { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 10px; font-size: 0.92rem; cursor: pointer; }
.field.checks input[type="checkbox"] { margin-top: 3px; accent-color: var(--accent); }

/* ========== Compte rendu et rémunération ========== */
.table-cr input[type="text"] { width: 100%; padding: 6px 8px; font-size: 0.88rem; }
.table-cr td { vertical-align: middle; }
.compte-rendu-texte { white-space: pre-wrap; background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-champ); padding: 14px 16px; margin-bottom: 16px; line-height: 1.55; }
.niveau-ecart { color: var(--warn); font-weight: 600; }
.row-total td { background: var(--bg-panel-2); }

/* ========== Thèmes (lot 9) ========== */
.themes-filiere, .themes-domaine { margin-bottom: 8px; }
.chip-theme span { display: inline-flex; flex-direction: column; align-items: flex-start; line-height: 1.25; }
/* Étiquette « en attente de validation » sur un élément de profil soumis à Okodo. */
/* Ressources d'entretien : une carte par ressource, lisible à l'écran comme à l'impression. */
.ressource-groupe { margin-bottom: 22px; }
.ressource-groupe h3 { margin: 0 0 10px; font-size: 1rem; }
.ressource { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte); padding: 14px 18px; margin-bottom: 12px; }
.ressource-titre { margin: 0 0 8px; font-size: 0.98rem; }
.ressource-enonce { font-size: 0.94rem; line-height: 1.6; }

/* ----- De la couleur sur les écrans de l'Entretien IA (remarque de Salim du 11/10/2026) -----
   Les écrans de question et d'exercice étaient tout en gris sur gris : corrects, mais austères, et un
   candidat y passe une heure. On colore donc ce qui porte du sens, et rien de décoratif : les étiquettes de
   l'en-tête, la barre d'avancement, le code en ligne dans un énoncé, et le liseré du bloc d'énoncé. */
/* Le code **en ligne** se pose sur l'accent, le code **en bloc** garde l'aspect d'un terminal. Sans le
   « :not(pre code) », un bloc d'exemple héritait du style en ligne et s'affichait en pastilles violettes. */
.ressource-enonce code:not(pre code) {
  padding: 1px 5px; border-radius: var(--r-mini);
  background: var(--accent-soft); color: var(--accent);
  font-family: var(--font-mono); font-size: 0.9em;
}
.ressource-enonce pre {
  margin: 8px 0 12px; padding: 10px 12px; border-radius: var(--r-champ);
  background: var(--bg); border: 1px solid var(--border);
  font-size: 0.86rem; line-height: 1.5; overflow-x: auto;
}
/* Dans un énoncé d'exercice, un bloc d'exemple ne porte souvent que huit caractères : étiré sur toute la
   colonne, il faisait une grande boîte presque vide. Il se serre donc sur son contenu, et se distingue par
   un liseré plutôt que par un cadre complet (remarque de Salim du 11/10/2026). */
.exercice-enonce .ressource-enonce pre {
  display: inline-block; min-width: 140px; max-width: 100%;
  margin: 6px 0 10px; padding: 7px 12px;
  background: var(--bg-panel); border: 0; border-left: 3px solid var(--accent-2); border-radius: 0 var(--r-champ) var(--r-champ) 0;
}
.ressource-enonce pre code { font-family: var(--font-mono); background: none; color: inherit; padding: 0; }
.ressource-enonce strong { color: var(--text); }
.ressource-enonce h1, .ressource-enonce h2, .ressource-enonce h3 { color: var(--accent); }
/* Le bloc de la question porte le même liseré que l'en-tête : c'est le texte que le candidat doit lire en
   premier, et il se détachait mal du reste de la page. */
.panel-question { border-left: 4px solid var(--accent); }
.panel-question .ressource-etiquette { color: var(--accent); margin-top: 0; }
.entretien-progression::-webkit-progress-value {
  background: var(--accent);
}
.entretien-progression::-moz-progress-bar {
  background: var(--accent);
}
.ressource-etiquette { margin: 12px 0 2px; font-size: 0.74rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--text-dim); }
.ressource-corps { font-size: 0.9rem; line-height: 1.55; }
.ressource-corps ul { margin: 4px 0 0; padding-left: 20px; }
.ressource-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 12px 0 0; }
.ressource-actions form { margin: 0; }

/* Justification d'une extension de profil, telle que l'expert l'a écrite. */
.justification { white-space: pre-wrap; background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte); padding: 14px 16px; font-size: 0.92rem; line-height: 1.6; }
.chip-attente { display: block; font-size: 0.7rem; font-weight: 600; color: var(--warn); text-transform: uppercase; letter-spacing: 0.02em; }
.chip-theme span small { font-size: 0.72rem; font-weight: 400; opacity: 0.75; }
.synthese-theme { font-weight: 400; }

/* ------------------------------------------------------------------------
   Entretien IA vu par le candidat (docs/spec-entretien-ia.md § 3.5 et § 3.6).
   ------------------------------------------------------------------------ */

/* ----- L'en-tête permanent : la barre de la séance -----
   Temps restant, étape en cours, et le temps de l'exercice quand il y en a un.

   **Elle est sombre, comme la scène qu'elle surmonte** (remarque de Salim du 18/10/2026 : le bandeau
   « Votre entretien » et son chronomètre étaient moches, et l'écran d'entretien n'avait aucun effet).
   Un titre de page noir sur blanc suivi d'un encadré gris ne disait rien de ce qui se jouait juste en
   dessous : la barre porte donc la matière de la scène, en clair comme en sombre, et le chronomètre y
   devient le chiffre qu'on vient chercher. */
.entretien-barre {
  display: flex; flex-wrap: wrap; gap: 14px 32px; align-items: center;
  padding: 14px 20px; margin: 0 0 14px;
  color: #fff; border-radius: var(--r-carte); border: 1px solid rgba(255, 255, 255, .09);
  background:
    radial-gradient(125% 190% at 0% 0%, rgba(169, 112, 255, .34), transparent 58%),
    linear-gradient(135deg, #1B1629, var(--scene-fond) 62%);
}
.entretien-seance { display: flex; align-items: center; gap: 12px; flex: 1 1 240px; min-width: 0; }
.entretien-barre h1 { margin: 0; font-size: 1.05rem; font-weight: 600; letter-spacing: .01em; color: #fff; }
.entretien-etape { margin: 3px 0 0; font-size: .88rem; color: rgba(255, 255, 255, .66); }
/* Le point qui bat : la séance est en cours et le chronomètre tourne. C'est le seul mouvement de la
   barre, et il remplace une ligne de texte de plus. */
.entretien-pastille {
  flex: none; width: 10px; height: 10px; border-radius: 50%;
  background: #C9A6FF; box-shadow: 0 0 10px rgba(201, 166, 255, .9);
  animation: seance-bat 2.6s ease-out infinite;
}
@keyframes seance-bat {
  0% { box-shadow: 0 0 10px rgba(201, 166, 255, .9), 0 0 0 0 rgba(169, 112, 255, .5); }
  70%, 100% { box-shadow: 0 0 10px rgba(201, 166, 255, .9), 0 0 0 13px rgba(169, 112, 255, 0); }
}
.entretien-chronos { display: flex; flex-wrap: wrap; gap: 10px 26px; margin-left: auto; }
/* Ce qui qualifie le chiffre, sous le chiffre : la duree de la seance, ou la question qu'il accompagne. */
.entretien-sous-chrono { font-size: .72rem; color: rgba(255, 255, 255, .5); letter-spacing: .01em; }
/* Le chronometre est **le** chiffre que le candidat surveille pendant une heure : il merite d'etre lisible
   et pose, pas une ligne de texte parmi d'autres. Chiffres tabulaires pour qu'il ne tremble pas a chaque
   seconde. Remarque de Salim du 11/10/2026.

   **Et pas de cadre autour** (remarque de Salim du 19/10/2026) : deux petits rectangles poses sur la barre
   sombre decoupaient le seul chiffre qui compte en deux etiquettes de formulaire. Sa taille et sa couleur
   le detachent assez, et c'est la barre qui porte la matiere. */
.entretien-chrono { display: flex; flex-direction: column; gap: 4px; }
.entretien-chrono .mono {
  display: inline-block; color: #fff;
  font-size: 1.75rem; font-weight: 700; line-height: 1.15; letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  transition: color .2s;
}
.entretien-chrono .mono.chrono-court { color: #F5A34A; }
.entretien-chrono .mono.chrono-fini { color: #F87171; }
.entretien-barre .entretien-etiquette { color: rgba(255, 255, 255, .56); }
.entretien-etiquette { font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-dim); }
.entretien-progression { width: 100%; height: 8px; appearance: none; border: none; border-radius: var(--r-mini); background: var(--border); overflow: hidden; }
.entretien-progression::-webkit-progress-bar { background: var(--border); border-radius: var(--r-mini); }
.entretien-progression::-webkit-progress-value { background: var(--accent); border-radius: var(--r-mini); }
.entretien-progression::-moz-progress-bar { background: var(--accent); border-radius: var(--r-mini); }
.chrono-court { color: var(--warn); }
.chrono-fini { color: var(--error); }

/* Second formulaire sous la réponse : « Je ne sais pas ». Il ne doit pas peser autant que le premier. */
.form-card-serree { padding: 12px 16px; margin-top: 12px; }
.form-card-serree .hint-small { margin: 8px 0 0; }
[data-sauter-ia][data-arme] { border-color: var(--warn); color: var(--warn); }

/* Vérification du matériel avant de commencer (§ 3.5) : l'aperçu de la caméra, puis une carte par point.
   **Une carte porte son titre, sa consigne, son état et sa commande** (remarque de Salim du 19/10/2026) :
   les lignes à puces, leur « OK » ou « KO » en gras et les trois boutons posés au milieu d'une phrase
   étaient « moches ». L'état se lit comme une étiquette d'état ailleurs sur le site, et la teinte de la
   carte dit tout de suite ce qui reste à faire : gris en attente, sarcelle au vert, rouge à corriger. */
.verif-technique { display: block; }
.verif-apercu {
  display: block; width: 200px; aspect-ratio: 4 / 3; object-fit: cover; transform: scaleX(-1);
  border-radius: var(--r-champ); border: 1px solid var(--border); background: var(--scene-fond);
}
.verif-points {
  margin: 0; padding: 0; list-style: none; align-content: start;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 10px;
}
/* La carte de la caméra porte l'aperçu à sa droite, sur toute sa hauteur : l'image et le point qu'elle
   prouve ne se quittent pas. */
.verif-camera { grid-template-columns: minmax(0, 1fr) auto 200px; }
.verif-camera .verif-titre { grid-column: 1; grid-row: 1; }
.verif-camera .verif-badge { grid-column: 2; grid-row: 1; }
.verif-camera .verif-ligne, .verif-camera .verif-message { grid-column: 1 / 3; }
.verif-camera .verif-apercu { grid-column: 3; grid-row: 1 / span 3; align-self: center; justify-self: end; }
.verif-point {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 2px 10px; align-items: start;
  padding: 12px 14px; background: var(--bg-panel);
  border: 1px solid var(--border); border-left: 3px solid var(--teinte); border-radius: var(--r-carte);
}
/* Le micro et le haut-parleur portent une transcription et trois boutons : ils prennent toute la rangée. */
.verif-large { grid-column: 1 / -1; }
.verif-titre { grid-column: 1; grid-row: 1; margin: 0; font-weight: 600; }
.verif-badge {
  grid-column: 2; grid-row: 1; justify-self: end; white-space: nowrap;
  padding: 2px 9px; border-radius: var(--r-mini); font-size: 0.72rem; font-weight: 600;
  color: var(--teinte);
  background: color-mix(in srgb, var(--teinte) 12%, var(--bg));
  border: 1px solid color-mix(in srgb, var(--teinte) 30%, var(--bg));
}
.verif-ligne { grid-column: 1 / -1; margin: 2px 0 0; font-size: 0.9rem; line-height: 1.5; color: var(--text-dim); }
.verif-message { grid-column: 1 / -1; margin: 4px 0 0; font-size: 0.85rem; color: var(--teinte); }
.verif-message:empty { display: none; }
.verif-attente { --teinte: var(--text-dim); }
.verif-ok { --teinte: var(--sarcelle); }
.verif-ko { --teinte: var(--rouge); }
/* La phrase entendue, rapportée telle quelle : c'est elle, et rien d'autre, qui prouve que le micro
   fonctionne. Le cadre n'existe pas tant qu'il n'y a rien à montrer. */
.verif-dit {
  grid-column: 1 / -1; margin: 8px 0 0; padding: 8px 12px; font-size: 0.9rem;
  border-radius: var(--r-champ); background: var(--bg-panel-2); color: var(--text);
}
.verif-dit:empty { display: none; }

/* Encadré de rappel des règles, juste au-dessus du bouton (§ 3.5). */
.rappel-regles { border: 1px solid var(--border); border-left: 3px solid var(--ambre); border-radius: var(--r-carte); padding: 16px 18px; margin: 24px 0 18px; background: var(--bg-panel); }
.rappel-regles h2 { margin: 0 0 10px; font-size: 1rem; }
.rappel-regles ul { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; }

/* Aperçu de la caméra pendant l'entretien : petit, discret, toujours visible (§ 7.2). */
/* **Pas de vignette de coin pendant la réunion** : le candidat s'y voit déjà en grand, et la vignette
   fixe recouvrait le panneau de sa transcription. Elle reste dans la page, c'est elle qui tient le flux de
   la caméra, et `apercuCamera` d'entretien-ia.js prend la photo sur celle qui s'affiche.

   Le marqueur `[data-entretien-ia]` est un `div` **vide et frère**, pas un parent : la règle vise donc la
   vignette qui a l'écran de réunion parmi ses frères suivants. */
.camera-coin:has(~ [data-entretien-oral]) { display: none; }
.camera-coin { position: fixed; right: 16px; bottom: 16px; width: 132px; aspect-ratio: 4 / 3; border-radius: var(--r-champ); border: 1px solid var(--border); background: #000; object-fit: cover; transform: scaleX(-1); z-index: 40; box-shadow: var(--ombre-flottante); }

/* Bandeau de retour au plein écran ou de caméra coupée (§ 7.1). */
/* ------------------------------------------------------------------------
   Document d'accord de l'Entretien IA (docs/spec-entretien-ia.md § 3.5).
   Remarque de Salim du 11/10/2026 : la page etait « beaucoup de texte en vrac ».
   Elle se lit maintenant comme des conditions que l'on accepte : articles
   numerotes, colonne de lecture bornee, et l'accord a la fin.
   ------------------------------------------------------------------------ */
/* Les trois boutons du test du haut-parleur : écouter, puis confirmer dans un sens ou dans l'autre. Ils
   sont sur leur propre rangée dans la carte, jamais au milieu d'une phrase. */
.verif-boutons { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }

/* **Les commandes s'alignent sur l'éditeur et entre elles.** Les cartes de formulaire portent un retrait de
   16 px : dans la colonne de travail, les boutons se trouvaient donc décalés du bord gauche de l'éditeur, et
   le bouton de développement décalé de ceux de la réunion. Remarques de Salim du 11/10/2026. */
.exercice-travail .form-card, .reunion .form-card {
  max-width: none; padding-left: 0; padding-right: 0; background: none; border: none;
}
.bloc-dev { margin-top: 16px; }
.bloc-dev .hint-small { margin: 8px 0 0; }

/* Une entrée ou une sortie attendue vide est un cas limite, pas un oubli : on le dit. */
.exercice-test-vide { margin: 2px 0 8px; color: var(--text-dim); font-style: italic; font-size: 0.85rem; }

/* L'état du micro, dans la vignette du candidat. */
.reunion-micro { display: inline-flex; align-items: center; gap: 8px; margin-left: 10px; font-size: .72rem; }

/* ----- L'assistant d'avant-entretien -----
   **Un écran à la fois, et un bouton pour avancer** (remarque de Salim du 19/10/2026 : la page était
   « encore trop chargée en texte, trop de paragraphes qui se suivent »). Le fil, en haut, dit où l'on en
   est et ce qui reste ; la navigation, en bas, porte « Précédent » et « Suivant », et c'est « Suivant »
   qui tient la règle du matériel : il ne s'ouvre pas tant que la caméra et le son ne répondent pas, sauf
   si le candidat a demandé l'entretien par écrit. */
.assistant { max-width: 82ch; }
.assistant .accord-document { max-width: none; }

.assistant-fil { display: flex; flex-wrap: wrap; gap: 6px 8px; margin: 0 0 20px; padding: 0; list-style: none; }
.assistant-fil li {
  display: flex; align-items: center; gap: 7px;
  padding: 5px 11px 5px 7px; font-size: 0.8rem; color: var(--text-dim);
  background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-champ);
}
.assistant-rang {
  flex: 0 0 auto; width: 20px; height: 20px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-panel-2); color: var(--text-dim); font-size: 0.72rem; font-weight: 700;
}
.assistant-fil li.courant {
  color: var(--text); font-weight: 600;
  border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, var(--bg));
}
.assistant-fil li.courant .assistant-rang { background: var(--accent); color: var(--on-accent); }
/* Un écran déjà lu passe au sarcelle, la teinte de ce qui est acquis. */
.assistant-fil li.fait {
  color: var(--sarcelle); border-color: color-mix(in srgb, var(--sarcelle) 32%, var(--bg));
}
.assistant-fil li.fait .assistant-rang { background: var(--sarcelle); color: #fff; }

/* L'écran qui arrive se pose, sans glisser : il faut sentir qu'on a changé d'écran, et rien de plus. */
.assistant-etape { animation: etape-entre .18s ease-out; }
@keyframes etape-entre {
  from { opacity: 0; transform: translateY(5px); }
  to { opacity: 1; transform: none; }
}

.assistant-nav {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
  margin: 20px 0 0; padding-top: 16px; border-top: 1px solid var(--border);
}
.assistant-nav .btn-primary { margin-left: auto; }
.assistant-compte { margin: 0; font-size: 0.82rem; color: var(--text-dim); font-variant-numeric: tabular-nums; }
/* Un bouton gris sans raison se lit comme une panne : la raison s'écrit juste en dessous, en ambre. */
.assistant-blocage { margin: 12px 0 0; color: var(--ambre); }

.accord-document {
  max-width: 78ch; margin: 0 0 24px; padding: 4px 26px 8px;
  background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte);
  border-left: 4px solid var(--accent);
}
.accord-article { padding: 20px 0; border-bottom: 1px solid var(--border); }
.accord-article:last-child { border-bottom: none; }
/* **Le numéro de l'article s'en va avec l'empilement** : chaque écran de l'assistant en porte un seul,
   et c'est le fil des écrans, en haut, qui dit où l'on en est. Deux numérotations concurrentes sur le
   même écran ne disaient plus rien. */
.accord-article h2 { margin: 0 0 12px; font-size: 1.05rem; color: var(--text); }
.accord-article ul { margin: 0; padding-left: 22px; }
.accord-article li { margin-bottom: 8px; line-height: 1.55; }
.accord-article p { margin: 0; line-height: 1.6; }
.accord-article a { color: var(--accent); }

.bandeau-alerte { position: fixed; inset: 0 0 auto; z-index: 60; display: flex; flex-wrap: wrap; gap: 12px; align-items: center; justify-content: center; padding: 12px 16px; background: var(--warn); color: #1b1300; font-weight: 600; }
.bandeau-alerte button { background: #1b1300; color: #fff; border: none; border-radius: var(--r-champ); padding: 8px 14px; font: inherit; cursor: pointer; min-height: 44px; }

/* Rubrique « Fiabilité de la session » du rapport (§ 7.4) : rien n'est collé au badge. */
.fiabilite-badge { display: block; margin: 0 0 10px; }
.fiabilite-raison { margin: 0 0 14px; font-size: 0.95rem; }
.fiabilite-chiffres { margin: 0 0 18px; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 6px; font-size: 0.9rem; }
.fiabilite-chiffres li { display: flex; gap: 8px; }
.fiabilite-chiffres b { font-variant-numeric: tabular-nums; }
.planche-photos { display: flex; flex-wrap: wrap; gap: 12px; margin: 12px 0 0; padding: 0; list-style: none; }
.planche-photos li { display: flex; flex-direction: column; gap: 4px; }
.planche-photos img { width: 160px; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--r-champ); border: 1px solid var(--border); background: var(--bg-panel); }
.planche-photos figcaption, .planche-photos .mono { font-size: 0.75rem; color: var(--text-dim); }

@media (max-width: 760px) {
  /* Sur un téléphone, la séance en haut et les chronomètres en dessous : côte à côte, le chiffre se
     serrait contre le bord. */
  .entretien-barre { gap: 10px 20px; padding: 12px 14px; }
  .entretien-chronos { margin-left: 0; width: 100%; }
  .entretien-chrono .mono { font-size: 1.3rem; }
  .verif-camera { grid-template-columns: minmax(0, 1fr) auto; }
  .verif-camera .verif-apercu { grid-column: 1 / -1; grid-row: auto; width: 100%; margin-top: 10px; }
  .camera-coin { width: 96px; right: 10px; bottom: 10px; }
  .planche-photos img { width: 132px; }
}

/* Transcription d'un Entretien IA dans le rapport, avec le lecteur de chaque réponse parlée (§ 17.5). */
.transcription-ia { list-style: none; margin: 0 0 24px; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.transcription-ia > li { padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--r-champ); background: var(--bg-panel); }
.transcription-ia-ligne { border-left: 3px solid var(--accent); }
.transcription-candidat-ligne { border-left: 3px solid var(--border); }
.transcription-ia audio { width: 100%; max-width: 420px; margin-top: 8px; }

/* ------------------------------------------------------------------------
   Écran de réunion de l'Entretien IA à l'oral (docs/spec-entretien-ia.md § 17.3).
   À gauche l'intervieweur, une onde abstraite aux couleurs du site : **jamais
   un visage humain**, le candidat sait qu'il parle à une IA. À droite sa caméra.
   ------------------------------------------------------------------------ */
.reunion { display: flex; flex-direction: column; gap: 14px; }

/* ----- La scène : les deux vignettes, sur toute la largeur -----
   Remarque de Salim du 17/10/2026, « pourquoi les fenêtres ne prennent pas toute la largeur » et
   « cela ne ressemble pas aux applications de réunion modernes ». Elles étaient plafonnées à 920 px au
   milieu d'un écran de 1760, du temps où l'intervieweur était une onde abstraite qui s'étirait : la
   mascotte 3D, elle, tient toutes les largeurs.

   **Le fond de la scène est sombre en clair comme en sombre**, comme le font Meet et Teams en clair :
   une image se regarde mieux sur du sombre, et c'est ce fond qui fait reconnaître une réunion au premier
   coup d'oeil. Ces trois couleurs ne sont donc pas des variables de thème, et c'est voulu.

   La hauteur est bornée : au format 16/9 pleine largeur, deux vignettes feraient 490 px de haut et la
   barre de commande passerait sous la ligne de flottaison. */
/* Le fond de scène sert aussi à l'écran d'attente du démarrage : il vit donc sur :root, pas sur la
   scène de réunion. Ce n'est pas une variable de thème, c'est une constante, en clair comme en sombre. */
:root { --scene-fond: #121019; }
.reunion-scene {
  --scene-tuile: #1C1928;
  --scene-bord: rgba(255, 255, 255, .08);
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px;
  padding: 10px; border-radius: var(--r-carte); background: var(--scene-fond);
}
/* **La hauteur se donne, elle ne se déduit pas.** Avec « aspect-ratio » et « max-height » ensemble, le
   navigateur garde le rapport et **rétrécit la largeur** : les vignettes reprenaient 737 px dans des
   colonnes de 865, et le vide revenait, ce qu'on cherchait justement à retirer. */
.reunion-vignette {
  position: relative; margin: 0; overflow: hidden;
  /* Assez haut pour que deux vignettes pleine largeur restent proches du 16/9 : à 865 px de large, 500 px
     de haut donnent 16/9,2. Plus bas, la caméra se recadrait en bandeau. */
  height: clamp(260px, 46vh, 500px);
  background: var(--scene-tuile); border-radius: var(--r-carte);
  display: flex; align-items: center; justify-content: center;
  box-shadow: inset 0 0 0 1px var(--scene-bord);
}
/* Qui parle se voit, même le son coupé : un liséré d'accent autour de la vignette, comme partout
   ailleurs. C'est la seule chose qui distingue les deux vignettes au repos. */
.reunion-vignette.parle {
  box-shadow: inset 0 0 0 2px var(--accent), 0 0 0 3px var(--accent-ring);
  animation: vignette-parle 2.4s ease-in-out infinite;
}
/* Le liséré respire pendant que l'intervieweur parle : au coin de l'œil, on voit qui a la parole sans
   quitter la question des yeux. */
@keyframes vignette-parle {
  0%, 100% { box-shadow: inset 0 0 0 2px var(--accent), 0 0 0 3px var(--accent-ring); }
  50% { box-shadow: inset 0 0 0 2px var(--accent), 0 0 0 9px rgba(169, 112, 255, .14); }
}
.reunion-vignette figcaption {
  position: absolute; left: 12px; bottom: 10px; padding: 4px 10px; border-radius: var(--r-champ);
  background: rgba(12, 10, 18, .62); color: #fff; font-size: .78rem; letter-spacing: .02em;
  backdrop-filter: blur(6px);
}
.reunion-candidat video { width: 100%; height: 100%; object-fit: cover; transform: scaleX(-1); }

/* ----- La barre de commande, sous la scène -----
   L'état de la parole à gauche, les trois actions à droite. Les boutons traînaient sous les deux
   panneaux de texte, loin de l'image : dans une réunion, les commandes sont sous la scène. */
.reunion-barre {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px;
  padding: 10px 14px; border-radius: var(--r-carte);
  /* **La barre de commande est de la scène**, pas de la page : elle porte donc le même fond sombre que
     les vignettes au-dessus et que la barre de la séance, en clair comme en sombre. Posée en gris clair
     entre deux blocs sombres, elle coupait l'écran en deux (remarque de Salim du 18/10/2026). */
  background: var(--scene-fond); border: 1px solid rgba(255, 255, 255, .09);
  color: #fff;
}
.reunion-barre .btn-secondary {
  background: rgba(255, 255, 255, .07); border-color: rgba(255, 255, 255, .18); color: #fff;
}
.reunion-barre .btn-secondary:hover { background: rgba(255, 255, 255, .13); }
.reunion-barre .btn-primary:disabled, .reunion-barre .btn-secondary:disabled {
  background: rgba(255, 255, 255, .05); border-color: rgba(255, 255, 255, .1); color: rgba(255, 255, 255, .38);
}
.reunion-commandes { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-left: auto; }

/* La question et la transcription, côte à côte : ce que l'intervieweur demande, ce que le candidat dit. */
.reunion-echange {
  display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: 14px; align-items: start;
}

/* L'onde ne s'anime que pendant que l'intervieweur parle : au repos elle est basse et immobile. */
/* ----- La mascotte d'Okodo, la sphère lumineuse qui mène l'entretien (§ 17.3) -----
   Décision de Salim du 18/10/2026, en remplacement du petit androïde. **Une étoile, jamais un visage**
   (§ 9.1) : elle ne mime rien d'humain, et son changement de couleur dit qui parle.

   Ce qui suit est le **dessin de secours**, affiché le temps que le moteur 3D se charge et durablement là
   où WebGL manque. Les couleurs sont les mêmes qu'en 3D : celle du site au repos, et un balayage de teintes
   vives pendant la parole, obtenu ici par rotation de teinte. */
:root {
  --mascotte-coeur: #F3ECFF;
  --mascotte-bord: #2E1C5F;
}

/* ----- Écran d'attente du démarrage (§ 3.5) -----
   Remarque de Salim du 11/10/2026 : attendre devant le document d'accord ne disait rien de ce qui se passe.
   La page se masque, et seul cet écran reste, avec la mascotte. Rien n'y est cliquable.

   **C'est l'écran entier qui est sombre, et non un rectangle noir au milieu d'une page blanche**
   (remarque de Salim du 19/10/2026). L'étoile pose sa lumière autour d'elle : sur du blanc, ses halos ne
   se voient pas, et il fallait donc un fond sombre quelque part. Un cadre de 520 px posé sur la page
   claire se lisait comme une image collée, alors que cet écran est déjà une prise de l'écran entier, et
   qu'il annonce la réunion qui suit, sombre elle aussi. Il la prend donc pour de bon, en position fixe,
   et c'est le même fond que la scène de la réunion. */
.masque-attente { display: none !important; }
.attente-plein {
  position: fixed; inset: 0; z-index: 50;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; padding: 24px; text-align: center;
  background: var(--scene-fond);
}
/* Aucun fond ici : l'étoile et ses halos se détachent sur le fond de l'écran, sans bord qui les découpe. */
.attente-plein-mascotte {
  position: relative; width: min(560px, 88vw); height: min(400px, 48vh);
  display: flex; align-items: center; justify-content: center;
}
/* **Retirer le fond ne suffit pas à retirer le rectangle.** Le halo le plus large déborde du cadre de la
   caméra 3D : le canevas le coupe net, et ce bord franc redessine exactement le rectangle qu'on venait
   d'enlever, en plus clair cette fois. Un dégradé en masque éteint la lumière avant le bord du canevas,
   sans toucher à l'étoile elle-même, qui tient dans les 62 % opaques. La vignette de la réunion, elle,
   garde son canevas entier : là, le rectangle est la tuile, et il est voulu. */
.attente-plein-mascotte .mascotte-3d,
.attente-plein-mascotte .mascotte {
  -webkit-mask-image: radial-gradient(ellipse closest-side at 50% 50%, #000 62%, transparent 100%);
  mask-image: radial-gradient(ellipse closest-side at 50% 50%, #000 62%, transparent 100%);
}
.attente-plein-titre { margin: 0; font-size: 1.25rem; font-weight: 600; color: #fff; }
.attente-plein-detail { margin: 0; max-width: 46ch; color: rgba(255, 255, 255, .72); line-height: 1.55; }

/* La scène 3D se superpose au dessin de secours et le masque dès qu'elle est prête. Sans WebGL, elle reste
   vide et c'est le SVG qui s'affiche : l'entretien ne dépend jamais du moteur de rendu. */
/* « overflow: hidden » n'est pas un détail : le canevas occupe toute la hauteur de la scène, et deux
   canevas empilés par erreur débordaient l'un sous l'autre, ce qui affichait la mascotte plusieurs fois
   (remarque de Salim du 11/10/2026). Le script n'en crée plus qu'un, et la scène le borne quand même. */
.mascotte-scene { position: absolute; inset: 0; overflow: hidden; }
.mascotte-3d { width: 100%; height: 100%; display: block; }
.mascotte-scene.mascotte-3d-prete + .mascotte { display: none; }

.mascotte { height: min(86%, 230px); width: auto; overflow: visible; }
.mascotte-halo { opacity: .6; transform-origin: 80px 80px; animation: mascotte-respire 5s ease-in-out infinite; }
.mascotte-noyau { transform-origin: 80px 80px; animation: mascotte-coeur 5s ease-in-out infinite; }
.mascotte-tache { opacity: .32; transform-origin: 80px 80px; animation: mascotte-coeur 7s ease-in-out infinite; }

/* Pendant la parole : l'étoile s'illumine, bat plus vite, et balaie des teintes vives. La rotation de
   teinte porte sur tout le dessin, comme le balayage de couleur du rendu 3D. */
.reunion-ia.parle .mascotte { animation: mascotte-couleurs 9s ease-in-out infinite; }
.reunion-ia.parle .mascotte-halo { opacity: 1; animation-duration: 1.6s; }
.reunion-ia.parle .mascotte-noyau { animation-duration: 1.6s; }
.reunion-ia.parle .mascotte-tache { opacity: .5; animation-duration: 2.2s; }

@keyframes mascotte-respire {
  0%, 100% { transform: scale(1); opacity: .6; }
  50% { transform: scale(1.06); opacity: .8; }
}
@keyframes mascotte-coeur {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.035); }
}
/* **Le secours blanchit comme le rendu 3D** (demande de Salim du 19/10/2026) : pendant la parole l'étoile
   est une lumière blanche très forte, et la couleur ne reste qu'en lisière. La saturation s'effondre,
   l'éclat monte, et la bande de teintes continue de tourner dessous, du cyan au rose, jamais le tour
   complet du cercle qui passerait par le vert et le jaune. */
@keyframes mascotte-couleurs {
  0%, 100% { filter: hue-rotate(-70deg) saturate(.45) brightness(1.8); }
  50% { filter: hue-rotate(70deg) saturate(.45) brightness(1.8); }
}

/* L'état de la parole, sur le fond sombre de la barre de commande : un violet clair, qui se lit. */
.reunion-etat {
  margin: 0; font-weight: 600; color: #C9A6FF;
  display: flex; align-items: center; gap: 8px; min-width: 0;
}
.reunion-etat::before {
  content: ''; width: 8px; height: 8px; border-radius: 50%;
  background: #C9A6FF; box-shadow: 0 0 8px rgba(201, 166, 255, .8); flex: 0 0 auto;
}

/* Les deux panneaux de l'echange : l'intitule discret en haut, le texte qui porte. Pas de gros titre. */
.reunion-soustitre, .reunion-transcription { margin: 0; height: 100%; }
.reunion-soustitre .ressource-etiquette,
.reunion-transcription .ressource-etiquette {
  margin: 0 0 8px; font-size: 0.72rem; letter-spacing: .09em; text-transform: uppercase;
  color: var(--text-dim); font-weight: 600;
}
.reunion-soustitre .ressource-enonce { font-size: 1.06rem; line-height: 1.6; }

/* Vignettes : le nom en gras, le role en dessous, en petit. L'intervieweur n'a jamais de prenom humain. */
.reunion-vignette figcaption {
  display: flex; flex-direction: column; line-height: 1.25;
}
.reunion-vignette figcaption span { font-size: .7rem; opacity: .85; }

/* Attente de la reponse du modele : un bloc qu'on voit, et trois points qui disent que cela avance. */
.attente-bloc {
  display: flex; align-items: center; gap: 12px; margin: 14px 0 0; padding: 12px 16px;
  background: var(--bg-panel); border: 1px solid var(--accent); border-radius: var(--r-champ);
  color: var(--text); font-size: 0.95rem;
}
.attente-points { display: inline-flex; gap: 5px; flex: 0 0 auto; }
.attente-points span {
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent);
  animation: attente 1.1s ease-in-out infinite;
}
.attente-points span:nth-child(2) { animation-delay: .15s; }
.attente-points span:nth-child(3) { animation-delay: .3s; }

@keyframes attente {
  0%, 100% { opacity: .25; transform: translateY(0); }
  50% { opacity: 1; transform: translateY(-3px); }
}

/* Pendant l'attente, l'ecran se met en retrait : il est clair que rien n'est a cliquer. */
.reunion.en-attente .reunion-echange { opacity: .55; }
.reunion.en-attente .reunion-commandes { opacity: .55; pointer-events: none; }

/* L'écran d'exercice s'estompe de la même façon pendant une exécution : elle demande une quinzaine de
   secondes, et sans ce signal le candidat croyait son clic perdu. L'éditeur, lui, reste utilisable : il
   peut continuer à lire son code et le corriger. */
.exercice.en-attente .form-actions,
.exercice.en-attente .ide-actions { opacity: .55; pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .attente-points span { animation: none; opacity: .8; }
  .assistant-etape { animation: none; }
}
/* L'indicateur de micro ne doit pas se lire comme un rectangle vide quand personne ne parle (remarque de
   Salim du 11/10/2026) : la piste garde donc un remplissage discret au repos, et ne s'anime que pendant la
   parole. Plus de cadre : c'est une jauge, pas une boite. */
.micro-niveau {
  display: block; width: 56px; height: 5px; border-radius: var(--r-mini); overflow: hidden;
  background: var(--border);
}
.micro-niveau > span {
  display: block; width: 18%; height: 100%; border-radius: var(--r-mini);
  background: var(--text-dim); transition: width .12s linear, background .2s;
}
.micro-niveau.actif > span {
  width: 100%; background: var(--teinte);
  animation: niveau .7s ease-in-out infinite;
}

@keyframes niveau {
  0%, 100% { width: 25%; }
  50% { width: 100%; }
}

.reunion-dit { margin: 0; white-space: pre-wrap; font-size: 1.02rem; line-height: 1.6; }
.reunion-dit:not(:empty) { min-height: 2.6em; }

/* Décompte avant l'envoi automatique d'une réponse (§ 17.2). Le candidat doit **voir venir** l'envoi : sans
   ce décompte, la réponse partait sans prévenir au bout du silence et il se faisait couper la parole sans
   comprendre pourquoi. La jauge se vide de droite à gauche, et reprendre la parole annule tout. */
.reunion-envoi {
  display: flex; align-items: center; gap: 12px; margin: 10px 0 0;
  padding: 8px 12px; border-radius: var(--r-champ);
  border: 1px solid var(--accent); background: var(--accent-soft);
  color: var(--text); font-size: 0.86rem;
}
.reunion-envoi-jauge {
  flex: 0 0 auto; width: 72px; height: 6px; border-radius: var(--r-mini);
  background: var(--border); overflow: hidden;
}
.reunion-envoi-jauge > span {
  display: block; width: 100%; height: 100%; border-radius: var(--r-mini);
  background: var(--teinte);
  /* La jauge est repeinte toutes les 60 ms : une transition de 0,9 s la faisait courir après elle-même et
     elle restait pleine alors que la réponse partait. */
  transition: width .12s linear;
}
/* L'invite ne s'affiche que tant que rien n'a ete dit : :empty disparait des le premier mot transcrit. */
.reunion-vide { margin: 4px 0 0; display: none; }
.reunion-dit:empty + .reunion-vide { display: block; }

/* L'animation gêne qui a demandé moins de mouvement : on la coupe, l'information reste dans le texte. */
@media (prefers-reduced-motion: reduce) {
  .entretien-pastille, .reunion-vignette.parle { animation: none; }
  .micro-niveau.actif > span { animation: none; }
  .mascotte-halo, .mascotte-noyau, .mascotte-tache,
  .reunion-ia.parle .mascotte { animation: none; }
  .micro-niveau.actif > span { width: 100%; }
}

/* ------------------------------------------------------------------------
   Environnement de code de l'Entretien IA (docs/spec-entretien-ia.md § 16.4).
   Sur ordinateur : énoncé, exemples et résultats à gauche, éditeur à droite.
   ------------------------------------------------------------------------ */
/* **L'exercice et la réunion sortent de la colonne de lecture.** `.wrap` tient le texte à 1080 px, ce qui
   est juste pour lire mais absurde pour un éditeur de code : l'IDE n'avait plus que 500 px et la page
   semblait tronquée en son milieu. Ces deux écrans prennent donc la largeur de la fenêtre, bordée de
   24 px, et plafonnée pour que l'énoncé ne s'étire pas sur un écran très large.

   La marche se calcule sans transformation : `transform` sur un ancêtre de Monaco perturbe sa géométrie. */
.exercice, .reunion, .percee, .entretien-barre-large {
  width: min(1760px, calc(100vw - 48px));
  margin-left: calc(50% - min(880px, calc(50vw - 24px)));
}

.exercice {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1.45fr);
  grid-template-areas: "enonce travail" "resultat resultat";
  /* Les deux colonnes se terminent sur la même ligne : la carte de l'énoncé s'étire jusqu'au bas de
     l'éditeur, plutôt que de flotter au-dessus d'un grand vide. */
  gap: 20px; align-items: stretch;
}
/* L'énoncé est une **carte**, comme l'éditeur et comme le résultat : posé à même le fond de la page, il
   faisait une colonne de texte nu à côté d'une fenêtre d'éditeur, et l'écran n'avait pas de tenue
   (remarque de Salim du 17/10/2026). Trois cartes, trois rôles. */
.exercice-enonce {
  grid-area: enonce; padding: 16px 18px 20px;
  background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte);
  box-shadow: var(--ombre);
}
.exercice-travail { grid-area: travail; }
.exercice-enonce, .exercice-travail { min-width: 0; }

/* **Plus de colonne figée.** La colonne de droite etait « sticky » du temps ou le resultat des essais
   vivait dans la colonne de gauche : l'editeur disparaissait sous la ligne de flottaison quand le candidat
   lisait son resultat. Depuis que le resultat occupe sa propre rangee en pleine largeur, figer la colonne
   la fait **glisser par-dessus ce resultat** des que la page defile. Remarque de Salim du 11/10/2026. */
.exercice-entete { margin-bottom: 14px; }
.exercice-entete h2 { margin: 0; font-size: 1.3rem; line-height: 1.3; }
.exercice-surtitre {
  margin: 0 0 2px; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--accent);
}
.exercice-enonce h3 { margin: 22px 0 6px; font-size: 0.95rem; color: var(--accent); }
.exercice-enonce h3 + .hint-small { margin: 0 0 10px; }

/* ----- Jeux d'essai -----
   Ils tenaient dans de grandes cartes, chaque valeur dans sa propre boîte blanche cernée d'un filet : trois
   cas occupaient la moitié de l'écran pour six caractères de données (remarque de Salim du 11/10/2026).
   Une ligne par cas, l'entrée et la sortie côte à côte, et les filets intérieurs disparaissent. */
.exercice-tests { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 1px; }
.exercice-tests li {
  display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 4px 18px; align-items: start;
  background: var(--bg); border: 1px solid var(--border); border-left: 3px solid var(--accent-2);
  padding: 8px 12px;
}
.exercice-tests li:first-child { border-radius: var(--r-champ) var(--r-champ) 0 0; }
.exercice-tests li:last-child { border-radius: 0 0 var(--r-champ) var(--r-champ); }
.exercice-tests li:only-child { border-radius: var(--r-champ); }
.exercice-tests li + li { border-top: 0; }
.exercice-tests pre {
  margin: 0; padding: 0; background: none; border: 0; font-size: 0.85rem;
  overflow-x: auto; white-space: pre-wrap; word-break: break-word;
}
.exercice-tests .entretien-etiquette { margin: 0; }

/* ----- Résultat des essais, sur toute la largeur (remarque de Salim du 11/10/2026) -----
   Il vivait dans la colonne de l'énoncé, large de 700 px, et les messages du compilateur s'y repliaient sur
   cinq lignes alors que l'écran en fait 1760. Il occupe maintenant sa propre rangée, sous les deux colonnes,
   et chaque test porte son verdict en couleur : vert s'il passe, rouge sinon. */
/* Le résultat est un **panneau à part**, avec son en-tête, comme la sortie d'un environnement en ligne :
   il flottait sur le fond de la page sous un simple titre, et ne se lisait pas comme une sortie de
   programme (remarque de Salim du 17/10/2026). */
.exercice-resultat {
  grid-area: resultat; min-width: 0; padding: 12px 14px 14px;
  background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-carte);
  box-shadow: var(--ombre);
}
.exercice-resultat h3 {
  margin: 0 0 10px; font-size: 0.72rem; letter-spacing: .09em; text-transform: uppercase;
  color: var(--text-dim); font-weight: 600;
}
.essai { background: var(--bg); }
.essais { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 10px; }
.essai {
  padding: 10px 14px; border: 1px solid var(--border); border-left-width: 4px; border-radius: var(--r-champ);
  background: var(--bg-panel);
}
.essai-reussi { border-left-color: var(--good); }
.essai-echoue { border-left-color: var(--error); }
.essai-neutre { border-left-color: var(--warn); }
.essai-entete { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px; }
.essai-numero { font-weight: 600; }
.essai-verdict {
  padding: 1px 9px; border-radius: var(--r-champ); font-size: 0.74rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.03em; color: var(--on-accent);
}
.essai-reussi .essai-verdict { background: var(--good); }
.essai-echoue .essai-verdict { background: var(--error); }
.essai-etat { color: var(--text-dim); font-size: 0.84rem; }
.essai-detail {
  margin: 8px 0 0; padding: 8px 10px; background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--r-champ); font-size: 0.82rem; line-height: 1.5;
  max-height: 220px; overflow: auto; white-space: pre-wrap; word-break: break-word;
}

/* ----- L'éditeur, dans une vraie fenêtre -----
   Remarque de Salim du 11/10/2026 : « l'IDE a un cadre très bizarre et très moche ». Il flottait dans un
   simple filet arrondi, le fond blanc de Monaco ne remplissait pas ce cadre, et la réglette d'aperçu de
   Monaco ajoutait un couloir gris le long du bord droit (supprimée par « overviewRulerLanes: 0 »).
   L'éditeur est maintenant une fenêtre d'un seul tenant : une barre qui porte le langage et l'état
   d'enregistrement, puis le code. Le fond vient des thèmes maison d'editeur-code.js, donc la fenêtre est
   d'une seule couleur, du haut au bas. */
.ide {
  border: 1px solid var(--border); border-radius: var(--r-carte); overflow: hidden;
  background: var(--bg-panel); box-shadow: var(--ombre);
}
.ide-barre {
  display: flex; align-items: center; gap: 12px; padding: 6px 8px 6px 0;
  background: var(--bg-panel-2); border-bottom: 1px solid var(--border);
}
/* L'onglet du fichier, comme dans un éditeur : le langage, précédé d'une pastille d'accent. Il portait un
   filet à droite et un trait épais au-dessus, qui dessinaient un angle en plein milieu de la barre. */
.ide-onglet {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 14px; margin: -6px 0 -6px 0;
  font-family: var(--font-mono); font-size: 0.82rem; font-weight: 600;
  color: var(--text); background: var(--bg-panel);
  border-bottom: 2px solid var(--accent);
}
.ide-point {
  width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto;
  background: var(--accent);
}
.ide-etat { margin-left: auto; font-size: 0.76rem; color: var(--text-dim); }

/* **Le bouton d'exécution**, dans la barre de l'éditeur (remarque de Salim du 17/10/2026, qui demandait
   l'allure des environnements en ligne). Sa couleur n'est pas l'accent du site : il ne doit pas se
   confondre avec « Soumettre ma solution », qui est définitif, alors que tester ne coûte rien. */
.btn-run {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid transparent; border-radius: var(--r-champ); cursor: pointer;
  background: var(--good); color: #FFFFFF; font-family: var(--font-sans); font-weight: 600;
  transition: filter .15s, box-shadow .15s;
}
.btn-run:hover { filter: brightness(1.07); }
.btn-run svg { width: 14px; height: 14px; display: block; }
/* Même boîte que les deux autres boutons compacts : un modificateur de taille doit exister pour chaque
   style de bouton, sans quoi la rangée se désaligne (voir CLAUDE.md, « Pièges connus »). */
.btn-run.btn-compact { margin-top: 0; padding: 8px 14px; font-size: 0.84rem; }

.ide-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-top: 14px; }
.ide-essais { margin: 0; }

/* L'éditeur a besoin d'une hauteur explicite : Monaco se dimensionne sur son conteneur. */
.exercice-editeur { height: min(68vh, 720px); min-height: 400px; }
.exercice-repli { width: 100%; height: 100%; border: none; padding: 10px 12px; resize: none; background: var(--bg); color: var(--text); font-size: 0.875rem; }
[data-soumettre-ia][data-arme] { border-color: var(--warn); color: var(--warn); }

@media (max-width: 1100px) {
  /* Sous cette largeur, la colonne double devient illisible : on empile. L'entretien reste refusé sur
     téléphone et tablette (§ 3.5), cette règle sert aux petits écrans d'ordinateur. */
  .exercice { grid-template-columns: minmax(0, 1fr); grid-template-areas: "enonce" "travail" "resultat"; }
  .exercice-editeur { height: 52vh; min-height: 320px; }
  /* Même raison pour la réunion : deux vignettes empilées, un seul panneau de texte par rangée. */
  .reunion-scene { grid-template-columns: minmax(0, 1fr); }
  .reunion-vignette { height: clamp(180px, 26vh, 300px); }
  .reunion-echange { grid-template-columns: minmax(0, 1fr); }
  .reunion-commandes { margin-left: 0; }
}

/* Bloc exercice du rapport (docs/spec-entretien-ia.md § 16.6). */
.code-soumis { margin: 8px 0 18px; padding: 12px 14px; background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--r-champ); font-size: 0.85rem; line-height: 1.5; overflow-x: auto; white-space: pre; tab-size: 4; }
.echanges-code { margin: 8px 0 0; }
.echanges-code dt { font-weight: 600; margin-top: 14px; }
.echanges-code dd { margin: 4px 0 0; padding-left: 14px; border-left: 2px solid var(--border); white-space: pre-wrap; }

@media print {
  /* Le code entier doit figurer sur la version imprimée, sans coupure au milieu d'une ligne. */
  .code-soumis { white-space: pre-wrap; word-break: break-all; border-color: #999; }
  .planche-photos img { max-width: 120px; }
}
