Free
Navbar
Kindhire Navbar
A navbar block extracted from the Kindhire template, available in Tailwind CSS and Bootstrap.
0
2
A navbar 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 Navbar | Tailwind CSS UI Block</title>
<meta name="description" content="A navbar 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" } %>
<!-- block:start navbar -->
<header class="relative z-40">
<nav class="mx-auto grid max-w-7xl grid-cols-[1fr_auto_1fr] items-center gap-4 px-5 py-6 md:px-10 md:py-8" aria-label="Main">
<button type="button" data-menu-toggle aria-controls="site-menu" aria-expanded="false" class="flex w-fit items-center gap-3 rounded-full py-2 pr-3 text-lg font-medium transition hover:text-royal"><i class="fa-solid fa-bars text-xl" aria-hidden="true"></i><span class="hidden sm:inline">Menu</span><span class="sr-only sm:hidden">Open menu</span></button>
<a href="index.html" class="flex items-center gap-1.5 text-xl font-bold tracking-tight md:text-2xl" aria-label="Kindhire home">
<svg class="h-8 w-9" viewBox="0 0 36 32" aria-hidden="true"><path d="M2 30 16 6l14 24Z" fill="#0b4ea2"/><path d="M14 30l9-15 11 15Z" fill="#0b4ea2" opacity=".75"/><path d="M8 4l1 2.4L11.5 7 9 7.6 8 10 7 7.6 4.5 7 7 6.4Z" fill="#f4846a"/></svg>
<span><span class="text-royal">KIND</span><span class="text-coral">HIRE</span></span>
</a>
<a href="platform.html" class="justify-self-end rounded-full border-2 border-royal px-5 py-2.5 font-semibold text-royal transition hover:bg-royal hover:text-white md:px-8 md:py-3">Platform</a>
</nav>
<div id="site-menu" hidden class="fixed inset-0 z-50 overflow-y-auto bg-royal text-white">
<div class="mx-auto flex min-h-full max-w-7xl flex-col px-5 py-6 md:px-10 md:py-8">
<button type="button" data-menu-close class="flex w-fit items-center gap-3 rounded-full py-2 pr-3 text-lg font-medium hover:text-sun"><i class="fa-solid fa-xmark text-xl" aria-hidden="true"></i>Close</button>
<div class="my-auto grid gap-12 py-12 lg:grid-cols-[1.4fr_1fr] lg:items-center">
<ul class="grid gap-2">
<% { "index" => "Home" }.merge(nav).each do |slug, label| %>
<% active = active_page == slug %>
<li><a href="<%= slug %>.html" <%= 'aria-current="page"'.html_safe if active %> class="font-serif text-5xl font-bold transition md:text-7xl <%= active ? 'text-sun underline decoration-coral decoration-4 underline-offset-8' : 'hover:text-sun' %>"><%= label %></a></li>
<% end %>
</ul>
<div class="hidden rounded-[2rem] bg-white/10 p-8 lg:block">
<p class="font-serif text-3xl font-bold">Need help signing up?</p>
<p class="mt-3 text-lg text-white/80">Call us, text us or book a video call with sign language. We're here weekdays 8–20.</p>
<a href="contact.html" class="mt-6 inline-flex rounded-full bg-sun px-6 py-3 font-semibold text-ink">Get in touch</a>
</div>
</div>
</div>
</div>
</header>
<!-- block:end navbar -->
<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