/* ===================================================================== MSG MOTOC — direction artistique « Motocultor 2026 » Nuit bleu-vert, cyan turquoise, braise orange, éclairs jaunes. Le chrome porte l'esthétique metal ; le fil de messages reste lisible. ===================================================================== */ :root { /* Nuit */ --night-900: #050f13; --night-850: #071318; --night-800: #0a1c22; --night-700: #0c2128; --night-600: #102a32; --night-500: #16353f; /* Traits */ --line: #1d4450; --line-bright: #2a5f6e; /* Accents */ --cyan: #48c9d6; --cyan-dim: #2f8d99; --cyan-deep: #1d6b78; --cyan-glow: rgba(72, 201, 214, 0.35); --ember: #ee8b3d; --ember-dim: #b8632a; --lightning: #f7dd54; --danger: #d94f4f; --success: #5bbf7a; /* Texte */ --text: #dbeef2; --text-dim: #8fb2ba; --text-faint: #5d838c; /* Formes */ --radius: 14px; --radius-lg: 20px; --radius-pill: 999px; /* Typo */ --font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; --font-display: 'Haettenschweiler', 'Arial Narrow Bold', Impact, 'Franklin Gothic Bold', 'Helvetica Neue', sans-serif; /* Gouttières sûres (encoche, barre de geste) */ --safe-top: env(safe-area-inset-top, 0px); --safe-bottom: env(safe-area-inset-bottom, 0px); --header-h: 58px; } * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; } html, body { height: 100%; margin: 0; overscroll-behavior-y: none; } body { font-family: var(--font-body); /* 16px minimum : empêche iOS de zoomer au focus des champs. */ font-size: 16px; line-height: 1.45; color: var(--text); background: var(--night-850); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; } /* Grain photocopie, repris de la texture de l'affiche. */ body::after { content: ''; position: fixed; inset: 0; pointer-events: none; z-index: 9999; opacity: 0.055; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E"); } button, input, textarea, select { font: inherit; color: inherit; } button { cursor: pointer; border: none; background: none; } ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-thumb { background: var(--line-bright); border-radius: 3px; } /* --- Typo d'affiche ---------------------------------------------------- */ .display { font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.055em; font-weight: 400; line-height: 1; } .glow { text-shadow: 0 0 14px var(--cyan-glow), 0 0 34px rgba(72, 201, 214, 0.18); } /* ====================================================================== Écrans ====================================================================== */ #app { height: 100dvh; overflow: hidden; position: relative; } .screen { position: absolute; inset: 0; display: none; flex-direction: column; background: var(--night-850); } .screen.active { display: flex; } /* Une vue qui glisse par-dessus (conversation, admin, réglages). */ .screen.overlay { z-index: 20; animation: slide-in 0.22s cubic-bezier(0.22, 0.61, 0.36, 1); } @keyframes slide-in { from { transform: translateX(100%); } to { transform: translateX(0); } } @media (prefers-reduced-motion: reduce) { .screen.overlay { animation: none; } } /* ====================================================================== Authentification — le seul écran pleinement « affiche » ====================================================================== */ #screen-auth { background: radial-gradient(120% 70% at 50% 108%, rgba(238, 139, 61, 0.26), transparent 62%), radial-gradient(90% 55% at 50% -8%, rgba(72, 201, 214, 0.16), transparent 60%), linear-gradient(180deg, var(--night-700), var(--night-900)); justify-content: center; padding: calc(var(--safe-top) + 24px) 22px calc(var(--safe-bottom) + 24px); overflow-y: auto; } .auth-inner { width: 100%; max-width: 400px; margin: auto; } .auth-mark { text-align: center; margin-bottom: 30px; } .auth-mark img { width: 76px; height: 76px; border-radius: 20px; box-shadow: 0 0 0 1px var(--line-bright), 0 12px 40px rgba(0, 0, 0, 0.6), 0 0 46px rgba(72, 201, 214, 0.16); } .auth-mark h1 { font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.09em; font-size: 40px; line-height: 1; margin: 18px 0 6px; color: var(--cyan); text-shadow: 0 0 16px var(--cyan-glow), 0 3px 0 rgba(0, 0, 0, 0.55); } .auth-mark p { margin: 0; color: var(--text-faint); font-size: 13px; letter-spacing: 0.16em; text-transform: uppercase; } /* Filet « éclair » décoratif */ .bolt-rule { height: 12px; margin: 20px 0; background: no-repeat center / auto 100% url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='12' viewBox='0 0 220 12'%3E%3Cpath d='M0 6h78l8-5 6 10 7-9 5 6 6-4 5 4 7-6 6 9 8-5h79' fill='none' stroke='%23f7dd54' stroke-width='1.4' opacity='.65'/%3E%3C/svg%3E"); } .auth-card { background: linear-gradient(180deg, rgba(22, 53, 63, 0.92), rgba(10, 28, 34, 0.92)); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 22px 20px; box-shadow: 0 18px 50px rgba(0, 0, 0, 0.5); position: relative; } /* Rivets industriels aux quatre coins */ .auth-card::before, .auth-card::after { content: ''; position: absolute; width: 5px; height: 5px; border-radius: 50%; background: var(--line-bright); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5); } .auth-card::before { top: 9px; left: 9px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5), calc(100% + 316px) 0 0 0 var(--line-bright); } .auth-card::after { bottom: 9px; left: 9px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5), calc(100% + 316px) 0 0 0 var(--line-bright); } .auth-step-title { font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.05em; font-size: 21px; margin: 0 0 4px; color: var(--text); } .auth-step-sub { margin: 0 0 18px; color: var(--text-dim); font-size: 14px; } /* --- Choix du profil (admin / bénévole) -------------------------------- */ .role-card { display: flex; align-items: center; gap: 14px; width: 100%; padding: 16px 15px; margin-bottom: 11px; text-align: left; border-radius: var(--radius); border: 1px solid var(--line-bright); background: linear-gradient(180deg, rgba(72, 201, 214, 0.1), rgba(10, 28, 34, 0.7)); transition: transform 0.12s, border-color 0.15s, background 0.15s; } .role-card:active { transform: scale(0.98); border-color: var(--cyan); } .role-card.benevole { background: linear-gradient(180deg, rgba(238, 139, 61, 0.1), rgba(10, 28, 34, 0.7)); } .role-card.benevole:active { border-color: var(--ember); } .role-card svg { flex: none; width: 30px; height: 30px; fill: none; stroke: var(--cyan); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; } .role-card.benevole svg { stroke: var(--ember); } .role-card strong { display: block; font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.07em; font-size: 20px; font-weight: 400; line-height: 1.1; } .role-card span { display: block; font-size: 12.5px; color: var(--text-faint); margin-top: 3px; } /* Rappel du profil choisi, au-dessus du champ numéro. */ .role-pill { display: inline-flex; align-items: center; gap: 6px; padding: 4px 11px; border-radius: var(--radius-pill); border: 1px solid var(--cyan-dim); color: var(--cyan); font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; font-weight: 700; margin-bottom: 12px; } .role-pill.benevole { border-color: var(--ember-dim); color: var(--ember); } /* --- Champs ------------------------------------------------------------ */ .field { margin-bottom: 14px; } .field label { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: 0.13em; color: var(--cyan-dim); margin-bottom: 6px; font-weight: 700; } .field input, .field textarea, .field select { width: 100%; padding: 13px 14px; background: rgba(5, 15, 19, 0.75); border: 1px solid var(--line); border-radius: var(--radius); color: var(--text); outline: none; transition: border-color 0.15s, box-shadow 0.15s; } .field input::placeholder, .field textarea::placeholder { color: var(--text-faint); } .field input:focus, .field textarea:focus, .field select:focus { border-color: var(--cyan-dim); box-shadow: 0 0 0 3px rgba(72, 201, 214, 0.14); } .field .hint { font-size: 12px; color: var(--text-faint); margin-top: 6px; } .input-phone { font-size: 21px !important; letter-spacing: 0.12em; text-align: center; font-variant-numeric: tabular-nums; } .input-pin { font-size: 27px !important; letter-spacing: 0.55em; text-align: center; padding-left: 0.55em !important; font-variant-numeric: tabular-nums; } .field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; } /* --- Boutons ----------------------------------------------------------- */ .btn { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; min-height: 50px; padding: 0 18px; border-radius: var(--radius); font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.08em; font-size: 17px; transition: transform 0.12s, filter 0.15s, opacity 0.15s; } .btn:active { transform: scale(0.975); } .btn:disabled { opacity: 0.45; pointer-events: none; } .btn-primary { background: linear-gradient(180deg, var(--cyan), var(--cyan-deep)); color: #04191d; box-shadow: 0 6px 20px rgba(72, 201, 214, 0.24), inset 0 1px 0 rgba(255, 255, 255, 0.28); } .btn-ember { background: linear-gradient(180deg, var(--ember), var(--ember-dim)); color: #1c0d03; box-shadow: 0 6px 20px rgba(238, 139, 61, 0.24), inset 0 1px 0 rgba(255, 255, 255, 0.25); } .btn-ghost { background: rgba(255, 255, 255, 0.04); border: 1px solid var(--line); color: var(--text-dim); } .btn-danger { background: rgba(217, 79, 79, 0.14); border: 1px solid rgba(217, 79, 79, 0.42); color: #f0a0a0; } .btn-sm { min-height: 38px; font-size: 13px; width: auto; padding: 0 14px; border-radius: 10px; } .btn-link { color: var(--cyan); font-size: 14px; text-decoration: underline; padding: 10px; width: 100%; text-align: center; } .form-error { background: rgba(217, 79, 79, 0.12); border: 1px solid rgba(217, 79, 79, 0.4); color: #f3b0b0; padding: 11px 13px; border-radius: 11px; font-size: 14px; margin-bottom: 14px; } .form-error:empty { display: none; } /* ====================================================================== En-têtes ====================================================================== */ .topbar { flex: none; display: flex; align-items: center; gap: 10px; height: calc(var(--header-h) + var(--safe-top)); padding: var(--safe-top) 8px 0; background: linear-gradient(180deg, var(--night-700), rgba(12, 33, 40, 0.94)); border-bottom: 1px solid var(--line); backdrop-filter: blur(12px); position: relative; } /* Liseré cyan+braise sous chaque en-tête */ .topbar::after { content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px; background: linear-gradient(90deg, transparent, var(--cyan-dim), var(--ember-dim), transparent); opacity: 0.75; } .topbar h2 { font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.05em; font-size: 19px; margin: 0; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .topbar .sub { font-family: var(--font-body); text-transform: none; letter-spacing: 0; font-size: 12px; color: var(--text-faint); font-weight: 400; } .icon-btn { flex: none; width: 42px; height: 42px; display: grid; place-items: center; border-radius: 11px; color: var(--text-dim); transition: background 0.15s, color 0.15s; } .icon-btn:active { background: rgba(255, 255, 255, 0.07); color: var(--cyan); } .icon-btn svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; } /* ====================================================================== Liste des groupes ====================================================================== */ .list-body { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; padding-bottom: calc(var(--safe-bottom) + 20px); } .search-wrap { padding: 10px 12px; position: sticky; top: 0; background: var(--night-850); z-index: 2; } .search-wrap input { width: 100%; padding: 11px 14px; border-radius: var(--radius-pill); background: var(--night-700); border: 1px solid var(--line); outline: none; } .search-wrap input:focus { border-color: var(--cyan-dim); } .group-section { margin-bottom: 4px; } .section-head { display: flex; align-items: center; gap: 9px; padding: 15px 16px 7px; font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.13em; font-size: 12px; color: var(--ember); } .section-head::after { content: ''; flex: 1; height: 1px; background: linear-gradient(90deg, var(--line-bright), transparent); } .group-row { display: flex; align-items: center; gap: 12px; padding: 11px 14px; width: 100%; text-align: left; border-bottom: 1px solid rgba(29, 68, 80, 0.4); transition: background 0.12s; } .group-row:active { background: rgba(72, 201, 214, 0.07); } .group-row.child { padding-left: 30px; position: relative; } /* Petit rail pour matérialiser les sous-groupes */ .group-row.child::before { content: ''; position: absolute; left: 17px; top: 0; bottom: 0; width: 2px; background: linear-gradient(180deg, var(--line-bright), transparent); } .avatar { flex: none; width: 46px; height: 46px; border-radius: 13px; display: grid; place-items: center; font-family: var(--font-display); font-size: 18px; letter-spacing: 0.04em; color: #04191d; background: linear-gradient(145deg, var(--cyan), var(--cyan-deep)); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25); } .avatar.sm { width: 34px; height: 34px; border-radius: 10px; font-size: 13px; } .avatar.ember { background: linear-gradient(145deg, var(--ember), var(--ember-dim)); color: #1c0d03; } .group-main { flex: 1; min-width: 0; } .group-name { font-weight: 600; font-size: 15.5px; display: flex; align-items: center; gap: 7px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .group-preview { font-size: 13.5px; color: var(--text-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; } .group-meta { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 5px; } .group-time { font-size: 11px; color: var(--text-faint); } .badge { min-width: 21px; height: 21px; padding: 0 6px; border-radius: var(--radius-pill); background: var(--ember); color: #1c0d03; font-size: 11.5px; font-weight: 800; display: grid; place-items: center; box-shadow: 0 0 12px rgba(238, 139, 61, 0.45); } .tag { font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 800; padding: 2px 6px; border-radius: 5px; border: 1px solid currentColor; opacity: 0.9; } .tag.admin { color: var(--lightning); } .tag.muted { color: var(--text-faint); } .empty { text-align: center; padding: 64px 30px; color: var(--text-faint); } .empty svg { width: 58px; height: 58px; stroke: var(--line-bright); fill: none; stroke-width: 1.5; margin-bottom: 14px; } .empty h3 { font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.07em; color: var(--text-dim); margin: 0 0 8px; font-size: 18px; } .empty p { margin: 0; font-size: 14px; line-height: 1.6; } /* ====================================================================== Conversation ====================================================================== */ .thread { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 14px 12px 8px; display: flex; flex-direction: column; gap: 3px; background: radial-gradient(100% 40% at 50% 0%, rgba(72, 201, 214, 0.05), transparent 70%), var(--night-850); } .day-sep { align-self: center; margin: 16px 0 10px; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.15em; color: var(--text-faint); background: var(--night-700); border: 1px solid var(--line); padding: 4px 13px; border-radius: var(--radius-pill); } .sys-msg { align-self: center; text-align: center; font-size: 12.5px; color: var(--text-faint); padding: 5px 12px; margin: 5px 0; font-style: italic; } .msg { display: flex; gap: 8px; max-width: 88%; animation: pop 0.16s ease-out; } @keyframes pop { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } } @media (prefers-reduced-motion: reduce) { .msg { animation: none; } } .msg.mine { align-self: flex-end; flex-direction: row-reverse; } .msg.theirs { align-self: flex-start; } /* Groupement : messages consécutifs du même auteur */ .msg.grouped { margin-top: -1px; } .msg-avatar { flex: none; width: 30px; height: 30px; border-radius: 9px; display: grid; place-items: center; font-size: 12px; font-weight: 700; color: #04191d; align-self: flex-end; margin-bottom: 2px; } .msg.grouped .msg-avatar { visibility: hidden; } .bubble { position: relative; padding: 8px 12px 7px; border-radius: 16px; min-width: 0; word-wrap: break-word; overflow-wrap: anywhere; font-size: 15px; } .msg.theirs .bubble { background: var(--night-600); border: 1px solid var(--line); border-bottom-left-radius: 5px; } .msg.mine .bubble { background: linear-gradient(160deg, var(--cyan-deep), #16505c); border: 1px solid var(--cyan-dim); border-bottom-right-radius: 5px; box-shadow: 0 2px 14px rgba(72, 201, 214, 0.13); } .msg.grouped.theirs .bubble { border-top-left-radius: 6px; } .msg.grouped.mine .bubble { border-top-right-radius: 6px; } .msg-author { font-size: 12px; font-weight: 800; color: var(--cyan); margin-bottom: 2px; letter-spacing: 0.02em; } .msg.grouped .msg-author { display: none; } .msg-body { white-space: pre-wrap; } .msg-body .mention { color: var(--lightning); font-weight: 700; background: rgba(247, 221, 84, 0.1); padding: 0 3px; border-radius: 4px; } .msg-body a { color: var(--lightning); } .msg-time { font-size: 10.5px; color: rgba(219, 238, 242, 0.45); text-align: right; margin-top: 2px; user-select: none; } .msg.theirs .msg-time { color: var(--text-faint); } .reply-quote { border-left: 2.5px solid var(--ember); padding: 3px 0 3px 8px; margin-bottom: 5px; font-size: 13px; opacity: 0.78; background: rgba(0, 0, 0, 0.18); border-radius: 0 6px 6px 0; } .reply-quote strong { color: var(--ember); display: block; font-size: 11.5px; } .reply-quote span { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } /* --- Images P2P -------------------------------------------------------- */ .p2p-image { margin: 2px 0 4px; border-radius: 11px; overflow: hidden; background: rgba(0, 0, 0, 0.35); border: 1px solid var(--line); min-width: 190px; max-width: 260px; } .p2p-image img { display: block; width: 100%; height: auto; max-height: 340px; object-fit: cover; } .p2p-state { display: flex; align-items: center; gap: 9px; padding: 13px 12px; font-size: 13px; color: var(--text-dim); } .p2p-state svg { width: 19px; height: 19px; flex: none; stroke: var(--cyan); fill: none; stroke-width: 2; } .p2p-state.error svg { stroke: var(--danger); } .p2p-bar { height: 3px; background: rgba(255, 255, 255, 0.08); overflow: hidden; } .p2p-bar span { display: block; height: 100%; background: linear-gradient(90deg, var(--cyan), var(--lightning)); transition: width 0.2s; } .spin { animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* --- Saisie ------------------------------------------------------------ */ .composer { flex: none; border-top: 1px solid var(--line); background: linear-gradient(180deg, rgba(12, 33, 40, 0.96), var(--night-800)); padding: 8px 10px calc(8px + var(--safe-bottom)); backdrop-filter: blur(12px); } .reply-bar { display: none; align-items: center; gap: 10px; padding: 7px 10px; margin-bottom: 7px; background: rgba(238, 139, 61, 0.1); border-left: 2.5px solid var(--ember); border-radius: 0 9px 9px 0; font-size: 13px; } .reply-bar.show { display: flex; } .reply-bar div { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--text-dim); } .reply-bar strong { color: var(--ember); } .composer-row { display: flex; align-items: flex-end; gap: 8px; } .composer textarea { flex: 1; min-height: 44px; max-height: 130px; padding: 11px 15px; border-radius: 22px; background: var(--night-700); border: 1px solid var(--line); outline: none; resize: none; line-height: 1.35; } .composer textarea:focus { border-color: var(--cyan-dim); } .composer .icon-btn { width: 44px; height: 44px; border-radius: 50%; background: var(--night-700); border: 1px solid var(--line); } .send-btn { flex: none; width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; background: linear-gradient(160deg, var(--cyan), var(--cyan-deep)); color: #04191d; box-shadow: 0 3px 14px rgba(72, 201, 214, 0.3); transition: transform 0.12s, opacity 0.15s; } .send-btn:active { transform: scale(0.9); } .send-btn:disabled { opacity: 0.35; box-shadow: none; } .send-btn svg { width: 21px; height: 21px; fill: currentColor; } .typing-line { height: 16px; font-size: 11.5px; color: var(--cyan-dim); padding: 0 6px 3px; font-style: italic; } /* ====================================================================== Feuilles, modales, listes de réglages ====================================================================== */ .sheet-backdrop { position: fixed; inset: 0; z-index: 60; background: rgba(3, 10, 13, 0.68); backdrop-filter: blur(3px); display: none; align-items: flex-end; } .sheet-backdrop.open { display: flex; } .sheet { width: 100%; max-height: 86dvh; overflow-y: auto; background: var(--night-700); border: 1px solid var(--line); border-bottom: none; border-radius: 22px 22px 0 0; padding: 8px 16px calc(20px + var(--safe-bottom)); animation: sheet-up 0.24s cubic-bezier(0.22, 0.61, 0.36, 1); } @keyframes sheet-up { from { transform: translateY(100%); } to { transform: none; } } .sheet-grip { width: 40px; height: 4px; border-radius: 2px; background: var(--line-bright); margin: 6px auto 14px; } .sheet h3 { font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.06em; font-size: 18px; margin: 0 0 14px; } .sheet-action { display: flex; align-items: center; gap: 13px; width: 100%; padding: 14px 6px; text-align: left; border-bottom: 1px solid rgba(29, 68, 80, 0.45); font-size: 15px; } .sheet-action:last-child { border-bottom: none; } .sheet-action svg { width: 20px; height: 20px; flex: none; stroke: var(--cyan); fill: none; stroke-width: 2; stroke-linecap: round; } .sheet-action.danger { color: #f0a0a0; } .sheet-action.danger svg { stroke: var(--danger); } .opt-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 13px 4px; border-bottom: 1px solid rgba(29, 68, 80, 0.45); } .opt-row .label { font-size: 15px; } .opt-row .desc { font-size: 12.5px; color: var(--text-faint); margin-top: 2px; } /* Interrupteur */ .switch { flex: none; width: 50px; height: 29px; border-radius: var(--radius-pill); background: var(--night-500); border: 1px solid var(--line-bright); position: relative; transition: background 0.2s, border-color 0.2s; } .switch::after { content: ''; position: absolute; top: 2px; left: 2px; width: 23px; height: 23px; border-radius: 50%; background: var(--text-dim); transition: transform 0.2s, background 0.2s; } .switch.on { background: rgba(72, 201, 214, 0.25); border-color: var(--cyan); } .switch.on::after { transform: translateX(21px); background: var(--cyan); } /* Segments (tous / mentions / muet) */ .segmented { display: flex; gap: 4px; background: var(--night-800); border: 1px solid var(--line); border-radius: 11px; padding: 3px; } .segmented button { flex: 1; padding: 8px 6px; border-radius: 8px; font-size: 12.5px; color: var(--text-dim); transition: background 0.15s, color 0.15s; } .segmented button.active { background: var(--cyan-deep); color: var(--text); font-weight: 600; } /* ====================================================================== Panneau superadmin ====================================================================== */ .tabs { flex: none; display: flex; border-bottom: 1px solid var(--line); background: var(--night-800); } .tabs button { flex: 1; padding: 13px 4px; font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.08em; font-size: 13px; color: var(--text-faint); border-bottom: 2px solid transparent; transition: color 0.15s, border-color 0.15s; } .tabs button.active { color: var(--cyan); border-bottom-color: var(--cyan); } .tab-panel { display: none; flex: 1; overflow-y: auto; padding: 14px 14px calc(28px + var(--safe-bottom)); } .tab-panel.active { display: block; } .panel-card { background: var(--night-700); border: 1px solid var(--line); border-radius: var(--radius); padding: 15px; margin-bottom: 14px; } .panel-card h4 { font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.08em; font-size: 14px; margin: 0 0 12px; color: var(--ember); } .stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 9px; } .stat { background: var(--night-800); border: 1px solid var(--line); border-radius: 11px; padding: 12px 10px; text-align: center; } .stat .v { font-family: var(--font-display); font-size: 25px; color: var(--cyan); line-height: 1; } .stat .k { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.09em; color: var(--text-faint); margin-top: 5px; } .meter { height: 9px; border-radius: 5px; background: var(--night-900); border: 1px solid var(--line); overflow: hidden; margin: 10px 0 7px; } .meter span { display: block; height: 100%; background: linear-gradient(90deg, var(--cyan), var(--lightning), var(--ember)); transition: width 0.3s; } .admin-row { display: flex; align-items: center; gap: 11px; padding: 10px 4px; border-bottom: 1px solid rgba(29, 68, 80, 0.4); } .admin-row .group-main .group-name { font-size: 14.5px; } .admin-row .group-preview { font-size: 12px; } .dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--text-faint); } .dot.online { background: var(--success); box-shadow: 0 0 8px var(--success); } .dot.invited { background: var(--lightning); } .dot.blocked { background: var(--danger); } /* ====================================================================== Toasts ====================================================================== */ #toasts { position: fixed; left: 12px; right: 12px; bottom: calc(18px + var(--safe-bottom)); z-index: 200; display: flex; flex-direction: column; gap: 8px; pointer-events: none; } .toast { background: var(--night-600); border: 1px solid var(--line-bright); border-left: 3px solid var(--cyan); border-radius: 11px; padding: 12px 14px; font-size: 14px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.55); animation: toast-in 0.22s ease-out; } .toast.error { border-left-color: var(--danger); } .toast.ok { border-left-color: var(--success); } @keyframes toast-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } } /* Notification interne (message reçu, autre groupe) */ .inapp-notif { position: fixed; top: calc(var(--safe-top) + 8px); left: 10px; right: 10px; z-index: 300; display: flex; gap: 11px; align-items: center; padding: 11px 13px; background: rgba(16, 42, 50, 0.97); border: 1px solid var(--cyan-dim); border-radius: var(--radius); box-shadow: 0 12px 34px rgba(0, 0, 0, 0.6); animation: toast-in 0.2s ease-out; cursor: pointer; } .inapp-notif .t { font-weight: 700; font-size: 14px; } .inapp-notif .b { font-size: 13px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* ====================================================================== Tableau de bord ====================================================================== */ .kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(88px, 1fr)); gap: 8px; } .kpi { background: var(--night-800); border: 1px solid var(--line); border-radius: 11px; padding: 11px 9px; } .kpi .v { font-family: var(--font-display); font-size: 24px; line-height: 1; color: var(--text); } .kpi .k { font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-faint); margin-top: 5px; } .kpi.accent .v { color: var(--cyan); } .kpi.warn .v { color: var(--lightning); } .kpi.alert .v { color: var(--danger); } .chart-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 12px; } .chart-head h4 { margin: 0; } .chart-note { font-size: 11px; color: var(--text-faint); white-space: nowrap; } /* Les séries larges défilent horizontalement sans faire déborder la page. */ .chart-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0 -4px; padding: 0 4px; } .chart svg { display: block; } /* Grille et axes : volontairement en retrait. */ .chart .grid-line { stroke: var(--line); stroke-width: 1; opacity: 0.42; } .chart .axis-label { fill: var(--text-faint); font-size: 9.5px; font-family: var(--font-body); } .chart .value-label { fill: var(--text-dim); font-size: 10px; font-weight: 700; font-family: var(--font-body); } .chart .bar { fill: var(--cyan); transition: fill 0.12s; } .chart .bar-hit { fill: transparent; cursor: pointer; } .chart .bar-hit:hover + .bar, .chart .bar.active { fill: var(--lightning); } /* Barres horizontales (palmarès) */ .rank-row { display: grid; grid-template-columns: 1fr auto; gap: 4px 10px; align-items: center; padding: 7px 0; border-bottom: 1px solid rgba(29, 68, 80, 0.35); } .rank-row:last-child { border-bottom: none; } .rank-label { font-size: 13.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; gap: 6px; } .rank-value { font-size: 12px; font-weight: 700; color: var(--text-dim); font-variant-numeric: tabular-nums; } .rank-track { grid-column: 1 / -1; height: 7px; background: var(--night-900); border-radius: 4px; overflow: hidden; } .rank-fill { height: 100%; background: var(--cyan); border-radius: 4px; min-width: 2px; transition: width 0.3s; } .rank-row.sub .rank-fill { background: var(--ember); } .chart-empty { color: var(--text-faint); font-size: 13px; padding: 18px 0; text-align: center; } /* Tooltip des graphiques */ #chart-tip { position: fixed; z-index: 400; pointer-events: none; background: var(--night-600); border: 1px solid var(--line-bright); border-radius: 9px; padding: 7px 10px; font-size: 12px; box-shadow: 0 8px 22px rgba(0, 0, 0, 0.6); display: none; white-space: nowrap; } #chart-tip .tv { font-weight: 800; color: var(--cyan); } /* --- Journal d'audit --------------------------------------------------- */ .audit-row { display: flex; gap: 9px; padding: 8px 0; border-bottom: 1px solid rgba(29, 68, 80, 0.35); font-size: 12.5px; } .audit-row:last-child { border-bottom: none; } .audit-time { flex: none; color: var(--text-faint); font-size: 11px; width: 76px; font-variant-numeric: tabular-nums; } .audit-main { flex: 1; min-width: 0; } .audit-action { font-weight: 600; } .audit-detail { color: var(--text-faint); font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .audit-row.sev-warn .audit-action { color: var(--lightning); } .audit-row.sev-bad .audit-action { color: var(--danger); } .audit-row.sev-ok .audit-action { color: var(--success); } /* --- Demandes d'assistance --------------------------------------------- */ .help-card { background: linear-gradient(180deg, rgba(238, 139, 61, 0.14), rgba(16, 42, 50, 0.9)); border: 1px solid var(--ember-dim); border-radius: var(--radius); padding: 15px; margin-bottom: 14px; } .help-card h4 { font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.08em; font-size: 14px; margin: 0 0 12px; color: var(--ember); display: flex; align-items: center; gap: 8px; } .help-item { background: rgba(5, 15, 19, 0.5); border: 1px solid var(--line); border-radius: 11px; padding: 11px; margin-bottom: 9px; } .help-item:last-child { margin-bottom: 0; } .help-who { font-weight: 700; font-size: 14.5px; } .help-meta { font-size: 12px; color: var(--text-faint); margin: 2px 0 6px; } .help-msg { font-size: 13px; color: var(--text-dim); font-style: italic; margin-bottom: 9px; overflow-wrap: anywhere; } .help-actions { display: flex; gap: 7px; flex-wrap: wrap; } /* Pastille de compte sur l'onglet Administration */ .icon-btn { position: relative; } .icon-btn .pip { position: absolute; top: 5px; right: 5px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: var(--radius-pill); background: var(--ember); color: #1c0d03; font-size: 10px; font-weight: 800; display: grid; place-items: center; border: 2px solid var(--night-700); } /* Sélection multiple de groupes (affectation d'un membre) */ .group-picker { max-height: 210px; overflow-y: auto; border: 1px solid var(--line); border-radius: 11px; padding: 4px; background: var(--night-800); } .pick-row { display: flex; align-items: center; gap: 10px; padding: 9px 8px; border-radius: 8px; cursor: pointer; font-size: 14px; } .pick-row:active { background: rgba(72, 201, 214, 0.08); } .pick-row.child { padding-left: 24px; } .pick-box { flex: none; width: 21px; height: 21px; border-radius: 6px; border: 1.5px solid var(--line-bright); display: grid; place-items: center; transition: background 0.14s, border-color 0.14s; } .pick-row.on .pick-box { background: var(--cyan); border-color: var(--cyan); } .pick-row.on .pick-box::after { content: ''; width: 10px; height: 6px; border-left: 2px solid #04191d; border-bottom: 2px solid #04191d; transform: rotate(-45deg) translate(1px, -1px); } .pick-row.member-of { opacity: 0.55; } .chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 9px; border-radius: var(--radius-pill); background: var(--night-800); border: 1px solid var(--line-bright); font-size: 12px; margin: 0 5px 5px 0; } .chip button { color: var(--text-faint); font-size: 15px; line-height: 1; padding: 0 0 2px; } .chip.admin { border-color: var(--lightning); color: var(--lightning); } /* Écran plus large : on centre dans un « téléphone ». */ @media (min-width: 720px) { body { background: #03090c; } #app { max-width: 460px; margin: 0 auto; border-left: 1px solid var(--line); border-right: 1px solid var(--line); } } /* ====================================================================== */ /* Signalement, inscription libre, import de tableur, épingles */ /* ====================================================================== */ .tag.flagged { color: var(--danger); } /* Note d'accueil pour un numéro encore inconnu, sur l'écran d'inscription. */ .auth-note { font-size: 13px; line-height: 1.5; color: var(--text-dim); background: rgba(72, 201, 214, 0.08); border-left: 2px solid var(--cyan-deep); border-radius: 0 8px 8px 0; padding: 10px 12px; margin: 0 0 16px; } .panel-note { font-size: 12.5px; line-height: 1.5; color: var(--text-faint); margin: -6px 0 12px; } /* --- Import d'un tableur --------------------------------------------- */ #import-result { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 12px; } .import-summary { font-size: 13.5px; line-height: 1.55; color: var(--text-dim); margin-bottom: 10px; } .import-mapping { font-size: 12px; color: var(--text-faint); margin-bottom: 10px; } .import-mapping .tag { margin-right: 4px; color: var(--cyan-dim); white-space: nowrap; } .import-warn { margin: 8px 0 0; padding: 8px 10px; font-size: 12.5px; line-height: 1.5; color: var(--lightning); background: rgba(247, 221, 84, 0.08); border-radius: 8px; } .import-fix { margin: 10px 0; font-size: 13px; } .import-fix summary { cursor: pointer; color: var(--cyan); padding: 6px 0; } .import-rejected { margin: 6px 0 0; padding-left: 18px; font-size: 12.5px; color: var(--text-faint); line-height: 1.6; } /* Le tableau d'aperçu défile seul : sur un téléphone, il déborderait. */ .import-preview { width: 100%; border-collapse: collapse; font-size: 12.5px; display: block; overflow-x: auto; white-space: nowrap; } .import-preview th { text-align: left; font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--cyan-dim); padding: 4px 8px 4px 0; border-bottom: 1px solid var(--line); } .import-preview td { padding: 5px 8px 5px 0; color: var(--text-dim); border-bottom: 1px solid rgba(42, 95, 110, 0.25); } .import-preview tr.known td { color: var(--text-faint); font-style: italic; } /* --- Bandeau des messages épinglés ------------------------------------ */ .pin-bar { flex: 0 0 auto; max-height: 132px; overflow-y: auto; background: var(--night-700); border-bottom: 1px solid var(--line); } .pin-item { display: flex; align-items: center; gap: 9px; padding: 9px 14px; cursor: pointer; border-left: 3px solid var(--lightning); } .pin-item + .pin-item { border-top: 1px solid rgba(42, 95, 110, 0.3); } .pin-item:active { background: rgba(247, 221, 84, 0.07); } .pin-item > svg { width: 15px; height: 15px; flex: 0 0 auto; fill: none; stroke: var(--lightning); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; } .pin-text { min-width: 0; font-size: 13px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .pin-text strong { color: var(--text); margin-right: 6px; } .msg.pinned .bubble { box-shadow: inset 2px 0 0 var(--lightning); } .pin-mark { width: 10px; height: 10px; vertical-align: -1px; fill: none; stroke: var(--lightning); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; } /* ====================================================================== */ /* Accusés de lecture */ /* ====================================================================== */ .receipt { width: 15px; height: 11px; margin-left: 5px; vertical-align: -1px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; opacity: 0.55; } /* Envoyé (une coche) et remis (deux coches) restent discrets ; la lecture passe en cyan, c'est la seule information qu'on cherche d'un coup d'œil. */ .receipt.delivered { opacity: 0.75; } .receipt.read, .receipt.read-partial { stroke: var(--cyan); opacity: 1; } .receipt.read-partial { opacity: 0.7; } .readers-block { margin-bottom: 16px; } .readers-title { font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; font-weight: 700; margin-bottom: 8px; color: var(--text-faint); } .readers-title.read { color: var(--cyan); } .readers-title.delivered { color: var(--text-dim); } .readers-row { display: flex; align-items: center; gap: 10px; padding: 6px 0; font-size: 14px; color: var(--text-dim); } .sheet-note { color: var(--text-faint); font-size: 13px; font-style: italic; margin: -8px 0 16px; } .empty-note { color: var(--text-faint); font-size: 13.5px; line-height: 1.5; margin: 4px 0; } /* ====================================================================== */ /* Modération */ /* ====================================================================== */ .tab-badge { display: inline-block; min-width: 17px; padding: 1px 5px; margin-left: 4px; border-radius: var(--radius-pill); background: var(--danger); color: #fff; font-size: 10px; font-weight: 800; vertical-align: 1px; } .alert-row { padding: 11px 0; border-bottom: 1px solid rgba(42, 95, 110, 0.3); } .alert-row.pending { border-left: 3px solid var(--danger); padding-left: 11px; } .alert-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; } .alert-time { font-size: 11.5px; color: var(--text-faint); } .alert-body { font-size: 14px; color: var(--text); line-height: 1.45; margin-bottom: 5px; overflow-wrap: anywhere; } .alert-meta { font-size: 12px; color: var(--text-faint); margin-bottom: 8px; } .alert-meta strong { color: var(--ember); } /* ====================================================================== */ /* Supervision machine et réseau */ /* ====================================================================== */ .sys-live { display: flex; align-items: center; gap: 9px; padding: 10px 15px; font-size: 12.5px; color: var(--text-dim); } .sys-live .btn-link { margin-left: auto; width: auto; } .sys-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-faint); flex: 0 0 auto; } .sys-dot.live { background: var(--success); box-shadow: 0 0 0 0 rgba(91, 191, 122, 0.6); animation: sys-pulse 2.4s infinite; } .sys-dot.off { background: var(--danger); } @keyframes sys-pulse { 70% { box-shadow: 0 0 0 7px rgba(91, 191, 122, 0); } 100% { box-shadow: 0 0 0 0 rgba(91, 191, 122, 0); } } @media (prefers-reduced-motion: reduce) { .sys-dot.live { animation: none; } } .sys-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); gap: 10px; padding: 0 15px 14px; } .sys-card { background: var(--night-700); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px; } .sys-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--cyan-dim); font-weight: 700; margin-bottom: 6px; } .sys-value { font-size: 17px; font-weight: 700; color: var(--text); margin-bottom: 8px; font-variant-numeric: tabular-nums; } .sys-value.warn { color: var(--lightning); } .sys-value.danger { color: var(--danger); } .sys-hint, .sys-detail { font-size: 11.5px; color: var(--text-faint); line-height: 1.45; } .sys-detail { padding-top: 8px; } .meter span.warn { background: var(--lightning); } .meter span.danger { background: var(--danger); } .spark-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; } .spark-label { font-size: 11.5px; color: var(--text-faint); margin-bottom: 5px; } .spark-label strong { color: var(--text); font-variant-numeric: tabular-nums; } .spark { width: 100%; height: 44px; display: block; } .spark.tall { height: 70px; } .spark polyline { fill: none; stroke: var(--cyan); stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; } .spark.ember polyline { stroke: var(--ember); } /* ====================================================================== */ /* Bac à sable */ /* ====================================================================== */ .sandbox-banner { padding: 9px 15px; font-size: 12.5px; line-height: 1.45; color: var(--lightning); background: rgba(247, 221, 84, 0.09); border-bottom: 1px solid rgba(247, 221, 84, 0.25); } #screen-sandbox .composer .field label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--cyan-dim); } /* ====================================================================== */ /* Poste de travail : l'administration devient un vrai tableau de bord */ /* ====================================================================== */ /* Le reste de l'application reste un « téléphone » centré, y compris sur grand écran — c'est un outil de terrain, utilisé au pouce. Seul le panneau superadmin s'étale : c'est le seul écran qu'on ouvre assis. `#app.desk` est posé par le script à l'ouverture du panneau, parce que la largeur du cadre se décide au niveau du conteneur, pas de l'écran. */ @media (min-width: 1024px) { #app.desk { max-width: none; border-left: none; border-right: none; } /* `.active` est indispensable : la visibilité des écrans passe par `display`, et une règle non qualifiée rendrait le panneau permanent, posé par-dessus l'écran de connexion. */ #screen-admin.active { display: grid; grid-template-columns: 236px minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); grid-template-areas: 'head head' 'nav main'; overflow: hidden; } #screen-admin.active > .topbar { grid-area: head; } #screen-admin.active > .tabs { grid-area: nav; flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 3px; padding: 16px 12px; border-right: 1px solid var(--line); border-bottom: none; overflow-y: auto; } /* Sans cette remise à zéro, `flex: 1` étire chaque onglet sur toute la hauteur de la colonne et les libellés se retrouvent à cent pixels les uns des autres. */ #screen-admin.active > .tabs button { flex: 0 0 auto; text-align: left; padding: 11px 14px; border-radius: 10px; border-bottom: none; font-size: 13.5px; } #screen-admin.active > .tabs button.active { background: rgba(72, 201, 214, 0.12); color: var(--cyan); border-bottom-color: transparent; } #screen-admin.active > .tab-panel { grid-area: main; min-width: 0; overflow-y: auto; padding: 20px 24px 40px; } /* Grille, et non colonnes CSS : `column-count` fragmente les cartes et, combiné à des hauteurs variables, les fait se chevaucher. La grille garde chaque carte entière et alignée en haut de sa colonne. */ #screen-admin.active > .tab-panel.active { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 18px; align-content: start; align-items: start; } #screen-admin.active .panel-card { margin-bottom: 0; } /* Ces deux blocs se lisent sur toute la largeur. */ #screen-admin.active #help-requests-card, #screen-admin.active .sys-live, #screen-admin.active .sys-grid { grid-column: 1 / -1; } #screen-admin.active .sys-grid { grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); padding: 0; } #screen-admin.active .sys-live { padding: 0 0 4px; } /* Les courbes ont besoin de largeur pour être lisibles : elles occupent deux colonnes, là où une jauge se contente d'une. */ #tab-system .panel-card { grid-column: span 2; } .spark.tall { height: 110px; } /* Le bac à sable garde la forme d'une conversation : une colonne. */ #screen-sandbox.active { max-width: 880px; margin: 0 auto; border-left: 1px solid var(--line); border-right: 1px solid var(--line); } } @media (min-width: 1600px) { #screen-admin.active { grid-template-columns: 262px minmax(0, 1fr); } #screen-admin.active > .tab-panel { padding: 26px 34px 48px; } } /* ====================================================================== */ /* Poste de travail : liste et conversation côte à côte */ /* ====================================================================== */ /* Au-delà de 1024 px, le cadre « téléphone » cède la place à deux volets : la liste des groupes à gauche, la conversation à droite. Étirer une bulle de message sur 1600 px serait pire que le cadre étroit — c'est la cohabitation des deux volets qui rend la largeur utile, pas l'étirement. `#app.shell` est posé à la connexion : l'écran d'accueil, lui, reste une carte centrée. */ #chat-placeholder { display: none; } @media (min-width: 1024px) { #app.shell { max-width: none; border-left: none; border-right: none; } /* Volet gauche : la liste garde une largeur de lecture confortable. */ #app.shell #screen-groups { right: auto; width: 372px; border-right: 1px solid var(--line); } /* Volet droit : la conversation ne recouvre plus la liste. */ #app.shell #screen-chat { left: 372px; animation: none; } /* Les bulles gardent une largeur de lecture : sur un écran large, une ligne de 1200 px est illisible. */ #app.shell #screen-chat .thread, #app.shell #screen-chat .composer > * { max-width: 1000px; width: 100%; margin-inline: auto; } #app.shell #screen-chat .msg { max-width: 74%; } /* Le bouton « retour » n'a plus de sens quand la liste est déjà visible. */ #app.shell #screen-chat [data-close-chat] { display: none; } /* Fond du volet droit tant qu'aucune conversation n'est ouverte. */ #app.shell #chat-placeholder { position: absolute; top: 0; right: 0; bottom: 0; left: 372px; z-index: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; text-align: center; padding: 40px; color: var(--text-faint); background: var(--night-850); } #app.shell #chat-placeholder svg { width: 46px; height: 46px; fill: none; stroke: currentColor; stroke-width: 1.4; opacity: 0.4; margin-bottom: 8px; } #app.shell #chat-placeholder h3 { font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.08em; font-size: 17px; color: var(--text-dim); margin: 0; } #app.shell #chat-placeholder p { margin: 0; font-size: 13.5px; } /* Les réglages restent une feuille étroite, centrée sur le volet droit. */ #app.shell #screen-settings { left: 372px; animation: none; } #app.shell #screen-settings > *:not(.topbar) { max-width: 760px; width: 100%; margin-inline: auto; } } @media (min-width: 1500px) { #app.shell #screen-groups { width: 400px; } #app.shell #screen-chat, #app.shell #screen-settings, #app.shell #chat-placeholder { left: 400px; } }