# PRINT_SAFE_HTML.md
## Standing Instructions: Zero Page-Overrun HTML Documents

These instructions apply to **every HTML document created in this project** that will be printed or saved as a PDF. Follow all rules before writing a single line of code, and complete the full pre-delivery checklist before presenting the first draft.

---

## PART 1 — MANDATORY PAGE SETUP

### 1.1 Base CSS — Include This in Every Print Document

```css
/* ── PRINT PAGE FOUNDATION ── */
@page {
  size: 8.5in 11in;
  margin: 1in 1in 1in 1in;   /* top right bottom left */
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  width: 8.5in;
}

body {
  width: 6.5in;          /* 8.5in minus 2× 1in margin */
  margin: 0 auto;
  font-size: 12pt;
  line-height: 1.5;
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}
```

### 1.2 Never Use These Properties in Print Documents

| ❌ Forbidden | ✅ Safe Alternative |
|---|---|
| `height: Xin / Xpx` on containers | Let content determine height |
| `min-height: Xin` on containers | Use `padding` instead |
| `overflow: hidden` without `overflow-wrap` | Add `overflow-wrap: break-word` |
| `position: fixed` | Use `position: relative` or static |
| `vh` / `vw` units | Use `in`, `pt`, `%` of body width |
| `flex` / `grid` rows that don't wrap | Always add `flex-wrap: wrap` |
| `white-space: nowrap` on variable content | Remove or scope tightly |
| Absolute pixel heights on table rows | Let rows grow naturally |

---

## PART 2 — CONTENT DENSITY RULES

### 2.1 Usable Page Space Budget

```
Page height:         11.00 in
Top margin:          -1.00 in
Bottom margin:       -1.00 in
Safe usable height:   9.00 in  ← NEVER EXCEED PER PAGE
```

If a document has multiple pages, **each page** has exactly 9.00 in of usable height. Account for:
- Page headers/footers (deduct from 9.00 in per page they appear on)
- Section titles and spacing
- Table/chart height estimates
- Block padding and margins accumulate — add them up

### 2.2 Typography Budget (Approximate Line Heights)

| Font Size | Line Height | Lines per Page |
|---|---|---|
| 10pt | 1.4 | ~82 lines |
| 11pt | 1.4 | ~74 lines |
| 12pt | 1.5 | ~64 lines |
| 14pt | 1.5 | ~55 lines |

Use these to gut-check paragraph density before finalizing.

### 2.3 Tables

- Never set explicit `height` on `<tr>` or `<td>`
- Always add `page-break-inside: avoid` to rows that must stay together
- Use `table-layout: fixed` with `width: 100%` on the `<table>` tag
- Constrain column widths in `%` that sum to ≤ 100%
- Long tables **must** use `<thead>` so headers repeat across pages

```css
table       { width: 100%; table-layout: fixed; border-collapse: collapse; }
thead       { display: table-header-group; }   /* repeat on each page */
tr          { page-break-inside: avoid; }
td, th      { word-wrap: break-word; overflow-wrap: break-word; padding: 6pt 8pt; }
```

### 2.4 Images and Charts

- Always set `max-width: 100%` and **never** set a pixel height that could exceed the page
- For full-width images: `width: 6.5in; max-width: 100%; height: auto;`
- If an image is tall, add `page-break-before: auto` so it flows to the next page cleanly
- SVG charts: set `viewBox` and `width="100%"` — never hardcode `height` in inches

---

## PART 3 — PAGE BREAK CONTROL

### 3.1 Required Rules for Multi-Section Documents

```css
/* Keep headings with their content */
h1, h2, h3, h4 {
  page-break-after: avoid;
}

/* Prevent orphaned first lines */
p {
  orphans: 3;
  widows: 3;
}

/* Sections that must not break mid-element */
.no-break {
  page-break-inside: avoid;
}

/* Force a new page before major sections */
.page-break-before {
  page-break-before: always;
}
```

### 3.2 When to Force Page Breaks

- Any section you know is visually "full" → add a `<div class="page-break-before">` wrapper
- Signature blocks, summary boxes, certification statements → always `page-break-inside: avoid`
- Cover pages → always followed by `page-break-before: always` on the next section

---

## PART 4 — THE PRE-DELIVERY CHECKLIST

**Before presenting the first draft, verify every item below. Do not skip any step.**

### ☐ Step 1 — Audit Every Height Declaration
Search the generated CSS for: `height`, `min-height`, `max-height`.  
For each match: ask *"Can this element's content grow beyond this value?"*  
If yes → remove the height constraint or convert to `padding`.

### ☐ Step 2 — Calculate Total Content Height
Mentally (or literally) add up the heights of every block in body order:
- Title block + padding
- Each section heading + its margin
- Each paragraph (estimate lines × line-height)
- Each table (rows × approximate row height)
- Each image (fixed height or max-width derived height)
- Decorative spacing / horizontal rules

If total exceeds 9.00 in, either:
- Split into multiple pages with explicit breaks, OR
- Reduce font size, padding, or content

### ☐ Step 3 — Check All Tables
- ✔ `table-layout: fixed` present?
- ✔ Column widths sum to ≤ 100%?
- ✔ No explicit `height` on `<tr>` or `<td>`?
- ✔ `<thead>` present for tables > ~8 rows?
- ✔ `overflow-wrap: break-word` on cells?

### ☐ Step 4 — Check All Images and SVGs
- ✔ Every image has `max-width: 100%`?
- ✔ No hardcoded pixel `height` that could push content off-page?
- ✔ SVG `viewBox` set, `width="100%"`, no hardcoded inch height?

### ☐ Step 5 — Check for Forbidden Units
Scan CSS for `vh`, `vw`, `fixed`, `100vh`. Remove or replace all occurrences.

### ☐ Step 6 — Verify @page Rule Is Present
The `@page { size: 8.5in 11in; margin: 1in; }` block must appear in the `<style>` tag.

### ☐ Step 7 — Simulate Each Page Visually
Walk through the document section by section, asking:  
*"If this were printed right now, does page [N] end before 9 inches of content?"*  
If uncertain, add a forced page break — it is always better to have one extra page than one overrun.

### ☐ Step 8 — Final Smell Test
Read the full HTML output aloud in your head as a sequence of printed pages.  
Any block that "feels" dense or long → measure it against the 9-inch budget again.

---

## PART 5 — QUICK-START TEMPLATE

Use this shell for every new print document:

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document Title</title>
  <style>
    @page {
      size: 8.5in 11in;
      margin: 1in;
    }
    *, *::before, *::after { box-sizing: border-box; }
    html { width: 8.5in; }
    body {
      width: 6.5in;
      margin: 0 auto;
      font-family: Georgia, 'Times New Roman', serif;
      font-size: 12pt;
      line-height: 1.5;
      color: #111;
      -webkit-print-color-adjust: exact;
      print-color-adjust: exact;
    }
    h1 { font-size: 20pt; page-break-after: avoid; margin-bottom: 12pt; }
    h2 { font-size: 15pt; page-break-after: avoid; margin-top: 18pt; margin-bottom: 8pt; }
    h3 { font-size: 13pt; page-break-after: avoid; margin-top: 14pt; margin-bottom: 6pt; }
    p  { margin: 0 0 10pt; orphans: 3; widows: 3; }
    table {
      width: 100%;
      table-layout: fixed;
      border-collapse: collapse;
      margin-bottom: 14pt;
    }
    thead { display: table-header-group; }
    tr    { page-break-inside: avoid; }
    td, th {
      padding: 6pt 8pt;
      border: 1px solid #ccc;
      word-wrap: break-word;
      overflow-wrap: break-word;
      vertical-align: top;
    }
    img {
      max-width: 100%;
      height: auto;
      display: block;
    }
    .no-break        { page-break-inside: avoid; }
    .page-break      { page-break-before: always; }
    .section         { margin-bottom: 20pt; }
  </style>
</head>
<body>

  <!-- PAGE 1 CONTENT HERE -->
  <!-- Use <div class="page-break"> to start a new page -->

</body>
</html>
```

---

## PART 6 — COMMON FAILURE PATTERNS TO ACTIVELY AVOID

| Pattern | Why It Overruns | Fix |
|---|---|---|
| Wrapper div with `height: 9in` containing dynamic content | Content taller than 9in gets clipped or overflows | Remove height; use page breaks |
| Table with many rows and no `page-break-inside` | Long row bleeds across page boundary | Add `tr { page-break-inside: avoid }` |
| Flexbox row of cards with fixed card height | Cards overflow their container when content is long | Use `align-items: flex-start`, no fixed height |
| Section heading at bottom of page with content on next | Heading orphaned from its body | `h2 { page-break-after: avoid }` |
| Background color div with `min-height` | Looks fine on screen, pushes following content off page | Replace with padding only |
| Logo/image set in `px` taller than ~200px | Eats into the 9-inch budget unexpectedly | Use `max-height: 1in` or `height: auto` |
| Footer set with `position: fixed; bottom: 0` | Overlaps bottom content on every page | Use `position: relative` or `@page` margin box |

---

*Place this file in any project folder where print-quality HTML documents will be created. Reference it at the start of every document generation task.*
