355 lines
10 KiB
CSS
355 lines
10 KiB
CSS
/* === Base === */
|
||
:root{
|
||
--bg:#f6f7fb; --card:#fff; --ink:#111; --muted:#6b7280; --brand:#38378B;
|
||
--line:#e5e7eb; --bubble:#f1f3f5; --bubble-me:#38378B; --bubble-me-ink:#fff;
|
||
--fond:#8CA9FF;
|
||
}
|
||
*{ box-sizing:border-box; }
|
||
html, body { height:100%; overflow-x:hidden; }
|
||
body{ background:var(--bg); color:var(--ink); min-width:0; }
|
||
|
||
/* Conteneur app */
|
||
.msg-app{
|
||
display:grid;
|
||
grid-template-columns: 1fr; /* mobile: une seule colonne */
|
||
min-width:0; overflow-x:hidden;
|
||
}
|
||
|
||
/* === Liste (mobile: plein écran par défaut) === */
|
||
.msg-list-panel{
|
||
display:block;
|
||
border-right:1px solid var(--line);
|
||
background:var(--card);
|
||
min-width:0; min-height:0;
|
||
}
|
||
.list-header{
|
||
display:flex; align-items:center; justify-content:space-between;
|
||
padding:12px; border-bottom:1px solid var(--line);
|
||
}
|
||
.list-title{ margin:0; font-size:16px; color:var(--ink); }
|
||
.list-new{ font-size:13px; color:var(--brand); text-decoration:none; }
|
||
.list-scroll{ max-height:calc(100vh - 180px); overflow:auto; } /* garde un scroll si la page est courte */
|
||
.conv-item{
|
||
display:flex; align-items:center; gap:8px;
|
||
padding:12px; border-bottom:1px solid var(--line); cursor:pointer; width:100%;
|
||
background:#fff;
|
||
}
|
||
.conv-item:hover{ background:#fafafa; }
|
||
.conv-title{ font-weight:600; color:var(--ink); }
|
||
.conv-last{ font-size:13px; color:var(--muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
|
||
.conv-badge{ margin-left:auto; background:#e11d48; color:#fff; font-size:12px; min-width:20px; height:20px; line-height:20px; text-align:center; border-radius:999px; padding:0 6px; }
|
||
|
||
/* === Fil (mobile: caché par défaut) === */
|
||
.msg-thread-panel{
|
||
display:none; /* mobile: on le montre seulement quand .show-thread */
|
||
flex-direction:column;
|
||
background:var(--card);
|
||
min-width:0; min-height:0;
|
||
}
|
||
.thread-header{
|
||
position:sticky; top:0; z-index:10;
|
||
display:flex; align-items:center; gap:8px;
|
||
padding:10px 12px; border-bottom:1px solid var(--line); background:var(--card);
|
||
}
|
||
.btn-back{
|
||
appearance:none; border:none; background:transparent; font-size:18px; line-height:1; cursor:pointer;
|
||
}
|
||
.thread-title{ font-weight:600; color:var(--ink); flex:1 1 auto; min-width:0; }
|
||
.thread-actions{ display:flex; gap:8px; flex-wrap:wrap; margin-left:auto; }
|
||
.th-btn{
|
||
border:1px solid var(--line); background:#fff; padding:6px 10px; border-radius:10px; cursor:pointer; font-size:13px;
|
||
}
|
||
.th-btn + .th-btn{ margin-left:0; }
|
||
|
||
/* Corps défilant */
|
||
.thread-body{
|
||
flex:1 1 auto;
|
||
min-height:0; /* CRUCIAL pour permettre le scroll interne */
|
||
overflow:auto;
|
||
padding:12px; background:var(--bg);
|
||
padding-bottom:84px; /* espace pour la barre fixe du bas */
|
||
}
|
||
|
||
/* Messages */
|
||
.msg{ margin-bottom:12px; display:flex; flex-direction:column; align-items:flex-start; }
|
||
.msg.me{ align-items:flex-end; }
|
||
.bubble{
|
||
max-width:90%; padding:10px 14px; border-radius:10px; background:var(--bubble); color:var(--ink);
|
||
box-shadow:0 1px 2px rgba(0,0,0,.05); overflow-wrap:anywhere; word-break:break-word;
|
||
}
|
||
.msg.me .bubble{ background:var(--bubble-me); color:var(--bubble-me-ink); }
|
||
.meta{ margin-top:6px; font-size:12px; color:var(--muted); }
|
||
.bubble a{ color:inherit; text-decoration:underline; }
|
||
|
||
/* Actions message */
|
||
.msg .msg-actions{ margin-top:6px; display:flex; gap:6px; opacity:.7; }
|
||
.msg .msg-actions button{
|
||
border:1px solid var(--line); background:#fff; font-size:12px; padding:2px 8px; border-radius:8px; cursor:pointer;
|
||
}
|
||
.msg .msg-actions button:hover{ background:#f8f8f8; }
|
||
|
||
/* Bandeau info (clôturée) */
|
||
.thread-banner{
|
||
background:#fff3cd; color:#7a5c00; border:1px solid #ffe69c;
|
||
padding:8px 12px; margin:8px 12px 0 12px; border-radius:8px; font-size:14px;
|
||
}
|
||
|
||
/* Barre d'envoi (fixe en bas) */
|
||
.thread-footer{
|
||
position:sticky; bottom:0; z-index:10;
|
||
padding:10px 12px; border-top:1px solid var(--line); background:var(--card);
|
||
}
|
||
.send-form{ display:flex; align-items:center; gap:8px; }
|
||
.msg-input{
|
||
flex:1; border:1px solid var(--line); border-radius:10px; padding:10px 12px; font-size:16px; outline:none; min-width:0;
|
||
}
|
||
.file-btn{
|
||
display:inline-flex; align-items:center; justify-content:center;
|
||
width:40px; height:40px; border-radius:10px; border:1px solid var(--line); cursor:pointer; user-select:none;
|
||
}
|
||
.hidden-file{ display:none; }
|
||
.send-btn{ border:none; background:var(--brand); color:#fff; border-radius:10px; padding:8px 8px; font-weight:600; cursor:pointer; }
|
||
.send-btn:disabled{ opacity:.6; cursor:not-allowed; }
|
||
.send-hint{ margin-top:6px; font-size:12px; color:var(--muted); }
|
||
|
||
/* === Logique d’affichage mobile (<= 899px) === */
|
||
@media (max-width: 899px){
|
||
/* Par défaut: liste visible, fil caché */
|
||
.msg-app { grid-template-columns:1fr; }
|
||
.msg-list-panel{ display:block; }
|
||
.msg-thread-panel{ display:none; }
|
||
|
||
/* Quand une conv est ouverte (.show-thread posé par JS) */
|
||
.msg-app.show-thread .msg-list-panel{ display:none !important; }
|
||
.msg-app.show-thread .msg-thread-panel{ display:flex !important; }
|
||
|
||
/* Actions compactes */
|
||
.th-btn{ padding:6px 8px; font-size:12px; }
|
||
}
|
||
|
||
/* === Desktop (>= 900px): split view stable === */
|
||
@media (min-width: 900px){
|
||
.msg-app{ grid-template-columns: 360px 1fr; }
|
||
.btn-back{ display:none; }
|
||
.msg-list-panel{ display:block !important; }
|
||
.msg-thread-panel{ display:flex !important; }
|
||
.thread-body{ padding-bottom:72px; } /* barre plus petite en desktop */
|
||
}
|
||
|
||
/* === Intégration dans un card Bootstrap (optionnel) === */
|
||
.chat-frame{ overflow:hidden; }
|
||
.chat-frame .msg-app{ height:auto; max-height:none; }
|
||
@media (min-width:900px){
|
||
.chat-frame .msg-app{ height:70vh; }
|
||
}
|
||
|
||
/* Style modernisé pour la liste des conversations */
|
||
.conv-item {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
width: 90%;
|
||
|
||
background: #fff;
|
||
border: 1px solid var(--line);
|
||
border-radius: 12px;
|
||
|
||
padding: 10px 14px;
|
||
margin: 8px 12px;
|
||
|
||
font-size: 15px;
|
||
font-weight: 500;
|
||
color: var(--ink);
|
||
|
||
transition: all 0.2s ease-in-out;
|
||
}
|
||
.conv-item:hover {
|
||
background: #f1f3f9;
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 2px 6px rgba(0,0,0,0.08);
|
||
}
|
||
|
||
/* Le nom */
|
||
.conv-title {
|
||
font-weight: 600;
|
||
color: var(--brand);
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
/* Aperçu du dernier message */
|
||
.conv-last {
|
||
font-size: 13px;
|
||
color: var(--muted);
|
||
margin-top: 2px;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
|
||
/* Badge non lus */
|
||
.conv-badge {
|
||
margin-left: auto;
|
||
background: #e11d48; /* rouge */
|
||
color: #fff;
|
||
font-size: 12px;
|
||
min-width: 20px;
|
||
height: 20px;
|
||
line-height: 20px;
|
||
text-align: center;
|
||
border-radius: 999px;
|
||
padding: 0 6px;
|
||
box-shadow: 0 1px 2px rgba(0,0,0,.15);
|
||
}
|
||
.conv-delete {
|
||
border: none;
|
||
background: transparent;
|
||
color: #aaa;
|
||
font-size: 16px;
|
||
cursor: pointer;
|
||
padding: 4px;
|
||
margin-left: 8px;
|
||
border-radius: 6px;
|
||
transition: background 0.2s, color 0.2s;
|
||
}
|
||
.conv-delete:hover {
|
||
background: #f8d7da;
|
||
color: #d6336c;
|
||
}
|
||
|
||
|
||
|
||
/* ===== HOTFIX Sélecteurs (compat HTML existant) ===== */
|
||
|
||
/* 1) Aligner les panneaux "liste" et "fil" sur tes IDs historiques */
|
||
.msg-list-panel, #conv-list { display:block; }
|
||
.msg-thread-panel, #msg-thread-panel { display:none; } /* caché par défaut en mobile */
|
||
|
||
/* 2) En mobile: logique d’affichage avec ou sans show-thread */
|
||
@media (max-width: 899px){
|
||
/* Par défaut: on montre la liste, on cache le fil */
|
||
.msg-app { grid-template-columns:1fr; }
|
||
.msg-list-panel, #conv-list { display:block !important; }
|
||
.msg-thread-panel, #msg-thread-panel { display:none !important; }
|
||
|
||
/* Quand une conv est ouverte (peut être posé sur .msg-app OU un parent générique) */
|
||
.msg-app.show-thread .msg-list-panel,
|
||
.show-thread .msg-list-panel,
|
||
.msg-app.show-thread #conv-list,
|
||
.show-thread #conv-list { display:none !important; }
|
||
|
||
.msg-app.show-thread .msg-thread-panel,
|
||
.show-thread .msg-thread-panel,
|
||
.msg-app.show-thread #msg-thread-panel,
|
||
.show-thread #msg-thread-panel { display:flex !important; flex-direction:column; }
|
||
}
|
||
|
||
/* 3) Desktop: split view stable pour les deux variantes (classes et IDs) */
|
||
@media (min-width: 900px){
|
||
.msg-app{ grid-template-columns: 360px 1fr; }
|
||
|
||
.msg-list-panel, #conv-list { display:block !important; }
|
||
.msg-thread-panel, #msg-thread-panel { display:flex !important; flex-direction:column; }
|
||
}
|
||
|
||
/* 4) Bouton Archiver désactivé visuellement mais présent (aucun JS requis) */
|
||
.th-btn.is-disabled{
|
||
opacity:.5;
|
||
pointer-events:none;
|
||
filter: grayscale(1);
|
||
}
|
||
|
||
/* =================================================
|
||
Barre d'envoi FIXE en mobile + PWA
|
||
================================================= */
|
||
|
||
/* Mobile */
|
||
@media (max-width: 899px) {
|
||
.thread-footer {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
|
||
z-index: 1000;
|
||
background: #fff;
|
||
|
||
border-top: 1px solid #e5e7eb;
|
||
padding: 10px 12px;
|
||
|
||
/* iOS notch / home indicator */
|
||
padding-bottom: calc(10px + env(safe-area-inset-bottom));
|
||
}
|
||
|
||
/* Important : laisser de la place au scroll au-dessus */
|
||
.thread-body {
|
||
padding-bottom: 90px; /* hauteur approx de la barre */
|
||
}
|
||
}
|
||
|
||
/* PWA explicite (au cas où la largeur est > 900px) */
|
||
@media (display-mode: standalone) {
|
||
.thread-footer {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
|
||
z-index: 1000;
|
||
background: #fff;
|
||
|
||
border-top: 1px solid #e5e7eb;
|
||
padding: 10px 12px;
|
||
padding-bottom: calc(10px + env(safe-area-inset-bottom));
|
||
}
|
||
|
||
.thread-body {
|
||
padding-bottom: 90px;
|
||
}
|
||
}
|
||
|
||
/* =================================================
|
||
Thread header FIXE (mobile + PWA)
|
||
================================================= */
|
||
|
||
/* Mobile */
|
||
@media (max-width: 899px) {
|
||
.thread-header {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
|
||
/* sera positionné via JS juste sous le header global */
|
||
top: var(--app-header-h, 64px);
|
||
|
||
z-index: 1000;
|
||
background: #fff;
|
||
|
||
border-bottom: 1px solid #e5e7eb;
|
||
}
|
||
|
||
/* laisser de la place au contenu */
|
||
.thread-body {
|
||
padding-top: 56px; /* hauteur approx du thread-header */
|
||
}
|
||
}
|
||
|
||
/* PWA explicite */
|
||
@media (display-mode: standalone) {
|
||
.thread-header {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
top: var(--app-header-h, 64px);
|
||
|
||
z-index: 1000;
|
||
background: #fff;
|
||
border-bottom: 1px solid #e5e7eb;
|
||
}
|
||
|
||
.thread-body {
|
||
padding-top: 56px;
|
||
}
|
||
}
|