/**
 * Design Sprint 3 (continued) — Premium Internal Experience, component
 * layer.
 *
 * `pages-premium.css` gave every internal template its page-level chrome
 * (hero, breadcrumb, prose, sidebars, forms, comments, pagination). This
 * module styles the components that sprint introduced *afterwards*, so the
 * remaining internal pages stop being flat lists inside a designed shell:
 *
 *   - Collection Toolbar — the shared filter bar the service archive, city
 *     archive, blog archive and search results now all open with.
 *   - Collection Group — the anchored category/region band under it.
 *   - Blog Featured Card — the magazine lead article.
 *   - Search Card — a result with a media rail, type badge and meta row.
 *   - Illustration — the decorative inline-SVG empty-state scenes.
 *   - Sticky CTA — the small-screen Book/Call bar on the detail routes.
 *   - How It Works — the shared process timeline, off the homepage.
 *   - About pillars — the Mission/Vision block.
 *
 * It does NOT touch Sprint 1 (`hero-premium.css`) or Sprint 2
 * (`sections-premium.css`). Nothing here selects `.home-hero--premium`,
 * and the shared card system stays owned by Sprint 2 — this file consumes
 * the `--premium-*` aliases that module declares rather than redeclaring
 * a single shadow, ring or radius.
 *
 * Design-system rules (unchanged from Sprints 2 and 3):
 *   - No hardcoded colour, spacing, radius, shadow or type value. Tokens,
 *     or `color-mix()` derived from tokens, with a `@supports` fallback to
 *     an existing token.
 *   - Mobile-first: base rules are the 360px layout; every media query is
 *     `min-width`. Chip rows wrap rather than scroll, so no viewport in
 *     the 360–1600px range can overflow horizontally.
 *   - Motion is `transform`/`opacity` only. Nothing here animates a layout
 *     property, so no rule can contribute to CLS. Every element that
 *     reserves space for media does so with `aspect-ratio`, before paint.
 */

/* ==================================================================
   1. Page hero eyebrow
   ------------------------------------------------------------------
   The service and city detail routes now open with their category /
   region above the title, and search with "Search". One rule, reusing
   the eyebrow rhythm Sprint 2 established for section headings.
   ================================================================== */

.page-hero__eyebrow {
	display: inline-flex;
	align-items: center;
	margin: 0 0 var(--space-3);
	padding: var(--space-1) var(--space-3);
	border: 1px solid var(--premium-ring);
	border-radius: var(--radius-full);
	background-color: color-mix(in srgb, var(--color-background) 68%, transparent);
	color: var(--color-primary-700);
	font-size: var(--font-size-xs);
	font-weight: var(--font-weight-semibold);
	letter-spacing: 0.14em;
	text-transform: uppercase;
}

.page-hero--has-overlay .page-hero__eyebrow {
	border-color: color-mix(in srgb, var(--color-text-inverse) 45%, transparent);
	background-color: color-mix(in srgb, var(--color-text-inverse) 14%, transparent);
	color: var(--color-text-inverse);
}

@supports not (color: color-mix(in srgb, red 50%, transparent)) {
	.page-hero__eyebrow {
		background-color: var(--color-background);
	}

	.page-hero--has-overlay .page-hero__eyebrow {
		border-color: var(--color-border);
		background-color: transparent;
	}
}

/* ==================================================================
   2. Collection toolbar
   ------------------------------------------------------------------
   One bar, four templates. Every chip is a link to something that
   already exists (an in-page anchor on the archives, a category archive
   on the blog and search), so the toolbar is presentation, never a
   filter mechanism.
   ================================================================== */

.collection-toolbar {
	display: grid;
	gap: var(--space-5);
	margin-block-end: var(--space-10);
	padding: var(--space-5);
	border: 1px solid var(--premium-ring);
	border-radius: var(--premium-radius);
	background-color: var(--premium-surface-soft);
}

.collection-toolbar__lead {
	display: flex;
	flex-direction: column;
	gap: var(--space-4);
}

.collection-toolbar__count {
	display: flex;
	align-items: baseline;
	gap: var(--space-2);
	margin: 0;
	color: var(--color-text-muted);
	font-size: var(--font-size-sm);
}

.collection-toolbar__count-value {
	font-family: var(--font-family-heading);
	font-size: var(--font-size-xl);
	font-weight: var(--font-weight-medium);
	line-height: 1;
	color: var(--color-heading);
}

.collection-toolbar__count-noun {
	letter-spacing: 0.08em;
	text-transform: uppercase;
	font-size: var(--font-size-xs);
}

.collection-toolbar__search .search-form {
	max-inline-size: none;
}

.collection-toolbar__list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.collection-toolbar__chip {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	/* WCAG 2.2 target size: chips stay at least 24px tall in every
	   direction, with comfortable padding well above that. */
	min-block-size: 2.5rem;
	padding-inline: var(--space-4);
	border: 1px solid var(--premium-ring);
	background-color: var(--color-background);
	color: var(--color-text);
	text-decoration: none;
	transition:
		transform var(--transition-fast) var(--ease-standard),
		border-color var(--transition-fast) var(--ease-standard),
		background-color var(--transition-fast) var(--ease-standard),
		color var(--transition-fast) var(--ease-standard);
}

/* `components.css` already declares `a.chip:hover { color: … }`, which is
   one element-selector more specific than a bare class. These two rules
   match that weight deliberately — without it the active chip would lose
   its inverse text on hover and drop to teal-on-teal. */
a.chip.collection-toolbar__chip:hover,
a.chip.collection-toolbar__chip:focus-visible {
	transform: translateY(-2px);
	border-color: var(--premium-ring-strong);
	background-color: var(--color-background);
	color: var(--color-primary-700);
}

.collection-toolbar__chip--current {
	border-color: var(--color-primary-500);
	background-image: var(--gradient-primary);
	color: var(--color-text-inverse);
}

a.chip.collection-toolbar__chip--current:hover,
a.chip.collection-toolbar__chip--current:focus-visible {
	background-color: transparent;
	color: var(--color-text-inverse);
}

.collection-toolbar__chip-count {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-inline-size: 1.5rem;
	padding-inline: var(--space-1);
	border-radius: var(--radius-full);
	background-color: color-mix(in srgb, var(--color-primary-500) 12%, transparent);
	color: var(--color-primary-700);
	font-size: var(--font-size-xs);
	font-variant-numeric: tabular-nums;
}

.collection-toolbar__chip--current .collection-toolbar__chip-count {
	background-color: color-mix(in srgb, var(--color-text-inverse) 22%, transparent);
	color: var(--color-text-inverse);
}

@supports not (color: color-mix(in srgb, red 50%, transparent)) {
	.collection-toolbar__chip-count {
		background-color: var(--color-primary-100);
	}

	.collection-toolbar__chip--current .collection-toolbar__chip-count {
		background-color: transparent;
		border: 1px solid currentColor;
	}
}

/* ==================================================================
   3. Collection group — one anchored band per category / region
   ================================================================== */

.collection-group {
	/* `scroll-margin` is what makes the toolbar's in-page anchors land
	   below the sticky header instead of underneath it. */
	scroll-margin-block-start: calc(var(--header-height, 4.5rem) + var(--space-6));
}

.collection-group + .collection-group {
	margin-block-start: var(--space-16);
}

.collection-group .section-heading {
	margin-block-end: var(--space-8);
}

/* ==================================================================
   4. Blog: the magazine lead article
   ================================================================== */

.blog-featured {
	display: grid;
	gap: var(--space-6);
	margin-block-end: var(--space-10);
	padding: var(--space-5);
	border: 1px solid var(--premium-ring);
	border-radius: var(--premium-radius);
	background-color: var(--color-background);
	box-shadow: var(--premium-shadow-soft);
	transition:
		transform var(--transition-base) var(--ease-standard),
		box-shadow var(--transition-base) var(--ease-standard),
		border-color var(--transition-base) var(--ease-standard);
}

.blog-featured:hover,
.blog-featured:focus-within {
	transform: translateY(var(--premium-lift));
	border-color: var(--premium-ring-strong);
	box-shadow: var(--premium-shadow-lift);
}

.blog-featured__media {
	display: block;
	border-radius: var(--premium-radius-sm);
	overflow: hidden;
	/* Reserved before the image loads — the LCP candidate on the blog
	   index never shifts the layout under it. */
	aspect-ratio: 16 / 10;
	background-color: var(--premium-surface-soft);
}



.blog-featured__body {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-3);
	padding: var(--space-2) var(--space-2) var(--space-3);
}



.blog-featured__title {
	margin: 0;
	font-family: var(--font-family-heading);
	font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.25rem);
	font-weight: var(--font-weight-medium);
	line-height: var(--line-height-tight);
	letter-spacing: -0.02em;
	text-wrap: balance;
}



.blog-featured__title a:hover {
	color: var(--color-primary-600);
}

.blog-featured__excerpt {
	margin: 0;
	color: var(--color-text-muted);
	font-size: var(--font-size-md);
	line-height: var(--line-height-relaxed);
	max-inline-size: 58ch;
}

.blog-featured__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-2) var(--space-3);
	margin: 0;
	color: var(--color-text-muted);
	font-size: var(--font-size-xs);
}







.blog-featured__cta {
	margin-block-start: var(--space-2);
}

/* The grid card gains the same author slot, so a post reads identically
   whether it is the lead or one of the cards below it. */


.blog-preview-card__thumbnail {
	display: block;
	aspect-ratio: 16 / 10;
	background-color: var(--premium-surface-soft);
	overflow: hidden;
}



/* ==================================================================
   5. Search results
   ================================================================== */

/* Flex rather than grid, so a result with no featured image simply fills
   the row instead of leaving an empty media column behind. */
.search-card {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-5);
	align-items: flex-start;
}

.search-card__media {
	display: block;
	flex: 1 1 100%;
	border-radius: var(--premium-radius-sm);
	overflow: hidden;
	aspect-ratio: 16 / 10;
	background-color: var(--premium-surface-soft);
}



.search-card__body {
	flex: 1 1 16rem;
	min-inline-size: 0;
}

.search-card__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-2) var(--space-3);
	margin: 0 0 var(--space-3);
	color: var(--color-text-muted);
	font-size: var(--font-size-xs);
}

.search-card__meta a {
	text-decoration: none;
}





.search-card__link {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	margin-block-start: var(--space-4);
	color: var(--color-primary-600);
	font-weight: var(--font-weight-semibold);
	font-size: var(--font-size-sm);
	text-decoration: none;
}

.search-card__link:hover {
	color: var(--color-primary-700);
}

.search-card__link svg {
	inline-size: 1rem;
	block-size: 1rem;
	transition: transform var(--transition-fast) var(--ease-standard);
}

.search-card:hover .search-card__link svg {
	transform: translateX(3px);
}

/* ==================================================================
   6. Illustrations — decorative inline SVG empty states
   ================================================================== */

.illustration {
	inline-size: 100%;
	max-inline-size: 20rem;
	margin-inline: auto;
	margin-block-end: var(--space-6);
}

.illustration__svg {
	inline-size: 100%;
	block-size: auto;
	/* Matches the viewBox, so the box is reserved before paint. */
	aspect-ratio: 320 / 200;
	overflow: visible;
	fill: none;
	stroke: var(--color-primary-500);
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.illustration__wash {
	fill: var(--premium-surface-soft);
	stroke: none;
}

.illustration__arch,
.illustration__door {
	fill: var(--color-background);
	stroke: var(--color-primary-500);
}

.illustration__note {
	fill: var(--color-accent-100);
	stroke: var(--color-accent-600);
}

.illustration__note-line,
.illustration__door-line {
	stroke: var(--color-primary-300);
}

.illustration__handle,
.illustration__spark {
	fill: var(--color-accent-400);
	stroke: none;
}

.illustration__spark-line {
	stroke: var(--color-accent-400);
}

.illustration__leaf,
.illustration__pot {
	fill: color-mix(in srgb, var(--color-primary-500) 16%, var(--color-background));
	stroke: var(--color-primary-500);
}

@supports not (color: color-mix(in srgb, red 50%, transparent)) {
	.illustration__leaf,
	.illustration__pot {
		fill: var(--color-primary-50);
	}
}

/* ==================================================================
   7. Sticky CTA — the small-screen Book / Call bar
   ------------------------------------------------------------------
   The detail routes keep their primary action reachable without a
   scroll listener: a fixed bar below 64rem, retired above it because
   the sticky sidebar rail already does the job there.
   ================================================================== */

.sticky-cta {
	position: fixed;
	inset-inline: 0;
	inset-block-end: 0;
	z-index: var(--z-sticky);
	padding: var(--space-3) var(--space-4);
	/* Clears the iOS home indicator without a media query. */
	padding-block-end: calc(var(--space-3) + env(safe-area-inset-bottom, 0px));
	border-block-start: 1px solid var(--premium-ring);
	background-color: color-mix(in srgb, var(--color-background) 92%, transparent);
	box-shadow: var(--premium-shadow-lift);
}

@supports (backdrop-filter: blur(1px)) {
	.sticky-cta {
		backdrop-filter: blur(var(--blur-md));
	}
}

@supports not (color: color-mix(in srgb, red 50%, transparent)) {
	.sticky-cta {
		background-color: var(--color-background);
	}
}

.sticky-cta__inner {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	inline-size: 100%;
	max-inline-size: var(--container-wide);
	margin-inline: auto;
}

.sticky-cta__label {
	flex: 1 1 auto;
	min-inline-size: 0;
	margin: 0;
	color: var(--color-text-muted);
	font-size: var(--font-size-xs);
	font-weight: var(--font-weight-semibold);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	/* Never let a long service name push the buttons off-screen. */
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.sticky-cta__actions {
	display: flex;
	align-items: center;
	gap: var(--space-2);
	flex: 0 0 auto;
}

.sticky-cta__actions .btn {
	min-block-size: 2.75rem;
	padding-inline: var(--space-4);
	border-radius: var(--radius-lg);
	white-space: nowrap;
}

/* The only `max-width` query in this module, and deliberately so: both
   rules below exist purely to make room for a bar that is itself retired
   at 64rem, so expressing them mobile-first would mean undoing them
   above the breakpoint — which cannot be done without also discarding
   `footer.css`'s and `global-components.css`'s own values.
   Browsers without `:has()` keep their default spacing; the bar may then
   sit over the last footer row on a short page, which is a cosmetic
   overlap, never a lost control. */
@media (max-width: 63.9375rem) {
	/* The footer reserves the bar's height so the last row of footer
	   content is never trapped underneath it. */
	body:has(.sticky-cta) .site-footer {
		padding-block-end: calc(var(--space-16) + env(safe-area-inset-bottom, 0px));
	}

	/* The Global Layout floating action stack sits in the same corner, so
	   it is lifted above the bar when both are on screen. */
	body:has(.sticky-cta) .floating-actions {
		inset-block-end: calc(var(--space-16) + env(safe-area-inset-bottom, 0px));
	}
}

/* ==================================================================
   8. How It Works — the shared timeline, off the homepage
   ------------------------------------------------------------------
   `sections-premium.css` (Sprint 2, site-wide) owns the timeline rail,
   the marker and the desktop column switch. The list reset and the step
   card surface, however, live in `home.css`, which only loads on the
   front page — so the two declarations below supply exactly what is
   missing off the homepage and nothing else. They are scoped to
   `.how-it-works`, so they can never reach the homepage's own Process
   section or override Sprint 2.
   ================================================================== */

.how-it-works {
	margin-block-start: var(--space-12);
}



.how-it-works .process-step {
	background-color: var(--color-background);
	border: 1px solid var(--premium-ring);
}

/* ==================================================================
   9. About — Mission / Vision pillars
   ================================================================== */

.about-pillars {
	display: grid;
	gap: var(--space-6);
}

.about-pillar {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-3);
	padding: var(--space-8) var(--space-6);
	border: 1px solid var(--premium-ring);
	border-radius: var(--premium-radius);
	background-image: linear-gradient(
		160deg,
		var(--premium-surface-soft),
		var(--color-background) 60%
	);
	box-shadow: var(--premium-shadow-soft);
}

.about-pillar__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: 3.25rem;
	block-size: 3.25rem;
	border-radius: var(--radius-full);
	background-image: var(--gradient-primary);
	color: var(--color-text-inverse);
}

.about-pillar__icon svg {
	inline-size: 1.5rem;
	block-size: 1.5rem;
}



.about-pillar__title {
	margin: 0;
	font-family: var(--font-family-heading);
	font-size: var(--font-size-xl);
	font-weight: var(--font-weight-medium);
	line-height: var(--line-height-snug);
	letter-spacing: -0.01em;
}

.about-pillar__text {
	margin: 0;
	color: var(--color-text-muted);
	line-height: var(--line-height-relaxed);
}

/* ==================================================================
   10. City — coverage panel
   ------------------------------------------------------------------
   The nearby-areas list reads as a coverage map legend rather than a
   loose row of badges.
   ================================================================== */

.city-section--coverage .city-areas {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2);
	margin: 0;
	padding: var(--space-5);
	list-style: none;
	border: 1px solid var(--premium-ring);
	border-radius: var(--premium-radius);
	background-color: var(--premium-surface-soft);
}

.city-section--coverage .city-areas__item {
	background-color: var(--color-background);
	border: 1px solid var(--premium-ring);
}

/* ==================================================================
   11. Post table of contents — indent level
   ================================================================== */

.post-toc__item--level-3 {
	padding-inline-start: var(--space-4);
	font-size: var(--font-size-xs);
}

/* ==================================================================
   12. Breakpoints
   ================================================================== */

@media (min-width: 30rem) {
	.collection-toolbar {
		padding: var(--space-6);
	}
}

@media (min-width: 48rem) {
	.collection-toolbar__lead {
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
		gap: var(--space-6);
	}

	.collection-toolbar__search {
		flex: 0 1 24rem;
	}

	.blog-featured {
		padding: var(--space-6);
	}

	.search-card {
		flex-wrap: nowrap;
		gap: var(--space-6);
	}

	.search-card__media {
		flex: 0 0 12rem;
		aspect-ratio: 4 / 3;
	}

	.about-pillars {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 64rem) {
	.blog-featured {
		padding: var(--space-8);
	}

	/* Two columns only when there is actually a lead image to put in the
	   first one. Browsers without `:has()` keep the stacked layout, which
	   is a complete design in its own right — not a broken one. */
	.blog-featured:has(.blog-featured__media) {
		grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
		align-items: center;
		gap: var(--space-8);
	}

	.blog-featured__media {
		aspect-ratio: 4 / 3;
		block-size: 100%;
	}

	/* The bar is a small-screen affordance: above 64rem the sticky
	   sidebar rail already keeps Book / Call in view. */
	.sticky-cta {
		display: none;
	}

	.collection-group + .collection-group {
		margin-block-start: var(--space-20);
	}
}

@media (min-width: 80rem) {
	.blog-featured__excerpt {
		font-size: var(--font-size-lg);
	}
}

/* ==================================================================
   13. Motion, contrast and print safeguards
   ================================================================== */

@media (prefers-reduced-motion: reduce) {
	a.chip.collection-toolbar__chip:hover,
	a.chip.collection-toolbar__chip:focus-visible,
	.blog-featured:hover,
	.blog-featured:focus-within {
		transform: none;
	}

	.search-card:hover .search-card__link svg {
		transform: none;
	}
}

@media (forced-colors: active) {
	/* Decorative artwork reads as an unlabelled silhouette in a forced
	   palette — the heading and paragraph beside it already carry the
	   meaning, so the scene stands down entirely. */
	.illustration {
		display: none;
	}

	.collection-toolbar,
	.blog-featured,
	.about-pillar,
	.sticky-cta,
	.city-section--coverage .city-areas {
		border: 1px solid CanvasText;
	}

	.collection-toolbar__chip--current {
		background-image: none;
		background-color: Highlight;
		color: HighlightText;
		forced-color-adjust: none;
	}

	.about-pillar__icon {
		background-image: none;
		border: 1px solid CanvasText;
		color: CanvasText;
	}
}

@media print {
	.collection-toolbar,
	.sticky-cta,
	.illustration,
	.blog-featured__cta,
	.search-card__link {
		display: none;
	}

	.blog-featured,
	.about-pillar {
		border: 1px solid var(--color-border-strong);
		background-image: none;
		box-shadow: none;
	}
}
