Spaces:
Runtime error
Runtime error
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>Resume Ranker API – Instantly Score Resumes with AI</title> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet"> | |
| <style> | |
| :root { | |
| --primary: #2563eb; | |
| --primary-light: #60a5fa; | |
| --accent: #14b8a6; | |
| --bg: #f8fafc; | |
| --bg-dark: #18181b; | |
| --text: #1e293b; | |
| --text-light: #f1f5f9; | |
| --card: #fff; | |
| --card-dark: #23272f; | |
| --border: #e5e7eb; | |
| --border-dark: #2d3340; | |
| --transition: 0.3s cubic-bezier(.4,0,.2,1); | |
| } | |
| [data-theme="dark"] { | |
| --bg: var(--bg-dark); | |
| --text: var(--text-light); | |
| --card: var(--card-dark); | |
| --border: var(--border-dark); | |
| } | |
| html, body { | |
| margin: 0; | |
| padding: 0; | |
| font-family: 'Inter', sans-serif; | |
| background: var(--bg); | |
| color: var(--text); | |
| transition: background var(--transition), color var(--transition); | |
| } | |
| a { color: var(--primary); text-decoration: none; transition: color var(--transition); } | |
| a:hover { color: var(--accent); } | |
| .container { max-width: 1100px; margin: 0 auto; padding: 0 1.5rem; } | |
| header { | |
| display: flex; align-items: center; justify-content: space-between; | |
| padding: 2rem 0 1.5rem 0; | |
| } | |
| .logo { | |
| font-weight: 700; font-size: 1.5rem; letter-spacing: -1px; | |
| color: var(--primary); | |
| } | |
| .nav-links { | |
| display: flex; gap: 2rem; | |
| } | |
| .nav-links a { font-weight: 500; } | |
| .theme-toggle { | |
| background: none; border: none; cursor: pointer; font-size: 1.3rem; | |
| color: var(--text); margin-left: 1.5rem; transition: color var(--transition); | |
| } | |
| /* Hero */ | |
| .hero { | |
| text-align: center; padding: 4rem 0 3rem 0; | |
| } | |
| .hero h1 { | |
| font-size: 2.7rem; font-weight: 700; margin-bottom: 1rem; | |
| letter-spacing: -1px; | |
| } | |
| .hero p { | |
| font-size: 1.25rem; color: var(--text); margin-bottom: 2.5rem; | |
| max-width: 600px; margin-left: auto; margin-right: auto; | |
| } | |
| .cta-btns { | |
| display: flex; justify-content: center; gap: 1.2rem; | |
| } | |
| .cta-primary, .cta-secondary { | |
| padding: 0.85rem 2.2rem; border-radius: 0.5rem; font-size: 1.1rem; | |
| font-weight: 600; border: none; cursor: pointer; transition: background var(--transition), color var(--transition), box-shadow var(--transition); | |
| } | |
| .cta-primary { | |
| background: var(--primary); color: #fff; box-shadow: 0 2px 12px 0 rgba(37,99,235,0.08); | |
| } | |
| .cta-primary:hover { background: var(--accent); } | |
| .cta-secondary { | |
| background: transparent; color: var(--primary); border: 2px solid var(--primary); | |
| } | |
| .cta-secondary:hover { background: var(--primary-light); color: #fff; } | |
| /* How It Works */ | |
| .section { | |
| padding: 3.5rem 0 2.5rem 0; | |
| } | |
| .section-title { | |
| font-size: 2rem; font-weight: 700; text-align: center; margin-bottom: 2.2rem; | |
| } | |
| .steps { | |
| display: flex; flex-wrap: wrap; justify-content: center; gap: 2.5rem; | |
| margin-bottom: 2.5rem; | |
| } | |
| .step { | |
| background: var(--card); border: 1px solid var(--border); border-radius: 1rem; | |
| padding: 2rem 1.5rem; width: 260px; box-shadow: 0 2px 8px 0 rgba(30,41,59,0.04); | |
| text-align: center; transition: background var(--transition), border var(--transition); | |
| } | |
| .step-icon { | |
| font-size: 2.2rem; margin-bottom: 1rem; color: var(--primary); | |
| } | |
| .step-title { font-weight: 600; font-size: 1.1rem; margin-bottom: 0.5rem; } | |
| .step-desc { color: #64748b; font-size: 1rem; } | |
| [data-theme="dark"] .step-desc { color: #cbd5e1; } | |
| .code-demo { | |
| background: #0f172a; color: #f1f5f9; border-radius: 0.7rem; | |
| padding: 1.2rem 1rem; font-size: 0.98rem; font-family: 'Fira Mono', 'Consolas', monospace; | |
| margin: 0 auto 1.5rem auto; max-width: 600px; overflow-x: auto; | |
| box-shadow: 0 2px 8px 0 rgba(20,184,166,0.08); | |
| transition: background var(--transition), color var(--transition); | |
| } | |
| [data-theme="dark"] .code-demo { background: #1e293b; color: #e0e7ef; } | |
| /* Live Demo */ | |
| .demo-box { | |
| background: var(--card); border: 1px solid var(--border); border-radius: 1rem; | |
| padding: 2rem 1.5rem; max-width: 600px; margin: 0 auto 2rem auto; | |
| box-shadow: 0 2px 8px 0 rgba(20,184,166,0.06); | |
| transition: background var(--transition), border var(--transition); | |
| } | |
| .demo-inputs { display: flex; flex-direction: column; gap: 1rem; margin-bottom: 1.2rem; } | |
| .demo-inputs textarea { | |
| width: 100%; min-height: 60px; border-radius: 0.5rem; border: 1px solid var(--border); | |
| padding: 0.7rem; font-size: 1rem; font-family: inherit; resize: vertical; | |
| background: var(--bg); color: var(--text); transition: background var(--transition), color var(--transition), border var(--transition); | |
| } | |
| .demo-btn { | |
| background: var(--primary); color: #fff; border: none; border-radius: 0.5rem; | |
| padding: 0.7rem 1.5rem; font-size: 1rem; font-weight: 600; cursor: pointer; | |
| transition: background var(--transition); | |
| } | |
| .demo-btn:hover { background: var(--accent); } | |
| .demo-output { | |
| background: #f1f5f9; color: #334155; border-radius: 0.5rem; padding: 1rem; font-size: 0.98rem; | |
| margin-top: 1rem; font-family: 'Fira Mono', 'Consolas', monospace; white-space: pre-wrap; | |
| transition: background var(--transition), color var(--transition); | |
| } | |
| [data-theme="dark"] .demo-output { background: #23272f; color: #e0e7ef; } | |
| /* Docs Teaser */ | |
| .code-snippets { | |
| display: flex; flex-wrap: wrap; gap: 1.5rem; justify-content: center; margin-bottom: 1.5rem; | |
| } | |
| .snippet { | |
| background: var(--card); border: 1px solid var(--border); border-radius: 0.7rem; | |
| padding: 1rem 1rem; font-size: 0.97rem; font-family: 'Fira Mono', 'Consolas', monospace; | |
| min-width: 220px; max-width: 320px; box-shadow: 0 2px 8px 0 rgba(37,99,235,0.04); | |
| transition: background var(--transition), border var(--transition); | |
| } | |
| .snippet-title { font-weight: 600; font-size: 1rem; margin-bottom: 0.5rem; color: var(--primary); } | |
| /* Use Cases */ | |
| .use-cases { | |
| display: flex; flex-wrap: wrap; gap: 1.5rem; justify-content: center; | |
| margin-bottom: 2rem; | |
| } | |
| .use-case { | |
| background: var(--card); border: 1px solid var(--border); border-radius: 0.7rem; | |
| padding: 1.2rem 1.2rem; min-width: 180px; max-width: 240px; text-align: center; | |
| box-shadow: 0 2px 8px 0 rgba(20,184,166,0.04); | |
| font-weight: 500; font-size: 1.05rem; | |
| transition: background var(--transition), border var(--transition); | |
| } | |
| /* Pricing */ | |
| .pricing { | |
| display: flex; flex-wrap: wrap; gap: 2rem; justify-content: center; margin-bottom: 2rem; | |
| } | |
| .plan { | |
| background: var(--card); border: 1px solid var(--border); border-radius: 0.7rem; | |
| padding: 2rem 1.5rem; min-width: 220px; max-width: 300px; text-align: center; | |
| box-shadow: 0 2px 8px 0 rgba(37,99,235,0.04); | |
| transition: background var(--transition), border var(--transition); | |
| } | |
| .plan-title { font-weight: 700; font-size: 1.2rem; margin-bottom: 0.5rem; } | |
| .plan-price { font-size: 2rem; font-weight: 700; color: var(--primary); margin-bottom: 0.5rem; } | |
| .plan-desc { color: #64748b; font-size: 1rem; margin-bottom: 1rem; } | |
| [data-theme="dark"] .plan-desc { color: #cbd5e1; } | |
| /* Testimonials */ | |
| .testimonials { | |
| display: flex; flex-wrap: wrap; gap: 2rem; justify-content: center; margin-bottom: 2rem; | |
| } | |
| .testimonial { | |
| background: var(--card); border: 1px solid var(--border); border-radius: 0.7rem; | |
| padding: 1.5rem 1.2rem; min-width: 220px; max-width: 320px; text-align: center; | |
| box-shadow: 0 2px 8px 0 rgba(20,184,166,0.04); | |
| font-size: 1rem; font-style: italic; | |
| transition: background var(--transition), border var(--transition); | |
| } | |
| .testimonial-logo { | |
| width: 80px; height: 32px; background: #e0e7ef; border-radius: 0.3rem; margin: 0 auto 0.7rem auto; | |
| display: flex; align-items: center; justify-content: center; color: #64748b; font-weight: 700; font-size: 1.1rem; | |
| } | |
| [data-theme="dark"] .testimonial-logo { background: #23272f; color: #cbd5e1; } | |
| /* CTA Footer */ | |
| .cta-footer { | |
| background: var(--primary); color: #fff; text-align: center; padding: 2.5rem 1rem 2rem 1rem; | |
| border-radius: 1rem; margin: 2rem auto 2rem auto; max-width: 900px; | |
| box-shadow: 0 2px 12px 0 rgba(37,99,235,0.10); | |
| } | |
| .cta-footer h2 { font-size: 2rem; font-weight: 700; margin-bottom: 1rem; } | |
| .cta-footer .cta-btns { margin-top: 1.2rem; } | |
| /* Footer */ | |
| footer { | |
| text-align: center; color: #64748b; font-size: 0.98rem; padding: 2rem 0 1.2rem 0; | |
| } | |
| .footer-links { display: flex; gap: 1.5rem; justify-content: center; margin-bottom: 0.7rem; flex-wrap: wrap; } | |
| .footer-links a { color: inherit; font-weight: 500; } | |
| @media (max-width: 900px) { | |
| .steps, .code-snippets, .use-cases, .pricing, .testimonials { flex-direction: column; align-items: center; } | |
| .container { padding: 0 0.5rem; } | |
| } | |
| .sticky-header { | |
| position: sticky; | |
| top: 0; | |
| z-index: 100; | |
| background: var(--bg); | |
| transition: background var(--transition); | |
| box-shadow: 0 2px 8px 0 rgba(30,41,59,0.04); | |
| } | |
| .hamburger { | |
| display: none; | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| width: 40px; | |
| height: 40px; | |
| background: none; | |
| border: none; | |
| cursor: pointer; | |
| margin-left: 1rem; | |
| z-index: 110; | |
| } | |
| .hamburger span { | |
| display: block; | |
| width: 24px; | |
| height: 3px; | |
| margin: 3px 0; | |
| background: var(--text); | |
| border-radius: 2px; | |
| transition: all 0.3s; | |
| } | |
| @media (max-width: 900px) { | |
| .nav-links { | |
| position: fixed; | |
| top: 70px; | |
| right: 0; | |
| background: var(--card); | |
| flex-direction: column; | |
| align-items: flex-start; | |
| gap: 1.5rem; | |
| padding: 2rem 2rem 2rem 1.5rem; | |
| box-shadow: 0 4px 24px 0 rgba(30,41,59,0.10); | |
| border-radius: 0 0 0.7rem 0.7rem; | |
| transform: translateY(-120%); | |
| opacity: 0; | |
| pointer-events: none; | |
| transition: transform 0.3s, opacity 0.3s; | |
| min-width: 60vw; | |
| } | |
| .nav-links.open { | |
| transform: translateY(0); | |
| opacity: 1; | |
| pointer-events: auto; | |
| } | |
| .hamburger { | |
| display: flex; | |
| } | |
| .logo { | |
| z-index: 120; | |
| } | |
| .theme-toggle { | |
| z-index: 120; | |
| margin-left: 0.5rem; | |
| } | |
| } | |
| @media (max-width: 600px) { | |
| .nav-links { | |
| top: 60px; | |
| padding: 1.2rem 1.2rem 1.2rem 1rem; | |
| min-width: 80vw; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <header class="container sticky-header"> | |
| <div class="logo">ResumeRanker<span style="color:var(--accent)">.API</span></div> | |
| <nav class="nav-links" id="navLinks"> | |
| <a href="#how">How it works</a> | |
| <a href="#demo">Live Demo</a> | |
| <a href="#docs">Docs</a> | |
| <a href="#pricing">Pricing</a> | |
| <a href="{{ url_for('auth.login') }}">Login</a> | |
| </nav> | |
| <button class="theme-toggle" id="themeToggle" aria-label="Toggle dark mode">🌙</button> | |
| <button class="hamburger" id="hamburger" aria-label="Open menu"> | |
| <span></span><span></span><span></span> | |
| </button> | |
| </header> | |
| <!-- Hero Section --> | |
| <section class="hero"> | |
| <h1>Rank Resumes Instantly with AI</h1> | |
| <p>Send resumes + job description, and get smart, ranked results in seconds via API.</p> | |
| <div class="cta-btns"> | |
| <a href="{{ url_for('auth.login') }}"> | |
| <button class="cta-primary">Get Your API Key</button> | |
| </a> | |
| <a href="#demo"> | |
| <button class="cta-secondary">See Live Demo</button> | |
| </a> | |
| </div> | |
| </section> | |
| <!-- How It Works --> | |
| <section class="section" id="how"> | |
| <div class="section-title">How It Works</div> | |
| <div class="steps"> | |
| <div class="step"> | |
| <div class="step-icon">📄</div> | |
| <div class="step-title">1. Upload Resumes</div> | |
| <div class="step-desc">Send one or more resumes (PDF, DOCX, or text) to the API.</div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-icon">📝</div> | |
| <div class="step-title">2. Pass Job Description</div> | |
| <div class="step-desc">Include the job description for the role you're hiring for.</div> | |
| </div> | |
| <div class="step"> | |
| <div class="step-icon">⚡</div> | |
| <div class="step-title">3. Get Ranked Results</div> | |
| <div class="step-desc">Receive a ranked JSON array of candidates, scored by fit.</div> | |
| </div> | |
| </div> | |
| <div class="code-demo"> | |
| <span style="color:#60a5fa">POST</span> /api/rank | |
| <br>{ | |
| <br> "resumes": ["<b>PDF/Doc/Text</b>"], | |
| <br> "job_description": "<b>string</b>" | |
| <br>} | |
| <br><span style="color:#14b8a6">// → Response:</span> | |
| <br>[ | |
| <br> { "name": "Jane Doe", "score": 92, "summary": "Excellent fit for Data Scientist" }, | |
| <br> { "name": "John Smith", "score": 78, "summary": "Good match, missing Python" } | |
| <br>] | |
| </div> | |
| </section> | |
| <!-- Live Demo Preview --> | |
| <section class="section" id="demo"> | |
| <div class="section-title">Live Demo Preview</div> | |
| <div class="demo-box"> | |
| <form id="demoForm" autocomplete="off"> | |
| <div class="demo-inputs"> | |
| <textarea id="demoResumes" placeholder="Paste 1-2 sample resumes here (text only)"></textarea> | |
| <textarea id="demoJob" placeholder="Paste job description here"></textarea> | |
| </div> | |
| <button type="submit" class="demo-btn">Rank Resumes</button> | |
| </form> | |
| <div class="demo-output" id="demoOutput" style="display:none;"></div> | |
| </div> | |
| </section> | |
| <!-- Developer Docs Teaser --> | |
| <section class="section" id="docs"> | |
| <div class="section-title">Easy API Integration</div> | |
| <div class="code-snippets"> | |
| <div class="snippet"> | |
| <div class="snippet-title">cURL</div> | |
| curl -X POST https://api.resumeranker.com/rank \ | |
| <br> -H "Authorization: Bearer <API_KEY>" \ | |
| <br> -d '{"resumes": ["..."], "job_description": "..."}' | |
| </div> | |
| <div class="snippet"> | |
| <div class="snippet-title">Python</div> | |
| import requests<br> | |
| resp = requests.post( | |
| <br> "https://api.resumeranker.com/rank", | |
| <br> headers={"Authorization": "Bearer <API_KEY>"}, | |
| <br> json={"resumes": ["..."], "job_description": "..."} | |
| <br>) | |
| <br>print(resp.json()) | |
| </div> | |
| <div class="snippet"> | |
| <div class="snippet-title">Node.js</div> | |
| fetch("https://api.resumeranker.com/rank", { | |
| <br> method: "POST", | |
| <br> headers: { "Authorization": "Bearer <API_KEY>", "Content-Type": "application/json" }, | |
| <br> body: JSON.stringify({ resumes: ["..."], job_description: "..." }) | |
| <br>}) | |
| <br>.then(res => res.json()) | |
| <br>.then(console.log) | |
| </div> | |
| </div> | |
| <div style="text-align:center; margin-bottom:1.5rem;"> | |
| <a href="#" class="cta-secondary" style="padding:0.6rem 1.5rem; font-size:1rem;">View Full API Docs →</a> | |
| </div> | |
| </section> | |
| <!-- Use Cases --> | |
| <section class="section" id="use-cases"> | |
| <div class="section-title">Use Cases</div> | |
| <div class="use-cases"> | |
| <div class="use-case">Applicant Tracking Systems</div> | |
| <div class="use-case">Job Boards</div> | |
| <div class="use-case">Recruiting Agencies</div> | |
| <div class="use-case">Career Services Platforms</div> | |
| </div> | |
| </section> | |
| <!-- Pricing Preview --> | |
| <section class="section" id="pricing"> | |
| <div class="section-title">Pricing</div> | |
| <div class="pricing"> | |
| <div class="plan"> | |
| <div class="plan-title">Free Tier</div> | |
| <div class="plan-price">$0</div> | |
| <div class="plan-desc">100 resume rankings/month<br>Community support</div> | |
| <a href="#signup" class="cta-primary" style="display:inline-block; margin-top:0.7rem;">Start Free</a> | |
| </div> | |
| <div class="plan"> | |
| <div class="plan-title">Pro</div> | |
| <div class="plan-price">$49/mo</div> | |
| <div class="plan-desc">10,000 resume rankings/month<br>Email support</div> | |
| <a href="#signup" class="cta-secondary" style="display:inline-block; margin-top:0.7rem;">Get Started</a> | |
| </div> | |
| <div class="plan"> | |
| <div class="plan-title">Enterprise</div> | |
| <div class="plan-price">Custom</div> | |
| <div class="plan-desc">Unlimited usage<br>Dedicated support & SLAs</div> | |
| <a href="#contact" class="cta-secondary" style="display:inline-block; margin-top:0.7rem;">Contact Us</a> | |
| </div> | |
| </div> | |
| <div style="text-align:center; color:#64748b; font-size:1rem; margin-top:1rem;">*Pricing subject to change. More plans coming soon.</div> | |
| </section> | |
| <!-- Testimonials / Trusted By --> | |
| <section class="section" id="testimonials"> | |
| <div class="section-title">Trusted by Innovators</div> | |
| <div class="testimonials"> | |
| <div class="testimonial"> | |
| <div class="testimonial-logo">Jobly</div> | |
| "ResumeRanker API made our candidate screening 10x faster." | |
| </div> | |
| <div class="testimonial"> | |
| <div class="testimonial-logo">HireFlow</div> | |
| "Seamless integration and great support!" | |
| </div> | |
| <div class="testimonial"> | |
| <div class="testimonial-logo">TalentPro</div> | |
| "Our recruiters love the instant scoring." | |
| </div> | |
| </div> | |
| </section> | |
| <!-- CTA Footer --> | |
| <section class="cta-footer"> | |
| <h2>Start ranking resumes in 2 minutes</h2> | |
| <div class="cta-btns"> | |
| <a href="#signup"><button class="cta-primary">Sign Up</button></a> | |
| <a href="#login"><button class="cta-secondary">Login</button></a> | |
| </div> | |
| </section> | |
| <!-- Footer --> | |
| <footer> | |
| <div class="footer-links"> | |
| <a href="#docs">Docs</a> | |
| <a href="#">GitHub</a> | |
| <a href="#">Support</a> | |
| <a href="#">Terms</a> | |
| <a href="#">Privacy</a> | |
| </div> | |
| <div>© 2024 ResumeRanker API. All rights reserved.</div> | |
| </footer> | |
| <script> | |
| // Light/Dark mode toggle | |
| const themeToggle = document.getElementById('themeToggle'); | |
| const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; | |
| function setTheme(theme) { | |
| document.documentElement.setAttribute('data-theme', theme); | |
| localStorage.setItem('theme', theme); | |
| themeToggle.textContent = theme === 'dark' ? '☀️' : '🌙'; | |
| } | |
| const savedTheme = localStorage.getItem('theme'); | |
| setTheme(savedTheme || (prefersDark ? 'dark' : 'light')); | |
| themeToggle.onclick = () => { | |
| const current = document.documentElement.getAttribute('data-theme'); | |
| setTheme(current === 'dark' ? 'light' : 'dark'); | |
| }; | |
| // Live Demo (mocked) | |
| document.getElementById('demoForm').onsubmit = function(e) { | |
| e.preventDefault(); | |
| const resumes = document.getElementById('demoResumes').value.trim(); | |
| const job = document.getElementById('demoJob').value.trim(); | |
| const output = document.getElementById('demoOutput'); | |
| if (!resumes || !job) { | |
| output.style.display = 'block'; | |
| output.textContent = 'Please provide both resumes and a job description.'; | |
| return; | |
| } | |
| output.style.display = 'block'; | |
| output.textContent = 'Ranking...'; | |
| setTimeout(() => { | |
| output.textContent = JSON.stringify([ | |
| { name: "Jane Doe", score: 92, summary: "Excellent fit for Data Scientist" }, | |
| { name: "John Smith", score: 78, summary: "Good match, missing Python" } | |
| ], null, 2); | |
| }, 900); | |
| }; | |
| // Hamburger menu toggle | |
| const hamburger = document.getElementById('hamburger'); | |
| const navLinks = document.getElementById('navLinks'); | |
| hamburger.onclick = function() { | |
| navLinks.classList.toggle('open'); | |
| hamburger.classList.toggle('open'); | |
| }; | |
| // Close menu when clicking a link (on mobile) | |
| Array.from(navLinks.getElementsByTagName('a')).forEach(link => { | |
| link.onclick = () => { | |
| if (window.innerWidth <= 900) { | |
| navLinks.classList.remove('open'); | |
| hamburger.classList.remove('open'); | |
| } | |
| }; | |
| }); | |
| </script> | |
| </body> | |
| </html> | |