Back to templates components
Storefront
A starting-point eCommerce example built with Tailwind CSS, combining a shop listing with filters and a product detail page with gallery, variants, and reviews. Not a production-ready template.
Starting point — not a finished product
This template combines existing HyperUI components into a full page layout to help you move faster. It still needs real content, working functionality, accessibility checks, and testing before it's ready for production.
0/2 Dark Mode (Request)Updated: N/ANo commit information available.
<input type="checkbox" id="nav-toggle" class="peer sr-only" />
<header class="border-b border-gray-100">
<div class="mx-auto flex h-16 max-w-7xl items-center gap-6 px-4 sm:px-6 lg:px-8">
<a href="#" class="flex items-center gap-2 text-emerald-700">
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.75"
stroke="currentColor"
class="size-6"
>
<path stroke-linecap="round" stroke-linejoin="round" d="M3 20l7-15 4 9 3-6 4 12H3Z" />
</svg>
<span class="text-sm font-semibold tracking-tight text-gray-900">Fernweg Supply</span>
</a>
<nav aria-label="Global" class="hidden md:block">
<ul class="flex items-center gap-6 text-sm text-gray-600">
<li><a href="#" class="font-medium text-gray-900">Shop</a></li>
<li><a href="#" class="transition hover:text-gray-900">Guides</a></li>
<li><a href="#" class="transition hover:text-gray-900">About</a></li>
</ul>
</nav>
<div class="ml-auto flex items-center gap-1">
<button
type="button"
class="rounded-md p-2 text-gray-600 transition hover:bg-gray-100 hover:text-gray-900"
>
<span class="sr-only">Search</span>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="size-5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"
/>
</svg>
</button>
<a
href="#"
class="relative rounded-md p-2 text-gray-600 transition hover:bg-gray-100 hover:text-gray-900"
>
<span class="sr-only">Cart, 2 items</span>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="size-5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M2.25 3h1.386c.51 0 .955.343 1.087.835l.383 1.437M7.5 14.25a3 3 0 0 0-3 3h15.75m-12.75-3h11.218c1.121-2.3 2.1-4.684 2.924-7.138a60.114 60.114 0 0 0-16.536-1.84M7.5 14.25 5.106 5.272M6 20.25a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Zm12.75 0a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Z"
/>
</svg>
<span
class="absolute top-0.5 right-0.5 flex size-4 items-center justify-center rounded-full bg-emerald-700 text-[10px] font-medium text-white"
>
2
</span>
</a>
<label
for="nav-toggle"
id="nav-toggle-label"
aria-expanded="false"
aria-controls="mobile-nav"
class="cursor-pointer rounded-md p-2 text-gray-600 transition peer-focus-visible:ring-2 peer-focus-visible:ring-emerald-700 peer-focus-visible:ring-offset-2 hover:bg-gray-100 md:hidden"
>
<span class="sr-only">Toggle menu</span>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
class="size-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"
/>
</svg>
</label>
</div>
</div>
<nav
id="mobile-nav"
aria-label="Global Mobile"
class="hidden border-t border-gray-100 peer-checked:block md:hidden"
>
<ul class="space-y-1 px-4 py-4 text-sm">
<li>
<a href="#" class="block rounded-lg bg-gray-100 px-3 py-2 font-medium text-gray-900"
>Shop</a
>
</li>
<li>
<a href="#" class="block rounded-lg px-3 py-2 text-gray-600 hover:bg-gray-50">Guides</a>
</li>
<li>
<a href="#" class="block rounded-lg px-3 py-2 text-gray-600 hover:bg-gray-50">About</a>
</li>
</ul>
</nav>
</header>
<main class="mx-auto max-w-7xl px-4 py-8 sm:px-6 sm:py-12 lg:px-8">
<nav aria-label="Breadcrumb">
<ol class="flex items-center gap-1 text-xs text-gray-500">
<li><a href="#" class="hover:text-gray-800">Home</a></li>
<li aria-hidden="true">/</li>
<li aria-current="page" class="text-gray-800">Tents & shelters</li>
</ol>
</nav>
<div class="mt-4 sm:flex sm:items-end sm:justify-between">
<div class="max-w-lg">
<h1 class="text-2xl font-semibold text-gray-900 sm:text-3xl">Tents & shelters</h1>
<p class="mt-2 text-sm text-gray-600">
Four-season and three-season shelters, tested above the treeline before they reach the
shop floor.
</p>
</div>
<p class="mt-4 text-sm text-gray-500 sm:mt-0">18 results</p>
</div>
<div class="mt-6 block lg:hidden">
<button
type="button"
class="flex cursor-pointer items-center gap-2 rounded-md border border-gray-300 px-4 py-2 text-sm font-medium text-gray-700"
>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="size-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M10.5 6h9.75M10.5 6a1.5 1.5 0 1 1-3 0m3 0a1.5 1.5 0 1 0-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 0 1-3 0m3 0a1.5 1.5 0 0 0-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 0 1-3 0m3 0a1.5 1.5 0 0 0-3 0m-9.75 0h9.75"
/>
</svg>
Filters & sorting
</button>
</div>
<div class="mt-6 lg:grid lg:grid-cols-4 lg:items-start lg:gap-8">
<div class="hidden space-y-6 lg:block">
<div>
<label for="SortBy" class="block text-xs font-medium text-gray-700">Sort by</label>
<select
id="SortBy"
class="mt-1 w-full rounded-md border-gray-300 text-sm focus:border-emerald-600 focus:ring-emerald-600"
>
<option>Most popular</option>
<option>Price, low to high</option>
<option>Price, high to low</option>
<option>Newest</option>
</select>
</div>
<fieldset class="border-t border-gray-200 pt-6">
<legend class="text-xs font-medium text-gray-700">Season rating</legend>
<div class="mt-3 space-y-2">
<label class="flex items-center gap-2">
<input
type="checkbox"
class="size-4 rounded-sm border-gray-300 text-emerald-700 focus:ring-emerald-600"
/>
<span class="text-sm text-gray-700">3-season (11)</span>
</label>
<label class="flex items-center gap-2">
<input
type="checkbox"
class="size-4 rounded-sm border-gray-300 text-emerald-700 focus:ring-emerald-600"
/>
<span class="text-sm text-gray-700">4-season (7)</span>
</label>
</div>
</fieldset>
<fieldset class="border-t border-gray-200 pt-6">
<legend class="text-xs font-medium text-gray-700">Capacity</legend>
<div class="mt-3 space-y-2">
<label class="flex items-center gap-2">
<input
type="checkbox"
class="size-4 rounded-sm border-gray-300 text-emerald-700 focus:ring-emerald-600"
/>
<span class="text-sm text-gray-700">1 person (4)</span>
</label>
<label class="flex items-center gap-2">
<input
type="checkbox"
class="size-4 rounded-sm border-gray-300 text-emerald-700 focus:ring-emerald-600"
/>
<span class="text-sm text-gray-700">2 person (9)</span>
</label>
<label class="flex items-center gap-2">
<input
type="checkbox"
class="size-4 rounded-sm border-gray-300 text-emerald-700 focus:ring-emerald-600"
/>
<span class="text-sm text-gray-700">3+ person (5)</span>
</label>
</div>
</fieldset>
<fieldset class="border-t border-gray-200 pt-6">
<legend class="text-xs font-medium text-gray-700">Price</legend>
<div class="mt-3 flex items-center gap-3">
<label class="flex items-center gap-1">
<span class="text-sm text-gray-500">$</span>
<input
type="number"
placeholder="Min"
class="w-full rounded-md border-gray-300 text-sm focus:border-emerald-600 focus:ring-emerald-600"
/>
</label>
<span class="text-gray-400">–</span>
<label class="flex items-center gap-1">
<span class="text-sm text-gray-500">$</span>
<input
type="number"
placeholder="Max"
class="w-full rounded-md border-gray-300 text-sm focus:border-emerald-600 focus:ring-emerald-600"
/>
</label>
</div>
</fieldset>
</div>
<div class="mt-6 lg:col-span-3 lg:mt-0">
<ul class="grid grid-cols-2 gap-x-4 gap-y-8 sm:grid-cols-3">
<li>
<a href="#" class="group block">
<div class="relative overflow-hidden rounded-lg bg-gray-100">
<span
class="absolute top-2 left-2 z-10 rounded-full bg-white px-2 py-1 text-[10px] font-medium text-gray-900"
>
New
</span>
<img
alt=""
src="https://images.unsplash.com/photo-1504280390367-361c6d9f38f4?auto=format&fit=crop&q=80&w=800"
class="aspect-square w-full object-cover transition duration-500 group-hover:scale-105"
/>
</div>
<h3 class="mt-3 text-sm font-medium text-gray-900">Kestrel 2P Ultralight</h3>
<p class="mt-1 text-xs text-gray-500">3-season · 1.4kg</p>
<p class="mt-1 text-sm font-medium text-gray-900">$389</p>
</a>
</li>
<li>
<a href="#" class="group block">
<div class="relative overflow-hidden rounded-lg bg-gray-100">
<img
alt=""
src="https://images.unsplash.com/photo-1504851149312-7a075b496cc7?auto=format&fit=crop&q=80&w=800"
class="aspect-square w-full object-cover transition duration-500 group-hover:scale-105"
/>
</div>
<h3 class="mt-3 text-sm font-medium text-gray-900">Cairn 1P Solo</h3>
<p class="mt-1 text-xs text-gray-500">3-season · 0.9kg</p>
<p class="mt-1 text-sm font-medium text-gray-900">$329</p>
</a>
</li>
<li>
<a href="#" class="group block">
<div class="relative overflow-hidden rounded-lg bg-gray-100">
<span
class="absolute top-2 left-2 z-10 rounded-full bg-amber-400 px-2 py-1 text-[10px] font-medium text-gray-900"
>
3 left
</span>
<img
alt=""
src="https://images.unsplash.com/photo-1478131143081-80f7f84ca84d?auto=format&fit=crop&q=80&w=800"
class="aspect-square w-full object-cover transition duration-500 group-hover:scale-105"
/>
</div>
<h3 class="mt-3 text-sm font-medium text-gray-900">Basecamp 4P Expedition</h3>
<p class="mt-1 text-xs text-gray-500">4-season · 4.1kg</p>
<p class="mt-1 text-sm font-medium text-gray-900">$649</p>
</a>
</li>
<li>
<a href="#" class="group block">
<div class="relative overflow-hidden rounded-lg bg-gray-100">
<img
alt=""
src="https://images.unsplash.com/photo-1517824806704-9040b037703b?auto=format&fit=crop&q=80&w=800"
class="aspect-square w-full object-cover transition duration-500 group-hover:scale-105"
/>
</div>
<h3 class="mt-3 text-sm font-medium text-gray-900">Ridgeline 3P Family</h3>
<p class="mt-1 text-xs text-gray-500">3-season · 2.6kg</p>
<p class="mt-1 text-sm font-medium text-gray-900">$419</p>
</a>
</li>
<li>
<a href="#" class="group block">
<div class="relative overflow-hidden rounded-lg bg-gray-100">
<img
alt=""
src="https://images.unsplash.com/photo-1445308394109-4ec2920981b1?auto=format&fit=crop&q=80&w=800"
class="aspect-square w-full object-cover transition duration-500 group-hover:scale-105"
/>
</div>
<h3 class="mt-3 text-sm font-medium text-gray-900">Summit 2P Storm</h3>
<p class="mt-1 text-xs text-gray-500">4-season · 2.2kg</p>
<p class="mt-1 text-sm font-medium text-gray-900">$589</p>
</a>
</li>
<li>
<a href="#" class="group block">
<div class="relative overflow-hidden rounded-lg bg-gray-100">
<img
alt=""
src="https://images.unsplash.com/photo-1487730116645-74489c95b41b?auto=format&fit=crop&q=80&w=800"
class="aspect-square w-full object-cover transition duration-500 group-hover:scale-105"
/>
</div>
<h3 class="mt-3 text-sm font-medium text-gray-900">Hollow 1P Bivy</h3>
<p class="mt-1 text-xs text-gray-500">3-season · 0.6kg</p>
<p class="mt-1 text-sm font-medium text-gray-900">$219</p>
</a>
</li>
</ul>
<nav aria-label="Pagination" class="mt-10 flex items-center justify-center gap-1">
<a
href="#"
class="inline-flex size-8 items-center justify-center rounded-md border border-gray-200 text-gray-500 rtl:rotate-180"
>
<span class="sr-only">Previous</span>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
class="size-3"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M11.78 5.22a.75.75 0 0 1 0 1.06L8.06 10l3.72 3.72a.75.75 0 1 1-1.06 1.06l-4.25-4.25a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0Z"
clip-rule="evenodd"
/>
</svg>
</a>
<a
href="#"
class="inline-flex size-8 items-center justify-center rounded-md bg-emerald-700 text-sm font-medium text-white"
>
1
</a>
<a
href="#"
class="inline-flex size-8 items-center justify-center rounded-md text-sm font-medium text-gray-700 hover:bg-gray-100"
>
2
</a>
<a
href="#"
class="inline-flex size-8 items-center justify-center rounded-md text-sm font-medium text-gray-700 hover:bg-gray-100"
>
3
</a>
<a
href="#"
class="inline-flex size-8 items-center justify-center rounded-md border border-gray-200 text-gray-500 rtl:rotate-180"
>
<span class="sr-only">Next</span>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
class="size-3"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fill-rule="evenodd"
d="M8.22 5.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L11.94 10 8.22 6.28a.75.75 0 0 1 0-1.06Z"
clip-rule="evenodd"
/>
</svg>
</a>
</nav>
</div>
</div>
</main>
<footer class="border-t border-gray-100 bg-gray-50">
<div class="mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8">
<div class="grid grid-cols-2 gap-8 sm:grid-cols-4">
<div class="col-span-2 sm:col-span-1">
<p class="text-sm font-semibold text-gray-900">Fernweg Supply</p>
<p class="mt-2 text-sm text-gray-500">
Gear tested in the field it's sold for, not just the lab.
</p>
</div>
<div>
<p class="text-sm font-medium text-gray-900">Shop</p>
<ul class="mt-4 space-y-2 text-sm text-gray-500">
<li><a href="#" class="hover:text-gray-900">Tents & shelters</a></li>
<li><a href="#" class="hover:text-gray-900">Sleep systems</a></li>
<li><a href="#" class="hover:text-gray-900">Packs</a></li>
</ul>
</div>
<div>
<p class="text-sm font-medium text-gray-900">Support</p>
<ul class="mt-4 space-y-2 text-sm text-gray-500">
<li><a href="#" class="hover:text-gray-900">Shipping</a></li>
<li><a href="#" class="hover:text-gray-900">Returns</a></li>
<li><a href="#" class="hover:text-gray-900">Size guide</a></li>
</ul>
</div>
<div>
<p class="text-sm font-medium text-gray-900">Company</p>
<ul class="mt-4 space-y-2 text-sm text-gray-500">
<li><a href="#" class="hover:text-gray-900">About</a></li>
<li><a href="#" class="hover:text-gray-900">Field guides</a></li>
<li><a href="#" class="hover:text-gray-900">Contact</a></li>
</ul>
</div>
</div>
<div
class="mt-10 flex flex-col gap-4 border-t border-gray-200 pt-8 sm:flex-row sm:items-center sm:justify-between"
>
<p class="text-xs text-gray-500">© 2026 Fernweg Supply. All rights reserved.</p>
<ul class="flex gap-4 text-xs text-gray-500">
<li><a href="#" class="hover:text-gray-900">Privacy</a></li>
<li><a href="#" class="hover:text-gray-900">Terms</a></li>
</ul>
</div>
</div>
</footer>
<script>
const navToggleCheckbox = document.getElementById('nav-toggle')
const navToggleLabel = document.getElementById('nav-toggle-label')
navToggleCheckbox.addEventListener('change', () => {
navToggleLabel.setAttribute('aria-expanded', String(navToggleCheckbox.checked))
})
</script><input type="checkbox" id="nav-toggle" class="peer sr-only" />
<header class="border-b border-gray-100">
<div class="mx-auto flex h-16 max-w-7xl items-center gap-6 px-4 sm:px-6 lg:px-8">
<a href="#" class="flex items-center gap-2 text-emerald-700">
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.75"
stroke="currentColor"
class="size-6"
>
<path stroke-linecap="round" stroke-linejoin="round" d="M3 20l7-15 4 9 3-6 4 12H3Z" />
</svg>
<span class="text-sm font-semibold tracking-tight text-gray-900">Fernweg Supply</span>
</a>
<nav aria-label="Global" class="hidden md:block">
<ul class="flex items-center gap-6 text-sm text-gray-600">
<li><a href="#" class="font-medium text-gray-900">Shop</a></li>
<li><a href="#" class="transition hover:text-gray-900">Guides</a></li>
<li><a href="#" class="transition hover:text-gray-900">About</a></li>
</ul>
</nav>
<div class="ml-auto flex items-center gap-1">
<button
type="button"
class="rounded-md p-2 text-gray-600 transition hover:bg-gray-100 hover:text-gray-900"
>
<span class="sr-only">Search</span>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="size-5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"
/>
</svg>
</button>
<a
href="#"
class="relative rounded-md p-2 text-gray-600 transition hover:bg-gray-100 hover:text-gray-900"
>
<span class="sr-only">Cart, 2 items</span>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="size-5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M2.25 3h1.386c.51 0 .955.343 1.087.835l.383 1.437M7.5 14.25a3 3 0 0 0-3 3h15.75m-12.75-3h11.218c1.121-2.3 2.1-4.684 2.924-7.138a60.114 60.114 0 0 0-16.536-1.84M7.5 14.25 5.106 5.272M6 20.25a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Zm12.75 0a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Z"
/>
</svg>
<span
class="absolute top-0.5 right-0.5 flex size-4 items-center justify-center rounded-full bg-emerald-700 text-[10px] font-medium text-white"
>
2
</span>
</a>
<label
for="nav-toggle"
id="nav-toggle-label"
aria-expanded="false"
aria-controls="mobile-nav"
class="cursor-pointer rounded-md p-2 text-gray-600 transition peer-focus-visible:ring-2 peer-focus-visible:ring-emerald-700 peer-focus-visible:ring-offset-2 hover:bg-gray-100 md:hidden"
>
<span class="sr-only">Toggle menu</span>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
class="size-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"
/>
</svg>
</label>
</div>
</div>
<nav
id="mobile-nav"
aria-label="Global Mobile"
class="hidden border-t border-gray-100 peer-checked:block md:hidden"
>
<ul class="space-y-1 px-4 py-4 text-sm">
<li>
<a href="#" class="block rounded-lg bg-gray-100 px-3 py-2 font-medium text-gray-900"
>Shop</a
>
</li>
<li>
<a href="#" class="block rounded-lg px-3 py-2 text-gray-600 hover:bg-gray-50">Guides</a>
</li>
<li>
<a href="#" class="block rounded-lg px-3 py-2 text-gray-600 hover:bg-gray-50">About</a>
</li>
</ul>
</nav>
</header>
<main class="mx-auto max-w-7xl px-4 py-8 sm:px-6 sm:py-12 lg:px-8">
<nav aria-label="Breadcrumb">
<ol class="flex flex-wrap items-center gap-1 text-xs text-gray-500">
<li><a href="#" class="hover:text-gray-800">Home</a></li>
<li aria-hidden="true">/</li>
<li><a href="#" class="hover:text-gray-800">Tents & shelters</a></li>
<li aria-hidden="true">/</li>
<li aria-current="page" class="text-gray-800">Kestrel 2P Ultralight</li>
</ol>
</nav>
<div class="mt-6 grid gap-10 lg:grid-cols-2 lg:gap-16">
<div>
<div class="overflow-hidden rounded-lg bg-gray-100">
<img
id="ProductGalleryImage"
alt="Kestrel 2P Ultralight tent pitched on a ridgeline at dawn"
src="https://images.unsplash.com/photo-1504280390367-361c6d9f38f4?auto=format&fit=crop&q=80&w=1200"
class="aspect-square w-full object-cover"
/>
</div>
<ul class="mt-3 grid grid-cols-4 gap-3">
<li>
<button
type="button"
aria-pressed="true"
data-gallery-image="https://images.unsplash.com/photo-1504280390367-361c6d9f38f4?auto=format&fit=crop&q=80&w=1200"
data-gallery-alt="Kestrel 2P Ultralight tent pitched on a ridgeline at dawn"
class="overflow-hidden rounded-md aria-pressed:ring-2 aria-pressed:ring-emerald-700 aria-pressed:ring-offset-2"
>
<span class="sr-only">Show ridgeline photo</span>
<img
alt=""
src="https://images.unsplash.com/photo-1504280390367-361c6d9f38f4?auto=format&fit=crop&q=80&w=200"
class="aspect-square w-full object-cover"
/>
</button>
</li>
<li>
<button
type="button"
aria-pressed="false"
data-gallery-image="https://images.unsplash.com/photo-1478131143081-80f7f84ca84d?auto=format&fit=crop&q=80&w=1200"
data-gallery-alt="Kestrel 2P Ultralight interior showing double-wall construction"
class="overflow-hidden rounded-md aria-pressed:ring-2 aria-pressed:ring-emerald-700 aria-pressed:ring-offset-2"
>
<span class="sr-only">Show interior photo</span>
<img
alt=""
src="https://images.unsplash.com/photo-1478131143081-80f7f84ca84d?auto=format&fit=crop&q=80&w=200"
class="aspect-square w-full object-cover"
/>
</button>
</li>
<li>
<button
type="button"
aria-pressed="false"
data-gallery-image="https://images.unsplash.com/photo-1445308394109-4ec2920981b1?auto=format&fit=crop&q=80&w=1200"
data-gallery-alt="Kestrel 2P Ultralight packed down into its stuff sack"
class="overflow-hidden rounded-md aria-pressed:ring-2 aria-pressed:ring-emerald-700 aria-pressed:ring-offset-2"
>
<span class="sr-only">Show packed photo</span>
<img
alt=""
src="https://images.unsplash.com/photo-1445308394109-4ec2920981b1?auto=format&fit=crop&q=80&w=200"
class="aspect-square w-full object-cover"
/>
</button>
</li>
<li>
<button
type="button"
aria-pressed="false"
data-gallery-image="https://images.unsplash.com/photo-1487730116645-74489c95b41b?auto=format&fit=crop&q=80&w=1200"
data-gallery-alt="Kestrel 2P Ultralight with the storm fly pitched in wind"
class="overflow-hidden rounded-md aria-pressed:ring-2 aria-pressed:ring-emerald-700 aria-pressed:ring-offset-2"
>
<span class="sr-only">Show storm-fly photo</span>
<img
alt=""
src="https://images.unsplash.com/photo-1487730116645-74489c95b41b?auto=format&fit=crop&q=80&w=200"
class="aspect-square w-full object-cover"
/>
</button>
</li>
</ul>
</div>
<div>
<h1 class="text-2xl font-semibold text-gray-900 sm:text-3xl">Kestrel 2P Ultralight</h1>
<a href="#reviews" class="mt-2 flex items-center gap-2">
<span class="flex items-center gap-0.5 text-amber-500">
<span class="sr-only">Rated 4 out of 5 stars</span>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-4"
aria-hidden="true"
>
<path
d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-4"
aria-hidden="true"
>
<path
d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-4"
aria-hidden="true"
>
<path
d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-4"
aria-hidden="true"
>
<path
d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-4 text-gray-200"
aria-hidden="true"
>
<path
d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z"
/>
</svg>
</span>
<span class="text-sm text-gray-500 underline underline-offset-2">126 reviews</span>
</a>
<p class="mt-4 text-2xl font-medium text-gray-900">$389.00</p>
<p class="mt-4 text-gray-600">
A freestanding 2-person shelter built for three-season trips where every gram in the
pack has to earn its place. Double-wall construction sheds condensation without
sacrificing the 1.4kg trail weight.
</p>
<div class="mt-6">
<p class="text-sm font-medium text-gray-900">
Colour: <span class="font-normal text-gray-600">Moss green</span>
</p>
<div class="mt-2 flex items-center gap-2">
<button
type="button"
aria-label="Moss green"
class="size-8 rounded-full bg-emerald-700 ring-2 ring-emerald-700 ring-offset-2"
></button>
<button
type="button"
aria-label="Slate grey"
class="size-8 rounded-full bg-gray-500 ring-2 ring-transparent ring-offset-2 hover:ring-gray-300"
></button>
<button
type="button"
aria-label="Burnt orange"
class="size-8 rounded-full bg-orange-600 ring-2 ring-transparent ring-offset-2 hover:ring-gray-300"
></button>
</div>
</div>
<div class="mt-6 flex flex-wrap items-end gap-4">
<div>
<label for="Quantity" class="block text-sm font-medium text-gray-900">Quantity</label>
<div class="mt-1 flex items-center gap-1">
<button
type="button"
class="size-10 leading-10 text-gray-600 transition hover:opacity-75"
>
−
</button>
<input
type="number"
id="Quantity"
value="1"
class="h-10 w-16 rounded-md border-gray-300 text-center sm:text-sm"
/>
<button
type="button"
class="size-10 leading-10 text-gray-600 transition hover:opacity-75"
>
+
</button>
</div>
</div>
<button
type="button"
class="flex-1 rounded-md bg-emerald-700 px-6 py-3 text-sm font-medium text-white transition hover:bg-emerald-800"
>
Add to cart
</button>
</div>
<ul class="mt-6 space-y-2 border-t border-gray-200 pt-6 text-sm text-gray-600">
<li class="flex items-center gap-2">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke-width="1.5"
stroke="currentColor"
class="size-4 text-emerald-700"
aria-hidden="true"
>
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" />
</svg>
In stock — ships within 2 business days
</li>
<li class="flex items-center gap-2">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke-width="1.5"
stroke="currentColor"
class="size-4 text-emerald-700"
aria-hidden="true"
>
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" />
</svg>
Free returns within 30 days
</li>
</ul>
</div>
</div>
<div class="mt-16">
<div class="border-b border-gray-200">
<div role="tablist" class="-mb-px flex gap-6">
<button
type="button"
id="tab-description"
role="tab"
aria-selected="true"
aria-controls="description"
class="border-b-2 py-3 text-sm font-medium aria-selected:border-emerald-700 aria-selected:text-emerald-700 aria-[selected=false]:border-transparent aria-[selected=false]:text-gray-500 aria-[selected=false]:hover:text-gray-700"
>
Description
</button>
<button
type="button"
id="tab-shipping"
role="tab"
aria-selected="false"
aria-controls="shipping"
tabindex="-1"
class="border-b-2 py-3 text-sm font-medium aria-selected:border-emerald-700 aria-selected:text-emerald-700 aria-[selected=false]:border-transparent aria-[selected=false]:text-gray-500 aria-[selected=false]:hover:text-gray-700"
>
Shipping & returns
</button>
<button
type="button"
id="tab-reviews"
role="tab"
aria-selected="false"
aria-controls="reviews"
tabindex="-1"
class="border-b-2 py-3 text-sm font-medium aria-selected:border-emerald-700 aria-selected:text-emerald-700 aria-[selected=false]:border-transparent aria-[selected=false]:text-gray-500 aria-[selected=false]:hover:text-gray-700"
>
Reviews (126)
</button>
</div>
</div>
<div
id="description"
role="tabpanel"
aria-labelledby="tab-description"
class="mt-6 max-w-2xl text-gray-600"
>
<p>
The Kestrel uses a single-hub aluminium pole set that pitches in under four minutes,
even with cold hands. Colour-coded clips and a symmetrical fly mean there's only one way
to get it wrong, and it's hard to.
</p>
<ul class="mt-4 grid grid-cols-2 gap-x-6 gap-y-2 text-sm">
<li><span class="text-gray-500">Packed weight</span> · 1.4kg</li>
<li><span class="text-gray-500">Floor area</span> · 2.7m²</li>
<li><span class="text-gray-500">Peak height</span> · 104cm</li>
<li><span class="text-gray-500">Season rating</span> · 3-season</li>
</ul>
</div>
<div
id="shipping"
role="tabpanel"
aria-labelledby="tab-shipping"
hidden
class="mt-6 max-w-2xl text-gray-600"
>
<p>
Ships within 2 business days from our EU and US warehouses. Free returns within 30 days
if it hasn't been pitched outside — unused, tags on, original packaging.
</p>
<ul class="mt-4 grid grid-cols-2 gap-x-6 gap-y-2 text-sm">
<li><span class="text-gray-500">Delivery</span> · 2–4 business days</li>
<li><span class="text-gray-500">Returns window</span> · 30 days</li>
<li><span class="text-gray-500">Warranty</span> · 2 years</li>
<li><span class="text-gray-500">Repair kit</span> · Included</li>
</ul>
</div>
<div
id="reviews"
role="tabpanel"
aria-labelledby="tab-reviews"
hidden
class="mt-6 max-w-2xl scroll-mt-20"
>
<div class="flex items-center justify-between">
<h2 class="text-lg font-semibold text-gray-900">Reviews</h2>
<span class="text-sm text-gray-500">4.6 average from 126 reviews</span>
</div>
<ul class="mt-6 space-y-4">
<li class="rounded-lg border border-gray-200 p-6">
<div class="flex items-center justify-between gap-4">
<div class="flex items-center gap-0.5 text-amber-500">
<span class="sr-only">Rated 4 out of 5 stars</span>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-4"
aria-hidden="true"
>
<path
d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-4"
aria-hidden="true"
>
<path
d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-4"
aria-hidden="true"
>
<path
d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-4"
aria-hidden="true"
>
<path
d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-4 text-gray-200"
aria-hidden="true"
>
<path
d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z"
/>
</svg>
</div>
<span class="inline-flex items-center gap-1 text-xs font-medium text-emerald-700">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-3.5"
aria-hidden="true"
>
<path
fill-rule="evenodd"
d="M10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16Zm3.857-9.809a.75.75 0 0 0-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 1 0-1.06 1.061l2.5 2.5a.75.75 0 0 0 1.137-.089l4-5.5Z"
clip-rule="evenodd"
/>
</svg>
Verified purchase
</span>
</div>
<p class="mt-3 text-sm font-medium text-gray-900">
Kept us dry through a week of rain
</p>
<p class="mt-1 text-sm text-gray-600">
Pitched this in a downpour at 6,000ft and stayed dry all night. Poles are
colour-coded so it went up in under four minutes even in the wind.
</p>
<p class="mt-3 text-xs text-gray-500">Freya Lindqvist · 3 weeks ago</p>
</li>
<li class="rounded-lg border border-gray-200 p-6">
<div class="flex items-center gap-0.5 text-amber-500">
<span class="sr-only">Rated 3 out of 5 stars</span>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-4"
aria-hidden="true"
>
<path
d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-4"
aria-hidden="true"
>
<path
d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-4"
aria-hidden="true"
>
<path
d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-4 text-gray-200"
aria-hidden="true"
>
<path
d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-4 text-gray-200"
aria-hidden="true"
>
<path
d="M10.868 2.884c-.321-.772-1.415-.772-1.736 0l-1.83 4.401-4.753.381c-.833.067-1.171 1.107-.536 1.651l3.62 3.102-1.106 4.637c-.194.813.691 1.456 1.405 1.02L10 15.591l4.069 2.485c.713.436 1.598-.207 1.404-1.02l-1.106-4.637 3.62-3.102c.635-.544.297-1.584-.536-1.65l-4.752-.382-1.831-4.401Z"
/>
</svg>
</div>
<p class="mt-3 text-sm font-medium text-gray-900">Good pack, straps run narrow</p>
<p class="mt-1 text-sm text-gray-600">
Compression straps and the hip belt are excellent, but the shoulder straps dug in on
longer days. Sizing up helped.
</p>
<p class="mt-3 text-xs text-gray-500">Owen Baptiste · 2 months ago</p>
</li>
</ul>
</div>
</div>
<div class="mt-16">
<h2 class="text-lg font-semibold text-gray-900">You might also like</h2>
<ul class="mt-6 grid grid-cols-2 gap-x-4 gap-y-8 sm:grid-cols-4">
<li>
<a href="#" class="group block">
<div class="overflow-hidden rounded-lg bg-gray-100">
<img
alt=""
src="https://images.unsplash.com/photo-1504851149312-7a075b496cc7?auto=format&fit=crop&q=80&w=600"
class="aspect-square w-full object-cover transition duration-500 group-hover:scale-105"
/>
</div>
<h3 class="mt-3 text-sm font-medium text-gray-900">Cairn 1P Solo</h3>
<p class="mt-1 text-sm text-gray-600">$329</p>
</a>
</li>
<li>
<a href="#" class="group block">
<div class="overflow-hidden rounded-lg bg-gray-100">
<img
alt=""
src="https://images.unsplash.com/photo-1517824806704-9040b037703b?auto=format&fit=crop&q=80&w=600"
class="aspect-square w-full object-cover transition duration-500 group-hover:scale-105"
/>
</div>
<h3 class="mt-3 text-sm font-medium text-gray-900">Ridgeline 3P Family</h3>
<p class="mt-1 text-sm text-gray-600">$419</p>
</a>
</li>
<li>
<a href="#" class="group block">
<div class="overflow-hidden rounded-lg bg-gray-100">
<img
alt=""
src="https://images.unsplash.com/photo-1445308394109-4ec2920981b1?auto=format&fit=crop&q=80&w=600"
class="aspect-square w-full object-cover transition duration-500 group-hover:scale-105"
/>
</div>
<h3 class="mt-3 text-sm font-medium text-gray-900">Hollow 1P Bivy</h3>
<p class="mt-1 text-sm text-gray-600">$219</p>
</a>
</li>
<li>
<a href="#" class="group block">
<div class="overflow-hidden rounded-lg bg-gray-100">
<img
alt=""
src="https://images.unsplash.com/photo-1487730116645-74489c95b41b?auto=format&fit=crop&q=80&w=600"
class="aspect-square w-full object-cover transition duration-500 group-hover:scale-105"
/>
</div>
<h3 class="mt-3 text-sm font-medium text-gray-900">Summit 2P Storm</h3>
<p class="mt-1 text-sm text-gray-600">$589</p>
</a>
</li>
</ul>
</div>
</main>
<footer class="mt-16 border-t border-gray-100 bg-gray-50">
<div class="mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8">
<div class="grid grid-cols-2 gap-8 sm:grid-cols-4">
<div class="col-span-2 sm:col-span-1">
<p class="text-sm font-semibold text-gray-900">Fernweg Supply</p>
<p class="mt-2 text-sm text-gray-500">
Gear tested in the field it's sold for, not just the lab.
</p>
</div>
<div>
<p class="text-sm font-medium text-gray-900">Shop</p>
<ul class="mt-4 space-y-2 text-sm text-gray-500">
<li><a href="#" class="hover:text-gray-900">Tents & shelters</a></li>
<li><a href="#" class="hover:text-gray-900">Sleep systems</a></li>
<li><a href="#" class="hover:text-gray-900">Packs</a></li>
</ul>
</div>
<div>
<p class="text-sm font-medium text-gray-900">Support</p>
<ul class="mt-4 space-y-2 text-sm text-gray-500">
<li><a href="#" class="hover:text-gray-900">Shipping</a></li>
<li><a href="#" class="hover:text-gray-900">Returns</a></li>
<li><a href="#" class="hover:text-gray-900">Size guide</a></li>
</ul>
</div>
<div>
<p class="text-sm font-medium text-gray-900">Company</p>
<ul class="mt-4 space-y-2 text-sm text-gray-500">
<li><a href="#" class="hover:text-gray-900">About</a></li>
<li><a href="#" class="hover:text-gray-900">Field guides</a></li>
<li><a href="#" class="hover:text-gray-900">Contact</a></li>
</ul>
</div>
</div>
<div
class="mt-10 flex flex-col gap-4 border-t border-gray-200 pt-8 sm:flex-row sm:items-center sm:justify-between"
>
<p class="text-xs text-gray-500">© 2026 Fernweg Supply. All rights reserved.</p>
<ul class="flex gap-4 text-xs text-gray-500">
<li><a href="#" class="hover:text-gray-900">Privacy</a></li>
<li><a href="#" class="hover:text-gray-900">Terms</a></li>
</ul>
</div>
</div>
</footer>
<script>
const navToggleCheckbox = document.getElementById('nav-toggle')
const navToggleLabel = document.getElementById('nav-toggle-label')
navToggleCheckbox.addEventListener('change', () => {
navToggleLabel.setAttribute('aria-expanded', String(navToggleCheckbox.checked))
})
const tabs = document.querySelectorAll('[role="tab"]')
const activateTab = (tab) => {
tabs.forEach((otherTab) => {
const isSelected = otherTab === tab
otherTab.setAttribute('aria-selected', String(isSelected))
otherTab.tabIndex = isSelected ? 0 : -1
document.getElementById(otherTab.getAttribute('aria-controls')).hidden = !isSelected
})
}
tabs.forEach((tab, index) => {
tab.addEventListener('click', () => {
activateTab(tab)
tab.focus()
})
tab.addEventListener('keydown', (event) => {
const targetIndex = {
ArrowLeft: (index - 1 + tabs.length) % tabs.length,
ArrowRight: (index + 1) % tabs.length,
Home: 0,
End: tabs.length - 1,
}[event.key]
if (targetIndex === undefined) return
event.preventDefault()
activateTab(tabs[targetIndex])
tabs[targetIndex].focus()
})
})
document.querySelector('a[href="#reviews"]').addEventListener('click', () => {
activateTab(document.getElementById('tab-reviews'))
})
const galleryImage = document.getElementById('ProductGalleryImage')
const galleryButtons = document.querySelectorAll('[data-gallery-image]')
galleryButtons.forEach((button) => {
button.addEventListener('click', () => {
galleryButtons.forEach((otherButton) => {
otherButton.setAttribute('aria-pressed', String(otherButton === button))
})
galleryImage.src = button.dataset.galleryImage
galleryImage.alt = button.dataset.galleryAlt
})
})
</script>