Free
Hero
Kindhire Hero
A hero block extracted from the Kindhire template, available in Tailwind CSS and Bootstrap.
0
2
A hero block extracted from the Kindhire template, available in Tailwind CSS and Bootstrap.
<!DOCTYPE html>
<html lang="en">
<head>
<script>
window.FontAwesomeConfig = { autoReplaceSvg: 'nest' };
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/js/all.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kindhire Hero | Tailwind CSS UI Block</title>
<meta name="description" content="A hero block extracted from the Kindhire template, available in Tailwind CSS and Bootstrap.">
<meta name="keywords" content="Kindhire, Tailwind CSS template, HTML website template, business template, inclusive hiring, accessible job board, disability employment, recruitment platform, remote jobs website, employer page">
<meta name="author" content="Let's templates">
<link rel="canonical" href="">
<meta property="og:type" content="product">
<meta property="og:site_name" content="Let's templates">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="">
<meta property="og:title" content="Kindhire | Tailwind CSS Business Template">
<meta property="og:description" content="A warm, accessible Tailwind CSS business template for inclusive hiring platforms, with arch portraits, a story carousel and a live job matcher.">
<meta property="og:image" content="">
<meta property="og:image:alt" content="Kindhire template preview">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:url" content="">
<meta name="twitter:title" content="Kindhire | Tailwind CSS Business Template">
<meta name="twitter:description" content="A warm, accessible Tailwind CSS business template for inclusive hiring platforms, with arch portraits, a story carousel and a live job matcher.">
<meta name="twitter:image" content="">
<meta name="twitter:image:alt" content="Kindhire template preview">
<script src="https://cdn.tailwindcss.com/3.4.17"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,700;9..144,800&family=Urbanist:wght@400;500;600;700&display=swap" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
colors: { paper: '#f4f4f2', ink: '#141414', royal: { DEFAULT: '#0b4ea2', dark: '#083a7a', soft: '#dfe9f7' }, coral: { DEFAULT: '#f4846a', soft: '#fde3dc' }, leaf: { DEFAULT: '#3aa52a', soft: '#dff1db' }, sun: '#ffc928' },
fontFamily: { sans: ['Urbanist', 'sans-serif'], serif: ['Fraunces', 'serif'] }
}
}
}
</script>
<style>
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: 180ms ease-out both page-fade-out; }
::view-transition-new(root) { animation: 220ms ease-in both page-fade-in; }
@keyframes page-fade-out { to { opacity: 0; } }
@keyframes page-fade-in { from { opacity: 0; } }
html { scroll-behavior: smooth; }
[hidden] { display: none !important; }
.wiggle { animation: wiggle 5s ease-in-out infinite; transform-origin: center; }
@keyframes wiggle { 50% { rotate: 6deg; } }
.logos { animation: logos 34s linear infinite; }
.logos:hover { animation-play-state: paused; }
@keyframes logos { to { transform: translateX(-50%); } }
.ring-fill { transition: stroke-dashoffset .7s ease; }
.timeline-fill { transform-origin: top; }
.story { transition: opacity .4s ease; }
.reveal-ready [data-reveal] { opacity: 0; transform: translateY(24px); transition: opacity .6s ease, transform .6s ease; transition-delay: var(--reveal-delay, 0ms); }
.reveal-ready [data-reveal].is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
.wiggle, .logos { animation: none; }
.ring-fill, .story { transition: none; }
::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}
</style>
</head>
<body class="bg-paper font-sans text-ink antialiased">
<% active_page = "index" %>
<% nav = { "platform" => "Platform", "jobs" => "Jobs", "employers" => "For employers", "stories" => "Stories", "about" => "About", "contact" => "Contact" } %>
<% { "index" => "Home" }.merge(nav).each do |slug, label| %>
<% active = active_page == slug %>
<% end %>
<% arches = [["1507003211169-0a1dd7228f2d", "Smiling man in a white T-shirt", "Marco", "QA tester", "bg-royal", "halo", "lg:mt-0"], ["1580489944761-15a19d654956", "Smiling woman with her hair tied up", "Lina", "web designer", "bg-coral", "burst", "lg:mt-36"], ["1599566150163-29194dcaad36", "Young man with glasses and a beard", "Sam", "content moderator", "bg-leaf", "zigzag", "lg:mt-0"]] %>
<!-- block:start hero -->
<section class="mx-auto grid max-w-7xl items-center gap-12 px-5 pb-20 pt-6 md:px-10 lg:grid-cols-[1fr_1.15fr] lg:pb-28 lg:pt-12">
<div>
<h1 class="font-serif text-5xl font-extrabold leading-[1.02] tracking-tight md:text-7xl">Work that fits the way you live</h1>
<p class="mt-6 max-w-md text-xl leading-snug md:text-2xl">Remote and flexible roles for people with every kind of disability, wherever they are.</p>
<a href="contact.html" class="mt-9 inline-flex rounded-full bg-royal px-9 py-4 text-lg font-semibold text-white shadow-lg shadow-royal/25 transition hover:bg-royal-dark">Join Kindhire</a>
</div>
<div class="relative">
<svg class="absolute -bottom-8 -left-24 hidden h-40 w-28 lg:block" viewBox="0 0 110 160" aria-hidden="true"><path d="M100 4C60 12 40 50 70 70c22 14 30-30 4-30C40 40 14 90 8 150m0 0-6-12m6 12 8-10" fill="none" stroke="#141414" stroke-width="2" stroke-linecap="round"/></svg>
<ul class="grid grid-cols-3 gap-3 sm:gap-5">
<% arches.each_with_index do |(photo, alt, name, role, color, doodle, offset), index| %>
<li class="<%= offset %>" data-reveal style="--reveal-delay: <%= index * 120 %>ms">
<% if index == 1 %><p class="mb-4 hidden text-center text-lg leading-snug lg:block"><%= name %> —<br><%= role %></p><% end %>
<div class="relative aspect-[2/3] overflow-hidden rounded-full <%= color %>">
<img src="https://images.unsplash.com/photo-<%= photo %>?auto=format&fit=crop&w=500&h=620&q=80" alt="<%= alt %>" class="absolute inset-x-0 bottom-0 h-[80%] w-full rounded-t-full object-cover object-top">
<svg class="wiggle absolute left-1/2 top-[6%] h-[16%] w-[45%] -translate-x-1/2" viewBox="0 0 80 40" aria-hidden="true">
<% if doodle == "halo" %><ellipse cx="40" cy="20" rx="34" ry="11" fill="none" stroke="#fff" stroke-width="3"/><ellipse cx="42" cy="18" rx="28" ry="8" fill="none" stroke="#fff" stroke-width="2"/>
<% elsif doodle == "burst" %><path d="M8 34 16 10l8 18 8-24 8 22 10-18 4 26" fill="none" stroke="#fff" stroke-width="3.5" stroke-linejoin="round" stroke-linecap="round"/>
<% else %><path d="M6 10c6-6 10 6 16 0s10 6 16 0 10 6 16 0 10 6 16 0M10 22c6-6 10 6 16 0s10 6 16 0 10 6 16 0M14 34c6-6 10 6 16 0s10 6 16 0 10 6 16 0" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round"/><% end %>
</svg>
</div>
<% unless index == 1 %><p class="mt-4 text-center text-sm leading-snug sm:text-lg"><%= name %> —<br><%= role %></p><% else %><p class="mt-4 text-center text-sm leading-snug sm:text-lg lg:hidden"><%= name %> —<br><%= role %></p><% end %>
</li>
<% end %>
</ul>
</div>
</section>
<!-- block:end hero -->
<script>
const reducedMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;
const watchMotion = !reducedMotion && !navigator.webdriver && 'IntersectionObserver' in window;
document.querySelectorAll('[data-menu-toggle]').forEach((button) => {
const menu = document.getElementById(button.getAttribute('aria-controls'));
const close = menu.querySelector('[data-menu-close]');
const set = (open) => { menu.hidden = !open; button.setAttribute('aria-expanded', String(open)); document.body.style.overflow = open ? 'hidden' : ''; (open ? close : button).focus(); };
button.addEventListener('click', () => set(menu.hidden));
close.addEventListener('click', () => set(false));
document.addEventListener('keydown', (event) => { if (event.key === 'Escape' && !menu.hidden) set(false); });
});
document.querySelectorAll('[data-carousel]').forEach((root) => {
const slides = [...root.querySelectorAll('[data-slide]')];
const dots = [...root.querySelectorAll('[data-carousel-dot]')];
let current = 0;
const show = (index) => {
current = (index + slides.length) % slides.length;
slides.forEach((slide, i) => { slide.hidden = i !== current; });
dots.forEach((dot, i) => dot.setAttribute('aria-current', String(i === current)));
};
root.querySelectorAll('[data-carousel-prev]').forEach((button) => button.addEventListener('click', () => show(current - 1)));
root.querySelectorAll('[data-carousel-next]').forEach((button) => button.addEventListener('click', () => show(current + 1)));
dots.forEach((dot, i) => dot.addEventListener('click', () => show(i)));
root.addEventListener('keydown', (event) => { if (event.key === 'ArrowLeft') show(current - 1); if (event.key === 'ArrowRight') show(current + 1); });
});
document.querySelectorAll('[data-matcher]').forEach((root) => {
const jobs = [...root.querySelectorAll('[data-job]')];
const isOn = (el) => el.getAttribute('aria-pressed') === 'true' || el.selected === true || el.checked === true;
const paint = () => {
const skills = [...root.querySelectorAll('[data-skill]:not([data-job])')].filter(isOn).map((el) => el.dataset.skill);
const needs = [...root.querySelectorAll('[data-need]')].filter(isOn).map((el) => el.dataset.need);
let shown = 0;
jobs.forEach((job) => {
const match = (!skills.length || skills.includes(job.dataset.skill)) && needs.every((need) => job.dataset.needs.split(' ').includes(need));
job.hidden = !match;
if (match) shown += 1;
});
root.querySelector('[data-match-count]').textContent = shown;
root.querySelector('[data-match-empty]').hidden = shown > 0;
};
root.querySelectorAll('[data-skill]:not([data-job])').forEach((chip) => chip.addEventListener('click', () => { if (chip.hasAttribute('aria-pressed')) chip.setAttribute('aria-pressed', String(chip.getAttribute('aria-pressed') !== 'true')); requestAnimationFrame(paint); }));
root.addEventListener('change', paint);
if (window.customElements) customElements.whenDefined('md-filter-chip').then(() => requestAnimationFrame(paint));
paint();
});
document.querySelectorAll('[data-timeline]').forEach((root) => {
const fill = root.querySelector('[data-timeline-fill]');
if (!watchMotion) return;
const update = () => {
const box = root.getBoundingClientRect();
fill.style.transform = `scaleY(${Math.min(1, Math.max(0, (innerHeight * 0.6 - box.top) / box.height))})`;
};
update();
addEventListener('scroll', update, { passive: true });
});
document.querySelectorAll('[data-rings]').forEach((root) => {
const rings = root.querySelectorAll('[data-ring]');
if (!watchMotion) return;
rings.forEach((ring) => { ring.style.strokeDashoffset = 326.73; });
const observer = new IntersectionObserver((entries) => {
if (!entries.some((entry) => entry.isIntersecting)) return;
rings.forEach((ring) => { ring.style.strokeDashoffset = 326.73 * (1 - Number(ring.dataset.ring) / 100); });
observer.disconnect();
}, { threshold: 0.3 });
observer.observe(root);
});
document.querySelectorAll('[data-chat]').forEach((root) => {
const log = root.querySelector('[data-chat-log]');
const add = (text, mine) => {
const item = document.createElement('li');
item.className = mine ? 'ml-auto max-w-[85%] rounded-3xl rounded-br-md bg-royal px-5 py-3 text-white' : 'max-w-[85%] rounded-3xl rounded-bl-md bg-paper px-5 py-3';
item.textContent = text;
log.append(item);
log.scrollTop = log.scrollHeight;
};
root.querySelectorAll('[data-chat-question]').forEach((button) => button.addEventListener('click', () => {
add(button.dataset.label || button.textContent.trim(), true);
setTimeout(() => add(button.dataset.answer, false), reducedMotion ? 0 : 450);
}));
});
document.querySelectorAll('[data-hover-list]').forEach((root) => {
const image = root.querySelector('[data-hover-image]');
root.querySelectorAll('[data-hover-row]').forEach((row) => {
const show = () => { image.src = row.dataset.image; image.alt = row.dataset.alt; root.querySelectorAll('[data-hover-row]').forEach((other) => other.setAttribute('aria-current', String(other === row))); };
row.addEventListener('mouseenter', show);
row.addEventListener('focus', show);
row.addEventListener('click', show);
});
});
document.querySelectorAll('[data-job-board]').forEach((root) => {
const list = root.querySelector('[data-board-list]');
const items = [...list.children];
const search = root.querySelector('[data-board-search]');
const sort = root.querySelector('[data-board-sort]');
const apply = () => {
const query = String(search.value || '').trim().toLowerCase();
const sorted = [...items].sort((a, b) => sort.value === 'salary' ? b.dataset.salary - a.dataset.salary : sort.value === 'hours' ? a.dataset.hours - b.dataset.hours : b.dataset.date - a.dataset.date);
let shown = 0;
sorted.forEach((item) => { const match = !query || item.textContent.toLowerCase().includes(query); item.hidden = !match; if (match) shown += 1; list.append(item); });
root.querySelector('[data-board-count]').textContent = shown;
root.querySelector('[data-board-empty]').hidden = shown > 0;
};
search.addEventListener('input', apply);
sort.addEventListener('change', apply);
const initial = new URLSearchParams(location.search).get('q');
if (initial) search.value = initial;
apply();
});
document.querySelectorAll('[data-calculator]').forEach((root) => {
const money = (value) => `$${Math.round(value).toLocaleString('en-US')}`;
const paint = () => {
const hires = Number(root.querySelector('[data-hires]').value);
const salary = Number(root.querySelector('[data-salary]').value);
const fee = hires * salary * 0.08;
const credit = hires * Math.min(salary * 0.25, 9600);
root.querySelector('[data-hires-label]').textContent = hires;
root.querySelector('[data-salary-label]').textContent = money(salary);
root.querySelector('[data-fee]').textContent = money(fee);
root.querySelector('[data-credit]').textContent = `−${money(credit)}`;
root.querySelector('[data-net]').textContent = money(Math.max(0, fee - credit));
};
root.addEventListener('input', paint);
paint();
});
document.querySelectorAll('[data-chat-form]').forEach((form) => {
const log = form.querySelector('[data-chat-log]');
const steps = [...form.querySelectorAll('[data-chat-step]')];
const status = form.querySelector('[data-form-status]');
let current = 0;
const say = (text, mine) => {
const bubble = document.createElement('li');
bubble.className = mine ? 'ml-auto max-w-[85%] rounded-3xl rounded-br-md bg-royal px-5 py-3 text-white' : 'max-w-[85%] rounded-3xl rounded-bl-md bg-paper px-5 py-3';
bubble.textContent = text;
log.append(bubble);
log.scrollTop = log.scrollHeight;
};
const show = (index) => steps.forEach((step, i) => { step.hidden = i !== index; });
const field = (step) => step.querySelector('input, select, textarea, md-outlined-text-field, md-outlined-select');
form.addEventListener('submit', (event) => {
event.preventDefault();
const input = field(steps[current]);
if (!input.checkValidity() || !String(input.value || '').trim()) { status.textContent = form.dataset.error; input.focus(); return; }
status.textContent = '';
say(String(input.value), true);
current += 1;
if (current < steps.length) { say(steps[current].dataset.question, false); show(current); field(steps[current]).focus(); }
else { say(form.dataset.success, false); show(-1); }
});
show(0);
});
document.querySelectorAll('[data-contact-form]').forEach((form) => {
form.addEventListener('submit', (event) => {
event.preventDefault();
const status = form.querySelector('[data-form-status]');
if (!form.checkValidity()) {
status.textContent = form.dataset.error;
form.querySelector(':invalid')?.focus();
return;
}
status.textContent = form.dataset.success;
form.reset();
});
});
document.querySelectorAll('[data-current-year]').forEach((el) => { el.textContent = new Date().getFullYear(); });
(() => {
const items = document.querySelectorAll('[data-reveal]');
if (!items.length || !watchMotion) return;
document.documentElement.classList.add('reveal-ready');
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
entry.target.classList.add('is-visible');
observer.unobserve(entry.target);
});
}, { rootMargin: '0px 0px -10% 0px' });
items.forEach((item) => observer.observe(item));
})();
</script>
</body>
</html>
Business
Unlock the entire library of premium templates and blocks. Renews automatically, cancel anytime.
Tailwind CSS · HTML download