<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>ResumeCraft · Smart & Simple Resume Builder</title>

    <style>

        /* ===== SIMPLE, NATURAL, PROFESSIONAL PALETTE ===== */

        :root {

            --blue-deep: #1a365d;

            --blue-mid: #2b5a8a;

            --blue-soft: #d4e4f7;

            --blue-pale: #eef5fc;

            --orange-warm: #e67e22;

            --orange-soft: #fdebd0;

            --orange-light: #fff5eb;

            --text-dark: #1a2b3c;

            --text-mid: #3b5a7a;

            --text-soft: #6b8299;

            --white: #ffffff;

            --shadow-sm: 0 2px 8px rgba(26, 54, 93, 0.06);

            --shadow-md: 0 8px 24px -6px rgba(26, 54, 93, 0.14);

            --shadow-lg: 0 24px 48px -16px rgba(26, 54, 93, 0.22);

            --radius: 18px;

            --radius-sm: 12px;

            --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

        }


        * {

            margin: 0;

            padding: 0;

            box-sizing: border-box;

        }


        body {

            background: linear-gradient(135deg, #fdebd0 0%, #eef5fc 45%, #d4e4f7 100%);

            font-family: var(--font);

            min-height: 100vh;

            display: flex;

            align-items: center;

            justify-content: center;

            padding: 1.8rem;

            line-height: 1.55;

            color: var(--text-dark);

            -webkit-font-smoothing: antialiased;

        }


        /* ===== MAIN CARD ===== */

        .tool-card {

            max-width: 1300px;

            width: 100%;

            background: rgba(255, 255, 255, 0.88);

            backdrop-filter: blur(18px);

            -webkit-backdrop-filter: blur(18px);

            border-radius: var(--radius);

            padding: 2.2rem 2.4rem;

            box-shadow: var(--shadow-lg), 0 0 0 1px rgba(255, 255, 255, 0.6);

            border: 1px solid rgba(255, 255, 255, 0.5);

        }


        /* ===== HEADER ===== */

        .header {

            display: flex;

            align-items: center;

            justify-content: space-between;

            margin-bottom: 2rem;

            padding-bottom: 1.2rem;

            border-bottom: 2px solid var(--blue-soft);

        }


        .header-left {

            display: flex;

            align-items: center;

            gap: 14px;

        }


        .logo-mark {

            width: 50px;

            height: 50px;

            background: linear-gradient(145deg, var(--blue-mid), var(--blue-deep));

            color: #fff;

            border-radius: 14px;

            display: flex;

            align-items: center;

            justify-content: center;

            font-size: 1.6rem;

            font-weight: 700;

            box-shadow: 0 8px 18px -6px rgba(43, 90, 138, 0.45);

            transition: transform 0.25s ease;

        }


        .logo-mark:hover {

            transform: rotate(-4deg) scale(1.03);

        }


        .header-left h1 {

            font-size: 1.7rem;

            font-weight: 800;

            letter-spacing: -0.025em;

            color: var(--blue-deep);

            line-height: 1.15;

        }


        .header-left .tagline {

            font-size: 0.78rem;

            font-weight: 500;

            color: var(--text-soft);

            letter-spacing: 0.3px;

            display: flex;

            align-items: center;

            gap: 6px;

        }


        .dot-green {

            width: 7px;

            height: 7px;

            background: #27ae60;

            border-radius: 50%;

            display: inline-block;

            animation: pulse 2s infinite;

        }


        @keyframes pulse {

            0% { opacity: 0.6; transform: scale(1); }

            50% { opacity: 1; transform: scale(1.15); }

            100% { opacity: 0.6; transform: scale(1); }

        }


        .header-badge {

            background: var(--orange-soft);

            color: #a85c1a;

            font-size: 0.72rem;

            font-weight: 700;

            padding: 0.4rem 1.1rem;

            border-radius: 60px;

            letter-spacing: 0.3px;

            text-transform: uppercase;

            border: 1px solid rgba(255, 255, 255, 0.8);

            display: flex;

            align-items: center;

            gap: 7px;

            box-shadow: var(--shadow-sm);

        }


        .header-badge .badge-dot {

            width: 7px;

            height: 7px;

            background: var(--orange-warm);

            border-radius: 50%;

            display: inline-block;

        }


        /* ===== TWO COLUMN LAYOUT ===== */

        .main-grid {

            display: grid;

            grid-template-columns: 1fr 1.75fr;

            gap: 2rem;

            align-items: start;

        }


        /* ===== LEFT: FORM PANEL ===== */

        .form-panel {

            background: var(--white);

            border-radius: var(--radius-sm);

            padding: 1.8rem 1.6rem;

            border: 1px solid var(--blue-soft);

            box-shadow: var(--shadow-sm);

        }


        .form-panel h2 {

            font-size: 1.1rem;

            font-weight: 700;

            color: var(--blue-deep);

            margin-bottom: 1.4rem;

            display: flex;

            align-items: center;

            gap: 8px;

            padding-bottom: 0.6rem;

            border-bottom: 2px dashed var(--blue-soft);

        }


        .form-panel h2 span {

            background: var(--orange-warm);

            color: #fff;

            width: 26px;

            height: 26px;

            border-radius: 8px;

            display: inline-flex;

            align-items: center;

            justify-content: center;

            font-size: 0.8rem;

            font-weight: 700;

        }


        .field {

            margin-bottom: 1.2rem;

        }


        .field label {

            display: block;

            font-size: 0.72rem;

            font-weight: 700;

            text-transform: uppercase;

            letter-spacing: 0.06em;

            color: var(--text-mid);

            margin-bottom: 0.4rem;

        }


        .field input,

        .field textarea {

            width: 100%;

            padding: 0.8rem 1rem;

            font-family: var(--font);

            font-size: 0.92rem;

            background: var(--blue-pale);

            border: 1.5px solid var(--blue-soft);

            border-radius: 10px;

            transition: all 0.2s ease;

            color: var(--text-dark);

            resize: vertical;

        }


        .field input:focus,

        .field textarea:focus {

            outline: none;

            border-color: var(--blue-mid);

            background: #fff;

            box-shadow: 0 0 0 4px rgba(43, 90, 138, 0.1);

        }


        .field textarea {

            min-height: 75px;

            line-height: 1.5;

        }


        /* ===== ACTION BUTTONS ===== */

        .action-group {

            display: flex;

            flex-direction: column;

            gap: 0.7rem;

            margin-top: 1.6rem;

        }


        .btn {

            width: 100%;

            padding: 0.9rem 1.3rem;

            border: none;

            border-radius: 12px;

            font-weight: 600;

            font-size: 0.9rem;

            font-family: var(--font);

            display: flex;

            align-items: center;

            justify-content: center;

            gap: 9px;

            cursor: pointer;

            transition: all 0.2s ease;

            letter-spacing: 0.2px;

        }


        .btn-primary {

            background: var(--blue-mid);

            color: #fff;

            box-shadow: 0 8px 18px -6px rgba(43, 90, 138, 0.45);

            border: 1px solid rgba(255, 255, 255, 0.1);

        }


        .btn-primary:hover {

            background: #1e4a73;

            transform: translateY(-2px);

            box-shadow: 0 12px 22px -8px rgba(43, 90, 138, 0.55);

        }


        .btn-primary:active {

            transform: translateY(1px);

        }


        .btn-download {

            background: var(--orange-warm);

            color: #fff;

            box-shadow: 0 8px 18px -6px rgba(230, 126, 34, 0.45);

            border: 1px solid rgba(255, 255, 255, 0.15);

        }


        .btn-download:hover {

            background: #c96a2e;

            transform: translateY(-2px);

            box-shadow: 0 12px 22px -8px rgba(230, 126, 34, 0.55);

        }


        .btn-download:active {

            transform: translateY(1px);

        }


        .btn .icon {

            font-size: 1.1rem;

            line-height: 1;

        }


        .hint {

            font-size: 0.7rem;

            color: var(--text-soft);

            text-align: center;

            margin-top: 0.2rem;

        }


        /* ===== RIGHT: RESUME PREVIEW ===== */

        .preview-panel {

            background: var(--white);

            border-radius: var(--radius-sm);

            padding: 2rem 2.2rem;

            border: 1px solid var(--blue-soft);

            box-shadow: var(--shadow-md);

            position: relative;

            overflow: hidden;

            min-height: 540px;

        }


        /* subtle decorative watermark */

        .preview-panel::after {

            content: "📄";

            position: absolute;

            right: -10px;

            bottom: -20px;

            font-size: 10rem;

            opacity: 0.025;

            transform: rotate(-12deg);

            pointer-events: none;

        }


        .resume-content {

            position: relative;

            z-index: 2;

        }


        /* ===== RESUME HEADER ===== */

        .resume-header {

            display: flex;

            flex-wrap: wrap;

            justify-content: space-between;

            align-items: flex-start;

            border-bottom: 3px solid var(--orange-soft);

            padding-bottom: 1.2rem;

            margin-bottom: 1.5rem;

        }


        .resume-name-block {

            flex: 2;

            min-width: 180px;

        }


        .resume-name {

            font-size: 2.1rem;

            font-weight: 800;

            color: var(--blue-deep);

            line-height: 1.2;

            word-break: break-word;

            letter-spacing: -0.025em;

        }


        .resume-title {

            font-size: 1rem;

            font-weight: 600;

            color: var(--blue-mid);

            background: var(--blue-soft);

            display: inline-block;

            padding: 0.25rem 1rem;

            border-radius: 40px;

            margin-top: 0.4rem;

            letter-spacing: 0.2px;

        }


        .resume-contact {

            flex: 1;

            min-width: 170px;

            text-align: right;

            font-size: 0.85rem;

            color: var(--text-mid);

            line-height: 1.8;

            background: var(--blue-pale);

            padding: 0.7rem 1rem;

            border-radius: 12px;

            border: 1px solid var(--blue-soft);

        }


        .resume-contact span {

            display: flex;

            align-items: center;

            justify-content: flex-end;

            gap: 6px;

        }


        /* ===== RESUME SECTIONS ===== */

        .resume-section {

            margin-top: 1.5rem;

        }


        .section-title {

            font-size: 0.78rem;

            font-weight: 800;

            text-transform: uppercase;

            letter-spacing: 0.1em;

            color: var(--blue-deep);

            display: flex;

            align-items: center;

            gap: 10px;

            margin-bottom: 0.9rem;

            background: linear-gradient(to right, var(--orange-light), transparent);

            padding: 0.3rem 0 0.3rem 0.9rem;

            border-left: 5px solid var(--orange-warm);

            border-radius: 0 30px 30px 0;

        }


        .resume-summary {

            font-size: 0.94rem;

            color: var(--text-dark);

            line-height: 1.7;

            background: var(--blue-pale);

            padding: 1rem 1.2rem;

            border-radius: 12px;

            white-space: pre-wrap;

            word-break: break-word;

            border: 1px solid var(--blue-soft);

        }


        .skills-container {

            display: flex;

            flex-wrap: wrap;

            gap: 0.6rem;

            margin-top: 0.3rem;

        }


        .skill-badge {

            background: var(--blue-pale);

            color: var(--text-mid);

            padding: 0.35rem 1rem;

            border-radius: 30px;

            font-size: 0.8rem;

            font-weight: 600;

            border: 1px solid var(--blue-soft);

            transition: all 0.15s ease;

        }


        .skill-badge:hover {

            background: var(--blue-soft);

            transform: translateY(-1px);

        }


        .empty-message {

            color: var(--text-soft);

            font-style: italic;

            font-size: 0.9rem;

            background: var(--blue-pale);

            padding: 0.7rem 1rem;

            border-radius: 10px;

            border: 1px dashed var(--blue-soft);

        }


        /* ===== ANIMATION ===== */

        .preview-updated {

            animation: fadeIn 0.35s ease-out;

        }


        @keyframes fadeIn {

            0% { opacity: 0.7; transform: translateY(5px); }

            100% { opacity: 1; transform: translateY(0); }

        }


        /* ===== RESPONSIVE ===== */

        @media (max-width: 900px) {

            .main-grid {

                grid-template-columns: 1fr;

                gap: 1.8rem;

            }

            .tool-card {

                padding: 1.6rem;

            }

            .resume-header {

                flex-direction: column;

                gap: 0.8rem;

            }

            .resume-contact {

                text-align: left;

                width: 100%;

            }

            .resume-contact span {

                justify-content: flex-start;

            }

        }


        @media (max-width: 480px) {

            body { padding: 0.8rem; }

            .tool-card { padding: 1.2rem; }

            .header-left h1 { font-size: 1.4rem; }

            .logo-mark { width: 40px; height: 40px; font-size: 1.3rem; }

            .resume-name { font-size: 1.7rem; }

            .preview-panel { padding: 1.2rem; }

            .form-panel { padding: 1.2rem; }

        }

    </style>

</head>

<body>

    <div class="tool-card">

        <!-- ===== HEADER ===== -->

        <header class="header">

            <div class="header-left">

                <div class="logo-mark">R</div>

                <div>

                    <h1>ResumeCraft</h1>

                    <div class="tagline">

                        <span class="dot-green"></span> smart · simple · professional

                    </div>

                </div>

            </div>

            <div class="header-badge">

                <span class="badge-dot"></span> free forever

            </div>

        </header>


        <!-- ===== MAIN GRID ===== -->

        <div class="main-grid">

            <!-- LEFT: FORM -->

            <section class="form-panel">

                <h2><span>1</span> Your details</h2>


                <div class="field">

                    <label for="fullName">Full name</label>

                    <input type="text" id="fullName" value="Jordan Lee" placeholder="Jordan Lee">

                </div>


                <div class="field">

                    <label for="jobTitle">Job title</label>

                    <input type="text" id="jobTitle" value="Senior Software Engineer" placeholder="Senior Software Engineer">

                </div>


                <div class="field">

                    <label for="email">Email</label>

                    <input type="email" id="email" value="jordan.lee@example.com" placeholder="jordan@example.com">

                </div>


                <div class="field">

                    <label for="phone">Phone</label>

                    <input type="tel" id="phone" value="+1 (555) 123-4567" placeholder="+1 (555) 123-4567">

                </div>


                <div class="field">

                    <label for="summary">Professional summary</label>

                    <textarea id="summary" rows="4">Results-driven software engineer with 8+ years of experience designing and scaling distributed systems. Proven track record of leading cross-functional teams and delivering high-impact products.</textarea>

                </div>


                <div class="field">

                    <label for="skills">Skills (comma separated)</label>

                    <textarea id="skills" rows="2">JavaScript, TypeScript, React, Node.js, Python, AWS, Docker, Kubernetes</textarea>

                </div>


                <div class="action-group">

                    <button class="btn btn-primary" id="generateBtn">

                        <span class="icon">⚡</span> Generate resume

                    </button>

                    <button class="btn btn-download" id="downloadBtn">

                        <span class="icon">⬇</span> Download as PDF

                    </button>

                    <div class="hint">click "Download" to save your resume as PDF</div>

                </div>

            </section>


            <!-- RIGHT: PREVIEW -->

            <section class="preview-panel" id="previewPanel">

                <div class="resume-content" id="resumeContent">

                    <!-- HEADER -->

                    <div class="resume-header">

                        <div class="resume-name-block">

                            <div class="resume-name" id="previewName">Jordan Lee</div>

                            <div class="resume-title" id="previewTitle">Senior Software Engineer</div>

                        </div>

                        <div class="resume-contact" id="previewContact">

                            <span>✉ jordan.lee@example.com</span>

                            <span>📞 +1 (555) 123-4567</span>

                        </div>

                    </div>


                    <!-- SUMMARY -->

                    <div class="resume-section">

                        <div class="section-title">📋 Professional Summary</div>

                        <div class="resume-summary" id="previewSummary">Results-driven software engineer with 8+ years of experience designing and scaling distributed systems. Proven track record of leading cross-functional teams and delivering high-impact products.</div>

                    </div>


                    <!-- SKILLS -->

                    <div class="resume-section">

                        <div class="section-title">⚙️ Core Skills</div>

                        <div class="skills-container" id="previewSkills">

                            <!-- populated by JS -->

                        </div>

                    </div>

                </div>

            </section>

        </div>

    </div>


    <script>

        (function() {

            "use strict";


            // ----- DOM REFS: INPUTS -----

            const fullNameInput = document.getElementById('fullName');

            const jobTitleInput = document.getElementById('jobTitle');

            const emailInput = document.getElementById('email');

            const phoneInput = document.getElementById('phone');

            const summaryInput = document.getElementById('summary');

            const skillsInput = document.getElementById('skills');

            const generateBtn = document.getElementById('generateBtn');

            const downloadBtn = document.getElementById('downloadBtn');


            // ----- DOM REFS: PREVIEW -----

            const previewName = document.getElementById('previewName');

            const previewTitle = document.getElementById('previewTitle');

            const previewContact = document.getElementById('previewContact');

            const previewSummary = document.getElementById('previewSummary');

            const previewSkills = document.getElementById('previewSkills');

            const resumeContent = document.getElementById('resumeContent');


            // ----- UTILITY: ESCAPE HTML -----

            function escapeHtml(text) {

                if (text == null) return '';

                return String(text)

                    .replace(/&/g, '&amp;')

                    .replace(/</g, '&lt;')

                    .replace(/>/g, '&gt;')

                    .replace(/"/g, '&quot;')

                    .replace(/'/g, '&#039;');

            }


            // ----- CORE RENDER FUNCTION -----

            function renderResume() {

                const name = fullNameInput.value.trim() || 'Your Name';

                const title = jobTitleInput.value.trim() || 'Professional Title';

                const email = emailInput.value.trim() || 'email@example.com';

                const phone = phoneInput.value.trim() || '+1 (555) 000-0000';

                const summary = summaryInput.value.trim() || 'A short professional summary will appear here.';

                const skillsRaw = skillsInput.value.trim();


                // Update header

                previewName.textContent = name;

                previewTitle.textContent = title;


                // Contact

                previewContact.innerHTML = `

                    <span>✉ ${escapeHtml(email)}</span>

                    <span>📞 ${escapeHtml(phone)}</span>

                `;


                // Summary

                previewSummary.textContent = summary;


                // Skills

                let skillsArray = [];

                if (skillsRaw) {

                    skillsArray = skillsRaw

                        .split(',')

                        .map(s => s.trim())

                        .filter(s => s.length > 0);

                }


                // Deduplicate (case-insensitive)

                const seen = new Set();

                const uniqueSkills = [];

                for (let skill of skillsArray) {

                    const lower = skill.toLowerCase();

                    if (!seen.has(lower)) {

                        seen.add(lower);

                        uniqueSkills.push(skill);

                    }

                }


                const maxSkills = 16;

                const displaySkills = uniqueSkills.slice(0, maxSkills);

                const hasMore = uniqueSkills.length > maxSkills;


                if (displaySkills.length === 0) {

                    previewSkills.innerHTML = `<div class="empty-message">Add skills above to see them here</div>`;

                } else {

                    let html = displaySkills.map(skill =>

                        `<span class="skill-badge">${escapeHtml(skill)}</span>`

                    ).join('');

                    if (hasMore) {

                        html += `<span class="skill-badge" style="background:#e2ecf7;">+${uniqueSkills.length - maxSkills} more</span>`;

                    }

                    previewSkills.innerHTML = html;

                }


                // Subtle animation

                resumeContent.classList.remove('preview-updated');

                void resumeContent.offsetWidth;

                resumeContent.classList.add('preview-updated');

            }


            // ----- INITIAL RENDER -----

            renderResume();


            // ----- EVENT LISTENERS -----

            generateBtn.addEventListener('click', (e) => {

                e.preventDefault();

                renderResume();

            });


            // Live update on blur

            [fullNameInput, jobTitleInput, emailInput, phoneInput, summaryInput, skillsInput].forEach(input => {

                input.addEventListener('blur', renderResume);

            });


            // Enter key (non-textarea)

            [fullNameInput, jobTitleInput, emailInput, phoneInput].forEach(input => {

                input.addEventListener('keypress', (e) => {

                    if (e.key === 'Enter') {

                        e.preventDefault();

                        renderResume();

                        input.blur();

                    }

                });

            });


            // Ctrl+Enter in textareas

            [summaryInput, skillsInput].forEach(ta => {

                ta.addEventListener('keydown', (e) => {

                    if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {

                        e.preventDefault();

                        renderResume();

                    }

                });

            });


            // ----- DOWNLOAD AS PDF -----

            downloadBtn.addEventListener('click', function() {

                // Ensure preview is current

                renderResume();


                const previewElement = document.getElementById('previewPanel');


                function loadHtml2Pdf(callback) {

                    if (window.html2pdf) {

                        callback();

                        return;

                    }

                    const script = document.createElement('script');

                    script.src = 'https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js';

                    script.onload = callback;

                    document.head.appendChild(script);

                }


                loadHtml2Pdf(function() {

                    const opt = {

                        margin:       [0.5, 0.5, 0.5, 0.5],

                        filename:     'resume.pdf',

                        image:        { type: 'jpeg', quality: 0.98 },

                        html2canvas:  { scale: 2, useCORS: true, letterRendering: true },

                        jsPDF:        { unit: 'in', format: 'a4', orientation: 'portrait' }

                    };


                    // Clone the preview for clean PDF generation

                    const clone = previewElement.cloneNode(true);

                    clone.style.background = '#ffffff';

                    clone.style.borderRadius = '0';

                    clone.style.boxShadow = 'none';

                    clone.style.border = 'none';

                    clone.style.padding = '0.7in 0.6in';

                    clone.style.position = 'relative';


                    // Remove animation class from clone

                    const contentClone = clone.querySelector('.resume-content');

                    if (contentClone) {

                        contentClone.classList.remove('preview-updated');

                    }


                    html2pdf().set(opt).from(clone).save();

                });

            });


        })();

    </script>


    <!-- Preload html2pdf for instant download -->

    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js" async></script>

</body>

</html>

Comments