/*
================================================================================
  ◎ DEMO KXCLOUD — ZONE FOCUS : CHAT / QUALIFICATION (ADR-007, dossier 05 §4-5)
  Fichier  : /opt/cortex/demo/src/css/components/focus.css
  Rôle     : Exécution & flux — large plan Washi, marges internes ≥ 48px,
             flux de conversation, courbe de score Bézier, input flottant.
================================================================================
*/

.board-focus {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-g2);
}

.focus-panel {
  background-color: var(--glass-paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-float);
  padding: var(--space-g3); /* marges internes massives — exigence ≥ 48px */
  display: flex;
  flex-direction: column;
  gap: var(--space-g2);
}

/* ── CALIBRATION SECTORIELLE (puces pilule) ────────────────────────────────── */
/* min-height : les puces sont gravées statiquement dans le HTML (v66.6,
   anti-CLS) — la ceinture réserve quand même l'assise du bloc. */
.sector-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  min-height: 38px;
}

.chip {
  font-family: "Wotfard", sans-serif;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink-2);
  background-color: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  padding: 6px 16px;
  cursor: pointer;
  transition:
    background-color var(--duration-z3) ease,
    color var(--duration-z3) ease,
    border-color var(--duration-z3) ease;
}

.chip:hover {
  background-color: var(--bg-card-alt);
}

.chip:active {
  transform: scale(0.96); /* réponse haptique — transform seul, zéro reflow */
}

.chip[aria-pressed="true"] {
  background-color: var(--signal);
  border-color: transparent;
  color: var(--ink); /* label en encre sur Mousse — ratio ≈ 7.7:1 */
}

/* ── FLUX DE CONVERSATION — CANAL ÉTANCHE (anti-CLS v66.4) ─────────────────
   Hauteur RÉSERVÉE fixe : les bulles défilent À L'INTÉRIEUR (scroll interne)
   et ne poussent JAMAIS le reste de la page — zéro décalage à l'arrivée
   des messages (le contre-pattern « gesticulation » est annihilé). */
.flow {
  display: flex;
  flex-direction: column;
  gap: var(--space-z1);
  height: clamp(220px, 38vh, 440px);
  padding: var(--space-z1);
  overflow-y: auto;
  scroll-behavior: smooth;
  overscroll-behavior: contain;
  /* Zone de conversation ENCADRÉE : fond à pois très subtils + cadre à la plume
     + élévation douce. box-sizing:border-box (reset global) → la hauteur réservée
     reste identique : anti-CLS préservé, scroll interne inchangé. */
  background-color: color-mix(in oklab, var(--bg-paper) 50%, transparent);
  background-image: radial-gradient(oklch(0.21 0.02 50 / 0.05) 1px, transparent 1.5px);
  background-size: 16px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow:
    inset 0 1px 2px oklch(0.21 0.02 50 / 0.03),
    0 4px 16px oklch(0.21 0.02 50 / 0.04);
}

.flow-msg {
  position: relative;
  max-width: 78%;
  padding: 0.8rem 1.15rem;
  border-radius: var(--radius-md);
  font-size: var(--text-base);
  line-height: 1.65;
  word-wrap: break-word;
}

/* Bulles : verre translucide + entrée douce (fondu + montée). transform/opacity
   SEULS → couche compositée, zéro reflow (anti-CLS conservé). */
.flow-msg--prospect,
.flow-msg--agent {
  animation: flow-msg-in var(--duration-z2) cubic-bezier(0.16, 1, 0.3, 1) both;
  box-shadow: 0 2px 12px oklch(0.21 0.02 50 / 0.05);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* Prospect — verre clair (Washi translucide), côté opérateur (droite), coin tail */
.flow-msg--prospect {
  align-self: flex-end;
  background-color: color-mix(in oklab, var(--bg-paper) 70%, transparent);
  color: var(--ink-2);
  border: 1px solid var(--line-strong);
  border-bottom-right-radius: 6px;
}

/* Agent — verre Mousse teinté, côté agent (gauche), coin tail */
.flow-msg--agent {
  align-self: flex-start;
  background-color: var(--signal-dim);
  color: var(--ink);
  border: 1px solid color-mix(in oklab, var(--signal) 28%, transparent);
  border-bottom-left-radius: 6px;
}

.flow-msg--system {
  align-self: center;
  background-color: transparent;
  color: var(--ink-muted);
  font-size: var(--text-sm);
  text-align: center;
  padding: 0;
}

.flow-msg--error {
  align-self: center;
  color: var(--accent-ink);
  background-color: var(--accent-dim);
  border: 1px solid color-mix(in oklab, var(--accent) 24%, transparent);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
}

/* Curseur de frappe du flux dactylo */
.flow-caret {
  display: inline-block;
  width: 2px;
  height: 1em;
  vertical-align: text-bottom;
  background-color: var(--signal-deep);
  animation: caret-pulse calc(var(--duration-z1) * 2) step-end infinite;
}

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

/* Entrée des bulles (verre POC élevé) — fondu + montée légère */
@keyframes flow-msg-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .flow-msg--prospect,
  .flow-msg--agent { animation: none; }
}

/* ── TIMELINE DE RÉFLEXION — l'agent pense (couche présentation, thinking.js) ──
   Côté agent (gauche), verre cohérent C1, élévation douce. Fil vertical d'étapes :
   franchie = coche, courante = puce qui pulse, à venir = puce sourde.
   Épouse la latence réelle du webhook puis se résorbe (is-leaving). */
.flow-think {
  align-self: flex-start;
  position: relative;
  max-width: 78%;
  padding: 0.75rem 1rem;
  border-radius: var(--radius-md);
  border-bottom-left-radius: 6px;
  background-color: var(--signal-dim);
  border: 1px solid color-mix(in oklab, var(--signal) 28%, transparent);
  box-shadow: 0 6px 22px oklch(0.21 0.02 50 / 0.07);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  animation: flow-msg-in var(--duration-z2) cubic-bezier(0.16, 1, 0.3, 1) both;
}
.flow-think.is-leaving {
  animation: flow-think-out var(--duration-z3) forwards cubic-bezier(0.4, 0, 1, 1);
}

.think-timeline {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* Étape : puce (colonne fixe) + libellé ; fil vertical reliant les puces. */
.think-step {
  position: relative;
  display: grid;
  grid-template-columns: 16px 1fr;
  align-items: center;
  gap: 0.6rem;
}
.think-step:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 7.25px;            /* centre de la puce de 16px */
  top: 16px;
  bottom: calc(-0.5rem - 1px);
  width: 1.5px;
  background-color: var(--line-strong);
}
.think-step.is-done::before {
  background-color: color-mix(in oklab, var(--signal) 50%, transparent);
}

/* Puce d'étape */
.think-mark {
  position: relative;
  z-index: 1;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 1.5px solid var(--line-strong);
  background-color: var(--bg-paper);
}
/* Étape franchie : pastille Mousse + coche blanche */
.think-step.is-done .think-mark {
  border-color: transparent;
  background-color: var(--signal-status);
}
.think-step.is-done .think-mark::after {
  content: "";
  position: absolute;
  inset: 0;
  background: center / 9px no-repeat
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13l4 4L19 7'/%3E%3C/svg%3E");
}
/* Étape courante : puce pleine + halo qui pulse */
.think-step.is-current .think-mark {
  border-color: var(--signal-deep);
  background-color: var(--signal-dim);
  animation: think-pulse calc(var(--duration-z1) * 2) ease-in-out infinite;
}
.think-step.is-current .think-mark::after {
  content: "";
  position: absolute;
  inset: 50%;
  width: 6px;
  height: 6px;
  margin: -3px;
  border-radius: 50%;
  background-color: var(--signal-deep);
}

/* Libellés par état */
.think-label {
  font-family: "Wotfard", sans-serif;
  font-size: var(--text-sm);
  line-height: 1.3;
  color: var(--ink-muted);
  transition: color var(--duration-z3) ease;
}
.think-step.is-current .think-label { color: var(--ink); font-weight: 600; }
.think-step.is-done .think-label { color: var(--ink-2); }

@keyframes think-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--signal) 45%, transparent); }
  50%      { box-shadow: 0 0 0 5px color-mix(in oklab, var(--signal) 0%, transparent); }
}
@keyframes flow-think-out { to { opacity: 0; transform: translateY(-6px) scale(0.97); } }

@media (prefers-reduced-motion: reduce) {
  .flow-think { animation: none; }
  .think-step.is-current .think-mark { animation: none; }
}

/* ── CARTES DE MÉTRIQUES (remplace le tracé courbe) — qualification courante ───
   Style dashboard cohérent avec le verre/encadrement validés : une métrique par
   carte (label discret + valeur en grand). Carte SCORE pleine largeur, colorée
   par palier de chaleur (OKLCH demo, FROID slate muté — jamais bleu vif).
   chart.js ne rend QUE les données réelles présentes (aucune carte vide). */
.score-chart {
  position: relative;
}
.metric-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-z1);
}

.metric-card {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: var(--space-z1);
  background-color: var(--glass-paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-input);
  animation: metric-card-in var(--duration-z2) cubic-bezier(0.16, 1, 0.3, 1) both;
}
.metric-card-label {
  font-family: "Roboto Mono", monospace;
  font-size: 0.68rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.metric-card-value {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: var(--text-lg);
  line-height: 1.15;
  color: var(--ink);
  word-break: break-word;
}

/* Carte SCORE DE CHALEUR — pleine largeur, l'élément le plus visible */
.metric-card--heat {
  grid-column: 1 / -1;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-z2);
  border-color: color-mix(in oklab, var(--heat, var(--signal)) 30%, transparent);
  background-color: color-mix(in oklab, var(--heat, var(--signal)) 8%, var(--glass-paper));
}
.heat-figure {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}
.heat-score {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 900;
  font-size: clamp(2rem, 6vw, 2.75rem);
  line-height: 1;
  color: var(--heat, var(--ink));
}
.heat-score small {
  font-size: 0.42em;
  font-weight: 700;
  color: var(--ink-muted);
}
.heat-level {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.85rem;
  border-radius: var(--radius-pill);
  font-family: "Roboto Mono", monospace;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
  color: var(--heat, var(--ink));
  background-color: color-mix(in oklab, var(--heat, var(--signal)) 14%, transparent);
  border: 1px solid color-mix(in oklab, var(--heat, var(--signal)) 32%, transparent);
}
.heat-level::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--heat, var(--signal));
}

/* Paliers de chaleur — OKLCH demo (FROID slate muté, TIÈDE ambre, CHAUD orange,
   BRÛLANT rouge ; zéro bleu vif, zéro couleur de mockup) */
.metric-card--heat[data-level="FROID"]   { --heat: oklch(0.58 0.05 245); }
.metric-card--heat[data-level="TIÈDE"]   { --heat: oklch(0.62 0.11 75); }
.metric-card--heat[data-level="CHAUD"]   { --heat: oklch(0.60 0.15 47); }
.metric-card--heat[data-level="BRÛLANT"] { --heat: oklch(0.56 0.19 25); }

@keyframes metric-card-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.metric-card:nth-child(2) { animation-delay: 60ms; }
.metric-card:nth-child(3) { animation-delay: 120ms; }

@media (max-width: 540px) {
  .metric-cards { grid-template-columns: minmax(0, 1fr); }
  .metric-card--heat {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-z1);
  }
}
@media (prefers-reduced-motion: reduce) {
  .metric-card { animation: none; }
}

/* ── INPUT FLOTTANT (soft-shadow, anneau Mousse à la saisie) ───────────────── */
/* min-height EXPLICITE : l'espace est réservé dès le premier rendu — le
   bloc ne décale plus la page au chargement (CLS mobile, v66.4). */
.lead-input {
  display: flex;
  align-items: flex-end;
  gap: var(--space-g1);
  min-height: 92px;
  background-color: var(--glass-paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-input);
  padding: var(--space-z1);
  transition: box-shadow var(--duration-z2) ease;
}

.lead-input:focus-within {
  box-shadow: var(--shadow-input), var(--shadow-focus);
}

.lead-input textarea {
  flex: 1;
  min-width: 0;            /* autorise la compression sous le contenu (flexbox) */
  border: none;
  background: transparent;
  resize: none;
  min-height: 52px;
  max-height: 160px;
  font-family: "Wotfard", sans-serif;
  font-size: var(--text-base);
  line-height: 1.6;
  color: var(--ink);
}

/* Le bouton garde sa taille et son axe : il ne se comprime jamais sous le
   textarea et reste aligné en bas de la carte input (v66.12). */
.lead-input .btn-primary {
  flex-shrink: 0;
  align-self: flex-end;
}

.lead-input textarea:focus {
  outline: none;
  box-shadow: none;
}

.lead-input textarea::placeholder {
  color: var(--ink-muted);
}

@media (max-width: 1023px) {
  .focus-panel {
    padding: var(--space-g2); /* le « Ma » se maintient, compacté */
  }

  .flow-msg {
    max-width: 92%;
  }
}

/* Mobile natif (<768px) : densité — la largeur réelle du viewport est
   exploitée, le contenu métier prime (v66.5). */
@media (max-width: 767px) {
  .focus-panel {
    padding: clamp(16px, 4vw, 28px) var(--space-z1);
    gap: clamp(18px, 4vw, 28px); /* aération verticale */
  }

  .lead-input {
    padding: 10px;
    gap: 10px;
    min-height: 76px;
  }

  .lead-input .btn-primary {
    padding: 0.6rem 1rem;
    font-size: 1rem;       /* lisible, et cible tactile suffisante */
    min-height: 48px;
  }

  .lead-input textarea {
    font-size: 1rem;       /* ≥ 16px : pas de zoom automatique iOS */
  }

  .flow-msg--system {
    line-height: 1.7;
    padding: 0 var(--space-z1);
  }
}

/* Grille secteurs (v66.6) : 2 colonnes ≤640px, 1 colonne ≤480px — texte
   jamais coupé, cibles tactiles ≥ 48px, libellés pleinement lisibles. */
@media (max-width: 640px) {
  .sector-chips {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
  }

  .chip {
    min-height: 48px;
    padding: 8px 12px;
    font-size: 1rem;
    white-space: normal;     /* le libellé revient à la ligne, jamais tronqué */
    text-align: center;
    border-radius: var(--radius-md); /* pilule → carte : lisibilité 2 lignes */
  }
}

@media (max-width: 480px) {
  .sector-chips {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ── POLISSAGE ERGONOMIE TACTILE (v66.8 — mobile ≤768px) ──────────────────── */
@media (max-width: 767px) {
  /* Clavier mobile : quand le textarea prend le focus, le navigateur le
     fait défiler avec une marge basse — il n'est jamais collé au clavier
     ni masqué. Réserve aussi un repère de scroll dans le canal. */
  .lead-input textarea {
    scroll-margin-bottom: calc(64px + env(safe-area-inset-bottom, 0px) + 16px);
  }

  /* Canal de conversation : momentum naturel iOS, couche GPU dédiée pour
     un scroll interne fluide sans repaint du fond (v66.12). */
  .flow {
    -webkit-overflow-scrolling: touch;
    scroll-padding-bottom: var(--space-z1);
    overscroll-behavior: contain;
    transform: translateZ(0);
  }

  /* Feedback tactile immédiat : enfoncement au tap (transform seul, zéro
     reflow). Le hover desktop reste géré ailleurs — ici on cible le doigt. */
  .chip:active {
    transform: scale(0.97);
  }

  .lead-input .btn-primary:active {
    transform: translate(2px, 2px) scale(0.99);
  }
}

/* Anti-hover collant : sur écran tactile sans souris, les états :hover
   « restent allumés » après le tap. On neutralise le survol des puces là
   où il n'y a pas de vrai pointeur — le tap garde son :active. */
@media (hover: none) {
  .chip:hover {
    background-color: transparent;
  }
  .chip[aria-pressed="true"]:hover {
    background-color: var(--signal); /* l'état actif reste, lui, affirmé */
  }
}

/* ── ANCRAGE DE LA SAISIE + SCROLL ENCHAÎNÉ (desktop ≥1024px) — C2c-bis ────────
   Fenêtre de chat stable : la zone de saisie reste ANCRÉE en bas du panneau
   (footer collant) pendant que le canal .flow scrolle en interne ou que la page
   défile — elle ne dérive plus avec le contenu. Le .flow GARDE sa hauteur clamp
   (JAMAIS retirée — erreur fatale C2c) et reste le seul scroll interne ; en fin
   de canal la molette enchaîne sur la page (overscroll auto) → fin du piège de
   molette. Mobile/tablette (<1024px : tab bar + clavier réglés v66.x) INCHANGÉS. */
@media (min-width: 1024px) {
  .lead-input {
    position: sticky;
    bottom: var(--space-g1);
    z-index: 2;
  }
  .flow {
    overscroll-behavior: auto;
  }
}
