[
 {
  "chave": "CS-148",
  "territorio": "frontend",
  "titulo": "AS PECAS DE `componentes/base` PASSAM DE MOSTRUARIO A BIBLIOTECA: o acto entra por PROP no `Botao`, no `ChipDeFiltro`, no `Chip` de estado, no `Campo` e no `Dialogo` — medido hoje, `grep -rn \"onClick|onChange|onSelect\" src/componentes/base/*.tsx` da' ZERO, e e' por isso que os 19 ecras foram montados a' mao: usar o sistema custava mais do que ⛔ nao o usar (7 embrulhos a apanhar clique borbulhado em 5 ficheiros, 3 `display: contents`, `<button>` crus fora da base). ⚠️ E E' O MESMO DEFEITO EM DUAS PECAS MAIS, ESCRITO PELO PROPRIO PRODUTO: `app/coordenador/pecas.tsx:111` diz «⛔ nao e' a peca `ListaDensa` do CS-22 a desenhar isto: ela ⛔ nao recebe ligacao por linha» ⟹ `ListaDensa` e `Cartao` passam tambem a receber LIGACAO OU ACTO POR LINHA, senao ⛔ nenhum ecra as pode adoptar. ACRESCENTAR prop e' ADITIVO ⟹ o mostruario continua a desenhar-se como hoje e `e2e/sistema.spec.ts` continua a fechar. ⛔ Este card ⛔ NAO toca em ecra nenhum: e' a biblioteca, e e' o PAI de tudo o resto",
  "escopo_paths": [
   "frontend/src/componentes/base/",
   "frontend/e2e/pecas-com-acto.spec.ts",
   "frontend/e2e/sistema.spec.ts",
   "frontend/e2e/botoes.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/pecas-com-acto.spec.ts --reporter=line",
   "cd frontend && test $(grep -rlE 'onClick|onChange|onSelect' src/componentes/base/*.tsx | wc -l) -ge 5",
   "cd frontend && grep -rqE 'onClick|onChange' src/componentes/base/Botao.tsx && grep -rqE 'onClick|onChange' src/componentes/base/Chip.tsx && grep -rqE 'onClick|onChange' src/componentes/base/Campo.tsx && grep -rqE 'onClick|onChange' src/componentes/base/Dialogo.tsx",
   "cd frontend && grep -qE 'href|onClick' src/componentes/base/ListaDensa.tsx",
   "cd frontend && npx playwright test e2e/sistema.spec.ts e2e/botoes.spec.ts --reporter=line",
   "cd frontend && ! grep -rqE '#[0-9a-fA-F]{3,8}' src/componentes/base/",
   "cd frontend && npx next build"
  ],
  "depende_de": []
 },
 {
  "chave": "CS-149",
  "territorio": "frontend",
  "titulo": "INTER ENTRA AUTO-ALOJADA, E E' ISTO QUE TIRA A «CARA DE ARQUIVO.MD»: `tokens.css:94` nomeia `Inter` desde 25/09 e medido no repo ha' 0 `@font-face`, 0 `next/font`, 0 ficheiros de letra e 0 `public/` ⟹ na maquina do dono o produto cai para `system-ui`. O ficheiro da letra entra DENTRO do repositorio com a licenca ao lado (o mesmo padrao do `PROVENIENCIA.md` do CS-43), o `@font-face` e' escrito a' mao numa folha propria servida pelo `layout.tsx`, e `.md-corpo` passa a estar aplicada UMA vez na raiz. ⛔ ZERO chamadas de rede para letra (R27): ⛔ sem `fonts.googleapis`, ⛔ sem CDN. ⛔ `estilo/tokens.css` ⛔ NAO ENTRA NA CERCA — os 123 tokens estao certos",
  "escopo_paths": [
   "frontend/src/app/layout.tsx",
   "frontend/src/estilo/letra.css",
   "frontend/src/assets/letra/",
   "frontend/package.json",
   "frontend/next.config.js",
   "frontend/e2e/letra.spec.ts",
   "frontend/e2e/tokens-servidos.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/letra.spec.ts --reporter=line",
   "cd frontend && grep -rq '@font-face' src/estilo/letra.css",
   "cd frontend && test $(ls src/assets/letra/ | grep -cE '\\.woff2?$|\\.ttf$|\\.otf$') -ge 1",
   "cd frontend && grep -q 'md-corpo' src/app/layout.tsx",
   "cd frontend && ! grep -rqE 'fonts\\.googleapis|fonts\\.gstatic|use-font|cdn\\.' src/ --include=*.css --include=*.tsx --include=*.ts",
   "cd frontend && test -f src/assets/letra/PROVENIENCIA.md",
   "cd frontend && git diff --exit-code -- src/estilo/tokens.css",
   "cd frontend && npx playwright test e2e/tokens-servidos.spec.ts --reporter=line",
   "cd frontend && npx next build"
  ],
  "depende_de": []
 },
 {
  "chave": "CS-150",
  "territorio": "frontend",
  "titulo": "A CASCA DEIXA DE HERDAR O SERIF DO BROWSER, E PASSA A FALAR POR TOKEN: a barra de topo aparece nos 19 ecras e `<span className={estilos.produto}>Capacita Salvador</span>` (`casca.tsx:81`) tem `font-weight: 700` e ⛔ SEM `font-family`, ⛔ sem tamanho, ⛔ sem token nenhum (`casca.module.css:107-110`) ⟹ o nome do produto sai em Times New Roman na maquina do dono. E e' tambem onde ha' mais valor cru: medido, `casca.module.css` tem literais de espaco e de letra fora de `var(--md-sys-*)` (`padding: .75rem 1rem`, `gap: .75rem`). O `<button>` cru «Sair» (`casca.tsx:88`) passa a `Botao` com acto. ⛔ Nenhuma familia nova: a marca e o corpo sao UMA SO'",
  "escopo_paths": [
   "frontend/src/componentes/casca/",
   "frontend/e2e/casca.spec.ts",
   "frontend/e2e/navegacao.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/casca.spec.ts --reporter=line",
   "cd frontend && grep -A6 '^\\.produto' src/componentes/casca/casca.module.css | grep -q 'md-sys-typescale'",
   "cd frontend && ! grep -qE '(padding|margin|gap|font-size|line-height|border-radius)[^;]*[0-9]+(\\.[0-9]+)?(rem|px)' src/componentes/casca/casca.module.css",
   "cd frontend && ! grep -rq '<button' src/componentes/casca/",
   "cd frontend && ! grep -rqE '#[0-9a-fA-F]{3,8}' src/componentes/casca/",
   "cd frontend && npx playwright test e2e/navegacao.spec.ts --reporter=line",
   "cd frontend && npx next build"
  ],
  "depende_de": [
   "CS-148",
   "CS-149"
  ]
 },
 {
  "chave": "CS-151",
  "territorio": "frontend",
  "titulo": "OS SEIS ESTADOS GANHAM DESENHO EM VEZ DE TEXTO SECO, E VEM DAS 39 PECAS QUE O DONO JA' APROVOU (regra 135 §3, terceiro sitio): `componentes/base/estados.tsx` passa a servir peca do lote em 48dp — vazio, a carregar, erro, sem permissao, sucesso e parcial — com cor por TOKEN (`onSurfaceVariant` no metadado, `primary` na accao), ⛔ nenhuma placa branca por baixo (CS-42, criterio 3), ⛔ nenhum `#hex`, e a PALAVRA sempre escrita ao lado (⛔ icone ⛔ nunca vai sozinho). ⚠️ ESTE CARD VEM ANTES DOS 19 ECRAS E ⛔ NAO DEPOIS, por mecanica e ⛔ nao por gosto: a peca e' a mesma nos 19, e fazer isto depois reabria as 19 capturas. A PRIORIDADE E' DO DONO — corrija no aceite",
  "escopo_paths": [
   "frontend/src/componentes/base/estados.tsx",
   "frontend/src/componentes/base/base.module.css",
   "frontend/src/componentes/base/index.ts",
   "frontend/e2e/estados.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/estados.spec.ts --reporter=line",
   "cd frontend && grep -q 'Icone' src/componentes/base/estados.tsx && grep -qE 'tamanho={48}|tamanho: 48' src/componentes/base/estados.tsx",
   "cd frontend && ! grep -rqE '#[0-9a-fA-F]{3,8}|shimmer|animate-pulse' src/componentes/base/estados.tsx",
   "cd frontend && npx playwright test e2e/sistema.spec.ts --reporter=line",
   "cd frontend && npx next build"
  ],
  "depende_de": [
   "CS-148"
  ]
 },
 {
  "chave": "CS-152",
  "territorio": "backend",
  "titulo": "`GET /vinculos` ABRE-SE A' SECRETARIA E OS DOIS `POST` FICAM COORDENADOR-SO' — e ⛔ nao e' escolha de agente, e' a letra da regra 111 («Ver e administrar, sim; substituir, nao. Quem aceita o medico e' o coordenador da UPA»). Medido: `@Papeis(Papel.COORDENADOR)` esta' NA CLASSE (`vinculo.controlador.ts:26-27`) e essa classe cobre o GET **e** `POST :id/aceitar` **e** `POST :id/tirar` ⟹ dar hoje a porta «Pedidos» a' secretaria era leva-la a um 403. A LEITURA dela e' de TODAS as UPAs (`listar` hoje filtra pelas do coordenador, `vinculo.servico.ts`); os dois POST respondem 403 a sessao de secretaria e 200 ao coordenador DAQUELA UPA, como hoje. ⛔ Sem porta nova no menu: isso e' o CS-153",
  "escopo_paths": [
   "backend/src/modules/vinculo/",
   "backend/test/vinculo.e2e-spec.ts"
  ],
  "aceites": [
   "cd backend && npx jest test/vinculo.e2e-spec.ts --runInBand --ci",
   "cd backend && ! grep -qE '^@Papeis\\(Papel.COORDENADOR\\)' src/modules/vinculo/vinculo.controlador.ts",
   "cd backend && test $(grep -cE '^ *@Papeis\\(' src/modules/vinculo/vinculo.controlador.ts) -ge 2",
   "cd backend && npx jest test/identidade.e2e-spec.ts test/upa.e2e-spec.ts test/cadastro.e2e-spec.ts --runInBand --ci",
   "cd backend && test -d src/modules/vinculo && ! grep -rqiE 'maissaude' src/modules/vinculo/"
  ],
  "depende_de": []
 },
 {
  "chave": "CS-153",
  "territorio": "frontend",
  "titulo": "A SECRETARIA VE TUDO NO MENU, `/sistema` SAI PARA ORFA DELIBERADA, E CADA PORTA GANHA ICONE: medido, `PORTAS` (`lib/navegacao.ts`) tem SETE e a secretaria ve' QUATRO — UPAs, Nucleos, Aulas e **Sistema** — ⛔ sem Calendario, ⛔ sem Pedidos, ⛔ sem Questoes (decisao do dono, regra 111; o criterio «instrumento de trabalho» escrito DENTRO da casa cai). `/sistema` ⛔ nao aparece no menu de papel NENHUM, entra em `ORFAS_DELIBERADAS` com o motivo escrito, continua a abrir pela morada, e ⛔ NAO se apaga (o irreversivel e' do dono). E os icones das portas: hoje 3 das 7 tem, `icone: undefined` esta' em UPAs, Nucleos e Sistema ⟹ cada porta leva peca do lote de 39, e a peca que ⛔ nao existir no lote fica CONTADA E ESCRITA no ficheiro como o `SEM_PECA` do CS-43 ja' exige — ⛔ nao se finge um icone que minta",
  "escopo_paths": [
   "frontend/src/lib/navegacao.ts",
   "frontend/src/componentes/casca/navegacao.tsx",
   "frontend/src/componentes/base/Icone.tsx",
   "frontend/e2e/navegacao.spec.ts",
   "frontend/e2e/alcance.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/navegacao.spec.ts --reporter=line",
   "cd frontend && npx playwright test e2e/alcance.spec.ts --reporter=line",
   "cd frontend && grep -A8 \"caminho: '/calendario'\" src/lib/navegacao.ts | grep -q SECRETARIA",
   "cd frontend && grep -A8 \"caminho: '/coordenador'\" src/lib/navegacao.ts | grep -q SECRETARIA",
   "cd frontend && grep -A8 \"caminho: '/especialista/questoes'\" src/lib/navegacao.ts | grep -q SECRETARIA",
   "cd frontend && test $(sed -n '/ORFAS_DELIBERADAS/,$p' src/lib/navegacao.ts | grep -c \"caminho: '/sistema'\") -eq 1",
   "cd frontend && test $(sed -n '/export const PORTAS/,/^];/p' src/lib/navegacao.ts | grep -c 'icone: undefined') -eq 0",
   "cd frontend && npx playwright test e2e/alcance.spec.ts --reporter=line -g 'as orfas sao exactamente as deliberadas'",
   "cd frontend && npx next build"
  ],
  "depende_de": [
   "CS-150",
   "CS-152"
  ]
 },
 {
  "chave": "CS-154",
  "territorio": "backend",
  "titulo": "OS DEZ NUCLEOS DO DONO RECEBEM A MARCA POR MIGRACAO IDEMPOTENTE, DO MAPA QUE JA' EXISTE: medido na base, `select count(*) from \"Nucleo\" where marca is null` da' **10**, e `nucleo.semente.ts:85` cria com `marca: null` de proposito («dez linhas a apontar para pecas inexistentes era pior do que nulo») — A RAZAO CADUCOU: as 39 pecas estao no disco desde o CS-43 e `app/secretaria/nucleos/galeria.ts:31-42` JA' CASA os dez nucleos com as dez pecas, uma a uma (`nu-urologia`→Urologia … `s-orto`→Ortopedia). O par entra no `nucleo.semente.ts` conferido NOME POR NOME contra a `galeria.ts`, corre DUAS voltas com o mesmo resultado, e ⛔ NAO sobrescreve nucleo cuja marca alguem ja' tenha escolhido. ⛔ Nada a perguntar ao dono: ele ja' viu as pecas («ok, gostei dos modelos») e a secretaria troca qualquer uma no ecra do CS-48 a qualquer momento",
  "escopo_paths": [
   "backend/prisma/migrations/",
   "backend/prisma/seed-nucleos.ts",
   "backend/src/modules/nucleo/",
   "backend/test/marca-dos-dez.e2e-spec.ts",
   "backend/test/nucleo.e2e-spec.ts"
  ],
  "aceites": [
   "cd backend && npx jest test/marca-dos-dez.e2e-spec.ts --runInBand --ci",
   "cd backend && for p in nu-urologia:Urologia s-cardio:Cardiologia nu-paliativos:paliativos nu-urgencia:emerg nu-cirurgia:Cirurgia s-peds:Pediatria nu-infecto:Infectologia s-neuro:Neurologia nu-psiquiatria:Psiquiatria s-orto:Ortopedia; do grep -q \"${p%%:*}\" src/modules/nucleo/nucleo.semente.ts || exit 1; grep -q \"${p%%:*}\" ../frontend/src/app/secretaria/nucleos/galeria.ts || exit 1; done",
   "cd backend && ! grep -qE 'marca: null' src/modules/nucleo/nucleo.semente.ts",
   "cd backend && npx jest test/nucleo.e2e-spec.ts test/migracao-nucleo.e2e-spec.ts test/marca.e2e-spec.ts --runInBand --ci",
   "cd backend && npx jest test/marca-dos-dez.e2e-spec.ts --runInBand --ci -t 'duas voltas dao o mesmo resultado e a marca escolhida a mao nao se sobrescreve'"
  ],
  "depende_de": []
 },
 {
  "chave": "CS-155",
  "territorio": "frontend",
  "titulo": "REPAGINACAO 1 DE 9 — A ENTRADA E O CADASTRO, OS QUATRO ECRAS QUE QUALQUER PESSOA VE PRIMEIRO (`/`, `/entrar`, `/cadastro`, `/cadastro/[token]`): passam a cartao de cantos arredondados com sombra suave SEPARADO POR ESPACO (regra 84), `Campo` do sistema com o acto por prop, e o ecra vazio/erro/sucesso com o desenho do CS-151. Medido hoje: destes quatro, ⛔ NENHUM usa `Cartao` e o `/cadastro/formulario.tsx` tem `<button>` cru. ⚠️ O ecra que ⛔ nao levar cartao leva a RAZAO ESCRITA no proprio ficheiro — o numero final ⛔ nao se finge",
  "escopo_paths": [
   "frontend/src/app/page.tsx",
   "frontend/src/app/raiz.module.css",
   "frontend/src/app/entrar/",
   "frontend/src/app/cadastro/",
   "frontend/e2e/raiz.spec.ts",
   "frontend/e2e/entrada.spec.ts",
   "frontend/e2e/cadastro.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/raiz.spec.ts e2e/entrada.spec.ts e2e/cadastro.spec.ts --reporter=line",
   "cd frontend && { grep -rq '<Cartao' src/app/entrar/ src/app/cadastro/ src/app/page.tsx || grep -rq 'CARTAO ⛔ NAO ENTRA AQUI PORQUE' src/app/entrar/ src/app/cadastro/ src/app/page.tsx; }",
   "cd frontend && ! grep -rq '<button' src/app/entrar/ src/app/cadastro/ src/app/page.tsx",
   "cd frontend && ! grep -rqE \"closest\\('button'\\)|display: *contents\" src/app/entrar/ src/app/cadastro/",
   "cd frontend && ! grep -rqE '#[0-9a-fA-F]{3,8}|shimmer|animate-pulse|snackbar|<progress' src/app/entrar/ src/app/cadastro/ src/app/raiz.module.css",
   "cd frontend && npx next build"
  ],
  "depende_de": [
   "CS-150",
   "CS-151"
  ]
 },
 {
  "chave": "CS-156",
  "territorio": "frontend",
  "titulo": "REPAGINACAO 2 DE 9 — O INSTRUMENTO DO COORDENADOR (`/coordenador` e `/coordenador/pedidos/[id]`), E E' AQUI QUE O CHIP PASSA A FILTRAR DE VERDADE: hoje `ChipDeFiltro` recebe `rotulo` e `escolhido` e ⛔ NADA MAIS (`Chip.tsx:17-19`) ⟹ «filtrar por UPA e' clicar num chip» (regra 83) ⛔ nao e' clicavel. Com o acto do CS-148: clica-se o chip de uma UPA, A LISTA FILTRA, o ✓ de 18dp aparece A' FRENTE e o nome vai POR EXTENSO. A etiqueta de estado e' chip e fica NA ULTIMA COLUNA (regra 87e), o avatar leva SEMPRE o nome escrito ao lado (83a), tirar medico ⛔ nao e' botao vermelho, e o embrulho `Acto` de `pecas.tsx:14-20` DESAPARECE — que e' o que o proprio comentario dele diz que acontece «no dia em que as pecas ganharem onClick». E A FRONTEIRA DA REGRA 111 VE-SE AQUI: a SECRETARIA le' os pedidos de TODAS as UPAs e ⛔ NAO lhe aparece o acto de aceitar nem de tirar — e' SEM PERMISSAO, com a linha a dizer QUE PAPEL age, ⛔ sem vermelho",
  "escopo_paths": [
   "frontend/src/app/coordenador/",
   "frontend/e2e/coordenador.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/coordenador.spec.ts --reporter=line",
   "cd frontend && npx playwright test e2e/coordenador.spec.ts --reporter=line -g 'o coordenador clica o chip de uma UPA e a lista filtra, com o visto a frente e o nome por extenso'",
   "cd frontend && npx playwright test e2e/coordenador.spec.ts --reporter=line -g 'a secretaria le os pedidos de todas as UPAs e nao ve o acto de aceitar nem de tirar'",
   "cd frontend && grep -rq '<ListaDensa' src/app/coordenador/",
   "cd frontend && ! grep -rqE \"closest\\('button'\\)|display: *contents\" src/app/coordenador/",
   "cd frontend && ! grep -rq 'export function Acto' src/app/coordenador/pecas.tsx",
   "cd frontend && ! grep -rq '<button' src/app/coordenador/",
   "cd frontend && ! grep -rqE '#[0-9a-fA-F]{3,8}|shimmer|animate-pulse|snackbar|<progress' src/app/coordenador/",
   "cd frontend && npx next build"
  ],
  "depende_de": [
   "CS-150",
   "CS-151"
  ]
 },
 {
  "chave": "CS-157",
  "territorio": "frontend",
  "titulo": "REPAGINACAO 3 DE 9 — O CALENDARIO (`/calendario`), E A MARCA DO NUCLEO APARECE NELE: e' o unico dos 19 ecras que ja' usa `Cartao` (medido: 1 de 19), e passa a usa-lo A' LETRA da referencia — cartao branco, canto 12dp, sombra suave, SEPARADO POR ESPACO, chip de estado na ultima coluna, e A MARCA DE CADA NUCLEO no cartao da aula (regra 135 §3, primeiro sitio) vinda da base depois do CS-154. O `closest('button')` e o `display: contents` de `Calendario.tsx:79` e `calendario.module.css:57` morrem, e os 4 `<button>` crus passam a `Botao` com acto",
  "escopo_paths": [
   "frontend/src/app/calendario/",
   "frontend/e2e/calendario.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/calendario.spec.ts --reporter=line",
   "cd frontend && npx playwright test e2e/calendario.spec.ts --reporter=line -g 'a aula de um dos dez nucleos mostra a marca dele e nao a marca por omissao'",
   "cd frontend && ! grep -rqE \"closest\\('button'\\)|display: *contents\" src/app/calendario/",
   "cd frontend && ! grep -rq '<button' src/app/calendario/",
   "cd frontend && test $(grep -rho '<Cartao' src/app/calendario/ | wc -l) -ge 2",
   "cd frontend && ! grep -rqE '#[0-9a-fA-F]{3,8}|shimmer|animate-pulse|snackbar|<progress' src/app/calendario/",
   "cd frontend && npx next build"
  ],
  "depende_de": [
   "CS-150",
   "CS-151",
   "CS-154"
  ]
 },
 {
  "chave": "CS-158",
  "territorio": "frontend",
  "titulo": "REPAGINACAO 4 DE 9 — A LISTA DE UPAs DA SECRETARIA (`/secretaria/upas` e `/secretaria/upas/nova`): passa a LISTA DENSA do M3 na ordem de colunas do produto — [avatar da UPA] | nome + coordenador | numero tabular a' direita | ETIQUETA DE ESTADO SEMPRE NA ULTIMA COLUNA (regra 87e) —, ⛔ sem zebra, rato = camada 8% e ⛔ nao levanta a linha. O avatar leva SEMPRE o nome da unidade escrito ao lado (83a). Medido hoje: este ecra ⛔ nao usa `Cartao`, ⛔ nao usa `ListaDensa`, tem 1 `closest('button')` (`pecas.tsx`) e 1 `display: contents` (`upas.module.css:302`)",
  "escopo_paths": [
   "frontend/src/app/secretaria/upas/",
   "frontend/e2e/upas.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/upas.spec.ts --reporter=line",
   "cd frontend && grep -rq '<ListaDensa' src/app/secretaria/upas/",
   "cd frontend && ! grep -rqE \"closest\\('button'\\)|display: *contents\" src/app/secretaria/upas/",
   "cd frontend && ! grep -rq '<button' src/app/secretaria/upas/",
   "cd frontend && ! grep -rqE '#[0-9a-fA-F]{3,8}|shimmer|animate-pulse|snackbar|<progress' src/app/secretaria/upas/",
   "cd frontend && npx next build"
  ],
  "depende_de": [
   "CS-150",
   "CS-151"
  ]
 },
 {
  "chave": "CS-159",
  "territorio": "frontend",
  "titulo": "REPAGINACAO 5 DE 9 — OS NUCLEOS (`/secretaria/nucleos` e `/secretaria/nucleos/nova`), E O ECRA DEIXA DE PEDIR AO DONO O QUE JA' ESTAVA FEITO: com o CS-154 na base, «0 de 10 nucleos com marca escolhida» passa a «10 de 10», e «Carregar imagem» CONTINUA A EXISTIR (regra 102 manda poder subir) ⛔ mas deixa de ser o que salta a' vista como se faltasse tudo. A lista passa a cartao/lista densa com a marca de cada nucleo, e os TRES `closest('button')` de `pecas.tsx` mais o `display: contents` de `nucleos.module.css:234` morrem",
  "escopo_paths": [
   "frontend/src/app/secretaria/nucleos/",
   "frontend/e2e/nucleos.spec.ts",
   "frontend/e2e/nucleos-carregar.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/nucleos.spec.ts e2e/nucleos-carregar.spec.ts --reporter=line",
   "cd frontend && npx playwright test e2e/nucleos.spec.ts --reporter=line -g 'o ecra diz 10 de 10 nucleos com marca escolhida e Carregar imagem continua a existir'",
   "cd frontend && ! grep -rqE \"closest\\('button'\\)|display: *contents\" src/app/secretaria/nucleos/",
   "cd frontend && ! grep -rq '<button' src/app/secretaria/nucleos/",
   "cd frontend && grep -rqE '<Cartao|<ListaDensa' src/app/secretaria/nucleos/",
   "cd frontend && grep -q 'Carregar imagem' src/app/secretaria/nucleos/carregar-textos.ts",
   "cd frontend && ! grep -rqE '#[0-9a-fA-F]{3,8}|shimmer|animate-pulse|snackbar|<progress' src/app/secretaria/nucleos/",
   "cd frontend && npx next build"
  ],
  "depende_de": [
   "CS-150",
   "CS-151",
   "CS-154"
  ]
 },
 {
  "chave": "CS-160",
  "territorio": "frontend",
  "titulo": "REPAGINACAO 6 DE 9 — AS AULAS DA SECRETARIA, OS TRES ECRAS (`/secretaria/aulas`, `/secretaria/aulas/nova`, `/secretaria/aulas/[id]`): a lista passa a `ListaDensa` com a etiqueta de estado em chip NA ULTIMA COLUNA, as `Abas` do M3 entram onde ha' separacao por estado (medido: `Abas` esta' em 0 dos 19 ecras de produto), e a marca do nucleo aparece na linha da aula. ⚠️ E CONSERTA-SE UMA FALTA QUE O PRODUTO JA' TINHA MEDIDO E ⛔ NINGUEM USOU: `secretaria/aulas/dados.ts:461` diz «FALTA DO CS-22, medida: o `ChipDeEstado` … tem quatro tons»",
  "escopo_paths": [
   "frontend/src/app/secretaria/aulas/",
   "frontend/e2e/aulas.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/aulas.spec.ts --reporter=line",
   "cd frontend && grep -rq '<Abas' src/app/secretaria/aulas/ && grep -rq '<ListaDensa' src/app/secretaria/aulas/",
   "cd frontend && grep -rq 'ChipDeEstado' src/app/secretaria/aulas/pecas.tsx",
   "cd frontend && ! grep -rqE \"closest\\('button'\\)|display: *contents\" src/app/secretaria/aulas/",
   "cd frontend && ! grep -rq '<button' src/app/secretaria/aulas/",
   "cd frontend && ! grep -rqE '#[0-9a-fA-F]{3,8}|shimmer|animate-pulse|snackbar|<progress' src/app/secretaria/aulas/",
   "cd frontend && npx next build"
  ],
  "depende_de": [
   "CS-150",
   "CS-151",
   "CS-154"
  ]
 },
 {
  "chave": "CS-161",
  "territorio": "frontend",
  "titulo": "REPAGINACAO 7 DE 9 — O ESPECIALISTA E AS SUAS QUESTOES (`/especialista/questoes` e `/especialista/questoes/[aulaId]`): a lista das aulas dele passa a cartao/lista densa com o chip de estado na ultima coluna, o `Campo` do sistema recebe o acto por prop (hoje escrever uma questao ⛔ nao passa pela peca), e o erro de campo diz O QUE ACONTECEU E O QUE FAZER — ⛔ nunca «campo invalido». ⛔ Sem vermelho onde ⛔ nao ha' erro de sistema (regra 80.3)",
  "escopo_paths": [
   "frontend/src/app/especialista/",
   "frontend/e2e/questoes.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/questoes.spec.ts --reporter=line",
   "cd frontend && npx playwright test e2e/questoes.spec.ts --reporter=line -g 'o especialista escreve a questao pelo Campo do sistema e o erro diz o que aconteceu e o que fazer'",
   "cd frontend && ! grep -q 'rodapeDoCartao' src/app/especialista/questoes/page.tsx",
   "cd frontend && test $(grep -rho '<Cartao' src/app/especialista/ | wc -l) -ge 2",
   "cd frontend && ! grep -rqE \"closest\\('button'\\)|display: *contents\" src/app/especialista/",
   "cd frontend && ! grep -rq '<button' src/app/especialista/",
   "cd frontend && ! grep -rqE '#[0-9a-fA-F]{3,8}|shimmer|animate-pulse|<progress' src/app/especialista/",
   "cd frontend && npx next build"
  ],
  "depende_de": [
   "CS-150",
   "CS-151"
  ]
 },
 {
  "chave": "CS-162",
  "territorio": "frontend",
  "titulo": "REPAGINACAO 8 DE 9 — A SALA DO AO VIVO E O LEITOR DA GRAVACAO (`/ao-vivo/[aulaId]` e `/gravacao/[aulaId]`), QUE E' O ECRA ONDE ESTE PRODUTO ACONTECE: o painel passa a cartao, o `Dialogo` e o `Botao` recebem o acto por prop, e o `<button>` cru de cada um morre. 🩸 E AS TRAVAS DURAS DESTE ECRA ⛔ NAO SE TOCAM: os minutos continuam em BLOCOS de 48x48dp com icone + numero + hora e ⛔ NUNCA uma barra lisa (regra 87.1), o bloco perdido e' VAZADO e ⛔ nao vermelho, o total em tabular fica AO LADO e ⛔ nunca em vez, e o estado PARCIAL mostra as tres coisas ao mesmo tempo com a linha que explica a diferenca entre o que se assistiu e o que contou",
  "escopo_paths": [
   "frontend/src/app/ao-vivo/",
   "frontend/src/app/gravacao/",
   "frontend/e2e/ao-vivo.spec.ts",
   "frontend/e2e/gravacao.spec.ts",
   "frontend/e2e/chat.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/ao-vivo.spec.ts e2e/gravacao.spec.ts e2e/chat.spec.ts --reporter=line",
   "cd frontend && grep -rq '<Cartao' src/app/ao-vivo/ src/app/gravacao/",
   "cd frontend && ! grep -rq '<button' src/app/ao-vivo/ src/app/gravacao/",
   "cd frontend && ! grep -rqE \"closest\\('button'\\)|display: *contents\" src/app/ao-vivo/ src/app/gravacao/",
   "cd frontend && ! grep -rqE '#[0-9a-fA-F]{3,8}|shimmer|animate-pulse|snackbar|<progress|LinearProgress' src/app/ao-vivo/ src/app/gravacao/",
   "cd frontend && npx next build"
  ],
  "depende_de": [
   "CS-150",
   "CS-151"
  ]
 },
 {
  "chave": "CS-163",
  "territorio": "frontend",
  "titulo": "REPAGINACAO 9 DE 9 — O MOSTRUARIO `/sistema` PASSA A DIZER A VERDADE: e' o 19.º ecra e o unico orfao de produto, e hoje anuncia pecas cujas props estao fechadas — a prop `estado` do `Botao` diz-se a si propria «So' para o mostruario e para o QA». Depois do CS-148 o mostruario mostra AS PECAS A FUNCIONAR (o botao carrega, o chip filtra, o campo escreve, o dialogo confirma), leva a letra e os estados com desenho como os outros 18, e a pagina CONTINUA A ABRIR PELA MORADA depois de ter saido do menu no CS-153. ⛔ NAO se apaga: orfa deliberada, com o motivo escrito",
  "escopo_paths": [
   "frontend/src/app/sistema/",
   "frontend/e2e/sistema.spec.ts"
  ],
  "aceites": [
   "cd frontend && npx playwright test e2e/sistema.spec.ts --reporter=line",
   "cd frontend && npx playwright test e2e/sistema.spec.ts --reporter=line -g 'no mostruario o botao carrega, o chip filtra, o campo escreve e o dialogo confirma'",
   "cd frontend && grep -rqE 'onClick|aoCarregar|aoEscolher' src/app/sistema/",
   "cd frontend && ! grep -rqE \"closest\\('button'\\)|display: *contents\" src/app/sistema/",
   "cd frontend && ! grep -rqE '#[0-9a-fA-F]{3,8}|shimmer|animate-pulse' src/app/sistema/",
   "cd frontend && npx playwright test e2e/alcance.spec.ts --reporter=line -g 'as orfas sao exactamente as deliberadas'",
   "cd frontend && npx next build"
  ],
  "depende_de": [
   "CS-148",
   "CS-153"
  ]
 }
]