BikeControl (SwiftControl)
使用 Zwift Click、Zwift Play、Shimano Di2,或任何藍牙控制器搭配 MyWhoosh、Rouvy、Zwift 等。可於 iOS、Android、Windows 與 macOS 免費試用。
AI 翻譯
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
PWA de treino de Jiu-Jitsu que transforma o histórico de rolas no diagnóstico do jogo do aluno. Público principal: faixas branca e azul, mas tudo tem que fazer sentido pra qualquer faixa. Este arquivo é o mapa vivo do app: pra que serve cada parte, onde mora e quais regras não se quebram. Toda mudança que altera o que está aqui atualiza este arquivo na mesma hora, e o que deixou de existir sai daqui.檢視完整 README ↗
PWA de treino de Jiu-Jitsu que transforma o histórico de rolas no diagnóstico do jogo do aluno. Público principal: faixas branca e azul, mas tudo tem que fazer sentido pra qualquer faixa.
Este arquivo é o mapa vivo do app: pra que serve cada parte, onde mora e quais regras não se quebram. Toda mudança que altera o que está aqui atualiza este arquivo na mesma hora, e o que deixou de existir sai daqui.
jj-theta-eight.vercel.app (Vercel, deploy a cada push na main)n8n.nexusrugido.com (ver n8n/README.md)| Tela | Propósito | Grátis | Premium |
|---|---|---|---|
| Painel | O resumo do dia: ofensiva (toque abre "Sua ofensiva"), tatame, lutas, finalizações, metas e técnicas | números | gráficos e "o que treinar agora" |
| Treinos e rolas | O registro. Academia, professor e duração vêm do padrão; cada rola com parceiro, peso, posição inicial, pontos IBJJF e finalizações | tudo, sem limite | igual ao grátis |
| Estudo | Aulas e quiz. Por tema e Por dificuldade são livres; "Pra você" escolhe aula longa pelo jogo do aluno e tem as exclusivas de assinante | 1 aula completa + 1 rápida + 1 rodada de quiz por dia, quiz sorteado | Pra você, estudo sem limite, quiz que volta no que errou |
| Liga | Só a liga: o grupo da semana, pódio, sobe e desce de divisão. O ranking global abre por um link ("Os faixas-pretas da ofensiva") | tudo | igual ao grátis |
| Amigos | Pedidos de amizade e a sala (liga só de amigos, 3 a 5 pessoas) | tudo | igual ao grátis |
| Meu jogo | A faixa no topo, o estilo (o que aparece em mais rolas), onde ganha e onde cede | resumo | por situação (peso e posição inicial) |
| Minhas técnicas | O grau de cada técnica que apareceu nos rolas e o que falta pro próximo | tudo | o que treinar agora |
| Análise | Evolução, presença, contra quem luta, onde fica por cima | vitrine | tudo |
| Metas | Metas que o aluno assumiu; as que zeram (defesa, frequência) mostram quando e por quê | até 2, só as sugeridas | próprias e sem limite |
| Conquistas | Marcos e registro de graduação | tudo | igual ao grátis |
| Musculação (Força pro jiu-jitsu) | Os exercícios de força, resistência e prevenção de lesão (40 hoje; os que entram ganham a etiqueta "novo" por 30 dias) que mais ajudam no tatame, cada um com o plano pra encaixar no treino de academia que o aluno já faz (séries × repetições, vezes por semana, descanso, carga, onde entra, a regra de progressão sem fim e o erro comum; o como fazer é o botão de buscar o vídeo). Não registra academia | vitrine | tudo |
| Nutrição (Combustível pro jiu-jitsu) | Proteína, carboidrato e água pelo peso e pela semana de tatame, com a conta à vista (src/lib/nutricao.js, base ISSN); o dia de comida (a barra enche até a meta; na tela só o que comeu no dia, e o "Adicionar comida" abre a busca num popup; "Bati" verde e "Não bati" vermelho pra quem não anota; navega pelos dias), as rotinas (dietPlans, quantas quiser: dia de treino, dia de descanso, café da manhã; um toque aplica no dia, editor com a mesma busca; "Virar rotina" salva o dia), os alimentos da pessoa (foods, criados dentro do popup de busca), e um "?" em cada parte com a explicação, o mês de proteína num calendário (meals, um registro por dia); o dia que bateu ganha um ponto verde no calendário de presença; suplementação fechada numa sanfona no fim, só com o que ajuda (creatina, beta-alanina, cafeína, whey, kefir) e o que cada um faz no corpo e no tatame, sem veredito | pede o peso e mostra as contas dele na vitrine | tudo |
| Parceiros, Lesões | Apoio | tudo | igual ao grátis |
| Ajustes | Lista que abre popups: Perfil, Aparência, Como usar, App no celular, Avisos, Seus dados, Conta (sair e apagar a conta) | tudo | igual ao grátis |
| Painel do admin | Chaves de recurso, acervo de vídeos, medição, contas, links, vendas e recuperação. "Ver o app como" grátis ou premium | só admin | igual ao grátis |
O que é grátis e o que é pago mora em RECURSOS (src/lib/plano.js) e só vale com a chave cobranca ligada. Toda trava usa podeVer e mostra a Vitrine (a seção real borrada) ou o Convite (popup).
periodoDeDados (src/lib/periodo.js) e mostra o rótulo do período.npm run lint:copy barra o feminino e o travessão.src/lib/regras.js (avaliarTecnica). No treino, técnica fora da regra abre um popup: "Registrar mesmo assim", "Meu professor libera, não avisar mais" (settings.tecnicasLiberadas, desfaz em Ajustes → Perfil) ou "Não registrar". Em competição o aviso é de desclassificação.antigo no seed; a troca mora em src/db/renomeios.js), então aulas do acervo e dados da nuvem continuam ligados. Nenhuma técnica nova pode usar um nome antigo; teste:renomeios confere.teste:biblioteca reprova nome repetido, finalização que não termina em finalização e posição que não existe. A cópia repetida que saiu deixa o uid dela no campo juntou da que ficou (uids no catálogo), pra aula marcada com ela continuar achando. No aparelho, arrumarBiblioteca (db.js) corrige categoria e origem uma vez, sem subir. Katagatame: "da montada" e "dos 100kg"; o nome que servia pros dois foi pro 100kg. Armlock: todas as 12 versões que eram "Chave de braço ..." viraram "Armlock da/do ..." ("Armlock da guarda fechada" é o padrão e o que "armlock" solto acha); "chave de braço" continua achando na busca (APELIDOS_GERAIS). Ponto do rola tem uma vaga por vez (tecMeus[ponto][i] = a técnica da i-ésima vez, pode repetir). As mais usadas na frente: na aula, "As que você mais treina" (chips de 1 toque, por frequência); no ponto, até 3 técnicas que a pessoa mais usa naquele ponto embaixo da vaga vazia (, separado o seu lado do dele); na busca de técnica e na de finalização, as mais usadas no topo.registros, uma linha por registro, em JSON): o que está em TABELAS_SYNC (src/db/db.js), pra quem tem conta. Cada gravação entra numa fila (outbox) e sobe sozinha.sementeIntacta, src/lib/sync.js).__local). Sem isso a sincronização entrava em ciclo.garantirNuvem), inclusive as que entram no sync depois.restaurarPontos).supabase/conta.sql). A assinatura fica sem dono, porque registro de venda é guardado por lei.supabase/notificacoes.sql, pg_cron de hora em hora chamando a Edge Function notificar). No máximo um por dia.testar_aviso e diagnostico_de_aviso, só admin desde o SQL 14). Tem um botão pra cada aviso que existe (teste, ofensiva de 1 dia, ofensiva de vários dias, liga, resultado, volta); tocar de novo manda a próxima versão do texto (testar_aviso(email, tipo, dias, versao) desde o SQL 17b; a função usa o versao no lugar da versão do dia, só no teste). Aviso novo no sw.js precisa entrar também na lista AVISOS de src/components/TesteAviso.jsx.public/sw.js (função aviso): com a cara do tatame, com emoji e botões de ação, e se reveza por dia. Mudar texto é mexer lá, não no SQL.?ativar=CODIGO que libera com um toque (registrar_compra, guardarCodigoDaUrl/usarCodigoGuardado em src/lib/plano.js). Não existe mais o botão "Já assinei".src/components/Plano.jsx) mostra se renova sozinho, os dias pagos numa barra, as faturas (minha_assinatura(), lendo hotmart_evento) e o botão de renovar quando a renovação foi cancelada. Pagamento que não entrou manda pra Hotmart (Minhas compras) atualizar o cartão.src/components/Renovacao.jsx) aparece no máximo uma vez por dia, só com a cobrança ligada: renovação cancelada e faltando 7 dias ou menos, pagamento pendente, ou acabou há menos de uma semana. Quem renova sozinho nunca vê.npm run lint:copy barra a minúscula.src/lib/figurinha.js), com a folha em src/components/Figurinha.jsx. A logo e o nome NeuroJitsu saem sempre, em cima: cada post é propaganda. O @neuro_jitsu não vai na imagem (quem posta marca no Instagram); a folha só lembra de marcar.FRASES, uma lista por tipo (graduacao, recorde, ofensiva, semana, meta, marco), e quem abre a folha diz o tipo.temasFigurinha): a prévia mostra a cor, e no lugar dos botões aparece o convite.tipo: 'recorde', src/lib/milestones.js): um por recorde batido, a partir de 5 rolas ou 3h de tatame num dia. Aparece sozinho na comemoração depois de salvar o treino. Teste: npm run teste:marcos.public/figurinhas/, 8 PNGs sem fundo de ~30 KB, gerados com IA pelos prompts de NEUROJITSU-COLAR/18-PROMPTS-DESENHOS-FIGURINHA.md): vão no canto de cima à direita. Cada tipo tem um padrão (DESENHO_PADRAO) e a pessoa troca ou tira na fileira da folha. A arrumação prefere o desenho grande (até 560 px); com muito texto, primeiro a descrição e a frase diminuem um pouco, e só no fim o desenho encolhe. O número nunca fica abaixo de 84 px. Desenho novo entra em DESENHOS com o arquivo em 560×560./api/ia (Vercel Function) guarda a chave da Groq. Só atende conta logada (o token é conferido no Supabase). A Análise IA e o registrar falando (transcrever e ler_treino) pedem premium quando a cobrança está ligada; classificar vídeo é só do admin. Teste: teste:ia.
Registrar falando (src/components/Voz.jsx, src/lib/voz.js): o app grava o áudio (MediaRecorder, pedaços de 1 s por causa do iPhone, até 2 min por gravação, e cada gravação soma no texto) e o whisper-large-v3 da Groq transcreve em português, com a dica dos nomes da pessoa e das palavras do tatame. Sai o que o Whisper inventa no silêncio ("Legendas pela comunidade Amara.org", a própria dica, trecho em loop). Se a transcrição falhar, o áudio fica guardado e "Tentar de novo" reenvia. A IA monta o treino no tipo certo (open mat sem professor, competição com adversário pelo nome, drill sem rola, técnicas da aula com repetições), e professor, academia e parceiro novos viram cadastro. O reconhecimento de voz do navegador saiu: no Android ele parava no silêncio e repetia a frase a cada pedaço. Teste: teste:voz.
Limites: 500 MB de banco, 1 GB de arquivos, 5 GB de tráfego por mês. Em 24/09/2026: banco ~18 MB, 4 contas. Sem biblioteca na nuvem e sem o índice GIN (apagado), um aluno ativo ocupa ~0,5 a 0,8 MB por ano: o grátis aguenta algo como 500 a 700 alunos ativos por ano. O projeto não pausa (a vigia do pg_cron roda a cada 5 minutos). O grátis não tem backup: é o motivo pra ir pro Pro (US$ 25/mês) assim que tiver receita. Pra medir: NEUROJITSU-COLAR/12-VERIFICAR-BANCO.sql.
npm run check
Roda os linters (copy, símbolos, ciclos, chunks), o build e todos os testes, inclusive teste:telas, que abre todas as telas com cinco meses de dados falsos. Verde = pode subir.
Rodar local: npm install, cp .env.example .env.local, npm run dev. Sem .env.local funciona igual, só sem nuvem e sem IA.
Fase 2 do Premium (01/10): calculadora de horas (CalculadoraHoras, ritmoPelasHoras em lib/metas.js, grátis), o treino de hoje (lib/treinoDeHoje.js, cartão no Painel nos dias de treino), relatório do mês e retrospectiva do ano (lib/relatorio.js, RelatorioDoMes), raio-x do parceiro (lib/raioX.js, em Parceiros) e modo campeonato (lib/campeonato.js com a tabela de peso da IBJJF, ModoCampeonato na meta de campeonato). Os quatro últimos são Premium com a primeira parte grátis; testes em scripts/teste-fase2.mjs.
Backup dos dados: npm run backup (precisa do Docker e de SUPABASE_DB_URL no .env.local, a URI do Session pooler do Supabase). Salva um .dump em Downloads/neurojitsu-v12_7/NEUROJITSU-BACKUPS (fora do git, ficam os 10 mais novos), com os schemas public e auth; volta com pg_restore. supabase/44-tamanho-do-banco.sql (só leitura) mostra o uso dos 500 MB do plano grátis.
SQL do Supabase: os arquivos de supabase/ são a versão sem segredo; os prontos pra colar, com segredo, ficam em Downloads/neurojitsu-v12_7/NEUROJITSU-COLAR (fora do git). Desde 25/09 os SQLs novos são numerados em supabase/NN-*.sql (25 a 42).
Só as últimas, pra saber o estado atual. O detalhe de cada dia fica em Downloads/neurojitsu-v12_7/NEUROJITSU-RELATORIOS.
teste:metas): as horas de tatame nascem do ritmo (alvoDeHoras em metas.js: treinos por semana × semanas que faltam até 31/12 × duração do Gi; modos derivada, manual, desligada em settings.metaAnualHorasModo), com o cartão no último passo do onboarding e a origem escrita em Metas, Painel e Ajustes. Meta que depende de técnica não existe sem técnica (metaIncompleta): sai do onboarding, não fica ativa e pede a técnica (biblioteca de finalizações também). "1 treino" mantém a ofensiva, em número.enfileirarAjustes, registro settings com o id da conta em registros): celular novo recupera ano, metas de horas, academia, liberadas e não repete o primeiro acesso. Aparelho virgem nunca sobe configuração em branco e aceita a da nuvem. teste:sync cobre aparelho A → nuvem → aparelho B, sem duplicar e sem sobrescrever o mais novo.perfil.lesao_desde, resultado protegido, SQL supabase/35-liga-lesao.sql). Nutrição: suplementos lado a lado (src/db/suplementos.js). Acervo: vídeo novo já grava se é em pé. Avisos com prazo (SQL 36-avisos-contagem-regressiva.sql): reta final da ofensiva no domingo às 21h de Brasília, com o tempo que falta contado no celular (public/sw.js, tag ofensiva_reta_final); meta de treinos por semana avisa no dia em que não sobra folga, toda semana. 37-raio-x-avisos.sql (só leitura) mostra se o cron, a função e os envios estão de pé. Onboarding pergunta quanto dura 1 treino (vira duracaoTreinoPadrao e base das horas). Parceiros: abas na ordem do padrão do treino (Academias, Professores, Parceiros); todo parceiro tem academia (sem nenhuma, o cadastro começa por ela; no rola, entra na academia do treino); peso do parceiro é relativo (pesoRel, igual ao rola) e escolher o parceiro no rola já marca o peso. Academia e professor se cadastram por cima do treino (SheetAcademia, SheetProfessor em Parceiros.jsx). 38-respostas-por-origem.sql separa as respostas do banco por origem. Relógio da reta final: aviso de site não tem o cronômetro nativo do Android (o do Duolingo é app da loja); o sw.js desenha um cartão com o tempo que falta (OffscreenCanvas, imagem do aviso) e no domingo das 21h à meia-noite o cron (SQL 39) faz o aviso ser redesenhado de 15 em 15 minutos, em silêncio, tocando às 21h e às 23h. Toda copy de aviso cabe no aviso fechado (título ~30, texto ~75 caracteres). Avisos do tatame (SQL 40): pós-treino nos dias em que a pessoa costuma treinar, reta final da liga pra quem está na zona de rebaixamento (mesma conta do fechar_semana, com o relógio), amigo que te passou nos pontos da semana, resumo de segunda (substitui o resultado da liga), técnica perto do grau (o Painel manda nas configurações: e ) e campeonato faltando 7, 3, 2 e 1 dia. No máximo 1 aviso por dia e nada entre 22h e 8h; só as retas finais e a ofensiva de domingo ficam fora. Oferta do Premium ( em Plano.jsx, aberta de qualquer botão de venda por ): 4 promessas, anual (R$ 297, destaque) e mensal (R$ 29,90) com preço ( em lib/plano.js), garantia e com data. : abre a oferta, confere o acesso de novo por 30 min depois do clique em Assinar (libera na hora), comemora quando vira Premium e pede o presente de 7 dias no 1º treino (, SQL 41). SQL 41 também corrige o (coluna ambígua: falhava pra todo mundo logado) e cria o funil (, , visto em Medição do admin). Dois checkouts (SQL 42): Hotmart e Getfy entram pelo n8n (, ) e caem no mesmo ; a assinatura guarda a e o app manda gerenciar/cancelar no checkout certo ( em Renovacao.jsx).Regras da IBJJF mudam de temporada: confirme no site oficial antes de competir. Orientações de treino, nutrição e recuperação são educativas e não substituem profissional nem o seu professor.
recentesFocomaisNoPontosession.focoPosicoes (slugs do mapa) ao lado de focoTecnicas. As 82 entradas com etiqueta posicao (De La Riva, Montada...) saem da busca de técnica da aula. Regras em src/lib/posicoes.js (passagem e queda listam por categoria); tela em src/components/PosicaoDaAula.jsx.variacaoProvavel em src/lib/golpes.js): o último ponto marcado no rola, a posição inicial, a posição da aula; depois o que a pessoa já registrou; depois o jeito padrão. O nome no chip abre "De onde saiu?" pra trocar com 1 toque; + e − continuam somando várias no mesmo rola (8 do professor cabem). O golpe sai do nome por regra (GOLPES), então técnica nova cai no golpe sozinha. No ponto do rola, a busca de técnica sugere primeiro as da posição da aula.ler_treino (api/ia.js) recebe a lista de posições (slug: nome) e devolve posicoes (tema da aula), tecMeus/tecDele (a técnica de cada ponto, só nome exato) e a finalização na versão da posição quando a pessoa fala de onde saiu; quando não fala, devolve só o golpe e o app escolhe a origem pelo rola (resolverFinalizacao). Posição que vem como técnica ("De La Riva") vira posição da aula antes da conferência. Técnica de ponto que não existe na biblioteca é descartada (o ponto continua valendo).repertorioPorPosicao (src/lib/posicoes.js) conta, por posição, quantas técnicas diferentes entraram em rola e quantas vezes (técnica do ponto + finalização aplicada; passagem em "Combatendo a guarda", queda em "De pé"; drill não conta). Meu jogo: cartão "Suas posições" (número e dica da posição com 1 saída grátis; quais técnicas, Premium pelo recurso meujogo). Minhas técnicas: posição sai da conta e da lista de técnicas e ganha a seção Posições (aulas de tema, saídas no rola, grau antigo guardado); a ficha da finalização mostra "o mesmo golpe, de outro lugar".minhasTecnicas deixa a posição de fora por padrão (Painel, Conquistas, marcos, Estudo, Ajustes); Minhas técnicas e Metas pedem { comPosicoes: true }. ehPosicao reconhece pela etiqueta e pelo nome do catálogo (aparelho antigo). Treino de hoje ganha a linha da posição (posicaoDeHoje: a aula da semana que não chegou no rola, ou a posição com 1 saída); Relatório do mês/ano ganha "a posição do mês" e "entrou no seu jogo"; Raio-x mostra de que posição sai o seu ataque nele e o dele em você.dia:N (0 = segunda): aula rápida, seu jogo, meta, técnica, aula pro fim de semana, liga, aula de domingo. Quem ignorou 7 avisos não some mais, recebe só esse. A trava de 30 dias da "volta" foi pra dentro da escolha, pra não ocupar a hora. Botão de cada tema no sw.js (BOTAO_DO_DIA); teste no painel de avisos do admin.settings.avisosDoApp perto, pega (golpe que mais te pega), unica (posição com 1 saída), forte (técnica que mais entra) e tema (aula da semana que não chegou no rola); tema_do_aviso roda um fato por dia e aviso_do_dia escreve o texto (dia:perto... ou dia:0-6, a frase de tatame do dia da semana). Saiu o "a liga fecha hoje" de domingo de manhã. Botão de cada um no sw.js (BOTAO_DO_DIA).assinantes) ou particular (avulso) chega com a chave chave_da_aula ("p" + 15 letras, chavePaga em lib/aulas.js), sem capa do YouTube (a Capa desenha a arte), e o vídeo só sai por abrir_aula (Premium, presente, cobrança desligada ou compra). A tabela pública mostra só as grátis. minhas_compras volta na chave. Acervo FORMATO 4 limpa o cache velho. teste:aulas-pagas confere.ExclusivasDoApp), pra todo mundo.AulaQueDestrava + exclusivaPara(pedido): pro assunto que trava a pessoa (bloco do Pra você, "o que mais te pega" no Painel), o motor procura entre as exclusivas do Premium a que vai direto nele; só aparece se for do assunto (nunca reserva/genérica). Grátis vê com cadeado e "Desbloquear a aula"; Premium, "Assistir". A exclusiva sai da lista comum e não repete na faixa do topo; sem aula grátis do assunto, o bloco existe só com ela.fimEm) e calcula quanto falta; fases que passaram com o app no fundo já passam. Pausa de verdade, tela acesa religada ao voltar, aviso do celular no fim do round com o app no fundo (soFocar no sw.js: o toque não recarrega).corrigirClassificacao (classificar.js) roda na leitura do acervo (acervo.js, FORMATO 5): posição de domínio sem neutro (ataque = cima, defesa = baixo; lógica geral fica neutra), título de defesa sem a palavra "defesa" ("o que fazer quando pegam…") ganha escapada + defesa, "saindo" só é fuga abrindo o título, 100kg de peso do corpo não é posição. ehAulaDeDefesa: o motor não manda aula de defender pra quem quer aprender o golpe. Pedido de posição marca como "em geral" a aula que não trata dela. Necessidade nova "Defender a queda" (ponto de queda sofrido → queda_sofrida, só aula de defesa). Prompt da IA (classificar_videos) com regras de ataque × defesa, lado e queda; 50-reclassificar-aulas.sql devolve as automáticas pra fila. Relatório e guia de título: NEUROJITSU-RELATORIOS/2026-10-13-aulas-cobertura-e-titulos.md.public.faxina() às 7h30 UTC: apaga o histórico do agendador com mais de 7 dias (a vigia sozinha grava ~300 linhas por dia) e os avisos enviados com mais de 120 dias (as regras olham no máximo 60). 47-verificar-avisos-e-banco.sql confere 45, 46, avisos por dia e tamanho do banco.settings.anoNascimento). Abaixo de 16, um responsável autoriza. A idade decide a regra das técnicas, a divisão de campeonato (divisaoDaIdade, src/lib/idade.js) e esconde a dose de creatina, beta-alanina e cafeína antes dos 18.notificar-reta-finalavisosDoApppertosubiramOfertaPremiumpedirOferta(recurso)PRECOSNOVIDADEScomponents/PremiumNoApp.jsxganhar_presentemeu_acessomarcar_funilfunil_premium/webhook/hotmart/webhook/getfyprocessar_vendaorigemondeGerenciarliga.js: beneficiosDa, progressoPraSubir, escudosDaDivisao, molduraDe; SQL supabase/liga-divisoes.sql = NEUROJITSU-COLAR/24): moldura na foto (Estadual+), selo "Divisão X" na figurinha (Estadual+), ofensiva com 3 escudos (Nacional+), coroa no Mundial, +30 no total ao subir (evento divisao, do servidor, fora da corrida e fora da ofensiva) e o recorde da melhor divisão (total_xp.melhor_divisao, minha_divisao()). Na Liga, tocar na divisão abre "As divisões da liga" (a escada, onde você está, o recorde, o que cada uma dá, subir e descer), e a barra "Pra subir pro X" mostra pontos, 1º lugar e grupo valendo. O pódio da Liga é o de medalhas da Competição, com foto, desde 2 pessoas, e quem ficou fora aparece embaixo.aula.vertical: a esteira pede part=player&maxHeight ao YouTube e grava; o Acervo do painel completa sozinho os que faltam; SQL supabase/aula-vertical.sql = NEUROJITSU-COLAR/23). Sem a proporção, vale o short. Legenda tira num toque só (o toque olha a legenda que está na tela). Liga: subir só vale com 3+ no grupo e com o mínimo de pontos da divisão (80/120/170/220, minimo_pra_subir no SQL 22). Treinos: no celular, Novo treino fica numa linha só dele.Liga.jsx, liga.js, SQL supabase/liga-resultado.sql = NEUROJITSU-COLAR/22): relógio da semana ("fecha em 2d 14h", os dias e a bandeira de segunda 12h de Brasília, relogioDaLiga), o grupo enchendo (quem já entrou com foto e as vagas procurando), radar de "Procurando adversários" quando está sozinho, passo a passo pra quem ainda não entrou, e o resultado da semana passada (posição, subiu/desceu/ficou, de qual divisão pra qual, pódio com foto), que abre num popup uma vez quando a semana fecha e fica no topo da Liga a semana seguinte. O fechamento agora guarda posição, resultado e divisão antes/depois de cada um (minha_semana_passada()). Cronômetro apita também com 1 minuto pro fim, igual aos 10s. Falar ganhou o diamante do Premium.renomeou_v3)..player-caixa > div do vídeo esticava a barra até o topo, e o fixed dentro da folha com transform ia pro meio), com play redondo, tempo, legenda e sair. Aula rápida (short) fica em pé na janela e na tela cheia, sem deitar o celular.pedido.defesa em necessidades.js, ensinaDefesa no motor): a aula de aplicar a técnica não responde "Defesa contra X". Ordem: defesa da técnica → defesa da família → sair da posição de onde ela sai ("esta ensina a sair do 100kg, de onde ela costuma sair") → defesa em geral, sempre dizendo o que falta. Técnicas que viraram um nome só levam todos os uids pro pedido.vezesNaPosicao), igual à escada. Nomes: a lista antiga de renomeação (db.js) desfazia a varredura a cada abertura ("Chave de braço, armlock") e deixava "Katagatame (braço-cabeça)" nos rolas; agora aponta pro nome final (nomeFinal) e a varredura roda de novo (renomeou_v2).Campeonato em Treinos.jsx, situacaoDoCampeonato em competicao.js): uma tela com 4 etapas (o campeonato, suas lutas, as outras lutas da chave, o pódio) e cada uma abre a sua. Cada luta entra quando acontece ("Registrar a 2ª luta") e cada etapa grava na hora (salvarEtapa): dá pra fechar entre uma luta e outra, e a lista mostra "Em andamento". Sem tempo: a luta vale o tempo oficial da faixa (tempoDaLuta). O pódio só usa nomes que já apareceram (lutas e chave, sem duplicar por acento), sugere você campeão quando venceu todas e dá a colocação (sai o "Como terminou"). Pesagem explicada pra Gi e No-Gi. Teste: teste:campeonato (o caminho inteiro no app).voz em RECURSOS).NEUROJITSU-RELATORIOS/2026-09-25-tecnicas-para-revisar.csv.regras.js, teste:regras): o escudo no seletor e o popup no treino. Idade: passo "Sua idade" no primeiro acesso (9 etapas), pergunta única pra quem já usava (PerguntaIdade), campo em Ajustes → Perfil, divisão Infantil no campeonato, Privacidade atualizada (aceite de novo, versão 2026-09-25.1).teste:resultados prova que cada rola cai no balde certo e que gráfico, totais e resumo batem.graficoForma). Nas barras, partes do mesmo todo empilham (como venceu, como perdeu) e lados opostos espelham (ganhou e perdeu, finalizações, pontos). Saiu "Variedade técnica"; o volume desenha só rolas, com as horas no número de cima.EscolherData: "Hoje" em destaque, outro dia no popup). Graduação escolhe academia e professor de Parceiros (AcademiaProfessor). Meta de campeonato e treino de Competição falam do mesmo evento: a meta vira atalho no treino e fecha sozinha quando o campeonato é registrado.ResumoDoTipo): Gi/No-Gi com vitória e armas, Drill com o que mais drillou, Open mat com parceiros, Aula privada com professores e técnicas, Competição com pódio de medalhas e a contagem do próximo campeonato da meta. Padrão por tipo (src/lib/padraoTreino.js): competição sem academia/professor, open mat sem professor, e cada tipo pode salvar o seu. Resumo de campeonato conta vitória pela regra do placar (antes, luta com finalização contava como vitória mesmo perdida).FORMA em Treinos.jsx): Drill com repetições por técnica e sem rola; Open mat sem professor; Aula particular com rola opcional ("Teve rola no fim da aula"); Competição sem aula, adversário pelo nome, a chave da categoria (lutas dos outros só com quem venceu) e o pódio (campeão, vice, dois 3º) com você em destaque (EU, podioComEu em competicao.js). "Novo treino" dentro de uma aba já nasce daquele tipo.evento_valor do servidor).lint:copy barra palavras de IA (mergulhar, jornada, alavancar...).