feat(vida): semana da casa com análise por IA e rotina contada
O aprendizado passa a entender a logística da semana, não só a hora:
- presença por dia da semana × hora (7×24, média móvel por dia) e
histórico dos últimos 42 dias;
- depois da meia-noite, com 7 dias observados, a IA escolhida (Gemini,
IA local ou Qwen do S10, via Criacao.chamar) cruza os dias e devolve
padrões em frases e um plano da semana (casa / fora / dormindo);
- o plano da IA só é adotado se conferir com 70% das horas medidas;
senão fica como sugestão ("Usar este plano");
- "Conte sua rotina": texto livre vira plano na hora e vale sobre o da
IA; o painel mostra o quanto confere com o que os sensores veem;
- o plano guia o comportamento: acorda do cochilo 15 min antes da
chegada naquele dia da semana e, com a casa vazia, tira cochilos
longos para guardar energia;
- lição da rotina só quando muda 3+ horas ou depois de uma semana, e
some quando já existe plano da semana;
- painel: quadro da semana (o que eu vi / plano), a rotina entendida,
sugestão, contar rotina, analisar agora e a IA da análise diária.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,20 +1,45 @@
|
||||
<script lang="ts">
|
||||
import { GraduationCap } from '@lucide/svelte';
|
||||
import { configurarAprendizado, esquecerAprendizado } from '../aprendizado.svelte';
|
||||
import { CalendarClock, GraduationCap } from '@lucide/svelte';
|
||||
import {
|
||||
analisarSemana,
|
||||
apagarPlano,
|
||||
configurarAprendizado,
|
||||
contarRotina,
|
||||
esquecerAprendizado,
|
||||
usarSugestao,
|
||||
} from '../aprendizado.svelte';
|
||||
import { estado } from '../estado.svelte';
|
||||
import type { PlanoSemana, TipoPeriodo } from '../tipos';
|
||||
import Grupo from './Grupo.svelte';
|
||||
import Interruptor from './Interruptor.svelte';
|
||||
import Linha from './Linha.svelte';
|
||||
|
||||
// O que ele aprendeu com o dia a dia: rotina da casa (24 h), do que gostam, lições e o sono.
|
||||
// O que ele aprendeu com o dia a dia: a semana da casa (medida e planejada), do que gostam,
|
||||
// as lições e o sono. A IA cruza a semana; você também pode contar a rotina.
|
||||
const a = $derived(estado.aprendizado);
|
||||
let confirmar = $state(false);
|
||||
let vista = $state<'visto' | 'plano'>('visto');
|
||||
let rotina = $state('');
|
||||
|
||||
const horaAgora = $derived(new Date(estado.agora).getHours());
|
||||
const temRotina = $derived(!!a && a.rotina.some((v) => v !== null));
|
||||
const DIAS = ['seg', 'ter', 'qua', 'qui', 'sex', 'sáb', 'dom'];
|
||||
const NOME_TIPO: Record<TipoPeriodo, string> = { casa: 'em casa', fora: 'casa vazia', dormindo: 'dormindo' };
|
||||
const IAS = [
|
||||
{ valor: 'gemini', nome: 'Gemini' },
|
||||
{ valor: 'local', nome: 'IA local' },
|
||||
{ valor: 's10', nome: 'Qwen do S10' },
|
||||
] as const;
|
||||
|
||||
const agora = $derived(new Date(estado.agora));
|
||||
const hojeSemana = $derived((agora.getDay() + 6) % 7); // 0 = segunda, como na placa
|
||||
const horaAgora = $derived(agora.getHours());
|
||||
const temDados = $derived(!!a && a.semana.some((l) => l.some((v) => v !== null)));
|
||||
const plano = $derived(a?.plano ?? null);
|
||||
const verPlano = $derived(vista === 'plano' && !!plano);
|
||||
const faz_mais = $derived(a ? a.gosto.filter((g) => g.peso > 1.05).slice(0, 4) : []);
|
||||
const faz_menos = $derived(a ? [...a.gosto].reverse().filter((g) => g.peso < 0.95).slice(0, 3) : []);
|
||||
const respostas = $derived(a ? Object.values(a.hoje.respostas).reduce((s, n) => s + n, 0) : 0);
|
||||
const ocupado = $derived(!!a?.analise.ocupado);
|
||||
const faltamDias = $derived(a ? Math.max(0, a.analise.minimo - a.historico_dias) : 0);
|
||||
|
||||
const detalhe = $derived.by(() => {
|
||||
if (!a) return '';
|
||||
@@ -23,12 +48,24 @@
|
||||
return `${dias} · hoje: ${a.hoje.atos} ${a.hoje.atos === 1 ? 'gesto' : 'gestos'} com alguém perto, ${respostas} ${respostas === 1 ? 'carinho ou conversa' : 'carinhos ou conversas'}`;
|
||||
});
|
||||
|
||||
const resumoRotina = $derived.by(() => {
|
||||
if (!a) return '';
|
||||
const cheias = a.rotina.flatMap((v, h) => (v !== null && v >= 0.5 ? [h] : []));
|
||||
return cheias.length ? 'Costuma ter gente às ' + cheias.map((h) => h + 'h').join(', ') : 'Ainda sem um horário marcado';
|
||||
});
|
||||
|
||||
function tipoNoPlano(p: PlanoSemana, dia: number, h: number): TipoPeriodo | null {
|
||||
return p.dias[dia]?.find((x) => x.ini <= h && h < x.fim)?.tipo ?? null;
|
||||
}
|
||||
function rotuloCelula(dia: number, h: number) {
|
||||
if (verPlano && plano) {
|
||||
const t = tipoNoPlano(plano, dia, h);
|
||||
return `${DIAS[dia]} ${h}h: ${t ? NOME_TIPO[t] : 'sem plano'}`;
|
||||
}
|
||||
const v = a?.semana[dia][h];
|
||||
return `${DIAS[dia]} ${h}h: ${v == null ? 'sem dados' : Math.round(v * 100) + '% do tempo com gente'}`;
|
||||
}
|
||||
function confere(p: PlanoSemana) {
|
||||
return p.confere === null ? 'ainda conferindo com o que eu vejo' : `confere ${Math.round(p.confere * 100)}% com o que eu vi`;
|
||||
}
|
||||
function quando(s: number | null) {
|
||||
if (!s) return '';
|
||||
return new Date(s * 1000).toLocaleString('pt-BR', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' });
|
||||
}
|
||||
function dia(iso: string) {
|
||||
const [, m, d] = iso.split('-');
|
||||
return `${d}/${m}`;
|
||||
@@ -36,46 +73,145 @@
|
||||
function vezes(peso: number) {
|
||||
return '×' + peso.toLocaleString('pt-BR', { maximumFractionDigits: 1 });
|
||||
}
|
||||
async function enviarRotina(e: SubmitEvent) {
|
||||
e.preventDefault();
|
||||
if (await contarRotina(rotina.trim())) {
|
||||
rotina = '';
|
||||
vista = 'plano';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Grupo
|
||||
titulo="O que ele aprendeu"
|
||||
ajuda="aprendizado"
|
||||
rodape="Ele conta gestos feitos com alguém por perto e o que veio logo depois (carinho, conversa). À meia-noite junta o dia e escreve as lições."
|
||||
rodape="Ele conta o que acontece em casa: quando tem gente, o que agrada e quando acorda à toa. À meia-noite junta o dia, escreve as lições e a IA cruza a semana."
|
||||
>
|
||||
{#if !a}
|
||||
<p class="vazio">Carregando…</p>
|
||||
{:else}
|
||||
<Linha icone={GraduationCap} cor="#30b0c7" rotulo="Aprender com o dia a dia" {detalhe}>
|
||||
{#snippet acessorio()}
|
||||
<Interruptor rotulo="Aprender com o dia a dia" checked={a.config.ligado} onchange={(l) => configurarAprendizado(l)} />
|
||||
<Interruptor rotulo="Aprender com o dia a dia" checked={a.config.ligado} onchange={(l) => configurarAprendizado({ ligado: l })} />
|
||||
{/snippet}
|
||||
</Linha>
|
||||
|
||||
{#if a.config.ligado}
|
||||
<section class="bloco" aria-labelledby="ap-rotina">
|
||||
<h3 id="ap-rotina">Rotina da casa <span>{temRotina ? resumoRotina : 'aparece depois da primeira meia-noite'}</span></h3>
|
||||
<div class="rotina" role="img" aria-label={resumoRotina}>
|
||||
{#each a.rotina as v, h (h)}
|
||||
<span
|
||||
class="hora"
|
||||
class:agora={h === horaAgora}
|
||||
class:sem={v === null}
|
||||
title={`${h}h: ${v === null ? 'sem dados' : Math.round(v * 100) + '% do tempo com gente'}${a.sono[h] ? ' · acordou à toa aqui' : ''}`}
|
||||
>
|
||||
<span class="barra" style="--v: {v ?? 0}"></span>
|
||||
{#if a.sono[h]}<span class="lua" aria-hidden="true">☾</span>{/if}
|
||||
<section class="bloco" aria-labelledby="ap-semana">
|
||||
<div class="cabeca">
|
||||
<h3 id="ap-semana">Semana da casa</h3>
|
||||
{#if plano}
|
||||
<span class="segmentos" role="radiogroup" aria-label="Mostrar">
|
||||
<button role="radio" aria-checked={vista === 'visto'} class:ativo={vista === 'visto'} onclick={() => (vista = 'visto')}>O que eu vi</button>
|
||||
<button role="radio" aria-checked={vista === 'plano'} class:ativo={vista === 'plano'} onclick={() => (vista = 'plano')}>Plano</button>
|
||||
</span>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
<div class="eixo mono" aria-hidden="true"><span>0h</span><span>6h</span><span>12h</span><span>18h</span><span>24h</span></div>
|
||||
{#if a.sono.some((n) => n > 0)}
|
||||
<p class="nota"><span aria-hidden="true">☾</span> Horas em que acordou à toa: ali o sensor precisa de mais movimento para acordá-lo.</p>
|
||||
|
||||
<div class="quadro-rolagem">
|
||||
<div class="quadro" class:modo-plano={verPlano} role="img" aria-label={verPlano ? 'Plano da semana' : 'Presença medida por dia da semana e hora'}>
|
||||
{#each DIAS as nomeDia, d (d)}
|
||||
<span class="dia" class:hoje={d === hojeSemana}>{nomeDia}</span>
|
||||
{#each a.semana[d] as v, h (h)}
|
||||
{@const t = verPlano && plano ? tipoNoPlano(plano, d, h) : null}
|
||||
<span
|
||||
class="celula {t ?? ''}"
|
||||
class:sem={!verPlano && v === null}
|
||||
class:agora={d === hojeSemana && h === horaAgora}
|
||||
style={!verPlano && v !== null ? `--v: ${v}` : ''}
|
||||
title={rotuloCelula(d, h)}
|
||||
></span>
|
||||
{/each}
|
||||
{/each}
|
||||
<span></span>
|
||||
{#each Array(24) as _, h (h)}
|
||||
<span class="hora mono" aria-hidden="true">{h % 6 === 0 ? h + 'h' : ''}</span>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{#if verPlano}
|
||||
<p class="legenda">
|
||||
<span class="ponto casa"></span> em casa <span class="ponto fora"></span> casa vazia <span class="ponto dormindo"></span> dormindo
|
||||
</p>
|
||||
{:else if !temDados}
|
||||
<p class="nota">Cada dia aparece aqui depois da meia-noite. Com 2 ou 3 semanas ele separa bem um dia do outro.</p>
|
||||
{:else if a.sono.some((n) => n > 0)}
|
||||
<p class="nota">☾ Em algumas horas ele acordou à toa: ali o sensor precisa de mais movimento para acordá-lo.</p>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<section class="bloco" aria-labelledby="ap-rotina">
|
||||
<h3 id="ap-rotina"><CalendarClock size={13} /> A rotina que ele entendeu</h3>
|
||||
{#if plano}
|
||||
<div class="plano">
|
||||
<span class="selo" class:voce={plano.origem === 'voce'}>{plano.origem === 'voce' ? 'Você contou' : 'A IA percebeu'}</span>
|
||||
<span class="confere">{confere(plano)}</span>
|
||||
{#if plano.padroes.length}
|
||||
<ul class="padroes">
|
||||
{#each plano.padroes as p (p)}<li>{p}</li>{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
<button class="btn fantasma pequeno" onclick={apagarPlano}>Apagar plano</button>
|
||||
</div>
|
||||
{:else}
|
||||
<p class="nota">Sem plano ainda: ele segue só o que mede em cada dia da semana.</p>
|
||||
{/if}
|
||||
|
||||
{#if a.sugestao}
|
||||
<div class="plano sugestao">
|
||||
<span class="selo">Sugestão da IA</span>
|
||||
<span class="confere">{confere(a.sugestao)}</span>
|
||||
<ul class="padroes">
|
||||
{#each a.sugestao.padroes as p (p)}<li>{p}</li>{/each}
|
||||
</ul>
|
||||
<button class="btn pequeno" onclick={usarSugestao}>Usar este plano</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<form class="contar" onsubmit={enviarRotina}>
|
||||
<label for="ap-contar">Conte sua rotina</label>
|
||||
<textarea
|
||||
id="ap-contar"
|
||||
rows="2"
|
||||
maxlength="600"
|
||||
placeholder="Ex.: fico fora de terça a quinta, das 8h às 18h. Segunda, sexta e fim de semana fico em casa."
|
||||
bind:value={rotina}
|
||||
></textarea>
|
||||
<div class="acoes">
|
||||
<button class="btn pequeno" type="submit" disabled={ocupado || rotina.trim().length < 5 || !a.analise.pode}>Ensinar</button>
|
||||
<button
|
||||
class="btn fantasma pequeno"
|
||||
type="button"
|
||||
onclick={analisarSemana}
|
||||
disabled={ocupado || faltamDias > 0 || !a.analise.pode}
|
||||
title={faltamDias > 0 ? `Faltam ${faltamDias} dias observados` : ''}
|
||||
>
|
||||
{ocupado && a.analise.tipo === 'analise' ? 'Analisando…' : 'Analisar a semana agora'}
|
||||
</button>
|
||||
{#if ocupado && a.analise.tipo === 'rotina'}<span class="nota">Entendendo sua rotina…</span>{/if}
|
||||
</div>
|
||||
{#if a.analise.erro}
|
||||
<p class="erro" role="alert">{a.analise.erro}</p>
|
||||
{:else if !a.analise.pode}
|
||||
<p class="nota">A IA escolhida não está pronta. Confira a chave do Gemini ou a IA local nos Ajustes.</p>
|
||||
{:else if faltamDias > 0}
|
||||
<p class="nota">A análise da IA libera com {a.analise.minimo} dias observados (faltam {faltamDias}). Contar a rotina já funciona.</p>
|
||||
{:else if a.analise.em}
|
||||
<p class="nota">Última análise: {quando(a.analise.em)}</p>
|
||||
{/if}
|
||||
</form>
|
||||
|
||||
<div class="ajustes-ia">
|
||||
<Interruptor rotulo="Analisar todo dia com IA" checked={a.config.analise_ia} onchange={(l) => configurarAprendizado({ analise_ia: l })} />
|
||||
<span>Analisar todo dia com</span>
|
||||
<select aria-label="IA da análise" value={a.config.ia} onchange={(e) => configurarAprendizado({ ia: e.currentTarget.value as any })}>
|
||||
{#each IAS as ia (ia.valor)}<option value={ia.valor}>{ia.nome}</option>{/each}
|
||||
</select>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{#if faz_mais.length || faz_menos.length}
|
||||
<section class="bloco gosto" aria-labelledby="ap-gosto">
|
||||
<section class="bloco" aria-labelledby="ap-gosto">
|
||||
<h3 id="ap-gosto">Do que vocês gostam</h3>
|
||||
<div class="colunas">
|
||||
<ul>
|
||||
@@ -114,11 +250,11 @@
|
||||
|
||||
<div class="esquecer">
|
||||
{#if confirmar}
|
||||
<span>Apagar rotina, gostos e lições?</span>
|
||||
<span>Apagar semana, plano, gostos e lições?</span>
|
||||
<button class="btn pequeno perigo" onclick={() => { confirmar = false; esquecerAprendizado(); }}>Esquecer tudo</button>
|
||||
<button class="btn fantasma pequeno" onclick={() => (confirmar = false)}>Cancelar</button>
|
||||
{:else}
|
||||
<button class="btn fantasma pequeno" onclick={() => (confirmar = true)} disabled={!a.dias && !a.gosto.length && !a.licoes.length}>
|
||||
<button class="btn fantasma pequeno" onclick={() => (confirmar = true)} disabled={!a.dias && !a.gosto.length && !a.licoes.length && !plano}>
|
||||
Esquecer o que aprendeu
|
||||
</button>
|
||||
{/if}
|
||||
@@ -136,17 +272,28 @@
|
||||
.vazio {
|
||||
padding: var(--e-3) var(--e-4);
|
||||
}
|
||||
.erro {
|
||||
margin: 0;
|
||||
color: var(--perigo);
|
||||
font-size: var(--t-xs);
|
||||
}
|
||||
.bloco {
|
||||
display: grid;
|
||||
gap: var(--e-2);
|
||||
padding: var(--e-3) var(--e-4);
|
||||
border-top: 1px solid var(--borda);
|
||||
}
|
||||
h3 {
|
||||
.cabeca {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: baseline;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--e-2);
|
||||
}
|
||||
h3 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin: 0;
|
||||
font-size: var(--t-xs);
|
||||
font-weight: 600;
|
||||
@@ -154,56 +301,164 @@
|
||||
text-transform: uppercase;
|
||||
color: var(--texto-3);
|
||||
}
|
||||
h3 span {
|
||||
font-weight: 400;
|
||||
letter-spacing: 0;
|
||||
text-transform: none;
|
||||
.segmentos {
|
||||
display: inline-flex;
|
||||
padding: 2px;
|
||||
border-radius: var(--raio-sm);
|
||||
background: var(--superficie-3);
|
||||
}
|
||||
.rotina {
|
||||
.segmentos button {
|
||||
min-height: 26px;
|
||||
padding: 0 var(--e-2);
|
||||
border: 0;
|
||||
border-radius: calc(var(--raio-sm) - 2px);
|
||||
background: transparent;
|
||||
color: var(--texto-2);
|
||||
font: 500 var(--t-xs) var(--fonte);
|
||||
cursor: pointer;
|
||||
}
|
||||
.segmentos button.ativo {
|
||||
background: var(--superficie);
|
||||
color: var(--texto);
|
||||
box-shadow: var(--sombra);
|
||||
}
|
||||
.quadro-rolagem {
|
||||
overflow-x: auto;
|
||||
}
|
||||
.quadro {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(24, minmax(0, 1fr));
|
||||
align-items: end;
|
||||
grid-template-columns: 2.2em repeat(24, minmax(9px, 1fr));
|
||||
gap: 2px;
|
||||
height: 44px;
|
||||
min-width: 280px;
|
||||
align-items: center;
|
||||
}
|
||||
.hora {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
height: 100%;
|
||||
border-radius: 3px;
|
||||
.dia {
|
||||
font-size: 10px;
|
||||
color: var(--texto-3);
|
||||
}
|
||||
.dia.hoje {
|
||||
color: var(--texto);
|
||||
font-weight: 600;
|
||||
}
|
||||
.celula {
|
||||
height: 14px;
|
||||
border-radius: 2px;
|
||||
background: color-mix(in srgb, #30b0c7 calc(var(--v, 0) * 100%), var(--superficie-2));
|
||||
}
|
||||
.celula.sem {
|
||||
background: var(--superficie-2);
|
||||
opacity: 0.5;
|
||||
}
|
||||
.modo-plano .celula {
|
||||
background: var(--superficie-2);
|
||||
}
|
||||
.barra {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: calc(var(--v) * 100%);
|
||||
min-height: 2px;
|
||||
border-radius: 3px;
|
||||
.modo-plano .celula.casa,
|
||||
.ponto.casa {
|
||||
background: #30b0c7;
|
||||
transition: height 600ms ease;
|
||||
}
|
||||
.sem .barra {
|
||||
background: transparent;
|
||||
.modo-plano .celula.fora,
|
||||
.ponto.fora {
|
||||
background: color-mix(in srgb, var(--texto-3) 35%, var(--superficie-2));
|
||||
}
|
||||
.agora {
|
||||
outline: 1.5px solid var(--texto-2);
|
||||
.modo-plano .celula.dormindo,
|
||||
.ponto.dormindo {
|
||||
background: #5e5ce6;
|
||||
}
|
||||
.celula.agora {
|
||||
outline: 1.5px solid var(--texto);
|
||||
outline-offset: 1px;
|
||||
}
|
||||
.lua {
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-size: 10px;
|
||||
line-height: 1;
|
||||
color: #5e5ce6;
|
||||
}
|
||||
.eixo {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.hora {
|
||||
font-size: 9px;
|
||||
color: var(--texto-3);
|
||||
font-size: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.legenda {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 4px var(--e-2);
|
||||
margin: 0;
|
||||
font-size: var(--t-xs);
|
||||
color: var(--texto-3);
|
||||
}
|
||||
.ponto {
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.plano {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
padding: var(--e-2) var(--e-3);
|
||||
border-radius: var(--raio-sm);
|
||||
background: var(--superficie-2);
|
||||
justify-items: start;
|
||||
}
|
||||
.plano.sugestao {
|
||||
background: transparent;
|
||||
border: 1px dashed var(--borda);
|
||||
}
|
||||
.selo {
|
||||
font-size: var(--t-xs);
|
||||
font-weight: 600;
|
||||
color: #30b0c7;
|
||||
}
|
||||
.selo.voce {
|
||||
color: var(--texto);
|
||||
}
|
||||
.confere {
|
||||
font-size: var(--t-xs);
|
||||
color: var(--texto-3);
|
||||
}
|
||||
.padroes {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
margin: 0;
|
||||
padding-left: 1.1em;
|
||||
font-size: var(--t-sm);
|
||||
color: var(--texto);
|
||||
}
|
||||
.contar {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
}
|
||||
.contar label {
|
||||
font-size: var(--t-xs);
|
||||
color: var(--texto-2);
|
||||
}
|
||||
.contar textarea {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: var(--e-2);
|
||||
border: 1px solid var(--borda);
|
||||
border-radius: var(--raio-sm);
|
||||
background: var(--superficie);
|
||||
color: var(--texto);
|
||||
font: var(--t-sm) var(--fonte);
|
||||
resize: vertical;
|
||||
}
|
||||
.acoes,
|
||||
.ajustes-ia {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: var(--e-2);
|
||||
}
|
||||
.ajustes-ia {
|
||||
font-size: var(--t-sm);
|
||||
color: var(--texto-2);
|
||||
}
|
||||
.ajustes-ia select {
|
||||
width: auto;
|
||||
flex: none;
|
||||
min-height: 28px;
|
||||
border: 1px solid var(--borda);
|
||||
border-radius: var(--raio-sm);
|
||||
background: var(--superficie);
|
||||
color: var(--texto);
|
||||
font: var(--t-sm) var(--fonte);
|
||||
}
|
||||
.colunas {
|
||||
display: grid;
|
||||
@@ -224,21 +479,21 @@
|
||||
gap: var(--e-2);
|
||||
color: var(--texto-2);
|
||||
}
|
||||
.colunas .titulo {
|
||||
color: var(--texto-3);
|
||||
font-size: var(--t-xs);
|
||||
}
|
||||
.colunas b {
|
||||
font-weight: 600;
|
||||
font-size: var(--t-xs);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.mais b {
|
||||
color: var(--ok, #34c759);
|
||||
color: var(--ok);
|
||||
}
|
||||
.menos b {
|
||||
color: var(--texto-3);
|
||||
}
|
||||
.colunas .titulo {
|
||||
color: var(--texto-3);
|
||||
font-size: var(--t-xs);
|
||||
}
|
||||
.nada {
|
||||
color: var(--texto-3);
|
||||
font-size: var(--t-xs);
|
||||
@@ -275,9 +530,4 @@
|
||||
.esquecer span {
|
||||
padding-left: var(--e-1);
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.barra {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user