# /html-report - Generate Application Tracker Dashboard
Generate a self-contained HTML dashboard from `job_search_tracker.csv` and the application archives under `documents/applications/`. The output is a single `.html` file — no server, no dependencies — that can be opened directly in a browser.
## Step 0: Parse Arguments
- No argument → output to `reports/application-dashboard.html`
- A path argument (e.g. `/html-report ~/Desktop/report.html`) → use that path
- `--open` flag → after writing, tell the user to open the file (cannot open a browser directly)
Create `reports/` if it does not exist.
---
## Step 1: Collect Data
Read in parallel:
1. **`job_search_tracker.csv`** — the primary source. Parse every row into a record with fields:
`date`, `company`, `sector`, `role`, `role_type`, `channel`, `status`, `contact_person`, `fit_rating`, `notes`, `cv_file`, `cover_letter_file`, `source`
2. **`documents/applications/*/outcome.md`** — for each resolved application, read the outcome file to get the exact interview stages reached (the checkboxes) and any notes. Merge this into the matching tracker row by company+role fuzzy match (lowercase, ignore punctuation). If an archive exists for a row but there is no match, attach it as extra context anyway.
Status normalisation — map tracker values to five canonical buckets before computing stats:
- `applied` → **Active** (resume submitted, no further signal)
- `interview` → **Interview**
- `offer` → **Offer**
- `hired` → **Hired**
- `rejected` / `no_response` / `no response` / `offer_declined` / `interview_only` / `withdrawn` → **Rejected/Closed**
---
## Step 2: Compute Summary Stats
From the normalised data compute:
- **Total applications**
- **By status bucket:** count per bucket
- **By sector:** count per unique sector value
- **By channel:** online vs referral vs other
- **By year/season:** group by the `date` field (which may be a year like `2025` or a full date)
- **Funnel rates:** what % progressed past resume screen (reached Interview or beyond)
- **Rejection rate:** Rejected/Closed ÷ Total with a resolved status (exclude Active)
---
## Step 3: Generate the HTML
Write a single self-contained HTML file. All CSS is inline in a `