Entrixy — guia de design

Um documento vivo. Regista as calibrações, o ritmo e os acordos sobre a interface, e é atualizado sempre que algo fica decidido.

Conteúdo
  1. Ícones — tamanhos e calibração
  2. Typography
  3. Ritmo e espaçamentos
  4. Cores e níveis
  5. Controls
  6. Animations
  7. Regras do texto
  8. Padrões de interação
  9. O que não mexer

1. Ícones — tamanhos e calibração

O problema

Os ícones Material de androidx.compose.material.icons.outlined.* partilham um tamanho nominal — uma grelha de 24×24 — mas a parte desenhada difere de um para outro. Dê a todos um simples Modifier.size(24.dp)e uns parecerão grandes e pesados (Bolt, Delete) enquanto outros parecerão minúsculos (Contacts, VpnKey). É preciso calibrá-los à mão.

O método de calibração

  1. Tirar uma captura do ecrã com os ícones nos seus círculos de 38 dp — o nosso lugar de assentamento.
  2. Com Python, PIL e numpy, medir o retângulo delimitador do glifo desenhado — a sua largura e altura máximas em píxeis.
  3. A fórmula: new_size = 24 × 52 / measured_px, limitado a [18..28].
  4. Depois centrá-lo no espaço de 38 dp, na vertical e na horizontal.

52 px é o glifo de referência, Fingerprint; tudo se mede em relação a ele como unidade.

O mapa de tamanhos resultante

IconTamanhoWhy
Add, Apps, ArrowBack, Close28dplinhas finas, glifo de 36–41 px
AutoMode, Bolt, DeleteOutline, Edit, List, Photo, QrCode, Tune, DriveFileRenameOutline26dpdensidade média, glifo de cerca de 47 px
LocationOn24dpo alfinete do mapa — não mexer, é referência
LocationOff26dpo alfinete riscado — não mexer
ContentCopy, MyLocation, PeopleAlt, Wifi, ExpandMore, ExpandLess22dplargos ou altos, e visualmente pesados
Contacts, VpnKey20dpsobrecarregados de detalhe interno
Não mexer: LocationOn (24), LocationOff (26), ExpandMore e ExpandLess (22). São os ícones de referência: foram acertados píxel a píxel e toda a calibração se mede a partir deles.

AutoMode

Usa-se onde antes estava o Bolt — o botão Automatização no cartão da chave, o ícone da secção nas definições. Tamanho 26 dp, igual ao Bolt.

Onde a tabela vive no código

IconsDebugSheet.kt — o mapa iconSizeByName. O ecrã de depuração abre-se a partir de SettingsScreen com o botão Ícones da interface (depuração): em cima uma FlowRow de ícones calibrados, em baixo uma lista de nomes, tamanhos e contextos.

2. Tipografia

Usamos os papéis padrão do Material 3, limitados de propósito a quatro:

RoleTamanho / entrelinhaOnde se usa
titleLarge SemiBold22sp/28spO título da folha inferior (Para o convidado · <objeto>)
titleMedium SemiBold16sp/24spCabeçalhos de regra (Geolocalização, Wi-Fi, Intervalo, Ativação) e rótulos de FieldSection (Coordenadas, Raio, Modo, Redes guardadas)
bodyMedium14sp/20spRótulos dos botões de opção, o texto dentro dos botões cápsula, nomes dos segmentos
bodySmall muted12sp/16spEstados e dicas (36540 m até ao ponto, 74 m · máximo, o convidado pode reduzir, textos de ajuda). Cor: onSurfaceVariant
Rule: não misturar pesos dentro de um papel. Se algo é titleMedium SemiBold, é SemiBold em toda a parte — não regular aqui e Semi ali.

3. Ritmo e espaçamentos

A escala

Combinámos trabalhar em múltiplos de 2 / 4 / 8 / 10 / 14 / 16 / 20. Nada de festim ou fome: elementos iguais recebem espaços iguais.

Entre cartões no deslocamento principal

Dentro de um cartão (RuleCard)

Dentro de uma FieldSection (rótulo mais conteúdo)

Botões cápsula e estados

Os cursores são um caso à parte

Um cursor do Material 3 ocupa cerca de 48 dp de disposição por causa da área tátil mínima, dos quais a pista visível são apenas uns 4 dp ao centro, com cerca de 22 dp de zona tátil vazia acima e abaixo. Daí que:

O resultado: a distância do último elemento visível — cápsula, botão de opção ou cursor — à margem inferior do cartão é praticamente a mesma em todos.

4. Cores e níveis

Três níveis de confiança no convidado

Cada regra — Geolocalização, Wi-Fi, Tempo, Autorização, Confirmação — e o bloco de Ativação assumem um de três níveis. O círculo do ícone do cartão fica com a cor correspondente quando o interruptor está ligado.

KeyLabelColourDescription
own Decide o convidado #3BA55D (green) O convidado escolhe ele próprio a definição
suggest Preset #E5B409 (yellow) O valor está definido e o convidado pode alterá-lo
force Locked #CC3322 (red) O valor está definido e o convidado não pode alterá-lo

Com o interruptor desligado o círculo fica cinzento (#9AA0A6), seja qual for o nível escolhido.

O sentido do máximo e do mínimo: in yellow (Predefinido) o valor do raio é um máximo e o convidado só pode baixá-lo. Com o número de redes Wi-Fi — o limiar de correspondência — é ao contrário: é um mínimo que o convidado só pode subir. A direção da liberdade inverte-se, e os textos de estado dizem-no sem rodeios: máximo, o convidado pode reduzir / mínimo, o convidado pode aumentar.

Regras para as descrições dos níveis

5. Controlos

O círculo colorido com ícone (38 dp)

Um único lugar de assentamento de 38 dp em toda a aplicação:

Botões de opção

Envolvê-los em Box(Modifier.size(38.dp), contentAlignment=Center) { RadioButton(...) } para que o centro do círculo do botão coincida com o centro do círculo colorido acima. Sem o invólucro o botão desloca-se na horizontal, porque RadioButton se desenha com preenchimentos próprios.

Entre o botão de opção e o seu texto: Spacer(14.dp). Entre linhas de botões de opção de um grupo: Column(spacedBy(4.dp)).

A área tátil mínima está desativada: CompositionLocalProvider(LocalMinimumInteractiveComponentEnforcement provides false) — caso contrário cada linha de opção incha até 48 dp e quebra o ritmo.

Switch

Um interruptor padrão do Material 3, à direita do título do cartão. Desliga a regra inteira e a cor do nível deixa de ser mostrada — o círculo fica cinzento.

Linha segmentada

Um controlo próprio para trocar de modo dentro de uma regra — hoje só no Wi-Fi: Por uma rede específica / Pelas redes em redor. Dois elementos numa Row, cada um com weight(1f):

Botões cápsula

Um contorno, um ícone e texto, totalmente arredondados. Para ações secundárias — Usar a posição atual, Capturar as redes em redor. Quando desativados, o contorno e o texto descem para alpha=0.4.

Slider

Ver a secção 3 sobre offset(y=-16.dp) e sliderTrim(). Antes de um cursor vai sempre um StatusLine com texto de estado (bodySmall, atenuado) — 74 m · máximo, o convidado pode reduzir.

O menu pendente de níveis

Abre-se tocando na linha de título do cartão — toda a Row exceto o interruptor. Aparece logo abaixo do cabeçalho, a toda a largura do conteúdo do cartão. Para isso:

Os itens do menu respiram em vez de serem linhas achatadas: um marcador de cor à esquerda, o rótulo a negrito e por baixo a descrição em letra pequena e atenuada. Alinham-se na vertical pela primeira linha, o rótulo.

6. Animações

O círculo pulsante da Ativação

Ao contrário dos círculos coloridos normais das regras, o círculo do cabeçalho da Ativação pulsa.

Não mexer na fórmula da opacidade. Custou várias iterações, e qualquer simplificação — linear (1−p) ou ease-out — produz um solavanco visível.

7. Regras do texto

Punctuation

Uma única frase numa cadeia da interface não leva ponto. Os pontos só aparecem quando há duas frases ou mais, para as separar. Vale para toda a descrição, dica, estado, balão de ajuda, cabeçalho e frase solta.

Em que voz escrevemos

Escolher entre um máximo e um valor exato

Nos estados do cursor em modo amarelo (Predefinido) indicamos sem rodeios a direção da liberdade:

A vermelho (Bloqueado): 74 m · exatamente / 5 de 7 · exatamente.

Os nomes dos níveis estão assentes

Decide o convidado / Predefinido / Bloqueado pegaram; não os mudamos.

8. Padrões de interação

Um interruptor ou uma opção de rádio não selecionado

Se uma regra tem estado desligado, exprima-o com um interruptor e não com uma opção de rádio do tipo Não é preciso / Não / Desligado. Caso contrário o utilizador tem duas maneiras de desligar a mesma coisa, e isso confunde.

Examples:

As coordenadas e as ações à direita

No bloco Coordenadas os ícones de copiar e apagar ficam à direita ao nível das duas linhas (o rótulo e o estado). Implementado como Row { Column(weight=1f) { label; status }; CopyIcon; DeleteIcon }. Os ícones centram-se na vertical em relação ao par inteiro.

Mostrar e ocultar o corpo de um cartão

O corpo abre-se apenas quando:

Animation: expandVertically(tween(220)) + fadeIn(tween(220)) ao abrir, shrinkVertically(tween(180)) + fadeOut(tween(120)) ao fechar.

Quando mostrar o diálogo Chave adicionada

Ao receber uma chave de convidado — só se a aplicação estiver no ecrã e a chave for nova e não repetida. Caso contrário guardamos em silêncio.

9. O que não mexer

Documentos relacionados

Última atualização: 18 de abril de 2026 · versão do documento 2.07