Vet — Services
A warm veterinary services page with a hero, filter chips by pet type and service category, a responsive grid of service cards showing icons, blurbs and pricing-from hints, and a sticky book-now CTA band that updates a live count of matching services.
MCP
Code
:root {
--teal: #179c8e;
--teal-d: #0f7f73;
--teal-50: #e6f5f2;
--coral: #ff8a5c;
--ink: #173a36;
--muted: #6b827e;
--bg: #f2f8f6;
--white: #ffffff;
--line: #d9ece8;
--radius: 22px;
--radius-sm: 14px;
--shadow: 0 10px 30px rgba(15, 127, 115, 0.10);
--shadow-hover: 0 16px 44px rgba(15, 127, 115, 0.18);
--font: 'Inter', system-ui, -apple-system, sans-serif;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
font-family: var(--font);
background: var(--bg);
color: var(--ink);
line-height: 1.55;
-webkit-font-smoothing: antialiased;
}
.page { max-width: 1080px; margin: 0 auto; padding: 0 20px 120px; }
/* ---------- HERO ---------- */
.hero {
margin: 24px 0 28px;
border-radius: 28px;
background:
radial-gradient(120% 140% at 100% 0%, rgba(255, 138, 92, 0.28), transparent 55%),
linear-gradient(135deg, var(--teal), var(--teal-d));
color: var(--white);
overflow: hidden;
}
.hero__inner { padding: 54px 44px; max-width: 660px; }
.hero__eyebrow {
display: inline-flex; align-items: center; gap: 8px;
font-size: 13px; font-weight: 600; letter-spacing: .02em;
background: rgba(255, 255, 255, 0.16);
padding: 7px 14px; border-radius: 999px;
}
.paw { font-size: 15px; }
.hero__title {
font-size: clamp(28px, 5vw, 42px); font-weight: 800;
line-height: 1.12; margin: 18px 0 12px; letter-spacing: -.02em;
}
.hero__lead { font-size: 17px; margin: 0 0 22px; color: rgba(255, 255, 255, 0.92); }
.hero__meta {
display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
font-size: 14px; color: rgba(255, 255, 255, 0.9);
}
.hero__stat strong { font-weight: 700; }
.hero__dot { width: 4px; height: 4px; border-radius: 50%; background: rgba(255, 255, 255, 0.55); }
/* ---------- FILTERS ---------- */
.filters { margin-bottom: 22px; }
.filters__row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.chip {
font-family: var(--font); font-size: 14px; font-weight: 600;
color: var(--ink); background: var(--white);
border: 1px solid var(--line); border-radius: 999px;
padding: 9px 16px; cursor: pointer;
transition: background .18s, color .18s, border-color .18s, transform .12s;
}
.chip:hover { border-color: var(--teal); transform: translateY(-1px); }
.chip:focus-visible { outline: 3px solid rgba(23, 156, 142, 0.4); outline-offset: 2px; }
.chip.is-active {
background: var(--teal); border-color: var(--teal); color: var(--white);
}
.chip--pet.is-active { background: var(--coral); border-color: var(--coral); }
.filters__sep {
width: 1px; height: 24px; background: var(--line); margin: 0 4px;
}
.filters__count {
margin: 14px 2px 0; font-size: 14px; font-weight: 600; color: var(--muted);
}
/* ---------- GRID ---------- */
.grid {
list-style: none; margin: 0; padding: 0;
display: grid; grid-template-columns: repeat(auto-fill, minmax(248px, 1fr)); gap: 18px;
}
.card {
position: relative;
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--radius);
padding: 24px 22px 20px;
display: flex; flex-direction: column;
box-shadow: var(--shadow);
transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
.card:hover { transform: translateY(-4px); box-shadow: var(--shadow-hover); border-color: rgba(23, 156, 142, 0.4); }
.card.is-hidden { display: none; }
.card__icon {
width: 56px; height: 56px; border-radius: 18px;
background: var(--teal-50);
display: grid; place-items: center; font-size: 26px;
margin-bottom: 14px;
}
.card__title { font-size: 18px; font-weight: 700; margin: 0 0 6px; letter-spacing: -.01em; }
.card__blurb { font-size: 14px; color: var(--muted); margin: 0 0 16px; flex: 1; }
.card__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 16px; }
.tag {
font-size: 12px; font-weight: 600; color: var(--teal-d);
background: var(--teal-50); border-radius: 999px; padding: 4px 10px;
}
.card__foot {
display: flex; align-items: center; justify-content: space-between;
border-top: 1px dashed var(--line); padding-top: 14px;
}
.price { font-size: 14px; color: var(--muted); }
.price strong { font-size: 18px; color: var(--ink); font-weight: 800; }
.card__time { font-size: 12px; font-weight: 600; color: var(--muted); }
/* urgent card */
.card--urgent {
border-color: var(--coral);
background: linear-gradient(180deg, #fff4ee, var(--white) 60%);
}
.card--urgent .card__icon { background: #ffe6da; }
.card--urgent .tag { color: #c1502a; background: #ffe6da; }
.card__badge {
position: absolute; top: 16px; right: 16px;
font-size: 12px; font-weight: 800; letter-spacing: .04em;
color: var(--white); background: var(--coral);
border-radius: 999px; padding: 5px 11px;
}
.services__empty {
text-align: center; color: var(--muted); font-weight: 600;
padding: 48px 16px; background: var(--white);
border: 1px dashed var(--line); border-radius: var(--radius);
}
/* ---------- CTA ---------- */
.cta {
position: sticky; bottom: 16px;
margin-top: 36px;
}
.cta__inner {
display: flex; align-items: center; justify-content: space-between; gap: 24px;
flex-wrap: wrap;
background: linear-gradient(135deg, var(--teal), var(--teal-d));
border-radius: var(--radius);
padding: 26px 30px; color: var(--white);
box-shadow: var(--shadow-hover);
}
.cta__title { font-size: 22px; font-weight: 800; margin: 0 0 4px; }
.cta__sub { font-size: 14px; margin: 0; color: rgba(255, 255, 255, 0.9); }
.cta__actions { display: flex; gap: 12px; flex-wrap: wrap; }
.btn {
font-family: var(--font); font-size: 15px; font-weight: 700;
border-radius: 999px; padding: 13px 24px; cursor: pointer;
border: 1px solid transparent; text-decoration: none;
display: inline-flex; align-items: center; gap: 8px;
transition: transform .12s, background .16s, color .16s;
}
.btn:focus-visible { outline: 3px solid rgba(255, 255, 255, 0.7); outline-offset: 2px; }
.btn--ghost {
background: rgba(255, 255, 255, 0.14); color: var(--white);
border-color: rgba(255, 255, 255, 0.4);
}
.btn--ghost:hover { background: rgba(255, 255, 255, 0.24); transform: translateY(-1px); }
.btn--primary { background: var(--coral); color: var(--white); }
.btn--primary:hover { background: #ff744a; transform: translateY(-1px); }
.btn--primary.is-booked { background: #0d6b61; }
/* ---------- RESPONSIVE ---------- */
@media (max-width: 520px) {
.page { padding: 0 14px 100px; }
.hero__inner { padding: 36px 24px; }
.hero__title { font-size: 28px; }
.grid { grid-template-columns: 1fr; }
.filters__sep { display: none; }
.cta { position: static; }
.cta__inner { flex-direction: column; align-items: stretch; text-align: center; padding: 22px; }
.cta__actions { justify-content: center; }
.btn { flex: 1; justify-content: center; }
}(function () {
"use strict";
var chips = Array.prototype.slice.call(document.querySelectorAll(".chip"));
var cards = Array.prototype.slice.call(document.querySelectorAll(".card"));
var countEl = document.getElementById("resultCount");
var emptyEl = document.getElementById("emptyState");
var bookBtn = document.getElementById("bookBtn");
// Active filter state: one category + one pet filter, "all" resets both groups.
var state = { cat: "all", pet: "all" };
var CATS = ["all", "preventive", "medical", "lifestyle"];
var PETS = ["dog", "cat", "small"];
function matches(card) {
var cat = card.getAttribute("data-cat");
var pets = (card.getAttribute("data-pets") || "").split(" ");
var catOk = state.cat === "all" || cat === state.cat;
var petOk = state.pet === "all" || pets.indexOf(state.pet) !== -1;
return catOk && petOk;
}
function render() {
var shown = 0;
cards.forEach(function (card) {
if (matches(card)) {
card.classList.remove("is-hidden");
shown++;
} else {
card.classList.add("is-hidden");
}
});
countEl.textContent =
"Showing " + shown + " service" + (shown === 1 ? "" : "s");
emptyEl.hidden = shown !== 0;
}
function syncChips() {
chips.forEach(function (chip) {
var f = chip.getAttribute("data-filter");
var active =
f === state.cat || f === state.pet || (f === "all" && state.cat === "all");
chip.classList.toggle("is-active", active);
chip.setAttribute("aria-pressed", active ? "true" : "false");
});
}
chips.forEach(function (chip) {
chip.addEventListener("click", function () {
var f = chip.getAttribute("data-filter");
if (f === "all") {
state.cat = "all";
state.pet = "all";
} else if (CATS.indexOf(f) !== -1) {
state.cat = state.cat === f ? "all" : f;
} else if (PETS.indexOf(f) !== -1) {
state.pet = state.pet === f ? "all" : f;
}
syncChips();
render();
});
});
if (bookBtn) {
bookBtn.addEventListener("click", function () {
var cta = document.querySelector(".cta");
if (cta && cta.scrollIntoView) {
cta.scrollIntoView({ behavior: "smooth", block: "center" });
}
bookBtn.classList.add("is-booked");
bookBtn.textContent = "We'll call you ✓";
setTimeout(function () {
bookBtn.classList.remove("is-booked");
bookBtn.textContent = "Book now";
}, 2200);
});
}
syncChips();
render();
})();<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Pawmile Vet — Services</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<main class="page">
<!-- HERO -->
<header class="hero">
<div class="hero__inner">
<span class="hero__eyebrow"><span class="paw" aria-hidden="true">🐾</span> Pawmile Veterinary Clinic</span>
<h1 class="hero__title">Gentle care for the ones who can’t ask for it</h1>
<p class="hero__lead">
From routine check-ups to round-the-clock emergencies, our team looks after dogs, cats and
small pets with the warmth they deserve. Browse our services below.
</p>
<div class="hero__meta">
<span class="hero__stat"><strong>12</strong> vets & nurses</span>
<span class="hero__dot" aria-hidden="true"></span>
<span class="hero__stat"><strong>4.9★</strong> from 2,140 reviews</span>
<span class="hero__dot" aria-hidden="true"></span>
<span class="hero__stat">Open <strong>7 days</strong></span>
</div>
</div>
</header>
<!-- FILTERS -->
<section class="filters" aria-label="Filter services">
<div class="filters__row" role="group" aria-label="Filter by category">
<button class="chip is-active" type="button" data-filter="all" aria-pressed="true">All services</button>
<button class="chip" type="button" data-filter="preventive" aria-pressed="false">Preventive</button>
<button class="chip" type="button" data-filter="medical" aria-pressed="false">Medical</button>
<button class="chip" type="button" data-filter="lifestyle" aria-pressed="false">Lifestyle</button>
<span class="filters__sep" aria-hidden="true"></span>
<button class="chip chip--pet" type="button" data-filter="dog" aria-pressed="false">🐶 Dogs</button>
<button class="chip chip--pet" type="button" data-filter="cat" aria-pressed="false">🐱 Cats</button>
<button class="chip chip--pet" type="button" data-filter="small" aria-pressed="false">🐰 Small pets</button>
</div>
<p class="filters__count" id="resultCount" aria-live="polite">Showing 8 services</p>
</section>
<!-- SERVICES GRID -->
<section class="services" aria-label="Our services">
<ul class="grid" id="serviceGrid">
<li class="card" data-cat="preventive" data-pets="dog cat small">
<div class="card__icon" aria-hidden="true">🩺</div>
<h2 class="card__title">Wellness Exams</h2>
<p class="card__blurb">Nose-to-tail annual check-ups to spot issues early and keep your companion thriving.</p>
<div class="card__tags"><span class="tag">Preventive</span><span class="tag">All pets</span></div>
<div class="card__foot"><span class="price">from <strong>$49</strong></span><span class="card__time">30 min</span></div>
</li>
<li class="card" data-cat="preventive" data-pets="dog cat small">
<div class="card__icon" aria-hidden="true">💉</div>
<h2 class="card__title">Vaccinations</h2>
<p class="card__blurb">Core and lifestyle vaccines on a schedule tailored to your pet’s age and habits.</p>
<div class="card__tags"><span class="tag">Preventive</span><span class="tag">All pets</span></div>
<div class="card__foot"><span class="price">from <strong>$28</strong></span><span class="card__time">15 min</span></div>
</li>
<li class="card" data-cat="medical" data-pets="dog cat">
<div class="card__icon" aria-hidden="true">🦷</div>
<h2 class="card__title">Dental Care</h2>
<p class="card__blurb">Ultrasonic scaling, polishing and extractions under safe, monitored anaesthesia.</p>
<div class="card__tags"><span class="tag">Medical</span><span class="tag">Dogs & cats</span></div>
<div class="card__foot"><span class="price">from <strong>$180</strong></span><span class="card__time">~2 hrs</span></div>
</li>
<li class="card" data-cat="medical" data-pets="dog cat small">
<div class="card__icon" aria-hidden="true">🔬</div>
<h2 class="card__title">Surgery</h2>
<p class="card__blurb">Spays, neuters and soft-tissue procedures with full pre-op screening and pain care.</p>
<div class="card__tags"><span class="tag">Medical</span><span class="tag">All pets</span></div>
<div class="card__foot"><span class="price">from <strong>$220</strong></span><span class="card__time">By quote</span></div>
</li>
<li class="card" data-cat="medical" data-pets="dog cat small">
<div class="card__icon" aria-hidden="true">🧪</div>
<h2 class="card__title">Diagnostics</h2>
<p class="card__blurb">In-house bloodwork, digital X-ray and ultrasound with same-day results.</p>
<div class="card__tags"><span class="tag">Medical</span><span class="tag">All pets</span></div>
<div class="card__foot"><span class="price">from <strong>$65</strong></span><span class="card__time">Same day</span></div>
</li>
<li class="card" data-cat="lifestyle" data-pets="dog cat small">
<div class="card__icon" aria-hidden="true">✂️</div>
<h2 class="card__title">Grooming</h2>
<p class="card__blurb">Baths, trims, nail clips and de-shedding by gentle, fear-free groomers.</p>
<div class="card__tags"><span class="tag">Lifestyle</span><span class="tag">All pets</span></div>
<div class="card__foot"><span class="price">from <strong>$35</strong></span><span class="card__time">45 min</span></div>
</li>
<li class="card" data-cat="lifestyle" data-pets="dog cat small">
<div class="card__icon" aria-hidden="true">🏡</div>
<h2 class="card__title">Boarding</h2>
<p class="card__blurb">Cosy overnight stays with medical supervision, playtime and daily photo updates.</p>
<div class="card__tags"><span class="tag">Lifestyle</span><span class="tag">All pets</span></div>
<div class="card__foot"><span class="price">from <strong>$42</strong>/night</span><span class="card__time">Per night</span></div>
</li>
<li class="card card--urgent" data-cat="medical" data-pets="dog cat small">
<span class="card__badge">24/7</span>
<div class="card__icon" aria-hidden="true">🚑</div>
<h2 class="card__title">Emergency & Urgent Care</h2>
<p class="card__blurb">Walk in any hour — our on-call team handles trauma, poisoning and critical care.</p>
<div class="card__tags"><span class="tag">Medical</span><span class="tag">All pets</span></div>
<div class="card__foot"><span class="price">Triage <strong>$95</strong></span><span class="card__time">Always open</span></div>
</li>
</ul>
<p class="services__empty" id="emptyState" hidden>No services match that filter. Try another chip.</p>
</section>
<!-- CTA BAND -->
<section class="cta" aria-label="Book an appointment">
<div class="cta__inner">
<div class="cta__text">
<h2 class="cta__title">Ready to book a visit?</h2>
<p class="cta__sub">Same-week appointments available. Call us or book online in under a minute.</p>
</div>
<div class="cta__actions">
<a class="btn btn--ghost" href="tel:+15550182233">📞 (555) 018-2233</a>
<button class="btn btn--primary" type="button" id="bookBtn">Book now</button>
</div>
</div>
</section>
</main>
<script src="script.js"></script>
</body>
</html>Vet Services
A friendly, approachable landing page for a neighbourhood veterinary practice. It opens with a teal hero and a band of filter chips so visitors can narrow the catalogue by pet type (dogs, cats, small pets) or by service category (preventive, medical, lifestyle).
The body is a responsive grid of eight service cards — wellness exams, vaccinations, dental care, surgery, diagnostics, grooming, boarding and 24/7 emergency — each with a rounded icon, a short blurb, a tag set and a clear “from” price. A live counter reflects how many services match the current filter, and an emergency card stays highlighted at all times.
A sticky “book now” CTA band sits at the foot of the page with the clinic phone number and a primary booking button. Everything is vanilla JS — chip filtering, the live count and the smooth-scroll CTA all work with no libraries.
Illustrative UI only — not for real veterinary use.