Tuff: catálogo a base visual do VSSH

Todo componente da biblioteca, numa página só, sem servidor e sem build. O que se julga aqui é se uma janela montada com estas peças passa por janela do ambiente, ou se denuncia que é uma página web dentro de outra.

O que não está aqui, e nunca vai estar: diálogo, menu de contexto, aviso, bandeja e seletor de arquivo. Essas superfícies são do desktop. O app as pede por vssh.dialog, vssh.contextMenu, vssh.toast e vssh.pickFile, e é por isso que elas se parecem com o resto do ambiente em vez de serem um <div> que alguém estilizou.

Botões
Três variantes. O primário tira a cor do destaque da pessoa.
quadrados, para barra e chrome, onde perdem a moldura

A barra de ações gruda no fim do painel. Botão flutuando no meio do espaço é o sintoma mais comum de tela feita às pressas.
Campos
Nunca controle nativo, inclusive a lista aberta do select.
Linhas de configuração
Rótulo e valor nunca com o mesmo peso. Sem hierarquia, a coluna vira uma pilha de pares iguais.
Manter o backend vivo
Fechar a janela não encerra o processo.
Aceleração por GPU
Sem placa detectada neste servidor.
Qualidade
Vale para novas sessões.
Estado
As cores são as semânticas do ambiente, as mesmas em toda peça.
no ar degradado fora subindo desconhecido
python3 ffmpeg python3-pip
Ctrl Shift P
Espera
Spinner para "não sei quanto falta"; barra para "sei". Trocar os dois custa confiança.
Conectando ao servidor…
Listas
A seleção usa o mesmo realce do gerenciador de arquivos do ambiente.
4 itens
relatorio-2026.pdf
medicoes.parquet
notas.md
um-nome-bem-comprido-que-nao-cabe-na-coluna.tar.gz
caminho
/home/pesquisador/dados
socket
/run/user/1000/vssh-app.sock
Nome de arquivo
TuffNome.desenhar quebra nos separadores e, quando o nome não cabe em duas linhas, corta no meio e guarda a extensão.
Dicas e vazio
Uma tela vazia é um convite para agir. A frase diz o que fazer.
O servidor resolve o caminho; a sua máquina não entra.
Sem systemd de usuário, nenhum limite é aplicado. É informação, sem erro.
O socket já está em uso por outra instância deste app.
Nenhuma pasta escolhida
Escolha uma pasta do servidor para começar. O app lê e grava nela como você.
O índice não abriu
O servidor de busca não respondeu.
Detalhe técnico
Código 503
Detalhe
<details> nativo: abre sem JavaScript e é achável pelo Ctrl+F do navegador.
Por que o app não vê meus arquivos
O backend roda como você no servidor, com acesso POSIX. O seletor existe para você dizer qual pasta, e a permissão já havia.
Tooltip
Passe o ponteiro sobre este item. O title nativo seria desenhado pelo sistema: claro, com fonte do sistema, no meio de uma janela escura.
Abas
A encaixada: a ativa tem a cor da barra de baixo e se liga a ela, e as outras ficam soltas, separadas por um fio. As setas, Home e End andam entre as abas, e Delete fecha. Com reordenar, uma aba arrastada troca de lugar na tira, e Ctrl+Shift com a seta a move pelo teclado.
Trilha
O caminho até o lugar atual, de TuffTrilha.desenhar. Quando não cabe, as partes do meio recolhem num "…" e a pasta atual continua inteira. O "…" e os rótulos da barra de menus abrem o menu do ambiente, que fora dele não existe.
Barra de menus
Os rótulos de um app de documento, ligados por TuffMenus.ligar: as setas andam entre eles, e com o Alt apertado a letra de atalho aparece sublinhada.
Tabela
Colunas que se ordenam pelo clique ou pelo Enter no cabeçalho, com a ordem em aria-sort. A forma em grade mede a própria largura: abaixo de 480 px, as colunas que não são essenciais descem para a segunda linha do item.
Alça de largura
A borda entre duas regiões, que se arrasta para mudar a largura de uma delas, com TuffAlca.ligar. No teclado, as setas andam 16 px, Home e End vão aos limites, e o duplo clique volta à largura de partida.
A lista cede o espaço.
O painel muda de largura.
Ícones de arquivo
A folha com selo, de TuffArquivo.svg: o glifo do tipo na cor dele e a extensão no selo. A pasta segue a cor de destaque, e as da pessoa levam a gravura. Num contêiner .tuff-arquivo-p o selo some.
Pessoas
A cor é da pessoa e a acompanha: no avatar, no cursor e na prévia. O ponto verde é quem está no documento agora.
AM HD RA AM

A pesquisa ouviu docentes de quatro escoHelenalas da rede estadual.

Ícones
Os que o shell pede, os que um visualizador de fotos e um player de vídeo pedem, e os de edição de texto, comentário e pessoas. Um traço só, 16×16, currentColor. Passe o ponteiro para ver o nome.
14, 16 e 20. A cor vem do texto ao redor, sempre. herda a cor

HTML sem classe

Com tuff-base.css, que o tuff: true injeta, a tag sem classe sai com o desenho da peça ao lado. A base fica em @layer vssh com especificidade zero, e só pega o elemento sem classe nenhuma: um botão com a classe do próprio app fica como o app o desenhou. A caixa de marcar, a opção e a faixa continuam nativas, com a cor de destaque.

sem classea peça
NomeTamanho
dados-campo.csv88 KB
NomeTamanho
dados-campo.csv88 KB

80%
Detalhes
bad CRC 3f1a92c1 (should be 8b04e7d2)
Pasta de rede
O grupo de campo usa a legenda como o rótulo da peça.

Moldura de app

As cinco regiões de um app de lista e detalhe: a barra, a lateral, o miolo, o painel e o rodapé. A disposição sai da largura da moldura, nas classes de janela do Android. De 840 px em diante as três colunas ficam lado a lado; de 600 a 839 o painel entra por cima do miolo, pela borda direita; abaixo de 600 a lateral vira gaveta, o painel vira a tela seguinte, e os botões de prioridade baixa da barra vão para o "Mais". Estique a caixa pelo canto de baixo.

Moldura
.tuff-app com TuffApp.ligar. O app chama abrirPainel(item) ao selecionar, e o foco volta ao item quando o painel fecha.

Mídia

O shell não tem player, nem grade de fotos, nem visor com zoom. O chrome de mídia usa o material do ambiente, opaco e com a divisa da barra de tarefas, no lugar da barra de vidro que todo player web usa: o sistema declara --ds-blur: none, e isso é decisão de produto.

A assinatura: o destaque que você escolheu é o playhead. Troque a cor com esta página aberta e a trilha, o anel de seleção da grade e a borda da tira acompanham. As imagens abaixo são desenhadas em <canvas> na hora; mídia binária num repositório é uma dívida que ninguém revisita.

Player
A trilha tem 3px em repouso e 6px sob o ponteiro; o 6 é a medida de trilho fino do ambiente, a mesma da scrollbar. O timecode é monoespaçado com tabular-nums: em fonte proporcional o número treme a cada segundo, no único elemento que o olho segue continuamente.
15:47
15:47 / 41:37
O chrome some sozinho depois de 2,5 s sem ponteiro, e nunca com o foco do teclado dentro dele, nem com o vídeo pausado. Sumir ali deixaria quem navega por teclado sem controle e sem caminho de volta.
Transporte
O chrome acima fica sobre o vídeo e some sozinho. Isto é a outra peça: a barra que não some, embaixo da janela inteira, enquanto a pessoa navega a biblioteca, porque o vídeo não parou de tocar só porque ela foi olhar outra coisa. É o que separa um player de desktop de uma página com vídeo dentro.

Dois andares: em cima, onde estou no tempo; embaixo, o que eu faço. O aglomerado de transporte fica no centro óptico por 1fr auto 1fr; com flex ele andaria conforme o nome da faixa fosse curto ou comprido, e o botão que se procura sem olhar mudaria de lugar a cada vídeo.
12:04
41:37
entrevista-final.mkv
O botão de repetir acima está ligado, e o de aleatório não. A diferença vem de aria-pressed="true", que é o seletor do estado ligado. Um alternador idêntico nos dois estados faz a fila fazer algo que ninguém pediu.
Forma de onda
Os picos que o app mediu, uma barra por trecho, com regiões de cor: aqui, as falas de duas pessoas numa entrevista. O que já tocou fica aceso e o resto apagado, e a linha é a posição. Clique ou arraste para buscar; com o foco nela, as setas andam 5 s, e 1 s com Shift. Ela lê e escreve o tempo pela mesma régua do player, e as duas nunca discordam.
0:00
3:10
Grade virtualizada
10 000 itens, e só as fileiras visíveis existem no DOM. Setas e Home/End andam dentro; a grade inteira é uma parada de Tab só.
Visor
Roda para ampliar no ponteiro, arraste para mover, duplo-clique alterna entre caber na janela e 1:1. Sem inércia, de propósito: ferramenta de trabalho não desliza depois que a mão parou.
900 × 640