Comece por aqui
O essencial do recorte
${htmlEscape(content.lede)}
-
${lineItemsHtml(content.essential)}
/**
* Briefing de capacitação — print renderer (C210).
*
* Ports the approved gate design (`docs/plans/briefing-capacitacao-solla-ui-design.html`)
* class by class into the inline print CSS the report family uses: four fixed
* A4 sheets (`essencial|defesas|qa|evitar`), sober, no campaign brand, the
* literal internal label on every sheet and the vote request as a rendered
* literal. The companion `.md` carries everything the PDF may have shed.
*/
import { BRIEFING_LABEL, BRIEFING_PAGE_TOTAL } from './briefingContent.mjs'
import { formatDateBr, formatDateTimeBr } from './cityReportFormat.mjs'
import { resolveDossierUnit } from './dossieUnit.mjs'
import { htmlEscape, moreItemsLabel } from './reportText.mjs'
const BRIEFING_REQUEST_LINE =
'“Posso contar com você? Para deputado federal, vote 1313, Jorge Solla.”'
const BRIEFING_PRINT_CSS = `
:root {
--ink: #18232d;
--ink-soft: #52616d;
--accent: #4d6d7c;
--line: #bdc8ce;
--line-light: #dce3e6;
--paper: #ffffff;
--workspace: #e9edef;
--note: #f2f5f6;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body { color: var(--ink); background: var(--paper); font-family: 'Fira Sans', 'DejaVu Sans', Arial, sans-serif; -webkit-font-smoothing: antialiased; }
@page { size: A4; margin: 0; }
.sheet {
display: flex;
width: 210mm;
height: 297mm;
padding: 14mm 16mm 12mm;
overflow: hidden;
flex-direction: column;
background: var(--paper);
break-after: page;
font-size: 9.4pt;
line-height: 1.42;
}
.sheet:last-child { break-after: auto; }
.sheet p, .sheet ul, .sheet ol { margin-top: 0; }
.sheet a { color: var(--accent); }
.brief-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 9mm; padding-bottom: 3mm; border-bottom: .35mm solid var(--ink); }
.kicker, .eyebrow { margin: 0; color: var(--accent); font-size: 7.3pt; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; }
.brief-title { margin: 1mm 0 0; font-size: 19pt; font-weight: 650; line-height: 1.05; letter-spacing: -.025em; }
.brief-subtitle { margin: 1.2mm 0 0; color: var(--ink-soft); font-size: 8.7pt; }
.internal-label { max-width: 47mm; margin: 0; color: var(--ink); font-size: 7.2pt; font-weight: 700; line-height: 1.4; text-align: right; text-transform: uppercase; }
.page-no { display: block; margin-top: 1mm; color: var(--ink-soft); font-weight: 500; text-transform: none; }
.section { margin-top: 5mm; }
.section + .section { margin-top: 6mm; }
.section-title { margin: 1.2mm 0 0; font-size: 13.5pt; font-weight: 650; line-height: 1.15; letter-spacing: -.015em; }
.lede { max-width: 158mm; margin: 3mm 0 0; font-size: 10.2pt; line-height: 1.5; }
.rule-note { margin-top: 4mm; padding: 2.5mm 0 2.5mm 4mm; border-top: .25mm solid var(--line); border-bottom: .25mm solid var(--line); border-left: 1mm solid var(--accent); color: var(--ink-soft); font-size: 8.4pt; line-height: 1.42; }
.rule-note strong { color: var(--ink); }
.line-list, .script-list, .avoid-list, .check-list { margin: 3mm 0 0; padding: 0; border-top: .35mm solid var(--ink); list-style: none; }
.line-list li, .script-list li, .avoid-list li, .check-list li { position: relative; padding: 2.5mm 0 2.5mm 6mm; border-bottom: .2mm solid var(--line-light); }
.line-list li::before, .script-list li::before, .avoid-list li::before, .check-list li::before { position: absolute; top: 3.7mm; left: 0; width: 2.2mm; height: .45mm; background: var(--accent); content: ''; }
.line-title { display: block; font-weight: 700; }
.line-meta { display: block; margin-top: .8mm; color: var(--ink-soft); font-size: 7.8pt; line-height: 1.4; }
.more-note { margin: 3mm 0 0; color: var(--ink-soft); font-size: 8pt; font-weight: 600; line-height: 1.4; }
.source { color: var(--accent); font-size: 7.4pt; font-weight: 700; }
.request-line { margin: 3.5mm 0 0; padding: 4mm 0; border-top: .6mm solid var(--ink); border-bottom: .6mm solid var(--ink); font-size: 14pt; font-weight: 650; line-height: 1.3; letter-spacing: -.015em; }
.request-line em { color: var(--accent); font-style: normal; }
.script-list { counter-reset: script-step; }
.script-list li { min-height: 14mm; padding-left: 13mm; counter-increment: script-step; }
.script-list li::before { top: 2.7mm; width: 8mm; height: auto; color: var(--accent); background: none; content: counter(script-step, decimal-leading-zero); font-size: 8pt; font-weight: 700; }
.qa-list { margin: 3mm 0 0; padding: 0; border-top: .35mm solid var(--ink); list-style: none; }
.qa-item { display: grid; padding: 3.2mm 0; border-bottom: .2mm solid var(--line-light); grid-template-columns: 46mm 1fr; gap: 5mm; }
.qa-question { margin: 0; font-size: 8.6pt; font-weight: 700; line-height: 1.38; }
.qa-side { display: block; margin-bottom: 1mm; color: var(--accent); font-size: 6.8pt; letter-spacing: .07em; text-transform: uppercase; }
.qa-answer { margin: 0; font-size: 8.6pt; line-height: 1.45; }
.qa-answer b { font-weight: 700; }
.avoid-list strong, .check-list strong { font-weight: 700; }
.two-column { display: grid; margin-top: 5mm; grid-template-columns: 1fr 1fr; gap: 8mm; }
.limits { margin-top: 5mm; padding-top: 3mm; border-top: .6mm solid var(--ink); }
.limits p { margin: 1.5mm 0 0; color: var(--ink-soft); font-size: 8pt; line-height: 1.42; }
.brief-footer { display: flex; margin-top: auto; padding-top: 2.5mm; border-top: .25mm solid var(--line); justify-content: space-between; gap: 8mm; color: var(--ink-soft); font-size: 7.2pt; line-height: 1.3; }
.brief-footer strong { color: var(--ink); }
.sheet-compact .section { margin-top: 3.8mm; }
.sheet-compact .avoid-list, .sheet-compact .check-list { margin-top: 2mm; }
.sheet-compact .avoid-list li, .sheet-compact .check-list li { padding-top: 1.65mm; padding-bottom: 1.65mm; font-size: 8.7pt; line-height: 1.32; }
.sheet-compact .avoid-list li::before, .sheet-compact .check-list li::before { top: 2.8mm; }
.sheet-compact .two-column { margin-top: 3.8mm; gap: 6mm; }
.sheet-compact .section-title { font-size: 12.5pt; }
.sheet-compact .limits { margin-top: 3.5mm; padding-top: 2mm; }
.sheet-compact .limits p { margin-top: 1mm; font-size: 7.5pt; line-height: 1.32; }
.sheet-compact .brief-footer { padding-top: 1.8mm; }
`
const HOW_TO_USE_COPY =
'Antes: escolha dois fatos e ensaie o pedido. Durante: escute, responda com um fato verificável e peça o voto. Depois: registre a dúvida que ficou sem resposta para o próximo ciclo do dossiê.'
const WHY_COPY =
'contato pessoal e relacional mobiliza melhor do que broadcast; escuta e narrativa vêm antes do argumento. Evidência internacional orienta o método, mas EUA ≠ Brasil — aqui o plano ajuda também a lembrar o número na urna.'
const RULER_COPY =
'reconheça a preocupação em uma frase, sem repetir o ataque; responda com um fato local verificável; feche perguntando se pode contar com o voto 1313. Se o dossiê não sustenta a resposta, diga que vai conferir.'
const limitsCopyA = (name) =>
`Material interno de capacitação. Não publicar, encaminhar como peça, impulsionar nem adaptar sem revisão editorial e jurídica. Sem CTA público, marca de campanha, cenário eleitoral, estimativa de votos ou dado staff-only. Os fatos foram selecionados do dossiê de ${name} e devem ser conferidos na fonte antes de uso público.`
const LIMITS_COPY_B =
'A evidência de mobilização citada no treinamento é majoritariamente internacional e não mede automaticamente o Brasil. Use os princípios para orientar contato pessoal, plano de voto e lembrança do número — nunca para prometer efeito ou misturar resultados de estudos diferentes.'
const QA_SIDE_LABELS = {
direita: 'Objeção à direita',
esquerda: 'Objeção à esquerda',
entrega: 'Dúvida sobre entrega',
}
/**
* The recorte name printed in headers/footers: the dossiê subject (municipality
* or institution/theme), falling back to the content slug. Shared with the
* builder log so the name has one owner.
*/
export const briefingSubjectName = (report, content) =>
report?.meta?.municipalityName ?? report?.meta?.subjectName ?? content?.slug ?? '—'
const inlineBold = (value) => htmlEscape(value).replace(/\*\*([^*]+)\*\*/g, '$1')
const anchorHtml = (item) =>
item.fact
? `fonte${
item.fact.sourceDate ? ` · ${htmlEscape(formatDateBr(item.fact.sourceDate))}` : ''
}`
: 'lacuna'
const anchorMd = (item) =>
item.fact
? `[fonte](${item.fact.sourceUrl})${item.fact.sourceDate ? ` · ${formatDateBr(item.fact.sourceDate)}` : ''}`
: `_lacuna: ${item.gapReason}_`
const headerHtml = (unit, title, subtitle, page, kickerSubject) => `
Briefing de capacitação · ${htmlEscape(kickerSubject ?? unit.briefingNoun ?? unit.id)} ${htmlEscape(subtitle)}
${BRIEFING_LABEL}
folha ${page}/${BRIEFING_PAGE_TOTAL}
${htmlEscape(title)}
${htmlEscape(moreItemsLabel(count, singular, plural))} no briefing completo (.md)
` : '' const lineItemsHtml = (items) => (items ?? []) .map( (item) => `Comece por aqui
${htmlEscape(content.lede)}
Leitura dos registros · não é opinião
Roteiro curto · fale como pessoa, não como disparo
${BRIEFING_REQUEST_LINE}
${htmlEscape(QA_SIDE_LABELS[item.side] ?? item.side)}${htmlEscape(item.question)}
Reconhecer: ${htmlEscape(item.acknowledge)} Fato: ${htmlEscape(item.answer)} ${anchorHtml(item)} Fechar: ${htmlEscape(item.close)}
Antes de responder
Consulta em campo
Limites e defeso
${htmlEscape(limitsCopyA(briefingSubjectName(report, content)))}
${htmlEscape(LIMITS_COPY_B)}