resume-forge / static /index.html
aka38's picture
Upload 5 files
f226eb6 verified
Raw
History Blame Contribute Delete
19.4 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="ResumeForge — AI-powered resume tailoring with PDF preview.">
<title>ResumeForge — AI Resume Tailoring</title>
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<nav id="navbar">
<div class="nav-brand">
<svg class="nav-logo" viewBox="0 0 32 32" fill="none">
<rect width="32" height="32" rx="8" fill="url(#lg)"/>
<path d="M8 22V10l8 6-8 6zm8-6l8-6v12l-8-6z" fill="white" opacity="0.9"/>
<defs><linearGradient id="lg" x1="0" y1="0" x2="32" y2="32">
<stop stop-color="#6366f1"/><stop offset="1" stop-color="#3b82f6"/>
</linearGradient></defs>
</svg>
<span class="nav-title">ResumeForge</span>
<span class="nav-badge">V2</span>
</div>
<div class="nav-steps">
<div class="step active" data-step="1"><span class="step-number">1</span><span class="step-label">Upload</span></div>
<div class="step-connector"></div>
<div class="step" data-step="2"><span class="step-number">2</span><span class="step-label">Review</span></div>
<div class="step-connector"></div>
<div class="step" data-step="3"><span class="step-number">3</span><span class="step-label">Export</span></div>
</div>
<div class="nav-spacer" style="display: flex; justify-content: flex-end; align-items: center;">
<button id="btn-change-key" class="btn btn-outline btn-small" title="Change API Key">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/></svg>
API Key
</button>
</div>
</nav>
<!-- ══════════ Stage 1: Upload & Preview ══════════ -->
<main id="stage-input" class="stage active">
<div class="input-layout">
<!-- Left: Upload + JD -->
<div class="input-left">
<div class="input-panel">
<div class="panel-header">
<div class="panel-icon resume-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14,2 14,8 20,8"/></svg></div>
<div><h2 class="panel-title">LaTeX Resume</h2><p class="panel-subtitle">Upload your .tex file</p></div>
</div>
<div id="drop-zone" class="drop-zone">
<div class="drop-zone-content">
<svg class="drop-icon" viewBox="0 0 48 48" fill="none"><circle cx="24" cy="24" r="23" stroke="currentColor" stroke-width="1" stroke-dasharray="4 4" opacity="0.4"/><path d="M24 16v16M16 24h16" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
<p class="drop-text">Drag & drop your <strong>.tex</strong> file</p>
<p class="drop-subtext">or</p>
<button id="btn-browse" class="btn btn-outline btn-small">Browse Files</button>
<input type="file" id="file-input" accept=".tex,.latex,.txt" hidden>
</div>
</div>
<div id="resume-file-info" class="file-info hidden">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14,2 14,8 20,8"/></svg>
<span id="file-name">resume.tex</span>
<button id="btn-remove-file" class="btn-icon" title="Remove"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
</div>
<div class="input-panel">
<div class="panel-header">
<div class="panel-icon jd-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 21V5a2 2 0 00-2-2h-4a2 2 0 00-2 2v16"/></svg></div>
<div><h2 class="panel-title">Job Description</h2><p class="panel-subtitle">Paste the job posting</p></div>
</div>
<div class="textarea-wrapper">
<textarea id="jd-input" class="jd-textarea" placeholder="Paste the full job description here..."></textarea>
</div>
</div>
<div class="input-panel" style="margin-top: 1.5rem;">
<div class="panel-header">
<div class="panel-icon jd-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg></div>
<div><h2 class="panel-title">Additional Instructions</h2><p class="panel-subtitle">Custom instructions for the AI</p></div>
</div>
<div class="textarea-wrapper" style="height: 100px;">
<textarea id="instructions-input" class="jd-textarea" placeholder="E.g., Focus on my leadership experience..."></textarea>
</div>
</div>
</div>
<!-- Right: PDF Preview -->
<div class="input-right">
<div class="pdf-panel">
<div class="pdf-panel-header">
<h3 class="pdf-panel-title">PDF Preview</h3>
<div id="pdf-compile-status" class="compile-status hidden">
<div class="mini-spinner"></div>
<span>Compiling...</span>
</div>
</div>
<div id="pdf-preview-container" class="pdf-container">
<div id="pdf-placeholder" class="pdf-placeholder">
<svg viewBox="0 0 64 64" fill="none" stroke="currentColor" stroke-width="1.5" opacity="0.3"><rect x="12" y="4" width="40" height="56" rx="4"/><line x1="20" y1="18" x2="44" y2="18"/><line x1="20" y1="26" x2="40" y2="26"/><line x1="20" y1="34" x2="44" y2="34"/><line x1="20" y1="42" x2="36" y2="42"/></svg>
<p>Upload a .tex file to see the PDF preview</p>
</div>
<canvas id="pdf-canvas" class="pdf-canvas hidden"></canvas>
</div>
</div>
</div>
</div>
<div class="action-bar">
<button id="btn-load-sample" class="btn btn-ghost"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14,2 14,8 20,8"/></svg> Load Sample</button>
<button id="btn-analyze" class="btn btn-primary btn-large" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="20" height="20"><polygon points="13,2 3,14 12,14 11,22 21,10 12,10"/></svg> Analyze & Suggest Edits</button>
</div>
</main>
<!-- Loading Overlay -->
<div id="loading-overlay" class="loading-overlay hidden">
<div class="loading-card">
<div class="loading-spinner"><div class="spinner-ring"></div></div>
<h3 class="loading-title">Analyzing Your Resume</h3>
<p class="loading-subtitle" id="loading-status">Gemini is reviewing your resume against the job description...</p>
<div class="loading-dots"><span></span><span></span><span></span></div>
</div>
</div>
<!-- ══════════ Stage 2: Review ══════════ -->
<main id="stage-review" class="stage">
<div class="review-layout">
<!-- Left: PDF -->
<div class="review-pdf-pane">
<div class="pdf-panel">
<div class="pdf-panel-header">
<h3 class="pdf-panel-title">Original Resume</h3>
</div>
<div class="pdf-container review-pdf-container">
<canvas id="review-pdf-canvas" class="pdf-canvas"></canvas>
</div>
</div>
</div>
<!-- Right: Analysis + Edits -->
<div class="review-edits-pane">
<!-- Score + Summary -->
<div class="review-summary-bar">
<div class="score-mini">
<span id="score-before" class="score-num">0</span>
<svg viewBox="0 0 24 24" fill="none" width="16" height="16"><path d="M5 12h14m-4-4l4 4-4 4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
<span id="score-after" class="score-num score-green">0</span>
<span class="score-unit">match</span>
</div>
<div class="keyword-pills" id="keyword-pills"></div>
</div>
<p id="analysis-summary" class="analysis-summary-text"></p>
<!-- Edit Controls -->
<div class="edit-controls">
<h3 class="edits-title">Suggested Edits <span id="edit-count" class="edit-count">0</span></h3>
<div class="edit-controls-right">
<button id="btn-select-all" class="btn btn-outline btn-small">All</button>
<button id="btn-deselect-all" class="btn btn-outline btn-small">None</button>
</div>
</div>
<!-- Edit Cards -->
<div id="edits-container" class="edits-container"></div>
</div>
</div>
<div class="action-bar">
<button id="btn-back-input" class="btn btn-ghost"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18"><line x1="19" y1="12" x2="5" y2="12"/><polyline points="12,19 5,12 12,5"/></svg> Back</button>
<button id="btn-apply" class="btn btn-primary btn-large"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="20" height="20"><polyline points="20,6 9,17 4,12"/></svg> Apply <span id="selected-count">0</span> Edits & Compile PDF</button>
</div>
</main>
<!-- ══════════ Stage 3: Export ══════════ -->
<main id="stage-export" class="stage">
<div class="export-layout">
<div class="export-pdf-pane">
<div class="pdf-panel">
<div class="pdf-panel-header" style="justify-content: flex-start; gap: 1rem;">
<button id="btn-compile-preview" class="btn btn-primary btn-small hidden" style="padding: 4px 12px; font-size: 0.8rem; margin-right: auto;">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><polygon points="5 3 19 12 5 21 5 3"/></svg>
Compile
</button>
<h3 class="pdf-panel-title" id="export-pdf-title" style="margin-right: auto;">Tailored Resume</h3>
<div class="export-success-badge" id="export-success-badge">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" width="14" height="14"><polyline points="20,6 9,17 4,12"/></svg>
Updated
</div>
</div>
<div class="pdf-container export-pdf-container">
<canvas id="export-pdf-canvas" class="pdf-canvas"></canvas>
</div>
</div>
</div>
<div class="export-actions-pane" style="align-items: flex-start;">
<div class="export-card" id="main-export-card" style="margin: auto;">
<div class="export-card-icon">
<svg viewBox="0 0 48 48" fill="none"><circle cx="24" cy="24" r="22" stroke="currentColor" stroke-width="2"/><polyline points="14,24 22,32 34,16" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>
<h2 class="export-card-title">Resume Tailored!</h2>
<p class="export-card-sub">Your resume has been updated and compiled.</p>
<div class="export-buttons">
<button id="btn-download-pdf" class="btn btn-primary btn-large export-btn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="20" height="20"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="7,10 12,15 17,10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
Download PDF
</button>
<button id="btn-download-tex" class="btn btn-outline btn-large export-btn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="20" height="20"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14,2 14,8 20,8"/></svg>
Download .tex
</button>
</div>
<div class="export-actions-secondary">
<button id="btn-edit-source" class="btn btn-outline btn-large export-btn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg>
Edit Source
</button>
<button id="btn-copy-tex" class="btn btn-ghost btn-large export-btn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg>
Copy
</button>
</div>
<div class="export-footer-actions" style="margin-top: 1.5rem; display: flex; gap: 1rem; justify-content: center;">
<button id="btn-iterate-ai" class="btn btn-ghost start-over-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg> Iterate with AI</button>
<button id="btn-start-over" class="btn btn-ghost start-over-btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><polyline points="1,4 1,10 7,10"/><path d="M3.51 15a9 9 0 105.32-12.36L1 10"/></svg> Start Over</button>
</div>
</div>
<div id="manual-edit-card" class="export-card hidden" style="display: flex; flex-direction: column; max-width: 100%; width: 500px; text-align: left; margin: 0; padding: 20px;">
<div class="edit-card-header" style="justify-content: space-between; margin-bottom: 1rem;">
<h2 class="export-card-title" style="margin:0; font-size: 1.25rem;">Manual LaTeX Edit</h2>
<button id="btn-done-editing" class="btn btn-ghost btn-small"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><polyline points="20 6 9 17 4 12"/></svg> Done</button>
</div>
<textarea id="manual-latex-editor" style="width: 100%; height: 500px; min-height: 200px; font-family: monospace; font-size: 0.85rem; padding: 1rem; resize: both; border: 1px solid var(--border-subtle); background: var(--bg-surface); color: var(--text-primary); border-radius: var(--radius-md); margin-bottom: 0; outline: none; line-height: 1.5;"></textarea>
</div>
</div>
</div>
</main>
<!-- API Key Modal -->
<div id="key-modal" class="modal-overlay hidden">
<div class="modal-card" style="position: relative;">
<button id="btn-close-modal" class="btn-icon" style="position: absolute; top: 16px; right: 16px;"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
<div class="modal-icon"><svg viewBox="0 0 48 48" fill="none"><circle cx="24" cy="24" r="22" stroke="currentColor" stroke-width="2" opacity="0.3"/><path d="M24 14v8m0 4v2m-8-6h16" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg></div>
<h3 class="modal-title">Gemini API Key Required</h3>
<p class="modal-subtitle">Enter your free API key from <a href="https://ai.google.dev" target="_blank" rel="noopener">ai.google.dev</a></p>
<div class="modal-input-wrapper"><input type="password" id="api-key-input" class="modal-input" placeholder="AIza..." autocomplete="off"></div>
<div class="modal-actions"><button id="btn-save-key" class="btn btn-primary btn-large" style="width:100%">Save & Continue</button></div>
<p class="modal-note">Your key stays local — never sent anywhere except Google's API.</p>
</div>
</div>
<!-- Toast -->
<div id="toast" class="toast hidden">
<div class="toast-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg></div>
<p id="toast-message" class="toast-message"></p>
<button id="toast-close" class="btn-icon toast-close"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<!-- PDF.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
<script>pdfjsLib.GlobalWorkerOptions.workerSrc='https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';</script>
<script src="/static/app.js"></script>
</body>
</html>