From 72b7602e8e66417740f640c090f0da69ae59c406 Mon Sep 17 00:00:00 2001 From: JohannVelazquez Date: Tue, 30 Jun 2026 12:42:45 -0600 Subject: [PATCH] =?UTF-8?q?Bit=C3=A1cora=208=E2=80=9330=20jun:=20contrato?= =?UTF-8?q?=20firmado,=20plan=20de=20actividades=20y=20skill=20proposal-pd?= =?UTF-8?q?f?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Comunicaciones (REGISTRO #15–#21): respuesta v1.1 (10-jun), luz verde (16-jun), contrato (envío 25-jun, ajustes + firma 26-jun), arranque con Erika y kickoff 1-jul - Evidencia en fuentes/ (correos 8/10/16-jun, WhatsApp Paola y Erika) - Contratos (sin firmar y firmado) en propuesta/ - Plan de actividades Etapa 0–3 + guion del kickoff (planeacion/) - Skill proposal-pdf instalado (.claude/skills) + Propuesta-Balam.pdf regenerada - README/PENDIENTES al día; limpieza de archivos sueltos; .gitignore (locks de Office) Co-Authored-By: Claude Opus 4.8 --- .claude/skills/proposal-pdf/SKILL.md | 228 ++++++ .../assets/fonts/Caladea-Bold.ttf | Bin 0 -> 84492 bytes .../assets/fonts/Caladea-BoldItalic.ttf | Bin 0 -> 83356 bytes .../assets/fonts/Caladea-Italic.ttf | Bin 0 -> 83780 bytes .../assets/fonts/Caladea-Regular.ttf | Bin 0 -> 81600 bytes .../assets/fonts/Carlito-Bold.ttf | Bin 0 -> 682468 bytes .../assets/fonts/Carlito-BoldItalic.ttf | Bin 0 -> 808508 bytes .../assets/fonts/Carlito-Italic.ttf | Bin 0 -> 615236 bytes .../assets/fonts/Carlito-Regular.ttf | Bin 0 -> 628032 bytes .../assets/fonts/DejaVuSansMono.ttf | Bin 0 -> 340712 bytes .../assets/pdf.config.example.json | 43 ++ .../skills/proposal-pdf/assets/template.html | 366 ++++++++++ .../proposal-pdf/assets/test.config.json | 15 + .../examples/example-a4.config.json | 31 + .../proposal-pdf/examples/example-a4.html | 362 ++++++++++ .../skills/proposal-pdf/scripts/build_pdf.py | 459 ++++++++++++ .../proposal-pdf/scripts/render_check.py | 55 ++ .gitignore | 12 + README.md | 37 +- bitacora/PENDIENTES.md | 41 +- bitacora/REGISTRO.md | 192 ++++- ...- Correo - Noe aclaraciones y preguntas.md | 27 + ...-06-10 - Correo - Johann respuesta v1.1.md | 27 + ...eo - Noe luz verde y documento de firma.md | 15 + ... Paola (RH) ajustes y firma de contrato.md | 38 + ... Erika arranque del plan de actividades.md | 26 + planeacion/Kickoff-2026-07-01.md | 47 ++ planeacion/Plan-actividades.md | 69 ++ planeacion/Plan-actividades.xlsx | Bin 0 -> 12267 bytes propuesta/00 - PROPUESTA-COMERCIAL.md | 40 +- ...nales__Johann_Joseph_Velazquez_Antonio.pdf | Bin 0 -> 59124 bytes ...nales__Johann_Joseph_Velazquez_Antonio.pdf | Bin 0 -> 84681 bytes propuesta/Propuesta-Balam.html | 673 ++++++++++++++++++ propuesta/Propuesta-Balam.pdf | Bin 2546419 -> 2214917 bytes propuesta/fonts/Caladea-Bold.ttf | Bin 0 -> 84492 bytes propuesta/fonts/Caladea-BoldItalic.ttf | Bin 0 -> 83356 bytes propuesta/fonts/Caladea-Italic.ttf | Bin 0 -> 83780 bytes propuesta/fonts/Caladea-Regular.ttf | Bin 0 -> 81600 bytes propuesta/fonts/Carlito-Bold.ttf | Bin 0 -> 682468 bytes propuesta/fonts/Carlito-BoldItalic.ttf | Bin 0 -> 808508 bytes propuesta/fonts/Carlito-Italic.ttf | Bin 0 -> 615236 bytes propuesta/fonts/Carlito-Regular.ttf | Bin 0 -> 628032 bytes propuesta/fonts/DejaVuSansMono.ttf | Bin 0 -> 340712 bytes propuesta/pdf.config.json | 48 ++ 44 files changed, 2789 insertions(+), 62 deletions(-) create mode 100644 .claude/skills/proposal-pdf/SKILL.md create mode 100644 .claude/skills/proposal-pdf/assets/fonts/Caladea-Bold.ttf create mode 100644 .claude/skills/proposal-pdf/assets/fonts/Caladea-BoldItalic.ttf create mode 100644 .claude/skills/proposal-pdf/assets/fonts/Caladea-Italic.ttf create mode 100644 .claude/skills/proposal-pdf/assets/fonts/Caladea-Regular.ttf create mode 100644 .claude/skills/proposal-pdf/assets/fonts/Carlito-Bold.ttf create mode 100644 .claude/skills/proposal-pdf/assets/fonts/Carlito-BoldItalic.ttf create mode 100644 .claude/skills/proposal-pdf/assets/fonts/Carlito-Italic.ttf create mode 100644 .claude/skills/proposal-pdf/assets/fonts/Carlito-Regular.ttf create mode 100644 .claude/skills/proposal-pdf/assets/fonts/DejaVuSansMono.ttf create mode 100644 .claude/skills/proposal-pdf/assets/pdf.config.example.json create mode 100644 .claude/skills/proposal-pdf/assets/template.html create mode 100644 .claude/skills/proposal-pdf/assets/test.config.json create mode 100644 .claude/skills/proposal-pdf/examples/example-a4.config.json create mode 100644 .claude/skills/proposal-pdf/examples/example-a4.html create mode 100644 .claude/skills/proposal-pdf/scripts/build_pdf.py create mode 100644 .claude/skills/proposal-pdf/scripts/render_check.py create mode 100644 fuentes/2026-06-08 - Correo - Noe aclaraciones y preguntas.md create mode 100644 fuentes/2026-06-10 - Correo - Johann respuesta v1.1.md create mode 100644 fuentes/2026-06-16 - Correo - Noe luz verde y documento de firma.md create mode 100644 fuentes/2026-06-26 - WhatsApp - Paola (RH) ajustes y firma de contrato.md create mode 100644 fuentes/2026-06-29 - WhatsApp - Erika arranque del plan de actividades.md create mode 100644 planeacion/Kickoff-2026-07-01.md create mode 100644 planeacion/Plan-actividades.md create mode 100644 planeacion/Plan-actividades.xlsx create mode 100644 propuesta/2026_06-25_12-13__Contrato_de_servicios_profesionales__Johann_Joseph_Velazquez_Antonio.pdf create mode 100644 propuesta/2026_06-26_14-19__Contrato_de_servicios_profesionales__Johann_Joseph_Velazquez_Antonio.pdf create mode 100644 propuesta/Propuesta-Balam.html create mode 100644 propuesta/fonts/Caladea-Bold.ttf create mode 100644 propuesta/fonts/Caladea-BoldItalic.ttf create mode 100644 propuesta/fonts/Caladea-Italic.ttf create mode 100644 propuesta/fonts/Caladea-Regular.ttf create mode 100644 propuesta/fonts/Carlito-Bold.ttf create mode 100644 propuesta/fonts/Carlito-BoldItalic.ttf create mode 100644 propuesta/fonts/Carlito-Italic.ttf create mode 100644 propuesta/fonts/Carlito-Regular.ttf create mode 100644 propuesta/fonts/DejaVuSansMono.ttf create mode 100644 propuesta/pdf.config.json diff --git a/.claude/skills/proposal-pdf/SKILL.md b/.claude/skills/proposal-pdf/SKILL.md new file mode 100644 index 0000000..fd398e0 --- /dev/null +++ b/.claude/skills/proposal-pdf/SKILL.md @@ -0,0 +1,228 @@ +--- +name: proposal-pdf +description: >- + Build polished, print-optimized PDF proposals, quotes, and reports with an + editorial design system (navy + terracotta, serif display headings, full-bleed + cover, auto-numbered table of contents, stamped confidential footers). Use this + skill WHENEVER the user wants a professional/branded PDF deliverable from + content — e.g. "make this proposal a PDF", "generate a commercial proposal / + cotización / propuesta", "turn this into a nice client-facing PDF", "build a + quote/report PDF", or any request for a high-quality multi-page PDF document + that needs a cover, table of contents, tables, or page numbers. Prefer this + over ad-hoc HTML-to-PDF or reportlab-from-scratch whenever presentation quality + matters. Works in Spanish or English. +--- + +# proposal-pdf + +Produces a refined, print-ready PDF from hand-authored HTML using headless +Chromium, with an automatically numbered table of contents and stamped footers. +This is the same pipeline used to build real commercial proposals — it favors +typographic quality over speed. + +## Why this approach + +Tools like `reportlab`-from-scratch or `pandoc` give you a document but not a +*designed* one. This skill instead has you author one print-optimized HTML file +against a ready-made design system, then renders it with Chromium (which has the +best CSS print engine available). Two things that are otherwise painful are +handled for you: + +- **Full-bleed cover** — a dark cover that runs edge-to-edge, via `@page:first { margin:0 }`. +- **Real TOC page numbers** — resolved in a second render pass by searching the + rendered PDF, so they're always correct regardless of how content paginates. + +## Setup (once) + +```bash +pip install playwright pdfplumber pypdf reportlab +python -m playwright install chromium +``` + +### Fonts — bundled and embedded (no system install needed) + +The design uses **Caladea** (serif display), **Carlito** (sans body) and +**DejaVu Sans Mono** (code). These ship with the skill in `assets/fonts/`, and +`template.html` embeds them with `@font-face` rules that point at a `fonts/` +folder **next to the HTML**. The output therefore does not depend on which fonts +happen to be installed on the build machine. Rules of the road: + +- When you copy `template.html` to your working file, **also copy `assets/fonts/` + next to it** so the `url("fonts/…")` paths resolve. `build_pdf.py` renders each + document from its own folder, so relative paths (fonts, logos, images) just work. +- If the fonts are missing at build time, Chromium silently falls back to system + fonts (Cambria/Calibri/…) — it looks *close* but isn't identical. After building, + `build_pdf.py` inspects the finished PDF and **prints a warning** if Caladea or + Carlito didn't embed, so that regression can't ship unnoticed. +- Caladea/Carlito are *metric-compatible* with Cambria/Calibri: swapping them + changes the glyph shapes but **not** the pagination. So if a rebuild has a + different page count than an older PDF, the **content** changed — not the fonts. + +The footer text is stamped separately with a TTF set in the config +(`fonts.footer_ttf`); if that path doesn't exist it falls back to Helvetica. + +### En este proyecto (Windows / Balam) + +El skill ya está instalado en `.claude/skills/proposal-pdf/`. Para usarlo aquí: + +```powershell +# 1) Dependencias (una vez) +pip install playwright pdfplumber pypdf reportlab +python -m playwright install chromium + +# 2) Construir (desde la raíz del repo) +python .claude/skills/proposal-pdf/scripts/build_pdf.py /pdf.config.json --check # valida +python .claude/skills/proposal-pdf/scripts/build_pdf.py /pdf.config.json # construye +``` + +- **Fuentes:** las fuentes del diseño (Caladea/Carlito/DejaVu Sans Mono) van **embebidas** vía `@font-face` desde `propuesta/fonts/`, así que el PDF sale idéntico sin depender de lo que tenga instalado Windows. No instales nada. Para el **texto del footer** (que se estampa aparte con reportlab) sí se usa una TTF del sistema: `fonts.footer_ttf` apunta a `C:\Windows\Fonts\calibri.ttf`. Si al reconstruir ves el aviso `⚠ design font(s) missing`, es que la carpeta `fonts/` no quedó junto al HTML. +- **Verificación visual:** en este entorno **no hay `pdftoppm`/poppler**, así que el paso "verify visually" se hace con el helper incluido, que usa `pypdfium2` (ya viene con `pdfplumber`): + ```powershell + python .claude/skills/proposal-pdf/scripts/render_check.py /Salida.pdf 1 2 3 # rasteriza páginas a PNG + ``` + Luego abre los PNG (o pídeme que los lea). Siempre revisa: portada full-bleed, números de TOC presentes y plausibles, tablas que no se desborden, y que el footer aparezca en el cuerpo pero **no** en la portada. +- **Consola UTF-8:** el script ya fuerza salida UTF-8 (la consola de Windows es cp1252 y truena con los glifos ✓/⚠). No necesitas hacer nada. + +## Files in this skill + +``` +proposal-pdf/ +├── SKILL.md +├── scripts/ +│ └── build_pdf.py # the render → number → stamp engine +├── assets/ +│ ├── template.html # the design system + every component, with examples +│ ├── fonts/ # bundled design fonts (Caladea, Carlito, DejaVu Sans Mono) +│ ├── pdf.config.example.json # the full config schema (documented) +│ └── test.config.json # smoke test for the template +└── examples/ # a second, complete worked example + ├── example-a4.html # A4 + cover logo + a long page-spanning table + └── example-a4.config.json # shows A4, "X / N" footer, skip_pages +``` + +Smoke-test the install end-to-end: +```bash +python3 scripts/build_pdf.py assets/test.config.json # Letter template +python3 scripts/build_pdf.py examples/example-a4.config.json # A4 worked example +``` + +## Workflow + +### 1. Author the content as HTML + +Copy `assets/template.html` to a working file (e.g. `proposal.html`) and replace +the example content with the real content. **Keep the CSS and the component +markup/classes** — that's the design system. The big in-file comment and the +component cheat-sheet at the top of the template tell you which class does what. +Common building blocks: numbered section headers (`.sec-head` + `.sec-num`), +tables with `td.k` / `td.num` / `tr.total` / `tr.sub-total` / `td.cov`, accent +panels (`.callout`, `.callout.cool`), a pipeline diagram (`.flow` + `.chip`), +headline stat cards (`.synthesis` + `.stat`), and phase blocks (`.etapa`). + +For each section that appears in the table of contents: +- put a `{{PG_}}` token in its TOC row (already wired in the template), and +- remember a **unique phrase from that section's body** (see step 2). + +Appendices/new-page sections get the `.break` class to start on a fresh page. + +### 2. Write the config + +Copy `assets/pdf.config.example.json` to `pdf.config.json` (next to your HTML) +and fill it in. The important part is the `toc` map: each key matches a +`{{PG_}}` token, and its value is a phrase the engine will search for to +find that section's page. + +> **Anchor rules — read this, it prevents the two failure modes:** +> 1. **Use BODY text, never the section title.** Titles also render in the TOC, +> so a title would match the TOC page first and give the wrong number. +> 2. **Don't start the anchor on the first letter of a drop-cap paragraph.** The +> CSS drop cap splits the first letter into its own glyph, so the extracted +> text reads `"T his…"`. Start the anchor a word or two in +> (e.g. `"opening paragraph…"`, not `"This opening paragraph…"`). +> +> Good anchor: the first ~6–10 words of the first normal paragraph after the +> heading. Keep it distinctive. + +### 3. Build + +```bash +python scripts/build_pdf.py pdf.config.json --check # validate config + env first (optional) +python scripts/build_pdf.py pdf.config.json # build +``` + +`--check` runs a **preflight**: confirms the deps and Chromium are installed, the +input HTML exists, and — importantly — that every `{{PG_*}}` token in the HTML +has a matching anchor in `toc` (and warns about anchors with no token). Fix any +reported issue before building. + +The build renders once with tokens blanked, prints the resolved page numbers, +fills the TOC, re-renders, stamps footers, sets metadata, and writes the PDF. If +an anchor can't be found it stops and tells you exactly which one. If an anchor +matches more than one page it warns and uses the first — make it more specific if +that's wrong. + +### 4. ALWAYS verify visually + +Rendering bugs are visual, so look at the result. Rasterize a few pages and +inspect them (don't just trust that it ran): + +```bash +pdftoppm -png -r 80 -f 1 -l 1 Output.pdf check_cover # full-bleed cover +pdftoppm -png -r 80 -f 2 -l 2 Output.pdf check_toc # TOC page numbers filled +# …and a content page or two +``` + +Check: the cover fills the page edge-to-edge, the TOC numbers are present and +plausible, tables don't overflow, and the footer shows on body pages but not the +cover. Re-author and rebuild as needed — iteration is normal. + +## Customizing + +- **Colors / fonts:** edit the `:root` CSS variables in your HTML (`--ink`, + `--accent`, `--cream`, the font stacks). One accent color used sparingly reads + as more premium than many. +- **Page size:** set `"page_size"` to `"Letter"`, `"Legal"`, `"A4"`, `"A3"`, or a + custom `{"width_mm":210,"height_mm":297}`. The engine derives the footer + geometry automatically — you do **not** edit the script. For A4/A3 also change + `@page { size:Letter }` to the matching size in the HTML CSS (there's a comment + there). See `examples/example-a4.html` for a full A4 document. +- **Cover logo:** drop a `