{"id":30748,"date":"2026-10-23T10:35:00","date_gmt":"2026-10-23T05:05:00","guid":{"rendered":"https:\/\/internshala.com\/blog\/?p=30748"},"modified":"2026-10-22T22:36:01","modified_gmt":"2026-10-22T17:06:01","slug":"employer-laravel-developer-job-description","status":"publish","type":"post","link":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/","title":{"rendered":"Laravel Developer Job Description [with Free Template]"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"427\" src=\"https:\/\/internshala.com\/blog\/wp-content\/uploads\/2026\/10\/Laravel-Developer-Job-Description-1-1024x427.png\" alt=\"Laravel Developer Job Description (1)\" class=\"wp-image-30749\" srcset=\"https:\/\/internshala.com\/blog\/wp-content\/uploads\/2026\/10\/Laravel-Developer-Job-Description-1-1024x427.png 1024w, https:\/\/internshala.com\/blog\/wp-content\/uploads\/2026\/10\/Laravel-Developer-Job-Description-1-672x280.png 672w, https:\/\/internshala.com\/blog\/wp-content\/uploads\/2026\/10\/Laravel-Developer-Job-Description-1.png 1199w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-pale-cyan-blue-background-color has-background\"><tbody><tr><td><strong>Summary: <\/strong>Employers should assess Laravel developers based on project needs, technical expertise, and the complexity of assigned tasks. A junior developer may handle routine fixes, while a senior developer can manage architecture and security. Job titles alone do not guarantee specific skills. Clear responsibilities and practical assessments help employers evaluate candidates and match their abilities to the role.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Building a successful web application starts with finding the right developer. Laravel has become a popular choice for businesses building websites, online platforms, and custom software solutions. However, attracting skilled developers requires more than listing technical requirements. Employers need to define the role clearly, explain why the opportunity is worth it, and set realistic expectations. A well-written job description can help hiring teams connect with professionals whose skills match their project goals. It also gives candidates a clear picture of the opportunity before applying. In this blog, we&#8217;ll show you how to write a Laravel developer job description.<\/p>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_86 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title ez-toc-toggle\" style=\"cursor:pointer\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 eztoc-toggle-hide-by-default' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#Who_Is_a_Laravel_Developer\" >Who Is a Laravel Developer?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#Laravel_Developer_Job_Description_Template\" >Laravel Developer Job Description Template<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#Laravel_Developer_Job_Description_Sample\" >Laravel Developer Job Description Sample<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#Cost_of_Hiring_a_Laravel_Developer\" >Cost of Hiring a Laravel Developer<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#Conclusion\" >Conclusion<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#FAQs\" >FAQs<\/a><\/li><\/ul><\/nav><\/div>\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Who_Is_a_Laravel_Developer\"><\/span>Who Is a Laravel Developer?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>A Laravel developer uses Laravel, an open-source PHP framework, to build, test, and maintain web applications. Laravel provides built-in tools for common development tasks, such as routing, authentication, database management, and session handling, allowing developers to create web solutions more efficiently.<\/p>\n\n\n\n<p>Depending on the project, a Laravel developer may work on the back end, integrate APIs, manage databases, or collaborate with front-end developers to deliver functional web applications. Employers hiring for this role should look for candidates with a strong understanding of PHP, Laravel, databases, and web development fundamentals.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Laravel_Developer_Job_Description_Template\"><\/span>Laravel Developer Job Description Template<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Use the following Laravel developer job description template to outline the role, responsibilities, technical requirements, and qualifications. Customize each section to match your company&#8217;s needs, project requirements, and the experience level you&#8217;re hiring for.<\/p>\n\n\n\n<!-- Job Description Template Builder: paste this whole file into a WordPress \"Custom HTML\" block.\n     The template is filled in from the post the builder is placed in; there are no built-in job templates.\n       Job title: the post's main heading (\"Python Developer Job Description: ...\" or \"Job Description for a Telecaller\").\n       Responsibilities, skills \/ qualifications, role overview and benefits: the post's sample job description (the section\n       under an H2 containing \"sample\", \"template\" or \"example\") first, then matching sections anywhere in the article.\n       Anything not found is left as a [placeholder]. Intern posts get internship details and intern benefits.\n       To choose exactly which blocks are used, add a CSS class in WordPress (block settings > Advanced > Additional CSS class):\n       jd-title, jd-summary, jd-responsibilities, jd-qualifications, jd-benefits.\n     data-role=\"blank\" ignores the post and opens with placeholders only (leave it as \"auto\" otherwise).\n     data-design sets the template style a post opens with: classic, modern (Bold header), simple or sidebar.\n     data-cta-url is where the \"Post this job\" link goes. The builder adds tracking tags to it automatically:\n     utm_source=is_blog, utm_medium=jd_builder, utm_campaign=(the post's URL slug), utm_content=(the job title read from the post). Tags you put in the URL yourself are kept.\n     data-gate=\"form\" asks for name, work email, mobile and company before a download and sends them to data-lead-url (a Google\n       Apps Script web app that adds a row to a Google Sheet). data-gate=\"signup\" asks visitors to create an Internshala\n       account instead. data-gate=\"off\" lets anyone download.\n       Employers already signed in to the site download straight away. To tell, the builder loads data-login-check\n       (default \/employer\/dashboard) in the background: signed-out visitors get a login form there. Others see the sign-up box;\n       sign-up opens in a small window, which closes and the download starts once the site confirms the sign-in.\n       Optional settings, added the same way as data-gate: data-google-url, data-login-url (sign-up and log-in addresses),\n       data-login-cookie (name of a cookie that only signed-in users have), data-gate-fallback=\"off\" (hides the \"I've signed in\"\n       button). Add ?jdgate=reset to a post's address to be asked again.\n     Analytics events sent to GA4 or Tag Manager when present: jd_builder_view, jd_builder_edit,\n     jd_builder_design_change, jd_builder_download, jd_builder_cta_click,\n     jd_builder_gate_open, jd_builder_signup_click, jd_builder_signup_complete, jd_builder_gate_close,\n     jd_builder_already_signed_in, jd_builder_lead_submit -->\n<div id=\"cwjd\" class=\"cwjd\" data-role=\"auto\" data-design=\"classic\" data-gate=\"form\" data-lead-url=\"https:\/\/script.google.com\/macros\/s\/AKfycbz-qprMw0zQmyDBBI7huZ9pGWNbDa8DAlea1nEmt7fvOmcPsY8vySLYyf1tyU4xWsIt3w\/exec\" data-cta-url=\"https:\/\/internshala.com\/hire-talent\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link rel=\"stylesheet\" href=\"https:\/\/fonts.googleapis.com\/css2?family=DM+Sans:wght@400;500;700&#038;family=Fraunces:opsz,wght@9..144,500;9..144,700&#038;display=swap\">\n<style>\n#cwjd,#cwjd *{box-sizing:border-box}\n#cwjd{--ui-ink:#1d1d1b;--ui-muted:#5c5a54;--ui-line:#d9d5cb;--ui-bg:#ffffff;--ui-soft:#f6f4ef;--ui-accent:#0f5e5a;color:var(--ui-ink);font-size:16px;line-height:1.45;text-align:left;margin:32px 0;max-width:none}\n#cwjd .cwjd-app{display:grid;grid-template-columns:1fr;gap:28px;align-items:start}\n#cwjd.cwjd-wide .cwjd-app{grid-template-columns:minmax(290px,360px) minmax(0,1fr);gap:24px}\n#cwjd .cwjd-previewcol{min-width:0}\n#cwjd .cwjd-app{position:relative}\n#cwjd.cwjd-wide.cwjd-sticky:not(.cwjd-expanded) .cwjd-previewcol{position:sticky;top:var(--cwjd-top,16px)}\n#cwjd.cwjd-wide:not(.cwjd-expanded) .cwjd-actions{gap:8px;margin-bottom:10px}\n#cwjd.cwjd-wide:not(.cwjd-expanded) .cwjd-actions .cwjd-btn{min-height:40px;padding:8px 14px;font-size:14px;gap:6px}\n#cwjd.cwjd-wide:not(.cwjd-expanded) .cwjd-actions .cwjd-btn svg{width:16px;height:16px}\n#cwjd.cwjd-wide:not(.cwjd-expanded) .cwjd-status{min-height:0;margin-bottom:8px}\n#cwjd.cwjd-wide:not(.cwjd-expanded) .cwjd-status:empty{display:none}\n#cwjd .cwjd-stage{cursor:zoom-in}\n#cwjd.cwjd-expanded .cwjd-previewcol{position:fixed;top:0;left:0;right:0;bottom:0;z-index:2147483000;background:rgba(29,29,27,.88);overflow:auto;padding:20px 16px 40px 16px;transform:none !important}\n#cwjd.cwjd-expanded .cwjd-actions{justify-content:center}\n#cwjd.cwjd-expanded .cwjd-status{text-align:center;color:#ffffff}\n#cwjd.cwjd-expanded .cwjd-btn,#cwjd.cwjd-expanded .cwjd-btn-primary{background:#ffffff;color:#1d1d1b;border-color:#ffffff}\n#cwjd.cwjd-expanded .cwjd-btn:hover{background:#e9e6df}\n#cwjd.cwjd-expanded .cwjd-stage{cursor:default}\n#cwjd .cwjd-form{background:var(--ui-bg);border:1px solid var(--ui-line);border-radius:14px;padding:22px;display:flex;flex-direction:column;gap:22px}\n#cwjd .cwjd-formtitle{font-size:20px;font-weight:700;margin:0 0 4px 0;line-height:1.25}\n#cwjd .cwjd-hint{font-size:14px;color:var(--ui-muted);margin:0}\n#cwjd .cwjd-jump{display:inline-block;margin-top:10px;font-size:14px;font-weight:600;color:var(--ui-accent);text-decoration:underline}\n#cwjd.cwjd-wide .cwjd-jump{display:none}\n#cwjd .cwjd-group{display:flex;flex-direction:column;gap:12px;padding-top:18px;border-top:1px solid var(--ui-line)}\n#cwjd .cwjd-gtitle{font-size:13px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--ui-muted);margin:0}\n#cwjd .cwjd-field{display:flex;flex-direction:column;gap:5px;margin:0;font-size:14px;font-weight:600;font-style:normal;color:var(--ui-ink)}\n#cwjd label,#cwjd .cwjd-field span,#cwjd .cwjd-field small{font-style:normal}\n#cwjd .cwjd-field small{font-weight:400;color:var(--ui-muted);font-size:13px}\n#cwjd .cwjd-field input[type=text],#cwjd .cwjd-field textarea,#cwjd .cwjd-field select{width:100%;max-width:none;margin:0;padding:10px 12px;border:1px solid #bdb8ab;border-radius:8px;background:#fff;color:var(--ui-ink);font:inherit;font-weight:400;font-size:15px;line-height:1.45;box-shadow:none;height:auto;min-height:44px}\n#cwjd .cwjd-field textarea{resize:vertical;min-height:96px}\n#cwjd .cwjd-field textarea.cwjd-tall{min-height:190px}\n#cwjd .cwjd-field input:focus,#cwjd .cwjd-field textarea:focus,#cwjd .cwjd-field select:focus{outline:2px solid var(--ui-accent);outline-offset:1px;border-color:var(--ui-accent)}\n#cwjd .cwjd-swatches{display:flex;flex-wrap:wrap;gap:8px;align-items:center}\n#cwjd .cwjd-swatch{width:36px;height:36px;min-height:0;padding:0;margin:0;border-radius:50%;border:2px solid #fff;box-shadow:0 0 0 1px var(--ui-line);cursor:pointer}\n#cwjd .cwjd-swatch[aria-pressed=true]{box-shadow:0 0 0 2px var(--ui-ink)}\n#cwjd .cwjd-colorwrap{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:600}\n#cwjd .cwjd-colorwrap input[type=color]{width:44px;height:36px;padding:0;margin:0;border:1px solid #bdb8ab;border-radius:8px;background:#fff;cursor:pointer}\n#cwjd .cwjd-logorow{display:flex;flex-wrap:wrap;gap:8px;align-items:center;font-weight:400}\n#cwjd .cwjd-logorow input[type=file]{font:inherit;font-size:14px;font-weight:400;width:auto;max-width:100%;height:auto;margin:0;padding:6px 0;border:0;background:none;box-shadow:none}\n#cwjd .cwjd-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;margin:0;padding:10px 18px;border-radius:999px;border:1.5px solid var(--ui-ink);background:#fff;color:var(--ui-ink);font:inherit;font-size:15px;font-weight:700;line-height:1.2;text-transform:none;letter-spacing:0;cursor:pointer;box-shadow:none;text-decoration:none}\n#cwjd .cwjd-btn:hover{background:var(--ui-soft)}\n#cwjd .cwjd-btn-primary{background:var(--ui-ink);color:#fff}\n#cwjd .cwjd-btn-primary:hover{background:#3a3a36}\n#cwjd .cwjd-btn-small{min-height:36px;padding:6px 14px;font-size:14px}\n#cwjd .cwjd-btn:disabled{opacity:.55;cursor:wait}\n#cwjd .cwjd-btn svg{width:18px;height:18px;flex:none}\n#cwjd .cwjd-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;padding:0;margin:-1px}\n#cwjd .cwjd-fmt{display:inline-flex;margin:0;position:relative}\n#cwjd .cwjd-select{min-height:44px;height:auto;width:auto;max-width:100%;margin:0;padding:8px 34px 8px 16px;border:1.5px solid var(--ui-ink);border-radius:999px;background-color:#fff;color:var(--ui-ink);font:inherit;font-size:15px;font-weight:700;line-height:1.2;box-shadow:none;cursor:pointer}\n#cwjd .cwjd-select:focus{outline:2px solid var(--ui-accent);outline-offset:1px}\n#cwjd .cwjd-select:disabled{opacity:.55;cursor:wait}\n#cwjd.cwjd-wide:not(.cwjd-expanded) .cwjd-actions .cwjd-select{min-height:40px;padding:6px 30px 6px 14px;font-size:14px}\n#cwjd.cwjd-expanded .cwjd-select{border-color:#ffffff}\n#cwjd .cwjd-formfoot{display:flex;flex-wrap:wrap;gap:10px;padding-top:18px;border-top:1px solid var(--ui-line)}\n#cwjd .cwjd-actions{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:0 0 14px 0}\n#cwjd .cwjd-status{font-size:14px;color:var(--ui-muted);min-height:20px;margin:0 0 10px 0}\n#cwjd .cwjd-status.cwjd-err{color:#a1260d;font-weight:600}\n#cwjd .cwjd-gate{position:fixed;top:0;left:0;right:0;bottom:0;z-index:2147483600;background:rgba(29,29,27,.62);display:flex;align-items:center;justify-content:center;padding:16px;overflow:auto;margin:0}\n#cwjd .cwjd-gate-box{position:relative;width:100%;max-width:420px;box-sizing:border-box;background:#ffffff;color:#1d1d1b;border-radius:16px;padding:32px 28px 24px 28px;box-shadow:0 20px 60px rgba(0,0,0,.3);display:flex;flex-direction:column;gap:12px;text-align:left;font-size:15px;line-height:1.45}\n#cwjd .cwjd-gate-x{position:absolute;top:8px;right:8px;width:44px;height:44px;min-height:0;margin:0;padding:0;border:0;border-radius:50%;background:none;color:#5c5a54;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:none}\n#cwjd .cwjd-gate-x:hover{background:#f1efe9}\n#cwjd .cwjd-gate-x svg{width:20px;height:20px}\n#cwjd .cwjd-gate-title{font-size:22px;font-weight:700;line-height:1.25;margin:0;padding-right:36px;color:#1d1d1b}\n#cwjd .cwjd-gate-sub{margin:0 0 6px 0;font-size:15px;line-height:1.45;color:#4a4944}\n#cwjd .cwjd-gate-btn{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;min-height:48px;margin:0;padding:10px 16px;border:1.5px solid #0077c2;border-radius:10px;background:#ffffff;color:#006bb0;font:inherit;font-size:16px;font-weight:700;line-height:1.2;text-transform:none;letter-spacing:0;cursor:pointer;box-shadow:none}\n#cwjd .cwjd-gate-btn:hover{background:#eaf5fc;color:#006bb0}\n#cwjd .cwjd-gate-btn.cwjd-gate-main{background:#0077c2;color:#ffffff}\n#cwjd .cwjd-gate-btn.cwjd-gate-main:hover{background:#006bb0;color:#ffffff}\n#cwjd .cwjd-gate-btn svg{width:20px;height:20px;flex:none}\n#cwjd .cwjd-gate-btn:focus-visible,#cwjd .cwjd-gate-x:focus-visible,#cwjd .cwjd-gate-link:focus-visible{outline:2px solid #1d1d1b;outline-offset:2px}\n#cwjd .cwjd-gate-login,#cwjd .cwjd-gate-terms{margin:0;font-size:14px;line-height:1.45;color:#4a4944}\n#cwjd .cwjd-gate-status{margin:0;font-size:14px;line-height:1.45;font-weight:600;color:#1d1d1b}\n#cwjd .cwjd-gate-status:empty{display:none}\n#cwjd .cwjd-gate-link{display:inline;width:auto;min-height:0;margin:0;padding:0;border:0;border-radius:0;background:none;color:#006bb0;font:inherit;font-weight:700;text-decoration:underline;text-transform:none;letter-spacing:0;cursor:pointer;box-shadow:none}\n#cwjd .cwjd-gate-terms a,#cwjd .cwjd-gate-open{color:#006bb0;text-decoration:underline;font-weight:700}\n#cwjd .cwjd-gate-form{display:flex;flex-direction:column;gap:12px;margin:0}\n#cwjd .cwjd-gate-row{display:grid;grid-template-columns:1fr 1fr;gap:10px}\n#cwjd .cwjd-gate-field{display:flex;flex-direction:column;gap:5px;margin:0;font-size:14px;font-weight:600;font-style:normal;color:#1d1d1b;line-height:1.3}\n#cwjd .cwjd-gate-field input{width:100%;max-width:none;height:auto;min-height:44px;box-sizing:border-box;margin:0;padding:10px 12px;border:1px solid #bdb8ab;border-radius:8px;background:#ffffff;color:#1d1d1b;font:inherit;font-size:15px;font-weight:400;line-height:1.3;box-shadow:none}\n#cwjd .cwjd-gate-field input:focus{outline:2px solid #0077c2;outline-offset:1px;border-color:#0077c2}\n#cwjd .cwjd-gate-field input[aria-invalid=true]{border-color:#a1260d}\n#cwjd .cwjd-gate-tel{display:flex;gap:8px}\n#cwjd .cwjd-gate-cc{flex:none;display:flex;align-items:center;min-height:44px;padding:0 12px;border:1px solid #bdb8ab;border-radius:8px;background:#f6f4ef;font-weight:400;font-size:15px;color:#1d1d1b}\n#cwjd .cwjd-gate-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}\n#cwjd .cwjd-gate-ferr{margin:0;font-size:14px;line-height:1.4;font-weight:600;color:#a1260d}\n#cwjd .cwjd-gate-ferr:empty{display:none}\n#cwjd .cwjd-gate-form .cwjd-gate-btn:disabled{opacity:.6;cursor:wait}\n#cwjd .cwjd-gate-done{display:flex;flex-direction:column;gap:10px;padding-top:12px;border-top:1px solid #d9d5cb}\n#cwjd .cwjd-gate-done .cwjd-btn{width:100%}\n#cwjd .cwjd-cta{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:44px;margin:0 0 12px 0;padding:8px 14px;border:1px solid #b9dcf2;border-radius:10px;background:#eaf5fc;color:#1d1d1b;font-size:14px;line-height:1.35;font-weight:400;text-decoration:none;box-shadow:none}\n#cwjd .cwjd-cta strong{color:#006bb0;font-weight:700}\n#cwjd .cwjd-cta svg{width:18px;height:18px;flex:none;color:#006bb0}\n#cwjd .cwjd-cta:hover{background:#dcedf9;color:#1d1d1b;text-decoration:none}\n#cwjd .cwjd-cta:focus-visible{outline:2px solid #006bb0;outline-offset:2px}\n#cwjd .cwjd-cta.cwjd-cta-hot{background:#0077c2;border-color:#0077c2;color:#ffffff}\n#cwjd .cwjd-cta.cwjd-cta-hot strong,#cwjd .cwjd-cta.cwjd-cta-hot svg{color:#ffffff}\n#cwjd .cwjd-cta.cwjd-cta-hot:hover{background:#006bb0;color:#ffffff}\n#cwjd.cwjd-expanded .cwjd-cta{max-width:560px;margin-left:auto;margin-right:auto}\n#cwjd .cwjd-stage{position:relative;overflow:hidden;margin:0 auto;max-width:100%;border-radius:10px;box-shadow:0 1px 3px rgba(0,0,0,.12),0 8px 28px rgba(0,0,0,.08);background:#f6f4ef}\n#cwjd .cwjd-scale{position:absolute;top:0;left:0;width:1080px;transform-origin:0 0}\n#cwjd [hidden]{display:none !important}\n#cwjd:not([data-live]) .cwjd-app{display:none}\n#cwjd .cwjd-boot{margin:0;padding:16px 18px;border:1px dashed var(--ui-line);border-radius:12px;background:var(--ui-soft);color:var(--ui-muted);font-size:15px}\n#cwjd .cwjd-boot.cwjd-boot-err{border:1px solid #a1260d;color:#a1260d;background:#fff6f3;font-weight:600}\n\/* ---------- the job description sheet (what gets downloaded) ---------- *\/\n#cwjd .cwjd-scale{--cw-accent:#0f5e5a;--cw-on:#ffffff;--cw-head:#0f5e5a;--cw-display:'Fraunces',Georgia,'Times New Roman',serif;--cw-body:'DM Sans','Helvetica Neue',Helvetica,Arial,sans-serif}\n#cwjd .cwjd-scale[data-font=sans]{--cw-display:'DM Sans','Helvetica Neue',Helvetica,Arial,sans-serif}\n#cwjd .cwjd-sheet{width:1080px;min-height:1400px;box-sizing:border-box;background:#ffffff;color:#1d1d1b;font-family:var(--cw-body);font-size:17px;line-height:1.55;text-align:left;margin:0}\n#cwjd .cwjd-sheet *{margin:0;padding:0;border:0;background:none;text-transform:none;letter-spacing:normal;font-family:inherit;color:inherit;box-shadow:none}\n#cwjd .cwjd-sheet *::before,#cwjd .cwjd-sheet *::after{content:none}\n#cwjd .cwjd-sheet .cw-logo{display:block;max-height:56px;max-width:200px;width:auto;height:auto;object-fit:contain}\n#cwjd .cwjd-sheet .cw-p{white-space:pre-line;overflow-wrap:anywhere}\n#cwjd .cwjd-sheet .cw-list{display:flex;flex-direction:column;gap:10px;min-width:0}\n#cwjd .cwjd-sheet .cw-li{display:flex;gap:12px;align-items:flex-start;line-height:25px;overflow-wrap:anywhere}\n#cwjd .cwjd-sheet .cw-dotbox{flex:none;display:flex;align-items:center;height:25px}\n#cwjd .cwjd-sheet .cw-dot{display:block;width:7px;height:7px;border-radius:50%;background:var(--cw-accent)}\n#cwjd .cwjd-sheet .cw-ph{opacity:.45}\n\/* design 1: Classic *\/\n#cwjd .cw-classic{padding:72px 72px 0 72px;display:flex;flex-direction:column;gap:40px;background:#f6f4ef}\n#cwjd .cw-classic .cw-top{display:flex;flex-direction:column;gap:14px;padding-bottom:36px;border-bottom:2px solid #1d1d1b}\n#cwjd .cw-classic .cw-brandrow{display:flex;justify-content:space-between;align-items:center;gap:24px}\n#cwjd .cw-classic .cw-brand{display:flex;align-items:center;gap:16px;min-width:0}\n#cwjd .cw-classic .cw-company{font-size:18px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;line-height:1.3}\n#cwjd .cw-classic .cw-badge{flex:none;display:flex;align-items:center;height:42px;font-size:16px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;white-space:nowrap;color:var(--cw-on);background:var(--cw-accent);padding:0 18px;border-radius:999px;line-height:42px}\n#cwjd .cw-classic .cw-title{margin-top:12px;font-family:var(--cw-display);font-weight:700;font-size:92px;line-height:1.02;letter-spacing:-.02em;overflow-wrap:anywhere}\n#cwjd .cwjd-scale[data-font=sans] .cw-classic .cw-title{letter-spacing:-.03em}\n#cwjd .cw-classic .cw-details{font-size:20px;color:#4a4944}\n#cwjd .cw-classic .cw-h{font-family:var(--cw-display);font-weight:500;font-size:30px;line-height:1.2;color:var(--cw-head)}\n#cwjd .cwjd-scale[data-font=sans] .cw-classic .cw-h{font-weight:700;font-size:28px}\n#cwjd .cw-classic .cw-sec{display:flex;flex-direction:column;gap:14px;min-width:0}\n#cwjd .cw-classic .cw-row{display:grid;grid-template-columns:1fr 1fr;gap:48px}\n#cwjd .cw-classic .cw-row.cw-single{grid-template-columns:1fr}\n#cwjd .cw-classic .cw-row.cw-qb{grid-template-columns:1.4fr 1fr}\n#cwjd .cw-classic .cw-row.cw-qb.cw-single{grid-template-columns:1fr}\n#cwjd .cw-classic .cw-card{background:#ffffff;border:1px solid #d9d5cb;border-radius:16px;padding:32px;align-self:start}\n#cwjd .cw-classic .cw-foot{margin:auto -72px 0 -72px;background:var(--cw-accent);color:var(--cw-on);padding:44px 72px;display:flex;justify-content:space-between;align-items:center;gap:32px}\n#cwjd .cw-classic .cw-foot-l{display:flex;flex-direction:column;gap:6px;min-width:0}\n#cwjd .cw-classic .cw-foot-h{font-family:var(--cw-display);font-weight:700;font-size:34px;line-height:1.2}\n#cwjd .cw-classic .cw-foot-t{font-size:18px}\n#cwjd .cw-classic .cw-contact{flex:none;max-width:520px;font-size:24px;font-weight:700;border:2px solid var(--cw-on);border-radius:999px;padding:14px 28px;overflow-wrap:anywhere;text-align:center;line-height:1.3}\n\/* design 2: Bold header *\/\n#cwjd .cw-modern{display:flex;flex-direction:column}\n#cwjd .cw-modern .m-head{background:var(--cw-accent);color:var(--cw-on);padding:60px 72px 56px 72px;display:flex;flex-direction:column;gap:16px}\n#cwjd .cw-modern .m-brandrow{display:flex;justify-content:space-between;align-items:center;gap:24px}\n#cwjd .cw-modern .m-brand{display:flex;align-items:center;gap:16px;min-width:0}\n#cwjd .cw-modern .m-brand .cw-logo{background:#ffffff;padding:8px 12px;border-radius:10px;box-sizing:content-box}\n#cwjd .cw-modern .m-company{font-size:18px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;line-height:1.3}\n#cwjd .cw-modern .m-badge{flex:none;display:flex;align-items:center;height:40px;padding:0 18px;border:2px solid var(--cw-on);border-radius:999px;font-size:15px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;white-space:nowrap;line-height:36px}\n#cwjd .cw-modern .m-title{margin-top:22px;font-family:var(--cw-display);font-weight:700;font-size:84px;line-height:1.04;letter-spacing:-.02em;overflow-wrap:anywhere}\n#cwjd .cw-modern .m-details{font-size:20px;opacity:.9}\n#cwjd .cw-modern .m-body{flex:1;display:grid;grid-template-columns:1.55fr 1fr;gap:56px;padding:52px 72px 64px 72px;align-items:start}\n#cwjd .cw-modern .m-main,#cwjd .cw-modern .m-side{display:flex;flex-direction:column;gap:36px;min-width:0}\n#cwjd .cw-modern .m-sec{display:flex;flex-direction:column;gap:14px;min-width:0}\n#cwjd .cw-modern .m-h{font-size:15px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--cw-head);line-height:1.3;padding-bottom:10px;border-bottom:2px solid var(--cw-accent)}\n#cwjd .cw-modern .m-card{display:flex;flex-direction:column;gap:14px;background:#f3f2ee;border-radius:14px;padding:26px}\n#cwjd .cw-modern .m-card .m-h{border-bottom:0;padding-bottom:0}\n#cwjd .cw-modern .m-apply{display:flex;flex-direction:column;gap:8px;border:2px solid var(--cw-accent);border-radius:14px;padding:26px}\n#cwjd .cw-modern .m-apply-h{font-family:var(--cw-display);font-weight:700;font-size:26px;line-height:1.2}\n#cwjd .cw-modern .m-apply-t{font-size:16px}\n#cwjd .cw-modern .m-contact{font-size:19px;font-weight:700;color:var(--cw-head);overflow-wrap:anywhere}\n\/* design 3: Simple *\/\n#cwjd .cw-simple{padding:84px 88px 76px 88px;display:flex;flex-direction:column;gap:30px}\n#cwjd .cw-simple .n-top{display:flex;flex-direction:column;gap:14px;padding-bottom:10px}\n#cwjd .cw-simple .n-brand{display:flex;align-items:center;gap:14px}\n#cwjd .cw-simple .n-company{font-size:17px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--cw-head);line-height:1.3}\n#cwjd .cw-simple .n-badge{margin-left:auto;flex:none;font-size:14px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#5c5a54;white-space:nowrap}\n#cwjd .cw-simple .n-title{margin-top:20px;font-family:var(--cw-display);font-weight:700;font-size:72px;line-height:1.05;letter-spacing:-.02em;overflow-wrap:anywhere}\n#cwjd .cw-simple .n-details{font-size:20px;color:#4a4944}\n#cwjd .cw-simple .n-sec{display:grid;grid-template-columns:210px 1fr;gap:36px;padding-top:28px;border-top:1px solid #d3d1c9}\n#cwjd .cw-simple .n-h{font-size:15px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--cw-head);line-height:1.5;padding-top:2px}\n#cwjd .cw-simple .n-apply{margin-top:auto;padding-top:28px;border-top:2px solid var(--cw-accent);display:flex;flex-direction:column;gap:6px}\n#cwjd .cw-simple .n-apply-h{font-family:var(--cw-display);font-weight:700;font-size:26px;line-height:1.2}\n#cwjd .cw-simple .n-apply-row{display:flex;flex-wrap:wrap;gap:4px 10px;font-size:18px}\n#cwjd .cw-simple .n-contact{font-weight:700;color:var(--cw-head);overflow-wrap:anywhere}\n\/* design 4: Sidebar *\/\n#cwjd .cw-sidebar{display:flex;flex-direction:row;align-items:stretch}\n#cwjd .cw-sidebar .s-side{flex:none;width:350px;box-sizing:border-box;background:var(--cw-accent);color:var(--cw-on);padding:64px 40px 56px 40px;display:flex;flex-direction:column;gap:34px}\n#cwjd .cw-sidebar .s-side .cw-dot{background:var(--cw-on)}\n#cwjd .cw-sidebar .s-brand{display:flex;flex-direction:column;align-items:flex-start;gap:16px}\n#cwjd .cw-sidebar .s-brand .cw-logo{background:#ffffff;padding:8px 12px;border-radius:10px;box-sizing:content-box}\n#cwjd .cw-sidebar .s-company{font-size:19px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;line-height:1.3;overflow-wrap:anywhere}\n#cwjd .cw-sidebar .s-badge{align-self:flex-start;display:flex;align-items:center;height:38px;padding:0 16px;border:2px solid var(--cw-on);border-radius:999px;font-size:14px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;white-space:nowrap;line-height:34px}\n#cwjd .cw-sidebar .s-sec{display:flex;flex-direction:column;gap:12px;font-size:16px;line-height:1.55}\n#cwjd .cw-sidebar .s-h{font-size:14px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;opacity:.85}\n#cwjd .cw-sidebar .s-apply{margin-top:auto;display:flex;flex-direction:column;gap:8px;padding-top:28px;border-top:1px solid var(--cw-on)}\n#cwjd .cw-sidebar .s-apply-h{font-family:var(--cw-display);font-weight:700;font-size:24px;line-height:1.2}\n#cwjd .cw-sidebar .s-apply-t{font-size:15px}\n#cwjd .cw-sidebar .s-contact{font-size:17px;font-weight:700;overflow-wrap:anywhere}\n#cwjd .cw-sidebar .s-main{flex:1;min-width:0;padding:64px 64px 64px 56px;display:flex;flex-direction:column;gap:34px}\n#cwjd .cw-sidebar .s-headline{display:flex;flex-direction:column;gap:14px;padding-bottom:30px;border-bottom:2px solid #1d1d1b}\n#cwjd .cw-sidebar .s-title{font-family:var(--cw-display);font-weight:700;font-size:72px;line-height:1.05;letter-spacing:-.02em;overflow-wrap:anywhere}\n#cwjd .cw-sidebar .s-details{font-size:20px;color:#4a4944}\n#cwjd .cw-sidebar .s-msec{display:flex;flex-direction:column;gap:14px}\n#cwjd .cw-sidebar .s-mh{font-family:var(--cw-display);font-weight:500;font-size:28px;line-height:1.2;color:var(--cw-head)}\n#cwjd .cwjd-scale[data-font=sans] .cw-sidebar .s-mh{font-weight:700;font-size:26px}\n<\/style>\n<p class=\"cwjd-boot\">Loading the job description builder\u2026 If this message doesn&#8217;t go away, scripts are being blocked or removed on this page.<\/p>\n<script>\n(function () {\n  var s = document.currentScript, r = (s && s.closest) ? s.closest('.cwjd') : null;\n  if (!r) return;\n  var b = r.querySelector('.cwjd-boot'), err = '';\n  if (b) b.textContent = 'Loading the job description builder\u2026';\n  function onErr(e) {\n    var m = (e && e.message) || '';\n    if (!err && \/SyntaxError\/i.test(m) && (!e.filename || e.filename.split('#')[0] === location.href.split('#')[0])) err = m + (e.lineno ? ' (line ' + e.lineno + ')' : '');\n  }\n  window.addEventListener('error', onErr);\n  function check() {\n    window.removeEventListener('error', onErr);\n    if (!b || r.getAttribute('data-live') || \/cwjd-boot-err\/.test(b.className)) return;\n    b.className = 'cwjd-boot cwjd-boot-err';\n    b.textContent = err ? \"The job description builder's code was changed or cut off when it was saved, so it can't run. Browser error: \" + err\n      : \"The job description builder's main code didn't run on this page. It may have been removed, cut off while pasting, or delayed by a speed plugin.\";\n  }\n  if (document.readyState === 'complete') setTimeout(check, 2500);\n  else window.addEventListener('load', function () { setTimeout(check, 2500); });\n})();\n<\/script>\n<div class=\"cwjd-app\">\n<div class=\"cwjd-form\">\n<div class=\"cwjd-formhead\">\n<div class=\"cwjd-formtitle\">Customize your job description<\/div>\n<p class=\"cwjd-hint\">The job title, responsibilities and skills are filled in from this article. Edit any field and the preview updates as you type. Everything stays in your browser, nothing is uploaded.<\/p>\n<a class=\"cwjd-jump\" href=\"#cwjd-previewcol\">Jump to preview and download<\/a>\n<\/div>\n<div class=\"cwjd-group\">\n<div class=\"cwjd-gtitle\">Template<\/div>\n<label class=\"cwjd-field\">Template style <small>Changes the look only. Your text stays the same.<\/small><select id=\"cwjd-design\"><option value=\"classic\">Classic<\/option><option value=\"modern\">Bold header<\/option><option value=\"simple\">Simple<\/option><option value=\"sidebar\">Sidebar<\/option><\/select><\/label>\n<\/div>\n<div class=\"cwjd-group\">\n<div class=\"cwjd-gtitle\">Company &amp; branding<\/div>\n<label class=\"cwjd-field\">Company name<input type=\"text\" data-field=\"companyName\" autocomplete=\"organization\" placeholder=\"Your company name\"><\/label>\n<div class=\"cwjd-field\"><label for=\"cwjd-logo\">Logo <small>(optional, PNG, JPG, WebP or SVG)<\/small><\/label>\n<div class=\"cwjd-logorow\"><input type=\"file\" id=\"cwjd-logo\" accept=\"image\/png,image\/jpeg,image\/webp,image\/svg+xml\"><button type=\"button\" class=\"cwjd-btn cwjd-btn-small\" id=\"cwjd-logo-remove\" hidden>Remove logo<\/button><\/div><\/div>\n<label class=\"cwjd-field\">Tag text <small>Leave empty to hide it<\/small><input type=\"text\" data-field=\"badge\"><\/label>\n<div class=\"cwjd-field\"><span id=\"cwjd-color-label\">Brand color<\/span>\n<div class=\"cwjd-swatches\" role=\"group\" aria-labelledby=\"cwjd-color-label\">\n<button type=\"button\" class=\"cwjd-swatch\" data-color=\"#0f5e5a\" style=\"background:#0f5e5a\" aria-label=\"Teal\"><\/button>\n<button type=\"button\" class=\"cwjd-swatch\" data-color=\"#23408e\" style=\"background:#23408e\" aria-label=\"Blue\"><\/button>\n<button type=\"button\" class=\"cwjd-swatch\" data-color=\"#6d2b5e\" style=\"background:#6d2b5e\" aria-label=\"Plum\"><\/button>\n<button type=\"button\" class=\"cwjd-swatch\" data-color=\"#a23b12\" style=\"background:#a23b12\" aria-label=\"Rust\"><\/button>\n<button type=\"button\" class=\"cwjd-swatch\" data-color=\"#2f2f2f\" style=\"background:#2f2f2f\" aria-label=\"Charcoal\"><\/button>\n<label class=\"cwjd-colorwrap\">Custom <input type=\"color\" id=\"cwjd-color\" value=\"#0f5e5a\"><\/label>\n<\/div><\/div>\n<label class=\"cwjd-field\">Heading style<select data-field=\"font\"><option value=\"serif\">Classic serif<\/option><option value=\"sans\">Modern sans<\/option><\/select><\/label>\n<\/div>\n<div class=\"cwjd-group\">\n<div class=\"cwjd-gtitle\">Job basics<\/div>\n<label class=\"cwjd-field\">Job title<input type=\"text\" data-field=\"jobTitle\"><\/label>\n<label class=\"cwjd-field\">Details line <small>e.g. job type, location, experience<\/small><input type=\"text\" data-field=\"details\"><\/label>\n<\/div>\n<div class=\"cwjd-group\">\n<div class=\"cwjd-gtitle\">About the company<\/div>\n<label class=\"cwjd-field\">Section heading<input type=\"text\" data-field=\"aboutHeading\"><\/label>\n<label class=\"cwjd-field\">Text <small>Leave empty to hide this section<\/small><textarea data-field=\"aboutText\"><\/textarea><\/label>\n<\/div>\n<div class=\"cwjd-group\">\n<div class=\"cwjd-gtitle\">About the role<\/div>\n<label class=\"cwjd-field\">Section heading<input type=\"text\" data-field=\"roleHeading\"><\/label>\n<label class=\"cwjd-field\">Text <small>Leave empty to hide this section<\/small><textarea data-field=\"roleText\"><\/textarea><\/label>\n<\/div>\n<div class=\"cwjd-group\">\n<div class=\"cwjd-gtitle\">Responsibilities<\/div>\n<label class=\"cwjd-field\">Section heading<input type=\"text\" data-field=\"respHeading\"><\/label>\n<label class=\"cwjd-field\">One per line <small>Long lists split into two columns automatically<\/small><textarea class=\"cwjd-tall\" data-field=\"respList\"><\/textarea><\/label>\n<\/div>\n<div class=\"cwjd-group\">\n<div class=\"cwjd-gtitle\">Qualifications<\/div>\n<label class=\"cwjd-field\">Section heading<input type=\"text\" data-field=\"qualHeading\"><\/label>\n<label class=\"cwjd-field\">One per line<textarea class=\"cwjd-tall\" data-field=\"qualList\"><\/textarea><\/label>\n<\/div>\n<div class=\"cwjd-group\">\n<div class=\"cwjd-gtitle\">Benefits<\/div>\n<label class=\"cwjd-field\">Section heading<input type=\"text\" data-field=\"benHeading\"><\/label>\n<label class=\"cwjd-field\">One per line <small>Leave empty to hide this section<\/small><textarea data-field=\"benList\"><\/textarea><\/label>\n<\/div>\n<div class=\"cwjd-group\">\n<div class=\"cwjd-gtitle\">How to apply<\/div>\n<label class=\"cwjd-field\">Heading<input type=\"text\" data-field=\"applyHeading\"><\/label>\n<label class=\"cwjd-field\">Short line<input type=\"text\" data-field=\"applyText\"><\/label>\n<label class=\"cwjd-field\">Email or link<input type=\"text\" data-field=\"applyContact\" placeholder=\"e.g. careers@yourcompany.com\"><\/label>\n<\/div>\n<div class=\"cwjd-formfoot\">\n<button type=\"button\" class=\"cwjd-btn cwjd-btn-small\" id=\"cwjd-reset\">Reset template<\/button>\n<button type=\"button\" class=\"cwjd-btn cwjd-btn-small\" id=\"cwjd-clear\">Clear all fields<\/button>\n<\/div>\n<\/div>\n<div class=\"cwjd-previewcol\" id=\"cwjd-previewcol\">\n<div class=\"cwjd-actions\">\n<label class=\"cwjd-fmt\"><span class=\"cwjd-sr\">Download format<\/span><select id=\"cwjd-format\" class=\"cwjd-select\"><option value=\"pdf\">PDF<\/option><option value=\"docx\">Word (.docx)<\/option><option value=\"png\">PNG image<\/option><\/select><\/label>\n<button type=\"button\" class=\"cwjd-btn cwjd-btn-primary\" id=\"cwjd-download\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 3v12\"\/><path d=\"m7 10 5 5 5-5\"\/><path d=\"M5 21h14\"\/><\/svg>Download<\/button>\n<button type=\"button\" class=\"cwjd-btn\" id=\"cwjd-zoom\" aria-expanded=\"false\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M15 3h6v6\"\/><path d=\"M9 21H3v-6\"\/><path d=\"M21 3l-7 7\"\/><path d=\"M3 21l7-7\"\/><\/svg><span id=\"cwjd-zoom-label\">Enlarge<\/span><\/button>\n<\/div>\n<a class=\"cwjd-cta\" id=\"cwjd-cta\" href=\"https:\/\/internshala.com\/hire-talent?utm_source=is_blog&amp;utm_medium=jd_builder\" target=\"_blank\" rel=\"noopener\"><span><span id=\"cwjd-cta-lead\">Hiring for this role?<\/span> <strong id=\"cwjd-cta-strong\">Post this job for free<\/strong><\/span><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M5 12h14\"\/><path d=\"m13 6 6 6-6 6\"\/><\/svg><\/a>\n<p class=\"cwjd-status\" id=\"cwjd-status\" role=\"status\" aria-live=\"polite\"><\/p>\n<div class=\"cwjd-stage\" id=\"cwjd-stage\">\n<div class=\"cwjd-scale\" id=\"cwjd-scale\" data-font=\"serif\">\n<div class=\"cwjd-sheet cw-classic\" data-design=\"classic\">\n<div class=\"cw-top\">\n<div class=\"cw-brandrow\">\n<div class=\"cw-brand\"><img class=\"cw-logo\" alt=\"\" hidden><div class=\"cw-company\" data-out=\"companyName\" data-ph=\"[Company name]\"><\/div><\/div>\n<div class=\"cw-badge\" data-out=\"badge\" data-hide-empty=\"badge\"><\/div>\n<\/div>\n<div class=\"cw-title\" data-out=\"jobTitle\" data-ph=\"[Job title]\"><\/div>\n<div class=\"cw-details\" data-out=\"details\" data-hide-empty=\"details\"><\/div>\n<\/div>\n<div class=\"cw-row\" data-pair=\"aboutText roleText\">\n<div class=\"cw-sec\" data-hide-empty=\"aboutText\"><div class=\"cw-h\" data-out=\"aboutHeading\"><\/div><div class=\"cw-p\" data-out=\"aboutText\"><\/div><\/div>\n<div class=\"cw-sec\" data-hide-empty=\"roleText\"><div class=\"cw-h\" data-out=\"roleHeading\"><\/div><div class=\"cw-p\" data-out=\"roleText\"><\/div><\/div>\n<\/div>\n<div class=\"cw-sec\" data-hide-empty=\"respList\"><div class=\"cw-h\" data-out=\"respHeading\"><\/div>\n<div class=\"cw-row\" data-two=\"respList\"><div class=\"cw-list\" data-list=\"respList\" data-half=\"a\"><\/div><div class=\"cw-list\" data-list=\"respList\" data-half=\"b\"><\/div><\/div>\n<\/div>\n<div class=\"cw-row cw-qb\" data-pair=\"qualList benList\">\n<div class=\"cw-sec\" data-hide-empty=\"qualList\"><div class=\"cw-h\" data-out=\"qualHeading\"><\/div><div class=\"cw-list\" data-list=\"qualList\"><\/div><\/div>\n<div class=\"cw-sec cw-card\" data-hide-empty=\"benList\"><div class=\"cw-h\" data-out=\"benHeading\"><\/div><div class=\"cw-list\" data-list=\"benList\"><\/div><\/div>\n<\/div>\n<div class=\"cw-foot\">\n<div class=\"cw-foot-l\"><div class=\"cw-foot-h\" data-out=\"applyHeading\"><\/div><div class=\"cw-foot-t\" data-out=\"applyText\"><\/div><\/div>\n<div class=\"cw-contact\" data-out=\"applyContact\" data-ph=\"[Your email or job link]\"><\/div>\n<\/div>\n<\/div>\n<div class=\"cwjd-sheet cw-modern\" data-design=\"modern\" hidden>\n<div class=\"m-head\">\n<div class=\"m-brandrow\">\n<div class=\"m-brand\"><img class=\"cw-logo\" alt=\"\" hidden><div class=\"m-company\" data-out=\"companyName\" data-ph=\"[Company name]\"><\/div><\/div>\n<div class=\"m-badge\" data-out=\"badge\" data-hide-empty=\"badge\"><\/div>\n<\/div>\n<div class=\"m-title\" data-out=\"jobTitle\" data-ph=\"[Job title]\"><\/div>\n<div class=\"m-details\" data-out=\"details\" data-hide-empty=\"details\"><\/div>\n<\/div>\n<div class=\"m-body\">\n<div class=\"m-main\">\n<div class=\"m-sec\" data-hide-empty=\"roleText\"><div class=\"m-h\" data-out=\"roleHeading\"><\/div><div class=\"cw-p\" data-out=\"roleText\"><\/div><\/div>\n<div class=\"m-sec\" data-hide-empty=\"respList\"><div class=\"m-h\" data-out=\"respHeading\"><\/div><div class=\"cw-list\" data-list=\"respList\"><\/div><\/div>\n<div class=\"m-sec\" data-hide-empty=\"qualList\"><div class=\"m-h\" data-out=\"qualHeading\"><\/div><div class=\"cw-list\" data-list=\"qualList\"><\/div><\/div>\n<\/div>\n<div class=\"m-side\">\n<div class=\"m-sec\" data-hide-empty=\"aboutText\"><div class=\"m-h\" data-out=\"aboutHeading\"><\/div><div class=\"cw-p\" data-out=\"aboutText\"><\/div><\/div>\n<div class=\"m-card\" data-hide-empty=\"benList\"><div class=\"m-h\" data-out=\"benHeading\"><\/div><div class=\"cw-list\" data-list=\"benList\"><\/div><\/div>\n<div class=\"m-apply\"><div class=\"m-apply-h\" data-out=\"applyHeading\"><\/div><div class=\"m-apply-t\" data-out=\"applyText\"><\/div><div class=\"m-contact\" data-out=\"applyContact\" data-ph=\"[Your email or job link]\"><\/div><\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cwjd-sheet cw-simple\" data-design=\"simple\" hidden>\n<div class=\"n-top\">\n<div class=\"n-brand\"><img class=\"cw-logo\" alt=\"\" hidden><div class=\"n-company\" data-out=\"companyName\" data-ph=\"[Company name]\"><\/div><div class=\"n-badge\" data-out=\"badge\" data-hide-empty=\"badge\"><\/div><\/div>\n<div class=\"n-title\" data-out=\"jobTitle\" data-ph=\"[Job title]\"><\/div>\n<div class=\"n-details\" data-out=\"details\" data-hide-empty=\"details\"><\/div>\n<\/div>\n<div class=\"n-sec\" data-hide-empty=\"aboutText\"><div class=\"n-h\" data-out=\"aboutHeading\"><\/div><div class=\"cw-p\" data-out=\"aboutText\"><\/div><\/div>\n<div class=\"n-sec\" data-hide-empty=\"roleText\"><div class=\"n-h\" data-out=\"roleHeading\"><\/div><div class=\"cw-p\" data-out=\"roleText\"><\/div><\/div>\n<div class=\"n-sec\" data-hide-empty=\"respList\"><div class=\"n-h\" data-out=\"respHeading\"><\/div><div class=\"cw-list\" data-list=\"respList\"><\/div><\/div>\n<div class=\"n-sec\" data-hide-empty=\"qualList\"><div class=\"n-h\" data-out=\"qualHeading\"><\/div><div class=\"cw-list\" data-list=\"qualList\"><\/div><\/div>\n<div class=\"n-sec\" data-hide-empty=\"benList\"><div class=\"n-h\" data-out=\"benHeading\"><\/div><div class=\"cw-list\" data-list=\"benList\"><\/div><\/div>\n<div class=\"n-apply\"><div class=\"n-apply-h\" data-out=\"applyHeading\"><\/div><div class=\"n-apply-row\"><div data-out=\"applyText\"><\/div><div class=\"n-contact\" data-out=\"applyContact\" data-ph=\"[Your email or job link]\"><\/div><\/div><\/div>\n<\/div>\n<div class=\"cwjd-sheet cw-sidebar\" data-design=\"sidebar\" hidden>\n<div class=\"s-side\">\n<div class=\"s-brand\"><img class=\"cw-logo\" alt=\"\" hidden><div class=\"s-company\" data-out=\"companyName\" data-ph=\"[Company name]\"><\/div><\/div>\n<div class=\"s-badge\" data-out=\"badge\" data-hide-empty=\"badge\"><\/div>\n<div class=\"s-sec\" data-hide-empty=\"aboutText\"><div class=\"s-h\" data-out=\"aboutHeading\"><\/div><div class=\"cw-p\" data-out=\"aboutText\"><\/div><\/div>\n<div class=\"s-sec\" data-hide-empty=\"benList\"><div class=\"s-h\" data-out=\"benHeading\"><\/div><div class=\"cw-list\" data-list=\"benList\"><\/div><\/div>\n<div class=\"s-apply\"><div class=\"s-apply-h\" data-out=\"applyHeading\"><\/div><div class=\"s-apply-t\" data-out=\"applyText\"><\/div><div class=\"s-contact\" data-out=\"applyContact\" data-ph=\"[Your email or job link]\"><\/div><\/div>\n<\/div>\n<div class=\"s-main\">\n<div class=\"s-headline\"><div class=\"s-title\" data-out=\"jobTitle\" data-ph=\"[Job title]\"><\/div><div class=\"s-details\" data-out=\"details\" data-hide-empty=\"details\"><\/div><\/div>\n<div class=\"s-msec\" data-hide-empty=\"roleText\"><div class=\"s-mh\" data-out=\"roleHeading\"><\/div><div class=\"cw-p\" data-out=\"roleText\"><\/div><\/div>\n<div class=\"s-msec\" data-hide-empty=\"respList\"><div class=\"s-mh\" data-out=\"respHeading\"><\/div><div class=\"cw-list\" data-list=\"respList\"><\/div><\/div>\n<div class=\"s-msec\" data-hide-empty=\"qualList\"><div class=\"s-mh\" data-out=\"qualHeading\"><\/div><div class=\"cw-list\" data-list=\"qualList\"><\/div><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cwjd-gate\" id=\"cwjd-gate\" hidden>\n<div class=\"cwjd-gate-box\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"cwjd-gate-title\">\n<button type=\"button\" class=\"cwjd-gate-x\" id=\"cwjd-gate-close\" aria-label=\"Close\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 6l12 12\"\/><path d=\"M18 6L6 18\"\/><\/svg><\/button>\n<div class=\"cwjd-gate-title\" id=\"cwjd-gate-title\">Sign up free to download your job description<\/div>\n<p class=\"cwjd-gate-sub\" id=\"cwjd-gate-sub\">Create your free Internshala employer account to download this JD, then post the job to reach candidates.<\/p>\n<div class=\"cwjd-gate-signup\" id=\"cwjd-gate-signup\">\n<button type=\"button\" class=\"cwjd-gate-btn cwjd-gate-main\" id=\"cwjd-gate-google\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"8\" r=\"4\"\/><path d=\"M4 21a8 8 0 0 1 16 0\"\/><\/svg>Sign up with Google<\/button>\n<button type=\"button\" class=\"cwjd-gate-btn\" id=\"cwjd-gate-email\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"\/><path d=\"m3 7 9 6 9-6\"\/><\/svg>Sign up with Email<\/button>\n<\/div>\n<form class=\"cwjd-gate-form\" id=\"cwjd-gate-form\" novalidate hidden>\n<div class=\"cwjd-gate-row\">\n<label class=\"cwjd-gate-field\">First name<input type=\"text\" name=\"first_name\" autocomplete=\"given-name\" maxlength=\"60\" required><\/label>\n<label class=\"cwjd-gate-field\">Last name<input type=\"text\" name=\"last_name\" autocomplete=\"family-name\" maxlength=\"60\" required><\/label>\n<\/div>\n<label class=\"cwjd-gate-field\">Official email<input type=\"email\" name=\"email\" autocomplete=\"email\" placeholder=\"name@company.com\" maxlength=\"120\" required><\/label>\n<label class=\"cwjd-gate-field\">Mobile number<span class=\"cwjd-gate-tel\"><span class=\"cwjd-gate-cc\">+91<\/span><input type=\"tel\" name=\"mobile\" autocomplete=\"tel-national\" inputmode=\"numeric\" placeholder=\"10-digit mobile number\" maxlength=\"20\" required><\/span><\/label>\n<label class=\"cwjd-gate-field\">Company name<input type=\"text\" name=\"company\" autocomplete=\"organization\" maxlength=\"120\" required><\/label>\n<label class=\"cwjd-gate-hp\" aria-hidden=\"true\">Leave this empty<input type=\"text\" name=\"website\" tabindex=\"-1\" autocomplete=\"off\"><\/label>\n<p class=\"cwjd-gate-ferr\" id=\"cwjd-gate-ferr\" role=\"alert\"><\/p>\n<button type=\"submit\" class=\"cwjd-gate-btn cwjd-gate-main\" id=\"cwjd-gate-submit\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12 3v12\"\/><path d=\"m7 10 5 5 5-5\"\/><path d=\"M5 21h14\"\/><\/svg>Download my JD<\/button>\n<\/form>\n<p class=\"cwjd-gate-login\"><span id=\"cwjd-gate-login-lead\">Already have an account?<\/span> <button type=\"button\" class=\"cwjd-gate-link\" id=\"cwjd-gate-login\">Log in<\/button><\/p>\n<p class=\"cwjd-gate-status\" id=\"cwjd-gate-status\" role=\"status\" aria-live=\"polite\"><\/p>\n<div class=\"cwjd-gate-done\" id=\"cwjd-gate-done\" hidden>\n<a class=\"cwjd-gate-open\" id=\"cwjd-gate-open\" href=\"https:\/\/internshala.com\/hire-talent\" target=\"_blank\" rel=\"noopener\" hidden>Open the sign-up page in a new tab<\/a>\n<button type=\"button\" class=\"cwjd-btn cwjd-btn-primary\" id=\"cwjd-gate-continue\">I&#8217;ve signed in, download my file<\/button>\n<\/div>\n<p class=\"cwjd-gate-terms\"><span id=\"cwjd-gate-terms-lead\">By signing up, you agree to our<\/span> <a href=\"https:\/\/internshala.com\/terms#employer\" target=\"_blank\" rel=\"noopener\">T&amp;C<\/a>.<\/p>\n<\/div>\n<\/div>\n<script>\n(function () {\n  \/* Find this script's own builder block, so the builder still works if a page has more than one copy. *\/\n  var me = document.currentScript, root = (me && me.closest) ? me.closest('.cwjd') : null;\n  if (!root || root.getAttribute('data-ready')) {\n    root = null;\n    var all = document.querySelectorAll('.cwjd');\n    for (var n = 0; all.length > n; n++) { if (!all[n].getAttribute('data-ready')) { root = all[n]; break; } }\n  }\n  if (!root) return;\n  root.setAttribute('data-ready', '1');\n  var boot = root.querySelector('.cwjd-boot');\n  function go() {\n    try {\n      start(root);\n      root.setAttribute('data-live', '1');\n      if (boot && boot.parentNode) boot.parentNode.removeChild(boot);\n    } catch (err) {\n      if (boot) { boot.textContent = \"Sorry, the job description builder couldn't start. Please refresh the page. (\" + (err && err.message ? err.message : err) + \")\"; boot.className = 'cwjd-boot cwjd-boot-err'; }\n      if (window.console && console.error) console.error('Job description builder:', err);\n    }\n  }\n  \/* Start once the whole post has loaded, so the builder can read sections that come after it in the article. *\/\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', go); else go();\n  function start(root) {\n  var H2C = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/html2canvas\/1.4.1\/html2canvas.min.js';\n  var JSPDF = 'https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jspdf\/2.5.1\/jspdf.umd.min.js';\n  var DOCX_SRC = ['https:\/\/cdn.jsdelivr.net\/npm\/docx@8.5.0\/build\/index.umd.min.js', 'https:\/\/unpkg.com\/docx@8.5.0\/build\/index.umd.js'];\n  var DESIGNS = ['classic', 'modern', 'simple', 'sidebar'];\n  var PAPER = { classic: '#f6f4ef', modern: '#ffffff', simple: '#ffffff', sidebar: '#ffffff' };\n  \/* Note: this code deliberately uses no backslash or less-than characters. WordPress's text formatter treats a less-than sign as\n     the start of an HTML tag and rewrites the ampersands after it, which breaks the script. Write comparisons as b > a instead. *\/\n  var NL = String.fromCharCode(10);\n  \/* Company-level fields: the same for every role, and kept when someone switches roles. *\/\n  var COMMON = {\n    companyName: \"\",\n    badge: \"We're hiring\",\n    aboutHeading: \"About us\",\n    aboutText: \"[Company name] is a [industry] company that [what you do and who you serve]. [Add a line about your team, culture or mission.]\",\n    roleHeading: \"The role\",\n    respHeading: \"Key responsibilities\",\n    qualHeading: \"Qualifications & skills\",\n    benHeading: \"Benefits\",\n    benList: [\"Competitive salary\", \"Health insurance\", \"Paid time off\", \"Learning and growth opportunities\"].join(NL),\n    applyHeading: \"Think you're a good fit?\",\n    applyText: \"Send your resume and a cover letter to\",\n    applyContact: \"\",\n    accent: \"#0f5e5a\",\n    font: \"serif\"\n  };\n  \/* ---- Template from the blog post ----\n     The builder has no built-in job templates: everything role-specific is read from the post it is placed in.\n     Job title: the post's main heading, e.g. \"Python Developer Job Description: ...\" or \"Job Description for a Telecaller\".\n     Responsibilities, skills \/ qualifications, the role overview and benefits: the post's own sample job description\n     (the section under an H2 containing \"sample\", \"template\" or \"example\") first, then matching sections anywhere in the article.\n     To choose the exact blocks, add a CSS class in WordPress (block settings > Advanced > Additional CSS class):\n       jd-title, jd-summary, jd-responsibilities, jd-qualifications, jd-benefits.\n     Anything the post doesn't have is left as a [placeholder] for the employer to fill in. *\/\n  var ROLE_FIELDS = [\"jobTitle\", \"details\", \"roleText\", \"respList\", \"qualList\", \"benList\"];\n  var KEEP_ON_CLEAR = [\"aboutHeading\", \"roleHeading\", \"respHeading\", \"qualHeading\", \"benHeading\", \"applyHeading\", \"accent\", \"font\"];\n  var INTERN_BEN = [\"Stipend of [amount] per month\", \"Certificate of completion\", \"Letter of recommendation\", \"Hands-on learning and mentorship\"].join(NL);\n  function toSlug(s) { return String(s || \"\").toLowerCase().replace(\/&\/g, \" and \").replace(\/[^a-z0-9]+\/g, \"-\").replace(\/^-+|-+$\/g, \"\"); }\n  var TAB = String.fromCharCode(9);\n  function squash(t) { return String(t || \"\").split(NL).join(\" \").split(TAB).join(\" \").replace(\/ {2,}\/g, \" \").trim(); }\n  function outsideBuilder(el) { return !root.contains(el) && !el.closest(\"nav, aside, footer, .cwjd\"); }\n  function articleScope() {\n    var host = root.closest(\"article, .entry-content, .post-content, .single-content, main\");\n    return host || document.body;\n  }\n  \/* The job named by a heading shaped like \"X Job Description...\" or \"Job Description for a X...\", or \"\" for any other heading. *\/\n  function jobFromText(t) {\n    t = squash(t);\n    var low = t.toLowerCase(), at = low.indexOf(\"job description\");\n    if (at > 0) t = t.slice(0, at);\n    else if (at === 0 && \/^job description (for|of) \/i.test(t)) {\n      t = t.replace(\/^job description (for|of) \/i, \"\").split(\":\")[0].split(\" - \")[0].split(\" | \")[0].split(\"(\")[0];\n    } else return \"\";\n    t = t.replace(\/^(how to (write|create|draft|make) |what is |writing |sample |free |simple |best |great |good |effective |perfect |the |an? )+\/i, \"\");\n    t = t.replace(\/^[0-9]{4} \/, \"\").replace(\/[ :,|-]+$\/, \"\").replace(\/('s|\u2019s)$\/i, \"\").trim();\n    if (\/^(free |sample |simple |best )*(templates?|samples?|examples?|formats?|guides?)$\/i.test(t)) return \"\";\n    return t.length > 1 && 70 > t.length ? t : \"\";\n  }\n  function titleFromHeading() {\n    var tagged = document.querySelector(\".jd-title\");\n    if (tagged && !root.contains(tagged)) return squash(tagged.textContent);\n    var h1 = null, art = root.closest(\"article\"), all = [];\n    if (art) all = Array.prototype.slice.call(art.querySelectorAll(\"h1\"));\n    all = all.concat(Array.prototype.slice.call(document.querySelectorAll(\"h1.entry-title, .entry-title h1, h1\")));\n    for (var i = 0; all.length > i; i++) {\n      if (!outsideBuilder(all[i])) continue;\n      h1 = jobFromText(all[i].textContent);\n      if (h1) return h1;\n    }\n    return jobFromText(document.title.split(\" - \")[0].split(\" | \")[0]);\n  }\n  \/* Top-level bullet points of a list (sub-points are left out), skipping bullets that are only links, e.g. a contents list. *\/\n  function listItems(el) {\n    var out = [], list = el.tagName === \"UL\" || el.tagName === \"OL\" ? el : el.querySelector(\"ul, ol\");\n    if (list) {\n      Array.prototype.forEach.call(list.children, function (li) {\n        if (li.tagName !== \"LI\") return;\n        var copy = li.cloneNode(true), subs = copy.querySelectorAll(\"ul, ol\");\n        for (var k = 0; subs.length > k; k++) { if (subs[k].parentNode) subs[k].parentNode.removeChild(subs[k]); }\n        var txt = squash(copy.textContent), links = copy.querySelectorAll(\"a\"), linkText = \"\";\n        for (var j = 0; links.length > j; j++) linkText += links[j].textContent;\n        if (links.length && squash(linkText) === txt) return;\n        if (txt.length > 2) out.push(txt.length > 220 ? txt.slice(0, 217) + \"\u2026\" : txt);\n      });\n    } else {\n      String(el.innerText || el.textContent || \"\").split(NL).forEach(function (l) {\n        l = squash(l).replace(\/^(?:[\u2022\u00b7\u25aa\u25e6*-]|[0-9]+[.)])(?=[ ])\/, \"\").trim();\n        if (l.length > 2) out.push(l);\n      });\n    }\n    return out.slice(0, 12);\n  }\n  \/* The first usable bullet list (or table cell) that belongs to a heading matching the pattern. *\/\n  function findSection(scope, pattern, wantText, from, to) {\n    var heads = Array.prototype.slice.call(scope.querySelectorAll(\"h2, h3, h4, h5, h6, th, td, strong, b, p\"));\n    var bounds = Array.prototype.slice.call(scope.querySelectorAll(\"h2, h3, h4\"));\n    var lists = Array.prototype.slice.call(scope.querySelectorAll(\"ul, ol\"));\n    var paras = Array.prototype.slice.call(scope.querySelectorAll(\"p\"));\n    for (var i = 0; heads.length > i; i++) {\n      var h = heads[i];\n      if (!outsideBuilder(h)) continue;\n      if (from && from !== h && !(from.compareDocumentPosition(h) & 4)) continue;\n      if (to && !(h.compareDocumentPosition(to) & 4)) continue;\n      var label = squash(h.textContent);\n      if (!label || label.length > 70 || !pattern.test(label)) continue;\n      if (h.tagName === \"STRONG\" || h.tagName === \"B\" || h.tagName === \"P\") {\n        if (h.tagName !== \"P\" && squash(h.parentNode.textContent).length > label.length + 3) continue;\n        if (h.tagName === \"P\" && label.length > 40) continue;\n      }\n      var cell = h.closest(\"td, th\");\n      if (cell && cell.parentNode) {\n        var cells = cell.parentNode.children;\n        for (var c = 0; cells.length > c; c++) {\n          if (cells[c] === cell || cells[c].contains(h)) continue;\n          if (wantText) { var tx = squash(cells[c].textContent); if (tx.length > 20) return tx; }\n          else { var fromCell = listItems(cells[c]); if (fromCell.length >= 2) return fromCell; }\n        }\n      }\n      var next = null;\n      for (var b = 0; bounds.length > b; b++) {\n        if (bounds[b] !== h && !bounds[b].contains(h) && (h.compareDocumentPosition(bounds[b]) & 4)) { next = bounds[b]; break; }\n      }\n      var pool = wantText ? paras : lists;\n      for (var k = 0; pool.length > k; k++) {\n        var el = pool[k];\n        if (el === h || el.contains(h) || h.contains(el) || !outsideBuilder(el)) continue;\n        if (!(h.compareDocumentPosition(el) & 4)) continue;\n        if (next && !(el.compareDocumentPosition(next) & 4)) break;\n        if (wantText) { var pt = squash(el.textContent); if (pt.length > 40) return pt.length > 600 ? pt.slice(0, 597) + \"\u2026\" : pt; continue; }\n        if (el.parentNode && el.parentNode.closest && el.parentNode.closest(\"li\")) continue;\n        var items = listItems(el);\n        if (items.length >= 2) return items;\n      }\n      if (wantText) continue;\n      var tables = scope.querySelectorAll(\"table\");\n      for (var tb = 0; tables.length > tb; tb++) {\n        var tbl = tables[tb];\n        if (tbl.contains(h) || !outsideBuilder(tbl) || !(h.compareDocumentPosition(tbl) & 4)) continue;\n        if (next && !(tbl.compareDocumentPosition(next) & 4)) break;\n        var rows = toItems(textLines(tbl).filter(function (l) { return !(25 > l.length && \/:$\/.test(l)); }));\n        if (rows.length >= 3) return rows;\n        break;\n      }\n    }\n    return wantText ? \"\" : [];\n  }\n  \/* The visible lines of a block: a new line at each line break, paragraph, list item and table row. *\/\n  function textLines(el) {\n    var out = [], cur = \"\";\n    (function walk(n) {\n      if (n.nodeType === 3) { cur += n.nodeValue; return; }\n      if (n.nodeType !== 1 || n.tagName === \"SCRIPT\" || n.tagName === \"STYLE\") return;\n      if (n.tagName === \"BR\") { out.push(cur); cur = \"\"; return; }\n      var block = \/^(P|DIV|LI|TR|TD|TH|H[1-6]|UL|OL|TABLE|TBODY|FIGURE|SECTION|BLOCKQUOTE)$\/.test(n.tagName);\n      if (block) { out.push(cur); cur = \"\"; }\n      for (var c = n.firstChild; c; c = c.nextSibling) walk(c);\n      if (block) { out.push(cur); cur = \"\"; }\n    })(el);\n    out.push(cur);\n    return out.map(squash).filter(function (l) { return l.length > 0; });\n  }\n  \/* Cleans lines into bullet points: drops bullet characters and splits one long run-on line into sentences. *\/\n  function toItems(lines) {\n    var out = [];\n    lines.forEach(function (l) {\n      l = squash(l).replace(\/^(?:[\u2022\u00b7\u25aa\u25e6*\u2013-]|[0-9]+[.)])(?=[ ])\/, \"\").trim();\n      if (l.length > 2) out.push(l);\n    });\n    if (out.length === 1 && out[0].length > 150) {\n      out = out[0].replace(\/([a-z]{3})[.](?=[A-Z][a-z])\/g, \"$1.\" + NL).replace(\/([.;]) +(?=[A-Z0-9])\/g, \"$1\" + NL).split(NL).map(squash).filter(function (l) { return l.length > 2; });\n    }\n    return out.map(function (l) { return l.length > 220 ? l.slice(0, 217) + \"\u2026\" : l; }).slice(0, 12);\n  }\n  \/* Sample job descriptions written as bold labels (\"Key Responsibilities:\") followed by lines of text, often inside a\n     one-cell table, rather than as bullet lists. Returns the sections in order: [{ label, lines }]. *\/\n  function labelSections(blocks) {\n    var labels = [], secs = [], cur = null;\n    blocks.forEach(function (b) {\n      var bolds = b.querySelectorAll(\"strong, b, h3, h4, h5, h6\");\n      for (var i = 0; bolds.length > i; i++) { var lb = squash(bolds[i].textContent); if (lb.length > 1 && 60 >= lb.length) labels.push(lb); }\n    });\n    labels.sort(function (a, z) { return z.length - a.length; });\n    blocks.forEach(function (b) {\n      textLines(b).forEach(function (l) {\n        var low = l.toLowerCase(), hit = \"\";\n        for (var i = 0; labels.length > i; i++) {\n          var lb = labels[i];\n          if (low.indexOf(lb.toLowerCase()) === 0 && (l.length === lb.length || \/[:\u2013-]$\/.test(lb) || KNOWN_LABEL.test(lb))) { hit = lb; break; }\n        }\n        if (hit) {\n          cur = { label: hit, lines: [] }; secs.push(cur);\n          var rest = squash(l.slice(hit.length)).replace(\/^[:\u2013-]+\/, \"\").trim();\n          if (rest.length > 2) cur.lines.push(rest);\n        } else if (cur) {\n          if (\/^(send|email|apply|interested|to apply|share your)\/i.test(l)) cur = null; else cur.lines.push(l);\n        }\n      });\n    });\n    return secs;\n  }\n  var KNOWN_LABEL = \/responsibilit|duties|qualification|skills|requirements|eligibility|overview|summary|about the role|job description|benefits|perks\/i;\n  function fromLabels(secs, pattern, wantText) {\n    for (var i = 0; secs.length > i; i++) {\n      if (!pattern.test(secs[i].label)) continue;\n      if (wantText) { var tx = squash(secs[i].lines.join(\" \")); if (tx.length > 40) return tx.length > 600 ? tx.slice(0, 597) + \"\u2026\" : tx; }\n      else { var items = toItems(secs[i].lines); if (items.length >= 2) return items; }\n    }\n    return wantText ? \"\" : [];\n  }\n  function taggedItems(cls) {\n    var el = document.querySelector(\".\" + cls);\n    return el && !root.contains(el) ? listItems(el) : [];\n  }\n  var RESP_RE = \/responsibilit|duties|what you.ll do|key tasks|day-to-day\/i;\n  var QUAL_RE = \/qualification|skills|requirements|eligibility|who you are|what we.re looking for\/i;\n  var SUM_RE = \/job overview|job summary|role overview|about the role|position summary|role summary|job purpose\/i;\n  var BEN_RE = \/benefits|perks|what we offer|why join\/i;\n  \/* Reads the post. kind says how much was found: \"tagged\" (marked blocks), \"auto\" (lists found in the article),\n     \"title\" (only the job title) or \"none\" (nothing; the template is all placeholders). *\/\n  function readPost() {\n    var p = { title: titleFromHeading(), summary: \"\", resp: [], qual: [], ben: [], kind: \"none\" };\n    p.resp = taggedItems(\"jd-responsibilities\"); p.qual = taggedItems(\"jd-qualifications\"); p.ben = taggedItems(\"jd-benefits\");\n    var sumEl = document.querySelector(\".jd-summary\");\n    if (sumEl && !root.contains(sumEl)) p.summary = squash(sumEl.textContent);\n    if (p.resp.length || p.qual.length) p.kind = \"tagged\";\n    else {\n      var scope = articleScope(), sample = null, sampleEnd = null, h2s = Array.prototype.slice.call(scope.querySelectorAll(\"h2\"));\n      \/* The post's own sample job description: the section under an H2 with \"sample\" in it (or else \"template\" \/ \"example\"),\n         skipping the section the builder itself sits in. *\/\n      [\/sample\/i, \/template|example\/i].forEach(function (re) {\n        if (sample) return;\n        for (var i = 0; h2s.length > i; i++) {\n          var h = h2s[i], end = h2s[i + 1] || null;\n          if (!re.test(h.textContent) || !outsideBuilder(h)) continue;\n          var holdsBuilder = (h.compareDocumentPosition(root) & 4) && (!end || (root.compareDocumentPosition(end) & 4));\n          if (holdsBuilder) continue;\n          sample = h; sampleEnd = end; return;\n        }\n      });\n      \/* The sample is the best source; the rest of the article is the fallback.\n         The overview and benefits are only taken from the sample, since articles often have unrelated sections with those words. *\/\n      if (sample) {\n        p.resp = findSection(scope, RESP_RE, false, sample, sampleEnd);\n        p.qual = findSection(scope, QUAL_RE, false, sample, sampleEnd);\n        if (!p.summary) p.summary = findSection(scope, SUM_RE, true, sample, sampleEnd);\n        if (!p.ben.length) p.ben = findSection(scope, BEN_RE, false, sample, sampleEnd);\n        var blocks = [];\n        for (var n = sample.nextElementSibling; n && n !== sampleEnd; n = n.nextElementSibling) {\n          if (n !== root && !n.contains(root) && !root.contains(n)) blocks.push(n);\n        }\n        var secs = labelSections(blocks);\n        if (!p.resp.length) p.resp = fromLabels(secs, RESP_RE, false);\n        if (!p.qual.length) p.qual = fromLabels(secs, QUAL_RE, false);\n        if (!p.summary) p.summary = fromLabels(secs, SUM_RE, true) || fromLabels(secs, \/^job description:?$\/i, true);\n        if (!p.ben.length) p.ben = fromLabels(secs, BEN_RE, false);\n      }\n      if (!p.resp.length) p.resp = findSection(scope, RESP_RE, false);\n      if (!p.qual.length) p.qual = findSection(scope, QUAL_RE, false);\n      p.kind = p.resp.length >= 2 || p.qual.length >= 2 ? \"auto\" : (p.title ? \"title\" : \"none\");\n    }\n    return p;\n  }\n  var post = { title: \"\", summary: \"\", resp: [], qual: [], ben: [], kind: \"none\" };\n  if (String(root.getAttribute(\"data-role\") || \"auto\").trim() !== \"blank\") {\n    try { post = readPost(); } catch (e) { if (window.console && console.warn) console.warn(\"Job description builder: could not read the post.\", e); }\n  }\n  \/* \"an HR Intern\", \"an SEO Executive\", \"a UI\/UX Designer\", \"an Accountant\". *\/\n  function anA(name) {\n    if (\/^[A-Z]{2,}\/.test(name)) return \/^[AEFHILMNORSX]\/.test(name) ? \"an\" : \"a\";\n    return \/^[aeiou]\/i.test(name) ? \"an\" : \"a\";\n  }\n  function isIntern(t) { return \/(^| )interns?( |$)|internship\/i.test(t || \"\"); }\n  \/* The template fields built from what was read; gaps become placeholders. *\/\n  function postValues(p) {\n    var name = p.title, intern = isIntern(name);\n    return {\n      jobTitle: name || \"[Job title]\",\n      details: intern ? \"Internship \u00b7 [Location] \u00b7 [Duration]\" : \"Full-time \u00b7 [Location] \u00b7 [Experience]\",\n      roleText: p.summary || (\"We're looking for \" + (name ? anA(name) + \" \" + name : \"a [job title]\") + \" to [main purpose of the role]. [Add one or two lines about the team and what success looks like.]\"),\n      respList: (p.resp.length ? p.resp : [\"[Main responsibility]\", \"[Another key responsibility]\", \"[Another key responsibility]\"]).join(NL),\n      qualList: (p.qual.length ? p.qual : [\"[Degree or certification required]\", \"[Years of experience]\", \"[Key skill or tool]\"]).join(NL),\n      benList: p.ben.length >= 2 ? p.ben.join(NL) : (intern ? INTERN_BEN : COMMON.benList)\n    };\n  }\n  \/* Used in reports (utm_content, analytics and the sheet's fallback job role): the job read from the post, as a slug. *\/\n  var currentRole = toSlug(post.title) || \"custom\";\n  var state = {};\n  var logoData = '';\n  var $ = function (sel) { return root.querySelector(sel); };\n  var $$ = function (sel) { return Array.prototype.slice.call(root.querySelectorAll(sel)); };\n  var sheets = $$('.cwjd-sheet'), sheet = sheets[0], stage = $('#cwjd-stage'), scaler = $('#cwjd-scale');\n  var uid = 'j' + Math.random().toString(36).slice(2, 10);\n  sheets.forEach(function (sh, n) { sh.setAttribute('data-cwjd-uid', uid + n); });\n  var currentDesign = 'classic';\n  var statusEl = $('#cwjd-status');\n  var cta = $('#cwjd-cta'), downloaded = false;\n  function postSlug() {\n    var parts = window.location.pathname.split('\/').filter(Boolean);\n    return toSlug(parts[parts.length - 1] || '') || 'blog';\n  }\n  \/* Sends a usage event to Google Analytics 4 (gtag) or Google Tag Manager (dataLayer), whichever the site has. *\/\n  function track(name, extra) {\n    var p = { jd_role: currentRole, jd_source: post.kind, jd_design: currentDesign, jd_post: postSlug() }, k;\n    if (extra) { for (k in extra) p[k] = extra[k]; }\n    try {\n      if (typeof window.gtag === 'function') window.gtag('event', name, p);\n      else if (window.dataLayer && typeof window.dataLayer.push === 'function') { var d = { event: name }; for (k in p) d[k] = p[k]; window.dataLayer.push(d); }\n    } catch (e1) {}\n    try { root.dispatchEvent(new CustomEvent('cwjd:track', { bubbles: true, detail: { name: name, params: p } })); } catch (e2) {}\n  }\n  \/* The \"Post this job\" link: the address from data-cta-url plus tracking tags, so sign-ups can be traced to this tool and post. *\/\n  function tagUrl(base, medium) {\n    var hash = '', at = base.indexOf('#');\n    if (at > -1) { hash = base.slice(at); base = base.slice(0, at); }\n    var add = [];\n    if (base.indexOf('utm_source=') === -1) add.push('utm_source=is_blog');\n    if (base.indexOf('utm_medium=') === -1) add.push('utm_medium=' + medium);\n    if (base.indexOf('utm_campaign=') === -1) add.push('utm_campaign=' + encodeURIComponent(postSlug()));\n    if (base.indexOf('utm_content=') === -1) add.push('utm_content=' + encodeURIComponent(currentRole));\n    return base + (add.length ? (base.indexOf('?') > -1 ? '&' : '?') + add.join('&') : '') + hash;\n  }\n  function ctaUrl() { return tagUrl(String(root.getAttribute('data-cta-url') || '').trim() || 'https:\/\/internshala.com\/hire-talent', 'jd_builder'); }\n  function updateCta() { cta.href = ctaUrl(); }\n  \/* Keeps a copy of the finished job description in this browser, so the job-posting form on the same site can pre-fill from it. *\/\n  function saveDraft() {\n    try {\n      window.localStorage.setItem('is_jd_builder_draft', JSON.stringify({\n        v: 1, savedAt: new Date().toISOString(), source: window.location.href, role: currentRole, design: currentDesign,\n        company: state.companyName || '', title: state.jobTitle || '', details: state.details || '', about: state.aboutText || '', summary: state.roleText || '',\n        responsibilities: lines(state.respList), qualifications: lines(state.qualList), benefits: lines(state.benList), applyContact: state.applyContact || ''\n      }));\n    } catch (e) {}\n  }\n  cta.addEventListener('click', function () {\n    saveDraft();\n    track('jd_builder_cta_click', { jd_cta_state: downloaded ? 'after_download' : 'before_download' });\n  });\n  function copy(obj) { var o = {}; for (var k in obj) o[k] = obj[k]; return o; }\n  function lines(text) {\n    return String(text || '').split(NL).map(function (l) {\n      return l.trim().replace(\/^(?:[\u2022\u00b7\u25aa\u25e6]|[*-](?=[ ])|[0-9]+[.)](?=[ ]))\/, '').trim();\n    }).filter(Boolean);\n  }\n  function fillList(el, items) {\n    el.textContent = '';\n    items.forEach(function (item) {\n      var row = document.createElement('div'); row.className = 'cw-li';\n      var box = document.createElement('span'); box.className = 'cw-dotbox';\n      var dot = document.createElement('span'); dot.className = 'cw-dot'; box.appendChild(dot);\n      var txt = document.createElement('span'); txt.textContent = item;\n      row.appendChild(box); row.appendChild(txt); el.appendChild(row);\n    });\n  }\n  function hexToRgb(hex) {\n    var m = \/^#?([0-9a-f]{6})$\/i.exec(String(hex).trim());\n    if (!m) return null;\n    var n = parseInt(m[1], 16);\n    return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n  }\n  function lum(rgb) {\n    var c = rgb.map(function (v) { v \/= 255; return 0.03928 >= v ? v \/ 12.92 : Math.pow((v + 0.055) \/ 1.055, 2.4); });\n    return 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];\n  }\n  function contrast(a, b) { var la = lum(a), lb = lum(b); return (Math.max(la, lb) + 0.05) \/ (Math.min(la, lb) + 0.05); }\n  function applyColor() {\n    var rgb = hexToRgb(state.accent) || hexToRgb('#0f5e5a');\n    var paper = [246, 244, 239];\n    scaler.style.setProperty('--cw-accent', state.accent);\n    scaler.style.setProperty('--cw-on', contrast(rgb, [255, 255, 255]) >= 4.5 ? '#ffffff' : '#1d1d1b');\n    scaler.style.setProperty('--cw-head', contrast(rgb, paper) >= 3 ? state.accent : '#1d1d1b');\n    root.style.setProperty('--ui-accent', contrast(rgb, [255, 255, 255]) >= 3 ? state.accent : '#1d1d1b');\n    $$('.cwjd-swatch').forEach(function (b) { b.setAttribute('aria-pressed', b.getAttribute('data-color').toLowerCase() === String(state.accent).toLowerCase() ? 'true' : 'false'); });\n    var picker = $('#cwjd-color'); if (picker.value.toLowerCase() !== String(state.accent).toLowerCase()) picker.value = state.accent;\n  }\n  function has(key) { return String(state[key] || '').trim() !== ''; }\n  function filled(key) { return \/List$\/.test(key) ? lines(state[key]).length > 0 : has(key); }\n  function render() {\n    $$('[data-out]').forEach(function (el) {\n      var key = el.getAttribute('data-out');\n      var val = String(state[key] || '').trim();\n      var ph = el.getAttribute('data-ph');\n      el.textContent = val || ph || '';\n      el.classList.toggle('cw-ph', !val && !!ph);\n    });\n    $$('[data-hide-empty]').forEach(function (el) { el.hidden = !filled(el.getAttribute('data-hide-empty')); });\n    $$('[data-list]').forEach(function (el) {\n      var items = lines(state[el.getAttribute('data-list')]), half = el.getAttribute('data-half');\n      if (!half) { fillList(el, items); return; }\n      var two = items.length > 5, cut = two ? Math.ceil(items.length \/ 2) : items.length;\n      if (half === 'a') fillList(el, items.slice(0, cut));\n      else { fillList(el, items.slice(cut)); el.hidden = !two; }\n    });\n    $$('[data-two]').forEach(function (el) { el.classList.toggle('cw-single', !(lines(state[el.getAttribute('data-two')]).length > 5)); });\n    $$('[data-pair]').forEach(function (el) {\n      var ks = el.getAttribute('data-pair').split(' '), a = filled(ks[0]), b = filled(ks[1]);\n      el.classList.toggle('cw-single', !(a && b));\n      el.hidden = !a && !b;\n    });\n    scaler.setAttribute('data-font', state.font === 'sans' ? 'sans' : 'serif');\n    $$('.cw-logo').forEach(function (img) {\n      if (logoData) { img.src = logoData; img.alt = (state.companyName || 'Company') + ' logo'; img.hidden = false; }\n      else { img.removeAttribute('src'); img.hidden = true; }\n    });\n    $('#cwjd-logo-remove').hidden = !logoData;\n    applyColor();\n    fit();\n  }\n  function fillForm() {\n    $$('[data-field]').forEach(function (el) { el.value = state[el.getAttribute('data-field')] || ''; });\n  }\n  function loadAny(list, test) {\n    var n = 0;\n    function next() { if (n >= list.length) return Promise.reject(new Error('lib')); return load(list[n++], test).catch(next); }\n    return next();\n  }\n  function load(src, test) {\n    if (test()) return Promise.resolve();\n    return new Promise(function (resolve, reject) {\n      var s = document.createElement('script');\n      s.src = src; s.async = true;\n      s.onload = function () { test() ? resolve() : reject(new Error('lib')); };\n      s.onerror = function () { s.parentNode && s.parentNode.removeChild(s); reject(new Error('net')); };\n      document.head.appendChild(s);\n    });\n  }\n  var app = root.querySelector('.cwjd-app'), col = $('#cwjd-previewcol'), form = root.querySelector('.cwjd-form');\n  var expanded = false, head = 0, mode = '', pinKey = '';\n  \/* Height of the bars that stay at the top of the window (admin bar, sticky site menu), measured as they sit once\n     stuck, so the preview can stay in view just below them. Measured on load, on resize and after scrolling stops,\n     never during scrolling, so scrolling stays smooth. *\/\n  function measureHead() {\n    if (!document.elementsFromPoint) return 0;\n    var off = 0, vw = window.innerWidth || 1200;\n    var x = Math.max(2, Math.round(root.getBoundingClientRect().left + 4));\n    for (var y = 2; 360 > y; y += 14) {\n      var stack = document.elementsFromPoint(x, y), el = null;\n      for (var i = 0; stack.length > i; i++) { if (!root.contains(stack[i])) { el = stack[i]; break; } }\n      while (el && el !== document.body && el !== document.documentElement) {\n        var cs = window.getComputedStyle(el);\n        if (cs.position === 'fixed' || cs.position === 'sticky') {\n          var r = el.getBoundingClientRect();\n          if (r.width > vw * 0.5 && 260 > r.height && r.height > 0) {\n            if (cs.position === 'fixed' && 200 > r.top && r.top > -5) off = Math.max(off, r.bottom);\n            if (cs.position === 'sticky') { var t = parseFloat(cs.top); if (!isNaN(t) && 200 > t) off = Math.max(off, t + r.height); }\n          }\n          break;\n        }\n        el = el.parentElement;\n      }\n    }\n    return Math.round(off);\n  }\n  \/* The browser's own sticky positioning is the smoothest, but a theme wrapper with overflow set blocks it. *\/\n  function stickyWorks() {\n    var el = root.parentElement;\n    while (el && el !== document.body && el !== document.documentElement) {\n      var cs = window.getComputedStyle(el), o = cs.overflowX + ' ' + cs.overflowY;\n      if (o.indexOf('hidden') > -1 || o.indexOf('auto') > -1 || o.indexOf('scroll') > -1) return false;\n      el = el.parentElement;\n    }\n    return true;\n  }\n  function applyHead() { root.style.setProperty('--cwjd-top', (head + 12) + 'px'); }\n  function fit() {\n    if (pinKey) clearPin();\n    var cs = window.getComputedStyle(col);\n    var width = (col.clientWidth - parseFloat(cs.paddingLeft || 0) - parseFloat(cs.paddingRight || 0)) || 1080;\n    var s = Math.min(1, width \/ 1080);\n    var h = sheet.offsetHeight;\n    if (!expanded && root.classList.contains('cwjd-wide')) {\n      var chrome = col.offsetHeight - stage.offsetHeight;\n      var room = (window.innerHeight || 900) - (head + 12) - chrome - 16;\n      s = Math.min(s, Math.max(0.22, room \/ h));\n    }\n    scaler.style.transform = 'scale(' + s + ')';\n    stage.style.width = Math.floor(1080 * s) + 'px';\n    stage.style.height = Math.ceil(h * s) + 'px';\n    pin();\n  }\n  \/* Backup for themes that block sticky: the preview switches between three states (in place, fixed to the window,\n     parked at the bottom of the builder). In the fixed state the browser itself holds it still, so scrolling stays smooth. *\/\n  function clearPin() { col.style.position = ''; col.style.top = ''; col.style.left = ''; col.style.width = ''; col.style.zIndex = ''; pinKey = ''; }\n  function pin() {\n    if (expanded || mode !== 'fixed' || !root.classList.contains('cwjd-wide')) { if (pinKey) clearPin(); return; }\n    var a = app.getBoundingClientRect(), f = form.getBoundingClientRect();\n    var line = head + 12, h = col.offsetHeight;\n    var gap = parseFloat(window.getComputedStyle(app).columnGap) || 24;\n    var left = Math.round(f.right + gap), width = Math.round(a.right - left);\n    var state = a.top >= line ? 'top' : (a.bottom - h >= line ? 'fixed' : 'bottom');\n    var key = state === 'top' ? '' : state + '|' + left + '|' + width + '|' + line + '|' + (state === 'bottom' ? Math.round(a.height - h) + '|' + Math.round(left - a.left) : '');\n    if (key === pinKey) return;\n    if (!key) { clearPin(); return; }\n    col.style.width = width + 'px';\n    col.style.zIndex = '5';\n    if (state === 'fixed') { col.style.position = 'fixed'; col.style.top = line + 'px'; col.style.left = left + 'px'; }\n    else { col.style.position = 'absolute'; col.style.top = Math.round(a.height - h) + 'px'; col.style.left = Math.round(left - a.left) + 'px'; }\n    pinKey = key;\n  }\n  var settleTimer = null;\n  function onScroll() {\n    if (mode === 'fixed') pin();\n    if (settleTimer) clearTimeout(settleTimer);\n    settleTimer = setTimeout(function () {\n      var h2 = measureHead();\n      if (Math.abs(h2 - head) > 4) { head = h2; applyHead(); fit(); }\n    }, 300);\n  }\n  var lastWidth = -1;\n  function layout() {\n    var w = root.clientWidth;\n    if (w !== lastWidth) {\n      lastWidth = w;\n      root.classList.toggle('cwjd-wide', w >= 680);\n      mode = stickyWorks() ? 'sticky' : 'fixed';\n      root.classList.toggle('cwjd-sticky', mode === 'sticky');\n      head = measureHead();\n      applyHead();\n    }\n    fit();\n  }\n  var zoomBtn = $('#cwjd-zoom'), zoomLabel = $('#cwjd-zoom-label'), savedOverflow = '';\n  function onKey(e) { if (e.key === 'Escape' || e.key === 'Esc') setExpanded(false); }\n  function setExpanded(on) {\n    if (on === expanded) return;\n    expanded = on;\n    root.classList.toggle('cwjd-expanded', on);\n    zoomBtn.setAttribute('aria-expanded', on ? 'true' : 'false');\n    zoomLabel.textContent = on ? 'Close preview' : 'Enlarge';\n    if (on) {\n      savedOverflow = document.documentElement.style.overflow;\n      document.documentElement.style.overflow = 'hidden';\n      document.addEventListener('keydown', onKey);\n      col.scrollTop = 0;\n    } else {\n      document.documentElement.style.overflow = savedOverflow;\n      document.removeEventListener('keydown', onKey);\n    }\n    fit();\n    zoomBtn.focus();\n  }\n  zoomBtn.addEventListener('click', function () { setExpanded(!expanded); });\n  stage.addEventListener('click', function () { if (!expanded) setExpanded(true); });\n  \/* The job title without [placeholders], e.g. \"\" while it still reads \"[Job title]\". *\/\n  function realTitle() {\n    var parts = String(state.jobTitle || '').split('['), out = parts[0];\n    for (var i = 1; parts.length > i; i++) { var at = parts[i].indexOf(']'); out += at > -1 ? parts[i].slice(at + 1) : parts[i]; }\n    return squash(out);\n  }\n  function slug() {\n    var s = (realTitle() + ' job description').trim();\n    return s.toLowerCase().replace(\/[^a-z0-9]+\/g, '-').replace(\/^-+|-+$\/g, '') || 'job-description';\n  }\n  function setStatus(msg, isErr) { statusEl.textContent = msg; statusEl.classList.toggle('cwjd-err', !!isErr); }\n  function capture() {\n    var fontsReady = (document.fonts && document.fonts.ready) ? document.fonts.ready : Promise.resolve();\n    var guard = null;\n    function unguard() { if (guard && guard.parentNode) guard.parentNode.removeChild(guard); guard = null; }\n    return load(H2C, function () { return !!window.html2canvas; }).then(function () { return fontsReady; }).then(function () {\n      \/* Themes often style every image tag (borders, display:block). html2canvas measures text with a hidden probe image,\n         so neutralize those styles on the probe while the file is being made, then remove this style again. *\/\n      guard = document.createElement('style');\n      guard.textContent = 'body>div[style*=\"visibility: hidden\"]>img,body>div[style*=\"visibility: hidden\"]>span{border:0 !important;display:inline !important;width:1px;height:1px;max-width:none !important;min-width:0 !important;box-shadow:none !important;float:none !important;position:static !important}body>div[style*=\"visibility: hidden\"]>span{width:auto;height:auto;line-height:inherit}';\n      document.head.appendChild(guard);\n      return window.html2canvas(sheet, {\n        scale: 2, backgroundColor: PAPER[currentDesign] || '#ffffff', useCORS: true, logging: false, windowWidth: 1400,\n        onclone: function (doc) {\n          var cs = doc.querySelector('[data-cwjd-uid=\"' + sheet.getAttribute('data-cwjd-uid') + '\"]');\n          var rt = cs && cs.closest ? cs.closest('.cwjd') : null;\n          if (!rt) return;\n          rt.classList.remove('cwjd-expanded');\n          var pc = rt.querySelector('.cwjd-previewcol');\n          if (pc) { pc.style.transform = 'none'; pc.style.position = 'static'; pc.style.width = 'auto'; }\n          var sc = rt.querySelector('.cwjd-scale'), st = rt.querySelector('.cwjd-stage');\n          if (sc) { sc.style.transform = 'none'; sc.style.position = 'static'; sc.style.left = '0'; }\n          if (st) { st.style.height = 'auto'; st.style.width = '1080px'; st.style.maxWidth = 'none'; st.style.overflow = 'visible'; }\n        }\n      });\n    }).then(function (c) { unguard(); return c; }, function (e) { unguard(); throw e; });\n  }\n  function saveBlob(blob, name) {\n    var url = URL.createObjectURL(blob);\n    var a = document.createElement('a');\n    a.href = url; a.download = name; a.style.display = 'none';\n    document.body.appendChild(a); a.click();\n    setTimeout(function () { URL.revokeObjectURL(url); a.parentNode && a.parentNode.removeChild(a); }, 1500);\n  }\n  var busy = false, edited = false;\n  var fmtSel = $('#cwjd-format'), dlBtn = $('#cwjd-download');\n  function run(fmt, work) {\n    if (busy) return;\n    busy = true;\n    dlBtn.disabled = true; fmtSel.disabled = true;\n    setStatus('Preparing your file\u2026');\n    work().then(function () {\n      setStatus('Done. Check your downloads folder.');\n      track('jd_builder_download', { jd_format: fmt });\n      if (!downloaded) {\n        downloaded = true;\n        cta.classList.add('cwjd-cta-hot');\n        $('#cwjd-cta-lead').textContent = 'Your JD is ready.';\n        $('#cwjd-cta-strong').textContent = 'Post this job on Internshala for free';\n        fit();\n      }\n    }).catch(function (err) {\n      if (window.console && console.error) console.error('Job description builder:', err);\n      setStatus(\"Sorry, the download couldn't be prepared. Please check your connection and try again.\", true);\n    }).then(function () {\n      busy = false;\n      dlBtn.disabled = false; fmtSel.disabled = false;\n    });\n  }\n  function makePng() {\n    return capture().then(function (canvas) {\n      return new Promise(function (resolve, reject) {\n        if (canvas.toBlob) canvas.toBlob(function (blob) { blob ? (saveBlob(blob, slug() + '.png'), resolve()) : reject(new Error('blob')); }, 'image\/png');\n        else { var a = document.createElement('a'); a.href = canvas.toDataURL('image\/png'); a.download = slug() + '.png'; a.click(); resolve(); }\n      });\n    });\n  }\n  function makePdf() {\n    return load(JSPDF, function () { return !!(window.jspdf && window.jspdf.jsPDF); }).then(capture).then(function (canvas) {\n      var w = 595.28, h = w * canvas.height \/ canvas.width;\n      var pdf = new window.jspdf.jsPDF({ orientation: 'portrait', unit: 'pt', format: [w, h], compress: true });\n      pdf.addImage(canvas.toDataURL('image\/jpeg', 0.95), 'JPEG', 0, 0, w, h);\n      pdf.save(slug() + '.pdf');\n    });\n  }\n  \/* Word needs PNG or JPG pictures, so any logo (including SVG and WebP) is redrawn as a PNG first. *\/\n  function logoPng() {\n    if (!logoData) return Promise.resolve(null);\n    return new Promise(function (resolve) {\n      var im = new Image();\n      im.onload = function () {\n        try {\n          var w = im.naturalWidth || 240, h = im.naturalHeight || 80, k = Math.min(1, 640 \/ w, 320 \/ h);\n          var c = document.createElement('canvas');\n          c.width = Math.max(1, Math.round(w * k)); c.height = Math.max(1, Math.round(h * k));\n          c.getContext('2d').drawImage(im, 0, 0, c.width, c.height);\n          c.toBlob(function (b) {\n            if (!b) { resolve(null); return; }\n            b.arrayBuffer().then(function (buf) { resolve({ data: new Uint8Array(buf), w: c.width, h: c.height }); }, function () { resolve(null); });\n          }, 'image\/png');\n        } catch (e) { resolve(null); }\n      };\n      im.onerror = function () { resolve(null); };\n      im.src = logoData;\n    });\n  }\n  \/* Builds an editable Word document from the same content: headings in the brand color, real bullet lists. *\/\n  function makeDocx() {\n    return loadAny(DOCX_SRC, function () { return !!(window.docx && window.docx.Document && window.docx.Packer); }).then(logoPng).then(function (logo) {\n      var D = window.docx;\n      var rgb = hexToRgb(state.accent) || [15, 94, 90];\n      var accent = String(state.accent || '').replace('#', '').toUpperCase();\n      if (accent.length !== 6) accent = '0F5E5A';\n      var headCol = contrast(rgb, [255, 255, 255]) >= 3 ? accent : '1D1D1B';\n      var display = state.font === 'sans' ? 'Calibri' : 'Georgia';\n      var kids = [];\n      function val(key, fallback) { return String(state[key] || '').trim() || fallback || ''; }\n      function tx(text, o) {\n        o = o || {};\n        return new D.TextRun({ text: text, bold: !!o.bold, size: o.size || 22, color: o.color || '1D1D1B', font: o.font || 'Calibri', allCaps: !!o.caps, characterSpacing: o.track || 0 });\n      }\n      function para(runs, o) {\n        o = o || {};\n        var p = { children: runs, spacing: { before: o.before || 0, after: o.after == null ? 120 : o.after } };\n        if (!o.plain) { p.spacing.line = 288; p.spacing.lineRule = D.LineRuleType.AUTO; }\n        if (o.bullet) p.bullet = { level: 0 };\n        if (o.border) p.border = o.border;\n        if (o.keepNext) p.keepNext = true;\n        return new D.Paragraph(p);\n      }\n      function heading(key) { var t = val(key); if (t) kids.push(para([tx(t, { bold: true, size: 28, color: headCol, font: display })], { before: 280, after: 100, keepNext: true, plain: true })); }\n      function block(key) { val(key).split(NL).forEach(function (l) { if (l.trim()) kids.push(para([tx(l.trim())])); }); }\n      function bullets(key) { lines(state[key]).forEach(function (l) { kids.push(para([tx(l)], { bullet: true, after: 40 })); }); }\n      if (logo) {\n        var k = Math.min(1, 170 \/ logo.w, 52 \/ logo.h);\n        kids.push(para([new D.ImageRun({ data: logo.data, transformation: { width: Math.max(1, Math.round(logo.w * k)), height: Math.max(1, Math.round(logo.h * k)) } })], { after: 160, plain: true }));\n      }\n      var top = [tx(val('companyName', '[Company name]'), { bold: true, size: 20, color: headCol, caps: true, track: 40 })];\n      if (val('badge')) top.push(tx('   |   ' + val('badge'), { size: 20, color: '5C5A54', caps: true, track: 40 }));\n      kids.push(para(top, { after: 200 }));\n      kids.push(para([tx(val('jobTitle', '[Job title]'), { bold: true, size: 60, font: display })], { after: 100, plain: true }));\n      kids.push(para(val('details') ? [tx(val('details'), { size: 24, color: '4A4944' })] : [], { after: 200, border: { bottom: { color: accent, space: 12, style: D.BorderStyle.SINGLE, size: 12 } } }));\n      if (val('aboutText')) { heading('aboutHeading'); block('aboutText'); }\n      if (val('roleText')) { heading('roleHeading'); block('roleText'); }\n      if (lines(state.respList).length) { heading('respHeading'); bullets('respList'); }\n      if (lines(state.qualList).length) { heading('qualHeading'); bullets('qualList'); }\n      if (lines(state.benList).length) { heading('benHeading'); bullets('benList'); }\n      heading('applyHeading');\n      var apply = [];\n      if (val('applyText')) apply.push(tx(val('applyText') + ' '));\n      apply.push(tx(val('applyContact', '[Your email or job link]'), { bold: true, color: headCol }));\n      kids.push(para(apply));\n      var doc = new D.Document({\n        creator: val('companyName', 'Job description builder'),\n        title: val('jobTitle', 'Job') + ' job description',\n        styles: { default: { document: { run: { font: 'Calibri', size: 22 } } } },\n        sections: [{ properties: { page: { margin: { top: 900, right: 1150, bottom: 900, left: 1150 } } }, children: kids }]\n      });\n      return D.Packer.toBlob(doc).then(function (blob) { saveBlob(blob, slug() + '.docx'); });\n    });\n  }\n  \/* ---- Sign-up step before download ----\n     Clicking Download first asks the site whether the visitor is already signed in as an employer (it opens\n     data-login-check, default \/employer\/dashboard, in the background: signed-out visitors get the login form there).\n     Signed-in employers download straight away. Everyone else sees a box with the site's own sign-up options, which open\n     in a small window; the download starts as soon as the site confirms the sign-in, and the window is closed.\n     A browser that has completed this once is remembered, so returning employers download straight away. *\/\n  var gate = $('#cwjd-gate'), gateStatusEl = $('#cwjd-gate-status'), gateDone = $('#cwjd-gate-done'), gateLink = $('#cwjd-gate-open');\n  var gateWin = null, gateTimer = null, gateFmt = 'pdf', gateMethod = '', gateShown = false, gateOverflow = '';\n  var gateHref = '', lastProbe = 0, probing = null, confirmClicks = 0;\n  var GATE_KEY = 'is_jd_builder_gate', GATE_DAYS = 30;\n  function attr(name, fallback) { return String(root.getAttribute(name) || '').trim() || fallback; }\n  function gateParam() { var q = \/[?&]jdgate=([^&#]+)\/.exec(window.location.search); return q ? q[1] : ''; }\n  \/* 'signup' (create an Internshala account), 'form' (fill in details that go to a Google Sheet) or 'off'. *\/\n  function gateMode() {\n    var v = gateParam();\n    if (v !== 'on' && v !== 'signup' && v !== 'form') v = attr('data-gate', 'off');\n    if (v === 'on') v = 'signup';\n    return v === 'signup' || v === 'form' ? v : 'off';\n  }\n  function gateOn() { return gateMode() !== 'off'; }\n  function cookieSaysIn() {\n    var n = attr('data-login-cookie', '');\n    return !!n && ('; ' + document.cookie + ';').indexOf('; ' + n + '=') > -1;\n  }\n  function gatePassed() {\n    try {\n      var t = parseInt(window.localStorage.getItem(GATE_KEY) || '0', 10), age = Date.now() - t;\n      if (t > 0 && age >= 0 && GATE_DAYS * 86400000 > age) return true;\n    } catch (e) {}\n    return cookieSaysIn();\n  }\n  function gateRemember() { try { window.localStorage.setItem(GATE_KEY, String(Date.now())); } catch (e) {} }\n  \/* Asks the site whether this browser is signed in as an employer. Resolves true (signed in), false (not signed in)\n     or null (could not tell, e.g. offline). Signed-out visitors get a login form (a password box or a Google login link). *\/\n  function checkSignedIn() {\n    if (probing) return probing;\n    if (cookieSaysIn()) return Promise.resolve(true);\n    if (!window.fetch) return Promise.resolve(null);\n    lastProbe = Date.now();\n    probing = window.fetch(attr('data-login-check', '\/employer\/dashboard'), { credentials: 'same-origin', cache: 'no-store' }).then(function (res) {\n      if (!res.ok) return null;\n      var path = '';\n      try { path = new URL(res.url, window.location.href).pathname; } catch (e) {}\n      return res.text().then(function (html) {\n        var loginForm = html.indexOf('type=\"password\"') > -1 || html.indexOf(\"type='password'\") > -1 || html.indexOf('type=password') > -1 || html.indexOf('login\/get_google') > -1;\n        return !loginForm && path.indexOf('\/employer') === 0;\n      });\n    }).then(function (v) { probing = null; return v; }, function () { probing = null; return null; });\n    return probing;\n  }\n  function gateStatus(msg) { gateStatusEl.textContent = msg || ''; }\n  function gateFallback(msg, withLink) {\n    if (msg) gateStatus(msg);\n    gateLink.hidden = !withLink;\n    if (attr('data-gate-fallback', 'on') !== 'off' || withLink) gateDone.hidden = false;\n    $('#cwjd-gate-continue').hidden = attr('data-gate-fallback', 'on') === 'off';\n  }\n  function gateStopWatch() { if (gateTimer) { clearInterval(gateTimer); gateTimer = null; } }\n  \/* Re-checks the sign-in now (soon=true) or at most every 8 seconds; finishes the download when it is confirmed. *\/\n  function gateVerify(soon) {\n    if (!gateShown) return Promise.resolve(false);\n    if (!soon && 8000 > Date.now() - lastProbe) return Promise.resolve(false);\n    return checkSignedIn().then(function (v) {\n      if (v === true && gateShown) gateSuccess('verified');\n      return v;\n    });\n  }\n  \/* Watches the sign-up window. Each time it moves to a new page on this site (for example after the Google step or after\n     the form is sent), the sign-in is checked. Pages on other sites, such as Google's, cannot be read and are skipped. *\/\n  function gateTick() {\n    if (!gateShown) return;\n    if (cookieSaysIn()) { gateSuccess('cookie'); return; }\n    if (!gateWin) { gateVerify(false); return; }\n    var closed = true;\n    try { closed = !!gateWin.closed; } catch (e) { closed = true; }\n    if (closed) {\n      gateWin = null; gateStopWatch();\n      gateStatus('Checking your sign-in\u2026');\n      gateVerify(true).then(function (v) { if (gateShown && v !== true) gateFallback('The sign-up window was closed before sign-in finished.', false); });\n      return;\n    }\n    var href = '';\n    try { var loc = gateWin.location; if (loc && loc.origin === window.location.origin) href = String(loc.href); } catch (e2) {}\n    if (href && href !== gateHref) { gateHref = href; setTimeout(function () { gateVerify(true); }, 400); return; }\n    gateVerify(false);\n  }\n  function gateKeys(e) {\n    if (e.key === 'Escape' || e.key === 'Esc') { closeGate(true); return; }\n    if (e.key !== 'Tab') return;\n    var items = Array.prototype.slice.call(gate.querySelectorAll('button, a[href], input:not([tabindex])')).filter(function (el) { return el.offsetParent !== null; });\n    if (!items.length) return;\n    var first = items[0], last = items[items.length - 1];\n    if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }\n    else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }\n  }\n  function onGateFocus() {\n    if (!gateShown || !gateMethod) return;\n    gateVerify(true).then(function (v) { if (gateShown && v !== true && !gateWin) gateFallback('', !gateLink.hidden); });\n  }\n  function onGateMessage(e) {\n    if (!gateShown || e.origin !== window.location.origin) return;\n    if (e.data && e.data.cwjd === 'signed-in') gateSuccess('message');\n  }\n  function openGate(fmt) {\n    gateFmt = fmt; gateMethod = ''; gateShown = true; gateHref = ''; confirmClicks = 0;\n    gateStatus(''); gateDone.hidden = true; gateLink.hidden = true;\n    gate.hidden = false;\n    gateOverflow = document.documentElement.style.overflow;\n    document.documentElement.style.overflow = 'hidden';\n    document.addEventListener('keydown', gateKeys);\n    window.addEventListener('focus', onGateFocus);\n    window.addEventListener('message', onGateMessage);\n    var formMode = gateMode() === 'form';\n    $('#cwjd-gate-signup').hidden = formMode;\n    gateForm.hidden = !formMode;\n    gateFormErr('');\n    $('#cwjd-gate-title').textContent = formMode ? 'Get your job description' : 'Sign up free to download your job description';\n    $('#cwjd-gate-sub').textContent = formMode ? 'Fill in a few details and your download starts right away.' : 'Create your free Internshala employer account to download this JD, then post the job to reach candidates.';\n    $('#cwjd-gate-login-lead').textContent = formMode ? 'Already registered on Internshala?' : 'Already have an account?';\n    $('#cwjd-gate-terms-lead').textContent = formMode ? 'By submitting, you agree to be contacted by Internshala about hiring and to our' : 'By signing up, you agree to our';\n    if (formMode) {\n      if (!gateForm.elements.company.value.trim()) gateForm.elements.company.value = String(state.companyName || '').trim();\n      gateForm.elements.first_name.focus();\n    } else { $('#cwjd-gate-google').focus(); }\n    track('jd_builder_gate_open', { jd_format: fmt, jd_gate: formMode ? 'form' : 'signup' });\n  }\n  function closeGate(byUser) {\n    if (!gateShown) return;\n    gateShown = false;\n    gateStopWatch();\n    gate.hidden = true;\n    document.documentElement.style.overflow = gateOverflow;\n    document.removeEventListener('keydown', gateKeys);\n    window.removeEventListener('focus', onGateFocus);\n    window.removeEventListener('message', onGateMessage);\n    if (byUser) { track('jd_builder_gate_close', { jd_signup_started: gateMethod || 'no' }); dlBtn.focus(); }\n  }\n  function gateSuccess(how) {\n    if (!gateShown) return;\n    var w = gateWin; gateWin = null;\n    gateRemember();\n    try { if (w && !w.closed) w.close(); } catch (e) {}\n    closeGate(false);\n    track('jd_builder_signup_complete', { jd_method: gateMethod || 'unknown', jd_detect: how, jd_format: gateFmt });\n    startDownload(gateFmt);\n  }\n  function gateUrl(method) {\n    var base = method === 'google' ? attr('data-google-url', 'https:\/\/internshala.com\/login\/get_google\/employer\/employer%2Fdashboard')\n      : (method === 'login' ? attr('data-login-url', 'https:\/\/internshala.com\/login\/employer') : attr('data-cta-url', 'https:\/\/internshala.com\/hire-talent'));\n    return tagUrl(base, 'jd_builder_download');\n  }\n  function gateGo(method) {\n    var url = gateUrl(method);\n    gateMethod = method; gateHref = '';\n    saveDraft();\n    track('jd_builder_signup_click', { jd_method: method });\n    var wpx = 520, hpx = 720, sw = (window.screen && window.screen.width) || 1280, sh = (window.screen && window.screen.height) || 800;\n    var feat = 'width=' + wpx + ',height=' + hpx + ',left=' + Math.max(0, Math.round((sw - wpx) \/ 2)) + ',top=' + Math.max(0, Math.round((sh - hpx) \/ 2));\n    gateStopWatch();\n    try { gateWin = window.open(url, 'is_jd_signup', feat); } catch (e) { gateWin = null; }\n    if (!gateWin) {\n      gateLink.href = url;\n      gateFallback('Your browser blocked the sign-up window. Open it in a new tab, sign in, then come back here.', true);\n      gateTimer = setInterval(gateTick, 1000);\n      return;\n    }\n    try { gateWin.focus(); } catch (e3) {}\n    gateDone.hidden = true;\n    gateStatus('Finish signing in in the window that just opened. Your download will start here automatically.');\n    gateTimer = setInterval(gateTick, 600);\n  }\n  $('#cwjd-gate-google').addEventListener('click', function () { gateGo('google'); });\n  $('#cwjd-gate-email').addEventListener('click', function () { gateGo('email'); });\n  $('#cwjd-gate-login').addEventListener('click', function () { gateGo('login'); });\n  $('#cwjd-gate-close').addEventListener('click', function () { closeGate(true); });\n  \/* \"I've signed in\": checks with the site first. If the site can't be reached, or the visitor clicks a second time,\n     the download goes ahead, so nobody is ever left stuck. *\/\n  $('#cwjd-gate-continue').addEventListener('click', function () {\n    var btn = this;\n    confirmClicks++;\n    btn.disabled = true;\n    gateStatus('Checking your sign-in\u2026');\n    checkSignedIn().then(function (v) {\n      btn.disabled = false;\n      if (v === true) gateSuccess('verified');\n      else if (v === null || confirmClicks >= 2) gateSuccess('unverified');\n      else gateStatus(\"We can't see a sign-in yet. Finish signing in, then click the button again.\");\n    });\n  });\n  gateLink.addEventListener('click', function () { gateMethod = gateMethod || 'email'; });\n  gate.addEventListener('mousedown', function (e) { if (e.target === gate) closeGate(true); });\n  if (gateParam() === 'reset') { try { window.localStorage.removeItem(GATE_KEY); } catch (e) {} }\n  \/* ---- Details form (data-gate=\"form\") ----\n     Sends the details to the address in data-lead-url (a Google Apps Script web app that adds a row to a Google Sheet),\n     then starts the download. The download never waits more than 4 seconds for the sheet, and still happens if it fails. *\/\n  var gateForm = $('#cwjd-gate-form'), gateFormErrEl = $('#cwjd-gate-ferr');\n  function gateFormErr(msg, field) {\n    gateFormErrEl.textContent = msg || '';\n    Array.prototype.forEach.call(gateForm.querySelectorAll('input'), function (el) { el.removeAttribute('aria-invalid'); });\n    if (field) { field.setAttribute('aria-invalid', 'true'); field.focus(); }\n  }\n  function leadValues() {\n    var f = gateForm.elements;\n    return {\n      first_name: f.first_name.value.trim(), last_name: f.last_name.value.trim(), email: f.email.value.trim(),\n      mobile: f.mobile.value.replace(\/[^0-9]\/g, ''), company: f.company.value.trim(), website: f.website.value\n    };\n  }\n  function leadProblem(v) {\n    var f = gateForm.elements;\n    if (!v.first_name) return ['Please enter your first name.', f.first_name];\n    if (!v.last_name) return ['Please enter your last name.', f.last_name];\n    if (!\/^[^ @]+@[^ @]+[.][^ @]+$\/.test(v.email)) return ['Please enter a valid email address.', f.email];\n    if (v.mobile.length === 12 && v.mobile.indexOf('91') === 0) v.mobile = v.mobile.slice(2);\n    if (v.mobile.length === 11 && v.mobile.charAt(0) === '0') v.mobile = v.mobile.slice(1);\n    if (v.mobile.length !== 10) return ['Please enter a 10-digit mobile number.', f.mobile];\n    if (!v.company) return ['Please enter your company name.', f.company];\n    return null;\n  }\n  function sendLead(v) {\n    var url = attr('data-lead-url', '');\n    if (!url || !window.fetch || !window.URLSearchParams) {\n      if (!url && window.console && console.warn) console.warn('Job description builder: data-lead-url is not set, so form details are not being saved.');\n      return Promise.resolve('no');\n    }\n    var body = new URLSearchParams();\n    body.append('first_name', v.first_name); body.append('last_name', v.last_name); body.append('email', v.email);\n    body.append('mobile', '+91 ' + v.mobile); body.append('company', v.company); body.append('website', v.website);\n    body.append('job_role', realTitle() || post.title || '(not filled in)'); body.append('template', currentDesign); body.append('format', gateFmt);\n    body.append('blog_post', postSlug()); body.append('page_url', window.location.origin + window.location.pathname);\n    var sent = window.fetch(url, { method: 'POST', mode: 'no-cors', body: body, keepalive: true }).then(function () { return 'yes'; }, function () { return 'no'; });\n    var slow = new Promise(function (resolve) { setTimeout(function () { resolve('slow'); }, 4000); });\n    return Promise.race([sent, slow]);\n  }\n  gateForm.addEventListener('submit', function (e) {\n    e.preventDefault();\n    var v = leadValues(), problem = leadProblem(v);\n    if (problem) { gateFormErr(problem[0], problem[1]); return; }\n    gateFormErr('');\n    var btn = $('#cwjd-gate-submit');\n    btn.disabled = true;\n    gateStatus('Preparing your download\u2026');\n    if (v.website) { gateMethod = 'form'; gateSuccess('form'); btn.disabled = false; return; }\n    sendLead(v).then(function (result) {\n      btn.disabled = false;\n      gateStatus('');\n      track('jd_builder_lead_submit', { jd_lead_saved: result });\n      gateMethod = 'form';\n      gateSuccess('form');\n    });\n  });\n  function startDownload(f) { run(f, f === 'pdf' ? makePdf : (f === 'docx' ? makeDocx : makePng)); }\n  dlBtn.addEventListener('click', function () {\n    var f = fmtSel.value;\n    if (!gateOn() || gatePassed()) { startDownload(f); return; }\n    if (busy) return;\n    dlBtn.disabled = true;\n    setStatus('Checking your sign-in\u2026');\n    checkSignedIn().then(function (v) {\n      dlBtn.disabled = false;\n      setStatus('');\n      if (v === true) { gateRemember(); track('jd_builder_already_signed_in', { jd_format: f }); startDownload(f); }\n      else openGate(f);\n    });\n  });\n  $$('[data-field]').forEach(function (el) {\n    el.addEventListener('input', function () {\n      state[el.getAttribute('data-field')] = el.value; render();\n      if (!edited) { edited = true; track('jd_builder_edit', { jd_field: el.getAttribute('data-field') }); }\n    });\n    el.addEventListener('change', function () { state[el.getAttribute('data-field')] = el.value; render(); });\n  });\n  $$('.cwjd-swatch').forEach(function (b) {\n    b.addEventListener('click', function () { state.accent = b.getAttribute('data-color'); render(); });\n  });\n  $('#cwjd-color').addEventListener('input', function () { state.accent = this.value; render(); });\n  $('#cwjd-logo').addEventListener('change', function () {\n    var file = this.files && this.files[0];\n    if (!file) return;\n    if (['image\/png', 'image\/jpeg', 'image\/webp', 'image\/svg+xml'].indexOf(file.type) === -1) { setStatus('Please choose a PNG, JPG, WebP or SVG image.', true); this.value = ''; return; }\n    if (file.size > 3 * 1024 * 1024) { setStatus('That logo is over 3 MB. Please use a smaller file.', true); this.value = ''; return; }\n    var reader = new FileReader();\n    reader.onload = function () { logoData = String(reader.result); setStatus(''); render(); };\n    reader.readAsDataURL(file);\n  });\n  $('#cwjd-logo-remove').addEventListener('click', function () { logoData = ''; $('#cwjd-logo').value = ''; render(); });\n  var designSel = $('#cwjd-design');\n  function pickDesign() {\n    var q = \/[?&]jddesign=([^&#]+)\/.exec(window.location.search);\n    if (q && DESIGNS.indexOf(decodeURIComponent(q[1])) > -1) return decodeURIComponent(q[1]);\n    var attr = String(root.getAttribute('data-design') || '').trim();\n    return DESIGNS.indexOf(attr) > -1 ? attr : 'classic';\n  }\n  function setDesign(id) {\n    currentDesign = DESIGNS.indexOf(id) > -1 ? id : 'classic';\n    sheets.forEach(function (sh) {\n      var on = sh.getAttribute('data-design') === currentDesign;\n      sh.hidden = !on;\n      if (on) sheet = sh;\n    });\n    designSel.value = currentDesign;\n    fit();\n  }\n  designSel.addEventListener('change', function () {\n    var from = currentDesign;\n    setDesign(designSel.value);\n    track('jd_builder_design_change', { jd_from_design: from });\n  });\n  \/* Fills the role fields from the post (also used by Reset). Company details are not touched. *\/\n  function applyPost() {\n    var vals = postValues(post);\n    ROLE_FIELDS.forEach(function (k) { state[k] = vals[k]; });\n  }\n  $('#cwjd-reset').addEventListener('click', function () {\n    if (!window.confirm('Reset every field back to the template from this article? Your changes will be lost.')) return;\n    state = copy(COMMON); logoData = ''; $('#cwjd-logo').value = ''; applyPost();\n    fillForm(); setStatus(''); render(); updateCta();\n  });\n  $('#cwjd-clear').addEventListener('click', function () {\n    var next = {}, all = copy(COMMON);\n    ROLE_FIELDS.forEach(function (k) { all[k] = ''; });\n    for (var k in all) next[k] = KEEP_ON_CLEAR.indexOf(k) > -1 ? state[k] : '';\n    state = next; fillForm(); setStatus(''); render();\n  });\n  if (window.name === 'is_jd_signup' && window.opener) { try { window.opener.postMessage({ cwjd: 'signed-in' }, window.location.origin); } catch (e) {} }\n  state = copy(COMMON);\n  applyPost();\n  fillForm();\n  updateCta();\n  render();\n  setDesign(pickDesign());\n  layout();\n  \/* Counts a view once, the first time the builder actually scrolls into sight. *\/\n  if (window.IntersectionObserver) {\n    var seen = new IntersectionObserver(function (entries) {\n      for (var i = 0; entries.length > i; i++) {\n        if (entries[i].isIntersecting) { seen.disconnect(); track('jd_builder_view'); break; }\n      }\n    }, { threshold: 0.5 });\n    seen.observe(root.querySelector('.cwjd-formhead') || root);\n  } else { track('jd_builder_view'); }\n  if (window.ResizeObserver) {\n    new ResizeObserver(layout).observe(root);\n    var sheetWatch = new ResizeObserver(function () { fit(); });\n    sheets.forEach(function (sh) { sheetWatch.observe(sh); });\n  }\n  window.addEventListener('resize', layout);\n  window.addEventListener('scroll', onScroll, { passive: true });\n  if (document.fonts && document.fonts.ready) document.fonts.ready.then(fit);\n  }\n})();\n<\/script>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Laravel_Developer_Job_Description_Sample\"><\/span>Laravel Developer Job Description Sample<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>A Laravel developer job description outlines the responsibilities, technical skills, and qualifications required for an entry-level role. It helps candidates understand the position\u2019s expectations, including developing web features, fixing bugs, and supporting senior developers. The following sample provides a practical example for employers hiring junior Laravel developers.\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Junior Laravel Developer Job Description<\/strong><br><br><strong>Job Title:<\/strong> Junior Laravel Developer<br><strong>Company:<\/strong> Nexora Digital Solutions<br><strong>Location:<\/strong> Noida, Uttar Pradesh<br><strong>Employment Type:<\/strong> Full-Time<br><br><strong>Job Summary<\/strong><br><br>Nexora Digital Solutions is hiring a Junior Laravel Developer to support its web development team. The selected candidate will help build new website features, maintain existing applications, and improve backend functionality. This role suits an early-career developer who enjoys coding, solving technical problems, and learning modern web development practices through practical projects and team collaboration.<br><br><strong>Key Responsibilities<\/strong><br><br>Develop backend features for websites and web applications using Laravel and PHP.<br>Write maintainable code that follows established development standards.<br>Assist with database operations, including queries, migrations, and data management.<br>Support the development and integration of APIs for different application features.<br>Investigate software issues and help implement suitable fixes.<br>Conduct basic testing to verify application functionality and identify errors.<br>Work with senior developers to improve existing code and implement new features.<br>Update technical documentation and maintain accurate project records.<br><br><strong>Required Skills and Qualifications<\/strong><br><br>Bachelor&#8217;s degree in Computer Applications, Computer Science, Information Technology, or a related discipline.<br>Working knowledge of object-oriented programming, PHP, and Laravel fundamentals.<br>Familiarity with MySQL, database relationships, and SQL queries.<br>Basic understanding of HTML, CSS, JavaScript, and responsive web design.<br>Familiarity with Git or similar version control systems.Understanding of REST APIs, routing, controllers, and Laravel&#8217;s MVC structure.<br>Good analytical thinking, attention to detail, and communication skills.<br><br><strong>Experience Requirements<\/strong><br><br>Applicants should have up to two years of experience in web development. Fresh graduates with relevant academic projects, internship experience, or a portfolio demonstrating Laravel skills are encouraged to apply.<br><br><strong>Salary and Benefits<\/strong><br><br>The selected candidate will receive a competitive salary based on their technical knowledge and experience. <br>Benefits include paid leave, mentorship from experienced developers, opportunities to learn new technologies, and professional growth within the development team.<br><br><strong>Work Details<\/strong><br><br>This is a full-time, office-based position in Noida. The developer will work closely with the backend development team and participate in project discussions, code reviews, and regular progress meetings.<br><br><strong>How to Apply?<\/strong><br><br>Candidates can email their updated resume and links to relevant projects to <strong>careers@nexoradigital.example<\/strong>. Shortlisted applicants will be contacted for a technical assessment and interview.<br><br>Nexora Digital Solutions evaluates applicants based on their relevant skills, qualifications, and suitability for the position.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>Read More: <\/strong>Explore <a href=\"https:\/\/internshala.com\/blog\/employer-ai-powered-hiring-solutions-by-internshala\/\" target=\"_blank\" rel=\"noreferrer noopener\">AI-powered hiring solutions by Internshala<\/a> to streamline candidate screening and identify applicants whose skills match your job requirements. Combine AI-driven insights with human evaluation to assess candidates more effectively and make informed hiring decisions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Cost_of_Hiring_a_Laravel_Developer\"><\/span>Cost of Hiring a Laravel Developer<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The cost of hiring a Laravel developer in India varies based on experience level, technical expertise, and project requirements. More experienced developers often earn higher salaries because they can handle complex applications, optimize performance, and lead development projects. Businesses can use the following salary ranges to estimate annual hiring costs.<\/p>\n\n\n\n<p>Here is the average annual salary range for Laravel developers:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Experience Level<\/strong><\/td><td><strong>Average Annual Salary Range<\/strong><\/td><\/tr><tr><td><strong>Entry-Level (0 &#8211; 2 Years)<\/strong><\/td><td>\u20b93 LPA &#8211; \u20b93.35 LPA<\/td><\/tr><tr><td><strong>Intermediate Level (3 &#8211; 5 Years)<\/strong><\/td><td>\u20b95 LPA &#8211; \u20b97.5 LPA<\/td><\/tr><tr><td><strong>Experienced Level (6+ Years)<\/strong><\/td><td>\u20b95 LPA &#8211; \u20b910 LPA<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>Read More: <\/strong>When calculating the <a href=\"https:\/\/internshala.com\/blog\/employer-cost-to-hire-remote-team\/\" target=\"_blank\" rel=\"noreferrer noopener\">cost to hire a remote team<\/a>, consider more than salaries. Include recruitment fees, onboarding, software licenses, equipment, and ongoing communication costs. Comparing these expenses across hiring locations can help you plan your budget and avoid unexpected costs.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large desktop-image\"><a href=\"https:\/\/internshala.com\/post-job\/?utm_source=is_blog&amp;utm_medium=employer-laravel-developer-job-description&amp;utm_campaign=employer-web-banner\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"203\" src=\"https:\/\/internshala.com\/blog\/wp-content\/uploads\/2024\/08\/Post-your-job-nowweb-1024x203.jpg\" alt=\"Post your job now(web)\" class=\"wp-image-24468\" srcset=\"https:\/\/internshala.com\/blog\/wp-content\/uploads\/2024\/08\/Post-your-job-nowweb-1024x203.jpg 1024w, https:\/\/internshala.com\/blog\/wp-content\/uploads\/2024\/08\/Post-your-job-nowweb-672x133.jpg 672w, https:\/\/internshala.com\/blog\/wp-content\/uploads\/2024\/08\/Post-your-job-nowweb-1536x305.jpg 1536w, https:\/\/internshala.com\/blog\/wp-content\/uploads\/2024\/08\/Post-your-job-nowweb-2048x406.jpg 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full mobile-image\"><a href=\"https:\/\/internshala.com\/post-job\/?utm_source=is_blog&amp;utm_medium=employer-laravel-developer-job-description&amp;utm_campaign=employer-mobile-banner\" target=\"_blank\" rel=\"noreferrer noopener\"><img loading=\"lazy\" decoding=\"async\" width=\"356\" height=\"256\" src=\"https:\/\/internshala.com\/blog\/wp-content\/uploads\/2024\/08\/Post-your-job-nowmobile.jpg\" alt=\"Post your job now (mobile)\" class=\"wp-image-24469\"\/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>In this blog, we have covered how to write a perfect Laravel developer job description. From outlining key responsibilities and technical skills to setting experience requirements and salary expectations, each element helps attract suitable candidates. A clear, well-structured job description also makes it easier to identify applicants who match your team&#8217;s needs.<\/p>\n\n\n\n<p>Once you have finalized the job description and shortlisted candidates, the next step is preparing for interviews. Wondering which questions can help you assess their Laravel knowledge and practical skills? Explore our guide to <a href=\"https:\/\/internshala.com\/blog\/top-laravel-interview-questions-and-answers\/\" target=\"_blank\" rel=\"noreferrer noopener\">Laravel interview questions and answers<\/a> to prepare relevant questions and make informed hiring decisions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"FAQs\"><\/span>FAQs<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<div class=\"schema-faq wp-block-yoast-faq-block\"><div class=\"schema-faq-section\" id=\"faq-question-1792688376660\"><strong class=\"schema-faq-question\">Q1. <strong>Can a Laravel developer work remotely?<\/strong><\/strong> <p class=\"schema-faq-answer\">Yes, many Laravel developers work remotely. They use collaboration tools, version control systems, and project management platforms to coordinate with teams, review code, and deliver application updates.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1792688388788\"><strong class=\"schema-faq-question\">Q2. <strong>What is the difference between a junior and senior Laravel developer?<\/strong><\/strong> <p class=\"schema-faq-answer\">Junior developers typically handle assigned coding tasks, bug fixes, and basic application features. Senior developers manage complex development work, make architectural decisions, optimize systems, and mentor other team members.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1792688407794\"><strong class=\"schema-faq-question\">Q3. <strong>Should a Laravel developer job description mention database skills?<\/strong><\/strong> <p class=\"schema-faq-answer\">Yes, database skills are important for Laravel development. Employers should mention relevant technologies, such as MySQL or PostgreSQL, along with database design, query optimization, migrations, and relationships.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1792688425474\"><strong class=\"schema-faq-question\">Q4. <strong>Is knowledge of APIs necessary for Laravel developers?<\/strong><\/strong> <p class=\"schema-faq-answer\">Yes, API development is a valuable skill for Laravel developers. Developers often build REST APIs, connect third-party services, manage authentication, and exchange data between web applications and other systems.<\/p> <\/div> <\/div>\n<aside class=\"mashsb-container mashsb-main \"><div class=\"mashsb-box\"><div class=\"mashsb-count mash-medium\" style=\"float:left\"><div class=\"counts mashsbcount\">0<\/div><span class=\"mashsb-sharetext\">SHARES<\/span><\/div><div class=\"mashsb-buttons\"><a class=\"mashicon-facebook mash-medium mashsb-noshadow\" href=\"https:\/\/www.facebook.com\/sharer.php?u=https%3A%2F%2Finternshala.com%2Fblog%2Femployer-laravel-developer-job-description%2F\" target=\"_top\" rel=\"nofollow\"><span class=\"icon\"><\/span><span class=\"text\">Share&nbsp;on&nbsp;Facebook<\/span><\/a><a class=\"mashicon-subscribe mash-medium mashsb-noshadow\" href=\"#\" target=\"_top\" rel=\"nofollow\"><span class=\"icon\"><\/span><span class=\"text\">Get&nbsp;Your&nbsp;Dream&nbsp;Internship<\/span><\/a><div class=\"onoffswitch2 mash-medium mashsb-noshadow\" style=\"display:none\"><\/div><\/div>\n            <\/div>\n                <div style=\"clear:both\"><\/div><\/aside>\n            <!-- Share buttons by mashshare.net - Version: 4.0.42-->","protected":false},"excerpt":{"rendered":"<p>Summary: Employers should assess Laravel developers based on project needs, technical expertise, and the complexity of assigned tasks. A junior developer may handle routine fixes, while a senior developer can<\/p>\n","protected":false},"author":6502,"featured_media":30750,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[4319],"tags":[],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Laravel Developer Job Description [with Free Template]<\/title>\n<meta name=\"description\" content=\"Explore Laravel developer job descriptions, key responsibilities, required skills, salary ranges, and sample templates to help you hire the right talent.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Laravel Developer Job Description [with Free Template]\" \/>\n<meta property=\"og:description\" content=\"Explore Laravel developer job descriptions, key responsibilities, required skills, salary ranges, and sample templates to help you hire the right talent.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/\" \/>\n<meta property=\"og:site_name\" content=\"Internshala blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-23T05:05:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-22T17:06:01+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/internshala.com\/blog\/wp-content\/uploads\/2026\/10\/Laravel-Developer-Job-Description.png\" \/>\n\t<meta property=\"og:image:width\" content=\"900\" \/>\n\t<meta property=\"og:image:height\" content=\"600\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Shobha Saini\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Shobha Saini\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/\"},\"author\":{\"name\":\"Shobha Saini\",\"@id\":\"https:\/\/internshala.com\/blog\/#\/schema\/person\/c220799e53244b6b0da150e24591978f\"},\"headline\":\"Laravel Developer Job Description [with Free Template]\",\"datePublished\":\"2026-10-23T05:05:00+00:00\",\"dateModified\":\"2026-10-22T17:06:01+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/\"},\"wordCount\":1439,\"publisher\":{\"@id\":\"https:\/\/internshala.com\/blog\/#organization\"},\"articleSection\":[\"HR Resources\"],\"inLanguage\":\"en-US\"},{\"@type\":[\"WebPage\",\"FAQPage\"],\"@id\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/\",\"url\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/\",\"name\":\"Laravel Developer Job Description [with Free Template]\",\"isPartOf\":{\"@id\":\"https:\/\/internshala.com\/blog\/#website\"},\"datePublished\":\"2026-10-23T05:05:00+00:00\",\"dateModified\":\"2026-10-22T17:06:01+00:00\",\"description\":\"Explore Laravel developer job descriptions, key responsibilities, required skills, salary ranges, and sample templates to help you hire the right talent.\",\"breadcrumb\":{\"@id\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#breadcrumb\"},\"mainEntity\":[{\"@id\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688376660\"},{\"@id\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688388788\"},{\"@id\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688407794\"},{\"@id\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688425474\"}],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/internshala.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Employer Resources\",\"item\":\"https:\/\/internshala.com\/blog\/employer-resources\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"HR Resources\",\"item\":\"https:\/\/internshala.com\/blog\/employer-resources\/hr-resources\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Laravel Developer Job Description\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/internshala.com\/blog\/#website\",\"url\":\"https:\/\/internshala.com\/blog\/\",\"name\":\"Internshala blog\",\"description\":\"Your favourite senior outside college\",\"publisher\":{\"@id\":\"https:\/\/internshala.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/internshala.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/internshala.com\/blog\/#organization\",\"name\":\"Internshala blog\",\"url\":\"https:\/\/internshala.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/internshala.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/internshala.com\/blog\/wp-content\/uploads\/2023\/08\/LOGO-1.png\",\"contentUrl\":\"https:\/\/internshala.com\/blog\/wp-content\/uploads\/2023\/08\/LOGO-1.png\",\"width\":112,\"height\":31,\"caption\":\"Internshala blog\"},\"image\":{\"@id\":\"https:\/\/internshala.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/internshala.com\/blog\/#\/schema\/person\/c220799e53244b6b0da150e24591978f\",\"name\":\"Shobha Saini\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/internshala.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/internshala.com\/blog\/wp-content\/uploads\/2023\/12\/Shobha-96x96.jpg\",\"contentUrl\":\"https:\/\/internshala.com\/blog\/wp-content\/uploads\/2023\/12\/Shobha-96x96.jpg\",\"caption\":\"Shobha Saini\"},\"description\":\"Shobha Saini is the Head of Human Resources at Internshala with over eight years of experience in employee relations and talent acquisition. She has led strategic HR initiatives and built effective people practices across the organization. She specializes in strategic planning, policy-making, and performance management. A multi-talented professional, she has played a key role in shaping HR strategies at Internshala.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/shobha-saini-she-her-7a95131a\/\"],\"url\":\"https:\/\/internshala.com\/blog\/author\/shobha-saini\/\"},{\"@type\":\"Question\",\"@id\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688376660\",\"position\":1,\"url\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688376660\",\"name\":\"Q1. Can a Laravel developer work remotely?\",\"answerCount\":1,\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Yes, many Laravel developers work remotely. They use collaboration tools, version control systems, and project management platforms to coordinate with teams, review code, and deliver application updates.\",\"inLanguage\":\"en-US\"},\"inLanguage\":\"en-US\"},{\"@type\":\"Question\",\"@id\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688388788\",\"position\":2,\"url\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688388788\",\"name\":\"Q2. What is the difference between a junior and senior Laravel developer?\",\"answerCount\":1,\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Junior developers typically handle assigned coding tasks, bug fixes, and basic application features. Senior developers manage complex development work, make architectural decisions, optimize systems, and mentor other team members.\",\"inLanguage\":\"en-US\"},\"inLanguage\":\"en-US\"},{\"@type\":\"Question\",\"@id\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688407794\",\"position\":3,\"url\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688407794\",\"name\":\"Q3. Should a Laravel developer job description mention database skills?\",\"answerCount\":1,\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Yes, database skills are important for Laravel development. Employers should mention relevant technologies, such as MySQL or PostgreSQL, along with database design, query optimization, migrations, and relationships.\",\"inLanguage\":\"en-US\"},\"inLanguage\":\"en-US\"},{\"@type\":\"Question\",\"@id\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688425474\",\"position\":4,\"url\":\"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688425474\",\"name\":\"Q4. Is knowledge of APIs necessary for Laravel developers?\",\"answerCount\":1,\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Yes, API development is a valuable skill for Laravel developers. Developers often build REST APIs, connect third-party services, manage authentication, and exchange data between web applications and other systems.\",\"inLanguage\":\"en-US\"},\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Laravel Developer Job Description [with Free Template]","description":"Explore Laravel developer job descriptions, key responsibilities, required skills, salary ranges, and sample templates to help you hire the right talent.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/","og_locale":"en_US","og_type":"article","og_title":"Laravel Developer Job Description [with Free Template]","og_description":"Explore Laravel developer job descriptions, key responsibilities, required skills, salary ranges, and sample templates to help you hire the right talent.","og_url":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/","og_site_name":"Internshala blog","article_published_time":"2026-10-23T05:05:00+00:00","article_modified_time":"2026-10-22T17:06:01+00:00","og_image":[{"width":900,"height":600,"url":"http:\/\/internshala.com\/blog\/wp-content\/uploads\/2026\/10\/Laravel-Developer-Job-Description.png","type":"image\/png"}],"author":"Shobha Saini","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Shobha Saini","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#article","isPartOf":{"@id":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/"},"author":{"name":"Shobha Saini","@id":"https:\/\/internshala.com\/blog\/#\/schema\/person\/c220799e53244b6b0da150e24591978f"},"headline":"Laravel Developer Job Description [with Free Template]","datePublished":"2026-10-23T05:05:00+00:00","dateModified":"2026-10-22T17:06:01+00:00","mainEntityOfPage":{"@id":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/"},"wordCount":1439,"publisher":{"@id":"https:\/\/internshala.com\/blog\/#organization"},"articleSection":["HR Resources"],"inLanguage":"en-US"},{"@type":["WebPage","FAQPage"],"@id":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/","url":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/","name":"Laravel Developer Job Description [with Free Template]","isPartOf":{"@id":"https:\/\/internshala.com\/blog\/#website"},"datePublished":"2026-10-23T05:05:00+00:00","dateModified":"2026-10-22T17:06:01+00:00","description":"Explore Laravel developer job descriptions, key responsibilities, required skills, salary ranges, and sample templates to help you hire the right talent.","breadcrumb":{"@id":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#breadcrumb"},"mainEntity":[{"@id":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688376660"},{"@id":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688388788"},{"@id":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688407794"},{"@id":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688425474"}],"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/internshala.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Employer Resources","item":"https:\/\/internshala.com\/blog\/employer-resources\/"},{"@type":"ListItem","position":3,"name":"HR Resources","item":"https:\/\/internshala.com\/blog\/employer-resources\/hr-resources\/"},{"@type":"ListItem","position":4,"name":"Laravel Developer Job Description"}]},{"@type":"WebSite","@id":"https:\/\/internshala.com\/blog\/#website","url":"https:\/\/internshala.com\/blog\/","name":"Internshala blog","description":"Your favourite senior outside college","publisher":{"@id":"https:\/\/internshala.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/internshala.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/internshala.com\/blog\/#organization","name":"Internshala blog","url":"https:\/\/internshala.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/internshala.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/internshala.com\/blog\/wp-content\/uploads\/2023\/08\/LOGO-1.png","contentUrl":"https:\/\/internshala.com\/blog\/wp-content\/uploads\/2023\/08\/LOGO-1.png","width":112,"height":31,"caption":"Internshala blog"},"image":{"@id":"https:\/\/internshala.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/internshala.com\/blog\/#\/schema\/person\/c220799e53244b6b0da150e24591978f","name":"Shobha Saini","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/internshala.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/internshala.com\/blog\/wp-content\/uploads\/2023\/12\/Shobha-96x96.jpg","contentUrl":"https:\/\/internshala.com\/blog\/wp-content\/uploads\/2023\/12\/Shobha-96x96.jpg","caption":"Shobha Saini"},"description":"Shobha Saini is the Head of Human Resources at Internshala with over eight years of experience in employee relations and talent acquisition. She has led strategic HR initiatives and built effective people practices across the organization. She specializes in strategic planning, policy-making, and performance management. A multi-talented professional, she has played a key role in shaping HR strategies at Internshala.","sameAs":["https:\/\/www.linkedin.com\/in\/shobha-saini-she-her-7a95131a\/"],"url":"https:\/\/internshala.com\/blog\/author\/shobha-saini\/"},{"@type":"Question","@id":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688376660","position":1,"url":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688376660","name":"Q1. Can a Laravel developer work remotely?","answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"Yes, many Laravel developers work remotely. They use collaboration tools, version control systems, and project management platforms to coordinate with teams, review code, and deliver application updates.","inLanguage":"en-US"},"inLanguage":"en-US"},{"@type":"Question","@id":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688388788","position":2,"url":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688388788","name":"Q2. What is the difference between a junior and senior Laravel developer?","answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"Junior developers typically handle assigned coding tasks, bug fixes, and basic application features. Senior developers manage complex development work, make architectural decisions, optimize systems, and mentor other team members.","inLanguage":"en-US"},"inLanguage":"en-US"},{"@type":"Question","@id":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688407794","position":3,"url":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688407794","name":"Q3. Should a Laravel developer job description mention database skills?","answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"Yes, database skills are important for Laravel development. Employers should mention relevant technologies, such as MySQL or PostgreSQL, along with database design, query optimization, migrations, and relationships.","inLanguage":"en-US"},"inLanguage":"en-US"},{"@type":"Question","@id":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688425474","position":4,"url":"https:\/\/internshala.com\/blog\/employer-laravel-developer-job-description\/#faq-question-1792688425474","name":"Q4. Is knowledge of APIs necessary for Laravel developers?","answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"Yes, API development is a valuable skill for Laravel developers. Developers often build REST APIs, connect third-party services, manage authentication, and exchange data between web applications and other systems.","inLanguage":"en-US"},"inLanguage":"en-US"}]}},"_links":{"self":[{"href":"https:\/\/internshala.com\/blog\/wp-json\/wp\/v2\/posts\/30748"}],"collection":[{"href":"https:\/\/internshala.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/internshala.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/internshala.com\/blog\/wp-json\/wp\/v2\/users\/6502"}],"replies":[{"embeddable":true,"href":"https:\/\/internshala.com\/blog\/wp-json\/wp\/v2\/comments?post=30748"}],"version-history":[{"count":0,"href":"https:\/\/internshala.com\/blog\/wp-json\/wp\/v2\/posts\/30748\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/internshala.com\/blog\/wp-json\/wp\/v2\/media\/30750"}],"wp:attachment":[{"href":"https:\/\/internshala.com\/blog\/wp-json\/wp\/v2\/media?parent=30748"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/internshala.com\/blog\/wp-json\/wp\/v2\/categories?post=30748"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/internshala.com\/blog\/wp-json\/wp\/v2\/tags?post=30748"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}