/* ═══════════════════════════════════════════════════════════════════════
   Captia — Démo en direct · feuille maîtresse (v2, 17 août 2026)
   ═══════════════════════════════════════════════════════════════════════
   SEULE feuille de style de cette page. Elle remplace quatre couches qui
   se contredisaient (styles inline, captia-hud.css, captia-editorial-v3.css,
   demo-cinematic.css) à coups de !important — la refonte « deux portes »
   posée par-dessus produisait des colonnes écrasées et du texte géant.

   Une page, une autorité. Les scripts (app.js, demo-cinematic.js) et les
   42 identifiants du contrat DOM sont inchangés : cette feuille ne fait
   qu'habiller.

   Langage : le trou noir de l'accueil. Vide profond, bleu brume #89aacc,
   violet retenu #8b6bd6, blanc cassé #f5f5f5. Fraunces pour la voix,
   Inter Tight pour le corps, DM Mono pour les étiquettes.
   ═══════════════════════════════════════════════════════════════════════ */

:root{
  /* Jetons consommés aussi par les styles inline restés dans le HTML
     (h2 de la porte sortante, boutons) : ils DOIVENT exister ici. */
  --void:#050608;
  --ink:#07090d; --ink-2:#0b1017; --ink-3:#101826; --ink-4:#172333;
  --paper:#f5f5f5; --paper-2:#dbe6f1;
  --accent:#89aacc; --accent-2:#4e85bf; --accent-ink:#050608;
  --violet:#8b6bd6;
  --fog:#8c98a7; --fog-2:#5d6877;
  --line:rgba(137,170,204,.14); --line-strong:rgba(137,170,204,.3);
  --glass:rgba(255,255,255,.02); --glass-2:rgba(255,255,255,.05);
  --danger:#ff6d78;
  --glow:rgba(78,133,191,.42);
  --font-display:'Fraunces',Georgia,serif;
  --font-body:'Inter Tight',-apple-system,'Segoe UI',sans-serif;
  --font-mono:'DM Mono',ui-monospace,Consolas,monospace;
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0; min-height:100vh;
  color:var(--paper);
  font-family:var(--font-body);
  font-size:15.5px; line-height:1.6;
  -webkit-font-smoothing:antialiased;
  background:
    radial-gradient(1100px 780px at 24% 8%, rgba(78,133,191,.14), transparent 62%),
    radial-gradient(900px 700px at 88% 74%, rgba(139,107,214,.1), transparent 66%),
    linear-gradient(150deg,#050608 0%,#080b10 48%,#050506 100%);
  background-attachment:fixed;
  overflow-x:hidden;
}

/* Voile d'étoiles : deux nappes de points, fixes, quasi imperceptibles.
   L'espace se suggère, il ne se crie pas. */
body::before{
  content:""; position:fixed; inset:0; z-index:-1; pointer-events:none;
  background-image:
    radial-gradient(1.1px 1.1px at 12% 22%, rgba(213,227,242,.5), transparent 100%),
    radial-gradient(1px 1px at 33% 68%, rgba(213,227,242,.34), transparent 100%),
    radial-gradient(1.3px 1.3px at 58% 12%, rgba(168,192,216,.42), transparent 100%),
    radial-gradient(1px 1px at 71% 41%, rgba(213,227,242,.3), transparent 100%),
    radial-gradient(1.2px 1.2px at 86% 79%, rgba(196,178,236,.32), transparent 100%),
    radial-gradient(1px 1px at 44% 89%, rgba(213,227,242,.26), transparent 100%),
    radial-gradient(1.1px 1.1px at 92% 16%, rgba(213,227,242,.38), transparent 100%),
    radial-gradient(1px 1px at 5% 55%, rgba(168,192,216,.3), transparent 100%);
}

img{max-width:100%}
button{font-family:inherit}
a{color:var(--accent)}
:focus-visible{outline:2px solid var(--accent); outline-offset:3px}

.wrap{min-height:100vh; display:flex; flex-direction:column}

/* Couche de compatibilité : l'ancien décor et les vieux accents cyan. */
.aurora{display:none}
.demo-outbound-portrait{display:none}

/* ── Topbar ─────────────────────────────────────────────────────────────── */
.topbar{
  position:sticky; top:0; z-index:50;
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  width:100%; padding:12px clamp(16px,3vw,32px);
  background:linear-gradient(180deg,rgba(5,6,8,.92),rgba(5,6,8,.78));
  backdrop-filter:blur(12px);
  border-bottom:1px solid rgba(255,255,255,.06);
}
.logo{
  display:inline-flex; align-items:center; gap:10px;
  text-decoration:none; color:var(--paper);
  font-family:var(--font-display); font-size:19px; font-weight:500;
}
.logo em{font-style:italic; font-weight:300; font-size:14px; color:var(--fog)}
.logo .captia-brand-mark{
  width:34px; height:34px; border-radius:50%; object-fit:contain;
  filter:drop-shadow(0 0 9px rgba(78,133,191,.4));
  transition:transform .28s ease, filter .28s ease;
}
.logo:is(:hover,:focus-visible) .captia-brand-mark{transform:scale(1.08) rotate(-4deg)}
.topbar-right{display:flex; align-items:center; gap:12px}
.back{
  display:inline-flex; align-items:center; gap:7px;
  font-size:13px; color:var(--fog); text-decoration:none;
  transition:color .2s ease;
}
.back:hover{color:var(--paper)}
.back svg{width:14px; height:14px}
.status{
  display:inline-flex; align-items:center; gap:8px;
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.12em; text-transform:uppercase;
  color:var(--fog); padding:7px 13px; border-radius:999px;
  border:1px solid var(--line); background:var(--glass-2);
}
.status-dot{width:8px; height:8px; border-radius:50%; background:var(--fog-2); flex:none; transition:background .3s ease, box-shadow .3s ease}
.status-dot.ready{background:var(--accent); box-shadow:0 0 9px rgba(137,170,204,.7)}
.status-dot.connecting{background:#e8d48b; box-shadow:0 0 9px rgba(232,212,139,.7); animation:dotPulse 1s ease-in-out infinite}
.status-dot.live{background:#7fd6a4; box-shadow:0 0 10px rgba(127,214,164,.8); animation:dotPulse 1.6s ease-in-out infinite}
.status-dot.error{background:var(--danger); box-shadow:0 0 9px rgba(255,109,120,.7)}
@keyframes dotPulse{0%,100%{transform:scale(1)}50%{transform:scale(1.35)}}
.lang-toggle{
  font-family:var(--font-mono); font-size:11.5px; font-weight:500; letter-spacing:.06em;
  color:var(--fog); background:transparent; border:1px solid var(--line);
  border-radius:999px; padding:7px 13px; cursor:pointer;
  transition:color .2s ease, border-color .2s ease;
}
.lang-toggle:hover{color:var(--paper); border-color:var(--line-strong)}

/* ── Héros ──────────────────────────────────────────────────────────────── */
.hero{
  text-align:center;
  max-width:940px; margin:0 auto;
  padding:clamp(46px,6.5vw,84px) 24px 30px;
}
.hero .kicker{display:none}
.hero .title{
  margin:0 0 16px;
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(40px,6.6vw,78px); line-height:1.02;
  letter-spacing:-.01em; text-wrap:balance;
}
.hero .title em{
  font-style:italic; font-weight:300;
  background:linear-gradient(94deg,#fff 6%,#a8c0d8 48%,#a98edc 96%);
  -webkit-background-clip:text; background-clip:text; color:transparent;
}
.hero .sub{
  margin:0 auto; max-width:560px;
  font-size:16.5px; color:var(--fog);
}
.hero .badges{display:none}

/* ── Le rail : la carte permanente des deux démos ───────────────────────── */
.portes-rail{
  position:sticky; top:59px; z-index:40;
  display:flex; align-items:stretch;
  width:min(1280px,100%); height:46px;
  margin:20px auto 26px;
  padding:0 clamp(16px,3vw,32px);
  background:linear-gradient(180deg,rgba(5,6,8,.94),rgba(5,6,8,.7));
  backdrop-filter:blur(10px);
  border-block:1px solid rgba(255,255,255,.06);
}
.porte-lien{
  flex:1; min-width:0;
  display:flex; align-items:center; justify-content:center; gap:9px;
  text-decoration:none; color:rgba(245,245,245,.42); font-size:13.5px;
  border-bottom:2px solid transparent;
  transition:color .25s ease, border-color .25s ease;
}
.porte-lien:hover{color:rgba(245,245,245,.8)}
.porte-lien.is-active{color:var(--paper); border-bottom-color:var(--tint,#89aacc)}
.pl-dot{width:8px; height:8px; border-radius:50%; flex:none; background:var(--tint); box-shadow:0 0 9px var(--tint)}
.pl-nom{font-weight:600; white-space:nowrap}
.pl-quoi{
  font-family:var(--font-mono); font-size:11px; letter-spacing:.05em;
  color:rgba(245,245,245,.35); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}

/* ── La grille : deux portes de poids égal ──────────────────────────────── */
.console{
  width:min(1340px,100%); margin:0 auto;
  display:grid;
  grid-template-columns:minmax(0,1fr) clamp(52px,5vw,84px) minmax(0,1fr);
  grid-template-areas:
    "porteA axe sortant"
    "tiroir tiroir tiroir"
    "resultat resultat resultat";
  align-items:stretch;
  gap:0 0;
  row-gap:26px;
  padding:0 clamp(16px,3vw,32px) 64px;
}
#porteA{grid-area:porteA}
#sortant{grid-area:sortant}
.portes-axe{grid-area:axe}
.tiroir{grid-area:tiroir}
.resultat{grid-area:resultat}

/* ── L'AXE : la séparation, rendue visible ──────────────────────────────
   Deux démos distinctes, pas une page à deux colonnes. Un trait lumineux
   qui s'éteint aux extrémités, un jeton « ou » au centre : le visiteur voit
   qu'il choisit entre deux choses, il ne lit pas une grille. */
.portes-axe{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:14px; padding:8px 0; pointer-events:none;
}
.axe-trait{
  flex:1; width:1px; min-height:40px;
  background:linear-gradient(180deg,
    transparent,
    rgba(137,170,204,.34) 22%,
    rgba(139,107,214,.34) 78%,
    transparent);
}
.axe-jeton{
  flex:none; display:grid; place-items:center;
  width:38px; height:38px; border-radius:50%;
  font-family:var(--font-mono); font-size:10px; letter-spacing:.12em; text-transform:uppercase;
  color:var(--fog);
  border:1px solid rgba(137,170,204,.24);
  background:radial-gradient(circle at 40% 34%, rgba(137,170,204,.16), transparent 62%), rgba(5,6,8,.92);
  box-shadow:0 0 24px -8px rgba(78,133,191,.5);
}

/* Cadre commun des deux portes — puis chacune assume sa couleur.
   Le liseré du haut est le signal le plus rapide : bleu brume à gauche,
   violet à droite, avant même d'avoir lu un mot. */
.porte{
  position:relative;
  display:flex; flex-direction:column;
  border-radius:22px;
  padding:26px clamp(18px,2.2vw,30px) 28px;
  overflow:hidden;
}
.porte::before{
  content:""; position:absolute; top:0; left:0; right:0; height:2px; z-index:2;
}
#porteA{
  border:1px solid rgba(137,170,204,.24);
  background:
    linear-gradient(168deg, rgba(78,133,191,.13), transparent 46%),
    rgba(6,9,14,.86);
  box-shadow:inset 0 1px rgba(255,255,255,.05), 0 0 70px -50px rgba(78,133,191,.9), 0 40px 90px -70px #000;
}
#porteA::before{background:linear-gradient(90deg, transparent, var(--accent) 28%, var(--accent) 72%, transparent)}
.porte-sortant{
  border:1px solid rgba(139,107,214,.28);
  background:
    linear-gradient(168deg, rgba(139,107,214,.13), transparent 46%),
    rgba(6,9,14,.86);
  box-shadow:inset 0 1px rgba(255,255,255,.05), 0 0 70px -50px rgba(139,107,214,.9), 0 40px 90px -70px #000;
}
.porte-sortant::before{background:linear-gradient(90deg, transparent, var(--violet) 28%, var(--violet) 72%, transparent)}

.porte-tete{display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-bottom:18px}
/* La pastille porte la couleur de sa démo, pas le blanc générique. */
.porte-tag,.sortant-tag{
  display:inline-flex; align-items:center; gap:8px;
  font-family:var(--font-mono); font-size:10px; letter-spacing:.14em;
  text-transform:uppercase; font-weight:500;
  border-radius:999px; padding:7px 14px; margin:0;
}
.porte-tag-a{
  color:#04121c;
  background:linear-gradient(120deg, #b8cadc, var(--accent) 58%);
  border:0;
}
.sortant-tag{
  color:#0d0718;
  background:linear-gradient(120deg, #c4b2ec, var(--violet) 62%);
  border:0;
}
.porte-tag svg,.sortant-tag svg{width:13px; height:13px}
.porte-tete .vortex-mode{margin-left:auto}
.vortex-mode{
  display:inline-flex; align-items:center; gap:8px;
  font-family:var(--font-mono); font-size:10px; letter-spacing:.15em; text-transform:uppercase;
  color:rgba(245,245,245,.35);
}
.vortex-mode::before{
  content:""; width:6px; height:6px; border-radius:50%;
  background:var(--accent); box-shadow:0 0 10px rgba(137,170,204,.75);
}
.demo-motion-toggle{
  width:38px; height:38px; display:grid; place-items:center; flex:none;
  border:1px solid rgba(255,255,255,.1); border-radius:50%;
  color:rgba(245,245,245,.6); background:rgba(255,255,255,.025); cursor:pointer;
  transition:color .2s ease, border-color .2s ease;
}
.demo-motion-toggle:hover{color:var(--paper); border-color:var(--line-strong)}
.demo-motion-toggle svg{width:14px; height:14px}
.demo-motion-toggle .motion-play{display:none}
.demo-motion-toggle[aria-pressed="true"] .motion-play{display:block}
.demo-motion-toggle[aria-pressed="true"] .motion-pause{display:none}

.porte-titre{
  font-family:var(--font-display); font-weight:400;
  font-size:clamp(22px,2.4vw,28px); line-height:1.15;
  margin:0 0 8px; color:var(--paper); text-wrap:balance;
}
/* Le mot-clé de chaque démo prend sa couleur : « elle répond » en bleu
   brume, « elle vous appelle » en violet. Un coup d'œil suffit. */
#porteA .porte-titre::after{
  content:""; display:block; width:34px; height:2px; margin-top:12px;
  background:var(--accent); border-radius:2px;
}
.porte-sortant h2::after{
  content:""; display:block; width:34px; height:2px; margin-top:12px;
  background:var(--violet); border-radius:2px;
}
.porte-sous{
  font-size:14px; line-height:1.55; color:var(--fog);
  margin:0 0 20px; max-width:52ch;
}
/* Le h2/p de la porte sortante gardent leurs styles inline (fonte, taille) :
   les jetons qu'ils consomment sont définis plus haut. */

/* ── Les réglages, dans leur porte ──────────────────────────────────────
   Ils vivaient dans un tiroir partagé en bas de page : la porte entrante
   n'avait plus aucune option, la sortante gardait les siennes. Deux démos
   jumelles ont le même rythme — un intertitre discret par réglage, rien de
   numéroté, et le geste principal reste toujours le plus gros élément. */
.reglages{display:flex; flex-direction:column; gap:18px; margin:0 0 22px}
.reglage{display:flex; flex-direction:column; gap:9px; min-width:0}
.reglage-label{
  display:flex; align-items:baseline; gap:8px;
  font-family:var(--font-mono); font-size:10px; letter-spacing:.15em;
  text-transform:uppercase; color:var(--fog);
}
.reglage-label em{
  font-style:normal; font-size:9px; letter-spacing:.1em;
  color:var(--fog-2); border:1px solid var(--line); border-radius:999px; padding:1px 7px;
}
.reglage .biz-input + .biz-input{margin-top:9px}

/* ════════════════════════════════════════════════════════════════════
   LE SÉLECTEUR DE VOIX — refait le 12 septembre 2026
   ════════════════════════════════════════════════════════════════════
   C'est le contrôle le plus important de la page : chez Captia, la voix EST
   le produit. Il ressemblait à trois boutons radio dans un formulaire.

   Ce qui change, et pourquoi :

   · UNE SIGNATURE D'ONDE par voix. Cinq barres, un motif distinct chacune.
     L'œil sépare les voix avant que l'oreille les ait entendues, et ça parle
     le langage du reste de la marque — le sillage lumineux de l'accueil,
     pas un pictogramme emprunté. Elle n'anime QUE sur la carte choisie :
     trois cartes qui bougent en même temps, c'est une vitrine de karaoké.

   · UN RAIL À GAUCHE qui s'allume à la sélection. Le même geste que les
     cartes du site. Il porte l'état; le fond ne fait que le confirmer.

   · PLUS DE LABEL « GPT-Live » SUR UNE SEULE CARTE. Les trois voix y sont —
     la note au-dessus de la rangée le dit une fois. Maya garde une marque
     « exclusive », parce que c'est ÇA qui est vrai d'elle et d'elle seule.
   ════════════════════════════════════════════════════════════════════ */
.reglage-note{
  display:block; margin:-2px 0 9px; font-size:11px; line-height:1.4;
  color:var(--fog-2); letter-spacing:.01em;
}

.voice-row{display:flex; gap:10px; flex-wrap:wrap}

.voice-option{
  position:relative; flex:1; min-width:132px; text-align:left; overflow:hidden;
  padding:12px 14px 12px 18px; border-radius:14px; cursor:pointer;
  border:1px solid rgba(255,255,255,.09);
  background:linear-gradient(150deg, rgba(255,255,255,.045), rgba(255,255,255,.015));
  color:var(--paper);
  transition:transform .25s cubic-bezier(.2,.75,.2,1), border-color .2s ease,
             background .2s ease, color .2s ease, box-shadow .25s ease;
}
/* Le rail. Il est TOUJOURS là, éteint — sinon la carte saute de trois pixels
   à la sélection et la rangée tressaille. */
.voice-option::before{
  content:''; position:absolute; left:0; top:9px; bottom:9px; width:2px;
  border-radius:0 2px 2px 0; background:rgba(255,255,255,.10);
  transition:background .2s ease, top .25s ease, bottom .25s ease;
}
.voice-option:hover{transform:translateY(-2px); border-color:rgba(137,170,204,.42)}
.voice-option:hover::before{background:rgba(137,170,204,.55)}
.voice-option:focus-visible{outline:2px solid var(--accent); outline-offset:2px}

.voice-option .v-haut{display:flex; align-items:baseline; gap:7px; flex-wrap:wrap}
.voice-option .v-name{font-size:15px; font-weight:600; letter-spacing:-.01em}
.voice-option .v-desc{display:block; font-size:11.5px; color:var(--fog); margin-top:2px; line-height:1.35}

/* « exclusive » : la seule chose vraie de Maya et d'elle seule. Minuscule,
   parce qu'une voix se choisit à l'oreille — pas sur une étiquette. */
.voice-option .v-exclusif{
  font-size:9px; letter-spacing:.09em; text-transform:uppercase;
  color:var(--violet); border:1px solid rgba(139,107,214,.42);
  border-radius:999px; padding:1px 6px; white-space:nowrap;
}

/* La signature d'onde. Décorative : aucun chiffre du produit ne s'y cache. */
.voice-option .v-onde{
  display:flex; align-items:flex-end; gap:2.5px; height:14px; margin-top:9px;
}
.voice-option .v-onde i{
  display:block; width:2.5px; border-radius:2px;
  background:rgba(137,170,204,.42);
  transition:background .2s ease;
}
.voice-option.selected .v-onde i{
  background:rgba(10,10,10,.34);
  animation:v-onde-bat 1.5s ease-in-out infinite;
}
@keyframes v-onde-bat{
  0%,100%{transform:scaleY(.55)}
  50%{transform:scaleY(1)}
}
.voice-option .v-onde i{transform-origin:bottom}
@media (prefers-reduced-motion:reduce){
  .voice-option{transition:border-color .2s ease, background .2s ease, color .2s ease}
  .voice-option:hover{transform:none}
  .voice-option.selected .v-onde i{animation:none}
}

.voice-option.vedette{
  border-color:rgba(137,170,204,.4);
  background:linear-gradient(160deg, rgba(78,133,191,.14), rgba(255,255,255,.02) 62%);
}
.voice-option.vedette::before{background:rgba(137,170,204,.45)}

.voice-option.selected{
  color:#0a0a0a; border-color:var(--paper); background:var(--paper);
  box-shadow:0 10px 30px -14px rgba(78,133,191,.55);
}
.voice-option.selected::before{background:#0a0a0a; top:0; bottom:0}
.voice-option.selected .v-desc{color:rgba(10,10,10,.6)}
.voice-option.selected .v-exclusif{color:#4e85bf; border-color:rgba(78,133,191,.45)}

/* Onglets : « un scénario type » et « mon site web » de POIDS ÉGAL.
   L'ancien libellé « OU LE VRAI TEST » disqualifiait le chemin principal —
   il sous-entendait que les scénarios étaient le faux test. */
.onglets{
  display:flex; gap:4px; padding:4px; border-radius:12px;
  border:1px solid rgba(255,255,255,.07); background:rgba(0,0,0,.3);
}
.onglet{
  flex:1; padding:8px 10px; border-radius:9px; cursor:pointer;
  font-size:12.5px; font-weight:500; color:var(--fog);
  background:transparent; border:0;
  transition:color .2s ease, background .2s ease;
}
.onglet:hover{color:var(--paper)}
.onglet.actif{color:#0a0a0a; background:var(--paper); font-weight:600}
.volet{display:flex; flex-direction:column; gap:9px; margin-top:11px}
.volet[hidden]{display:none}
.volet-mot{font-size:12px; line-height:1.5; color:var(--fog-2); margin:0}

/* Scénarios : des pastilles, pas des cartes — le noyau reste le héros. */
.scenario-grid{display:flex; gap:7px; flex-wrap:wrap}
.scenario-btn{
  text-align:left; padding:9px 13px; border-radius:999px; cursor:pointer;
  border:1px solid rgba(255,255,255,.09); background:rgba(255,255,255,.025); color:var(--paper);
  transition:transform .25s cubic-bezier(.2,.75,.2,1), border-color .2s ease, background .2s ease, color .2s ease;
}
.scenario-btn:hover{transform:translateY(-2px); border-color:rgba(137,170,204,.4)}
.scenario-btn .s-name{display:block; font-size:12.5px; font-weight:600}
.scenario-btn .s-desc{display:none}
.scenario-btn.active{color:#0a0a0a; border-color:var(--paper); background:var(--paper)}

/* ── PORTE A · la scène vocale ───────────────────────────────────────────
   Le canvas 3D (demo-cinematic.js) est l'unique spectacle. Le bouton au
   monogramme flotte au centre, la membrane organique de l'accueil respire
   derrière lui. Tout le reste s'efface. */
.orb-wrap{
  position:relative;
  width:100%; height:clamp(300px,30vw,400px);
  margin:2px 0 14px;
  border-radius:18px;
  border:1px solid rgba(137,170,204,.12);
  background:
    radial-gradient(circle at 50% 52%, rgba(78,133,191,.1), transparent 42%),
    #04050a;
  overflow:hidden;
  display:grid; place-items:center;
  isolation:isolate;
}
.vortex-canvas{position:absolute; inset:0; width:100%; height:100%; z-index:0}
.vortex-neural-art{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  opacity:.12; mix-blend-mode:screen; z-index:0; pointer-events:none;
}
.vortex-depth-plane{display:none}
.halo,.ring{display:none}
/* LE BAS DE PORTE — 28 aout 2026.

   `.porte` est deja une colonne flex. `margin-top:auto` sur son dernier bloc
   pousse le HUD et sa ligne de rappel au bas du panneau, des deux cotes.

   Consequence voulue : les trois blocs supplementaires de la porte sortante
   — le deroulement, le numero, la fenetre CRTC — mangent le mou que la porte
   entrante laisse en respiration, au lieu de decaler son cadre vers le bas.
   Les deux HUD tombent au meme pixel.

   Ca ne marche QUE si la hauteur sous les deux cadres est la meme. C'est
   pourquoi `.so-fine` est descendue sous le HUD sortant : une ligne grise de
   chaque cote, comme la ligne d'aide de la porte entrante. */
.porte-bas{
  margin-top:auto;
  display:flex; flex-direction:column;
  min-width:0;
}

/* LA LIGNE DE RAPPEL SOUS LE CADRE, une seule regle pour les deux portes.

   Il restait 7 px d'ecart entre les deux HUD apres l'ancrage : `.hint`
   (12 px, marge basse de 6) et `.so-fine` (11,5 px, marge haute de 13)
   n'occupaient pas la meme boite. Sept pixels ne se voient pas seuls — ils se
   voient quand deux cadres identiques sont cote a cote, et c'est exactement le
   cas ici.

   Une seule declaration pour les deux, donc, comme pour `.hud-etat` : deux
   regles separees finissent toujours par diverger d'un pixel ou deux, et
   personne ne sait plus laquelle corriger. */
.porte-bas .hint,
.porte-bas .so-fine{
  margin:12px auto 0; max-width:560px;
  font-size:11.5px; line-height:1.6; color:var(--fog-2);
  text-align:center;
}

/* LES REPÈRES, refondus le 28 août 2026.

   Ils étaient imprimés à la VERTICALE sur les flancs du cadre — « ÉCOUTE » et
   « COMPREND » tournés de 90 degrés, soit huit chaînes verticales entre les
   deux portes. Personne ne lit ça d'un coup d'œil, et le premier repère était
   « CAPTIA », le mot que le badge juste au-dessus dit déjà.

   Une ligne horizontale, en haut à gauche, trois mots dans l'ordre où ça se
   passe. Les mêmes règles servent les deux portes : c'est ce qui garantit
   qu'elles ne dériveront pas. */
.vortex-cardinals{
  position:absolute; top:14px; left:16px; right:16px; z-index:1;
  pointer-events:none;
  display:flex; gap:9px; flex-wrap:wrap;
  font-family:var(--font-mono); font-size:9px; letter-spacing:.22em;
  text-transform:uppercase; color:rgba(213,227,242,.3);
}
/* Le séparateur est dessiné, pas écrit : un « · » dans le HTML se retrouverait
   lu à voix haute par un lecteur d'écran et traduit dans les deux langues. */
.vortex-cardinals span + span::before{
  content:"·"; margin-right:9px; color:rgba(213,227,242,.2);
}
/* Les quatre repères de la porte sortante disent ce qu'elle FAIT — composer,
   parler, rappeler — là où ceux de l'entrante disent ce qu'elle écoute. Même
   typographie, même position, teinte de la porte. */
#sortantVortexShell .vortex-cardinals{color:rgba(214,203,240,.26)}

/* Le bouton : un noyau. La membrane organique (cellule 360 de l'accueil)
   vit derrière lui et s'en échappe par les bords. */
.mic-btn{
  position:relative; z-index:3;
  width:clamp(118px,13vw,148px); height:clamp(118px,13vw,148px);
  display:grid; place-items:center;
  border-radius:50%; border:1px solid rgba(255,255,255,.16); cursor:pointer;
  color:#fff;
  background:
    radial-gradient(circle at 42% 34%, rgba(78,133,191,.2), transparent 30%),
    radial-gradient(circle, #080808 0 52%, #020202 76%, #000 100%);
  box-shadow:
    inset 0 1px rgba(255,255,255,.09),
    0 0 0 9px rgba(0,0,0,.7),
    0 0 60px 4px rgba(78,133,191,.2),
    0 30px 70px -30px #000;
  transition:transform .5s cubic-bezier(.16,.8,.2,1), border-color .28s ease, box-shadow .5s ease;
}
.mic-btn:hover:not(:disabled){transform:scale(1.045)}
.mic-btn:disabled{cursor:progress; opacity:.85}
.mic-monogram{position:relative; z-index:2; width:52%; height:52%; object-fit:contain; filter:drop-shadow(0 0 12px rgba(137,170,204,.4))}
.mic-action-icon{
  position:absolute; z-index:3; right:4%; bottom:6%;
  width:30px; height:30px; border-radius:50%;
  display:grid; place-items:center;
  color:#0a0a0a; background:var(--paper);
  box-shadow:0 4px 14px rgba(0,0,0,.5);
  transition:background .25s ease, color .25s ease;
}
.mic-action-icon svg{width:15px; height:15px}

/* La cellule 360 — copiée de l'accueil (index.html est verrouillé par
   empreinte : on copie, on n'édite jamais là-bas). */
.demo-membrane{
  position:absolute; z-index:1; inset:-13%; pointer-events:none;
  border-radius:42% 58% 63% 37% / 51% 36% 64% 49%;
  background:
    radial-gradient(circle at 34% 26%, rgba(229,241,255,.72) 0 1.5%, rgba(137,170,204,.24) 4%, transparent 15%),
    radial-gradient(circle at 66% 68%, rgba(139,107,214,.44), transparent 38%),
    conic-gradient(from 218deg, rgba(78,133,191,.06), rgba(137,170,204,.5), rgba(5,8,13,.06) 38%, rgba(139,107,214,.42) 68%, rgba(78,133,191,.08));
  box-shadow:
    inset 11px -9px 28px rgba(2,3,6,.48),
    inset -8px 8px 22px rgba(213,227,242,.08),
    0 0 28px rgba(78,133,191,.24),
    0 0 72px rgba(78,133,191,.12);
  filter:saturate(1.08); opacity:.85;
  animation:membraneMorph 8.4s ease-in-out infinite alternate;
  transition:opacity .3s ease, filter .3s ease;
}
.demo-membrane::before{
  content:""; position:absolute; inset:9%; border-radius:inherit;
  background:
    repeating-radial-gradient(circle at 30% 38%, rgba(213,227,242,.36) 0 1px, transparent 1px 7px),
    linear-gradient(112deg, transparent 16%, rgba(213,227,242,.18) 48%, transparent 72%);
  mix-blend-mode:screen; opacity:.34; transform:rotate(-12deg);
  animation:membraneCells 6.6s ease-in-out infinite alternate;
}
.demo-membrane::after{
  content:""; position:absolute; inset:-9%;
  border-radius:47% 53% 39% 61% / 56% 41% 59% 44%;
  border:1px solid rgba(137,170,204,.28);
  border-left-color:transparent; border-bottom-color:rgba(139,107,214,.22);
  filter:blur(.2px) drop-shadow(0 0 9px rgba(137,170,204,.28));
  animation:membraneEdge 10s linear infinite;
}
@keyframes membraneMorph{
  0%{border-radius:42% 58% 63% 37% / 51% 36% 64% 49%; transform:rotate(-5deg) scale(.94)}
  48%{border-radius:61% 39% 44% 56% / 39% 57% 43% 61%; transform:rotate(3deg) scale(1.04,.97)}
  100%{border-radius:37% 63% 55% 45% / 62% 42% 58% 38%; transform:rotate(-2deg) scale(.98,1.05)}
}
@keyframes membraneCells{to{opacity:.58; transform:rotate(8deg) scale(1.08)}}
@keyframes membraneEdge{to{transform:rotate(360deg)}}
.mic-btn:is(:hover,:focus-visible) .demo-membrane{opacity:1; filter:saturate(1.28) brightness(1.14)}

/* Les états de l'appel — écrits par app.js, portés par la couleur. */
.mic-btn.connecting{border-color:rgba(232,212,139,.5); animation:btnBreath 1.2s ease-in-out infinite}
.mic-btn.live{border-color:rgba(137,170,204,.6); box-shadow:inset 0 1px rgba(255,255,255,.12), 0 0 0 9px rgba(0,0,0,.7), 0 0 70px 8px rgba(78,133,191,.32), 0 30px 70px -30px #000}
.mic-btn.live .mic-action-icon{background:var(--danger); color:#fff}
.mic-btn.user-speaking{border-color:rgba(127,214,164,.55)}
.mic-btn.assistant-speaking{border-color:rgba(168,192,216,.75)}
.mic-btn.assistant-speaking .demo-membrane{opacity:1; filter:saturate(1.3) brightness(1.2)}
.mic-btn.error{border-color:rgba(255,109,120,.6)}
@keyframes btnBreath{0%,100%{transform:scale(1)}50%{transform:scale(1.02)}}

/* Le liseré de niveau audio. Largeur ET hauteur non nulles obligatoires :
   startViz() calcule clientWidth × dpr — à zéro, il devient invisible sans
   lever la moindre erreur. */
/* L'ONDE ET L'ÉTAT, DANS LE CADRE — 28 août 2026.

   Ils flottaient sous le cadre de la porte entrante alors que la porte
   sortante affichait le sien DEDANS. La même information se cherchait donc à
   deux endroits selon la porte regardée, et trois lignes de texte se
   suivaient sous l'orbe : l'onde, l'état, l'aide.

   `.hud-etat` sert les DEUX portes. Une seule règle, donc aucune dérive
   possible entre les deux — c'est la leçon des descriptions de voix du
   19 août, appliquée au HUD. */
.viz{
  position:absolute; z-index:3; left:16px; right:16px; bottom:38px;
  display:block; width:auto; height:26px; margin:0; opacity:.8;
  pointer-events:none;
}

.hud-etat{
  position:absolute; z-index:3; left:16px; bottom:13px;
  display:flex; align-items:center; gap:8px;
  font-family:var(--font-mono); font-size:9.5px; letter-spacing:.16em;
  text-transform:uppercase; color:rgba(245,245,245,.42);
  margin:0; white-space:nowrap; pointer-events:none;
  transition:color .3s ease;
}
/* Le point d'état : la couleur se lit avant le mot, et il hérite de
   `currentColor`, donc les cinq règles `#sortant[data-call]` qui colorent la
   légende colorent le point du même coup, sans une ligne de plus. */
.hud-etat::before{
  content:""; flex:none; width:5px; height:5px; border-radius:50%;
  background:currentColor; box-shadow:0 0 8px currentColor;
}
.hud-etat strong{font-weight:600; color:var(--paper)}
.call-controls{display:flex; justify-content:center; margin:0 0 12px}
.call-controls[hidden]{display:none}
.call-end{
  display:inline-flex; align-items:center; gap:9px;
  font-size:13.5px; font-weight:600; padding:10px 18px 10px 14px;
  border-radius:999px; cursor:pointer; color:var(--paper);
  background:rgba(255,107,74,.09); border:1px solid rgba(255,107,74,.36);
  transition:background .2s ease, border-color .2s ease;
}
.call-end:hover{background:rgba(255,107,74,.16); border-color:rgba(255,107,74,.6)}
.call-end svg{width:15px; height:15px; color:var(--danger)}
.call-timer{
  font-family:var(--font-mono); font-size:12px; color:var(--fog);
  font-variant-numeric:tabular-nums; padding-left:9px;
  border-left:1px solid var(--line-strong);
}
.call-end.is-cancel svg{color:var(--fog)}
.call-end.is-cancel .call-timer{display:none}

.hint{
  font-size:12px; color:var(--fog-2); text-align:center; margin:0 0 6px;
}
.learn-note{
  display:flex; align-items:center; justify-content:center; gap:8px;
  font-size:12.5px; color:var(--fog); text-align:center; margin:6px auto 0;
  max-width:420px; line-height:1.45;
}
.learn-note svg{width:14px; height:14px; color:var(--accent); flex:none}
.err{
  display:none; margin-top:12px; padding:11px 14px; border-radius:12px;
  font-size:13.5px; line-height:1.5; color:#ffd9cf;
  border:1px solid rgba(255,107,74,.42); background:rgba(255,107,74,.07);
}
.err.show{display:block}

.demo-runtime-note{
  display:flex; gap:14px; align-items:center; justify-content:space-between;
  margin:0 0 16px; padding:14px 16px; border-radius:14px;
  border:1px solid rgba(232,212,139,.3); background:rgba(232,212,139,.06);
  font-size:13px;
}
.demo-runtime-note[hidden]{display:none}
.demo-runtime-kicker{
  display:block; font-family:var(--font-mono); font-size:9.5px;
  letter-spacing:.14em; color:#e8d48b; margin-bottom:4px;
}
.demo-runtime-note strong{display:block; font-size:13.5px; color:var(--paper); margin-bottom:3px}
.demo-runtime-note p{margin:0; color:var(--fog); font-size:12.5px}
.demo-runtime-note a{
  flex:none; display:inline-flex; align-items:center; gap:6px;
  font-size:13px; font-weight:600; color:var(--paper); text-decoration:none;
  padding:9px 14px; border-radius:10px; border:1px solid var(--line-strong);
}

/* ── PORTE B · elle vous appelle ────────────────────────────────────────── */
.sortant-inner{display:flex; flex-direction:column; min-width:0}
#sortant h2{max-width:none}
#sortant h2 em{font-style:italic; color:var(--violet) !important}

/* La séquence des trois réglages — compacte, dans la porte. */
.so-steps{display:flex; flex-direction:column; gap:18px; margin:0 0 4px}
.so-step{display:grid; grid-template-columns:26px 1fr; gap:13px; position:relative}
.so-step::before{
  content:""; position:absolute; left:12.5px; top:28px; bottom:-18px; width:1px;
  background:linear-gradient(180deg, rgba(139,107,214,.35), rgba(139,107,214,.05));
}
.so-step:last-of-type::before{display:none}
.so-num{
  width:26px; height:26px; border-radius:50%; display:grid; place-items:center;
  position:relative; z-index:1;
  font-family:var(--font-mono); font-size:10.5px; font-weight:500;
  color:var(--violet); background:rgba(10,10,10,.9);
  border:1px solid rgba(139,107,214,.4);
  font-variant-numeric:tabular-nums;
  transition:color .3s ease, background .3s ease, border-color .3s ease;
}
.so-step.filled .so-num{color:#0a0a0a; background:var(--paper); border-color:var(--paper)}
.so-head{display:flex; align-items:baseline; gap:9px; flex-wrap:wrap; margin:2px 0 9px}
.so-title{font-size:13.5px; font-weight:600; color:var(--paper); line-height:1.3}
.so-opt{
  font-family:var(--font-mono); font-size:9px; letter-spacing:.12em; text-transform:uppercase;
  color:var(--fog-2); border:1px solid var(--line); border-radius:999px; padding:2px 7px;
}
.so-chips{display:flex; gap:7px; flex-wrap:wrap}
.role-chip{
  font-size:12.5px; font-weight:500; padding:8px 13px; border-radius:999px;
  border:1px solid rgba(255,255,255,.1); background:rgba(255,255,255,.03);
  color:var(--paper); cursor:pointer;
  transition:transform .25s cubic-bezier(.2,.75,.2,1), border-color .2s ease, background .2s ease, color .2s ease;
}
.role-chip:hover{transform:translateY(-2px); border-color:rgba(139,107,214,.45)}
.role-chip.selected{color:#0a0a0a; border-color:var(--paper); background:var(--paper)}

.biz-input{
  width:100%; padding:12px 14px; border-radius:12px;
  background:rgba(6,8,12,.75); border:1px solid rgba(255,255,255,.1);
  color:var(--paper); font-size:14px; font-family:inherit;
  transition:border-color .2s ease, box-shadow .2s ease;
}
.biz-input:focus{outline:none; border-color:rgba(139,107,214,.55); box-shadow:0 0 0 4px rgba(139,107,214,.1)}
#porteA .biz-input:focus, .tiroir .biz-input:focus{border-color:rgba(137,170,204,.5); box-shadow:0 0 0 4px rgba(137,170,204,.09)}
.biz-input::placeholder{color:var(--fog-2)}
.biz-hint{font-size:11.5px; color:var(--fog-2); margin-top:6px}

/* Le moment du numéro : la seule vraie demande de la page. */
.so-call{margin-top:22px; padding-top:20px; border-top:1px solid rgba(255,255,255,.08)}
.so-call-label{
  display:flex; align-items:center; gap:9px; margin-bottom:10px;
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.12em; text-transform:uppercase; color:var(--fog);
}
.so-call-label svg{width:14px; height:14px; color:var(--violet)}
.so-row{display:flex; gap:10px; flex-wrap:wrap; align-items:stretch}
.so-phone-wrap{position:relative; flex:1; min-width:200px; display:flex; align-items:center}
#sortantPhone{
  padding-right:40px !important; font-size:16.5px !important;
  letter-spacing:.03em; font-variant-numeric:tabular-nums;
}
.so-check{
  position:absolute; right:14px; width:9px; height:9px; border-radius:50%;
  background:var(--fog-2);
  transition:background .3s ease, box-shadow .3s ease, transform .3s ease;
}
.so-check.ok{background:var(--violet); box-shadow:0 0 12px rgba(139,107,214,.9); transform:scale(1.15)}

#sortantGo{
  font-family:var(--font-body) !important; font-size:14.5px !important; font-weight:600 !important;
  padding:12px 22px !important; border-radius:999px !important;
  color:#0a0a0a !important; background:var(--paper) !important; border:1px solid var(--paper) !important;
  cursor:pointer; position:relative; overflow:hidden; white-space:nowrap;
  transition:transform .2s ease, background .25s ease, color .25s ease;
}
#sortantGo:hover:not(:disabled){transform:scale(1.03)}
#sortantGo:disabled{cursor:progress}
#sortantGo.is-sweeping::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(90deg,transparent,rgba(139,107,214,.35),transparent);
  animation:btnSweep 1.15s ease-in-out infinite;
}
@keyframes btnSweep{from{transform:translateX(-100%)}to{transform:translateX(100%)}}

.sortant-window{
  display:flex; align-items:flex-start; gap:9px; margin:12px 0 0;
  padding:11px 14px; border-radius:12px;
  border:1px solid rgba(232,212,139,.3); background:rgba(232,212,139,.05);
  font-size:12.5px; line-height:1.5; color:#e8d9ab;
}
.sortant-window[hidden]{display:none}
.sortant-window svg{width:14px; height:14px; color:#e8d48b; flex:none; margin-top:2px}

/* Trois puces devenues une phrase le 28 aout 2026. Elles disaient trois
   choses vraies, mais empilaient trois pastilles sous le bouton — juste la ou
   le visiteur cherche la confirmation que son numero est parti. */
.so-fine{
  margin:13px 0 0; max-width:560px;
  font-size:11.5px; line-height:1.6; color:var(--fog-2);
}

#sortantMsg{
  display:flex; align-items:flex-start; gap:10px;
  margin-top:12px; font-size:13.5px; line-height:1.5;
  padding:11px 14px; border-radius:12px; border:1px solid var(--line);
  animation:msgIn .34s cubic-bezier(.2,.7,.3,1);
}
#sortantMsg[hidden]{display:none}
#sortantMsg.ok{border-color:rgba(139,107,214,.45); background:rgba(139,107,214,.09); color:var(--paper)}
#sortantMsg.ko{border-color:rgba(255,107,74,.4); background:rgba(255,107,74,.06); color:#ffd9cf}
#sortantMsg svg{width:16px; height:16px; flex:none; margin-top:1px}
#sortantMsg.ok svg{color:var(--violet)}
#sortantMsg.ko svg{color:var(--danger)}
@keyframes msgIn{from{opacity:0; transform:translateY(-5px)}to{opacity:1; transform:none}}

/* La scène : noyau → fil → cellulaire. Pilotée par #sortant[data-call] —
   au repos rien ne circule, et le téléphone ne sonne à l'écran que lorsque
   le serveur a confirmé le départ. */
.sortant-visual{
  /* Les MÊMES mesures que .orb-wrap, à la couleur près. Deux démos côte à
     côte dont l'une fait le quart de la hauteur de l'autre ne se lisent pas
     comme un choix : elles se lisent comme une hiérarchie, et le visiteur
     conclut que la seconde est un brouillon. */
  position:relative;
  width:100%; height:clamp(300px,30vw,400px);
  margin:2px 0 14px;
  border-radius:18px;
  border:1px solid rgba(139,107,214,.14);
  background:
    radial-gradient(circle at 50% 52%, rgba(139,107,214,.1), transparent 42%),
    #05040a;
  overflow:hidden;
  display:grid; place-items:center;
  isolation:isolate;
  transition:border-color .35s ease, box-shadow .35s ease;

  /* LES TROIS MESURES DE LA SCÈNE, DÉCLARÉES UNE SEULE FOIS. Le décalage qui
     recentre l'orbe sur le noyau du tore se calcule à partir d'elles : si
     elles vivaient chacune dans leur règle, changer la longueur du fil
     désalignerait l'orbe sans que rien ne le signale. */
  --ob-orb:clamp(104px,9.5vw,126px);
  --ob-line:clamp(70px,9vw,132px);
  --ob-phone:clamp(72px,6.5vw,86px);
}
/* Le noyau 360 remplit le panneau; la scène qui INFORME flotte par-dessus. */
.sortant-visual > #sortantVortexShell{
  position:absolute; inset:0;
  display:grid; place-items:center;
}
.ob-scene{
  position:relative; z-index:2;
  display:flex; align-items:center;
  /* UNE CARTE DANS UNE CARTE, corrigé le 28 août 2026. Ce bloc portait son
     propre `padding`, son `border-radius:16px` et un `backdrop-filter` : au
     centre d'un cadre, ça faisait un second encadré, et le noyau tombait à
     92 px pendant que celui d'en face remplissait son panneau. Côte à côte, la
     porte sortante passait pour un schéma à côté d'un produit.

     LE VOILE RESTE, mais sans bord. Le commentaire d'origine avait raison sur
     un point qu'il ne faut pas perdre : sans lui, le fil pointillé se noie
     dans les particules et l'information disparaît dans la décoration. Il
     devient donc un dégradé large sans rayon ni flou — on garde la lisibilité,
     on perd la boîte. */
  padding:0;
  background:radial-gradient(ellipse 62% 46% at 50% 50%, rgba(3,3,8,.7), rgba(3,3,8,.3) 58%, transparent 82%);

  /* L'ORBE DOIT TOMBER SUR LE NOYAU DU TORE. La scène était centrée comme un
     GROUPE — orbe + fil + téléphone — donc l'orbe glissait à gauche du centre
     pendant que les particules tournaient autour du centre. Deux cercles
     concentriques décalés de trente pixels : rien ne casse, et ça se voit.

     On glisse donc la scène vers la gauche de la moitié de ce qui suit
     l'orbe. Le monogramme retrouve le cœur du tore, et le fil part de lui
     vers le téléphone, ce qui est exactement l'histoire à raconter. */
  /* `translateX` et non `margin-left` : une marge sur un enfant centre par
     `place-items:center` interagit avec le centrage lui-meme, et ma premiere
     tentative a decale du MAUVAIS COTE en aggravant l'ecart de 73 a 107 px.
     Une transformation ne touche pas la mise en page : le voile reste colle a
     la scene, et le signe se verifie a la mesure. Positif = vers la droite. */
  transform:translateX(calc((var(--ob-line) + var(--ob-phone)) / 2));
}
/* Le survol et la composition allument la bordure du panneau, comme la porte
   entrante allume la sienne. Les deux classes viennent de demo-cinematic.js. */
#sortant.is-visual-active .sortant-visual{
  border-color:rgba(139,107,214,.34);
  box-shadow:0 0 46px -22px rgba(139,107,214,.6);
}
#sortant.is-dialing .sortant-visual{
  border-color:rgba(139,107,214,.5);
  box-shadow:0 0 60px -18px rgba(139,107,214,.75);
}
.ob-orb{
  /* Agrandi le 28 août 2026 : il faisait 92 px face à un noyau qui remplit
     tout le panneau d'en face. Deux démos côte à côte dont l'une a un noyau
     trois fois plus petit ne se lisent pas comme un choix. */
  position:relative; width:var(--ob-orb); height:var(--ob-orb); border-radius:50%;
  display:grid; place-items:center;
  border:1px solid rgba(137,170,204,.3);
  background:radial-gradient(circle at 40% 35%, rgba(78,133,191,.22), transparent 26%), #04040a;
  box-shadow:inset 0 1px rgba(255,255,255,.08), 0 0 40px rgba(78,133,191,.18);
}
.ob-monogram{width:64%; height:64%; object-fit:contain; filter:drop-shadow(0 0 12px rgba(137,170,204,.35))}
.ob-orb > svg{
  position:absolute; right:2px; bottom:4px; width:26px; height:26px; padding:6px;
  border-radius:50%; color:#0a0a0a; background:var(--paper);
}
.ob-orb::after{
  content:""; position:absolute; inset:-7px; border-radius:50%;
  border:1px solid rgba(139,107,214,.35);
  animation:obPulse 2.2s ease-out infinite;
}
@keyframes obPulse{0%{transform:scale(1); opacity:.7}100%{transform:scale(1.4); opacity:0}}
.ob-line{
  position:relative; width:var(--ob-line); height:2px; overflow:visible;
  background-image:linear-gradient(90deg, rgba(137,170,204,.5) 48%, transparent 48%);
  background-size:12px 2px;
}
.ob-packet{
  position:absolute; top:50%; left:0; width:8px; height:8px; margin-top:-4px;
  border-radius:50%; background:var(--paper);
  box-shadow:0 0 14px 3px rgba(139,107,214,.8); opacity:0; pointer-events:none;
}
.ob-phone{display:flex; flex-direction:column; align-items:center; gap:8px}
.ob-phone .ph{
  position:relative; width:var(--ob-phone); height:var(--ob-phone); border-radius:50%;
  display:grid; place-items:center;
  background:rgba(255,255,255,.035); border:1px solid rgba(255,255,255,.14);
  transition:border-color .3s ease, background .3s ease, box-shadow .3s ease;
}
.ob-phone .ph svg{width:26px; height:26px; color:var(--accent); position:relative; z-index:2}
.ob-phone .ph::after{
  content:""; position:absolute; inset:-7px; border-radius:50%;
  border:1px solid var(--violet); opacity:0; pointer-events:none;
}
.ob-phone small{
  font-family:var(--font-mono); font-size:9px; letter-spacing:.12em;
  text-transform:uppercase; color:var(--fog);
}
/* `.ob-caption` ne place plus rien : `.hud-etat` s'en charge pour les deux
   portes. La classe SURVIT parce que cinq règles `#sortant[data-call]` la
   colorent selon l'état réel de l'appel, et que son `id` est lu par le script.
   La retirer aurait cassé la sonnerie à l'écran pour économiser deux lignes. */
@keyframes obTravel{0%{left:0; opacity:0}14%{opacity:1}86%{opacity:1}100%{left:100%; opacity:0}}
@keyframes obHalo{0%{transform:scale(.94); opacity:.7}100%{transform:scale(1.4); opacity:0}}
@keyframes obRing{0%,72%,100%{transform:rotate(0)}76%{transform:rotate(-7deg)}80%{transform:rotate(7deg)}84%{transform:rotate(-5deg)}88%{transform:rotate(5deg)}92%{transform:rotate(0)}}

#sortant[data-call="dialing"] .ob-packet{animation:obTravel 1.15s ease-in-out infinite}
#sortant[data-call="dialing"] .ob-line{box-shadow:0 0 20px rgba(139,107,214,.55)}
#sortant[data-call="dialing"] .ob-caption{color:var(--violet)}
#sortant[data-call="ringing"] .ob-line{background-image:linear-gradient(90deg, var(--violet) 100%, transparent 0); box-shadow:0 0 24px rgba(139,107,214,.7)}
#sortant[data-call="ringing"] .ob-phone .ph{border-color:rgba(139,107,214,.7); background:rgba(139,107,214,.1); box-shadow:0 0 40px -12px rgba(139,107,214,.9); animation:obRing 2.4s ease-in-out infinite}
#sortant[data-call="ringing"] .ob-phone .ph::after{animation:obHalo 1.6s ease-out infinite}
#sortant[data-call="ringing"] .ob-phone .ph svg{color:var(--paper)}
#sortant[data-call="ringing"] .ob-caption{color:var(--paper)}
#sortant[data-call="error"] .ob-line{background-image:linear-gradient(90deg, rgba(255,107,74,.5) 34%, transparent 34%); box-shadow:none}
#sortant[data-call="error"] .ob-phone .ph{border-color:rgba(255,107,74,.45)}
#sortant[data-call="error"] .ob-phone .ph svg{color:var(--danger)}
#sortant[data-call="error"] .ob-caption{color:var(--danger)}

/* Le tiroir partagé a disparu : chaque porte porte ses propres réglages.
   Voir le bloc « Les réglages, dans leur porte ». */

/* ── Le résultat : n'existe qu'après un appel ───────────────────────────── */
.resultat[hidden]{display:none}
.resultat{display:grid; gap:22px}
.transcript-wrap{
  border-radius:18px; border:1px solid rgba(255,255,255,.08);
  background:rgba(9,12,17,.72); padding:18px 20px 20px;
}
.t-head{
  display:flex; align-items:center; gap:8px;
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.13em;
  text-transform:uppercase; color:var(--fog); margin-bottom:14px;
}
.t-head svg{width:15px; height:15px; color:var(--accent)}
.transcript{max-height:320px; overflow-y:auto; padding-right:6px; display:flex; flex-direction:column; gap:12px}
.transcript::-webkit-scrollbar{width:4px}
.transcript::-webkit-scrollbar-thumb{background:var(--line-strong); border-radius:2px}
.msg{
  padding:12px 15px; border-radius:14px; font-size:14px; line-height:1.5;
  max-width:88%; animation:msgIn .3s ease;
}
.msg.user{align-self:flex-end; background:rgba(255,255,255,.05); border:1px solid rgba(255,255,255,.09); border-bottom-right-radius:4px}
.msg.assistant{align-self:flex-start; background:rgba(78,133,191,.1); border:1px solid rgba(137,170,204,.22); border-bottom-left-radius:4px}
.msg .who{
  font-family:var(--font-mono); font-size:9.5px; text-transform:uppercase;
  letter-spacing:.12em; color:var(--fog); margin-bottom:5px;
  display:flex; align-items:center; gap:6px;
}
.msg.assistant .who::before{content:""; width:7px; height:7px; border-radius:50%; background:var(--accent); box-shadow:0 0 8px var(--accent)}
.empty-state{
  text-align:center; padding:26px; color:var(--fog); font-size:13.5px;
  font-style:italic; font-family:var(--font-display);
}

/* ── Pied de page ───────────────────────────────────────────────────────── */
.foot{
  margin-top:auto; padding:24px 28px;
  font-family:var(--font-mono); font-size:10px; color:var(--fog-2);
  letter-spacing:.1em; text-transform:uppercase; text-align:center;
}

/* Langue */
.fr-c,.en-c{display:inline}
body.en .fr-c{display:none}
body:not(.en) .en-c{display:none}

/* ── Responsive ─────────────────────────────────────────────────────────── */
@media (max-width: 980px){
  .console{
    grid-template-columns:1fr;
    grid-template-areas:"porteA" "axe" "sortant" "tiroir" "resultat";
    max-width:760px;
    row-gap:0;
  }
  #porteA,.porte-sortant,.tiroir,.resultat{margin-bottom:0}
  #porteA{margin-bottom:0}
  .tiroir,.resultat{margin-top:26px}
  /* Empilé, l'axe devient une frontière horizontale — même rôle, même
     lecture : on choisit entre deux choses. */
  .portes-axe{
    flex-direction:row; width:100%;
    gap:16px; padding:26px 0;
  }
  .axe-trait{
    width:auto; height:1px; min-height:0; flex:1;
    background:linear-gradient(90deg, transparent, rgba(137,170,204,.34) 24%, rgba(139,107,214,.34) 76%, transparent);
  }
  .portes-rail{top:57px}
  .pl-quoi{display:none}
  .cfg-grid{grid-template-columns:1fr}
  .orb-wrap{height:clamp(280px,60vw,360px)}
}
@media (max-width: 560px){
  body{font-size:15px}
  .porte{padding:18px 15px 22px}
  .biz-input{font-size:16px} /* évite le zoom automatique iOS au focus */
  .hero{padding-top:38px}
  .topbar{padding:10px 14px}
  .logo em{display:none}
  .so-row{flex-direction:column}
  #sortantGo{width:100%}
}

/* ── Mouvement : UN SEUL bloc de gouvernance ────────────────────────────
   Le bouton pause (body.motion-paused, écrit par demo-cinematic.js) et la
   préférence système figent tout ce qui bouge — sélecteur large exprès :
   chaque élément ajouté plus tard est couvert sans qu'on y pense. */
body.motion-paused *,
body.motion-paused *::before,
body.motion-paused *::after{animation-play-state:paused !important}
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
  }
  html{scroll-behavior:auto}
}


/* ════════════════════════════════════════════════════════════════════
   LE TIROIR — 28 août 2026

   La porte entrante montrait neuf contrôles avant l'orbe, la sortante douze.
   Un visiteur qui veut simplement entendre la voix devait d'abord lire un
   formulaire. Les deux portes gardent trois temps visibles — sa voix, une
   seule action, l'orbe — et tout l'optionnel descend ici.

   MÊME CLASSE DES DEUX CÔTÉS, ET C'EST LE POINT. Côte à côte, les deux portes
   se répondent : même hairline, même chevron, même place dans la colonne.
   Deux tiroirs dessinés séparément auraient recréé l'écart que le 19 août a
   fermé sur les descriptions de voix.
   ════════════════════════════════════════════════════════════════════ */
.ajuster{
  margin:0 0 20px; padding-top:15px;
  border-top:1px solid var(--line);
}
.ajuster > summary{
  display:flex; align-items:center; gap:8px;
  padding:3px 0; cursor:pointer; list-style:none;
  font-size:12.5px; font-weight:500; color:var(--fog);
  transition:color .18s ease;
}
/* Safari peint encore son triangle sans ceci. */
.ajuster > summary::-webkit-details-marker{display:none}
.ajuster > summary::marker{content:''}
.ajuster > summary:hover{color:var(--paper-2)}
.ajuster > summary:focus-visible{
  outline:2px solid var(--accent); outline-offset:4px; border-radius:6px;
}
.ajuster > summary svg{
  width:14px; height:14px; flex:none; color:var(--accent);
  transition:transform .22s cubic-bezier(.22,.61,.36,1);
}
.ajuster[open] > summary{color:var(--paper-2); margin-bottom:4px}
.ajuster[open] > summary svg{transform:rotate(90deg)}

/* ── LA SECTION OUVERTE — 13 septembre 2026 ──────────────────────────────
   Décision de Vincent : le nom de l'entreprise reste à découvert. C'est le
   seul endroit de la porte entrante où le visiteur donne quelque chose de
   LUI; le cacher derrière une flèche demandait un clic pour atteindre la
   seule chose qui rend la démo personnelle.

   Le titre parle comme les autres étiquettes de réglage — même taille, même
   graisse, mêmes majuscules espacées — parce que c'en est une. Il n'a ni
   curseur, ni survol, ni flèche : rien qui laisse croire qu'il se replie.

   Le fil vertical du corps reste : il dit « ceci appartient au titre
   au-dessus » sans ajouter un encadré dans un encadré dans une porte. */
.ajuster-ouvert > .ajuster-titre{
  margin:0 0 2px; padding:0;
  font-size:10.5px; font-weight:600; letter-spacing:.12em; text-transform:uppercase;
  color:var(--fog-2); font-family:var(--font-body);
}
.ajuster-ouvert > .ajuster-corps{
  padding-top:11px;
  animation:none;
}

.ajuster-corps{
  display:flex; flex-direction:column; gap:13px;
  padding:14px 0 4px 22px; min-width:0;
  /* Le fil vertical dit « ceci appartient au résumé au-dessus » sans ajouter
     d'encadré : une boîte dans une boîte dans une porte, ça fait trois
     bordures pour un champ de texte. */
  border-left:1px solid var(--line);
  margin-left:6px;
}
.ajuster[open] .ajuster-corps{animation:tiroirOuvre .26s cubic-bezier(.22,.61,.36,1)}
@keyframes tiroirOuvre{
  from{opacity:0; transform:translateY(-5px)}
  to{opacity:1; transform:none}
}
@media (prefers-reduced-motion:reduce){
  .ajuster > summary svg{transition:none}
  .ajuster[open] .ajuster-corps{animation:none}
}

.ajuster-champ{
  display:flex; flex-direction:column; gap:7px; min-width:0;
  font-size:11.5px; line-height:1.5; color:var(--fog-2);
}
.ajuster-corps .reglage-label{margin-top:2px}
.ajuster-corps .volet-mot{margin:0}

/* La note qui dit que les entreprises sont inventées. Elle n'est pas
   décorative : la démo a fait parler de vraies entreprises jusqu'au 28 août,
   et un visiteur qui reconnaît un nom doit pouvoir voir tout de suite que
   celui-ci n'en est pas un. */
.fictif-note{
  display:flex; align-items:center; gap:6px;
  margin:8px 0 0; font-size:11px; line-height:1.45; color:var(--fog-2);
}
.fictif-note svg{width:12px; height:12px; flex:none; color:var(--fog-2)}

/* « APPRENDRE LA MIENNE » se distingue des trois scenarios sans crier.

   Les trois scenarios sont des choix instantanes; celle-la demande une adresse
   de site et quelques secondes de lecture. Un trait pointille dit « ce n'est
   pas tout a fait la meme chose » sans en faire un bouton d'action rival du
   noyau — et une fois l'entreprise apprise, la puce s'allume comme les autres
   parce qu'elle devient un choix comme les autres. */
.scenario-mienne{
  border-style:dashed;
  border-color:rgba(137,170,204,.32);
  color:var(--paper-2);
}
.scenario-mienne:hover{border-color:var(--accent); color:var(--paper)}
.scenario-mienne.active{
  border-style:solid; border-color:var(--paper);
  background:var(--paper); color:#0a0a0a;
}

/* Les exemples de deroulement de l'appel : ils REMPLISSENT la ligne, ils ne
   tiennent plus un etat cache. Assez discrets pour ne pas concurrencer le
   champ qu'ils servent. */
.reglage > .so-chips{margin-top:2px}

/* Le bouton du tiroir se tient a son rang. En blanc pleine largeur, il criait
   plus fort que « Qu'elle m'appelle » de la porte d'a cote — alors qu'il est
   l'action d'un panneau optionnel, replie par defaut. Un tiroir discret dont le
   bouton hurle annule le calme qu'on vient de gagner. */
.ajuster-corps button:not(.role-chip){
  align-self:flex-start; padding:9px 16px; border-radius:11px; cursor:pointer;
  font-family:var(--font-body); font-size:12.5px; font-weight:500;
  border:1px solid var(--line-strong); background:rgba(137,170,204,.09);
  color:var(--paper-2);
  transition:border-color .2s ease, background .2s ease, color .2s ease;
}
.ajuster-corps button:not(.role-chip):hover{
  border-color:var(--accent); background:rgba(137,170,204,.16); color:var(--paper);
}
/* Le champ et son bouton restent cote a cote tant qu'il y a la place, et le
   bouton ne s'etire jamais sur toute la largeur quand la ligne se casse. */
.ajuster-corps .so-row{display:flex; gap:8px; flex-wrap:wrap; align-items:center}

/* Une seule ligne sous l'orbe, et le raccourci se lit comme une touche. */
.hint kbd{
  font-family:var(--font-mono); font-size:10px; padding:1px 5px;
  border:1px solid var(--line-strong); border-radius:4px;
  background:rgba(255,255,255,.03); color:var(--fog);
}
