## Why

Contract previews and PDFs substitute field values (`${employee_position}`, `${employee_name}`, …) into the HTML contract template without escaping them. A value that contains HTML-significant characters is interpreted as markup instead of shown as text: an employee whose contract position is `Trưởng nhóm R&D / Kỹ thuật (Cấp 2) – "A" <b>` gets a preview where `<b>` disappears and the rest of the document may turn bold. The same gap lets any user-editable field inject arbitrary HTML/CSS into a legal document.

## What Changes

- Field values substituted into a contract or contract type template are HTML-escaped before substitution, so they render as literal text in the preview HTML and the generated PDF.
- This covers every value source: default fields (employee profile, employee, contract data, salary values), custom field values, and `overriding_fields` sent by the client.
- Data values that the system injects into template fragments (payslip item names in the `salary_information` list) are escaped as well.
- The template itself (authored in the rich text editor) is NOT escaped; it stays HTML.
- Already-signed contracts keep their existing static PDF file; no regeneration or backfill.

## Capabilities

### New Capabilities
- `contract-document-rendering`: how field values are substituted into contract and contract type templates when producing the preview HTML and PDF, in particular that values render as literal text.

### Modified Capabilities
<!-- none: employee-contract-position only defines the source of employee_position, which is unchanged -->

## Impact

- `app/Models/Contract.php` — `getPreviewByTemplate()` (used by `updatePreview()` → stored `preview` + static PDF for signed contracts, and by `getPDFByRequest()` for custom previews, e.g. `ContractController::previewByAccount`).
- `app/Models/ContractType.php` — `getPreviewByTemplate()` / `getPDFByRequest()` (contract type preview with fake data).
- `app/Models/Field.php` — `templateReplace()` (`salary_information` item fragment); likely home for a shared escaping helper.
- API: the `preview` HTML returned by contract endpoints changes for values containing `<`, `>`, `&`, `"`, `'` (now entity-encoded). The frontend renders it as HTML, so it displays the literal characters.
- No DB migration. No new dependency.
