/* WebPhone — standard téléphonique : laque sombre, signal ambre, jack jade */

:root {
  --ink:      #08191A;
  --lacquer:  #0F2A2B;
  --edge:     #1C4142;
  --amber:    #E9B341;
  --jade:     #46C99A;
  --coral:    #E1584B;
  --mist:     #D6E4E1;
  --dim:      #7C9895;

  --mono: ui-monospace, "SF Mono", "Roboto Mono", Menlo, Consolas, monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

* { box-sizing: border-box; }

/* Un display explicite (.panel est en flex) l'emporte sur le display:none
   implicite de l'attribut hidden : sans cette regle, tous les ecrans
   s'empilent sur la meme page. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  min-height: 100%;
  background: var(--ink);
  color: var(--mist);
  font-family: var(--sans);
  -webkit-text-size-adjust: 100%;
}

body {
  display: flex;
  justify-content: center;
  padding: max(16px, env(safe-area-inset-top)) 16px max(16px, env(safe-area-inset-bottom));
}

.phone {
  width: 100%;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* ---------------------------------------------------------------- bandeau */
.bar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--edge);
}

.mark {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--mist);
}

.state {
  flex: 0 1 auto;
  text-align: right;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--dim);
}

.state::before {
  content: "";
  display: inline-block;
  width: 7px; height: 7px;
  margin-right: 7px;
  border-radius: 50%;
  background: currentColor;
  vertical-align: middle;
}

.state[data-tone="ring"]  { color: var(--amber); animation: pulse 1.1s ease-in-out infinite; }
.state[data-tone="live"]  { color: var(--jade); }
.state[data-tone="ended"] { color: var(--coral); }

@keyframes pulse { 50% { opacity: .35; } }

/* ------------------------------------------------------------- formulaire */
.panel { display: flex; flex-direction: column; gap: 16px; }

.field { display: flex; flex-direction: column; gap: 7px; }

.field-label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--dim);
}

input {
  width: 100%;
  padding: 14px 15px;
  background: var(--lacquer);
  border: 1px solid var(--edge);
  border-radius: 3px;
  color: var(--mist);
  font-family: var(--sans);
  font-size: 16px;
}

input:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 1px;
}

input.dial {
  font-family: var(--mono);
  font-size: 26px;
  letter-spacing: .16em;
  text-transform: uppercase;
  text-align: center;
  color: var(--amber);
}

input::placeholder { color: #4C6D6B; letter-spacing: normal; }
input.dial::placeholder { letter-spacing: .16em; }

.hint {
  margin: 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--dim);
}

.error {
  margin: 0;
  padding: 11px 13px;
  border-left: 2px solid var(--coral);
  background: rgba(225, 88, 75, .1);
  color: #F3B4AE;
  font-size: 13px;
  line-height: 1.5;
}

/* ---------------------------------------------------------------- boutons */
.btn {
  padding: 16px;
  border: 0;
  border-radius: 3px;
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: .16em;
  text-transform: uppercase;
  cursor: pointer;
}

.btn-call {
  background: var(--amber);
  color: var(--ink);
  font-weight: 700;
}

.btn-call:disabled { opacity: .45; cursor: progress; }

.btn-ghost {
  background: transparent;
  border: 1px solid var(--edge);
  color: var(--dim);
}

.btn:focus-visible { outline: 2px solid var(--mist); outline-offset: 2px; }

/* ------------------------------------------------------------ appel actif */
.panel-call { gap: 22px; }

.line-id {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.line-label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--dim);
}

.line-id strong {
  font-family: var(--mono);
  font-size: 19px;
  letter-spacing: .14em;
  color: var(--amber);
  font-weight: 500;
}

/* Vumètre : une réglette de 24 segments par voie, alimentée par l'audio réel */
.meters { display: flex; flex-direction: column; gap: 14px; }

.meter { display: flex; flex-direction: column; gap: 8px; }

.meter-name {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--dim);
}

.bars {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 46px;
}

.bars i {
  flex: 1;
  height: 4px;
  min-height: 4px;
  background: var(--edge);
  border-radius: 1px;
  transition: height .07s linear, background-color .12s linear;
}

.bars i.on  { background: var(--jade); }
.bars i.hot { background: var(--amber); }

.meter-self .bars { height: 26px; opacity: .75; }
.meter-self .bars i.on { background: var(--dim); }

.timer {
  font-family: var(--mono);
  font-size: 44px;
  font-variant-numeric: tabular-nums;
  letter-spacing: .04em;
  line-height: 1;
}

.quality {
  margin-top: -14px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--dim);
}

.controls { display: flex; gap: 12px; }

.key {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  padding: 18px 10px;
  background: var(--lacquer);
  border: 1px solid var(--edge);
  border-radius: 3px;
  color: var(--mist);
  cursor: pointer;
}

.key-glyph { font-size: 17px; line-height: 1; }

.key-text {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.key[aria-pressed="true"] {
  background: var(--amber);
  border-color: var(--amber);
  color: var(--ink);
}

.key-end { border-color: rgba(225, 88, 75, .5); color: #F0968D; }
.key-end:active { background: var(--coral); color: var(--ink); }

.key:focus-visible { outline: 2px solid var(--mist); outline-offset: 2px; }

/* ------------------------------------------------------------------- pied */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ------------------------------------------------------------ votre poste */
.own-line {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px;
  background: var(--lacquer);
  border: 1px solid var(--edge);
  border-radius: 3px;
}

.own-number {
  font-family: var(--mono);
  font-size: 40px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: .22em;
  line-height: 1;
  color: var(--amber);
}

.own-line input {
  padding: 9px 11px;
  font-size: 14px;
  background: transparent;
  border-color: transparent;
  border-bottom-color: var(--edge);
  border-radius: 0;
}

.own-line input:focus-visible { outline-offset: 2px; }

/* --------------------------------------------------------- ligne partagée */
.shared {
  border-top: 1px solid var(--edge);
  padding-top: 16px;
}

.shared summary {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--dim);
  cursor: pointer;
}

.shared summary:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }

.shared > *:not(summary) { margin-top: 14px; }
.shared .field { gap: 7px; }
.shared .btn { width: 100%; }

/* ------------------------------------------------------------ appel entrant */
.panel-ring {
  align-items: center;
  gap: 14px;
  padding: 30px 16px;
  background: var(--lacquer);
  border: 1px solid var(--amber);
  border-radius: 3px;
  text-align: center;
}

.caller-number {
  font-family: var(--mono);
  font-size: 46px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: .18em;
  line-height: 1;
  color: var(--amber);
  animation: pulse 1.1s ease-in-out infinite;
}

.caller-name {
  font-size: 16px;
  color: var(--mist);
}

.panel-ring .controls { width: 100%; margin-top: 8px; }

.key-take {
  border-color: rgba(70, 201, 154, .5);
  color: var(--jade);
}

.key-take:active { background: var(--jade); color: var(--ink); }

/* ---------------------------------------------------------------- onglets */
/* ---------------------------------------------------------------- accueil */

/* Six portes en deux colonnes. Elles tiennent sur un ecran de telephone sans
   defiler, et surtout elles ne coutent plus rien aux autres pages : la barre
   d'onglets qu'elles remplacent se payait en haut de chacune. */
.accueil {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin-top: 18px;
}

.carte {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 15px 13px 14px;
  background: var(--lacquer);
  border: 1px solid var(--edge);
  border-radius: 3px;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

.carte:hover { border-color: var(--jade); }
.carte:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

.carte-signe {
  font-size: 21px;
  line-height: 1.1;
  color: var(--jade);
}

/* Les cartes que l'administration accorde poste par poste : le signe prend
   l'ambre, pour dire qu'elles ne sont pas la pour tout le monde. */
.carte-reglee .carte-signe { color: var(--amber); }

/* Armee : la carte prend la couleur de ce qu'elle va faire. Une annonce part
   vers tout le monde -- on ne la lance pas par megarde, et l'on doit voir
   qu'on est a un doigt de parler. */
.carte.armee {
  border-color: var(--coral);
  background: rgba(225, 88, 75, .12);
}

.carte.armee .carte-signe,
.carte.armee .carte-nom { color: var(--coral); }

.carte-nom {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .15em;
  text-transform: uppercase;
}

/* La note dit ce qu'on trouve derriere la porte : le seul mot du titre ne
   suffit pas a distinguer « Messages » de « Salons ». */
.carte-note {
  font-size: 12px;
  line-height: 1.35;
  color: var(--dim);
}

/* La pastille se pose dans le coin, comme sur l'onglet qu'elle remplace. */
.carte .badge {
  position: absolute;
  top: 9px;
  right: 9px;
}

/* Le retour occupe l'emplacement du nom : meme famille, meme graisse, pour
   que l'en-tete ne bouge pas d'une page a l'autre. */
.mark-retour {
  padding: 0;
  background: none;
  border: 0;
  color: var(--amber);
  cursor: pointer;
}

.mark-retour:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }

/* ------------------------------------------- en-tete d'une conversation */

/* Tout sur une ligne, et rien qui passe a la suivante : le nom cede la place
   aux actions plutot que de les repousser. */
.fil-tete-chat {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 7px;
}

.fil-tete-chat .fil-nom {
  flex: 1;
  min-width: 0;
  font-size: 15px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Le detail de presence ne parait qu'en bureau (voir #chat-etat) : il se range
   apres le nom, sans jamais le pousser. */
.fil-tete-chat .fil-etat {
  flex: none;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--dim);
}

/* Le sujet du salon : il complete le nom sans lui disputer la place, et se
   coupe le premier si la ligne se serre. */
.fil-tete-chat .fil-sujet {
  flex: 0 1 auto;
  min-width: 0;
  font-size: 12px;
  color: var(--dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fil-tete-chat .fil-sujet::before { content: '· '; }

.fil-tete-chat .dot,
.fil-tete-chat .btn-mini { flex: none; }

/* La fleche est un geste, pas un mot : elle se resserre. */
.fil-fleche {
  padding: 6px 10px;
  font-size: 16px;
  line-height: 1;
}

/* Appeler est l'action principale ; Effacer ne doit pas lui disputer l'oeil,
   et moins encore attirer le pouce -- c'est la seule des deux qui detruise. */
.fil-appeler {
  border-color: rgba(70, 201, 154, .45);
  color: var(--jade);
}

.fil-appeler:disabled { border-color: var(--edge); color: var(--dim); }
.fil-effacer { color: var(--dim); }

/* Le numero du correspondant, a cote de la sortie. Chiffres a chasse fixe :
   c'est un numero qu'on lit et qu'on recopie, pas un mot. */
.bar-num {
  font-family: var(--mono);
  font-size: 15px;
  font-variant-numeric: tabular-nums;
  letter-spacing: .12em;
  color: var(--amber);
}

/* ------------------------------------------------------------ appel rapide */

.raccourcis-tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 4px;
}

/* Une grille qui se remplit d'elle-meme : trois colonnes sur un telephone,
   davantage des que la largeur le permet, sans palier a ecrire. */
.raccourcis {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(94px, 1fr));
  gap: 8px;
}

.raccourci {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  padding: 9px 10px;
  background: var(--lacquer);
  border: 1px solid var(--edge);
  border-radius: 3px;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

.raccourci:hover:not(:disabled) { border-color: var(--jade); }
.raccourci:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

/* Injoignable : le bouton reste lisible mais se retire du jeu. L'effacer
   ferait disparaitre un poste de la grille d'un appel a l'autre, et l'on
   chercherait un raccourci qui a bouge. */
.raccourci:disabled { opacity: .4; cursor: default; }

.raccourci .dot { margin-bottom: 1px; }

.raccourci-num {
  font-family: var(--mono);
  font-size: 16px;
  font-variant-numeric: tabular-nums;
  letter-spacing: .08em;
  color: var(--amber);
  font-weight: 500;
}

/* Le nom se coupe plutot que d'elargir la colonne : la grille doit rester
   reguliere, c'est ce qui rend les raccourcis repérables du pouce. */
.raccourci-nom {
  align-self: stretch;
  font-size: 11px;
  color: var(--dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --------------------------------------------------------------- annuaire */
.book {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.book-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 13px;
  background: var(--lacquer);
  border: 1px solid var(--edge);
  border-radius: 3px;
}

.book-moi { border-color: rgba(233, 179, 65, .45); }

/* Pastille de presence : c'est elle qu'on lit en premier, avant le nom. */
.dot {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--edge);
}

.dot[data-etat="libre"]  { background: var(--jade); }

.dot[data-etat="occupe"] { background: var(--amber); }

/* ------------------------------------------------------- pieces jointes */

/* Les deux boutons de la saisie tiennent ensemble : le trombone est une action
   de second rang, il ne doit pas concurrencer « Envoyer ». */
.fil-boutons {
  display: flex;
  align-items: flex-end;
  gap: 6px;
}

#chat-joindre, #chat-photo {
  font-size: 15px;
  line-height: 1;
  padding: 9px 10px;
}

.fil-jointe {
  margin-top: 6px;
  color: var(--amber);
}

.jointe { display: block; }

/* Une image se regarde dans la conversation. Bornee en hauteur : une photo de
   telephone remplirait l'ecran a elle seule. */
.jointe-image {
  display: block;
  max-width: 100%;
  max-height: 260px;
  width: auto;
  border-radius: 4px;
  border: 1px solid var(--edge);
  background: var(--ink);
}

.bulle .jointe + * { margin-top: 8px; }

/* Ce qui ne se regarde pas se nomme, et se telecharge. */
.jointe-nom {
  display: inline-block;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--mist);
  text-decoration: none;
  padding: 8px 10px;
  border-radius: 4px;
  border: 1px solid var(--edge);
  background: var(--ink);
}

a.jointe-nom:hover, a.jointe-nom:focus-visible { border-color: var(--amber); }

/* Une version plus recente attend : assez visible pour qu'on la voie, assez
   discrete pour ne pas couper l'usage. */
.maj-appli {
  margin-top: 6px;
  padding: 9px 12px;
  border-radius: 4px;
  border: 1px solid color-mix(in srgb, var(--amber) 40%, transparent);
  background: color-mix(in srgb, var(--amber) 10%, var(--lacquer));
  color: var(--mist);
}

.maj-appli a { color: var(--amber); }

/* ------------------------------------------------- teintes des bulles */

/* Une seule gamme, deux usages : la bulle prend sa couleur du panneau, qui
   porte le choix. Le texte clair reste lisible sur les six. */
#panel-chat {
  --b-jade:    #1B4A42;
  --b-teal:    #1D3C3E;
  --b-ardoise: #2A3340;
  --b-indigo:  #262C50;
  --b-prune:   #3A2540;
  --b-terre:   #3B2C22;
}

.bulle { background: var(--teinte-autre, #1D3C3E); }
.bulle.moi { background: var(--teinte-moi, #1B4A42); }

#panel-chat[data-moi="jade"]    { --teinte-moi: var(--b-jade); }
#panel-chat[data-moi="teal"]    { --teinte-moi: var(--b-teal); }
#panel-chat[data-moi="ardoise"] { --teinte-moi: var(--b-ardoise); }
#panel-chat[data-moi="indigo"]  { --teinte-moi: var(--b-indigo); }
#panel-chat[data-moi="prune"]   { --teinte-moi: var(--b-prune); }
#panel-chat[data-moi="terre"]   { --teinte-moi: var(--b-terre); }

#panel-chat[data-autre="jade"]    { --teinte-autre: var(--b-jade); }
#panel-chat[data-autre="teal"]    { --teinte-autre: var(--b-teal); }
#panel-chat[data-autre="ardoise"] { --teinte-autre: var(--b-ardoise); }
#panel-chat[data-autre="indigo"]  { --teinte-autre: var(--b-indigo); }
#panel-chat[data-autre="prune"]   { --teinte-autre: var(--b-prune); }
#panel-chat[data-autre="terre"]   { --teinte-autre: var(--b-terre); }

.teintes [data-teinte="jade"]    { background: #1B4A42; }
.teintes [data-teinte="teal"]    { background: #1D3C3E; }
.teintes [data-teinte="ardoise"] { background: #2A3340; }
.teintes [data-teinte="indigo"]  { background: #262C50; }
.teintes [data-teinte="prune"]   { background: #3A2540; }
.teintes [data-teinte="terre"]   { background: #3B2C22; }

.teintes button[aria-pressed="true"] { border-color: var(--amber); }
.teintes button:disabled { opacity: .28; cursor: default; }

/* ------------------------------------------------------- fond du fil */

/* Le fond se pose sur le corps du fil, et sur lui seul : l'en-tete et la
   saisie gardent celui de l'application, ce qui les detache du fil. */
#chat-corps { background: var(--fond-fil, transparent); }

#panel-chat[data-fond="ardoise"] { --fond-fil: transparent; }
#panel-chat[data-fond="encre"]   { --fond-fil: #0A0D10; }
#panel-chat[data-fond="foret"]   { --fond-fil: #0D1E16; }
#panel-chat[data-fond="abysse"]  { --fond-fil: #0A1522; }
#panel-chat[data-fond="prune"]   { --fond-fil: #16101B; }
#panel-chat[data-fond="brique"]  { --fond-fil: #1A1210; }

#chat-corps {
  border-radius: 8px;
  padding-left: 8px;
  padding-right: 8px;
}

.fonds {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 8px 0 4px;
}

.fonds button {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 2px solid var(--edge);
  cursor: pointer;
  padding: 0;
}

.fonds button[aria-pressed="true"] { border-color: var(--amber); }
.fonds button:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

.fonds [data-fond="ardoise"] { background: var(--ink); }
.fonds [data-fond="encre"]   { background: #0A0D10; }
.fonds [data-fond="foret"]   { background: #0D1E16; }
.fonds [data-fond="abysse"]  { background: #0A1522; }
.fonds [data-fond="prune"]   { background: #16101B; }
.fonds [data-fond="brique"]  { background: #1A1210; }

/* ------------------------------------------------------------- salons */

.fils-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Un rang de l'annuaire des salons : le nom, ce dont on y parle, qui le tient,
   et ce qu'on peut en faire. Quatre lignes plutot qu'une, parce qu'un salon se
   choisit sur son sujet, pas sur son nom seul. */
.salon-rang {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 0;
  border-bottom: 1px solid var(--edge);
}

.salon-tete {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.salon-tete strong { font-size: 1.05rem; }

.salon-rang .apercu {
  color: var(--mist);
  opacity: .85;
}

.salon-rang .book-actions {
  display: flex;
  gap: 8px;
  margin-top: 4px;
}

/* Une demande en attente n'est pas une action : elle se lit, elle ne se
   clique pas. */
.salon-attente {
  align-self: center;
  font-style: italic;
}

/* Refuser est le geste qu'on ne veut pas faire par megarde. */
.btn-mini.refus {
  color: var(--coral);
  border-color: color-mix(in srgb, var(--coral) 40%, transparent);
}

/* Le formulaire de creation : encadre, pour qu'on voie qu'il s'agit d'une
   parenthese dans la liste et non d'un ecran de plus. */
.salon-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  margin-bottom: 12px;
  border: 1px solid var(--edge);
  border-radius: 6px;
  background: var(--lacquer);
}

.salon-form input {
  width: 100%;
  font: inherit;
  color: var(--mist);
  background: var(--ink);
  border: 1px solid var(--edge);
  border-radius: 4px;
  padding: 10px 12px;
}

.salon-form input:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: -1px;
}

.salon-form-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

/* La pastille se lit a cote du nom ; l'etat en toutes lettres suit le numero,
   pour qui ne distingue pas les couleurs. */
.fil-ligne {
  display: flex;
  align-items: center;
  gap: 7px;
}

.book-num {
  font-family: var(--mono);
  font-size: 17px;
  font-variant-numeric: tabular-nums;
  letter-spacing: .1em;
  color: var(--amber);
  font-weight: 500;
}

.book-nom {
  flex: 1;
  min-width: 0;
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.book-etat {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
}

/*
 * « en ligne · 12 min » quitte l'en-tete de la conversation sur telephone.
 *
 * La pastille dit deja la presence d'un coup d'oeil ; le detail, lui, ne sert
 * qu'a comparer -- et l'on compare dans l'annuaire, ou les postes sont les uns
 * sous les autres. Dans une conversation, il occupait la ligne du numero sans
 * rien apprendre qu'on ne fut venu chercher.
 *
 * En bureau la largeur ne manque pas : on le garde.
 * L'infobulle de la pastille le porte de toute facon, dans les deux cas.
 */
#chat-etat { display: none; }
body.bureau #chat-etat { display: inline; }

.btn-mini {
  flex: none;
  padding: 7px 11px;
  background: transparent;
  border: 1px solid var(--edge);
  border-radius: 3px;
  color: var(--mist);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  cursor: pointer;
}

.btn-mini:disabled { opacity: .3; cursor: not-allowed; }
.btn-mini:not(:disabled):active { background: var(--edge); }
.btn-mini:focus-visible { outline: 2px solid var(--mist); outline-offset: 2px; }

.btn-mini-danger { border-color: rgba(225, 88, 75, .45); color: #F0968D; }
.btn-mini-danger:not(:disabled):active { background: var(--coral); color: var(--ink); }

/* Droit accorde ou refuse : la teinte porte l'etat, la coche le confirme pour
   qui ne distingue pas les couleurs. */
/* Le numero de version de l'application installee. Discret, mais lisible :
   une mention qu'on ne peut pas lire ne renseigne personne. */
.version-appli {
  margin: -4px 0 12px;
  font-size: .78rem;
  letter-spacing: .04em;
  color: var(--dim);
}

/* ---------------------------------------------------------------- bureau
   Le mode etroit reste la reference : tout ce qui suit ne s'applique qu'a
   partir d'un ecran large, et seulement si l'utilisateur l'a accepte. */

.duo[hidden] { display: none; }

body.bureau .phone { max-width: 1180px; }

/* Le cadre y fait 1180 px : deux cartes seraient des pancartes de 580 px.
   Trois colonnes, et la grille garde des proportions de bouton. */
body.bureau .accueil { grid-template-columns: repeat(3, 1fr); }

body.bureau .duo {
  display: grid;
  grid-template-columns: minmax(280px, 360px) 1fr;
  gap: 22px;
  align-items: start;
}

/* Cote a cote, le fil n'a plus besoin de bouton retour ni d'occuper la
   hauteur d'un ecran entier : la liste reste visible a cote. */
body.bureau #chat-retour { display: none; }

/* Un salon occupe toute la largeur : la liste des conversations PRIVEES n'a
   rien a faire a cote de lui, et la colonne qu'elle laisse ne doit pas rester
   vide. */
body.bureau .duo[data-seul] { grid-template-columns: 1fr; }

/* Et le retour reparait : sans la liste a cote, il n'y a plus d'autre chemin
   vers l'annuaire des salons. */
body.bureau .duo[data-seul] #chat-retour { display: inline-block; }
body.bureau .panel-fil { min-height: 0; }
body.bureau .fil-corps { max-height: 58vh; }

/* Les listes profitent de la largeur, sans que le texte s'etire jusqu'a
   devenir penible a lire. */
body.bureau .book, body.bureau .fils { max-width: none; }
body.bureau .bulle { max-width: 62%; }

.fil-invite { margin: 24px 0; text-align: center; }

/* ---------------------------------------------------------------- messages
   Liste des fils, puis le fil lui-meme. */

.fils { list-style: none; margin: 0; padding: 0; }

.fil-ligne {
  display: flex;
  align-items: baseline;
  gap: 10px;
  width: 100%;
  padding: 12px 4px;
  background: none;
  border: none;
  border-bottom: 1px solid var(--edge);
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: inherit;
}

.fil-ligne:focus-visible { outline: 2px solid var(--amber); outline-offset: -2px; }

/* Le salon se distingue des fils a deux : c'est un lieu, pas un correspondant. */
.fil-ligne.salon .num { color: var(--jade); letter-spacing: .06em; }
.fil-ligne.salon { border-bottom-color: var(--bord-fort, var(--edge)); }

/* Dans un salon, chaque message dit qui parle : sans cela on ne suit plus. */
.bulle .auteur {
  display: block;
  margin-bottom: 3px;
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--amber);
}

/* Cote a cote, on doit voir quelle conversation est ouverte a droite. */
body.bureau .fil-ligne[aria-current="true"] {
  background: var(--lacquer);
  box-shadow: inset 3px 0 0 var(--amber);
}
.fil-ligne:active { background: var(--lacquer); }

.fil-ligne .num {
  flex: none;
  font-family: var(--mono);
  font-size: .92rem;
  letter-spacing: .1em;
  color: var(--amber);
}

.fil-ligne .qui { flex: none; max-width: 34%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.fil-ligne .apercu {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--dim);
  font-size: .88rem;
}

.fil-ligne .quand { flex: none; font-size: .74rem; color: var(--dim); }

.fil-ligne .badge {
  flex: none;
  min-width: 20px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--jade);
  color: var(--ink);
  font-size: .72rem;
  font-weight: 700;
  text-align: center;
}

/* Le fil occupe la hauteur : la saisie reste en bas, le corps defile. */
.panel-fil { display: flex; flex-direction: column; min-height: 60vh; }
.panel-fil[hidden] { display: none; }

.fils-tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

/* Effacer est irreversible pour celui qui le fait : le bouton ne doit pas
   attirer l'oeil comme une action ordinaire, mais rester trouvable. */
#chat-vider, #chats-vider {
  color: var(--coral);
  border-color: color-mix(in srgb, var(--coral) 40%, transparent);
}

/* Sans bandeau au centre, c'est la bulle qui doit dire l'urgence. */
.bulle.urgente {
  border-left: 3px solid var(--coral);
  background: color-mix(in srgb, var(--coral) 12%, var(--lacquer));
}

.fil-tete {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--edge);
}

.fil-qui { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.fil-qui strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fil-num { font-family: var(--mono); font-size: .8rem; letter-spacing: .12em; color: var(--dim); }

.fil-plus { align-self: center; margin: 10px 0 0; }

.fil-corps {
  flex: 1;
  overflow-y: auto;
  /* Un plancher, et pas seulement un plafond : sans lui le fil ne fait que la
     hauteur de ses messages, et l ecran reste vide en dessous — c est ce qui
     annulait la place gagnee en escamotant les onglets. */
  /* Releve de 55 a 62vh le jour ou l'en-tete est passe de deux etages a un :
     les 48 px rendus allaient a la marge du bas, pas a la conversation. Le
     plafond reste a 68vh -- sur telephone, vh compte le viewport large, celui
     qu'on a barre d'adresse repliee, et coller au plafond ferait deborder la
     page des qu'elle se deploie. */
  min-height: 62vh;
  max-height: 68vh;
  display: flex;
  flex-direction: column;
  /* Serre : deux messages d'un meme auteur se touchent presque, et c'est la
     marge de « .bulle:not(.suite) » qui separe les prises de parole. */
  gap: 2px;
  padding: 12px 2px;
}

/* Une bulle epouse son contenu : « Ok » ne doit pas occuper les trois quarts de
   l'ecran. Sans « align-self », un enfant de colonne flex s'etire — c'est ce qui
   donnait a toutes les bulles recues la meme largeur, quelle que soit leur
   longueur. */
.bulle {
  align-self: flex-start;
  max-width: 78%;
  padding: 7px 11px 6px;
  /* Le coin du cote de celui qui parle est ecourte : la bulle pointe vers lui
     sans avoir besoin d'une queue dessinee. */
  border-radius: 14px 14px 14px 4px;
  white-space: normal;
  line-height: 1.45;
  font-size: .95rem;

  /* L'heure vient se ranger a la suite du texte quand la place le permet, et
     passe a la ligne sinon. C'est ce qui donne aux messages courts leur allure
     ramassee. */
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  column-gap: 8px;
  row-gap: 1px;
}

.bulle .dit {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  min-width: 0;
}

/* Les siens a droite, ceux d'en face a gauche : on lit le sens sans legende. */
.bulle.moi {
  align-self: flex-end;
  border-radius: 14px 14px 4px 14px;
}

/* Deux messages d'affilee du meme auteur : le coin se rearrondit, le groupe se
   lit comme une seule prise de parole. */
.bulle.suite { border-top-left-radius: 6px; }
.bulle.moi.suite { border-top-left-radius: 14px; border-top-right-radius: 6px; }

/* La marge separe les prises de parole, pas les messages : c'est elle qui fait
   respirer le fil, tandis que le « gap » serre l'interieur d'un groupe. */
.bulle:not(.suite) { margin-top: 8px; }
.fil-corps > .bulle:first-child { margin-top: 0; }

.bulle .pied {
  margin-left: auto;
  font-size: .68rem;
  line-height: 1;
  padding-bottom: 1px;
  /* Le fond des bulles ayant ete eclairci, « --dim » tombait a 3,8 de contraste
     — sous le seuil de lisibilite d un petit texte. */
  color: rgba(214, 228, 225, .68);
  white-space: nowrap;
  flex: none;
}
.bulle.moi .pied .lu { color: var(--jade); }

/* Ce qui doit occuper toute la largeur de la bulle, et non se ranger en ligne. */
.bulle .auteur, .bulle .jointe { flex: 1 0 100%; }

/* Dans un groupe, le nom ne se dit qu une fois : le repeter a chaque bulle
   alourdit sans rien apprendre. */
.bulle.suite .auteur { display: none; }

.fil-saisie {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--edge);
}

/* Le champ et ses icones ne forment qu'un seul objet : c'est ce qui rend au
   texte la largeur que trois boutons alignes lui prenaient. */
.fil-pilule {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: flex-end;
  gap: 0;
  background: var(--ink);
  border: 1px solid var(--edge);
  border-radius: 22px;
  padding: 0 4px 0 14px;
}

.fil-pilule:focus-within { border-color: var(--amber); }

.fil-saisie textarea {
  flex: 1;
  min-width: 0;
  /* Une seule ligne au repos, qui grandit avec le texte jusqu'a une borne :
     deux lignes reservees d'avance coutaient de la hauteur pour rien. */
  resize: none;
  height: 40px;
  max-height: 120px;
  overflow-y: auto;
  font: inherit;
  font-size: .95rem;
  line-height: 1.45;
  color: var(--mist);
  background: none;
  border: none;
  padding: 10px 0;
}

.fil-saisie textarea:focus-visible { outline: none; }

.fil-icone {
  flex: none;
  background: none;
  border: none;
  color: var(--mist);
  font-size: 16px;
  line-height: 1;
  padding: 11px 7px;
  cursor: pointer;
  border-radius: 50%;
}

.fil-icone:hover:not(:disabled) { background: rgba(214, 228, 225, .08); }
.fil-icone:disabled { opacity: .4; cursor: default; }
.fil-icone:focus-visible { outline: 2px solid var(--amber); outline-offset: -2px; }

/* Rond, plein, seul a droite : on sait ou l'on appuie sans lire. */
.fil-envoi {
  flex: none;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: none;
  background: var(--jade);
  color: var(--ink);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}

.fil-envoi:disabled { opacity: .45; cursor: default; }
.fil-envoi:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

.fil-aide { margin: 6px 0 0; }

/* Sur un ecran tactile, le clavier a sa propre touche d'envoi : le rappel de
   Ctrl+Entree n'y apprend rien et coutait une ligne entiere. */
@media (pointer: coarse) {
  .fil-aide { display: none; }
}

/* Etat des trois maillons d'une notification. */
.diagnostic {
  list-style: none;
  margin: 6px 0 16px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: .85rem;
}

.diagnostic li {
  display: flex;
  align-items: baseline;
  gap: 8px;
  color: var(--dim);
}

.diagnostic .marque { flex: none; font-size: .9em; }
.diagnostic .bon .marque { color: var(--jade); }
.diagnostic .mauvais .marque { color: var(--coral); }
.diagnostic .bon { color: var(--mist); }

/* Une preference : la case, puis le libelle et son explication. */
.pref {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 0;
  cursor: pointer;
}

.pref input[type="checkbox"] {
  flex: none;
  width: 20px;
  height: 20px;
  margin-top: 2px;
  accent-color: var(--jade);
}

.pref-texte { display: flex; flex-direction: column; gap: 4px; }
.pref-texte strong { font-weight: 600; color: var(--mist); }
.pref-texte .hint { margin: 0; }

/* Les retours a la ligne d'un message doivent se voir. */
#toast-texte, .msg-multi { white-space: pre-wrap; }

.msg-champ, #toast-champ {
  resize: vertical;
  min-height: 62px;
  line-height: 1.5;
}

/* Repondre depuis le bandeau : le bouton ouvre la conversation. */
.toast-repondre { display: none; }
.toast.important .toast-repondre { display: inline-block; align-self: flex-start; }

/* Favori : une etoile qui se remplit. Discrete tant qu'elle est vide, pour ne
   pas parasiter la lecture d'un annuaire ou peu de lignes sont marquees. */
.book-etoile {
  flex: none;
  background: none;
  border: none;
  padding: 2px 4px;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  color: var(--dim);
  opacity: .45;
}

.book-etoile.marque { color: var(--amber); opacity: 1; }
.book-etoile:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

/* Sortie audio : dans l'application, un rang de boutons plutot qu'une liste. */
.sortie-seg { width: 100%; }
.sortie-seg .seg-btn { flex: 1 1 0; min-width: 0; }

/* Diffusion d'un message a plusieurs postes. */
.diffusion {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 18px;
}

.diffusion textarea {
  width: 100%;
  resize: vertical;
  min-height: 68px;
  font: inherit;
  font-size: .95rem;
  line-height: 1.5;
  color: var(--mist);
  background: var(--ink);
  border: 1px solid var(--edge);
  border-radius: 4px;
  padding: 10px 12px;
}

.diffusion textarea:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: -1px;
}

/* Case de selection dans l'annuaire, en mode administrateur. */
.book-choix {
  flex: none;
  width: 18px;
  height: 18px;
  margin-right: 2px;
  accent-color: var(--jade);
}

.btn-mini.droit { border-color: rgba(124, 152, 149, .3); color: var(--dim); }
.btn-mini.droit.accorde { border-color: rgba(70, 201, 154, .5); color: var(--jade); }
.btn-mini.droit:not(:disabled):active { background: var(--edge); }

/* Poste fermé mais abonné aux notifications : joignable malgré tout, donc ni
   la pastille verte des présents, ni le gris des injoignables. */
.dot[data-etat="notifiable"] {
  background: transparent;
  box-shadow: inset 0 0 0 2px var(--jade);
}

/* ------------------------------------------------------------- réglages */
.reglages {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-bottom: 18px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--edge);
}

.reglage {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
}

.reglage > span:first-child { color: var(--mist); }

.reglage em {
  font-style: normal;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
}

/* L'état du code est cliquable : c'est par là qu'on le retire. */
#rg-code-etat { cursor: pointer; text-decoration: underline dotted; }

.reglage-champ {
  flex: none;
  display: flex;
  align-items: baseline;
  gap: 6px;
}

.reglage-champ input {
  width: 96px;
  padding: 8px 10px;
  font-size: 14px;
  text-align: right;
}

.reglage-champ input[type="text"],
.reglage-champ input[type="password"] {
  width: 150px;
  text-align: left;
}

#rg-etat:empty { display: none; }

/* --------------------------------------------------------------- journal */
.badge {
  display: inline-block;
  min-width: 16px;
  padding: 1px 4px;
  margin-left: 4px;
  border-radius: 8px;
  background: var(--coral);
  color: var(--ink);
  font-size: 9px;
  font-weight: 700;
  line-height: 14px;
  text-align: center;
  vertical-align: middle;
}

.log-sens {
  flex: none;
  font-size: 15px;
  line-height: 1;
  color: var(--dim);
}

.log-manque .log-sens,
.log-manque .book-num { color: var(--coral); }

.log-quand {
  flex: none;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: .08em;
  color: var(--dim);
}

/* Sur écran étroit, la durée cède la place : l'heure et le nom priment. */
@media (max-width: 380px) {
  .log-row .book-etat { display: none; }
}

/* ------------------------------------------------------------ interphone */
.panel-diff, .panel-ecoute { gap: 16px; }

.panel-ecoute {
  align-items: center;
  padding: 26px 16px;
  background: var(--lacquer);
  border: 1px solid var(--jade);
  border-radius: 3px;
  text-align: center;
}

.panel-ecoute .caller-number { animation: none; color: var(--jade); }
.panel-ecoute .key-end, .panel-diff .key-end { width: 100%; }
.panel-diff .book-row { padding: 9px 12px; }

/* Un poste qui diffuse : ni libre, ni simplement occupé. */
.dot[data-etat="diffusion"] {
  background: var(--jade);
  box-shadow: 0 0 0 3px rgba(70, 201, 154, .28);
}

/* ---------------------------------------------------------- sortie audio */
.sortie {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: -8px;
}

.sortie select {
  padding: 9px 11px;
  background: var(--lacquer);
  border: 1px solid var(--edge);
  border-radius: 3px;
  color: var(--mist);
  font-family: var(--sans);
  font-size: 13px;
}

.sortie select:focus-visible { outline: 2px solid var(--amber); outline-offset: 1px; }

/* ------------------------------------------------------------ conférence */
.panel-conf { gap: 20px; }
.panel-conf .meters { gap: 12px; }
.panel-conf .bars { height: 30px; }
.panel-conf .meter-self .bars { height: 26px; }

/* Un poste en conférence : ni libre, ni en tête-à-tête. */
.dot[data-etat="conference"] {
  background: var(--amber);
  box-shadow: 0 0 0 3px rgba(233, 179, 65, .25);
}

/* =========================================================================
   Annuaire et journal : mise en page revue
   Le tri tient sur la meme ligne que le filtre, et les actions descendent sur
   leur propre bande — elles debordaient de l'ecran sur mobile.
   ========================================================================= */

.book-tools {
  align-items: center;
  gap: 8px;
}

.tri-select {
  flex: 1;
  min-width: 0;
  padding: 9px 10px;
  background: var(--lacquer);
  border: 1px solid var(--edge);
  border-radius: 3px;
  color: var(--mist);
  font-family: var(--sans);
  font-size: 13px;
}

.tri-select:focus-visible { outline: 2px solid var(--amber); outline-offset: 1px; }

/* Deux etages : identite au-dessus, actions en dessous. En administration
   seulement -- ailleurs la ligne tient sur un seul etage. */
.book-row {
  flex-wrap: wrap;
  row-gap: 9px;
}

/* Toute la ligne s'actionne : elle doit le dire, au survol comme au clavier. */
.book-row[data-ouvrir] { cursor: pointer; }
.book-row[data-ouvrir]:hover { border-color: var(--jade); }
.book-row[data-ouvrir]:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 2px;
}

/*
 * Le nom ne reclame plus sa largeur de contenu.
 *
 * « auto » la lui rendait, et c'est sur cette largeur que le navigateur decide
 * des retours a la ligne : un nom un peu long poussait l'etat a l'etage du
 * dessous -- trois lignes sur trente a 360 px. La regle datait de la mise en
 * page a deux etages, quand chaque poste portait ses boutons.
 *
 * Avec une base nulle (le « flex: 1 » de .book-nom), le nom prend ce qui reste
 * et se coupe d'un point de suspension s'il le faut. La ligne tient sur un
 * etage, et l'etat reste lisible a cote du nom.
 */
.book-row .book-nom { min-width: 0; }

/* La bande d'actions prend toute la largeur et pousse ses boutons a droite. */
.book-actions {
  flex: 1 0 100%;
  display: flex;
  /* Six actions ne tiennent plus sur une ligne de telephone : l'annuaire
     d'administration en compte autant depuis que « Salons » s'y ajoute, et
     sans cela c'est la page entiere qui defilait de cote (488 px pour 430). */
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 7px;
}

.book-actions .btn-mini { flex: 0 0 auto; }

/* Le journal : l'heure reste a gauche de ses actions. */
.log-row .log-quand { order: 5; }

@media (max-width: 380px) {
  /* L'administration garde ses six actions : elles, se serrent encore. */
  .book-actions .btn-mini { padding: 7px 9px; }
}

/* ---------------------------------------------------------- messages texte */
.toast {
  position: fixed;
  left: 50%;
  top: 12px;
  transform: translateX(-50%);
  z-index: 20;
  width: min(420px, calc(100vw - 24px));
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  background: var(--lacquer);
  border: 1px solid var(--jade);
  border-radius: 4px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, .45);
}

/* Un message recu ne doit pas se confondre avec un accuse d'envoi : il vient
   au centre de l'ecran, plus grand, et l'ombre demesuree fait office de voile
   sans ajouter d'element — une ombre ne capte pas les clics, l'application
   reste donc utilisable dessous. */
.toast.important {
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(460px, calc(100vw - 32px));
  flex-direction: column;
  gap: 8px;
  padding: 18px 20px;
  border-left: 4px solid var(--amber);
  border-radius: 8px;
  box-shadow: 0 0 0 100vmax rgba(8, 25, 26, .62), 0 18px 48px rgba(0, 0, 0, .6);
  animation: toast-parait .2s ease-out;
}

@keyframes toast-parait {
  from { opacity: 0; transform: translate(-50%, -46%); }
  to   { opacity: 1; transform: translate(-50%, -50%); }
}

@media (prefers-reduced-motion: reduce) {
  .toast.important { animation: none; }
}

.toast.important strong {
  max-width: none;
  font-size: 11px;
  color: var(--amber);
}

.toast.important span {
  font-size: 1.05rem;
  line-height: 1.55;
}

/* En pile, le bouton de fermeture tombait sous le texte, ou on ne le cherche
   pas. Il reprend sa place au coin, la ou on ferme les choses. */
.toast.important {
  position: fixed;
  padding-right: 44px;
}

/* Le bouton de fermeture seulement : viser tous les boutons du bandeau
   collait aussi ceux de la reponse dans le coin, les uns sur les autres. */
#toast-fermer { position: static; }

.toast.important > #toast-fermer {
  position: absolute;
  top: 12px;
  right: 12px;
}

.toast strong {
  flex: none;
  max-width: 45%;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--jade);
  line-height: 1.5;
}

.toast span {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  line-height: 1.5;
  word-break: break-word;
}

.toast button {
  flex: none;
  padding: 0 2px;
  background: transparent;
  border: 0;
  color: var(--dim);
  font-size: 13px;
  cursor: pointer;
}

/* Saisie d'un message sur sa propre bande, sous la ligne du poste. */
.msg-zone {
  flex: 1 0 100%;
  display: flex;
  gap: 7px;
  margin-top: 2px;
}

.msg-champ {
  flex: 1;
  min-width: 0;
  padding: 8px 10px;
  font-size: 14px;
}

/* =========================================================================
   Règles réintroduites : une réécriture précédente du fichier les avait
   emportées. Elles restaient indispensables aux filtres, au cadenas et à
   l'édition des noms.
   ========================================================================= */

.book-tools { display: flex; }

.seg {
  flex: none;
  display: flex;
  border: 1px solid var(--edge);
  border-radius: 3px;
  overflow: hidden;
}

.seg-btn {
  padding: 9px 12px;
  background: transparent;
  border: 0;
  color: var(--dim);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
}

.seg-btn + .seg-btn { border-left: 1px solid var(--edge); }
.seg-btn[aria-pressed="true"] { background: var(--edge); color: var(--mist); }
.seg-btn:focus-visible { outline: 2px solid var(--amber); outline-offset: -2px; }

.book-count {
  margin: 0;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--dim);
}

.book-nom-editable {
  cursor: text;
  text-decoration: underline dotted var(--edge);
  text-underline-offset: 3px;
}

.book-nom-champ {
  flex: 1 1 auto;
  min-width: 0;
  padding: 5px 8px;
  font-size: 14px;
}

.cadenas {
  flex: none;
  padding: 2px 4px;
  background: transparent;
  border: 0;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  opacity: .5;
}

.cadenas.ferme { opacity: 1; }
.cadenas:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

/* Sur écran étroit, les libellés du segment se resserrent plutôt que de
   pousser le tri à la ligne suivante. */
@media (max-width: 380px) {
  .seg-btn { padding: 9px 9px; letter-spacing: .06em; }
}

/* L'etat de la liaison, au bas de l'accueil. Discret : on ne le cherche pas,
   on tombe dessus quand on cherche pourquoi un appel n'aboutit pas. */
.liaison {
  margin-top: 4px;
  padding-top: 12px;
  border-top: 1px solid var(--edge);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #4C6D6B;
}

/* ------------------------------------------------------- messages vocaux */

/* Pendant l'enregistrement, la pilule s'efface : il n'y a plus qu'a parler,
   puis a trancher. Meme hauteur que la pilule, pour que rien ne saute. */
.fil-dictee {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 9px;
  min-height: 40px;
  padding: 5px 12px;
  background: var(--lacquer);
  border: 1px solid var(--coral);
  border-radius: 20px;
}

/* Le point qui bat : c'est lui qui dit que le micro est ouvert, sans avoir a
   le lire. */
.dictee-point {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--coral);
  animation: bat 1.2s ease-in-out infinite;
}

@keyframes bat {
  0%, 100% { opacity: 1; }
  50%      { opacity: .25; }
}

@media (prefers-reduced-motion: reduce) {
  .dictee-point { animation: none; }
}

.dictee-duree {
  flex: none;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: 14px;
  color: var(--text);
}

/* L'aide cede la place la premiere : sur un ecran etroit, la duree et les deux
   decisions valent mieux qu'un mot. */
.dictee-aide {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 11px;
  color: var(--dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fil-dictee .btn-mini { flex: none; padding: 6px 10px; }
.dictee-annuler { color: var(--dim); }
.dictee-envoyer { border-color: rgba(70, 201, 154, .45); color: var(--jade); }

/* Le lecteur, dans la bulle. Il prend la largeur qu'on lui laisse plutot que
   celle qu'il reclame : sans cela, il debordait de la bulle sur un telephone. */
.jointe-voix {
  display: block;
  width: 100%;
  max-width: 232px;
  min-width: 180px;
  height: 36px;
}

/* ------------------------------------------------------------- traduction */

/* Discret dans la bulle : c'est une offre, pas une action qu'on reclame. */
.traduire {
  align-self: flex-start;
  margin-top: 2px;
  padding: 0;
  background: none;
  border: 0;
  color: var(--jade);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  cursor: pointer;
}

.traduire:disabled { color: var(--dim); cursor: default; }
.traduire:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

/* La traduction se pose SOUS l'original, separee d'un filet : on voit d'un
   coup d'oeil ce qui a ete ecrit et ce qu'on en comprend. L'original ne
   disparait jamais. */
.traduit {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid rgba(255, 255, 255, .12);
}

.traduit-source {
  display: block;
  margin-bottom: 2px;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
}

.traduit-texte {
  display: block;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-style: italic;
  color: var(--mist);
}

/* Elle a sa place sur la ligne, a cote de la duree — jamais dedans : le
   journal masque « .book-etat » sous 380 px, et la liaison y disparaissait
   avec elle, sur le telephone justement ou l'on vient la lire. */
.log-row .log-liaison { flex: none; }

/* Le chemin qu'a pris la voix. Le direct en jade, le relais en ambre : ce
   n'est pas une faute, mais c'est la que la latence se paie — et c'est
   justement ce qu'on vient chercher dans ce journal. */
.log-liaison {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--jade);
}

.log-liaison.relais { color: var(--amber); }

/* Le micro occupe la meme case que l'envoi : meme taille, meme rondeur, pour
   que la bascule ne fasse pas sauter la ligne. */
.fil-micro { font-size: 17px; }

/*
 * Le choix photo/video/fichier, dans l'application Android seulement.
 *
 * Il prend la PLACE de la pilule, il ne s'ajoute pas dessous. Depliee sous la
 * ligne de saisie, cette barre allongeait le panneau d'une hauteur entiere :
 * il depassait l'ecran, et une barre de defilement paraissait — desagreable,
 * et pour rien.
 *
 * Meme hauteur et meme rondeur que la pilule qu'elle remplace : la ligne ne
 * saute pas quand on ouvre le choix, ni quand on le referme.
 */
.fil-choix {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  /* 42 px : exactement la hauteur de la pilule au repos, mesuree. A 40, la
     ligne bougeait de deux pixels en ouvrant le choix. */
  min-height: 42px;
  padding: 4px 8px;
  background: var(--ink);
  border: 1px solid var(--edge);
  border-radius: 22px;
}

/* Les libelles se coupent avant de deborder : quatre boutons sur un ecran de
   360 px, cela se joue a quelques pixels. */
.fil-choix .btn-mini {
  flex: 0 1 auto;
  min-width: 0;
  padding: 6px 9px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fil-choix .choix-annuler {
  flex: none;
  margin-left: auto;
  color: var(--dim);
}

/* La video dans la bulle : elle prend la largeur qu'on lui laisse, jamais
   celle qu'elle reclame — une video de telephone fait 1080 de large. */
.jointe-film {
  display: block;
  width: 100%;
  max-width: 232px;
  max-height: 300px;
  border-radius: 3px;
  background: #000;
}

/* ------------------------------------------------------------ visionneuse */

/* Par-dessus tout, et cadree a l'ecran : l'image debordait dans
   l'application, au point qu'il n'y avait plus rien d'autre a toucher. */
.visionneuse {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 16px;
  /* Assez opaque pour que l'image se detache, assez sombre pour qu'on
     comprenne que le fond se touche pour fermer. */
  background: rgba(4, 10, 12, .94);
}

.visionneuse img {
  max-width: 100%;
  /* Le bouton et le lien gardent leur place : sans cette reserve, une image
     haute les poussait hors de l'ecran — et l'on retombait sur le probleme
     qu'on vient de corriger. */
  max-height: calc(100vh - 130px);
  object-fit: contain;
  border-radius: 3px;
}

.visionneuse-fermer {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 40px;
  height: 40px;
  background: var(--lacquer);
  border: 1px solid var(--edge);
  border-radius: 50%;
  color: var(--text);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
}

.visionneuse-fermer:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

.visionneuse-lien {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--amber);
  text-decoration: none;
  border-bottom: 1px solid rgba(233, 179, 65, .4);
}
