Le fil ne passe plus sous la carte de saisie

Sur écran large, la fin de la conversation était recouverte par la carte de
saisie et aucun défilement ne la ramenait : le fil réservait 8 px sous lui
là où le composeur en occupe ~160.

styles.css réservait bien la hauteur (#chat{padding-bottom:170px}), mais deux
règles POSTÉRIEURES dans la feuille — ajoutées par le redesign « Terre » puis
par le correctif de largeur de lecture — réécrivaient `padding` en raccourci
sous @media (min-width:721px), ce qui remet padding-bottom à la valeur du
raccourci. Sous 721 px la règle en raccourci est déclarée AVANT, d'où un bug
invisible sur mobile. Ces règles passent en longhands (padding-top +
padding-inline), et un commentaire dit pourquoi le raccourci est proscrit ici.

La réserve devient mesurée au lieu d'être devinée : syncComposer() publie
--composer-h (hauteur réelle du composeur) via un ResizeObserver, à côté de
syncGutter() qui fait déjà ce travail pour --sbw. Une constante redevenait
fausse dès que la saisie grandit ou qu'une pièce jointe s'affiche. Le
scrollbtn suit la même variable. env(safe-area-inset-bottom) disparaît du
calcul : il est déjà dans la hauteur mesurée, le compter deux fois creusait
un trou en PWA iOS.

Le voile de fondu au-dessus de la carte s'exprimait en % de la hauteur TOTALE
du composeur : l'opacité pleine tombait sous le bord haut de la carte, et le
texte restait lisible au ras du bord — l'impression de « passer derrière ».
Une variable --fade pilote désormais la bande réservée ET la course du
dégradé, qui devient donc opaque exactement au bord de la carte.

Mesuré au navigateur, du 380 px au 2000 px, au repos / saisie 10 lignes /
pièce jointe en attente : écart de 46 à 52 px partout. En réinjectant
l'ancienne règle : -119 px, bug reproduit. La largeur de lecture est
inchangée (1080 px de contenu à 2000 px de fenêtre).

Barre latérale : la discussion sélectionnée porte un cadre sauge complet et
fin (1 px) au lieu d'un liseré de 3 px sur le seul bord gauche. La bordure
transparente est portée par tous les états, la sélection ne décale donc pas
le contenu.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VueWA9xcYadaYq65tBisix
This commit is contained in:
Claude committed 2026-08-16 09:09:38 +00:00
1 parent 3740b881a8
commit 1fa8452e44
3 files changed
+100 -26

No files matched your search

+50 -13
View File
@@ -1031,8 +1031,13 @@ h1{color:var(--text);font-weight:600;letter-spacing:-.01em}
/* Barre latérale : plus sombre/atténuée que la zone de conversation. */ /* Barre latérale : plus sombre/atténuée que la zone de conversation. */
.side{background:var(--panel);border-right-color:transparent} .side{background:var(--panel);border-right-color:transparent}
@media (max-width:720px){.side{background:var(--panel)}} @media (max-width:720px){.side{background:var(--panel)}}
/* Colonne de lecture centrée (comme le fil ChatGPT), pleine largeur sur mobile. */ /* Colonne de lecture centrée (comme le fil ChatGPT), pleine largeur sur mobile.
#chat{padding:28px max(16px,calc(50% - 380px)) 8px;gap:22px;scrollbar-gutter:stable both-edges} ⚠️ JAMAIS le raccourci `padding` ici : le rembourrage BAS réserve la hauteur
de la carte de saisie (voir #chat plus bas) et il est réglé ailleurs. Une
règle en raccourci le remet silencieusement à sa valeur du raccourci — c'est
exactement ce qui, jusqu'à ce correctif, laissait la fin du fil coincée sous
la carte au-delà de 721 px de large. Longhands uniquement. */
#chat{padding-top:28px;padding-inline:max(16px,calc(50% - 380px));gap:22px;scrollbar-gutter:stable both-edges}
/* Réponses de l'assistant : pas de cadre, pas de fond — juste du texte. */ /* Réponses de l'assistant : pas de cadre, pas de fond — juste du texte. */
#chat .msg.assistant{background:transparent;border:none;padding:0;max-width:100%;line-height:1.7} #chat .msg.assistant{background:transparent;border:none;padding:0;max-width:100%;line-height:1.7}
/* Question : pastille arrondie à droite, texte lisible sur fond clair OU sombre. */ /* Question : pastille arrondie à droite, texte lisible sur fond clair OU sombre. */
@@ -1078,9 +1083,21 @@ html[data-hide-stats="1"] #chat .msg .statline{display:none}
/* Le padding BAS dégage l'indicateur d'accueil de l'iPhone en PWA : la carte /* Le padding BAS dégage l'indicateur d'accueil de l'iPhone en PWA : la carte
flotte au-dessus de lui, son arrondi bas reste donc bien visible. Hors PWA flotte au-dessus de lui, son arrondi bas reste donc bien visible. Hors PWA
l'inset vaut 0 → strictement les 8 px d'origine. */ l'inset vaut 0 → strictement les 8 px d'origine. */
#composer{position:absolute;left:0;right:0;bottom:0;z-index:4;border-top:none;display:flex;flex-direction:column;padding:34px 0 calc(8px + env(safe-area-inset-bottom));--col:calc(max(16px,calc(50% - 380px)) + var(--sbw,0px));background:linear-gradient(to bottom,transparent 0,var(--bg) 34%)} /* --fade = la bande transparente au-dessus de la carte, celle où le fil doit
#chat{padding-bottom:calc(170px + env(safe-area-inset-bottom))} s'effacer. Le dégradé s'exprime dans la MÊME unité (et non en % de la hauteur
#scrollbtn{bottom:calc(180px + env(safe-area-inset-bottom));border-radius:999px} totale du composeur, qui varie) : l'opacité est donc pleine exactement au bord
haut de la carte. Avec un %, le fondu finissait SOUS ce bord et le texte
restait lisible au ras de la carte — l'impression de « passer derrière ». */
#composer{position:absolute;left:0;right:0;bottom:0;z-index:4;border-top:none;display:flex;flex-direction:column;--fade:34px;padding:var(--fade) 0 calc(8px + env(safe-area-inset-bottom));--col:calc(max(16px,calc(50% - 380px)) + var(--sbw,0px));background:linear-gradient(to bottom,transparent 0,var(--bg) var(--fade))}
/* Réserve sous le fil = hauteur RÉELLE du composeur, mesurée et publiée par
syncComposer() (08-chat-render.js). Une constante redevient fausse dès que la
saisie grandit ou qu'une pièce jointe s'affiche, et la fin du fil repasse hors
d'atteinte. 170px n'est que le repli du tout premier rendu, avant mesure.
Pas de env(safe-area-inset-bottom) ici : il est déjà DANS le padding bas du
composeur, donc dans sa hauteur mesurée — le compter deux fois creusait un
trou en PWA iOS. */
#chat{padding-bottom:calc(var(--composer-h,170px) + 12px)}
#scrollbtn{bottom:calc(var(--composer-h,170px) + 10px);border-radius:999px}
#inputbar{order:1;margin:0 var(--col);padding:8px 8px 8px 16px;gap:8px;align-items:flex-end;background:var(--panel);border:1px solid var(--border);border-bottom:none;border-radius:26px 26px 0 0} #inputbar{order:1;margin:0 var(--col);padding:8px 8px 8px 16px;gap:8px;align-items:flex-end;background:var(--panel);border:1px solid var(--border);border-bottom:none;border-radius:26px 26px 0 0}
#input{background:transparent;border:none;border-radius:0;padding:9px 0;min-height:36px;line-height:18px;max-height:160px} #input{background:transparent;border:none;border-radius:0;padding:9px 0;min-height:36px;line-height:18px;max-height:160px}
/* Pas de cadre qui s'assombrit au focus : la carte garde exactement la même /* Pas de cadre qui s'assombrit au focus : la carte garde exactement la même
@@ -1147,7 +1164,7 @@ html[data-hide-stats="1"] #chat .msg .statline{display:none}
overflow-x:auto;scrollbar-width:none} overflow-x:auto;scrollbar-width:none}
#attach-list::-webkit-scrollbar{display:none} #attach-list::-webkit-scrollbar{display:none}
#attach-list.show{display:flex} #attach-list.show{display:flex}
#composer:has(#attach-list.show){padding-top:6px} #composer:has(#attach-list.show){--fade:6px}
/* Posées sur le fil (et non sur la carte) : il leur faut un fond opaque et un /* Posées sur le fil (et non sur la carte) : il leur faut un fond opaque et un
cadre, sinon le texte de la conversation transparaît derrière. */ cadre, sinon le texte de la conversation transparaît derrière. */
#attach-list .chip-file{flex:0 0 auto;background:var(--panel);border-color:var(--border); #attach-list .chip-file{flex:0 0 auto;background:var(--panel);border-color:var(--border);
@@ -1296,10 +1313,10 @@ button:hover{border-color:var(--dim);color:var(--text)}
/* Colonne principale : une seule grande carte qui contient fil et saisie. */ /* Colonne principale : une seule grande carte qui contient fil et saisie. */
.main{background:var(--panel);border-radius:20px;box-shadow:var(--shadow);overflow:hidden} .main{background:var(--panel);border-radius:20px;box-shadow:var(--shadow);overflow:hidden}
#chat{padding:26px max(20px,calc(50% - 360px)) 8px} #chat{padding-top:26px;padding-inline:max(20px,calc(50% - 360px))}
/* Le dégradé qui fait disparaître le fil sous la carte de saisie doit fondre /* Le dégradé qui fait disparaître le fil sous la carte de saisie doit fondre
vers le PANNEAU, pas vers le fond de la coque. */ vers le PANNEAU, pas vers le fond de la coque. */
#composer{background:linear-gradient(to bottom,transparent 0,var(--panel) 34%)} #composer{background:linear-gradient(to bottom,transparent 0,var(--panel) var(--fade))}
/* Carte de saisie : posée SUR le panneau, donc un ton au-dessus, et sans /* Carte de saisie : posée SUR le panneau, donc un ton au-dessus, et sans
bordure — c'est l'élévation qui la détache. */ bordure — c'est l'élévation qui la détache. */
#inputbar,#ctxmeta{background:var(--row-bg-on);border-color:transparent} #inputbar,#ctxmeta{background:var(--row-bg-on);border-color:transparent}
@@ -1313,10 +1330,12 @@ button:hover{border-color:var(--dim);color:var(--text)}
.side{gap:8px} .side{gap:8px}
.side>details>summary{height:38px} .side>details>summary{height:38px}
/* Discussion active : un LISERÉ sauge à gauche, pas un cadre complet — c'est /* Discussion active : un cadre sauge COMPLET, mais fin (1 px) — le liseré de
la marque de sélection de la charte, et elle se lit sans alourdir. */ 3 px sur le seul bord gauche se lisait mal et déséquilibrait la ligne. La
.side .preset{border:0;border-left:3px solid transparent;border-radius:14px;background:transparent} bordure transparente est portée par tous les états : la sélection ne décale
.side .preset.active{background:var(--row-bg-on);border-left-color:var(--accent)} donc pas le contenu d'un pixel. */
.side .preset{border:1px solid transparent;border-radius:14px;background:transparent}
.side .preset.active{background:var(--row-bg-on);border-color:var(--accent)}
.side .preset:hover{background:var(--row-bg)} .side .preset:hover{background:var(--row-bg)}
/* Bulle de question : coin bas-droit rentré, comme une bulle qui pointe vers /* Bulle de question : coin bas-droit rentré, comme une bulle qui pointe vers
@@ -1341,7 +1360,7 @@ button:hover{border-color:var(--dim);color:var(--text)}
le début de la suivante). 1080 px ≈ 110 caractères, large mais tenable. */ le début de la suivante). 1080 px ≈ 110 caractères, large mais tenable. */
@media (min-width:721px){ @media (min-width:721px){
:root{--measure:min(1080px,100%)} :root{--measure:min(1080px,100%)}
#chat{padding:26px max(20px,calc(50% - var(--measure)/2)) 8px} #chat{padding-top:26px;padding-inline:max(20px,calc(50% - var(--measure)/2))}
#composer{--col:calc(max(20px,calc(50% - var(--measure)/2)) + var(--sbw,0px))} #composer{--col:calc(max(20px,calc(50% - var(--measure)/2)) + var(--sbw,0px))}
} }
@@ -4177,8 +4196,26 @@ function syncGutter(){
const g=Math.max(0,(chat.offsetWidth-chat.clientWidth)/2); const g=Math.max(0,(chat.offsetWidth-chat.clientWidth)/2);
document.documentElement.style.setProperty('--sbw', g+'px'); document.documentElement.style.setProperty('--sbw', g+'px');
} }
// La carte de saisie flotte AU-DESSUS du fil (position:absolute) : c'est au fil
// de réserver sa hauteur en rembourrage bas, sinon ses derniers messages passent
// dessous et deviennent hors d'atteinte — aucun défilement ne les ramène.
// Cette hauteur n'est pas constante : la saisie grandit avec le texte (autoGrow),
// et une pièce jointe en attente ajoute une rangée de pastilles. On la mesure
// donc au lieu de la deviner, comme on le fait déjà pour la gouttière.
// Pas de boucle d'observation : le composeur est en position:absolute, changer le
// rembourrage de #chat ne modifie pas sa hauteur.
function syncComposer(){
const c=document.getElementById('composer'); if(!c) return;
document.documentElement.style.setProperty('--composer-h', c.offsetHeight+'px');
}
addEventListener('resize', syncGutter); addEventListener('resize', syncGutter);
addEventListener('DOMContentLoaded', syncGutter); addEventListener('DOMContentLoaded', syncGutter);
addEventListener('resize', syncComposer);
addEventListener('DOMContentLoaded', ()=>{
syncComposer();
const c=document.getElementById('composer');
if(c && window.ResizeObserver) new ResizeObserver(syncComposer).observe(c);
});
function scrollMaybe(){ function scrollMaybe(){
// Pendant le replay initial on NE force AUCUN reflow : lire scrollHeight à chaque // Pendant le replay initial on NE force AUCUN reflow : lire scrollHeight à chaque
+18
View File
@@ -14,8 +14,26 @@ function syncGutter(){
const g=Math.max(0,(chat.offsetWidth-chat.clientWidth)/2); const g=Math.max(0,(chat.offsetWidth-chat.clientWidth)/2);
document.documentElement.style.setProperty('--sbw', g+'px'); document.documentElement.style.setProperty('--sbw', g+'px');
} }
// La carte de saisie flotte AU-DESSUS du fil (position:absolute) : c'est au fil
// de réserver sa hauteur en rembourrage bas, sinon ses derniers messages passent
// dessous et deviennent hors d'atteinte — aucun défilement ne les ramène.
// Cette hauteur n'est pas constante : la saisie grandit avec le texte (autoGrow),
// et une pièce jointe en attente ajoute une rangée de pastilles. On la mesure
// donc au lieu de la deviner, comme on le fait déjà pour la gouttière.
// Pas de boucle d'observation : le composeur est en position:absolute, changer le
// rembourrage de #chat ne modifie pas sa hauteur.
function syncComposer(){
const c=document.getElementById('composer'); if(!c) return;
document.documentElement.style.setProperty('--composer-h', c.offsetHeight+'px');
}
addEventListener('resize', syncGutter); addEventListener('resize', syncGutter);
addEventListener('DOMContentLoaded', syncGutter); addEventListener('DOMContentLoaded', syncGutter);
addEventListener('resize', syncComposer);
addEventListener('DOMContentLoaded', ()=>{
syncComposer();
const c=document.getElementById('composer');
if(c && window.ResizeObserver) new ResizeObserver(syncComposer).observe(c);
});
function scrollMaybe(){ function scrollMaybe(){
// Pendant le replay initial on NE force AUCUN reflow : lire scrollHeight à chaque // Pendant le replay initial on NE force AUCUN reflow : lire scrollHeight à chaque
+32 -13
View File
@@ -1005,8 +1005,13 @@ h1{color:var(--text);font-weight:600;letter-spacing:-.01em}
/* Barre latérale : plus sombre/atténuée que la zone de conversation. */ /* Barre latérale : plus sombre/atténuée que la zone de conversation. */
.side{background:var(--panel);border-right-color:transparent} .side{background:var(--panel);border-right-color:transparent}
@media (max-width:720px){.side{background:var(--panel)}} @media (max-width:720px){.side{background:var(--panel)}}
/* Colonne de lecture centrée (comme le fil ChatGPT), pleine largeur sur mobile. */ /* Colonne de lecture centrée (comme le fil ChatGPT), pleine largeur sur mobile.
#chat{padding:28px max(16px,calc(50% - 380px)) 8px;gap:22px;scrollbar-gutter:stable both-edges} ⚠️ JAMAIS le raccourci `padding` ici : le rembourrage BAS réserve la hauteur
de la carte de saisie (voir #chat plus bas) et il est réglé ailleurs. Une
règle en raccourci le remet silencieusement à sa valeur du raccourci — c'est
exactement ce qui, jusqu'à ce correctif, laissait la fin du fil coincée sous
la carte au-delà de 721 px de large. Longhands uniquement. */
#chat{padding-top:28px;padding-inline:max(16px,calc(50% - 380px));gap:22px;scrollbar-gutter:stable both-edges}
/* Réponses de l'assistant : pas de cadre, pas de fond — juste du texte. */ /* Réponses de l'assistant : pas de cadre, pas de fond — juste du texte. */
#chat .msg.assistant{background:transparent;border:none;padding:0;max-width:100%;line-height:1.7} #chat .msg.assistant{background:transparent;border:none;padding:0;max-width:100%;line-height:1.7}
/* Question : pastille arrondie à droite, texte lisible sur fond clair OU sombre. */ /* Question : pastille arrondie à droite, texte lisible sur fond clair OU sombre. */
@@ -1052,9 +1057,21 @@ html[data-hide-stats="1"] #chat .msg .statline{display:none}
/* Le padding BAS dégage l'indicateur d'accueil de l'iPhone en PWA : la carte /* Le padding BAS dégage l'indicateur d'accueil de l'iPhone en PWA : la carte
flotte au-dessus de lui, son arrondi bas reste donc bien visible. Hors PWA flotte au-dessus de lui, son arrondi bas reste donc bien visible. Hors PWA
l'inset vaut 0 → strictement les 8 px d'origine. */ l'inset vaut 0 → strictement les 8 px d'origine. */
#composer{position:absolute;left:0;right:0;bottom:0;z-index:4;border-top:none;display:flex;flex-direction:column;padding:34px 0 calc(8px + env(safe-area-inset-bottom));--col:calc(max(16px,calc(50% - 380px)) + var(--sbw,0px));background:linear-gradient(to bottom,transparent 0,var(--bg) 34%)} /* --fade = la bande transparente au-dessus de la carte, celle où le fil doit
#chat{padding-bottom:calc(170px + env(safe-area-inset-bottom))} s'effacer. Le dégradé s'exprime dans la MÊME unité (et non en % de la hauteur
#scrollbtn{bottom:calc(180px + env(safe-area-inset-bottom));border-radius:999px} totale du composeur, qui varie) : l'opacité est donc pleine exactement au bord
haut de la carte. Avec un %, le fondu finissait SOUS ce bord et le texte
restait lisible au ras de la carte — l'impression de « passer derrière ». */
#composer{position:absolute;left:0;right:0;bottom:0;z-index:4;border-top:none;display:flex;flex-direction:column;--fade:34px;padding:var(--fade) 0 calc(8px + env(safe-area-inset-bottom));--col:calc(max(16px,calc(50% - 380px)) + var(--sbw,0px));background:linear-gradient(to bottom,transparent 0,var(--bg) var(--fade))}
/* Réserve sous le fil = hauteur RÉELLE du composeur, mesurée et publiée par
syncComposer() (08-chat-render.js). Une constante redevient fausse dès que la
saisie grandit ou qu'une pièce jointe s'affiche, et la fin du fil repasse hors
d'atteinte. 170px n'est que le repli du tout premier rendu, avant mesure.
Pas de env(safe-area-inset-bottom) ici : il est déjà DANS le padding bas du
composeur, donc dans sa hauteur mesurée — le compter deux fois creusait un
trou en PWA iOS. */
#chat{padding-bottom:calc(var(--composer-h,170px) + 12px)}
#scrollbtn{bottom:calc(var(--composer-h,170px) + 10px);border-radius:999px}
#inputbar{order:1;margin:0 var(--col);padding:8px 8px 8px 16px;gap:8px;align-items:flex-end;background:var(--panel);border:1px solid var(--border);border-bottom:none;border-radius:26px 26px 0 0} #inputbar{order:1;margin:0 var(--col);padding:8px 8px 8px 16px;gap:8px;align-items:flex-end;background:var(--panel);border:1px solid var(--border);border-bottom:none;border-radius:26px 26px 0 0}
#input{background:transparent;border:none;border-radius:0;padding:9px 0;min-height:36px;line-height:18px;max-height:160px} #input{background:transparent;border:none;border-radius:0;padding:9px 0;min-height:36px;line-height:18px;max-height:160px}
/* Pas de cadre qui s'assombrit au focus : la carte garde exactement la même /* Pas de cadre qui s'assombrit au focus : la carte garde exactement la même
@@ -1121,7 +1138,7 @@ html[data-hide-stats="1"] #chat .msg .statline{display:none}
overflow-x:auto;scrollbar-width:none} overflow-x:auto;scrollbar-width:none}
#attach-list::-webkit-scrollbar{display:none} #attach-list::-webkit-scrollbar{display:none}
#attach-list.show{display:flex} #attach-list.show{display:flex}
#composer:has(#attach-list.show){padding-top:6px} #composer:has(#attach-list.show){--fade:6px}
/* Posées sur le fil (et non sur la carte) : il leur faut un fond opaque et un /* Posées sur le fil (et non sur la carte) : il leur faut un fond opaque et un
cadre, sinon le texte de la conversation transparaît derrière. */ cadre, sinon le texte de la conversation transparaît derrière. */
#attach-list .chip-file{flex:0 0 auto;background:var(--panel);border-color:var(--border); #attach-list .chip-file{flex:0 0 auto;background:var(--panel);border-color:var(--border);
@@ -1270,10 +1287,10 @@ button:hover{border-color:var(--dim);color:var(--text)}
/* Colonne principale : une seule grande carte qui contient fil et saisie. */ /* Colonne principale : une seule grande carte qui contient fil et saisie. */
.main{background:var(--panel);border-radius:20px;box-shadow:var(--shadow);overflow:hidden} .main{background:var(--panel);border-radius:20px;box-shadow:var(--shadow);overflow:hidden}
#chat{padding:26px max(20px,calc(50% - 360px)) 8px} #chat{padding-top:26px;padding-inline:max(20px,calc(50% - 360px))}
/* Le dégradé qui fait disparaître le fil sous la carte de saisie doit fondre /* Le dégradé qui fait disparaître le fil sous la carte de saisie doit fondre
vers le PANNEAU, pas vers le fond de la coque. */ vers le PANNEAU, pas vers le fond de la coque. */
#composer{background:linear-gradient(to bottom,transparent 0,var(--panel) 34%)} #composer{background:linear-gradient(to bottom,transparent 0,var(--panel) var(--fade))}
/* Carte de saisie : posée SUR le panneau, donc un ton au-dessus, et sans /* Carte de saisie : posée SUR le panneau, donc un ton au-dessus, et sans
bordure — c'est l'élévation qui la détache. */ bordure — c'est l'élévation qui la détache. */
#inputbar,#ctxmeta{background:var(--row-bg-on);border-color:transparent} #inputbar,#ctxmeta{background:var(--row-bg-on);border-color:transparent}
@@ -1287,10 +1304,12 @@ button:hover{border-color:var(--dim);color:var(--text)}
.side{gap:8px} .side{gap:8px}
.side>details>summary{height:38px} .side>details>summary{height:38px}
/* Discussion active : un LISERÉ sauge à gauche, pas un cadre complet — c'est /* Discussion active : un cadre sauge COMPLET, mais fin (1 px) — le liseré de
la marque de sélection de la charte, et elle se lit sans alourdir. */ 3 px sur le seul bord gauche se lisait mal et déséquilibrait la ligne. La
.side .preset{border:0;border-left:3px solid transparent;border-radius:14px;background:transparent} bordure transparente est portée par tous les états : la sélection ne décale
.side .preset.active{background:var(--row-bg-on);border-left-color:var(--accent)} donc pas le contenu d'un pixel. */
.side .preset{border:1px solid transparent;border-radius:14px;background:transparent}
.side .preset.active{background:var(--row-bg-on);border-color:var(--accent)}
.side .preset:hover{background:var(--row-bg)} .side .preset:hover{background:var(--row-bg)}
/* Bulle de question : coin bas-droit rentré, comme une bulle qui pointe vers /* Bulle de question : coin bas-droit rentré, comme une bulle qui pointe vers
@@ -1315,7 +1334,7 @@ button:hover{border-color:var(--dim);color:var(--text)}
le début de la suivante). 1080 px ≈ 110 caractères, large mais tenable. */ le début de la suivante). 1080 px ≈ 110 caractères, large mais tenable. */
@media (min-width:721px){ @media (min-width:721px){
:root{--measure:min(1080px,100%)} :root{--measure:min(1080px,100%)}
#chat{padding:26px max(20px,calc(50% - var(--measure)/2)) 8px} #chat{padding-top:26px;padding-inline:max(20px,calc(50% - var(--measure)/2))}
#composer{--col:calc(max(20px,calc(50% - var(--measure)/2)) + var(--sbw,0px))} #composer{--col:calc(max(20px,calc(50% - var(--measure)/2)) + var(--sbw,0px))}
} }