feat(web): cria painel Svelte com shell, Ao vivo e Ajustes
- web/ com Vite + Svelte 5 + TypeScript; servidor entrega web/dist em "/" (telas antigas seguem em /dashboard, /painel, /braco...) - design system em tokens CSS, tema escuro e claro, fontes locais - estado unico: foto de /estado + um EventSource em /eventos, sem polling - shell com navegacao lateral/inferior, selos de status reais e E-Stop fixo - command palette (Ctrl+K), gestos favoritos com atalhos 1-9, g+letra navega - Ao vivo: camera WebRTC e rastreamento portados para TS, rosto, aparencia, sensores do celular, IA local e feed de acontecimentos - Ajustes: campos do celular agrupados com busca, salvamento otimista e restaurar padrao (GET /app/padrao); motor da conversa, Gemini e token - carinha.html ganha modo ?painel=1 dirigido por postMessage (sem polling) - teste Playwright de ponta a ponta do painel novo Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
/* Design system do painel Carinha: tokens + poucos utilitários. Escuro por padrão, claro opcional. */
|
||||
:root {
|
||||
color-scheme: dark;
|
||||
--fundo: #0b1017;
|
||||
--fundo-2: #0f1620;
|
||||
--superficie: #141c27;
|
||||
--superficie-2: #1a2431;
|
||||
--superficie-3: #223041;
|
||||
--borda: #263447;
|
||||
--borda-forte: #34475f;
|
||||
--texto: #e8eef6;
|
||||
--texto-2: #a9b8c9;
|
||||
--texto-3: #8396ab; /* AA sobre --superficie */
|
||||
--destaque: #5cd6ff;
|
||||
--destaque-forte: #2fbff0;
|
||||
--destaque-texto: #04202b;
|
||||
--destaque-suave: rgb(92 214 255 / 0.12);
|
||||
--ok: #4ade80;
|
||||
--ok-suave: rgb(74 222 128 / 0.12);
|
||||
--aviso: #fbbf24;
|
||||
--aviso-suave: rgb(251 191 36 / 0.12);
|
||||
--perigo: #f87171;
|
||||
--perigo-forte: #ef4444;
|
||||
--perigo-suave: rgb(248 113 113 / 0.14);
|
||||
--vidro: rgb(15 22 32 / 0.72);
|
||||
|
||||
--fonte: 'Outfit Variable', 'Segoe UI', system-ui, sans-serif;
|
||||
--fonte-mono: 'JetBrains Mono Variable', ui-monospace, Consolas, monospace;
|
||||
--t-xs: 0.75rem; --t-sm: 0.875rem; --t-md: 1rem; --t-lg: 1.25rem; --t-xl: 1.6rem;
|
||||
|
||||
--e-1: 4px; --e-2: 8px; --e-3: 12px; --e-4: 16px; --e-5: 24px; --e-6: 32px;
|
||||
--raio-sm: 8px; --raio: 12px; --raio-lg: 18px; --raio-pill: 999px;
|
||||
--sombra: 0 1px 2px rgb(0 0 0 / 0.3), 0 8px 24px rgb(0 0 0 / 0.25);
|
||||
--sombra-flutuante: 0 12px 40px rgb(0 0 0 / 0.45);
|
||||
--transicao: 160ms cubic-bezier(0.2, 0.8, 0.2, 1);
|
||||
|
||||
--nav-largura: 232px;
|
||||
--topo-altura: 60px;
|
||||
}
|
||||
|
||||
:root[data-theme='light'] {
|
||||
color-scheme: light;
|
||||
--fundo: #f4f6f9;
|
||||
--fundo-2: #eef2f6;
|
||||
--superficie: #ffffff;
|
||||
--superficie-2: #f3f6fa;
|
||||
--superficie-3: #e7edf4;
|
||||
--borda: #dbe3ec;
|
||||
--borda-forte: #c3cfdc;
|
||||
--texto: #0f1722;
|
||||
--texto-2: #3d4d60;
|
||||
--texto-3: #5a6b7f;
|
||||
--destaque: #0284c7;
|
||||
--destaque-forte: #0369a1;
|
||||
--destaque-texto: #ffffff;
|
||||
--destaque-suave: rgb(2 132 199 / 0.1);
|
||||
--ok: #15803d; --ok-suave: rgb(21 128 61 / 0.1);
|
||||
--aviso: #b45309; --aviso-suave: rgb(180 83 9 / 0.1);
|
||||
--perigo: #dc2626; --perigo-forte: #b91c1c; --perigo-suave: rgb(220 38 38 / 0.1);
|
||||
--vidro: rgb(255 255 255 / 0.78);
|
||||
--sombra: 0 1px 2px rgb(15 23 34 / 0.06), 0 6px 20px rgb(15 23 34 / 0.08);
|
||||
--sombra-flutuante: 0 12px 40px rgb(15 23 34 / 0.18);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body { margin: 0; height: 100%; }
|
||||
body {
|
||||
background: var(--fundo);
|
||||
color: var(--texto);
|
||||
font: 400 var(--t-md)/1.5 var(--fonte);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
h1, h2, h3, h4 { margin: 0; line-height: 1.2; font-weight: 600; }
|
||||
h1 { font-size: var(--t-xl); }
|
||||
h2 { font-size: var(--t-lg); }
|
||||
h3 { font-size: var(--t-md); }
|
||||
p { margin: 0; }
|
||||
a { color: var(--destaque); }
|
||||
img, video, canvas, iframe { max-width: 100%; }
|
||||
[hidden] { display: none !important; }
|
||||
:focus-visible { outline: 2px solid var(--destaque); outline-offset: 2px; }
|
||||
|
||||
/* ---------- botões ---------- */
|
||||
.btn {
|
||||
display: inline-flex; align-items: center; justify-content: center; gap: var(--e-2);
|
||||
min-height: 40px; padding: 0 var(--e-4);
|
||||
border: 1px solid var(--borda-forte); border-radius: var(--raio-sm);
|
||||
background: var(--superficie-2); color: var(--texto);
|
||||
font: 500 var(--t-sm) var(--fonte); cursor: pointer; white-space: nowrap;
|
||||
transition: background var(--transicao), border-color var(--transicao), transform var(--transicao);
|
||||
touch-action: manipulation; user-select: none;
|
||||
}
|
||||
.btn:hover:not(:disabled) { background: var(--superficie-3); }
|
||||
.btn:active:not(:disabled) { transform: translateY(1px); }
|
||||
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
.btn.primario { background: var(--destaque); border-color: var(--destaque); color: var(--destaque-texto); }
|
||||
.btn.primario:hover:not(:disabled) { background: var(--destaque-forte); }
|
||||
.btn.perigo { background: var(--perigo-forte); border-color: var(--perigo-forte); color: #fff; }
|
||||
.btn.perigo:hover:not(:disabled) { background: var(--perigo); }
|
||||
.btn.fantasma { background: transparent; border-color: transparent; }
|
||||
.btn.fantasma:hover:not(:disabled) { background: var(--superficie-2); }
|
||||
.btn.icone { padding: 0; width: 40px; }
|
||||
.btn.pequeno { min-height: 32px; padding: 0 var(--e-3); font-size: var(--t-xs); }
|
||||
.btn.pequeno.icone { width: 32px; }
|
||||
|
||||
/* ---------- formulários ---------- */
|
||||
.campo { display: grid; gap: var(--e-1); }
|
||||
.campo > span, .rotulo { font-size: var(--t-sm); color: var(--texto-2); }
|
||||
input[type='text'], input[type='password'], input[type='search'], input[type='number'], select, textarea {
|
||||
width: 100%; min-height: 40px; padding: var(--e-2) var(--e-3);
|
||||
border: 1px solid var(--borda-forte); border-radius: var(--raio-sm);
|
||||
background: var(--fundo-2); color: var(--texto); font: inherit; font-size: var(--t-sm);
|
||||
}
|
||||
textarea { resize: vertical; min-height: 80px; }
|
||||
input::placeholder, textarea::placeholder { color: var(--texto-3); }
|
||||
|
||||
/* ---------- utilitários ---------- */
|
||||
.grade { display: grid; gap: var(--e-4); }
|
||||
.linha { display: flex; gap: var(--e-2); align-items: center; flex-wrap: wrap; }
|
||||
.entre { justify-content: space-between; }
|
||||
.mono { font-family: var(--fonte-mono); font-size: 0.92em; }
|
||||
.fraco { color: var(--texto-3); }
|
||||
.pequeno-texto { font-size: var(--t-sm); }
|
||||
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after { transition-duration: 0ms !important; animation-duration: 0ms !important; }
|
||||
}
|
||||
Reference in New Issue
Block a user