# The CV Reformatter

**Live version:** recruitergtm-cv.vercel.app. Open it before you build, so you know what you are aiming at.

**Where to run it:** Claude Code, or the Claude app with a project folder.

**You do not need this file.** Everything below the line is the prompt, and it is the same text that is on the slide. Copy it from either.

---

You are building me a mini app called the CV Reformatter. One HTML file, runs in the browser.
No database, no login, no server, no API key. Candidate CVs must never leave my machine, and that
requirement decides the architecture, so do not propose an upload or a backend at any point.

The job: I get CVs in twelve different layouts. I put one in and get back a one-page profile in my
branding that I can send to a client the same minute.

STAGE 0 - READ WHAT I ALREADY HAVE. Look for brand.json in this folder and use my colours, logo and
font. If it is missing, ask me for my agency name, my hex colour, my logo filename and my font, then
write brand.json yourself so the next app I build does not ask me again.

STAGE 1 - BUILD IT. One index.html, CSS and JS inline. Two columns.

  LEFT, the controls.
    A drop zone that takes PDF, .docx and .txt, by dropping or by browsing. Use pdf.js and mammoth.js
    from cdnjs. Both read the file in the browser. Show me the filename and the word count once it has
    read it, and a plain error if it cannot: an old .doc needs saving as .docx, and a scanned PDF has
    no text in it to find, so say that rather than failing silently.
    A box to paste into instead, which the file fills when I use one.
    My branding: colour picker and agency name, pre-filled from brand.json. A logo upload read in the
    browser. A reference field for speculative sends.
    Two switches. Redact the candidate, which removes the name, email and phone and puts the reference
    in their place. Tidy the bullets, which strips stray dashes and symbols and capitalises each line.
    Three buttons: Download as PDF, Copy as text, Load a sample.

  RIGHT, the profile, live, updating as I type. On white, in my colours. Name and title at the top, my
  logo top right, a coloured rule under the header. Then the sections it found, in this order: Profile,
  Experience, Education, Skills, Certifications. Job titles with their dates in bold on their own line,
  achievements as bullets under them. Skills as small rounded chips, never a paragraph. Footer with my
  agency name and today's date.

STAGE 2 - THE PARSING, WHICH IS THE HARD PART AND WHERE THIS WILL GO WRONG.
  Email and phone by pattern match. The name is the first short line with no digits and no @ in it.
  The title is the next line that qualifies after the name.
  Split into sections on heading lines and match the variants: Profile, Professional Summary, About and
  Personal Statement are one section, and so are Experience, Work Experience, Employment History and
  Career History.
  Within a section, a line is a job title if it is short and contains a year, a month or the word
  Present. Everything else is a bullet.
  READING A PDF: pdf.js gives you text items with x, y and width, not lines. Group items by their y to
  rebuild each line, then join them left to right, and only insert a space where there is a real
  horizontal gap between the end of one item and the start of the next. Join them with a space every
  time and ligatures come out broken: "qualified" becomes "quali fi ed" and "finance" becomes
  "fi nance". Test that specific case before you tell me it works.
  Found no headings at all: do not fail and do not show an empty page. Put every line under one heading
  and tell me on screen that it found no standard headings.
  Above the preview, show what it found, for example "Found: Profile, Experience, Education, Skills",
  so I can see whether the parse worked before I send anything to a client.

STAGE 3 - THE RULES YOU DO NOT BREAK.
  Nothing leaves the browser. No fetch of the CV, no upload, no analytics.
  Never invent, smooth over or rewrite what the CV says. Reformatting is the job. Changing the claims
  is fraud, and it is my licence on the line, not yours.
  A missing field means the line comes out. Never fill a gap with something plausible.
  The redact switch has to actually remove the name, email and phone from the output, not hide them
  with CSS where anyone can read them in the page source.

STAGE 4 - PROVE IT WORKS. Put a realistic sample CV behind the Load a sample button, using an invented
person. Then test it yourself against four layouts: one with clean headings, one in all caps, one with
no headings at all, and one with the contact details at the bottom instead of the top. Make a PDF and a
.docx and run both through. Fix what breaks. Only then show me, and tell me which of the four it
handles worst and why.

STAGE 5 - PUT IT ONLINE. Walk me through Vercel one step at a time, waiting after each: free account,
npm i -g vercel, vercel from this folder, then vercel --prod. Confirm the address opens in a browser.
If it asks for a login, deployment protection is on, so tell me where to switch it off. Then ask
whether I want it public, as a free tool on my own site that candidates and clients can use, or private
to my team, and set up whichever I pick.
