diff --git a/app/index.html b/app/index.html
index 766e446..c8691b9 100644
--- a/app/index.html
+++ b/app/index.html
@@ -5,8 +5,8 @@
-
-
VentoApp — NBR 6123:2023
+
+ BrainWind v1.0 — NBR 6123:2023
diff --git a/app/src/components/EducationalManual.tsx b/app/src/components/EducationalManual.tsx
index 44882c6..d1635de 100644
--- a/app/src/components/EducationalManual.tsx
+++ b/app/src/components/EducationalManual.tsx
@@ -207,7 +207,7 @@ export function EducationalManual({ type, params }: EducationalManualProps) {
- VentoApp • Referência: ABNT NBR 6123:2023
+ BrainWind v1.0 • Referência: ABNT NBR 6123:2023
diff --git a/app/src/lib/__tests__/export-ftool.test.ts b/app/src/lib/__tests__/export-ftool.test.ts
index c2a41ee..78e29d1 100644
--- a/app/src/lib/__tests__/export-ftool.test.ts
+++ b/app/src/lib/__tests__/export-ftool.test.ts
@@ -136,8 +136,8 @@ describe('M9.4 — serializeFtool (texto exportado)', () => {
txt = serializeFtool(model);
});
- it('Contém cabeçalho VentoApp', () => {
- expect(txt).toContain('VentoApp');
+ it('Contém cabeçalho BrainWind', () => {
+ expect(txt).toContain('BrainWind v1.0');
expect(txt).toContain('NBR 6123:2023');
});
diff --git a/app/src/lib/__tests__/i18n.test.ts b/app/src/lib/__tests__/i18n.test.ts
index 17aceee..0ae6d98 100644
--- a/app/src/lib/__tests__/i18n.test.ts
+++ b/app/src/lib/__tests__/i18n.test.ts
@@ -36,9 +36,11 @@ describe('M9.8 — Dicionário de traduções', () => {
expect(t('nav_warehouse', 'pt-BR')).not.toBe(t('nav_warehouse', 'en-US'));
});
- it('Chaves "neutras" (marca) são iguais em pt-BR e en-US', () => {
- expect(t('app_title', 'pt-BR')).toBe('VentoApp');
- expect(t('app_title', 'en-US')).toBe('VentoApp');
+ describe('Traduções básicas', () => {
+ it('app_title', () => {
+ expect(t('app_title', 'pt-BR')).toBe('BrainWind v1.0');
+ expect(t('app_title', 'en-US')).toBe('BrainWind v1.0');
+ });
});
it('Fallback para pt-BR quando locale é inválido', () => {
@@ -151,7 +153,7 @@ describe('M9.8 — Persistência localStorage (via polyfill)', () => {
});
describe('M9.8 — Chaves principais em pt-BR', () => {
- it('app_title = VentoApp', () => expect(t('app_title', 'pt-BR')).toBe('VentoApp'));
+ it('app_title = BrainWind v1.0', () => expect(t('app_title', 'pt-BR')).toBe('BrainWind v1.0'));
it('nav_home = Início', () => expect(t('nav_home', 'pt-BR')).toBe('Início'));
it('nav_warehouse = Galpão', () => expect(t('nav_warehouse', 'pt-BR')).toBe('Galpão'));
it('nav_cylinder = Cilindro', () => expect(t('nav_cylinder', 'pt-BR')).toBe('Cilindro'));
diff --git a/app/src/lib/audit/invariantes.ts b/app/src/lib/audit/invariantes.ts
new file mode 100644
index 0000000..b9d18dd
--- /dev/null
+++ b/app/src/lib/audit/invariantes.ts
@@ -0,0 +1,176 @@
+export const INVARIANTES_NBR6123 = `
+## Checklist de Verificação — NBR 6123:2023
+
+Use esta lista para auditar os resultados. Cada regra é OBRIGATÓRIA.
+
+---
+
+### GLOBAIS
+
+1. **q = 0.613 × Vk² / 1000** — fórmula exata, sem aproximação
+ - Calc: q_N = 0.613 × Vk²; q_kN = q_N / 1000
+ - Tolerância: ±0.0001 kN/m²
+
+2. **Vk = V0 × S1 × S2 × S3** — fórmula exata
+ - Verificar: Vk / (V0 × S1 × S2 × S3) ≈ 1.0
+ - Tolerância: ±0.01 m/s no arredondamento
+
+3. **S2 é não-decrescente com z** — monotonicidade
+ - Para z1 < z2: S2(z1) <= S2(z2)
+ - Exceto se z1 < 5m (nesse caso S2(5m) é o piso)
+
+4. **S2 saturado em z >= z_g**
+ - Cat I: z_g=250m, Cat II: z_g=300m, Cat III: z_g=350m
+ - Cat IV: z_g=420m, Cat V: z_g=500m
+
+5. **Cpi ∈ [-0.9, +0.9]** — limite normativo SEMPRE
+ - Qualquer valor fora deste intervalo = FAIL
+
+6. **Classe estrutural correta**
+ - dim <= 20 → Classe A
+ - 20 < dim <= 50 → Classe B
+ - dim > 50 → Classe C
+
+---
+
+### GALPÃO (paredes e telhados)
+
+7. **Pressão em cada zona = q × (Cpe − Cpi)**
+ - Verificar: p(Cpe) = q × (Cpe − Cpi)
+ - Cpe vem da Tabela 6 (paredes) ou Tabela 7 (telhados)
+
+8. **Sinal da zona C (sotavento)** — tipicamente positiva
+ - Cpe zona C > 0 (pressão) quando α=0°
+ - Exceção: quando Cpi é suficientemente negativo
+
+9. **Sinal das zonas E/F (barlavento do telhado)** — tipicamente negativas
+ - Cpe zona E < 0 (sucção) na maioria dos casos
+ - Verificar que não é > 0 sem motivo
+
+10. **Força de atrito — aplica SOMENTE quando l0/h > 4 OU l0/b > 4**
+ - Se condição falsa: força de atrito deve ser ZERO
+ - Cf: smooth=0.01, ribbed=0.02, rectangular=0.04
+
+---
+
+### CILINDRO
+
+11. **Re = 70.000 × Vk × d** — fórmula exata
+ - Verificar que o Reynolds está correto para o Vk e d fornecidos
+
+12. **Cpe(0°) > 0 (barlavento)** — pressão sempre positiva em θ=0°
+ - exceto cilindro muito curto (h/d < 0.5) pode variar
+
+13. **Cpe(90°) < 0 (sucção)** — zona de separação
+ - Qualquer valor positivo em 90° é suspeito
+
+14. **Cpi para topo aberto: -0.8 se h/d >= 0.3, -0.5 caso contrário**
+ - h/d = altura / diâmetro
+
+15. **Regime supercrítico: Re > 400.000**
+ - Se Re < 400.000: tabela de subcrítico deve ser usada
+ - A Tabela 13 é válida para Re > 400.000
+
+---
+
+### ABÓBADA
+
+16. **f/l determina regime correto**
+ - Regime laminar (baixa turbulência):Tabelas 15-17
+ - Regime turbulento (alta turbulência): Tabelas 18-20
+
+17. **Cpe negativo na maioria das zonas de sucção**
+ - Abóbadas tipicamente geram sucção na superfície superior
+
+---
+
+### CÚPULA
+
+18. **f/d razão limitada**
+ - Cúpulas com f/d muito alto (>0.5) são raras
+ - Verificar que f/d está em faixa coberta pelas tabelas
+
+19. **Força de sustentação (lift) existe para cúpulas no solo**
+ - Cs (coeficiente de sustentação) deve ser calculado
+ - Cúpulas em parede cilíndrica têm Csi = 0
+
+---
+
+### MUROS E PLACAS
+
+20. **Cf entre 0.8 e 2.0 para placas planas**
+ - Fc = Cf × q × A (força total)
+ - Verificar: Cf está na faixa válida da Figura 7
+
+21. **Força aplicada no centro de pressão**
+ - Altura do ponto de aplicação conforme tipo de placa
+
+---
+
+### COBERTURAS ISOLADAS
+
+22. **Cpe para telhado isolado em shed/gable**
+ - Diferente de telhado conectado a paredes
+ - Verificar que usa Tabela 24 ou 25, não Tabela 7
+
+---
+
+### BARRAS
+
+23. **Ca decresce com phi crescente (barras planas)**
+ - phi=0.05 → Ca≈3.6
+ - phi=1.0 → Ca≈1.4
+
+24. **Barras circulares: Ca depende do regime de Reynolds**
+ - Subcrítico: Ca≈1.2
+ - Supercrítico: Ca≈0.6
+
+---
+
+### PONTES
+
+25. **Pse < 0.04 → Classe 1; 0.04-1.0 → Classe 2; >1.0 → Classe 3**
+ - Pse = ρ × V_it² / (m × fv²) — forma simplificada
+ - ρ = 1.226 kg/m³
+
+26. **V_it = 0.65 × V0 × S1 × b × (z/10)^p**
+ - b e p vêm da Tabela 35 por categoria
+
+27. **Cx diminui com B/Heg crescente**
+ - Cx = 0.21 + 1.83 × (B/Heg)^(-1.13) para 1 <= B/Heg <= 27
+ - Cx máximo = 2.0
+
+---
+
+### TORRES
+
+28. **Ca para torre quadrada de barras planas**
+ - Ca diminui com phi aumentando (mais sólido = menos arrasto por shielding)
+ - K_alpha: 1.0 para α<=12.5°, sobe para ~1.16 em α=45°
+
+29. **Ca para torre triangular**
+ - K_alpha = 1.0 sempre (não varia com ângulo)
+
+---
+
+### DINÂMICA
+
+30. **Strouhal: St ≈ 0.20 para circular, St ≈ 0.11 para quadrado**
+ - Usado para calcular velocidade crítica Vcr = f × D / St
+
+31. **Scruton: Sc = 2 × m × δs / (ρ × D²)**
+ - Verificar que está acima do limite crítico para supressão de vórtices
+
+32. **Conforto: a_lim = 0.01 × ka × f^1.124**
+ - ka: 6.12 (comercial), 4.06 (residencial)
+ - Válido SOMENTE para f ∈ [0.06, 1.00] Hz
+
+---
+
+### SINAL CONVENCIONAL
+
+33. **p > 0 → pressão (empurrando a superfície para dentro)**
+34. **p < 0 → sucção (puxando a superfície para fora)**
+35. **Nunca omitir Cpi no cálculo de pressão**
+ - p = q × (Cpe − Cpi) é a fórmula completa
+`;
diff --git a/app/src/lib/audit/norm-reference.ts b/app/src/lib/audit/norm-reference.ts
new file mode 100644
index 0000000..a0dce42
--- /dev/null
+++ b/app/src/lib/audit/norm-reference.ts
@@ -0,0 +1,367 @@
+export const NORM_REFERENCE = `
+# NBR 6123:2023 — Referência Completa para Auditoria
+
+Este documento é uma extração autoritativa dos dados da norma NBR 6123:2023,
+implementados no código-fonte do VentoApp. Use-o como referência para verificar
+se os cálculos do aplicativo estão corretos.
+
+---
+
+## Seção 4 — Velocidade Básica e Pressão Dinâmica
+
+### Fórmulas fundamentais
+
+- **Velocidade característica**: Vk = V0 × S1 × S2 × S3 (m/s)
+- **Pressão dinâmica**: q = 0.613 × Vk² / 1000 (kN/m²)
+- **Massa específica do ar**: ρ = 1.226 kg/m³
+
+### Símbolos
+
+| Símbolo | Significado |
+|---------|-------------|
+| V0 | Velocidade básica do vento (m/s) — Figura 1 ou Anexo C |
+| S1 | Fator topográfico (Seção 5.2) |
+| S2 | Fator de rugosidade do terreno, tamanho da edificação e altura (Seção 5.3) |
+| S3 | Fator estatístico (Seção 5.4) |
+| Vk | Velocidade característica do vento (m/s) |
+| q | Pressão dinâmica (kN/m²) |
+
+---
+
+## Seção 5.3 — Fator S2 (Tabela 3)
+
+### z_g — Altura da camada limite atmosférica (m)
+
+| Categoria | I | II | III | IV | V |
+|-----------|-----|-----|------|-----|-----|
+| z_g (m) | 250 | 300 | 350 | 420 | 500 |
+
+### Tabela 1 — Parâmetros b, p, Fr
+
+| Categoria | Classe A | Classe B | Classe C |
+|-----------|----------|----------|----------|
+| **I** | b=1.10, p=0.06, Fr=1.00 | b=1.11, p=0.065, Fr=0.98 | b=1.12, p=0.07, Fr=0.95 |
+| **II** | b=1.00, p=0.085, Fr=1.00 | b=1.00, p=0.09, Fr=0.98 | b=1.00, p=0.10, Fr=0.95 |
+| **III** | b=0.94, p=0.10, Fr=1.00 | b=0.94, p=0.105, Fr=0.98 | b=0.93, p=0.115, Fr=0.95 |
+| **IV** | b=0.86, p=0.12, Fr=1.00 | b=0.85, p=0.125, Fr=0.98 | b=0.84, p=0.135, Fr=0.95 |
+| **V** | b=0.74, p=0.15, Fr=1.00 | b=0.73, p=0.16, Fr=0.98 | b=0.71, p=0.175, Fr=0.95 |
+
+### Tabela 3 — Fator S2 (extrato das alturas mais importantes)
+
+| z(m) | I-A | I-B | I-C | II-A | II-B | II-C | III-A | III-B | III-C | IV-A | IV-B | IV-C | V-A | V-B | V-C |
+|-------|------|------|------|-------|-------|-------|--------|--------|--------|-------|-------|-------|------|------|------|
+| 5 | 1.06 | 1.04 | 1.01 | 0.94 | 0.92 | 0.89 | 0.83 | 0.81 | 0.78 | 0.74 | 0.72 | 0.69 | 0.63 | 0.61 | 0.58 |
+| 10 | 1.10 | 1.09 | 1.06 | 1.00 | 0.98 | 0.95 | 0.90 | 0.88 | 0.85 | 0.82 | 0.80 | 0.77 | 0.71 | 0.69 | 0.66 |
+| 15 | 1.13 | 1.12 | 1.10 | 1.04 | 1.02 | 0.99 | 0.94 | 0.93 | 0.90 | 0.87 | 0.85 | 0.82 | 0.77 | 0.75 | 0.72 |
+| 20 | 1.15 | 1.14 | 1.12 | 1.06 | 1.04 | 1.01 | 0.98 | 0.96 | 0.93 | 0.91 | 0.89 | 0.86 | 0.81 | 0.79 | 0.76 |
+| 30 | 1.17 | 1.17 | 1.15 | 1.10 | 1.08 | 1.05 | 1.03 | 1.01 | 0.99 | 0.96 | 0.94 | 0.92 | 0.87 | 0.85 | 0.82 |
+| 40 | 1.20 | 1.20 | 1.18 | 1.13 | 1.11 | 1.08 | 1.06 | 1.05 | 1.02 | 1.00 | 0.98 | 0.96 | 0.91 | 0.89 | 0.87 |
+| 50 | 1.21 | 1.21 | 1.20 | 1.15 | 1.13 | 1.10 | 1.09 | 1.08 | 1.05 | 1.03 | 1.01 | 0.99 | 0.94 | 0.92 | 0.90 |
+| 60 | 1.22 | 1.22 | 1.21 | 1.16 | 1.14 | 1.12 | 1.12 | 1.10 | 1.08 | 1.06 | 1.04 | 1.02 | 0.97 | 0.95 | 0.93 |
+| 80 | 1.25 | 1.24 | 1.23 | 1.19 | 1.17 | 1.15 | 1.16 | 1.14 | 1.12 | 1.10 | 1.08 | 1.06 | 1.01 | 0.99 | 0.97 |
+| 100 | 1.26 | 1.26 | 1.25 | 1.22 | 1.20 | 1.18 | 1.19 | 1.17 | 1.15 | 1.13 | 1.11 | 1.09 | 1.04 | 1.03 | 1.01 |
+| 120 | 1.28 | 1.28 | 1.27 | 1.23 | 1.21 | 1.19 | 1.21 | 1.20 | 1.18 | 1.15 | 1.14 | 1.12 | 1.07 | 1.06 | 1.04 |
+| 140 | 1.29 | 1.29 | 1.28 | 1.24 | 1.22 | 1.20 | 1.22 | 1.21 | 1.19 | 1.17 | 1.16 | 1.14 | 1.09 | 1.08 | 1.06 |
+| 160 | 1.30 | 1.30 | 1.29 | 1.25 | 1.23 | 1.21 | 1.23 | 1.22 | 1.20 | 1.18 | 1.17 | 1.15 | 1.11 | 1.10 | 1.08 |
+| 180 | 1.31 | 1.31 | 1.30 | 1.26 | 1.24 | 1.22 | 1.24 | 1.23 | 1.21 | 1.19 | 1.18 | 1.16 | 1.12 | 1.11 | 1.09 |
+| 200 | 1.32 | 1.32 | 1.31 | 1.27 | 1.25 | 1.23 | 1.25 | 1.24 | 1.22 | 1.20 | 1.19 | 1.17 | 1.14 | 1.13 | 1.11 |
+| 250 | 1.34 | 1.34 | 1.33 | 1.29 | 1.27 | 1.25 | 1.28 | 1.27 | 1.25 | 1.23 | 1.22 | 1.20 | 1.17 | 1.16 | 1.14 |
+| 300 | 1.34 | 1.34 | 1.33 | 1.30 | 1.28 | 1.26 | 1.30 | 1.29 | 1.27 | 1.25 | 1.24 | 1.22 | 1.20 | 1.19 | 1.17 |
+| 350 | 1.34 | 1.34 | 1.33 | 1.31 | 1.29 | 1.27 | 1.31 | 1.30 | 1.28 | 1.27 | 1.26 | 1.24 | 1.22 | 1.21 | 1.19 |
+| 400 | 1.34 | 1.34 | 1.34 | 1.32 | 1.30 | 1.28 | 1.32 | 1.31 | 1.29 | 1.28 | 1.27 | 1.25 | 1.24 | 1.23 | 1.21 |
+| 420 | 1.35 | 1.35 | 1.35 | 1.32 | 1.30 | 1.28 | 1.33 | 1.32 | 1.30 | 1.29 | 1.28 | 1.26 | 1.25 | 1.24 | 1.22 |
+| 450 | 1.35 | 1.35 | 1.35 | 1.33 | 1.31 | 1.29 | 1.34 | 1.33 | 1.31 | 1.30 | 1.29 | 1.27 | 1.26 | 1.25 | 1.23 |
+| 500 | 1.35 | 1.35 | 1.35 | 1.34 | 1.32 | 1.30 | 1.35 | 1.34 | 1.32 | 1.32 | 1.31 | 1.29 | 1.28 | 1.27 | 1.25 |
+
+**Nota**: z mínimo = 5 m (piso normativo). S2 é saturado para z >= z_g.
+
+---
+
+## Seção 5.4 — Fator S3 (Tabela 4)
+
+| Grupo | S3 | Descrição |
+|-------|------|-------------|
+| 1 | 1.11 | Hospitais, quartéis de bombeiro, centrais de controle, pontes, substâncias perigosas |
+| 2 | 1.06 | Edificações com risco à vida (aglomerações >200 pessoas) |
+| 3 | 1.00 | Edificações residences, hotéis, comércio, indústrias (padrão) |
+| 4 | 0.95 | Depósitos, silos, sem circulação de pessoas |
+| 5 | 0.83 | Construções temporárias (máx 2 anos) |
+
+---
+
+## Seção 5.3.2 — Classe Estrutural
+
+| Maior dimensão | Classe |
+|----------------|--------|
+| dim <= 20 m | A |
+| 20 < dim <= 50 m | B |
+| dim > 50 m | C |
+
+---
+
+## Seção 6.1.1 — Coeficientes de Pressão Externa em Paredes (Tabela 6)
+
+### α = 0° (vento perpendicular à largura b)
+
+| h/b | a/b | A1/B1 | A2/B2 | C (sotavento) | D |
+|------|------|--------|--------|----------------|----|
+| <=0.5 | 1.0–1.5 | -0.8 | -0.5 | +0.7 | -0.4 |
+| <=0.5 | >=2.0 | -0.8 | -0.4 | +0.7 | -0.3 |
+| 0.5–1.5 | 1.0–1.5 | -0.9 | -0.5 | +0.7 | -0.5 |
+| 0.5–1.5 | >=2.0 | -0.9 | -0.4 | +0.7 | -0.3 |
+| >1.5 | 1.0–1.5 | -1.0 | -0.6 | +0.8 | -0.6 |
+| >1.5 | >=2.0 | -1.0 | -0.5 | +0.8 | -0.3 |
+
+### α = 90° (vento perpendicular ao comprimento a)
+
+| h/b | a/b | A (barlavento) | B (lateral) | C1/D1 | C2/D2 |
+|------|------|--------|--------|----------------|----|
+| <=0.5 | 1.0–1.5 | +0.7 | -0.4 | -0.8 | -0.4 |
+| <=0.5 | >=2.0 | +0.7 | -0.5 | -0.9 | -0.5 |
+| 0.5–1.5 | 1.0–1.5 | +0.7 | -0.5 | -0.9 | -0.5 |
+| 0.5–1.5 | >=2.0 | +0.7 | -0.6 | -0.9 | -0.5 |
+| >1.5 | 1.0–1.5 | +0.8 | -0.6 | -1.0 | -0.6 |
+| >1.5 | >=2.0 | +0.8 | -0.6 | -1.0 | -0.6 |
+
+---
+
+## Seção 6.2.1 — Cilindros de Seção Circular (Tabela 13)
+
+### Reynolds: Re = 70.000 × Vk × d
+
+### Tabela 13 — Cpe por ângulo, h/d e superfície
+
+Ângulos: 0°, 10°, 20°, 30°, 40°, 50°, 60°, 70°, 80°, 90°, 100°, 120°, 140°, 160°, 180°
+
+**Superfície RUUGOSA (h/d = 10):**
+0°=+1.0, 10°=+0.9, 20°=+0.7, 30°=+0.4, 40°=0, 50°=-0.5, 60°=-0.95, 70°=-1.25, 80°=-1.2, 90°=-1.0, 100°=-0.8, 120°=-0.5, 140°=-0.4, 160°=-0.4, 180°=-0.4
+
+**Superfície RUUGOSA (h/d ≤ 2.5):**
+0°=+1.0, 10°=+0.9, 20°=+0.7, 30°=+0.4, 40°=0, 50°=-0.4, 60°=-0.8, 70°=-1.1, 80°=-1.05, 90°=-0.85, 100°=-0.65, 120°=-0.35, 140°=-0.3, 160°=-0.3, 180°=-0.3
+
+**Superfície LISSA (h/d = 10):**
+0°=+1.0, 10°=+0.9, 20°=+0.7, 30°=+0.35, 40°=0, 50°=-0.7, 60°=-1.2, 70°=-1.4, 80°=-1.45, 90°=-1.4, 100°=-1.1, 120°=-0.6, 140°=-0.35, 160°=-0.35, 180°=-0.35
+
+**Superfície LISSA (h/d ≤ 2.5):**
+0°=+1.0, 10°=+0.9, 20°=+0.7, 30°=+0.35, 40°=0, 50°=-0.5, 60°=-1.05, 70°=-1.25, 80°=-1.3, 90°=-1.2, 100°=-0.85, 120°=-0.4, 140°=-0.25, 160°=-0.25, 180°=-0.25
+
+### Regime Supercrítico: Re > 400.000
+
+---
+
+## Seção 6.3 — Pressão Interna (Cpi)
+
+### Casos simplificados (Tabela)
+
+| Caso de permeabilidade | Cpi |
+|------------------------|------|
+| Duas faces opostas igualmente permeáveis, outras duas impermeáveis (α=0°) | +0.2 |
+| Duas faces opostas igualmente permeáveis, outras duas impermeáveis (α=90°) | -0.3 |
+| Quatro faces igualmente permeáveis | 0.0 |
+| Permeabilidade dominante na face de barlavento | +0.1 a +0.8 (conforme razão de áreas) |
+| Permeabilidade dominante na face de sotavento/lateral | -0.3 a -0.8 |
+| Faces estanques (sem aberturas) | -0.2 ou +0.2 |
+
+### Cilindro com topo aberto
+
+| h/d | Cpi |
+|------|------|
+| h/d < 0.3 | -0.5 |
+| h/d >= 0.3 | -0.8 |
+
+### Limite normativo: Cpi ∈ [-0.9, +0.9]
+
+---
+
+## Seção 6.1.2 — Coeficiente de Arrasto (Ca) para Edificações
+
+Para edificações com faces retangulares, o Ca é determinado pela Figura 4 (baixa turbulência) ou Figura 5 (alta turbulência), em função de h/l1 e l1/l2.
+
+- h/l1 = altura / menor dimensão em planta
+- l1/l2 = menor dimensão / maior dimensão em planta
+
+### Faixas típicas de Ca (baixa turbulência):
+
+| h/l1 | l1/l2=0.4 | l1/l2=0.7 | l1/l2=1.0 |
+|-------|-----------|-----------|-----------|
+| 0.25 | ~1.1 | ~1.15 | ~1.2 |
+| 1.0 | ~1.2 | ~1.3 | ~1.4 |
+| 2.0 | ~1.3 | ~1.4 | ~1.5 |
+| 4.0 | ~1.4 | ~1.55 | ~1.65 |
+| 8.0 | ~1.5 | ~1.65 | ~1.75 |
+
+### Alta turbulência (requer: profundidade/largura > 1/3 E altura <= 2 × altura média do entorno)
+
+Ca é menor que na baixa turbulência para a mesma geometria.
+
+---
+
+## Seção 6.1.5 — Força de Atrito
+
+Aplica-se quando l0/h > 4 OU l0/b > 4.
+
+| Tipo de superfície | Cf |
+|---------------------|------|
+| Lisa (metal, vidro) | 0.01 |
+| Nervurada/ribbed (ondulações) | 0.02 |
+| Nervuras retangulares | 0.04 |
+
+---
+
+## Seção 8.1-8.2 — Barras Prismáticas (Tabela 26-27)
+
+### Barras de face plana (Tabela 26) — Ca como função de phi (solidez)
+
+| phi (φ) | Ca |
+|----------|------|
+| 0.05 | ~3.6 |
+| 0.10 | ~3.0 |
+| 0.20 | ~2.4 |
+| 0.30 | ~2.0 |
+| 0.40 | ~1.8 |
+| 0.50 | ~1.7 |
+| 0.60 | ~1.6 |
+| 0.70 | ~1.5 |
+| 0.80 | ~1.45 |
+| 0.90 | ~1.4 |
+| 1.00 | ~1.4 |
+
+### Barras circulares (Tabela 27)
+
+- Subcrítico (Re < 3×10⁵): Ca ≈ 1.2
+- Transicional: Ca ≈ 0.7
+- Supercrítico (Re > 3×10⁵): Ca ≈ 0.6
+
+---
+
+## Seção 8.5 — Torres Treliçadas (Tabela 30)
+
+- Torre de seção quadrada: Kα = 1.0 para α<=12.5°, 1.08 para α<=45°
+- Torre de seção triangular: Kα = 1.0 sempre
+- Força: F = Ca × Kα × q × A_face × φ
+
+---
+
+## Seção 11 — Pontes
+
+### Tabela 35 — Parâmetros b, p para V_it = 0.65 × V0 × S1 × b × (z/10)^p
+
+| Categoria | b | p |
+|-----------|---|------|
+| I | 1.25 | 0.10 |
+| II | 1.00 | 0.16 |
+| III | 0.85 | 0.20 |
+| IV | 0.68 | 0.25 |
+| V | 0.44 | 0.35 |
+
+### Classificação de pontes (Parâmetro Pse)
+
+| Pse | Classe | Descrição |
+|-----|--------|-----------|
+| Pse < 0.04 | 1 | Efeitos dinâmicos podem ser desprezados |
+| 0.04 <= Pse <= 1.0 | 2 | Efeitos dinâmicos devem ser avaliados |
+| Pse > 1.0 | 3 | Análise aeroelástica obrigatória |
+
+### Tabela 36 — Taxa de amortecimento ξ (%)
+
+| Material | Detalhe | ξ (%) |
+|----------|---------|-------|
+| Aço | Chapas soldadas + pavimento asfáltico | 0.8 |
+| Aço | Chapas soldadas + concreto | 1.0 |
+| Aço | Parafusadas (ligação por atrito) | 1.5 |
+| Aço | Rebitadas | 1.5 |
+| Concreto armado | — | 2.5 |
+| Concreto protendido | Protensão completa | 2.0 |
+| Concreto protendido | Protensão parcial | 2.5 |
+| Mistas aço-concreto | Vigas | 1.8 |
+| Mistas aço-concreto | Vigas treliçadas | 2.0 |
+| Alumínio | — | 2.0 |
+| Madeira | — | 8.0 |
+| Compósito | Matriz polimérica + fibras | 6.0 |
+
+---
+
+## Seção 9-10 — Dinâmica
+
+### Strouhal Number (Tabela 33)
+
+- Seção circular: St ≈ 0.20
+- Seção quadrada: St ≈ 0.11
+
+### Scruton Number
+
+Sc = 2 × m × δs / (ρ × D²)
+onde δs = amortecimento estrutural (log decrement = 2π × ξ)
+
+### Velocidade crítica de vórtices
+
+Vcr = f × D / St
+
+### Conforto humano (ISO 10137)
+
+a_lim = 0.01 × ka × f^1.124
+
+| Uso | ka |
+|-----|-----|
+| Comercial/escritórios | 6.12 |
+| Residencial | 4.06 |
+
+Faixa de frequência válida: 0.06 Hz <= f <= 1.00 Hz
+
+---
+
+## Seção 7.2 — Coberturas Isoladas (Tabelas 24-25)
+
+### Cobertura em shed (uma água)
+
+- Cpe barlavento e sotavento conforme ângulo θ
+- Força de sustentação conforme área projetada
+
+### Cobertura em duas águas (gable)
+
+- Cpe em barlavento e sotavento conforme θ
+- Força de sustentação upwards quando configurado
+
+---
+
+## Anexo A — S2 normalizado para intervalo de tempo
+
+S2(t) = S2(3s) × (t/3)^(-0.17) para t em segundos
+
+---
+
+## Anexo B — Fator estatístico S3 por probabilidade e vida útil
+
+S3 = 0.54 × (-ln(1 - Pm))^(-1/7) × m^(1/7)
+
+onde:
+- Pm = probabilidade de excedência no período de vida útil
+- m = vida útil em anos
+
+| Pm | -ln(1-Pm) |
+|----|------------|
+| 0.10 | 0.1053 |
+| 0.20 | 0.2231 |
+| 0.37 | 0.4618 |
+
+---
+
+## Anexo C — Estações meteorológicas (49 estações)
+
+Principais: São Paulo (Granjinha/Viracopos), Rio de Janeiro (Santos Dumont/Galeão), Belo Horizonte (Pampulha), Salvador, Recife, Curitiba, Porto Alegre, etc.
+
+Cada estação fornece: V0 (m/s), categoria, latitude, longitude, altitude.
+
+---
+
+## Conversões e constantes importantes
+
+| Símbolo | Valor | Descrição |
+|---------|-------|-----------|
+| ρ (rho) | 1.226 kg/m³ | Massa específica do ar |
+| 0.613 | — | Fator de conversão q = 0.613×Vk²/1000 |
+| 70.000 | — | Fator Reynolds para cilindros |
+| 0.65 | — | Fator para V_it em pontes |
+| π | 3.14159... | Pi |
+| g | 9.80665 m/s² | Aceleração gravitacional |
+`;
diff --git a/app/src/lib/audit/types.ts b/app/src/lib/audit/types.ts
new file mode 100644
index 0000000..f9d3e58
--- /dev/null
+++ b/app/src/lib/audit/types.ts
@@ -0,0 +1,138 @@
+export type LLMProvider = 'openai' | 'anthropic' | 'ollama';
+
+export type TerrainCategory = 'I' | 'II' | 'III' | 'IV' | 'V';
+export type StructureClass = 'A' | 'B' | 'C';
+
+export interface AuditConfig {
+ provider: LLMProvider;
+ model: string;
+ apiKey: string;
+ baseUrl?: string;
+}
+
+export type ModuleType =
+ | 'galpao'
+ | 'cilindro'
+ | 'vault'
+ | 'dome'
+ | 'sign'
+ | 'isolated-roof'
+ | 'bar'
+ | 'bridge'
+ | 'tower'
+ | 'dynamics'
+ | 'cross-module'
+ | 'edge-case'
+ | 'cpi-variant';
+
+export const MODULE_LABELS: Record = {
+ galpao: { 'pt-BR': 'Galpão', 'en-US': 'Warehouse' },
+ cilindro: { 'pt-BR': 'Cilindro', 'en-US': 'Cylinder' },
+ vault: { 'pt-BR': 'Abóbada', 'en-US': 'Vault' },
+ dome: { 'pt-BR': 'Cúpula', 'en-US': 'Dome' },
+ sign: { 'pt-BR': 'Muros/Placas', 'en-US': 'Signs/Walls' },
+ 'isolated-roof': { 'pt-BR': 'Cobertura Isolada', 'en-US': 'Isolated Roof' },
+ bar: { 'pt-BR': 'Barras', 'en-US': 'Bars' },
+ bridge: { 'pt-BR': 'Pontes', 'en-US': 'Bridges' },
+ tower: { 'pt-BR': 'Torres', 'en-US': 'Towers' },
+ dynamics: { 'pt-BR': 'Dinâmica', 'en-US': 'Dynamics' },
+ 'cross-module': { 'pt-BR': 'Cross-Module', 'en-US': 'Cross-Module' },
+ 'edge-case': { 'pt-BR': 'Edge Cases', 'en-US': 'Edge Cases' },
+ 'cpi-variant': { 'pt-BR': 'Cpi Variants', 'en-US': 'Cpi Variants' },
+};
+
+export type DiagramType =
+ | 'warehouse'
+ | 'cylinder'
+ | 'vault'
+ | 'dome'
+ | 'sign'
+ | 'bar'
+ | 'bridge'
+ | 'tower'
+ | 'isolatedRoof'
+ | 'dynamics';
+
+export interface ExpectedRange {
+ readonly min: number;
+ readonly max: number;
+}
+
+export interface AuditScenario {
+ readonly id: string;
+ readonly module: ModuleType;
+ readonly moduleLabel: string;
+ readonly description: string;
+ readonly inputs: Record;
+ readonly intermediates: Record;
+ readonly outputs: Record;
+ readonly expectedRanges: Record;
+ readonly diagramType: DiagramType;
+ readonly diagramProps: Record;
+ readonly nbrSection: string;
+}
+
+export type CheckStatus = 'PASS' | 'WARN' | 'FAIL';
+
+export interface AuditCheck {
+ readonly name: string;
+ readonly status: CheckStatus;
+ readonly expected: string;
+ readonly actual: string;
+ readonly explanation: string;
+}
+
+export interface ScenarioResult {
+ readonly scenarioId: string;
+ readonly verdict: CheckStatus;
+ readonly checks: readonly AuditCheck[];
+ readonly summary: string;
+ readonly llmNotes?: string;
+}
+
+export interface ModuleAuditResult {
+ readonly module: ModuleType;
+ readonly moduleLabel: string;
+ readonly totalScenarios: number;
+ readonly passed: number;
+ readonly warnings: number;
+ readonly failed: number;
+ readonly scenarios: readonly ScenarioResult[];
+}
+
+export interface AuditReport {
+ readonly id: string;
+ readonly provider: string;
+ readonly model: string;
+ readonly timestamp: number;
+ readonly totalScenarios: number;
+ readonly totalPassed: number;
+ readonly totalWarnings: number;
+ readonly totalFailed: number;
+ readonly modules: readonly ModuleAuditResult[];
+ readonly rawResponse?: string;
+}
+
+export type AuditStatus = 'idle' | 'generating' | 'calling' | 'parsing' | 'done' | 'error';
+
+export interface AuditRun {
+ readonly config: AuditConfig;
+ readonly report: AuditReport | null;
+ readonly status: AuditStatus;
+ readonly progress: number;
+ readonly error?: string;
+}
+
+export interface AuditLLMResponse {
+ readonly scenarioId: string;
+ readonly verdict: CheckStatus;
+ readonly checks: readonly {
+ readonly name: string;
+ readonly status: CheckStatus;
+ readonly expected: string;
+ readonly actual: string;
+ readonly explanation: string;
+ }[];
+ readonly summary: string;
+ readonly llmNotes?: string;
+}
diff --git a/app/src/lib/export-ftool.ts b/app/src/lib/export-ftool.ts
index 8cee587..da68b71 100644
--- a/app/src/lib/export-ftool.ts
+++ b/app/src/lib/export-ftool.ts
@@ -170,7 +170,7 @@ export function serializeFtool(model: FtoolModel): string {
const lines: string[] = [];
lines.push('; =============================================');
- lines.push('; VentoApp — Modelo Ftool');
+ lines.push('; BrainWind v1.0 — Modelo Ftool');
lines.push(`; Gerado em: ${new Date().toISOString()}`);
lines.push('; NBR 6123:2023 — Forças devidas ao vento');
lines.push('; =============================================');
diff --git a/app/src/lib/export-generic-pdf.tsx b/app/src/lib/export-generic-pdf.tsx
index 01cbd90..62a01d6 100644
--- a/app/src/lib/export-generic-pdf.tsx
+++ b/app/src/lib/export-generic-pdf.tsx
@@ -44,7 +44,7 @@ const GenericReportDocument = ({ moduleName, sections, wind, sceneImage }: Gener
- VentoApp — Memória de Cálculo
+ BrainWind v1.0 — Memória de Cálculo
Cargas de Vento: {moduleName} — NBR 6123:2023
@@ -138,7 +138,7 @@ const GenericReportDocument = ({ moduleName, sections, wind, sceneImage }: Gener
))}
- Gerado por VentoApp — Ferramenta de Auxílio ao Cálculo Estrutural (NBR 6123:2023)
+ Gerado por BrainWind v1.0 — Ferramenta de Auxílio ao Cálculo Estrutural (NBR 6123:2023)
diff --git a/app/src/lib/export-pdf.tsx b/app/src/lib/export-pdf.tsx
index ea42704..eb77a62 100644
--- a/app/src/lib/export-pdf.tsx
+++ b/app/src/lib/export-pdf.tsx
@@ -98,7 +98,7 @@ const ReportDocument = ({ galpao, wind, sceneImage }: ReportProps) => {
- VentoApp — Memória de Cálculo
+ BrainWind v1.0 — Memória de Cálculo
Cargas de Vento em Galpão — NBR 6123:2023
@@ -282,7 +282,7 @@ const ReportDocument = ({ galpao, wind, sceneImage }: ReportProps) => {
)}
- Gerado por VentoApp — Ferramenta de Auxílio ao Cálculo Estrutural (NBR 6123:2023)
+ Gerado por BrainWind v1.0 — Ferramenta de Auxílio ao Cálculo Estrutural (NBR 6123:2023)
diff --git a/app/src/lib/i18n.ts b/app/src/lib/i18n.ts
index 47d8833..5e2b9ea 100644
--- a/app/src/lib/i18n.ts
+++ b/app/src/lib/i18n.ts
@@ -43,7 +43,7 @@ type Dict = Record>;
const translations: Dict = {
// === Aplicação ===
- app_title: { 'pt-BR': 'VentoApp', 'en-US': 'VentoApp' },
+ app_title: { 'pt-BR': 'BrainWind v1.0', 'en-US': 'BrainWind v1.0' },
app_subtitle: { 'pt-BR': 'Cálculo de cargas de vento — NBR 6123:2023', 'en-US': 'Wind load calculation — NBR 6123:2023' },
app_loading: { 'pt-BR': 'Carregando...', 'en-US': 'Loading...' },