/* ============================================================================
 * BRIEFLY — SERVICES SHAPE PACK. Five structurally distinct shapes.
 *
 * ── WHAT IS DIFFERENT ABOUT THIS PACK ───────────────────────────────────────
 * Services is the HEALTHIEST content type in the suite: 31 renderers across 27
 * distinct skeletons, against 0.24 for blog teasers and 0.44 for process steps.
 * So this pack is additive rather than corrective — the existing work is worth
 * keeping, and the job is to give the builder shapes it does not have, not to
 * replace shapes that already earn their place.
 *
 * ── THE PART THAT ACTUALLY DAMAGED SITES ────────────────────────────────────
 * Services is also where three separate live-site breakages lived, and all of
 * them were link resolution rather than layout:
 *   - the model invents service slugs (/lawn-mowing) while the real page is at
 *     /lawn-mowing-coffs-harbour, so a homepage shipped eight 404s;
 *   - service_pages() handed public URLs to UNBUILT DRAFT scaffolds, so every
 *     unbuilt service became a broken link on the most important page on the
 *     site — one line, reaching all thirteen services-index sections at once;
 *   - two themes held the only correct resolver while ten manufactured 404s.
 * Every shape below routes through Briefly_Pro_Trade::resolve_service_url() and
 * renders PLAIN TEXT when it returns nothing. No shape may link a service on
 * its own authority. That branch already existed in every theme; it simply
 * never fired, because a URL was always supplied.
 *
 * ── AND THE ANCHOR ──────────────────────────────────────────────────────────
 * "#services" is the single most common dead in-page anchor in the suite — 17
 * instances pointing at an id no section on those pages provides. Every shape
 * here carries id="services" on its section head, so the target exists at
 * source rather than being repaired at render time.
 * ========================================================================== */

/* ── SHARED GROUND ───────────────────────────────────────────────────────── */

.bfy-svc { padding: var(--bfy-sect, clamp(3rem, 5vw, 4.5rem)) var(--bfy-gut, clamp(1.5rem, 4vw, 3rem)); box-sizing: border-box; }
.bfy-svc__inner { max-width: var(--bfy-head-measure-wide, 1160px); margin: 0 auto; }

/* A services index is a LIST. It was 31 renderers of nested divs; a screen
   reader user gets "list, 12 items" here instead of nothing. */
.bfy-svc__list { list-style: none; margin: 0; padding: 0; }
.bfy-svc__item { min-width: 0; }

.bfy-svc__name {
	margin: 0;
	font-family: var(--bfy-title-font, inherit);
	font-size: var(--bfy-svc-name, 1.14rem);
	font-weight: 600;
	line-height: 1.3;
	letter-spacing: -0.005em;
	color: var(--bfy-title-ink, var(--wp--preset--color--foreground, #16181D));
}
.bfy-svc__desc {
	margin: 0.5rem 0 0;
	font-size: var(--bfy-svc-desc, 0.95rem);
	line-height: 1.55;
	color: var(--bfy-lede-ink, var(--wp--preset--color--foreground, #55606B));
	text-wrap: pretty;
}

/* A resolvable service is a link; an unresolvable one is text that still reads
   correctly. The two must be visually distinguishable or the page silently
   lies about what is clickable. */
.bfy-svc__link { color: inherit; text-decoration: none; }
.bfy-svc__link:hover { text-decoration: underline; text-underline-offset: 0.18em; }
.bfy-svc__link:focus-visible {
	outline: 3px solid var(--wp--preset--color--primary, currentColor);
	outline-offset: 3px;
	border-radius: 3px;
}

.bfy-svc__icon {
	flex: 0 0 auto;
	width: var(--bfy-svc-icon, 34px);
	height: var(--bfy-svc-icon, 34px);
	color: var(--bfy-svc-icon-ink, var(--wp--preset--color--primary, #0F4C5C));
}
.bfy-svc__icon svg { width: 100%; height: 100%; display: block; }

.bfy-svc__cat {
	font-size: var(--bfy-eyebrow-size, 0.75rem);
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--bfy-eyebrow-ink, var(--wp--preset--color--primary, #0F4C5C));
}


/* ── 1. GRID ─────────────────────────────────────────────────────────────────
 * The card grid, kept. It is the right answer for 6-12 peer services with no
 * hierarchy between them, which is most trade and clinic sites.
 * -------------------------------------------------------------------------- */

.bfy-svc--grid .bfy-svc__list {
	display: grid;
	grid-template-columns: var(--bfy-svc-cols, repeat(auto-fit, minmax(min(100%, 280px), 1fr)));
	gap: var(--bfy-svc-gap, clamp(1rem, 2vw, 1.5rem));
}
.bfy-svc--grid .bfy-svc__item {
	padding: var(--bfy-svc-pad, clamp(1.25rem, 2.2vw, 1.75rem));
	background: var(--bfy-svc-bg, var(--wp--preset--color--background-alt, #FFFFFF));
	border: 1px solid var(--bfy-svc-border, rgba(18, 24, 28, 0.10));
	border-radius: var(--bfy-svc-radius, 14px);
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
}


/* ── 2. RAIL ─────────────────────────────────────────────────────────────────
 * Category-grouped horizontal strips with a sticky category label.
 *
 * For a business with MANY services across a few categories — the case that
 * broke the builder, where 40 services met a 25-page cap. A grid of 40 cards is
 * a wall; four labelled rails of ten is a catalogue you can scan.
 *
 * The category label is position:sticky inside its own strip, so it stays put
 * while that strip scrolls sideways. The suite currently contains ZERO uses of
 * position:sticky.
 * -------------------------------------------------------------------------- */

.bfy-svc--rail .bfy-svc__group + .bfy-svc__group { margin-top: var(--bfy-svc-group-gap, clamp(1.75rem, 3vw, 2.5rem)); }
.bfy-svc--rail .bfy-svc__cat {
	position: sticky;
	left: 0;
	display: block;
	margin-bottom: 0.85rem;
}
.bfy-svc--rail .bfy-svc__list {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: var(--bfy-svc-rail-w, clamp(220px, 26vw, 290px));
	gap: var(--bfy-svc-gap, clamp(1rem, 2vw, 1.5rem));
	overflow-x: auto;
	scroll-snap-type: x proximity;
	scroll-padding-left: var(--bfy-gut, clamp(1.5rem, 4vw, 3rem));
	margin-right: var(--bfy-rail-bleed, calc(50% - 50vw));
	padding-right: var(--bfy-gut, clamp(1.5rem, 4vw, 3rem));
	padding-bottom: 0.5rem;
	scrollbar-width: thin;
	overscroll-behavior-x: contain;
}
.bfy-svc--rail .bfy-svc__item {
	scroll-snap-align: start;
	padding: var(--bfy-svc-pad, 1.25rem);
	background: var(--bfy-svc-bg, var(--wp--preset--color--background-alt, #FFFFFF));
	border: 1px solid var(--bfy-svc-border, rgba(18, 24, 28, 0.10));
	border-radius: var(--bfy-svc-radius, 14px);
}
.bfy-svc--rail .bfy-svc__list:focus-visible {
	outline: 3px solid var(--wp--preset--color--primary, currentColor);
	outline-offset: 4px;
}


/* ── 3. SPLIT-STICKY ─────────────────────────────────────────────────────────
 * A sticky index on the left, the service detail running beside it.
 *
 * This is what a real agency page does with 5-9 services that each deserve a
 * paragraph: you never lose your place, and the index doubles as a table of
 * contents. It also gives every service a genuine in-page anchor destination,
 * which is the honest fix for the "#services" family of dead links rather than
 * repairing them after the fact.
 * -------------------------------------------------------------------------- */

.bfy-svc--split .bfy-svc__inner {
	display: grid;
	grid-template-columns: var(--bfy-svc-split-cols, minmax(0, 0.36fr) minmax(0, 1fr));
	gap: var(--bfy-svc-split-gap, clamp(1.5rem, 4vw, 3.5rem));
	align-items: start;
}
.bfy-svc--split .bfy-svc__index {
	position: sticky;
	/* Clears a sticky site header. Same offset the section head uses for
	   scroll-margin, so the two never disagree. */
	top: var(--bfy-anchor-offset, 6rem);
	align-self: start;
}
.bfy-svc--split .bfy-svc__index ol { list-style: none; margin: 0.85rem 0 0; padding: 0; display: grid; gap: 0.55rem; }
.bfy-svc--split .bfy-svc__index a {
	display: block;
	padding: 0.35rem 0;
	font-size: var(--bfy-svc-index, 0.95rem);
	color: var(--bfy-lede-ink, var(--wp--preset--color--foreground, #55606B));
	text-decoration: none;
	border-bottom: 1px solid var(--bfy-svc-border, rgba(18, 24, 28, 0.10));
}
.bfy-svc--split .bfy-svc__index a:hover { color: var(--bfy-title-ink, var(--wp--preset--color--foreground, #16181D)); }
.bfy-svc--split .bfy-svc__index a:focus-visible {
	outline: 3px solid var(--wp--preset--color--primary, currentColor);
	outline-offset: 2px;
}

.bfy-svc--split .bfy-svc__list { display: grid; gap: var(--bfy-svc-run-gap, clamp(2rem, 4vw, 3rem)); }
.bfy-svc--split .bfy-svc__item { scroll-margin-top: var(--bfy-anchor-offset, 6rem); }
.bfy-svc--split .bfy-svc__name { font-size: var(--bfy-svc-run-name, clamp(1.25rem, 2vw, 1.6rem)); }
.bfy-svc--split .bfy-svc__desc { max-width: 62ch; }


/* ── 4. MATRIX ───────────────────────────────────────────────────────────────
 * Category headings with their services listed beneath as plain rows — no
 * cards, no boxes. Atlas's shape, generalised.
 *
 * The right answer for a multi-service business where the STRUCTURE is the
 * information: what falls under what. Cards actively hurt here, because a box
 * around each leaf makes every service look equally weighted and hides the
 * grouping that is the whole point.
 * -------------------------------------------------------------------------- */

.bfy-svc--matrix .bfy-svc__grid {
	display: grid;
	grid-template-columns: var(--bfy-svc-matrix-cols, repeat(auto-fit, minmax(min(100%, 240px), 1fr)));
	gap: var(--bfy-svc-matrix-gap, clamp(1.5rem, 3vw, 2.5rem));
}
.bfy-svc--matrix .bfy-svc__cat {
	display: block;
	padding-bottom: 0.7rem;
	margin-bottom: 0.85rem;
	border-bottom: 1px solid var(--bfy-svc-border, rgba(18, 24, 28, 0.14));
}
.bfy-svc--matrix .bfy-svc__list { display: grid; gap: 0.5rem; }
.bfy-svc--matrix .bfy-svc__name { font-size: var(--bfy-svc-matrix-name, 0.98rem); font-weight: 500; }


/* ── 5. EDITORIAL RUNS ───────────────────────────────────────────────────────
 * 3-5 high-value services, each given a full run: large name, a rule, a real
 * paragraph, and one link.
 *
 * NO NUMERALS, DELIBERATELY. The obvious editorial treatment is "01 / 02 / 03"
 * down the left, and it is wrong here: a numbered marker tells the reader the
 * ORDER CARRIES INFORMATION. For a process it does. For a service list it does
 * not — it implies a ranking the business never stated, and it is the single
 * most common way a generated page invents a claim. Several existing "process"
 * sections in this suite are unordered benefit lists already wearing 01/02/03;
 * this pack does not add more.
 *
 * The hairline and the size do the same structural work without the assertion.
 * -------------------------------------------------------------------------- */

.bfy-svc--runs .bfy-svc__list { display: grid; gap: 0; }
.bfy-svc--runs .bfy-svc__item {
	display: grid;
	grid-template-columns: var(--bfy-svc-runs-cols, minmax(0, 0.85fr) minmax(0, 1.15fr));
	gap: var(--bfy-svc-runs-gap, clamp(1.5rem, 4vw, 3rem));
	align-items: start;
	padding: var(--bfy-svc-runs-pad, clamp(1.75rem, 3vw, 2.5rem)) 0;
	border-top: 1px solid var(--bfy-svc-border, rgba(18, 24, 28, 0.14));
}
.bfy-svc--runs .bfy-svc__item:last-child { border-bottom: 1px solid var(--bfy-svc-border, rgba(18, 24, 28, 0.14)); }
.bfy-svc--runs .bfy-svc__name {
	font-size: var(--bfy-svc-runs-name, clamp(1.5rem, 3vw, 2.2rem));
	font-weight: 700;
	letter-spacing: -0.02em;
	text-wrap: balance;
}
.bfy-svc--runs .bfy-svc__desc { margin: 0; font-size: var(--bfy-lede-size, clamp(1rem, 1.3vw, 1.08rem)); max-width: 56ch; }
.bfy-svc--runs .bfy-svc__more {
	display: inline-block;
	margin-top: 1rem;
	font-size: 0.92rem;
	font-weight: 600;
	color: var(--bfy-eyebrow-ink, var(--wp--preset--color--primary, #0F4C5C));
}


/* ── RESPONSIVE ──────────────────────────────────────────────────────────── */

@media (max-width: 760px) {
	.bfy-svc--split .bfy-svc__inner { grid-template-columns: 1fr; }
	/* A sticky index above the content it indexes would pin a list to the top of
	   a phone screen and eat the viewport. It becomes an ordinary jump list. */
	.bfy-svc--split .bfy-svc__index { position: static; }

	.bfy-svc--runs .bfy-svc__item { grid-template-columns: 1fr; gap: 0.85rem; }
}


/* ── QUALITY FLOOR ───────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
	.bfy-svc__list { scroll-behavior: auto; }
	.bfy-svc, .bfy-svc * { animation: none !important; transition: none !important; }
}

/* A sticky element with no scroll-margin partner lands under the site header
   when jumped to; both offsets read the same token so they cannot drift. */
.bfy-svc__item[id] { scroll-margin-top: var(--bfy-anchor-offset, 6rem); }

@media (forced-colors: active) {
	.bfy-svc--grid .bfy-svc__item,
	.bfy-svc--rail .bfy-svc__item { border-color: CanvasText; }
	.bfy-svc--runs .bfy-svc__item { border-top-color: CanvasText; }
	.bfy-svc__icon { color: CanvasText; }
}

@media print {
	.bfy-svc--rail .bfy-svc__list { display: block; overflow: visible; }
	.bfy-svc--split .bfy-svc__index { position: static; }
}
