/* ===== Thèmes ===================================================== Toutes les couleurs de l'UI passent par ces variables. Pour AJOUTER un thème plus tard : 1) copier un bloc [data-theme="…"] ci-dessous en changeant les valeurs, 2) ajouter son {id,label} au registre THEMES (voir le JS). Le reste (sélecteur, persistance, application) est automatique. */ /* --font : police par défaut (mono). Un thème peut la surcharger (voir "soft"). Les blocs plus spécifiques qui ne redéfinissent pas --font héritent de :root. */ :root{color-scheme:dark;--font:ui-monospace,SFMono-Regular,Menlo,monospace;--bubble:#1f6feb;--bg:#0d1117;--panel:#161b22;--border:#30363d;--text:#e6edf3;--dim:#7d8590;--accent:#58a6ff;--accent-bg:rgba(88,166,255,.12);--ok:#58a6ff;--warn:#d29922;--err:#f85149;--mag:#bc8cff;--code-bg:#0d1117;--danger-bg:#3d1f23;--warn-bg:#3d2f1f} [data-theme="dark"]{color-scheme:dark;--bg:#0d1117;--panel:#161b22;--border:#30363d;--text:#e6edf3;--dim:#7d8590;--accent:#58a6ff;--accent-bg:rgba(88,166,255,.12);--ok:#58a6ff;--warn:#d29922;--err:#f85149;--mag:#bc8cff;--code-bg:#0d1117;--danger-bg:#3d1f23;--warn-bg:#3d2f1f} [data-theme="light"]{color-scheme:light;--bg:#f0f1f4;--panel:#f8f9fb;--border:#d7dbe1;--text:#24292f;--dim:#636b74;--accent:#0969da;--accent-bg:rgba(9,105,218,.10);--ok:#0969da;--warn:#9a6700;--err:#cf222e;--mag:#8250df;--code-bg:#e6e9ee;--danger-bg:#fbe6e6;--warn-bg:#fbefda} /* "doux" — thème clair chaud + police Lexend (lecture agréable). */ [data-theme="soft"]{color-scheme:light;--font:'Lexend',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;--bubble:#c2611f;--bg:#faf8f4;--panel:#ffffff;--border:#e8e3d9;--text:#2c2a26;--dim:#8c8577;--accent:#c2611f;--accent-bg:rgba(194,97,31,.10);--ok:#c2611f;--warn:#b45309;--err:#dc2626;--mag:#9a5bd6;--code-bg:#f3f0ea;--danger-bg:#fbe9e7;--warn-bg:#fbf1e0} /* "doux sombre" — même esprit que "doux" (Lexend, tons chauds) sur fond sombre chaud. */ [data-theme="soft-dark"]{color-scheme:dark;--font:'Lexend',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;--bubble:#c2611f;--bg:#1c1917;--panel:#26221e;--border:#3a342c;--text:#ece7de;--dim:#9c9284;--accent:#e8965a;--accent-bg:rgba(232,150,90,.14);--ok:#e8965a;--warn:#d9a441;--err:#f07862;--mag:#c39be8;--code-bg:#171412;--danger-bg:#3d2420;--warn-bg:#3a2f1c} /* "ChatGPT" — monochrome (noir & blanc), police système, aucun accent coloré. Seules les erreurs gardent un rouge discret pour rester lisibles. */ [data-theme="gpt"]{color-scheme:light;--font:system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;--bubble:#e8e8e8;--bg:#ffffff;--panel:#f9f9f9;--border:#e3e3e3;--text:#0d0d0d;--dim:#8f8f8f;--accent:#0d0d0d;--accent-bg:rgba(0,0,0,.06);--ok:#0d0d0d;--warn:#5d5d5d;--err:#c0392b;--mag:#5d5d5d;--code-bg:#f4f4f4;--danger-bg:#fbeae8;--warn-bg:#f0f0f0} /* Bulle utilisateur claire : le texte blanc par défaut (.msg.user) serait illisible. */ [data-theme="gpt"] .msg.user{color:var(--text)} *{box-sizing:border-box} body{margin:0;font-family:var(--font);background:var(--bg);color:var(--text);height:100vh;height:100dvh;display:flex;font-size:14px} /* PWA plein écran (viewport-fit=cover) : on décale le contenu des bords pour ne pas passer sous l'encoche / la barre système / l'indicateur d'accueil. Les env(safe-area-inset-*) valent 0 hors PWA, donc aucun impact ailleurs. */ body{padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)} .side{width:320px;border-right:1px solid var(--border);padding:16px;overflow-y:auto;flex-shrink:0} .main{flex:1;display:flex;flex-direction:column;min-width:0} #menubtn{display:none;position:fixed;top:calc(10px + env(safe-area-inset-top));left:calc(10px + env(safe-area-inset-left));z-index:20;background:var(--panel);border:1px solid var(--border);color:var(--text);width:40px;height:40px;border-radius:6px;font-size:18px;cursor:pointer} #backdrop{display:none;position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:10} @media (max-width:720px){ .side{position:fixed;inset:0 auto 0 0;width:80%;max-width:320px;z-index:15;transform:translateX(-100%);transition:transform .2s;background:var(--bg);padding-top:calc(16px + env(safe-area-inset-top));padding-left:calc(16px + env(safe-area-inset-left))} .side.open{transform:translateX(0)} #menubtn,#backdrop.open{display:block} body.drawer-open #menubtn{display:none} .main{width:100%} #chat{padding:60px 8px 12px} .msg{max-width:92%} #chat .msg.assistant,#chat .msg.reasoning{max-width:100%} #inputbar{padding:8px;gap:4px} #send,#stop{padding:0 12px} h1{margin-left:48px} /* Petit écran (menu replié en tiroir) : on masque l'aide clavier — inutile et ça prend de la place. Elle reste visible sur desktop. */ #sendhint{display:none} } /* Desktop : menu plus large et bulles (badges) un peu plus grosses. */ @media (min-width:721px){ .side{width:380px} .preset-meta .qtag,.preset-meta .rtag,.preset-meta .btag{font-size:11px;padding:2px 9px;border-radius:9px} .preset-meta .qtag svg,.preset-meta .rtag svg,.preset-meta .btag svg{width:11px;height:11px} } h1{margin:0;font-size:18px;color:var(--accent)} #brand{display:inline-flex;align-items:baseline} #ver{font-size:10px;font-weight:400;color:var(--dim);margin-left:5px;letter-spacing:0} .sidehead{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:18px} /* pastille d'état service, en haut à droite de la barre latérale */ .statuspill{display:inline-flex;align-items:center;gap:6px;font-size:11px;padding:3px 10px;border-radius:999px;border:1px solid var(--border);background:var(--panel);color:var(--dim);font-weight:600;white-space:nowrap;cursor:pointer} .statuspill.ok{color:var(--ok);border-color:color-mix(in srgb,var(--ok) 45%,transparent);background:color-mix(in srgb,var(--ok) 12%,transparent)} .statuspill.err{color:var(--err);border-color:color-mix(in srgb,var(--err) 45%,transparent);background:color-mix(in srgb,var(--err) 12%,transparent)} .statuspill.loading{color:var(--warn);border-color:color-mix(in srgb,var(--warn) 45%,transparent);background:color-mix(in srgb,var(--warn) 12%,transparent)} .statuspill.loading .dot{animation:pulse 1s ease-in-out infinite} @keyframes pulse{0%,100%{opacity:1}50%{opacity:.25}} .statuspill .dot{width:7px;height:7px;border-radius:50%;background:currentColor} .statuspill .port{opacity:.6;font-weight:400} /* en-tête + bouton d'ajout de skill (toujours visible) */ .skillshead{display:flex;align-items:center;justify-content:space-between;margin:12px 0 5px} .skillshead>span{font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:.08em;font-weight:600} .addbtn{font-size:11px;padding:3px 11px 4px;background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:6px;cursor:pointer;line-height:1.2} .addbtn:hover{border-color:var(--accent);color:var(--accent)} .mem-count{font-size:10px;color:var(--dim);font-weight:400;letter-spacing:0;text-transform:none;margin-left:4px} /* Titre de sous-section (Mémoire / Accès internet) : simple libellé, PAS de trait (le trait est réservé aux sections principales — cf. `details`). La séparation visuelle vient de la carte englobante .gated-block. */ .subhead{position:relative;display:flex;align-items:center;font-size:10px;text-transform:uppercase;letter-spacing:.09em;color:var(--accent);font-weight:600;margin:0 0 6px} /* Barre repliable « Pages » : un seul chevron, bouton + ajouter aligné à droite. */ .pages-bar{display:flex;align-items:center;gap:8px;cursor:pointer;user-select:none;padding:7px 0;margin-top:4px} .pages-bar .pages-caret{flex-shrink:0;font-size:9px;color:var(--dim);transition:transform .12s} .pages-bar.open .pages-caret{transform:rotate(90deg)} .pages-bar .pages-title{font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:var(--dim);font-weight:600} .pages-bar .addbtn{margin-left:auto} .mem-search{width:100%;box-sizing:border-box;background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:5px 9px;font:inherit;font-size:12px;margin:0 0 6px} .mem-search:focus{outline:none;border-color:var(--accent)} .mem-list{max-height:240px;overflow-y:auto;overscroll-behavior:contain} .mem-list .preset{margin:3px 0;padding:5px 9px} .mem-more{font-size:11px;color:var(--dim);text-align:center;padding:6px 0 2px} .ask-overlay{position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:60;display:flex;align-items:center;justify-content:center;padding:20px} .ask-box{background:var(--bg);border:1px solid var(--border);border-radius:10px;width:100%;max-width:420px;padding:20px;box-shadow:0 12px 40px rgba(0,0,0,.5);animation:askpop .12s ease-out} @keyframes askpop{from{opacity:0;transform:translateY(6px) scale(.98)}to{opacity:1;transform:none}} .ask-title{font-size:15px;font-weight:600;color:var(--text);margin-bottom:8px} .ask-msg{font-size:13px;color:var(--dim);line-height:1.5;white-space:pre-wrap;word-break:break-word} .ask-input{width:100%;box-sizing:border-box;margin-top:12px;background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:9px 11px;font:inherit;font-size:13px} .ask-input:focus{outline:none;border-color:var(--accent)} .ask-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:18px} .ask-actions button{margin:0;padding:7px 16px} .ask-ok{border-color:var(--accent);color:var(--accent)} .ask-ok.danger{border-color:var(--err);color:var(--err)} #brand-a{display:inline-block;line-height:1;max-width:0;opacity:0;overflow:hidden;color:var(--text);transition:max-width .35s ease,opacity .35s ease} #brand.agent #brand-a{max-width:1ch;opacity:1;margin-right:.04em} /* interrupteur (switch) */ .switchrow{position:relative;display:flex;align-items:center;gap:9px;font-size:12px;padding:6px 0;cursor:pointer;user-select:none} /* Sous-réglage du mode agent inaccessible quand l'agent est off : grisé + inerte. */ /* Sous-réglages du mode agent présentés en CARTES (bordure + fond) pour ne pas les confondre avec les traits des sections principales. */ .gated-block{margin-top:10px;border:1px solid var(--border);border-radius:8px;padding:9px 11px;background:var(--panel);transition:opacity .15s} .gated-block>.switchrow:first-of-type{padding-top:0} .gated-block.gated{opacity:.4;pointer-events:none;filter:grayscale(.4)} .switch{position:relative;display:inline-block;width:36px;height:20px;flex:none} .switch input{position:absolute;opacity:0;width:0;height:0} .switch .slider{position:absolute;inset:0;background:var(--border);border-radius:999px;transition:background .25s ease} .switch .slider::before{content:"";position:absolute;width:14px;height:14px;left:3px;top:3px;background:#fff;border-radius:50%;transition:transform .25s ease;box-shadow:0 1px 2px rgba(0,0,0,.4)} .switch input:checked + .slider{background:var(--accent)} .switch input:checked + .slider::before{transform:translateX(16px)} .switch input:focus-visible + .slider{box-shadow:0 0 0 2px var(--bg),0 0 0 4px var(--accent)} h2{margin:20px 0 8px;font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:.1em;font-weight:600} details{margin:7px 0;border-top:1px solid var(--border);padding-top:4px} details>summary{font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:.1em;font-weight:600;cursor:pointer;padding:3px 0;list-style:none;display:flex;justify-content:space-between;align-items:center;user-select:none} details>summary::-webkit-details-marker{display:none} details>summary::after{content:"▸";transition:transform .15s;color:var(--dim);font-size:10px} details[open]>summary::after{transform:rotate(90deg)} details>summary:hover{color:var(--text)} details>div,details>textarea{margin-top:6px} .preset-add{display:none;font-size:14px;padding:0 8px;margin:0 8px 0 auto;line-height:1.4;background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:6px;cursor:pointer} .preset-add:hover{border-color:var(--accent);color:var(--accent)} details[open]>summary>.preset-add{display:inline-block} .tag{display:inline-block;padding:2px 8px;border-radius:10px;font-size:11px;background:var(--panel);border:1px solid var(--border)} .tag.ok{color:var(--ok);border-color:var(--ok)} .tag.err{color:var(--err);border-color:var(--err)} button{background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:6px 10px;font:inherit;cursor:pointer;margin:2px} button:hover{border-color:var(--accent);color:var(--accent)} button:disabled{opacity:.5;cursor:not-allowed} .row{display:flex;gap:4px;flex-wrap:wrap} .preset{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:6px 10px;border:1px solid var(--border);border-radius:6px;margin:4px 0;cursor:pointer;background:var(--panel)} .preset:hover{border-color:var(--accent)} .preset.active{border-color:var(--accent);color:var(--accent);border-width:1.5px;padding:5.5px 9.5px} .preset>span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} .preset>button{flex-shrink:0} .preset-info{flex:1;min-width:0} .preset-name{min-width:0;overflow-wrap:anywhere;word-break:break-word} .preset-edit{flex-shrink:0;align-self:flex-start;margin:-3px -4px 0 0;padding:2px 4px;font-size:13px;line-height:1;background:transparent;border:none;opacity:.45} .preset-edit:hover{opacity:1;color:var(--accent)} .preset-meta{display:flex;align-items:center;gap:6px;margin-top:3px;flex-wrap:wrap} .qtag{flex-shrink:0;font-size:9px;padding:1px 6px;border:1px solid var(--border);color:var(--dim);border-radius:8px;letter-spacing:.03em;text-transform:uppercase} .rtag{flex-shrink:0;display:inline-flex;align-items:center;gap:3px;font-size:9px;padding:1px 6px;border:1px solid var(--border);color:var(--dim);border-radius:8px;letter-spacing:.03em} .btag{flex-shrink:0;display:inline-flex;align-items:center;gap:3px;font-size:9px;padding:1px 6px;border:1px solid var(--border);color:var(--dim);border-radius:8px;letter-spacing:.03em} /* Petit « ? » d'aide : bulle au survol/clic au lieu d'un pavé de texte permanent. */ .help{display:inline-flex;align-items:center;justify-content:center;width:15px;height:15px;margin-left:6px;flex-shrink:0;font-size:10px;font-weight:600;line-height:1;color:var(--dim);border:1px solid var(--border);border-radius:50%;cursor:help;user-select:none;vertical-align:middle} .help:hover{color:var(--accent);border-color:var(--accent)} /* La bulle est ancrée à la ligne (.switchrow position:relative), pas au « ? », pour rester alignée au bord gauche du panneau et ne pas déborder. */ .help>.tip{display:none;position:absolute;z-index:40;left:0;right:0;top:calc(100% + 2px);padding:8px 10px;background:var(--bg);border:1px solid var(--border);border-radius:6px;font-size:11px;font-weight:400;line-height:1.4;color:var(--text);box-shadow:0 4px 16px rgba(0,0,0,.4);white-space:normal;text-align:left;text-transform:none;letter-spacing:normal;cursor:auto} .help:hover>.tip,.help:focus>.tip,.help.open>.tip{display:block} .kv{display:flex;justify-content:space-between;gap:8px;padding:4px 0;border-bottom:1px solid var(--border);font-size:12px} .kv span:first-child{color:var(--dim);flex-shrink:0} .kv span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;direction:rtl;text-align:right;min-width:0} .bar{height:6px;background:var(--panel);border-radius:3px;overflow:hidden;margin:2px 0} .bar>div{height:100%;background:var(--accent)} #chat{flex:1;overflow-y:auto;padding:20px;display:flex;flex-direction:column;gap:14px} .msg{max-width:80%;padding:10px 14px;border-radius:10px;white-space:pre-wrap;word-wrap:break-word;line-height:1.45} .msg.assistant,.msg.reasoning{white-space:normal} .msg .body{overflow-wrap:anywhere;word-break:break-word} .msg.user{align-self:flex-end;background:var(--bubble);color:#fff} .msg.user .label{color:rgba(255,255,255,.8)} .msg.assistant{align-self:flex-start;background:var(--panel);border:1px solid var(--border)} .msg.assistant.errmsg{border-color:rgba(248,81,73,.55);background:rgba(248,81,73,.08);color:var(--err)} .msg .body>*{margin:1em 0} .msg .body>*:first-child{margin-top:0} .msg .body>*:last-child{margin-bottom:0} .msg .body h1,.msg .body h2,.msg .body h3,.msg .body h4{font-weight:600;line-height:1.25;margin:1.2em 0 .5em} .msg .body h1{font-size:1.3em} .msg .body h2{font-size:1.15em} .msg .body h3{font-size:1em} .msg .body h4{font-size:.95em} .msg .body ul,.msg .body ol{padding-left:1.4em} .msg .body li{margin:.15em 0} .msg .body li>p{margin:0} .msg.assistant .body code{background:var(--code-bg);padding:1px 5px;border-radius:3px;font-size:.9em;overflow-wrap:anywhere;word-break:break-word} .msg.assistant .body pre,.msg.reasoning .body pre{position:relative;background:var(--code-bg);border:1px solid var(--border);border-radius:6px;padding:10px;overflow-x:auto;max-width:100%;margin:.5em 0} .copybtn{position:absolute;bottom:6px;right:6px;font-size:11px;padding:3px 8px;margin:0;background:var(--panel);border:1px solid var(--border);color:var(--dim);border-radius:5px;opacity:.5;transition:opacity .15s,color .15s} .msg.assistant .body pre:hover .copybtn,.msg.reasoning .body pre:hover .copybtn{opacity:1} .copybtn:hover{border-color:var(--accent);color:var(--accent)} .copybtn.done{color:var(--ok);border-color:var(--ok);opacity:1} .msg.assistant .body pre code,.msg.reasoning .body pre code{background:transparent;padding:0;font-size:.85em;line-height:1.4} .msg.assistant .body blockquote{border-left:3px solid var(--border);padding:0 0 0 10px;margin:.4em 0;color:var(--dim)} .msg.assistant .body a{color:var(--accent);text-decoration:none} .msg.assistant .body a:hover{text-decoration:underline} .msg.assistant .body table{border-collapse:collapse;margin:.5em 0} .msg.assistant .body th,.msg.assistant .body td{border:1px solid var(--border);padding:4px 8px} .msg.assistant .body hr{border:none;border-top:1px solid var(--border);margin:.6em 0} #scrollbtn{position:absolute;bottom:80px;right:20px;background:var(--panel);border:1px solid var(--border);color:var(--accent);width:36px;height:36px;border-radius:50%;cursor:pointer;display:none;font-size:16px;z-index:5} #scrollbtn.show{display:block} .msg.reasoning{align-self:flex-start;background:transparent;border:1px dashed var(--border);color:var(--mag);font-size:12px;max-width:90%;overflow-wrap:anywhere;word-break:break-word} .msg.tool{align-self:flex-start;background:transparent;border:1px dashed var(--border);max-width:90%;white-space:normal;padding:8px 12px;font-size:12px;overflow-wrap:anywhere;word-break:break-word} .msg.tool .tool-head{font-size:12px;color:var(--accent);font-weight:600;margin-bottom:6px} .msg.tool .tool-sub{font-size:10px;color:var(--dim);text-transform:uppercase;letter-spacing:.1em;margin:8px 0 4px} .msg.tool pre{position:relative;background:var(--code-bg);border:1px solid var(--border);border-radius:6px;padding:8px 10px;overflow:auto;margin:0;max-height:280px} .msg.tool pre code{background:transparent;padding:0;font-size:.82em;line-height:1.4;white-space:pre} .msg.tool .tool-caret{color:var(--accent);animation:toolblink 1s step-end infinite} .msg.tool .tool-wait{font-size:12px;color:var(--dim);margin-top:8px;animation:toolblink 1.2s ease-in-out infinite} @keyframes toolblink{0%,100%{opacity:.45}50%{opacity:1}} /* Indicateur « le modèle réfléchit » : 3 points animés avant le 1er token. */ .msg.typing{display:inline-flex;gap:5px;align-items:center;padding:14px 16px} .msg.typing span{width:7px;height:7px;border-radius:50%;background:var(--dim);animation:typingdot 1.2s infinite ease-in-out} .msg.typing span:nth-child(2){animation-delay:.16s} .msg.typing span:nth-child(3){animation-delay:.32s} @keyframes typingdot{0%,70%,100%{opacity:.25;transform:translateY(0)}35%{opacity:1;transform:translateY(-4px)}} .msg .label{font-size:10px;color:var(--dim);text-transform:uppercase;letter-spacing:.1em;margin-bottom:4px;display:block} /* Bulles repliables (reasoning / tool) : une fois la réponse arrivée, on les replie en douceur pour désencombrer le fil, tout en gardant le label (et son compteur de tokens) cliquable pour redéplier. */ .msg.collapsible .label{cursor:pointer;user-select:none;margin-bottom:0} /* ===== Affichage simple ========================================== Mode "simple" (Apparence) : masque le raisonnement, les appels d'outils, les détails de vitesse sur les bulles et la config active à gauche. Piloté par [data-display="simple"] sur (persisté dans 'jean-display'). */ /* En simple, raisonnement et outils sont masqués. L'activité est signalée par le VRAI indicateur de frappe (.msg.typing, mêmes 3 points animés qu'avant la réponse), maintenu en bas pendant tout le tour côté JS — animation identique. */ [data-display="simple"] #chat .msg.reasoning, [data-display="simple"] #chat .msg.tool{display:none} [data-display="simple"] #chat .msg .label{display:none} [data-display="simple"] #cfg-details{display:none} /* Hauteur animée en JS (mesure scrollHeight → 0) plutôt que grid 1fr→0fr qui peut « dépasser ». overflow:hidden clippe le contenu pendant tout le repli. width revient à auto SANS délai à l'ouverture (pas de saut), et passe à 0 APRÈS le fold (width 0s .3s) à la fermeture pour rétrécir la bulle au label. */ /* height ET width sont animées (en px, pilotées en JS via scrollHeight/scrollWidth) → repli/dépli fluide en diagonale. overflow:hidden clippe pendant l'animation. */ .msg.collapsible .bodywrap{overflow:hidden;transition:height .42s cubic-bezier(.4,0,.2,1),width .42s cubic-bezier(.4,0,.2,1),opacity .3s ease,margin-top .42s cubic-bezier(.4,0,.2,1);opacity:1;margin-top:4px} .msg.collapsible .bodywrap>.body{min-width:0} .msg.collapsible.collapsed .bodywrap{opacity:0;margin-top:0} /* Composer = un seul bloc cohérent : barre de contexte intégrée en tête (fine ligne de progression pleine largeur affleurant le bord) + zone de saisie. */ #composer{border-top:1px solid var(--border);background:var(--panel-2,rgba(255,255,255,.02))} /* La jauge est un ENFANT de #ctxmeta (et non plus un frère au-dessus) : ainsi elle peut être clippée par la forme arrondie du bloc — indispensable au thème ChatGPT où elle sert de bord bas de carte. Position/rendu inchangés pour les autres thèmes : filet collé en haut de la ligne de contexte. */ #ctxtrack{position:absolute;top:0;left:0;right:0;height:3px;background:var(--panel);overflow:hidden} #ctx-fill{height:100%;width:0%;background:var(--ok,#3a7);transition:width .3s,background .3s} #ctxmeta{position:relative;display:flex;align-items:center;justify-content:flex-end;gap:10px;padding:8px 12px 0} #ctx-text{font-size:10px;letter-spacing:.03em;white-space:nowrap} #ctx-compact{display:none;margin:0;padding:2px 10px;font-size:10px;background:var(--warn-bg);border-color:var(--warn,#c93)} #inputbar{padding:8px 12px;display:flex;gap:8px} #input{flex:1;background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:10px;font:inherit;resize:none;min-height:44px;max-height:200px} #input:focus{outline:none;border-color:var(--accent)} #send{padding:0 20px} .muted{color:var(--dim);font-size:12px} #toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);background:var(--panel);border:1px solid var(--border);padding:8px 16px;border-radius:6px;opacity:0;transition:opacity .2s;pointer-events:none} #toast.show{opacity:1} @keyframes spin{from{transform:rotate(0)}to{transform:rotate(360deg)}} #compact-banner{display:flex;align-items:center;justify-content:center;gap:8px;font-size:12px;color:var(--accent);background:var(--accent-bg);border:1px solid var(--border);border-radius:8px;padding:6px 10px;margin-bottom:8px} #compact-banner .cspin{display:inline-block;animation:spin 1s linear infinite} /* iOS Safari auto-zoome au focus sur tout champ < 16px. On force 16px sur les appareils tactiles uniquement (le desktop garde son rendu, le pinch-zoom manuel reste possible). */ @media (hover:none) and (pointer:coarse){ #input,#sysprompt,#modal input,#modal textarea,#modal select{font-size:16px} } /* Appareil TACTILE en PAYSAGE : on réduit nettement tout pour gagner de la place (interface « un peu grosse » en horizontal, utile pour enregistrer des démos). Détection par (hover:none)+(pointer:coarse)+landscape : infaillible sur tout téléphone couché, sans dépendre d'un seuil de largeur/hauteur en pixels (les iPhone Pro Max font 932px de large et ~430px de haut, ce qui piégeait les seuils précédents). Le desktop (souris) n'est jamais touché. NB : la règle iOS 16px anti-zoom plus haut est surchargée ici volontairement pour #input — on garde une saisie compacte (le pinch-zoom manuel reste dispo). */ @media (hover:none) and (pointer:coarse) and (orientation:landscape){ body{font-size:11.5px} /* Tiroir latéral : on décale le TIROIR ENTIER après l'encoche (left = inset) au lieu de padder à l'intérieur — sinon grosse bordure vide à gauche qui rétrécit le contenu. Padding interne normal → largeur utile pleine. */ .side{width:300px;max-width:300px;left:env(safe-area-inset-left);padding:calc(14px + env(safe-area-inset-top)) 14px 14px 14px} #chat{padding:48px 10px 6px;gap:7px} .msg{padding:6px 10px;border-radius:8px;max-width:78%} #chat .msg.assistant,#chat .msg.reasoning{max-width:88%} #inputbar{padding:5px 8px;gap:6px} /* PAS de font-size < 16px ici : iOS Safari zoome à la sélection du champ. On garde 16px (hérité de la règle anti-zoom) et on compacte via hauteur/padding. */ #input{min-height:34px;max-height:120px;padding:6px 9px} #send,#stop{padding:0 14px} #composer .muted{display:none} #ctxmeta{padding:3px 10px 0} #ctx-text{font-size:9px} h1{font-size:15px} h2,details>summary{font-size:10px} #menubtn{width:32px;height:32px;font-size:15px;top:calc(6px + env(safe-area-inset-top))} } /* --- Backend llama.cpp (2 modes : rapide / optimisée) --------------------- */ .lc-head{font-size:12px;line-height:1.5;margin-bottom:10px} .lc-modes{display:flex;flex-direction:column;gap:8px} .lc-modes.busy{opacity:.5;pointer-events:none} .lc-mode{border:1px solid var(--border);border-radius:8px;padding:10px 12px;cursor:pointer;transition:border-color .12s,background .12s} .lc-mode:hover{border-color:var(--dim)} .lc-mode-t{font-size:13px;font-weight:600;color:var(--text);display:flex;align-items:center;gap:6px} .lc-reco{font-size:9px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--accent);border:1px solid var(--accent);border-radius:8px;padding:1px 6px} .lc-mode-d{font-size:11px;color:var(--dim);margin-top:3px} .lc-mode-state{font-size:11px;margin-top:7px;display:flex;align-items:center;gap:12px;flex-wrap:wrap} .lc-mode-go{color:var(--accent)} .lc-mode-active-tag{color:var(--accent);font-weight:600} .lc-update-link{color:var(--dim);text-decoration:none;cursor:pointer} .lc-update-link:hover{color:var(--accent)} /* Choix du moteur dans l'éditeur de modèle (3 options : rapide/optimisé/perso) */ .be-opts{display:flex;flex-direction:column;gap:7px;margin:6px 0 8px} .be-opt{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--text);cursor:pointer} .be-opt input{margin:0;flex-shrink:0} .be-note{font-size:11px;color:var(--dim);margin-left:auto} /* ===== Éditeur de preset — listes groupées façon Réglages iOS ======== */ #modal .modal-card{max-width:520px;overflow:hidden} .pe-body{padding:18px 16px 24px;display:flex;flex-direction:column;gap:26px;overflow-y:auto;overflow-x:hidden;flex:1;background:var(--bg)} /* Nombres : pas de flèches natives (spinner), champ épuré. */ .pe-val[type=number]{-moz-appearance:textfield} .pe-val::-webkit-outer-spin-button,.pe-val::-webkit-inner-spin-button{-webkit-appearance:none;margin:0} /* Un groupe = un petit titre + une liste encadrée aux coins arrondis. */ .pe-group{display:flex;flex-direction:column;gap:8px} .pe-gh{font-size:12px;font-weight:600;color:var(--dim);padding:0 6px} .pe-list{background:var(--panel);border:1px solid var(--border);border-radius:12px;overflow:hidden} /* Ligne : libellé à gauche, contrôle à droite, séparateur fin entre lignes. */ .pe-row{display:flex;align-items:center;gap:14px;min-height:48px;padding:9px 15px} .pe-row:not(:last-child){border-bottom:1px solid var(--border)} .pe-row-l{font-size:14px;color:var(--text);flex:1;min-width:0;line-height:1.3} .pe-row-l .pe-sub{display:block;font-size:11px;color:var(--dim);margin-top:2px} .pe-row-c{flex:none;display:flex;align-items:center;gap:6px;max-width:62%;justify-content:flex-end} /* Valeur éditable sans bordure, alignée à droite (nombre / texte). */ .pe-val{border:none;background:transparent;color:var(--accent);font:inherit;text-align:right;padding:4px 0;width:110px;max-width:44vw} .pe-val::placeholder{color:var(--dim)} .pe-val:focus{outline:none} .pe-unit{font-size:12px;color:var(--dim)} /* Select sans bordure, avec chevron discret. */ .pe-selc{position:relative;display:flex;align-items:center;max-width:100%} .pe-selc select{appearance:none;-webkit-appearance:none;border:none;background:transparent;color:var(--accent);font:inherit;text-align:right;text-align-last:right;padding:4px 16px 4px 0;cursor:pointer;max-width:100%;text-overflow:ellipsis} .pe-selc select:focus{outline:none} .pe-selc::after{content:"›";position:absolute;right:0;transform:rotate(90deg);color:var(--dim);font-size:14px;pointer-events:none} /* Ligne « champ pleine largeur » (Nom, chemin, config brute…). */ .pe-row.stack{flex-direction:column;align-items:stretch;gap:8px} .pe-inp{width:100%;box-sizing:border-box;background:var(--bg);color:var(--text);border:1px solid var(--border);border-radius:8px;padding:9px 11px;font:inherit;transition:border-color .12s,box-shadow .12s} .pe-inp:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-bg)} .pe-row.stack.plain .pe-inp{border:none;background:transparent;padding:6px 0;font-size:15px} .pe-row.stack.plain .pe-inp:focus{box-shadow:none} /* Champ + bouton accolé (téléchargement) — même trait que les autres champs, sans pastille colorée qui ressort. */ .pe-inpbtn{display:flex} .pe-inpbtn .pe-inp{border-top-right-radius:0;border-bottom-right-radius:0} .pe-inpbtn button{flex:none;margin:0;border:1px solid var(--border);border-left:0;border-radius:0 8px 8px 0;background:var(--panel);color:var(--dim);padding:0 15px;cursor:pointer;font-size:15px;transition:color .12s,border-color .12s} .pe-inpbtn button:hover{color:var(--accent);border-color:var(--accent)} .pe-inpbtn button:disabled{opacity:.5;cursor:default} /* Contrôle segmenté (moteur) façon iOS. */ .pe-seg{display:flex;gap:3px;background:color-mix(in srgb,var(--dim) 16%,transparent);border-radius:9px;padding:3px;width:100%} .pe-seg>label{flex:1;text-align:center;font-size:13px;font-weight:500;padding:7px 4px;border-radius:7px;cursor:pointer;color:var(--dim);transition:background .12s,color .12s} .pe-seg>label:has(input:checked){background:var(--panel);color:var(--text);box-shadow:0 1px 2px rgba(0,0,0,.22)} .pe-seg input{display:none} .pe-seg .be-note{display:none} .pe-seg-note{font-size:11px;color:var(--dim);padding:0 2px;min-height:14px} .pe-note{font-size:11px;color:var(--dim);line-height:1.45} /* Interrupteur à glissière. */ .pe-switch{position:relative;flex:none;width:40px;height:24px} .pe-switch input{position:absolute;opacity:0;width:0;height:0} .pe-sl{position:absolute;inset:0;background:color-mix(in srgb,var(--dim) 55%,transparent);border-radius:999px;transition:background .18s} .pe-sl::before{content:"";position:absolute;width:18px;height:18px;left:3px;top:3px;background:#fff;border-radius:50%;transition:transform .18s;box-shadow:0 1px 3px rgba(0,0,0,.35)} .pe-switch input:checked+.pe-sl{background:var(--accent)} .pe-switch input:checked+.pe-sl::before{transform:translateX(16px)} .pe-switch input:focus-visible+.pe-sl{box-shadow:0 0 0 3px var(--accent-bg)} /* Repli « avancé » / config brute : une ligne cliquable dans un groupe. */ .pe-adv{background:var(--panel);border:1px solid var(--border);border-radius:12px;overflow:hidden} .pe-adv>summary{cursor:pointer;font-size:14px;color:var(--text);padding:13px 15px;list-style:none;display:flex;align-items:center;user-select:none} .pe-adv>summary::-webkit-details-marker{display:none} .pe-adv>summary::after{content:"";margin-left:auto;width:7px;height:7px;border-right:1.5px solid var(--dim);border-bottom:1.5px solid var(--dim);transform:translateY(-2px) rotate(45deg);transition:transform .15s} .pe-adv[open]>summary::after{transform:translateY(1px) rotate(-135deg)} .pe-adv[open]>summary{border-bottom:1px solid var(--border)} .pe-adv .pe-adv-body{padding:14px 15px;display:flex;flex-direction:column;gap:10px} .pe-adv textarea.pe-inp{min-height:210px;resize:vertical;line-height:1.5;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;white-space:pre-wrap;overflow-wrap:anywhere;overflow-x:hidden} /* Ligne « éditer le .env » : chevron de disclosure + textarea de config brute. */ .pe-caret{display:inline-block;width:7px;height:7px;border-right:1.5px solid var(--dim);border-bottom:1.5px solid var(--dim);transform:rotate(-45deg);transition:transform .15s} .pe-caret.open{transform:rotate(45deg)} #m-content{min-height:220px;resize:vertical;line-height:1.5;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;white-space:pre-wrap;overflow-wrap:anywhere;overflow-x:hidden} /* Nombres avancés : chaque paire label/valeur sur sa propre ligne (réutilise pe-row). */ .pe-adv .pe-list{margin:0} /* Variante « champ en clair » : page mémoire → le contenu est le champ principal. */ .pe-adv.pe-raw-plain{border:none;background:transparent} .pe-adv.pe-raw-plain>summary{display:none} .pe-adv.pe-raw-plain .pe-adv-body{padding:0} /* Pied de modale. */ .pe-foot{padding:13px 16px;border-top:1px solid var(--border);display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap} .pe-foot .foot-r{display:flex;gap:8px} .pe-btn{margin:0;padding:9px 18px;border-radius:9px;font-weight:600;cursor:pointer;border:1px solid var(--border);background:var(--panel);color:var(--text)} .pe-btn:hover{border-color:var(--dim)} .pe-btn.primary{border-color:var(--accent);background:var(--accent);color:#fff} .pe-btn.primary:hover{filter:brightness(1.08)} .pe-btn.ghost-danger{border-color:transparent;background:transparent;color:var(--err);padding:9px 10px} .pe-btn.ghost-danger:hover{background:var(--danger-bg)} .pe-delmodel{display:inline-flex;align-items:center;gap:6px;font-size:11px;color:var(--dim);cursor:pointer} .pe-delmodel input{margin:0} /* Éditeur de preset/mémoire — mise en forme propre du modale */ .modal-ov{position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:30;align-items:center;justify-content:center;padding:20px} .modal-card{background:var(--bg);border:1px solid var(--border);border-radius:12px;width:100%;max-width:600px;max-height:90vh;display:flex;flex-direction:column;box-shadow:0 16px 50px rgba(0,0,0,.5)} .modal-head{padding:14px 16px;border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center} .modal-head strong{font-size:14px} .modal-x{margin:0;padding:3px 10px;font-size:16px;line-height:1;color:var(--dim)} .modal-body{padding:16px;overflow:auto;flex:1} .modal-foot{padding:12px 16px;border-top:1px solid var(--border);display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap} .foot-l{display:flex;align-items:center;gap:10px;flex-wrap:wrap} .foot-r{display:flex;gap:8px} .mform{display:flex;flex-direction:column;gap:14px} .fld{display:flex;flex-direction:column;gap:5px} .fld-l{font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--dim)} .fld-l .opt{text-transform:none;letter-spacing:0;font-weight:400;opacity:.65} .fld-hint{font-size:11px;color:var(--dim);margin-top:2px} .ctl{width:100%;box-sizing:border-box;background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:7px;padding:9px 11px;font:inherit} .ctl:focus{outline:none;border-color:var(--accent)} .ta{min-height:220px;resize:vertical;line-height:1.5} .card{border:1px solid var(--border);border-radius:10px;padding:13px;display:flex;flex-direction:column;gap:13px} .card-h{font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--accent)} .row{display:flex;gap:6px} .row .ctl{flex:1;min-width:0} .btn-dl{flex-shrink:0;margin:0} .input-btn{display:flex} .input-btn .ctl{flex:1;min-width:0;border-top-right-radius:0;border-bottom-right-radius:0} .input-btn .btn-in{flex-shrink:0;margin:0;padding:9px 13px;border-left:0;border-top-left-radius:0;border-bottom-left-radius:0} .input-btn .btn-in:hover{border-left:0} .seg{display:flex;gap:6px} .seg>label{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;text-align:center;min-height:46px;padding:6px 4px;border:1px solid var(--border);border-radius:8px;cursor:pointer;font-size:12px;background:var(--panel);transition:border-color .12s,background .12s,color .12s} .seg>label:hover{border-color:var(--accent)} .seg>label:has(input:checked){border-color:var(--accent);background:var(--accent-bg);color:var(--accent)} .seg input{display:none} .seg .be-note{font-size:10px;color:var(--dim);margin:0} .btn-danger{background:var(--danger-bg);border-color:var(--err);color:var(--err);margin:0} .btn-save{border-color:var(--accent);color:var(--accent);margin:0} .del-model{align-items:center;gap:5px;font-size:11px;color:var(--dim)} .del-model input{margin:0} .lc-logbar{display:flex;align-items:center;gap:6px;cursor:pointer;user-select:none;font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:.08em;font-weight:600;padding:6px 0;margin-top:4px} .lc-logbar #lc-log-caret{font-size:9px;transition:transform .12s;display:inline-block} .lc-logbar.open #lc-log-caret{transform:rotate(90deg)} #lc-log{background:var(--panel);border:1px solid var(--border);border-radius:6px;padding:8px;font-size:10px;line-height:1.45;max-height:220px;overflow:auto;white-space:pre-wrap;word-break:break-all;margin:0} .lc-spin{display:inline-block;animation:spin 1s linear infinite} /* Serveurs MCP */ .mcp-list{display:flex;flex-direction:column;gap:4px} .mcp-row{display:flex;align-items:center;gap:8px;padding:6px 10px;border:1px solid var(--border);border-radius:6px;background:var(--panel);cursor:pointer} .mcp-row:hover{border-color:var(--accent)} .mcp-row.off{opacity:.6} .mcp-dot{flex:none;width:8px;height:8px;border-radius:50%} .mcp-dot-ok{background:var(--accent)} .mcp-dot-err{background:var(--err)} .mcp-dot-off{background:var(--dim)} .mcp-info{flex:1;min-width:0} .mcp-name{font-size:12px;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap} .mcp-meta{display:flex;align-items:center;gap:6px;margin-top:2px} .mcp-tag{font-size:10px;padding:1px 7px;border-radius:9px;border:1px solid var(--border);color:var(--dim);text-transform:uppercase;letter-spacing:.04em} .mcp-tools{font-size:10px;color:var(--accent)} .mcp-err{font-size:10px;color:var(--err)} .mcp-switch{flex:none} .mcp-edit{flex:none;padding:2px 5px;font-size:13px;line-height:1;background:transparent;border:none;opacity:.5} .mcp-edit:hover{opacity:1;color:var(--accent)} /* Liste des outils MCP dans la modale */ .mcp-tools-list{display:flex;flex-direction:column;gap:2px;max-height:240px;overflow:auto;border:1px solid var(--border);border-radius:6px;padding:6px} .mcp-tool-row{display:flex;align-items:center;gap:10px;padding:4px 6px;border-radius:5px;cursor:pointer} .mcp-tool-row:hover{background:var(--panel)} .mcp-tool-switch{flex:none;transform:scale(.85)} .mcp-tool-name{font-size:12px;color:var(--text);word-break:break-all} /* Accès OpenAI / Accès distant : champs lecture seule (URL, clé) + libellés compacts, pour une présentation homogène et sans surcharge visuelle. */ .io-cap{color:var(--dim);font-size:11px;margin:0 0 3px} .io-input{flex:1;min-width:0;background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:6px;font:inherit;font-size:12px} .io-group{margin-top:12px} /* Toggles de la sous-section « Paramètres » du mode agent : chacun dans sa propre carte bordée et arrondie (comme les serveurs MCP), plus lisible. */ #param-block .switchrow{border:1px solid var(--border);border-radius:8px;padding:9px 11px;background:var(--bg)} #param-block .switchrow+.switchrow{margin-top:8px} /* Modale MCP (ajout/édition) : les champs des groupes stdio/http n'avaient aucun espacement vertical (le conteneur n'est pas un flex à gap) → ils se touchaient. On aligne leur rythme sur celui du reste du formulaire (.mform). */ #mcp-stdio-fields,#mcp-http-fields{display:flex;flex-direction:column;gap:14px} /* ===== Thème "ChatGPT" — mise en page ============================== Les thèmes gpt-* ne changent pas que la palette : ils reprennent la disposition de ChatGPT — colonne de lecture centrée, réponses SANS bulle (texte nu sur le fond), question de l'utilisateur en pastille arrondie à droite, composer en « pilule », pas d'étiquettes VOUS/JEAN, typo système plus grande et plus aérée. Tout est préfixé [data-theme="gpt"] : aucun autre thème n'est affecté. */ [data-theme="gpt"] body{font-size:15px} [data-theme="gpt"] h1{color:var(--text);font-weight:600;letter-spacing:-.01em} /* Barre latérale : plus sombre/atténuée que la zone de conversation. */ [data-theme="gpt"] .side{background:var(--panel);border-right-color:transparent} @media (max-width:720px){[data-theme="gpt"] .side{background:var(--panel)}} /* Colonne de lecture centrée (comme le fil ChatGPT), pleine largeur sur mobile. */ [data-theme="gpt"] #chat{padding:28px max(16px,calc(50% - 380px)) 8px;gap:22px} /* Réponses de l'assistant : pas de cadre, pas de fond — juste du texte. */ [data-theme="gpt"] #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. */ [data-theme="gpt"] #chat .msg.user{background:var(--bubble);color:var(--text);border-radius:20px;padding:11px 18px;max-width:75%;line-height:1.6} [data-theme="gpt"] #chat .msg.user .label{color:var(--dim)} /* Étiquettes VOUS / JEAN : inutiles ici (l'alignement suffit), sauf pour les bulles repliables (raisonnement / outils) où le label est le bouton de repli. */ [data-theme="gpt"] #chat .msg .label{display:none} [data-theme="gpt"] #chat .msg.collapsible .label{display:block} /* Raisonnement / outils : encart gris discret plutôt qu'un cadre pointillé. */ [data-theme="gpt"] #chat .msg.reasoning,[data-theme="gpt"] #chat .msg.tool{background:var(--panel);border:1px solid var(--border);border-radius:14px;color:var(--dim);padding:12px 16px} [data-theme="gpt"] #chat .msg.reasoning{color:var(--dim)} [data-theme="gpt"] #chat .msg.tool .tool-head{color:var(--text)} [data-theme="gpt"] #chat .msg.assistant .body pre,[data-theme="gpt"] #chat .msg.reasoning .body pre,[data-theme="gpt"] #chat .msg.tool pre{border-radius:12px;padding:12px 14px} [data-theme="gpt"] #chat .msg.assistant .body a{text-decoration:underline;text-underline-offset:2px} /* Composer = UNE seule carte posée PAR-DESSUS le fil : la conversation continue de défiler DERRIÈRE elle et s'efface en fondu (dégradé vers le fond) au lieu de s'arrêter net au-dessus. Dans la carte, de haut en bas : la saisie et ses boutons, un pied discret (préréglage · contexte · compacter), puis la jauge de contexte qui FORME le bord bas — elle épouse les coins arrondis (overflow:hidden sur le rayon). Les trois blocs sont des frères dans le HTML : on les recolle en dessinant les bordures par morceaux et l'ordre visuel vient de l'ordre flex — aucun changement de markup. */ [data-theme="gpt"] #composer{position:absolute;left:0;right:0;bottom:0;z-index:4;border-top:none;display:flex;flex-direction:column;padding:34px 0 8px;--col:max(16px,calc(50% - 380px));background:linear-gradient(to bottom,transparent 0,var(--bg) 34%)} [data-theme="gpt"] #chat{padding-bottom:170px} [data-theme="gpt"] #scrollbtn{bottom:180px;border-radius:999px} [data-theme="gpt"] #compact-banner{order:0;margin:0 var(--col) 8px;border-radius:14px} [data-theme="gpt"] #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} [data-theme="gpt"] #input{background:transparent;border:none;border-radius:0;padding:9px 0;min-height:26px} /* Pas de cadre qui s'assombrit au focus : la carte garde exactement la même bordure, seule la saisie change (curseur). */ [data-theme="gpt"] #input:focus{border-color:transparent} [data-theme="gpt"] #send,[data-theme="gpt"] #stop{border-radius:999px;height:36px;min-height:36px;padding:0 18px;margin:0} [data-theme="gpt"] #send{background:var(--text);color:var(--bg);border-color:var(--text);font-weight:600} [data-theme="gpt"] #send:hover:not(:disabled){opacity:.85;color:var(--bg);border-color:var(--text)} /* Pied de carte : c'est LUI qui porte l'arrondi bas (26 px, comme en haut) et qui clippe la jauge. Un bandeau de 7 px ne peut pas dessiner un rayon de 26 px (le navigateur l'écrase, d'où les coins bizarres) : on laisse donc la carte découper la jauge dans sa propre forme — la barre est bien épaisse ET rognée exactement sur la courbe, symétrique du haut. */ [data-theme="gpt"] #ctxmeta{order:2;margin:0 var(--col);padding:6px 16px 15px;gap:10px;background:var(--panel);border:1px solid var(--border);border-top:none;border-radius:0 0 26px 26px;overflow:hidden} [data-theme="gpt"] #ctx-text,[data-theme="gpt"] #status-preset{color:var(--dim);font-size:10px;letter-spacing:.02em} [data-theme="gpt"] #ctx-compact{border-radius:999px;padding:2px 10px;font-size:10px;background:transparent;border-color:var(--border);color:var(--dim)} [data-theme="gpt"] #ctx-compact:hover{border-color:var(--dim);color:var(--text)} /* Jauge = bord bas de la carte : épaisse, plaquée au ras du bord, rognée par l'arrondi du pied de carte. */ [data-theme="gpt"] #ctxtrack{top:auto;bottom:0;height:7px;background:var(--border)} [data-theme="gpt"] #ctx-fill{background:var(--text);opacity:.75} [data-theme="gpt"] #sendhint{order:4;padding:8px var(--col) 0} /* Reste de l'UI : coins arrondis et contrastes doux, dans le même esprit. */ [data-theme="gpt"] button,[data-theme="gpt"] .addbtn,[data-theme="gpt"] .mem-search,[data-theme="gpt"] #theme-select{border-radius:10px} [data-theme="gpt"] .preset,[data-theme="gpt"] .gated-block,[data-theme="gpt"] .lc-mode{border-radius:12px} [data-theme="gpt"] .preset{background:transparent;border-color:transparent} [data-theme="gpt"] .preset:hover{background:var(--accent-bg);border-color:transparent} [data-theme="gpt"] .preset.active{background:var(--accent-bg);border-color:var(--border);color:var(--text)} [data-theme="gpt"] .subhead,[data-theme="gpt"] .lc-reco,[data-theme="gpt"] .lc-mode-go,[data-theme="gpt"] .lc-mode-active-tag{color:var(--dim)} [data-theme="gpt"] button:hover{border-color:var(--dim);color:var(--text)} [data-theme="gpt"] .switch input:checked + .slider{background:var(--text)} [data-theme="gpt"] .switch .slider::before{background:var(--bg)} [data-theme="gpt"] .switch input:not(:checked) + .slider::before{background:#fff}