fix(discord-bridge): dashboard-ul e responsive pe telefon

Pe un ecran de 390px pagina se intindea pe 2621px si derula orizontal. Cauza:
copiii de grid au min-width:auto, deci liniile lungi din pre.log si tabelul de
fire dilatau coloana lui .wrap, si odata cu ea tot documentul. Rezolvat cu
min-width:0 explicit; derularea ramane inauntrul containerelor cu overflow.

Sub 640px:
- tabelul de fire devine carduri stivuite (capul de tabel dispare, eticheta vine
  din data-label) — 5 coloane pe 390px insemnau derulare la fiecare rand;
- butoanele stau doua pe rand, cu tinta de atins de 44px; sub 380px, unul pe rand;
- verificarile si confirmarile se aseaza pe verticala, comenzile lungi se rup;
- antetul trece pe doua randuri, notificarile se intind pe toata latimea;
- corpul trece la 16px, ca iOS sa nu mai dea zoom la focus pe input.

Verificat la 360, 390 si 1440px: zero depasiri pe orizontala, butoanele de
confirmare egale si de 44px inaltime, desktopul neschimbat.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B29CApsP1JkSdjYaGaHpE7
This commit is contained in:
Claude Agent
2026-08-30 14:05:44 +00:00
parent 22628fb178
commit 6b6f6644f9
3 changed files with 134 additions and 9 deletions

View File

@@ -39,7 +39,7 @@
<section class="card">
<h2>Fire active <span class="count" id="threadCount"></span></h2>
<div class="table-scroll">
<table>
<table class="stack-mobil">
<thead><tr><th>Fir</th><th>Model</th><th>Director</th><th>Stare</th><th class="num">USD</th></tr></thead>
<tbody id="threads"></tbody>
</table>
@@ -161,10 +161,14 @@ async function refresh() {
var st = t.inflight ? '<span class="pill busy">tur în lucru</span>'
: t.alive ? '<span class="pill ok">proces viu</span>'
: '<span class="pill">inactiv</span>';
return '<tr><td class="mono">' + esc(t.thread_id) + '</td><td>' + esc(t.model || '—') +
'</td><td class="mono">' + esc(t.cwd || '—') + '</td><td>' + st +
'</td><td class="num">' + Number(t.cost_usd || 0).toFixed(2) + '</td></tr>';
}).join('') : '<tr><td colspan="5" class="empty">niciun fir înregistrat</td></tr>';
// data-label: pe telefon capul de tabel dispare si eticheta vine din CSS
return '<tr><td class="mono" data-label="Fir">' + esc(t.thread_id) +
'</td><td data-label="Model">' + esc(t.model || '—') +
'</td><td class="mono" data-label="Director">' + esc(t.cwd || '—') +
'</td><td data-label="Stare">' + st +
'</td><td class="num" data-label="USD">' + Number(t.cost_usd || 0).toFixed(2) +
'</td></tr>';
}).join('') : '<tr><td colspan="5" class="empty" data-label="">niciun fir înregistrat</td></tr>';
// aprobări
document.getElementById('apprCount').textContent = s.pending_approvals || '';
@@ -182,8 +186,10 @@ async function refreshApprovals() {
'<div class="detail">' + esc(a.reason || a.rule || '') +
(a.expires_in !== null && a.expires_in !== undefined ? ' · expiră în ' + dur(a.expires_in) : '') +
' · fir ' + esc(a.thread_id) + '</div></div>' +
'<button class="small primary" onclick="decide(\'' + esc(a.request_id) + '\',\'allow\')">Permite</button> ' +
'<button class="small danger" onclick="decide(\'' + esc(a.request_id) + '\',\'deny\')">Refuză</button></div>';
'<div class="check-actions">' +
'<button class="small primary" onclick="decide(\'' + esc(a.request_id) + '\',\'allow\')">Permite</button>' +
'<button class="small danger" onclick="decide(\'' + esc(a.request_id) + '\',\'deny\')">Refuză</button>' +
'</div></div>';
}).join('') : '<div class="empty">niciuna</div>';
}