---
name: CV PDF/HTML Render Playbook
description: Standaard werkwijze voor stabiele A4 CV templates met web/PDF-pariteit, inclusief paginering, meting en debug-stappen.
---

# CV PDF/HTML Render Playbook (Cevace / YorFutur)

Deze skill is de praktische leidraad voor het bouwen en tunen van CV templates zodat:
- de browser preview en PDF hetzelfde gedrag tonen;
- A4-marges stabiel blijven;
- page-breaks voorspelbaar zijn;
- we sneller kunnen debuggen zonder opnieuw het wiel uit te vinden.

## 1. Kernprincipe: Altijd 3 lagen synchroon

Elke template met paginering heeft minimaal 3 lagen die op elkaar moeten aansluiten:

1. **Render (HTML preview)**  
   Voorbeeld: `components/cv-templates/*PagedTemplate.tsx`
2. **Measure (hoogtemeting off-screen)**  
   `components/cv-templates/CVContentMeasure.tsx`
3. **Pagination logic (blokverdeling over pagina’s)**  
   `hooks/useCVPagination.ts`

Als je maar 1 laag aanpast, krijg je bijna altijd mismatch tussen browser en PDF of onverwachte breaks.

## 2. Bestandskaart per template

Voor nieuwe of bestaande templates altijd deze map volgen:

- **Web template:** `components/cv-templates/<Template>PagedTemplate.tsx`
- **PDF template:** `components/cv-templates/<Template>PagedTemplatePDF.ts`
- **Meting:** `components/cv-templates/CVContentMeasure.tsx`
- **Paginering:** `hooks/useCVPagination.ts`
- **Registratie template-id/labels:** `types/cv-templates.ts` + eventuele registry-bestanden

## 3. A4-regels (praktisch)

- A4 = `210mm x 297mm`
- Kleine mm-aanpassingen lijken soms “sprongsgewijs” effect te geven door:
  - block-splitting (atomic chunks),
  - orphan-protection,
  - line wrapping op woordgrenzen.

Richtlijn:
- **~2 regels extra ruimte** is vaak circa **8-10mm** effectief, maar altijd in combinatie met paginering.

## 4. Standaard wijzigingsvolgorde

Bij requests als “nog 2 regels onderaan” of “talen toevoegen”:

1. **Template render aanpassen** (TSX/PDF)  
   Layout, volgorde, labels, secties.
2. **Measure aanpassen**  
   Exact dezelfde blokken/volgorde meetbaar maken met `data-block-id`.
3. **Pagination aanpassen**  
   `getTemplateUsableHeightPx` + eventuele template-specifieke reserve/orphan-rules.
4. **Verifiëren**  
   `npm exec tsc --noEmit` + visuele check browser + PDF.

## 5. Bekende valkuilen en oplossing

### A) Bottom overflow op pagina 1
Symptoom:
- Tekst loopt onderaan tegen rand of breekt te vroeg.

Oplossing:
- **Niet alleen padding wijzigen.**  
  Altijd zowel:
  - bottom padding in `*PagedTemplate.tsx`
  - usable height in `useCVPagination.ts`

### B) Sectie aanwezig in PDF maar niet in web (of andersom)
Symptoom:
- Bijvoorbeeld `Talen` ontbreekt in preview of schuift vreemd.

Oplossing:
- Sectie toevoegen in alle 3 lagen:
  - render,
  - measurement (`data-block-id`),
  - pagination block creation (`createBlocks`).

### C) Grote sprongen bij mini-aanpassingen
Symptoom:
- 0.5-1mm wijziging geeft ineens meerdere regels verschil.

Oplossing:
- Check of blokken atomic gesplitst worden (`splitHtmlContent`).
- Check orphan protection voor dat template.
- Tune in kleine stappen, maar op **bloklogica** (header+first body fit), niet alleen op mm.

## 6. Professionele template-aanpak (specifieke notitie)

Als we `professional` aanpassen:
- `Talen` direct boven `Opleidingen` plaatsen in render én blockvolgorde.
- Bottom fix op pagina 1 uitvoeren via bewezen dubbel-aanpak:
  - template padding
  - template usable-height in paginator
- Daarna pas micro-finetune.

## 7. Definition of Done

Template is “klaar” als:

1. Browser preview en PDF dezelfde sectievolgorde tonen.
2. Geen tekst tegen top/bottom rand op pagina 1 of 2+.
3. Geen extra lege eindpagina.
4. Belangrijke secties (`Profiel`, `Kernvaardigheden`, `Talen`, `Werkervaring`, `Opleidingen`) correct aanwezig volgens afgesproken volgorde.
5. TypeScript check is groen.

## 8. Snelle debug-checklist (copy/paste)

1. Is de sectie toegevoegd in render?
2. Is de sectie toegevoegd in `CVContentMeasure` met `data-block-id`?
3. Is de sectie opgenomen in `createBlocks` in `useCVPagination`?
4. Kloppen template-specifieke heights in `getTemplateUsableHeightPx`?
5. Is orphan protection te streng voor dit template?
6. Is bottom padding consistent met verwachte usable space?
7. `npm exec tsc --noEmit` groen?
