From 480effa5fc595abf9454229f0a9f95dadca02527 Mon Sep 17 00:00:00 2001 From: Paulo Massingue Date: Wed, 21 Oct 2026 12:36:08 +0200 Subject: [PATCH] separacao de sobre nos no dropdow Tempo --- .../v2/auditoria-portal/matriz-requisitos.csv | 6 +- resources/css/app.css | 409 +------------ resources/css/tempo-header.css | 321 ++++++++++ .../js/components/portal-grouped-menu.tsx | 549 ++++++++++-------- tools/portal-header-qa.mjs | 389 +++++++++++++ 5 files changed, 1023 insertions(+), 651 deletions(-) create mode 100644 resources/css/tempo-header.css create mode 100644 tools/portal-header-qa.mjs diff --git a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv index 1f2ba403..62646125 100644 --- a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv +++ b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv @@ -253,7 +253,7 @@ RNF-EDU-004,Disponibilidade — Percentagem de tempo de serviço mensal,educatio RNF-EDU-005,Escalabilidade — Consistência sob concorrência e backlog,education/nonfunctional.csv,educação,/management/education; /management/education/catalog/{kind}; /management/education/demands/{id}/analysis; /management/education/demands/{id}/investment; /management/education/{kind}; /management/education/{kind}/{id}/review,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,RNF-EDU-005: 0 duplicados em 100 reenvios concorrentes; proposta drenagem de 1000 eventos em <=15min sem dependência externa indisponível,P2,RNF-EDU-005: Limiar proposto não é resultado medido,RNF-EDU-005,1,"[{""id"":""RNF-EDU-005"",""pedido"":""Escalabilidade — Consistência sob concorrência e backlog"",""fontes"":[""education/nonfunctional.csv""],""aceitacao"":""0 duplicados em 100 reenvios concorrentes; proposta drenagem de 1000 eventos em <=15min sem dependência externa indisponível"",""estado"":""parcial"",""variantes"":""Limiar proposto não é resultado medido"",""modulo"":""educação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.labour_demands: 0 registos; public.training_capacities: 0 registos; public.education_opportunities: 0 registos; public.education_investment_proposals: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes",Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes.,Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: educação. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,educação,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/EducationController.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"EducationTest, SkillsEducationSchemaTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, RNF-EDU-006,Acessibilidade — Barreiras no percurso crítico,education/nonfunctional.csv,educação,/management/education; /management/education/catalog/{kind}; /management/education/demands/{id}/analysis; /management/education/demands/{id}/investment; /management/education/{kind}; /management/education/{kind}/{id}/review,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,RNF-EDU-006: 0 bloqueios de teclado; rótulos/erros legíveis; proposta WCAG 2.2 AA a validar com auditoria,P2,RNF-EDU-006: Limiar proposto não é resultado medido,RNF-EDU-006,1,"[{""id"":""RNF-EDU-006"",""pedido"":""Acessibilidade — Barreiras no percurso crítico"",""fontes"":[""education/nonfunctional.csv""],""aceitacao"":""0 bloqueios de teclado; rótulos/erros legíveis; proposta WCAG 2.2 AA a validar com auditoria"",""estado"":""parcial"",""variantes"":""Limiar proposto não é resultado medido"",""modulo"":""educação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.labour_demands: 0 registos; public.training_capacities: 0 registos; public.education_opportunities: 0 registos; public.education_investment_proposals: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes",Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes.,Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: educação. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,educação,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/EducationController.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"EducationTest, SkillsEducationSchemaTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, RNF-EDU-007,PT/EN — Cobertura de mensagens e estados críticos,education/nonfunctional.csv,educação,/management/education; /management/education/catalog/{kind}; /management/education/demands/{id}/analysis; /management/education/demands/{id}/investment; /management/education/{kind}; /management/education/{kind}/{id}/review,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,RNF-EDU-007: 100% fluxos críticos PT/EN; 0 chaves de tradução em bruto,P2,RNF-EDU-007: Limiar proposto não é resultado medido,RNF-EDU-007,1,"[{""id"":""RNF-EDU-007"",""pedido"":""PT/EN — Cobertura de mensagens e estados críticos"",""fontes"":[""education/nonfunctional.csv""],""aceitacao"":""100% fluxos críticos PT/EN; 0 chaves de tradução em bruto"",""estado"":""parcial"",""variantes"":""Limiar proposto não é resultado medido"",""modulo"":""educação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.labour_demands: 0 registos; public.training_capacities: 0 registos; public.education_opportunities: 0 registos; public.education_investment_proposals: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes",Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes.,Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: educação. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,educação,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/EducationController.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"EducationTest, SkillsEducationSchemaTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, -RNF-EDU-008,Responsividade — Overflow e perda de acções,education/nonfunctional.csv,educação,/management/education; /management/education/catalog/{kind}; /management/education/demands/{id}/analysis; /management/education/demands/{id}/investment; /management/education/{kind}; /management/education/{kind}/{id}/review,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,RNF-EDU-008: 0 overflow horizontal global a 360/390/768/1366px; tabelas com scroll local acessível,P2,RNF-EDU-008: Limiar proposto não é resultado medido,RNF-EDU-008,1,"[{""id"":""RNF-EDU-008"",""pedido"":""Responsividade — Overflow e perda de acções"",""fontes"":[""education/nonfunctional.csv""],""aceitacao"":""0 overflow horizontal global a 360/390/768/1366px; tabelas com scroll local acessível"",""estado"":""parcial"",""variantes"":""Limiar proposto não é resultado medido"",""modulo"":""educação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.labour_demands: 0 registos; public.training_capacities: 0 registos; public.education_opportunities: 0 registos; public.education_investment_proposals: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes",Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes.,Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: educação. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,educação,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/EducationController.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"EducationTest, SkillsEducationSchemaTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, +RNF-EDU-008,Responsividade — Overflow e perda de acções,education/nonfunctional.csv,educação,/management/education; /management/education/catalog/{kind}; /management/education/demands/{id}/analysis; /management/education/demands/{id}/investment; /management/education/{kind}; /management/education/{kind}/{id}/review,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,RNF-EDU-008: 0 overflow horizontal global a 360/390/768/1366px; tabelas com scroll local acessível,P2,RNF-EDU-008: Limiar proposto não é resultado medido,RNF-EDU-008,1,"[{""id"":""RNF-EDU-008"",""pedido"":""Responsividade — Overflow e perda de acções"",""fontes"":[""education/nonfunctional.csv""],""aceitacao"":""0 overflow horizontal global a 360/390/768/1366px; tabelas com scroll local acessível"",""estado"":""parcial"",""variantes"":""Limiar proposto não é resultado medido"",""modulo"":""educação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.labour_demands: 0 registos; public.training_capacities: 0 registos; public.education_opportunities: 0 registos; public.education_investment_proposals: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes",Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes.,Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: educação. Esforço de código adicional só após lacuna reproduzida.,"outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual. | 21/10/2026: pedido expresso da Tempo para uma única navbar, sem retirar acessos; aplicação de AGENTS.md, decisões de 12/10/2026. Agrupamento Tempo, posições, breakpoint 1280px e altura 72px são escolhas de apresentação, não novas regras operacionais. Prova local isolada do header em tools/portal-header-qa.mjs e outputs/header-navbar-20261021/qa-results.json; não encerra o critério integral nem representa implantação no activo.",educação,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/EducationController.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"EducationTest, SkillsEducationSchemaTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, RNF-EDU-009,Interoperabilidade — Validade de contratos e tipos,education/nonfunctional.csv,educação,/management/education; /management/education/catalog/{kind}; /management/education/demands/{id}/analysis; /management/education/demands/{id}/investment; /management/education/{kind}; /management/education/{kind}/{id}/review,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,"RNF-EDU-009: 100% exemplos conformes; datas ISO, UUID, moeda/país normalizados; 0 breaking changes não versionadas",P2,RNF-EDU-009: Limiar proposto não é resultado medido,RNF-EDU-009,1,"[{""id"":""RNF-EDU-009"",""pedido"":""Interoperabilidade — Validade de contratos e tipos"",""fontes"":[""education/nonfunctional.csv""],""aceitacao"":""100% exemplos conformes; datas ISO, UUID, moeda/país normalizados; 0 breaking changes não versionadas"",""estado"":""parcial"",""variantes"":""Limiar proposto não é resultado medido"",""modulo"":""educação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.labour_demands: 0 registos; public.training_capacities: 0 registos; public.education_opportunities: 0 registos; public.education_investment_proposals: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes",Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes.,Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: educação. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,educação,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/EducationController.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"EducationTest, SkillsEducationSchemaTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, RNF-EDU-010,Observabilidade — Operações correlacionadas sem segredos,education/nonfunctional.csv,educação,/management/education; /management/education/catalog/{kind}; /management/education/demands/{id}/analysis; /management/education/demands/{id}/investment; /management/education/{kind}; /management/education/{kind}/{id}/review,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,RNF-EDU-010: 100% mutações com correlation_id e actor; 0 tokens/PII nos eventos; proposta alerta em <=5min,P2,RNF-EDU-010: Limiar proposto não é resultado medido,RNF-EDU-010,1,"[{""id"":""RNF-EDU-010"",""pedido"":""Observabilidade — Operações correlacionadas sem segredos"",""fontes"":[""education/nonfunctional.csv""],""aceitacao"":""100% mutações com correlation_id e actor; 0 tokens/PII nos eventos; proposta alerta em <=5min"",""estado"":""parcial"",""variantes"":""Limiar proposto não é resultado medido"",""modulo"":""educação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.labour_demands: 0 registos; public.training_capacities: 0 registos; public.education_opportunities: 0 registos; public.education_investment_proposals: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes",Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes.,Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: educação. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,educação,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/EducationController.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"EducationTest, SkillsEducationSchemaTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, RNF-EDU-011,Backup — Cobertura e recuperabilidade,education/nonfunctional.csv,educação,/management/education; /management/education/catalog/{kind}; /management/education/demands/{id}/analysis; /management/education/demands/{id}/investment; /management/education/{kind}; /management/education/{kind}/{id}/review,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,RNF-EDU-011: Proposta backup diário cifrado; 100% recursos críticos incluídos; restauro trimestral verificado,P1,RNF-EDU-011: Limiar proposto não é resultado medido,RNF-EDU-011,1,"[{""id"":""RNF-EDU-011"",""pedido"":""Backup — Cobertura e recuperabilidade"",""fontes"":[""education/nonfunctional.csv""],""aceitacao"":""Proposta backup diário cifrado; 100% recursos críticos incluídos; restauro trimestral verificado"",""estado"":""parcial"",""variantes"":""Limiar proposto não é resultado medido"",""modulo"":""educação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.labour_demands: 0 registos; public.training_capacities: 0 registos; public.education_opportunities: 0 registos; public.education_investment_proposals: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Separar catálogo existente de procura/capacidade e painel por ator; preparar execução futura sem cadastros paralelos. Critério individual original preservado; cobertura atual ainda não individualizada.,"Cursos, necessidades/capacidades, atores, catálogo e políticas existentes",Novas jornadas não são iniciadas nesta auditoria. Dados reais/perfis/rascunho incompleto pendentes.,Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: educação. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,educação,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/EducationController.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"EducationTest, SkillsEducationSchemaTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, @@ -305,13 +305,13 @@ MASTER-9dee08d0-0006,"Cada página deve reduzir dúvidas, evitar jargão excessi MASTER-9dee08d0-0007,"Calculadora ou simulador de incentivos: permitir ao investidor estimar, de forma orientadora, possíveis impostos, benefícios fiscais e requisitos aplicáveis em função da província, do sector, da localização em ZEE ou ZFI e do volume de investimento, deixando claro que o resultado depende de validação legal e institucional.",portal do investidor\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 125 | portal do investidor\backup\Reformulacao do portal do investidor 1.docx; SHA efd550fd2a9d2a21785d7b3c140d4608f1ba27c52f156e2709e9fbf388a1a569; w:p 129 | portal do investidor\backup\Reformulacao do portal do investidor v2.docx; SHA 9f5719c8b0cf78855f727d980b77a8f9409fc7f93e303e25d355d009a07d5734; w:p 142 | portal do investidor\backup\Reformulacao do portal do investidor v3.docx; SHA 626cae3d584658842ca36b658e7b5b3cc98d87036747e65b29274f0209734e5a; w:p 146,Balcão/orientação,/balcao-virtual/contextos; /balcao-virtual/dossiers; /balcao-virtual/dossiers/{id}; /balcao-virtual/dossiers/{id}/documentos; /balcao-virtual/dossiers/{id}/documentos/{document}; /balcao-virtual/dossiers/{id}/documentos/{document}/conferencia; /balcao-virtual/dossiers/{id}/etapas; /balcao-virtual/dossiers/{id}/fontes; /balcao-virtual/dossiers/{id}/orientacao; /balcao-virtual/dossiers/{id}/pedidos; /balcao-virtual/dossiers/{id}/pressupostos; /balcao-virtual/dossiers/{id}/recomendacoes,"VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,"Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-9dee08d0-0007: Calculadora ou simulador de incentivos: permitir ao investidor estimar, de forma orientadora, possíveis impostos, benefícios fiscais e requisitos aplicáveis em função da província, do sector, da localização em ZEE ou ZFI e do volume de investimento, deixando claro que o resultado depende de validação legal e institucional. | MASTER-efd550fd-0007: Calculadora ou simulador de incentivos: permitir ao investidor estimar, de forma orientadora, possíveis impostos, benefícios fiscais e requisitos aplicáveis em função da província, do sector, da localização em ZEE ou ZFI e do volume de investimento, deixando claro que o resultado depende de validação legal e institucional. | MASTER-9f5719c8-0008: Calculadora ou simulador de incentivos: permitir ao investidor estimar, de forma orientadora, possíveis impostos, benefícios fiscais e requisitos aplicáveis em função da província, do sector, da localização em ZEE ou ZFI e do volume de investimento, deixando claro que o resultado depende de validação legal e institucional. | MASTER-626cae3d-0005: Calculadora ou simulador de incentivos: permitir ao investidor estimar, de forma orientadora, possíveis impostos, benefícios fiscais e requisitos aplicáveis em função da província, do sector, da localização em ZEE ou ZFI e do volume de investimento, deixando claro que o resultado depende de validação legal e institucional.",P2,MASTER-9dee08d0-0007: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-efd550fd-0007: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-9f5719c8-0008: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-626cae3d-0005: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-9dee08d0-0007 | MASTER-efd550fd-0007 | MASTER-9f5719c8-0008 | MASTER-626cae3d-0005,4,"[{""id"":""MASTER-9dee08d0-0007"",""pedido"":""Calculadora ou simulador de incentivos: permitir ao investidor estimar, de forma orientadora, possíveis impostos, benefícios fiscais e requisitos aplicáveis em função da província, do sector, da localização em ZEE ou ZFI e do volume de investimento, deixando claro que o resultado depende de validação legal e institucional."",""fontes"":[""portal do investidor\\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 125""],""aceitacao"":""Calculadora ou simulador de incentivos: permitir ao investidor estimar, de forma orientadora, possíveis impostos, benefícios fiscais e requisitos aplicáveis em função da província, do sector, da localização em ZEE ou ZFI e do volume de investimento, deixando claro que o resultado depende de validação legal e institucional."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""Balcão/orientação""},{""id"":""MASTER-efd550fd-0007"",""pedido"":""Calculadora ou simulador de incentivos: permitir ao investidor estimar, de forma orientadora, possíveis impostos, benefícios fiscais e requisitos aplicáveis em função da província, do sector, da localização em ZEE ou ZFI e do volume de investimento, deixando claro que o resultado depende de validação legal e institucional."",""fontes"":[""portal do investidor\\backup\\Reformulacao do portal do investidor 1.docx; SHA efd550fd2a9d2a21785d7b3c140d4608f1ba27c52f156e2709e9fbf388a1a569; w:p 129""],""aceitacao"":""Calculadora ou simulador de incentivos: permitir ao investidor estimar, de forma orientadora, possíveis impostos, benefícios fiscais e requisitos aplicáveis em função da província, do sector, da localização em ZEE ou ZFI e do volume de investimento, deixando claro que o resultado depende de validação legal e institucional."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""Balcão/orientação""},{""id"":""MASTER-9f5719c8-0008"",""pedido"":""Calculadora ou simulador de incentivos: permitir ao investidor estimar, de forma orientadora, possíveis impostos, benefícios fiscais e requisitos aplicáveis em função da província, do sector, da localização em ZEE ou ZFI e do volume de investimento, deixando claro que o resultado depende de validação legal e institucional."",""fontes"":[""portal do investidor\\backup\\Reformulacao do portal do investidor v2.docx; SHA 9f5719c8b0cf78855f727d980b77a8f9409fc7f93e303e25d355d009a07d5734; w:p 142""],""aceitacao"":""Calculadora ou simulador de incentivos: permitir ao investidor estimar, de forma orientadora, possíveis impostos, benefícios fiscais e requisitos aplicáveis em função da província, do sector, da localização em ZEE ou ZFI e do volume de investimento, deixando claro que o resultado depende de validação legal e institucional."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""Balcão/orientação""},{""id"":""MASTER-626cae3d-0005"",""pedido"":""Calculadora ou simulador de incentivos: permitir ao investidor estimar, de forma orientadora, possíveis impostos, benefícios fiscais e requisitos aplicáveis em função da província, do sector, da localização em ZEE ou ZFI e do volume de investimento, deixando claro que o resultado depende de validação legal e institucional."",""fontes"":[""portal do investidor\\backup\\Reformulacao do portal do investidor v3.docx; SHA 626cae3d584658842ca36b658e7b5b3cc98d87036747e65b29274f0209734e5a; w:p 146""],""aceitacao"":""Calculadora ou simulador de incentivos: permitir ao investidor estimar, de forma orientadora, possíveis impostos, benefícios fiscais e requisitos aplicáveis em função da província, do sector, da localização em ZEE ou ZFI e do volume de investimento, deixando claro que o resultado depende de validação legal e institucional."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""Balcão/orientação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.desk_cases: 1 registos; public.desk_requests: 0 registos; public.desk_institutional_links: 0 registos; public.desk_messages: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: balcão. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,balcão,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/VirtualDesk.php; app/Services/Ai/InvestorGuidance.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,InvestorGuidanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-9dee08d0-0008,"Suporte multilingue: disponibilizar, no mínimo, versões completas em português e inglês, com alternância visível em todas as páginas principais e tradução consistente dos formulários, guias, mensagens de erro, botões de ação e documentos de apoio essenciais. A inclusão futura de francês ou mandarim deve depender dos públicos-alvo prioritários e da capacidade de manutenção dos conteúdos.",portal do investidor\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 126,biblioteca,//; /Simulador; /api/v1/ai/documents; /api/v1/documents/recommendations; /api/v2/investment/admin/legal-sources; /api/v2/investment/admin/legal-sources/{id}/{action}; /apoio; /balcao-virtual; /balcao-virtual/dossiers/{id}/documentos/{document}/conferencia; /como-investir; /documentos; /documentos/{id},"documents, biblioteca, importação autenticada, VerifiedDocumentBinary, jobs/derivadas. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Cobrir consulta/importação/doc/derivada/hash/perfil e revogação; preservar original; divulgação separada. Não inferir relação territorial. Critério individual original preservado; cobertura atual ainda não individualizada.,Scanner/worker/GD/WebP e originais privados; ACL por oportunidade/sala diferente de partilha individual não implementada. LegadoOFF. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,"MASTER-9dee08d0-0008: Suporte multilingue: disponibilizar, no mínimo, versões completas em português e inglês, com alternância visível em todas as páginas principais e tradução consistente dos formulários, guias, mensagens de erro, botões de ação e documentos de apoio essenciais. A inclusão futura de francês ou mandarim deve depender dos públicos-alvo prioritários e da capacidade de manutenção dos conteúdos.",P2,MASTER-9dee08d0-0008: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-9dee08d0-0008,1,"[{""id"":""MASTER-9dee08d0-0008"",""pedido"":""Suporte multilingue: disponibilizar, no mínimo, versões completas em português e inglês, com alternância visível em todas as páginas principais e tradução consistente dos formulários, guias, mensagens de erro, botões de ação e documentos de apoio essenciais. A inclusão futura de francês ou mandarim deve depender dos públicos-alvo prioritários e da capacidade de manutenção dos conteúdos."",""fontes"":[""portal do investidor\\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 126""],""aceitacao"":""Suporte multilingue: disponibilizar, no mínimo, versões completas em português e inglês, com alternância visível em todas as páginas principais e tradução consistente dos formulários, guias, mensagens de erro, botões de ação e documentos de apoio essenciais. A inclusão futura de francês ou mandarim deve depender dos públicos-alvo prioritários e da capacidade de manutenção dos conteúdos."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""biblioteca""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.documents: 4 registos; public.portal_resources: 4 registos; public.portal_resource_links: 19 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Cobrir consulta/importação/doc/derivada/hash/perfil e revogação; preservar original; divulgação separada. Não inferir relação territorial. Critério individual original preservado; cobertura atual ainda não individualizada.,"documents, biblioteca, importação autenticada, VerifiedDocumentBinary, jobs/derivadas",Scanner/worker/GD/WebP e originais privados; ACL por oportunidade/sala diferente de partilha individual não implementada. LegadoOFF.,Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: documentos e legado. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,documentos e legado,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/PortalServicesController.php; app/Jobs/ScanDocumentForMalware.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"PortalServicesTest, DocumentLibrarySchemaCompatibilityTest, ImportDocumentBatchTest, ClamDScannerIntegrationTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-9dee08d0-0009,"Área Reservada ou Dashboard do Investidor: permitir ao investidor acompanhar o estado das submissões, visualizar documentos pendentes, receber notificações, agendar reuniões virtuais, consultar histórico de interacções e solicitar assistência direta junto dos serviços de facilitação do investimento.",portal do investidor\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 127 | portal do investidor\backup\Reformulacao do portal do investidor 1.docx; SHA efd550fd2a9d2a21785d7b3c140d4608f1ba27c52f156e2709e9fbf388a1a569; w:p 131 | portal do investidor\backup\Reformulacao do portal do investidor v2.docx; SHA 9f5719c8b0cf78855f727d980b77a8f9409fc7f93e303e25d355d009a07d5734; w:p 144 | portal do investidor\backup\Reformulacao do portal do investidor v3.docx; SHA 626cae3d584658842ca36b658e7b5b3cc98d87036747e65b29274f0209734e5a; w:p 148,CRM/solicitações,//; /Simulador; /api/v1/documents/recommendations; /api/v1/investment/submissions; /api/v1/investment/submissions/{id}; /api/v1/investment/submissions/{id}/attachments; /api/v1/investment/submissions/{id}/attachments/{attachment}; /api/v1/investment/submissions/{id}/submit; /apoio; /balcao-virtual; /como-investir; /documentos,"investors/contacts/leads/tasks, OpportunityContacts, acompanhamento interno existente. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,"Converter sem duplicar, tarefa/responsável/próxima ação recuperáveis; corrigir apenas falha comprovada. Critério individual original preservado; cobertura atual ainda não individualizada.",Relações mestre/contexto e autorizações; não depende de CRM externo. C131 sóQA. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,"MASTER-9dee08d0-0009: Área Reservada ou Dashboard do Investidor: permitir ao investidor acompanhar o estado das submissões, visualizar documentos pendentes, receber notificações, agendar reuniões virtuais, consultar histórico de interacções e solicitar assistência direta junto dos serviços de facilitação do investimento. | MASTER-efd550fd-0009: Área Reservada ou Dashboard do Investidor: permitir ao investidor acompanhar o estado das submissões, visualizar documentos pendentes, receber notificações, agendar reuniões virtuais, consultar histórico de interacções e solicitar assistência direta junto dos serviços de facilitação do investimento. | MASTER-9f5719c8-0010: Área Reservada ou Dashboard do Investidor: permitir ao investidor acompanhar o estado das submissões, visualizar documentos pendentes, receber notificações, agendar reuniões virtuais, consultar histórico de interacções e solicitar assistência direta junto dos serviços de facilitação do investimento. | MASTER-626cae3d-0007: Área Reservada ou Dashboard do Investidor: permitir ao investidor acompanhar o estado das submissões, visualizar documentos pendentes, receber notificações, agendar reuniões virtuais, consultar histórico de interacções e solicitar assistência direta junto dos serviços de facilitação do investimento.",P2,MASTER-9dee08d0-0009: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-efd550fd-0009: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-9f5719c8-0010: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-626cae3d-0007: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-9dee08d0-0009 | MASTER-efd550fd-0009 | MASTER-9f5719c8-0010 | MASTER-626cae3d-0007,4,"[{""id"":""MASTER-9dee08d0-0009"",""pedido"":""Área Reservada ou Dashboard do Investidor: permitir ao investidor acompanhar o estado das submissões, visualizar documentos pendentes, receber notificações, agendar reuniões virtuais, consultar histórico de interacções e solicitar assistência direta junto dos serviços de facilitação do investimento."",""fontes"":[""portal do investidor\\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 127""],""aceitacao"":""Área Reservada ou Dashboard do Investidor: permitir ao investidor acompanhar o estado das submissões, visualizar documentos pendentes, receber notificações, agendar reuniões virtuais, consultar histórico de interacções e solicitar assistência direta junto dos serviços de facilitação do investimento."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""CRM/solicitações""},{""id"":""MASTER-efd550fd-0009"",""pedido"":""Área Reservada ou Dashboard do Investidor: permitir ao investidor acompanhar o estado das submissões, visualizar documentos pendentes, receber notificações, agendar reuniões virtuais, consultar histórico de interacções e solicitar assistência direta junto dos serviços de facilitação do investimento."",""fontes"":[""portal do investidor\\backup\\Reformulacao do portal do investidor 1.docx; SHA efd550fd2a9d2a21785d7b3c140d4608f1ba27c52f156e2709e9fbf388a1a569; w:p 131""],""aceitacao"":""Área Reservada ou Dashboard do Investidor: permitir ao investidor acompanhar o estado das submissões, visualizar documentos pendentes, receber notificações, agendar reuniões virtuais, consultar histórico de interacções e solicitar assistência direta junto dos serviços de facilitação do investimento."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""CRM/solicitações""},{""id"":""MASTER-9f5719c8-0010"",""pedido"":""Área Reservada ou Dashboard do Investidor: permitir ao investidor acompanhar o estado das submissões, visualizar documentos pendentes, receber notificações, agendar reuniões virtuais, consultar histórico de interacções e solicitar assistência direta junto dos serviços de facilitação do investimento."",""fontes"":[""portal do investidor\\backup\\Reformulacao do portal do investidor v2.docx; SHA 9f5719c8b0cf78855f727d980b77a8f9409fc7f93e303e25d355d009a07d5734; w:p 144""],""aceitacao"":""Área Reservada ou Dashboard do Investidor: permitir ao investidor acompanhar o estado das submissões, visualizar documentos pendentes, receber notificações, agendar reuniões virtuais, consultar histórico de interacções e solicitar assistência direta junto dos serviços de facilitação do investimento."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""CRM/solicitações""},{""id"":""MASTER-626cae3d-0007"",""pedido"":""Área Reservada ou Dashboard do Investidor: permitir ao investidor acompanhar o estado das submissões, visualizar documentos pendentes, receber notificações, agendar reuniões virtuais, consultar histórico de interacções e solicitar assistência direta junto dos serviços de facilitação do investimento."",""fontes"":[""portal do investidor\\backup\\Reformulacao do portal do investidor v3.docx; SHA 626cae3d584658842ca36b658e7b5b3cc98d87036747e65b29274f0209734e5a; w:p 148""],""aceitacao"":""Área Reservada ou Dashboard do Investidor: permitir ao investidor acompanhar o estado das submissões, visualizar documentos pendentes, receber notificações, agendar reuniões virtuais, consultar histórico de interacções e solicitar assistência direta junto dos serviços de facilitação do investimento."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""CRM/solicitações""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.interest_requests: 4 registos; public.leads: 0 registos; public.investors: 3 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Converter sem duplicar, tarefa/responsável/próxima ação recuperáveis; corrigir apenas falha comprovada. Critério individual original preservado; cobertura atual ainda não individualizada.","investors/contacts/leads/tasks, OpportunityContacts, acompanhamento interno existente",Relações mestre/contexto e autorizações; não depende de CRM externo. C131 sóQA.,Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: acompanhamento. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,acompanhamento,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/CrmController.php; app/Services/DeclaredOriginStatistics.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"InterestSubmissionTest, InvestmentWorkspaceTest, PortalOriginCompatibilityTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, -MASTER-9dee08d0-0010,"Requisitos mínimos de acessibilidade: O portal deve garantir contraste adequado, leitura simples em dispositivos móveis, navegação por teclado, textos alternativos para imagens e ícones, rótulos claros em formulários e mensagens de erro compreensíveis. Estes requisitos são essenciais para que investidores com diferentes níveis de literacia digital consigam utilizar a plataforma sem apoio constante.",portal do investidor\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 129,biblioteca,//; /Simulador; /api/v1/ai/documents; /api/v1/documents/recommendations; /api/v2/investment/admin/legal-sources; /api/v2/investment/admin/legal-sources/{id}/{action}; /apoio; /balcao-virtual; /balcao-virtual/dossiers/{id}/documentos/{document}/conferencia; /como-investir; /documentos; /documentos/{id},"documents, biblioteca, importação autenticada, VerifiedDocumentBinary, jobs/derivadas. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Cobrir consulta/importação/doc/derivada/hash/perfil e revogação; preservar original; divulgação separada. Não inferir relação territorial. Critério individual original preservado; cobertura atual ainda não individualizada.,Scanner/worker/GD/WebP e originais privados; ACL por oportunidade/sala diferente de partilha individual não implementada. LegadoOFF. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,"MASTER-9dee08d0-0010: Requisitos mínimos de acessibilidade: O portal deve garantir contraste adequado, leitura simples em dispositivos móveis, navegação por teclado, textos alternativos para imagens e ícones, rótulos claros em formulários e mensagens de erro compreensíveis. Estes requisitos são essenciais para que investidores com diferentes níveis de literacia digital consigam utilizar a plataforma sem apoio constante.",P2,MASTER-9dee08d0-0010: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-9dee08d0-0010,1,"[{""id"":""MASTER-9dee08d0-0010"",""pedido"":""Requisitos mínimos de acessibilidade: O portal deve garantir contraste adequado, leitura simples em dispositivos móveis, navegação por teclado, textos alternativos para imagens e ícones, rótulos claros em formulários e mensagens de erro compreensíveis. Estes requisitos são essenciais para que investidores com diferentes níveis de literacia digital consigam utilizar a plataforma sem apoio constante."",""fontes"":[""portal do investidor\\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 129""],""aceitacao"":""Requisitos mínimos de acessibilidade: O portal deve garantir contraste adequado, leitura simples em dispositivos móveis, navegação por teclado, textos alternativos para imagens e ícones, rótulos claros em formulários e mensagens de erro compreensíveis. Estes requisitos são essenciais para que investidores com diferentes níveis de literacia digital consigam utilizar a plataforma sem apoio constante."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""biblioteca""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.documents: 4 registos; public.portal_resources: 4 registos; public.portal_resource_links: 19 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Cobrir consulta/importação/doc/derivada/hash/perfil e revogação; preservar original; divulgação separada. Não inferir relação territorial. Critério individual original preservado; cobertura atual ainda não individualizada.,"documents, biblioteca, importação autenticada, VerifiedDocumentBinary, jobs/derivadas",Scanner/worker/GD/WebP e originais privados; ACL por oportunidade/sala diferente de partilha individual não implementada. LegadoOFF.,Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: documentos e legado. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,documentos e legado,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/PortalServicesController.php; app/Jobs/ScanDocumentForMalware.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"PortalServicesTest, DocumentLibrarySchemaCompatibilityTest, ImportDocumentBatchTest, ClamDScannerIntegrationTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, +MASTER-9dee08d0-0010,"Requisitos mínimos de acessibilidade: O portal deve garantir contraste adequado, leitura simples em dispositivos móveis, navegação por teclado, textos alternativos para imagens e ícones, rótulos claros em formulários e mensagens de erro compreensíveis. Estes requisitos são essenciais para que investidores com diferentes níveis de literacia digital consigam utilizar a plataforma sem apoio constante.",portal do investidor\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 129,biblioteca,//; /Simulador; /api/v1/ai/documents; /api/v1/documents/recommendations; /api/v2/investment/admin/legal-sources; /api/v2/investment/admin/legal-sources/{id}/{action}; /apoio; /balcao-virtual; /balcao-virtual/dossiers/{id}/documentos/{document}/conferencia; /como-investir; /documentos; /documentos/{id},"documents, biblioteca, importação autenticada, VerifiedDocumentBinary, jobs/derivadas. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Cobrir consulta/importação/doc/derivada/hash/perfil e revogação; preservar original; divulgação separada. Não inferir relação territorial. Critério individual original preservado; cobertura atual ainda não individualizada.,Scanner/worker/GD/WebP e originais privados; ACL por oportunidade/sala diferente de partilha individual não implementada. LegadoOFF. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,"MASTER-9dee08d0-0010: Requisitos mínimos de acessibilidade: O portal deve garantir contraste adequado, leitura simples em dispositivos móveis, navegação por teclado, textos alternativos para imagens e ícones, rótulos claros em formulários e mensagens de erro compreensíveis. Estes requisitos são essenciais para que investidores com diferentes níveis de literacia digital consigam utilizar a plataforma sem apoio constante.",P2,MASTER-9dee08d0-0010: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-9dee08d0-0010,1,"[{""id"":""MASTER-9dee08d0-0010"",""pedido"":""Requisitos mínimos de acessibilidade: O portal deve garantir contraste adequado, leitura simples em dispositivos móveis, navegação por teclado, textos alternativos para imagens e ícones, rótulos claros em formulários e mensagens de erro compreensíveis. Estes requisitos são essenciais para que investidores com diferentes níveis de literacia digital consigam utilizar a plataforma sem apoio constante."",""fontes"":[""portal do investidor\\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 129""],""aceitacao"":""Requisitos mínimos de acessibilidade: O portal deve garantir contraste adequado, leitura simples em dispositivos móveis, navegação por teclado, textos alternativos para imagens e ícones, rótulos claros em formulários e mensagens de erro compreensíveis. Estes requisitos são essenciais para que investidores com diferentes níveis de literacia digital consigam utilizar a plataforma sem apoio constante."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""biblioteca""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.documents: 4 registos; public.portal_resources: 4 registos; public.portal_resource_links: 19 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Cobrir consulta/importação/doc/derivada/hash/perfil e revogação; preservar original; divulgação separada. Não inferir relação territorial. Critério individual original preservado; cobertura atual ainda não individualizada.,"documents, biblioteca, importação autenticada, VerifiedDocumentBinary, jobs/derivadas",Scanner/worker/GD/WebP e originais privados; ACL por oportunidade/sala diferente de partilha individual não implementada. LegadoOFF.,Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: documentos e legado. Esforço de código adicional só após lacuna reproduzida.,"outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual. | 21/10/2026: pedido expresso da Tempo para uma única navbar, sem retirar acessos; aplicação de AGENTS.md, decisões de 12/10/2026. Agrupamento Tempo, posições, breakpoint 1280px e altura 72px são escolhas de apresentação, não novas regras operacionais. Prova local isolada do header em tools/portal-header-qa.mjs e outputs/header-navbar-20261021/qa-results.json; não encerra o critério integral nem representa implantação no activo.",documentos e legado,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Http/Controllers/PortalServicesController.php; app/Jobs/ScanDocumentForMalware.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"PortalServicesTest, DocumentLibrarySchemaCompatibilityTest, ImportDocumentBatchTest, ClamDScannerIntegrationTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-9dee08d0-0011,A navegação deve reflectir o ciclo de vida do investidor:,portal do investidor\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 134 | portal do investidor\backup\Reformulacao do portal do investidor 1.docx; SHA efd550fd2a9d2a21785d7b3c140d4608f1ba27c52f156e2709e9fbf388a1a569; w:p 135 | portal do investidor\backup\Reformulacao do portal do investidor v2.docx; SHA 9f5719c8b0cf78855f727d980b77a8f9409fc7f93e303e25d355d009a07d5734; w:p 148 | portal do investidor\backup\Reformulacao do portal do investidor v3.docx; SHA 626cae3d584658842ca36b658e7b5b3cc98d87036747e65b29274f0209734e5a; w:p 152,governação/outros,/api/v1/investment/admin/interests/{interest}/status; /management/history; /management/interests; /management/interests/{interest}; /management/interests/{interest}/consent/contact; /management/interests/{interest}/consent/proponent; /management/opportunities; /management/opportunities/create; /management/opportunities/drafts; /management/opportunities/{id}/draft; /management/opportunities/{id}/edit; /management/opportunities/{id}/lifecycle,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.",MASTER-9dee08d0-0011: A navegação deve reflectir o ciclo de vida do investidor: | MASTER-efd550fd-0011: A navegação deve reflectir o ciclo de vida do investidor: | MASTER-9f5719c8-0012: A navegação deve reflectir o ciclo de vida do investidor: | MASTER-626cae3d-0009: A navegação deve reflectir o ciclo de vida do investidor:,P2,MASTER-9dee08d0-0011: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-efd550fd-0011: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-9f5719c8-0012: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-626cae3d-0009: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-9dee08d0-0011 | MASTER-efd550fd-0011 | MASTER-9f5719c8-0012 | MASTER-626cae3d-0009,4,"[{""id"":""MASTER-9dee08d0-0011"",""pedido"":""A navegação deve reflectir o ciclo de vida do investidor:"",""fontes"":[""portal do investidor\\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 134""],""aceitacao"":""A navegação deve reflectir o ciclo de vida do investidor:"",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-efd550fd-0011"",""pedido"":""A navegação deve reflectir o ciclo de vida do investidor:"",""fontes"":[""portal do investidor\\backup\\Reformulacao do portal do investidor 1.docx; SHA efd550fd2a9d2a21785d7b3c140d4608f1ba27c52f156e2709e9fbf388a1a569; w:p 135""],""aceitacao"":""A navegação deve reflectir o ciclo de vida do investidor:"",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-9f5719c8-0012"",""pedido"":""A navegação deve reflectir o ciclo de vida do investidor:"",""fontes"":[""portal do investidor\\backup\\Reformulacao do portal do investidor v2.docx; SHA 9f5719c8b0cf78855f727d980b77a8f9409fc7f93e303e25d355d009a07d5734; w:p 148""],""aceitacao"":""A navegação deve reflectir o ciclo de vida do investidor:"",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-626cae3d-0009"",""pedido"":""A navegação deve reflectir o ciclo de vida do investidor:"",""fontes"":[""portal do investidor\\backup\\Reformulacao do portal do investidor v3.docx; SHA 626cae3d584658842ca36b658e7b5b3cc98d87036747e65b29274f0209734e5a; w:p 152""],""aceitacao"":""A navegação deve reflectir o ciclo de vida do investidor:"",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,Requisito transversal; consultar estado-ativo-after.json,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global. [RECONCILIACAO-43-20261019] 3: Fluxos instalados; fechar observação com dossier legítimo quando disponível. Não reconstruir nem repetir percurso aceite.","Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada. | NAVEGACAO-QA-20261016: avaliação visual do protótipo pendente. Sem encerramento funcional global: vínculo genérico oportunidade/território, troca persistente e invalidação transversal, resumo integral de oportunidade/etapa e página Porquê investir por consolidar. Prévia não grava alterações de negócio. Manual aguarda avaliação e consolidação. | NAVEGACAO-CONSOLIDACAO-QA-20261016: os limites de persistência/entre dispositivos/Porquê investir do protótipo ficam superados neste recorte QA. A organização foi avaliada e ajustada tecnicamente; decisão visual e disponibilização pela Tempo continuam separadas. Não é prova volumétrica nem homologação fiscal/regulatória. Não encerra outros critérios deste requisito. Não repete os testes de navegação já aceites. | Cinco pontos do pedido consolidados neste recorte QA; confirmar da candidata funcional persiste, protótipo18534 fica histórico. Avaliação técnica visual executada, aceitação pela Tempo não presumida. Sem ativação. Não encerra outros critérios dos requisitos. Dois clientes simulados por sessões independentes, não dois equipamentos físicos. | RECTIFICAÇÃO: a revisão dos quatro formulários é parcial3/4. Preparar manifestação de interesse não mostra pré-preenchimento no percurso actual: manifestação não vinculada ao dossier. Presença de chaves na API/resumo global não encerra este critério. Resolver vínculo explícito/recuperável ao mesmo dossier e demonstrar o quarto formulário antes da decisão. Utilizador não abriu candidata nem conferiu novos anexos. | Actualização do critério anteriormente aberto da manifestação: concluído neste recorte QA; três formulários aceites conservam provas anteriores, sem repetição. Acesso directo sem dossier mantido; nenhum dossier/processo duplicado criado. Não encerra critérios globais nem presume conferência dos anexos pelo utilizador. Disponibilização separada. [UTILIZACAO-HOMOLOGACAO-20261019] 3: Disponibilidade condicionada conforme limite registado — Início, contexto e navegação abrem; gravação/recuperação aceites em QA reutilizadas. Sem dossier real no destino.","Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer","Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites. | NAVEGACAO-QA-20261016: reutiliza cinco fases/19 etapas, permissões e dossiers existentes; base anterior dos parques130000, sem incorporar L1 pendente. Confirmação futura do escopo funcional e autorização ativa separadas; zero migrations/grants/publicação/alterações no ativo. L1, duplicados e Fintech mantêm estados. | NAVEGACAO-CONSOLIDACAO-QA-20261016: ação autenticada nominal 150000 preparada e demonstrada somente no clone55441 *_test; uma tabela de preferência por conta, associações no dossier existente. Manifesto/compilação e reversão parcial compatível preservam dados após utilização. Backup/restauro fresco do ativo e autorização de ativação continuam futuros. B, COUNTRY02, L1 dos parques, duplicados, regulação Fintech e demais estados preservados; origem das restrições: instrução expressa da Tempo e controlos de acesso aprovados, sem novos grants. | Candidata reconciliada com fonte L1 instalada, sem repetir140000; nenhuma alteração ativa.150000 permanece somenteQA. Pacotes/reversão anteriores não usar directamente no ativo actualizado: futura disponibilização requer decisão própria, hashes/preflight/backup-restauro fresco e reversão reconciliada. Sem nova regra organizacional; B/COUNTRY02/ficha integral e demais estados preservados. | Disponibilização parcial: apenas150000 pendente. Prévia confirma investemoz:5432/revisão correta; aplicação exige MFA nesta sessão e botão desativado. Sem POST/DDL150000; utilizador deve concluir autenticação habitual, sem nova autorização.140000/L1 preservada e sem reensaios. Reversão reconciliada comL1,20fontes/buildcompatível, dados/schema/histórico retidos. | Pendência MFA/instalação anterior resolvida; nenhuma ação restante para disponibilizar este recorte.140000 preservada uma vez; sem repetir L1 ou três formulários aceites. Reversão parcial compatível20fontes/build, schema/vínculos/histórico conservados. Critérios globais e ficha integral dos parques mantêm estado próprio.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: governação e demais cláusulas. Esforço de código adicional só após lacuna reproduzida.,"outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual. | NAVEGACAO-QA-20261016: protótipo de organização em clone isolado, mapa52 ligações condicionais e vistas do catálogo; Descoberta/Realização/Suporte; área de trabalho separada; quatro entradas no mesmo UUID/v3, preenchimento autorizado preservando edição, cancelamento/confirmação apenas da prévia, novo login, teclado e móvel390. Evidência em outputs/investmoz-navegacao-QA-20261016/RELATORIO-QA.md. Origem: instrução expressa da Tempo nesta conversa; não é nova regra organizacional. | NAVEGACAO-CONSOLIDACAO-QA-20261016: substitui o saldo funcional da prévia histórica. Associações versionadas de oportunidade/sector/território no mesmo dossier encriptado; confirmação transacional com prévia e idempotência; foco/etapa recuperados entre sessões independentes; preservação de edições e preenchimento de vazios em formulários existentes; página Porquê investir dedicada. Prova positiva com cálculos locais reais (40 unidades; lacuna de financiamento 13000 MZN), duas submissões sintéticas reais pelo Balcão e recibo inalterado após troca. Resultados afetados conservados como históricos; rascunho anterior exige revisão explícita. Relatório: outputs/investmoz-navegacao-consolidacao-QA-20261016/RELATORIO-QA.md. | 18/10/2026: consolidação QA posterior ao protótipo revista; três menus com explicação/destinos, página Porquê investir dedicada melhorada, captura desktop/móvel390px e Escape/foco. Associações e contexto recuperados em duas sessões independentes autenticadas/MFA; quatro consumidores,19etapas, resultados para revisão e pedidos históricos recuperados. Provas transacionais40condições de16/10 reutilizadas. Relatório/pacote: outputs/investmoz-navegacao-consolidacao-20261018/para-revisao/. | Revisão visível18/10: candidata b1c98ec7140c, quatro entradas no mesmoUUID/próxima acção; prévia mantém/actualiza/revisão3resultados e9etapas, confirmação contexto3→4 e recuperação após logout/login/MFA observadas. Simulador, Terra/DUAT e Balcão mostram pré-preenchimento/comparação preservando edições. Relatório REVISAO-VISIVEL-DOC01.md e recibo em outputs/investmoz-navegacao-consolidacao-20261018/para-revisao/. | 18/10: integração da manifestação QA 73f8bd1347ca observada: vínculo opcional explícito no dossier existente, objectivo/localização preenchidos e sector editado preservado, recuperação em nova sessão/MFA, uma submissão e recibo IR-2026-01M576QMSKV91Q53GZCHKM61P0; dois reenvios com o mesmo protocolo.18 checksHTTP e15 de leitura;28 outros dossiers iguais. RELATORIO-MANIFESTACAO-QA.md na mesma entrega. | 18/10: Tempo autorizou disponibilização da candidata73f8bd1347ca. Código40fontes/build167 trocados por hash, manutenção terminada, cache de dados preservada. Backup fresco/restauro QA:295tabelas,31sequências,1320ficheiros, arranque/decifragem conferidos. Relatório operacional em outputs/investmoz-navegacao-ativacao-20261018/para-revisao/. | 18/10: disponibilização concluída73f8bd1347ca. MFA regularizado e150000 instalada pela conta2, reciboda1cae7b-a403-4256-9fd8-98ff2a69918d. Ledger/tabela=1, zero preferências importadas. Prévia e sucesso observados; Codex não repetiuPOST.290tabelas iguais ao backup e zero diferenças inesperadas. Relatório/recibo finais na mesma entrega. | Homologação teste-investidor 19/10/2026: Navegação contextual e manifestação de interesse=Ausente. Saldo derivado e limites em outputs/investmoz-disponibilizacao-integral-20261019/SALDO-E-ACTUALIZACAO-CONSOLIDADA.md. Não substitui estado/provas do activo; trecho documental encerrado, vínculo dossier aberto. | Proposta integral fdcb31f1b5b9: aplicação activa local completa + R2/DOC01/destino reconciliados; schema/build/recuperação de contexto e reversão de apresentação ensaiados no clone isolado. Não instalado remotamente. Inc. QA territoriais/Inhambane/programas separados. Limites e decisões em outputs/investmoz-disponibilizacao-integral-20261019/PROPOSTA-INTEGRAL-PARA-DECISAO.md. | Execução autorizada fdcb31f1b5b9 concluída em teste-investidor: Navegação contextual e manifestação de interesse=Disponível. 1080 hashes iguais, schema171/88, custódia/scan/recuperação reais. Sem publicação ou papéis novos. Vínculo dossier legítimo pendente; incrementos QA separados. Limites em outputs/investmoz-disponibilizacao-integral-20261019/RESULTADO-DISPONIBILIZACAO-INTEGRAL.md; não encerra critérios globais não demonstrados. [UTILIZACAO-HOMOLOGACAO-20261019] Leitura nominal de contas/recursos no destino; saldo18/10; prévia29 sem escrita; comparação de hashes QA separados. outputs/investmoz-disponibilizacao-integral-20261019/UTILIZACAO-EFECTIVA-HOMOLOGACAO.md [RECONCILIACAO-43-20261019] Código e critérios confrontados com leitura READ ONLY fresca; PROVA-RECONCILIACAO-43-LEITURA.json, RECONCILIACAO-43-QA-FONTES.json, RECONCILIACAO-43-SCHEMA-QA.json. Não encerra critério funcional por inventário. -[PLANO-P1-P6-20261019] Plano Tempo: 27–46 h disponibilização; P7 e desenvolvimento separados. Inclusão 36–39 expressa para decisão; sem publicação automática. Revisão de proposta d87970e701f0. Roteiro no manual existente; não encerra critério por instalação.",governação e demais cláusulas,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",AGENTS.md — componentes do domínio encontrados; correspondência integral deste requisito não presumida,; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,," | Revisão visível sóQA; edição de Terra/Balcão em memória, sem submissão. Comparação de cliques estrutural documentada, sem ganho global/telemetria presumidos. Código exacto SHA256b1c98ec7140c2753a40d22b6b4f235ab7c4f7c5a43d322d55ba6c84a53a169d6. L1 encerrado no âmbito entregue, não reensaiado; ativo inalterado. | Cliques comparativos continuam estruturais. Nesta associação observados uma escolha no select + uma activação; submissão uma activação; sem total desde início/tempo/ganho global. Dois reenviosHTTP não contam como cliques.998 ficheiros ativos iguais; sem schema novo, sem repetir140000/L1; ficha integral aberta. | Não confundir código disponibilizado com instalação integral concluída. Nenhuma ficha guardada/publicada, fixture/grant ou submissão ativa.292tabelas iguais; só cache/sessões/remember_token variaram, zero diferenças inesperadas. Provas QA anteriores reutilizadas; conferência dos novos anexos pelo utilizador não presumida; ficha integral aberta. | Instalação nominal e conferência operacional por leitura; zero fichas guardadas/publicadas, fixtures/grants ou manifestações submetidas no ativo. Provas funcionais são as QA anteriores, não novo ensaio ativo. Autorização da Tempo não presume conferência dos novos anexos pelo utilizador; cliques estruturais não viram telemetria.","0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, +[PLANO-P1-P6-20261019] Plano Tempo: 27–46 h disponibilização; P7 e desenvolvimento separados. Inclusão 36–39 expressa para decisão; sem publicação automática. Revisão de proposta d87970e701f0. Roteiro no manual existente; não encerra critério por instalação. | 21/10/2026: pedido expresso da Tempo para uma única navbar, sem retirar acessos; aplicação de AGENTS.md, decisões de 12/10/2026. Agrupamento Tempo, posições, breakpoint 1280px e altura 72px são escolhas de apresentação, não novas regras operacionais. Prova local isolada do header em tools/portal-header-qa.mjs e outputs/header-navbar-20261021/qa-results.json; não encerra o critério integral nem representa implantação no activo.",governação e demais cláusulas,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",AGENTS.md — componentes do domínio encontrados; correspondência integral deste requisito não presumida,; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,," | Revisão visível sóQA; edição de Terra/Balcão em memória, sem submissão. Comparação de cliques estrutural documentada, sem ganho global/telemetria presumidos. Código exacto SHA256b1c98ec7140c2753a40d22b6b4f235ab7c4f7c5a43d322d55ba6c84a53a169d6. L1 encerrado no âmbito entregue, não reensaiado; ativo inalterado. | Cliques comparativos continuam estruturais. Nesta associação observados uma escolha no select + uma activação; submissão uma activação; sem total desde início/tempo/ganho global. Dois reenviosHTTP não contam como cliques.998 ficheiros ativos iguais; sem schema novo, sem repetir140000/L1; ficha integral aberta. | Não confundir código disponibilizado com instalação integral concluída. Nenhuma ficha guardada/publicada, fixture/grant ou submissão ativa.292tabelas iguais; só cache/sessões/remember_token variaram, zero diferenças inesperadas. Provas QA anteriores reutilizadas; conferência dos novos anexos pelo utilizador não presumida; ficha integral aberta. | Instalação nominal e conferência operacional por leitura; zero fichas guardadas/publicadas, fixtures/grants ou manifestações submetidas no ativo. Provas funcionais são as QA anteriores, não novo ensaio ativo. Autorização da Tempo não presume conferência dos novos anexos pelo utilizador; cliques estruturais não viram telemetria.","0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-9dee08d0-0012,"Carteira PII 2026-2030: cada sector deve apresentar oportunidades associadas ao PII 2026-2030, com indicação de localização, entidade promotora, fase de preparação, necessidades de financiamento, impacto económico esperado e documentos de referência disponíveis.",portal do investidor\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 150,oportunidades,/api/v1/business-opportunities; /api/v1/business-opportunities/{slug}; /investidor/terra-duat; /investidor/terra-duat/novo; /investidor/terra-duat/{id}; /investidor/terra-duat/{id}/actualizacoes; /investidor/terra-duat/{id}/documentos; /investidor/terra-duat/{id}/documentos/{attachment}; /investidor/terra-duat/{id}/editar; /investidor/terra-duat/{id}/imprimir; /investidor/terra-duat/{id}/solicitar-apoio; /management/opportunities,"OpportunityManagement, OpportunityCanonicalContract/Response, OpportunityReviewMateriality, PortalProfileAccess, OpportunityResources. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Reconciliar contrato/cláusula e provas por categoria; completar apenas falha/variante executável identificada. Response normativo não é completo. Critério individual original preservado; cobertura atual ainda não individualizada.,"030000→040000 já instalados; contratos/resources existentes, sessão/MFA, ClamD e worker para ficheiros; gates das seis categorias ON. Variantes modulares/offers continuam separadas. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-9dee08d0-0012: Carteira PII 2026-2030: cada sector deve apresentar oportunidades associadas ao PII 2026-2030, com indicação de localização, entidade promotora, fase de preparação, necessidades de financiamento, impacto económico esperado e documentos de referência disponíveis.",P2,MASTER-9dee08d0-0012: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-9dee08d0-0012,1,"[{""id"":""MASTER-9dee08d0-0012"",""pedido"":""Carteira PII 2026-2030: cada sector deve apresentar oportunidades associadas ao PII 2026-2030, com indicação de localização, entidade promotora, fase de preparação, necessidades de financiamento, impacto económico esperado e documentos de referência disponíveis."",""fontes"":[""portal do investidor\\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 150""],""aceitacao"":""Carteira PII 2026-2030: cada sector deve apresentar oportunidades associadas ao PII 2026-2030, com indicação de localização, entidade promotora, fase de preparação, necessidades de financiamento, impacto económico esperado e documentos de referência disponíveis."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""oportunidades""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.opportunities: 6 registos; public.opportunity_images: tabela ausente; public.opportunity_documents: tabela ausente; public.opportunity_location_drafts: tabela ausente,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Reconciliar contrato/cláusula e provas por categoria; completar apenas falha/variante executável identificada. Response normativo não é completo. Critério individual original preservado; cobertura atual ainda não individualizada.,"OpportunityManagement, OpportunityCanonicalContract/Response, OpportunityReviewMateriality, PortalProfileAccess, OpportunityResources","030000→040000 já instalados; contratos/resources existentes, sessão/MFA, ClamD e worker para ficheiros; gates das seis categorias ON. Variantes modulares/offers continuam separadas.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: oportunidades. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,oportunidades,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/OpportunityManagement.php; app/Services/OpportunityResources.php; resources/js/pages/management/opportunity-draft.tsx — componentes do domínio encontrados; correspondência integral deste requisito não presumida,"OpportunityManagementTest, OpportunityResourcesTest, OpportunityOriginReviewTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.",Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-9dee08d0-0013,"Para transformar o portal num balcão único interoperável, as integrações de sistema devem ser tratadas como uma ambição funcional dependente de acordos institucionais, disponibilidade técnica das entidades públicas e validação jurídica dos fluxos de dados.",portal do investidor\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 161,Balcão/orientação,/balcao-virtual/contextos; /balcao-virtual/dossiers; /balcao-virtual/dossiers/{id}; /balcao-virtual/dossiers/{id}/documentos; /balcao-virtual/dossiers/{id}/documentos/{document}; /balcao-virtual/dossiers/{id}/documentos/{document}/conferencia; /balcao-virtual/dossiers/{id}/etapas; /balcao-virtual/dossiers/{id}/fontes; /balcao-virtual/dossiers/{id}/orientacao; /balcao-virtual/dossiers/{id}/pedidos; /balcao-virtual/dossiers/{id}/pressupostos; /balcao-virtual/dossiers/{id}/recomendacoes,"VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,"Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.","MASTER-9dee08d0-0013: Para transformar o portal num balcão único interoperável, as integrações de sistema devem ser tratadas como uma ambição funcional dependente de acordos institucionais, disponibilidade técnica das entidades públicas e validação jurídica dos fluxos de dados.",P2,MASTER-9dee08d0-0013: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-9dee08d0-0013,1,"[{""id"":""MASTER-9dee08d0-0013"",""pedido"":""Para transformar o portal num balcão único interoperável, as integrações de sistema devem ser tratadas como uma ambição funcional dependente de acordos institucionais, disponibilidade técnica das entidades públicas e validação jurídica dos fluxos de dados."",""fontes"":[""portal do investidor\\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 161""],""aceitacao"":""Para transformar o portal num balcão único interoperável, as integrações de sistema devem ser tratadas como uma ambição funcional dependente de acordos institucionais, disponibilidade técnica das entidades públicas e validação jurídica dos fluxos de dados."",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""Balcão/orientação""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,public.desk_cases: 1 registos; public.desk_requests: 0 registos; public.desk_institutional_links: 0 registos; public.desk_messages: 0 registos,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.","Pedido contextual→gravar→submeter→nova sessão→gestor→mensagem/documentos/resultado, reaproveitando A/B. Critério individual original preservado; cobertura atual ainda não individualizada.","VirtualDesk, pedidos/casos, anexos, contexto dossier e acompanhamento","Perfis próprios do Balcão; serviços/campos e decisões externas aplicáveis, sem inventar destinatário/prazo.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: balcão. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,balcão,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",app/Services/VirtualDesk.php; app/Services/Ai/InvestorGuidance.php — componentes do domínio encontrados; correspondência integral deste requisito não presumida,InvestorGuidanceTest; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, MASTER-9dee08d0-0014,O conteúdo e os fluxos de trabalho do portal devem refletir rigorosamente o quadro legal vigente em Moçambique:,portal do investidor\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 186 | portal do investidor\backup\Reformulacao do portal do investidor 1.docx; SHA efd550fd2a9d2a21785d7b3c140d4608f1ba27c52f156e2709e9fbf388a1a569; w:p 177 | portal do investidor\backup\Reformulacao do portal do investidor v2.docx; SHA 9f5719c8b0cf78855f727d980b77a8f9409fc7f93e303e25d355d009a07d5734; w:p 190 | portal do investidor\backup\Reformulacao do portal do investidor v3.docx; SHA 626cae3d584658842ca36b658e7b5b3cc98d87036747e65b29274f0209734e5a; w:p 194,governação/outros,/api/v1/investment/admin/interests/{interest}/status; /management/history; /management/interests; /management/interests/{interest}; /management/interests/{interest}/consent/contact; /management/interests/{interest}/consent/proponent; /management/opportunities; /management/opportunities/create; /management/opportunities/drafts; /management/opportunities/{id}/draft; /management/opportunities/{id}/edit; /management/opportunities/{id}/lifecycle,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,Sem evidência suficiente,Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.",MASTER-9dee08d0-0014: O conteúdo e os fluxos de trabalho do portal devem refletir rigorosamente o quadro legal vigente em Moçambique: | MASTER-efd550fd-0014: O conteúdo e os fluxos de trabalho do portal devem refletir rigorosamente o quadro legal vigente em Moçambique: | MASTER-9f5719c8-0015: O conteúdo e os fluxos de trabalho do portal devem refletir rigorosamente o quadro legal vigente em Moçambique: | MASTER-626cae3d-0012: O conteúdo e os fluxos de trabalho do portal devem refletir rigorosamente o quadro legal vigente em Moçambique:,P2,MASTER-9dee08d0-0014: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-efd550fd-0014: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-9f5719c8-0015: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas | MASTER-626cae3d-0012: Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas,MASTER-9dee08d0-0014 | MASTER-efd550fd-0014 | MASTER-9f5719c8-0015 | MASTER-626cae3d-0012,4,"[{""id"":""MASTER-9dee08d0-0014"",""pedido"":""O conteúdo e os fluxos de trabalho do portal devem refletir rigorosamente o quadro legal vigente em Moçambique:"",""fontes"":[""portal do investidor\\Reformulacao do portal do investidor.docx; SHA 9dee08d0ebbbb262651a01ffc7e0ade97323664bda59fe8ce0b07ead82736ce1; w:p 186""],""aceitacao"":""O conteúdo e os fluxos de trabalho do portal devem refletir rigorosamente o quadro legal vigente em Moçambique:"",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-efd550fd-0014"",""pedido"":""O conteúdo e os fluxos de trabalho do portal devem refletir rigorosamente o quadro legal vigente em Moçambique:"",""fontes"":[""portal do investidor\\backup\\Reformulacao do portal do investidor 1.docx; SHA efd550fd2a9d2a21785d7b3c140d4608f1ba27c52f156e2709e9fbf388a1a569; w:p 177""],""aceitacao"":""O conteúdo e os fluxos de trabalho do portal devem refletir rigorosamente o quadro legal vigente em Moçambique:"",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-9f5719c8-0015"",""pedido"":""O conteúdo e os fluxos de trabalho do portal devem refletir rigorosamente o quadro legal vigente em Moçambique:"",""fontes"":[""portal do investidor\\backup\\Reformulacao do portal do investidor v2.docx; SHA 9f5719c8b0cf78855f727d980b77a8f9409fc7f93e303e25d355d009a07d5734; w:p 190""],""aceitacao"":""O conteúdo e os fluxos de trabalho do portal devem refletir rigorosamente o quadro legal vigente em Moçambique:"",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""},{""id"":""MASTER-626cae3d-0012"",""pedido"":""O conteúdo e os fluxos de trabalho do portal devem refletir rigorosamente o quadro legal vigente em Moçambique:"",""fontes"":[""portal do investidor\\backup\\Reformulacao do portal do investidor v3.docx; SHA 626cae3d584658842ca36b658e7b5b3cc98d87036747e65b29274f0209734e5a; w:p 194""],""aceitacao"":""O conteúdo e os fluxos de trabalho do portal devem refletir rigorosamente o quadro legal vigente em Moçambique:"",""estado"":""parcial"",""variantes"":""Todas as ocorrências exatas preservadas nas fontes; variantes de texto têm linhas distintas"",""modulo"":""governação/outros""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,parcial,Requisito transversal; consultar estado-ativo-after.json,"A evidência existente é do domínio ou uma declaração histórica; não identifica a demonstração integral desta cláusula. Não afirmar implementado/parcial apenas por componente, menu ou teste global.",Localizar obrigação verificável e consumidores/contrato atuais antes de estimar implementação ou declarar conclusão. Critério individual original preservado; cobertura atual ainda não individualizada.,"Entidades, schema/configuração e serviços existentes; correspondência individual por estabelecer","Ler secção/versão correspondente; distinguir requisito funcional, decisão e exemplo. Fontes oficiais já aceites.",Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,Reconciliação e prova individual antes de estimar alteração,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: governação e demais cláusulas. Esforço de código adicional só após lacuna reproduzida.,outputs/investmoz-audit-current-20261012/runtime-active.json; runtime-qa18445.json. Inventário/GET do domínio não demonstra esta cláusula individual.,governação e demais cláusulas,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Verificar individualmente este critério no contrato e percurso aplicável; a matriz inicial conserva texto/fonte sem o promover a aceitação.,"QA de UI quando browser disponível; reutilizar o domínio existente. Dados/decisões específicos no backlog, sem segunda validação de fonte oficial.",AGENTS.md — componentes do domínio encontrados; correspondência integral deste requisito não presumida,; suite global QA e GET por perfil disponíveis. Evidência do domínio não demonstra integralmente esta cláusula; UI individual pendente.,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"0,5–2 h de análise/prova por cláusula sem correspondência, agrupada por contrato/consumidor; não somar estas faixas como projetos independentes. Implementação indeterminada até localizar lacuna.",,, diff --git a/resources/css/app.css b/resources/css/app.css index b3c8ec35..57037039 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -7,413 +7,8 @@ @custom-variant dark (&:is(.dark *)); -/* Institutional shell adapted from Tempo; page content keeps its own theme. */ -.tempo-header { - position: relative; - z-index: 40; - background: #090909; - color: #fff; -} -.tempo-header-inner { - position: relative; - display: grid; - grid-template-columns: minmax(0, 1fr) auto auto; - grid-template-rows: 72px; - column-gap: 0.5rem; - align-items: center; - max-width: 1440px; - margin-inline: auto; - padding-inline: 0.75rem; -} -.tempo-logo-link { - grid-area: 1 / 1; - display: inline-flex; - width: fit-content; - align-items: center; - flex-shrink: 0; - border-radius: 0.25rem; -} -.tempo-header-logo { - width: auto; - height: 36px; - object-fit: contain; -} -.tempo-primary-navigation { - display: none; - grid-area: 2 / 1 / auto / -1; - min-width: 0; - border-top: 1px solid #ffffff1a; -} -.tempo-primary-navigation > ul { - display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 0.25rem 0.5rem; - padding-block: 0.75rem; -} -.tempo-primary-navigation .tempo-nav-trigger { - font-size: 0.9375rem; - padding-inline: 0.5rem; -} -.tempo-nav-trigger { - display: flex; - width: 100%; - min-height: 44px; - align-items: center; - justify-content: space-between; - gap: 0.4rem; - padding: 0.5rem 0.75rem; - border-radius: 0.4rem; - font-size: 1rem; - line-height: 1.5; - font-weight: 600; - white-space: nowrap; - color: #eee; - transition: - color 0.2s, - background 0.2s; -} -.tempo-nav-trigger:hover, -.tempo-nav-trigger[data-state='open'] { - background: #ffffff0d; - color: #fff; -} -.tempo-nav-trigger[data-current-group] { - color: #fff; - box-shadow: inset 0 -2px #ed1c24; -} -.tempo-nav-trigger[data-state='open'] > svg { - transform: rotate(180deg); -} -.tempo-primary-navigation .tempo-nav-trigger > svg { - transform: none; - flex-shrink: 0; -} -.tempo-section-bar { - border-top: 1px solid #ffffff14; - background: inherit; -} -.tempo-section-inner { - display: grid; - grid-template-columns: minmax(0, 1fr) auto; - align-items: center; - gap: 0.25rem 0.75rem; - max-width: 1440px; - margin-inline: auto; - padding: 0 0.75rem 0.5rem; -} -.tempo-section-navigation { - grid-area: 1 / 1 / auto / -1; - min-width: 0; -} -.tempo-section-navigation > ul { - display: flex; - justify-content: center; - gap: 0.25rem; -} -.tempo-section-navigation .tempo-nav-trigger { - justify-content: center; - min-height: 44px; - gap: 0.25rem; - padding: 0.5rem 0.375rem; - border-radius: 0; - font-size: 0.8125rem; - letter-spacing: normal; -} -@media (min-width: 640px) { - .tempo-section-navigation .tempo-nav-trigger { - min-height: 48px; - gap: 0.5rem; - padding-inline: 0.75rem; - font-size: 1rem; - } -} -@media (min-width: 768px) { - .tempo-section-inner { - grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); - padding: 0.25rem 1.25rem; - } - .tempo-section-navigation { - grid-area: 1 / 2; - } - .tempo-section-inner .tempo-panel-summary { - grid-area: 1 / 1; - } - .tempo-section-inner .tempo-interest-button { - grid-area: 1 / 3; - } -} -.tempo-header-extras { - display: none; - grid-area: 3 / 1 / auto / -1; - flex-direction: column; - gap: 0.75rem; - min-width: 0; - padding-block: 0.75rem; - border-top: 1px solid #ffffff1a; -} -.tempo-header[data-expanded] .tempo-primary-navigation { - display: block; -} -.tempo-header[data-expanded] .tempo-header-extras { - display: flex; -} -.tempo-header-utilities { - display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: space-between; - gap: 0.5rem; -} -.tempo-utility-button { - display: flex; - min-height: 40px; - align-items: center; - gap: 0.4rem; - padding: 0.4rem; - border-radius: 0.5rem; - font-size: 0.8125rem; - color: #e2e8f0; -} -.tempo-utility-button:hover { - background: #ffffff10; -} -.tempo-header-social { - display: flex; - width: 30px; - height: 40px; - align-items: center; - justify-content: center; - color: var(--social-color); - transition: - transform 0.2s, - opacity 0.2s; - border-radius: 0.4rem; -} -.tempo-header-social:hover { - transform: translateY(-2px); - opacity: 0.8; -} -.tempo-login-button { - display: inline-flex; - min-height: 40px; - align-items: center; - gap: 0.5rem; - border: 1px solid #ffffff50; - border-radius: 0.4rem; - padding: 0.5rem 0.75rem; - font-size: 0.875rem; - font-weight: 600; - white-space: nowrap; - color: #fff; - transition: - background 0.2s, - border-color 0.2s; -} -.tempo-login-button:hover { - background: #ed1c24; - border-color: #ed1c24; -} -.tempo-login-button > span { - max-width: clamp(2rem, calc(100vw - 18rem), 6rem); -} -.tempo-header-actions { - grid-area: 1 / 2; - display: flex; - min-width: 0; - align-items: center; -} -.tempo-interest-button { - display: inline-flex; - grid-area: 2 / 2; - justify-self: end; - align-items: center; - justify-content: center; - min-height: 40px; - padding: 0.5rem 0.65rem; - border: 1px solid #ed1c24; - border-radius: 0.4rem; - background: #ed1c24; - color: white; - font-size: 0.75rem; - font-weight: 600; - white-space: nowrap; - transition: background 0.2s; -} -.tempo-interest-button:hover { - background: #c9151c; -} -.tempo-panel-summary { - grid-area: 2 / 1; - display: flex; - flex-direction: column; - align-items: flex-start; - justify-content: center; - gap: 0.1rem; - min-height: 44px; - font-size: 0.8125rem; - line-height: 1.4; - color: #fff; - text-underline-offset: 3px; -} -.tempo-panel-summary:hover { - text-decoration: underline; -} -.tempo-panel-count { - color: #cbd5e1; - font-size: 0.6875rem; -} -.tempo-header-toggle { - grid-area: 1 / 3; - display: inline-flex; - width: 44px; - height: 44px; - flex-shrink: 0; - align-items: center; - justify-content: center; - border: 1px solid #ffffff33; - border-radius: 0.4rem; - color: #fff; - cursor: pointer; -} -.tempo-header-toggle:hover, -.tempo-header-toggle[aria-expanded='true'] { - background: #ffffff10; -} -@media (min-width: 640px) { - .tempo-header-inner { - padding-inline: 1.25rem; - } - .tempo-header-logo { - height: 44px; - } - .tempo-primary-navigation > ul { - display: flex; - justify-content: space-between; - } -} -@media (min-width: 1024px) { - .tempo-header-inner { - grid-template-rows: 88px; - padding-inline: 1.5rem; - } - .tempo-header-logo { - height: 56px; - } -} -@media (min-width: 1280px) { - /* Shared columns keep each portal area below its institutional link. */ - .tempo-header-layout { - display: grid; - grid-template-columns: auto repeat(4, max-content) minmax(0, 1fr) auto; - column-gap: 0.25rem; - max-width: 1440px; - margin-inline: auto; - padding-inline: 2rem; - } - .tempo-header-inner { - grid-column: 1 / -1; - grid-template-columns: subgrid; - min-height: 88px; - column-gap: normal; - max-width: none; - margin: 0; - padding: 0; - } - .tempo-logo-link { - margin-right: 0.75rem; - } - .tempo-header-logo { - height: 64px; - } - .tempo-header[data-expanded] .tempo-primary-navigation, - .tempo-primary-navigation { - display: grid; - grid-area: 1 / 2 / 2 / 6; - grid-template-columns: subgrid; - border: 0; - } - .tempo-primary-navigation > ul { - display: grid; - grid-column: 1 / -1; - grid-template-columns: subgrid; - gap: normal; - padding: 0; - } - .tempo-nav-trigger { - justify-content: center; - padding-inline: 0.875rem; - font-size: 1.125rem; - letter-spacing: 0.025em; - } - .tempo-primary-navigation .tempo-nav-trigger { - padding-inline: 0.625rem; - font-size: 1.125rem; - } - .tempo-header-extras { - display: flex; - grid-area: 1 / 6; - justify-self: end; - flex-shrink: 0; - padding: 0 0.75rem; - border-top: 0; - border-inline: 1px solid #ffffff1a; - } - .tempo-header-utilities { - flex-wrap: nowrap; - gap: 0.5rem; - } - .tempo-header-social { - width: 26px; - } - .tempo-header-toggle { - display: none; - } - .tempo-header-actions { - grid-area: 1 / 7; - } - .tempo-section-bar { - display: grid; - grid-column: 1 / -1; - grid-template-columns: subgrid; - } - .tempo-section-inner { - grid-column: 1 / -1; - grid-template-columns: subgrid; - gap: normal; - max-width: none; - margin: 0; - padding-inline: 0; - } - .tempo-section-navigation { - display: grid; - grid-area: 1 / 2 / 2 / 5; - grid-template-columns: subgrid; - } - .tempo-section-navigation > ul { - display: grid; - grid-column: 1 / -1; - grid-template-columns: subgrid; - gap: normal; - } - .tempo-section-navigation .tempo-nav-trigger { - padding-inline: 0.625rem; - } - .tempo-primary-navigation .tempo-nav-trigger, - .tempo-section-navigation .tempo-nav-trigger { - justify-content: flex-start; - } - .tempo-interest-button { - padding-inline: 0.85rem; - font-size: 0.8125rem; - } - .tempo-section-inner .tempo-interest-button { - grid-area: 1 / 6 / 2 / -1; - } -} -.tempo-header :is(a, button):focus-visible { - outline: 2px solid #fff; - outline-offset: 4px; -} +@import './tempo-header.css'; + .tempo-dropdown { z-index: 60; border: 1px solid #e2e8f0; diff --git a/resources/css/tempo-header.css b/resources/css/tempo-header.css new file mode 100644 index 00000000..3b833003 --- /dev/null +++ b/resources/css/tempo-header.css @@ -0,0 +1,321 @@ +/* Presentation choice for Tempo's 21/10/2026 request: one shared navigation. */ +.tempo-header { + position: relative; + z-index: 40; + background: #090909; + color: #fff; + border-bottom: 1px solid #ffffff14; +} +.tempo-header-inner { + display: grid; + grid-template-columns: minmax(0, 1fr) auto auto; + grid-template-rows: 71px; + align-items: center; + column-gap: 0.5rem; + max-width: 1600px; + margin-inline: auto; + padding-inline: 0.75rem; +} +.tempo-logo-link { + grid-area: 1 / 1; + display: inline-flex; + align-items: center; + width: 112px; + max-width: 100%; + border-radius: 0.25rem; +} +.tempo-header-logo { + width: 100%; + height: auto; + object-fit: contain; +} +.tempo-primary-navigation { + display: none; + grid-area: 2 / 1 / auto / -1; + min-width: 0; + border-top: 1px solid #ffffff1a; + padding-block: 0.75rem; +} +.tempo-primary-navigation > ul { + display: grid; + gap: 0.25rem; +} +.tempo-nav-trigger { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.4rem; + width: 100%; + min-height: 44px; + padding: 0.5rem 0.75rem; + border-radius: 0.5rem; + color: #e2e8f0; + font-size: 1rem; + line-height: 1.5; + font-weight: 600; + white-space: nowrap; + transition: + color 0.2s, + background 0.2s; +} +.tempo-nav-trigger:hover, +.tempo-nav-trigger[data-state='open'] { + background: #ffffff0d; + color: #fff; +} +.tempo-nav-trigger[data-current-group] { + color: #fff; + background: #ffffff08; + box-shadow: inset 0 -2px #ed1c24; +} +.tempo-nav-trigger > svg { + flex-shrink: 0; + transition: transform 0.2s; +} +.tempo-nav-trigger[data-state='open'] > svg { + transform: rotate(180deg); +} +.tempo-header-extras { + display: none; + grid-area: 3 / 1 / auto / -1; + min-width: 0; + padding-block: 0.75rem; + border-top: 1px solid #ffffff1a; +} +.tempo-header-utilities { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem; +} +.tempo-utility-button { + display: flex; + align-items: center; + gap: 0.4rem; + min-height: 44px; + padding: 0.4rem; + border-radius: 0.5rem; + color: #e2e8f0; + font-size: 0.8125rem; +} +.tempo-utility-button:hover { + background: #ffffff10; +} +.tempo-header-actions { + grid-area: 1 / 2; + display: flex; + align-items: center; + gap: 0.5rem; + min-width: 0; +} +.tempo-login-button { + display: inline-flex; + align-items: center; + gap: 0.5rem; + min-height: 44px; + padding: 0.5rem 0.625rem; + border: 1px solid #ffffff40; + border-radius: 0.5rem; + color: #fff; + font-size: 0.875rem; + font-weight: 600; + white-space: nowrap; + transition: + background 0.2s, + border-color 0.2s; +} +.tempo-login-button:hover { + background: #ffffff10; + border-color: #ffffff80; +} +.tempo-login-button > span { + max-width: clamp(2rem, calc(100vw - 18rem), 6rem); +} +.tempo-panel-summary { + position: relative; + display: inline-flex; + align-items: center; + justify-content: center; + width: 44px; + height: 44px; + flex-shrink: 0; + border-radius: 0.5rem; + color: #e2e8f0; +} +.tempo-panel-summary:hover { + background: #ffffff10; + color: #fff; +} +.tempo-panel-count { + position: absolute; + top: 0; + right: -0.125rem; + min-width: 17px; + padding-inline: 0.2rem; + border: 2px solid #090909; + border-radius: 999px; + background: #ed1c24; + color: #fff; + font-size: 0.5625rem; + line-height: 1.4; + text-align: center; +} +.tempo-interest-button { + display: none; + grid-area: 4 / 1 / auto / -1; + align-items: center; + justify-content: center; + gap: 0.5rem; + min-height: 44px; + margin-bottom: 1rem; + padding: 0.5rem 0.875rem; + border: 1px solid #ed1c24; + border-radius: 0.5rem; + background: #ed1c24; + color: #fff; + font-size: 0.8125rem; + font-weight: 600; + white-space: nowrap; + transition: background 0.2s; +} +.tempo-interest-button:hover { + background: #c9151c; +} +.tempo-header-toggle { + grid-area: 1 / 3; + display: inline-flex; + align-items: center; + justify-content: center; + width: 44px; + height: 44px; + border: 1px solid #ffffff33; + border-radius: 0.5rem; + color: #fff; + cursor: pointer; +} +.tempo-header-toggle:hover, +.tempo-header-toggle[aria-expanded='true'] { + background: #ffffff10; +} +.tempo-header[data-expanded] .tempo-primary-navigation { + display: block; +} +.tempo-header[data-expanded] .tempo-header-extras { + display: flex; +} +.tempo-header[data-expanded] .tempo-interest-button { + display: inline-flex; +} +.tempo-header :is(a, button):focus-visible { + outline: 2px solid #fff; + outline-offset: 3px; +} +.tempo-submenu { + max-width: min( + calc(100vw - 1.5rem), + var(--radix-dropdown-menu-content-available-width) + ); +} +@media (min-width: 640px) { + .tempo-header-inner { + grid-template-columns: minmax(0, 1fr) auto auto auto; + column-gap: 0.75rem; + padding-inline: 1.5rem; + } + .tempo-logo-link { + width: 132px; + } + .tempo-interest-button { + display: inline-flex; + grid-area: 1 / 3; + margin-bottom: 0; + } + .tempo-header-toggle { + grid-area: 1 / 4; + } +} +@media (min-width: 1280px) { + .tempo-header-inner { + grid-template-columns: auto minmax(0, 1fr) auto auto auto; + column-gap: 0.25rem; + padding-inline: 1.25rem; + } + .tempo-logo-link { + width: 100px; + } + .tempo-login-button > span { + max-width: 3rem; + } + .tempo-primary-navigation, + .tempo-header[data-expanded] .tempo-primary-navigation { + display: block; + grid-area: 1 / 2; + border: 0; + padding: 0; + justify-self: center; + } + .tempo-primary-navigation > ul { + display: flex; + align-items: center; + gap: 0; + } + .tempo-nav-trigger { + justify-content: center; + padding-inline: 0.25rem; + font-size: 1.125rem; + letter-spacing: 0.025em; + } + .tempo-header-extras, + .tempo-header[data-expanded] .tempo-header-extras { + display: flex; + grid-area: 1 / 3; + padding: 0 0.5rem 0 0; + border: 0; + border-right: 1px solid #ffffff1a; + } + .tempo-header-utilities { + flex-wrap: nowrap; + } + .tempo-header-actions { + grid-area: 1 / 4; + } + .tempo-interest-button { + grid-area: 1 / 5; + } + .tempo-header-toggle { + display: none; + } +} +@media (min-width: 1440px) { + .tempo-header-inner { + column-gap: 0.75rem; + padding-inline: 2rem; + } + .tempo-nav-trigger { + padding-inline: 0.375rem; + font-size: 1.125rem; + } + .tempo-logo-link { + width: 132px; + } + .tempo-login-button > span { + max-width: 5rem; + } + .tempo-header-extras { + padding-right: 0.75rem; + } + .tempo-primary-navigation > ul { + gap: 0.125rem; + } +} +@media (min-width: 1536px) { + .tempo-header-inner { + column-gap: 1rem; + } + .tempo-nav-trigger { + padding-inline: 0.75rem; + } + .tempo-login-button > span { + max-width: 6rem; + } +} diff --git a/resources/js/components/portal-grouped-menu.tsx b/resources/js/components/portal-grouped-menu.tsx index 895b7e09..fd282ae9 100644 --- a/resources/js/components/portal-grouped-menu.tsx +++ b/resources/js/components/portal-grouped-menu.tsx @@ -2,14 +2,16 @@ import { Link, router, usePage } from '@inertiajs/react'; import { ChevronDown, ArrowUpRight, + LayoutDashboard, LogOut, Menu, UserRound, X, } from 'lucide-react'; -import { useEffect, useId, useRef, useState } from 'react'; +import { Fragment, useEffect, useId, useRef, useState } from 'react'; +import { useIsMobile } from '@/hooks/use-mobile'; import { useNavigationContext } from '@/components/navigation-context'; -import { TempoSocialLinks, useTempoUi } from '@/components/tempo-brand'; +import { tempoSocialLinks, useTempoUi } from '@/components/tempo-brand'; import { TempoLanguageSelector, TempoWeather, @@ -50,6 +52,7 @@ export function PortalGroupedMenu() { opportunityManagement?: OpportunityManagementAccess | null; }>(); const { t, language, requestCount } = useTempoUi(); + const mobile = useIsMobile(); const navigation = useNavigationContext(); const groups = portalNavigation({ context: navigation.view @@ -69,24 +72,34 @@ export function PortalGroupedMenu() { const currentItem = currentNavigationItem(groups, url); const [loggingOut, setLoggingOut] = useState(false); const [expanded, setExpanded] = useState(false); - const institutionalId = useId(); + const navigationId = useId(); const toolsId = useId(); + const interestId = useId(); const toggle = useRef(null); useEffect(() => router.on('navigate', () => setExpanded(false)), []); const items = (children: PortalNavItem[]) => children.map((item) => item.children ? ( - - - {t(item.label)} - - + mobile ? ( + + + {t(item.label)} + {items(item.children)} - - + + ) : ( + + + {t(item.label)} + + + {items(item.children)} + + + ) ) : ( !['home', 'discovery', 'realization', 'support'].includes(group.id), ); + const panelLabel = `${t('O meu painel')} — ${requestCount} ${t(requestCount === 1 ? 'pedido recebido' : 'pedidos recebidos')}`; + const institutionalCurrent = url.split('?')[0] === '/contacto'; return (
-
-
- - Tempo - - -
-
-
- - -
- -
-
-
- {props.auth?.user ? ( - - - - - - {props.auth.user.email} - - {items(accountGroups)} - - - router.flushAll()} - onStart={() => setLoggingOut(true)} - onFinish={() => - setLoggingOut(false) +
+ + Tempo + +
- -
-
-
- - {t('O meu painel')} - + Grupo actual + + )} + + + {items(group.children ?? [])} + + + + ))} +
  • + - {requestCount}{' '} - {t( - requestCount === 1 - ? 'pedido recebido' - : 'pedidos recebidos', - )} - - - - - {t('Manifestar interesse')} - + {name} + + + ), + )} + + +
  • + + +
    +
    +
    + + +
    +
    + +
    + + {t('Manifestar interesse')} +
    ); diff --git a/tools/portal-header-qa.mjs b/tools/portal-header-qa.mjs new file mode 100644 index 00000000..9883eb57 --- /dev/null +++ b/tools/portal-header-qa.mjs @@ -0,0 +1,389 @@ +// Isolated UI fixture: real header/providers, synthetic Inertia props, no database. +// Requires the local Vite server. No requests to Laravel or external services. +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import path from 'node:path'; +import { createRequire } from 'node:module'; +import { portalNavigation } from '../resources/js/lib/portal-navigation.ts'; + +const root = process.cwd(); +const dir = path.join(root, 'outputs/header-navbar-20261021'); +fs.mkdirSync(dir, { recursive: true }); +const require = createRequire(import.meta.url); +const { chromium } = require(process.env.HEADER_QA_PLAYWRIGHT || 'playwright'); +const { expect } = require( + (process.env.HEADER_QA_PLAYWRIGHT || 'playwright') + '/test', +); +const base = process.env.HEADER_QA_VITE || 'http://127.0.0.1:5173'; +assert.equal(new URL(base).hostname, '127.0.0.1'); +const before = process.argv.includes('--before'); +if (before && fs.existsSync(path.join(dir, 'before-results.json'))) { + throw new Error( + 'The original baseline already exists and must be preserved.', + ); +} +fs.writeFileSync( + path.join(dir, 'fixture.html'), + ` + +InvesteMoz · revisão do header
    +`, +); +fs.writeFileSync( + path.join(dir, 'fixture.tsx'), + ` +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import { createInertiaApp } from '@inertiajs/react'; +import { PortalGroupedMenu } from '../../resources/js/components/portal-grouped-menu'; +import { TempoUiProvider, useTempoUi } from '../../resources/js/components/tempo-brand'; +import '../../resources/css/app.css'; +const role = new URLSearchParams(location.search).get('role') || 'guest'; +const props = { + auth: { user: role === 'guest' ? null : { id: 1, name: 'Investidor de demonstração com nome extenso', email: 'qa@example.invalid' }, canManagePortal: role === 'manager' }, + existingBusinessEnabled: true, businessReviewUrl: role === 'manager' ? '/management/negocios' : null, + educationEnabled: true, aiEnabled: true, legacyContentEnabled: true, +}; +function Fixture() { + const ui = useTempoUi(); + return <>
    +

    INVESTEMOZ · REVISÃO LOCAL

    +

    O seu próximo investimento começa aqui

    +

    Navegação real do portal com dados fictícios para testar a apresentação.

    + +
    ; +} +await createInertiaApp({page:{component:'fixture',props,url:'/',version:null},resolve:()=>Fixture, + setup({el,App,props}) {createRoot(el).render();}}); +`, +); +const browser = await chromium.launch({ + headless: true, + ...(process.env.HEADER_QA_CHROMIUM + ? { executablePath: process.env.HEADER_QA_CHROMIUM } + : {}), +}); +const results = []; +const errors = []; +try { + for (const [width, role, language] of before + ? [ + [1440, 'guest', 'pt'], + [390, 'guest', 'pt'], + ] + : [ + [1280, 'manager', 'fr'], + [1280, 'manager', 'pt'], + [1440, 'manager', 'fr'], + [320, 'guest', 'pt'], + [320, 'investor', 'pt'], + [390, 'guest', 'pt'], + [390, 'manager', 'pt'], + [768, 'investor', 'pt'], + [1024, 'manager', 'pt'], + [1440, 'guest', 'pt'], + [1920, 'investor', 'en'], + ]) { + const context = await browser.newContext({ + viewport: { width, height: 900 }, + }); + await context.addInitScript( + (lang) => localStorage.setItem('tempo-navigation-language', lang), + language, + ); + await context.route('**/*', (route) => { + const url = new URL(route.request().url()); + if (url.origin === base && url.pathname.startsWith('/images/')) { + const asset = path.resolve(root, 'public', `.${url.pathname}`); + if ( + asset.startsWith( + path.join(root, 'public', 'images') + path.sep, + ) && + fs.existsSync(asset) + ) { + return route.fulfill({ path: asset }); + } + } + if (url.origin === base || url.protocol === 'data:') + return route.continue(); + return route.abort(); + }); + const page = await context.newPage(); + page.on('pageerror', (e) => { + errors.push(e.message); + console.error(e.message); + }); + await page.goto( + `${base}/outputs/header-navbar-20261021/fixture.html?role=${role}`, + { waitUntil: 'domcontentloaded', timeout: 60000 }, + ); + const header = page.locator('.tempo-header'); + await header.waitFor(); + await page.screenshot({ + path: path.join( + dir, + `${before ? 'before' : 'after'}-${width}-${role}-${language}.png`, + ), + }); + if (before) { + results.push({ + width, + height: await header.evaluate( + (el) => el.getBoundingClientRect().height, + ), + }); + await context.close(); + continue; + } + assert.equal( + await header.locator('nav').count(), + 1, + 'One navigation landmark in header', + ); + assert.equal(await header.locator('.tempo-section-bar').count(), 0); + const collapsedHeight = await header.evaluate( + (el) => el.getBoundingClientRect().height, + ); + assert.ok(collapsedHeight <= 80, `Header height ${collapsedHeight}`); + if (width < 1280) { + const toggle = header.locator('.tempo-header-toggle'); + await toggle.click(); + assert.equal(await toggle.getAttribute('aria-expanded'), 'true'); + await page.screenshot({ + path: path.join( + dir, + `expanded-${width}-${role}-${language}.png`, + ), + }); + await page.keyboard.press('Escape'); + assert.equal(await toggle.getAttribute('aria-expanded'), 'false'); + await expect(toggle).toBeFocused(); + await toggle.click(); + } + const nav = header.locator('nav'); + if (width >= 1280) { + const boxes = await Promise.all( + [ + '.tempo-logo-link', + '.tempo-primary-navigation', + '.tempo-header-extras', + '.tempo-header-actions', + '.tempo-interest-button', + ].map((selector) => header.locator(selector).boundingBox()), + ); + for (let i = 1; i < boxes.length; i++) + assert.ok( + boxes[i - 1].x + boxes[i - 1].width <= boxes[i].x + 1, + `Header elements overlap at ${width}px: ${JSON.stringify(boxes)}`, + ); + } + assert.deepEqual( + await nav + .locator(':scope > ul > li') + .evaluateAll((nodes) => + nodes.map( + (node) => + node + .querySelector('a,button') + ?.getAttribute('href') || + node.textContent.trim(), + ), + ), + language === 'pt' + ? [ + '/', + 'Descoberta', + 'Realização', + 'Suporte', + '/sobre', + 'Tempo', + ] + : language === 'fr' + ? [ + '/', + 'Découvrir', + 'Investir', + 'Assistance', + '/sobre', + 'Tempo', + ] + : ['/', 'Discover', 'Invest', 'Support', '/sobre', 'Tempo'], + ); + assert.equal(await nav.locator('a[href="/sobre"]').count(), 1); + assert.equal( + await nav + .locator('a') + .first() + .evaluate((el) => getComputedStyle(el).fontSize), + width >= 1280 ? '18px' : '16px', + ); + const destinations = new Set( + await header + .locator('a[href]') + .evaluateAll((nodes) => + nodes.map((node) => node.getAttribute('href')), + ), + ); + async function inspectMenu(menu) { + await menu.waitFor(); + menu = page.locator(`[id="${await menu.getAttribute('id')}"]`); + try { + await expect + .poll(async () => { + const box = await menu.boundingBox(); + return ( + !!box && + box.x >= 0 && + box.x + box.width <= width + 1 + ); + }) + .toBe(true); + } catch (error) { + console.error( + JSON.stringify({ + width, + role, + menu: await menu.getAttribute('aria-labelledby'), + box: await menu.boundingBox(), + }), + ); + await page.screenshot({ + path: path.join(dir, 'submenu-failure.png'), + }); + throw error; + } + for (const href of await menu + .locator('a[href]') + .evaluateAll((nodes) => + nodes.map((node) => node.getAttribute('href')), + )) + destinations.add(href); + const subIds = await menu + .locator('[role="menuitem"][aria-haspopup="menu"]') + .evaluateAll((nodes) => nodes.map((node) => node.id)); + for (const subId of subIds) { + const sub = page.locator(`[id="${subId}"]`); + await sub.focus(); + await page.keyboard.press('ArrowRight'); + await expect(sub).toHaveAttribute('aria-expanded', 'true'); + await inspectMenu(page.locator('[role="menu"]').last()); + await page.keyboard.press('ArrowLeft'); + await expect(sub).toBeFocused(); + } + } + for (const trigger of await nav + .locator(':scope > ul > li > button') + .all()) { + await trigger.focus(); + await page.keyboard.press('Enter'); + assert.equal(await trigger.getAttribute('aria-expanded'), 'true'); + const menu = page.locator('[role="menu"]').last(); + await inspectMenu(menu); + await page.keyboard.press('Escape'); + await expect(trigger).toBeFocused(); + } + await header + .getByRole('button', { name: 'Tempo', exact: true }) + .click(); + for (const href of [ + '/contacto', + 'https://revista.tempo.co.mz/', + 'https://www.facebook.com/revistatempo.mz/', + 'https://www.instagram.com/revistatempo.mz/', + 'https://www.linkedin.com/company/revistatempo/', + 'https://www.youtube.com/@RevistaTempoMz/', + ]) { + assert.equal( + await page.locator(`[role="menu"] a[href="${href}"]`).count(), + 1, + href, + ); + } + await page.keyboard.press('Escape'); + assert.ok( + await header + .getByRole('button', { name: 'Idioma da navegação' }) + .isVisible(), + ); + assert.ok( + await header + .getByRole('button', { name: 'Temperatura em Maputo' }) + .isVisible(), + ); + assert.ok( + await header.locator('a[href="/manifestar-interesse"]').isVisible(), + ); + const dashboard = header.locator('a[href="/investidor/manifestacoes"]'); + assert.ok(await dashboard.isVisible()); + await page.locator('[data-test="increment"]').click(); + assert.match(await dashboard.getAttribute('aria-label'), /1 /); + if (role !== 'guest') { + await header.locator('.tempo-login-button').click(); + await inspectMenu(page.locator('[role="menu"]').last()); + assert.ok( + await page + .locator('[data-test="portal-logout-button"]') + .isVisible(), + ); + const hasManagement = await page + .getByRole('menu') + .getByText('Gestão', { exact: true }) + .count(); + assert.equal(hasManagement > 0, role === 'manager'); + await page.keyboard.press('Escape'); + } else { + assert.ok(await header.locator('a[href="/login"]').isVisible()); + } + const catalog = portalNavigation({ + authenticated: role !== 'guest', + manager: role === 'manager', + businesses: true, + businessReviewUrl: + role === 'manager' ? '/management/negocios' : null, + education: true, + ai: true, + legacyContent: true, + }); + function checkDestinations(groups) { + for (const group of groups) { + if (group.children) checkDestinations(group.children); + else if (group.href) + assert.ok( + destinations.has(group.href), + `Preserved destination: ${group.href}`, + ); + } + } + checkDestinations( + role === 'guest' + ? catalog.filter((group) => group.id !== 'account') + : catalog, + ); + const overflow = await header.evaluate((el) => + Array.from(el.querySelectorAll('a,button,img')) + .filter((n) => { + const r = n.getBoundingClientRect(); + return r.width && (r.x < -1 || r.right > innerWidth + 1); + }) + .map((n) => n.textContent), + ); + assert.deepEqual(overflow, []); + results.push({ + width, + role, + language, + collapsedHeight, + destinations: destinations.size, + result: 'passed', + }); + await context.close(); + } + assert.deepEqual(errors, []); + fs.writeFileSync( + path.join(dir, before ? 'before-results.json' : 'qa-results.json'), + JSON.stringify({ results, errors }, null, 2), + ); + console.log(JSON.stringify({ results, errors })); +} finally { + await browser.close(); +}