/*
Theme Name: Sebo Theme
Theme URI: https://sebomarketing.com
Author: Sebo Marketing
Author URI: https://sebomarketing.com
Description: Brand-agnostic WordPress block theme used as the starting point for Sebo Marketing client sites. All colour, type, and spacing decisions live as design tokens in theme.json; this stylesheet only covers what theme.json cannot express. WooCommerce-ready.
Requires at least: 6.6
Tested up to: 7.0
Requires PHP: 8.1
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: sebo
Tags: block-theme, full-site-editing, e-commerce, one-column, custom-colors, custom-menu, editor-style
*/

/* -------------------------------------------------------------------------
   1. Base
   ---------------------------------------------------------------------- */

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}
}

body {
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-rendering: optimizeLegibility;
	font-optical-sizing: auto;
}

/* Balance short headings rather than leaving a single orphaned word. */
h1,
h2,
h3,
.wp-block-post-title {
	text-wrap: balance;
}

p,
li {
	text-wrap: pretty;
}

/* Body copy caps its measure even inside wide containers. */
:where(.entry-content) p:not([class*="has-"]) {
	max-width: 68ch;
}

img,
video {
	max-width: 100%;
	height: auto;
}

/* WordPress puts a block-gap margin between every top-level block, which
   leaves a white strip between the header and the first full-bleed section,
   and another between the last section and the footer. Sections carry their
   own padding, so those gaps are never wanted here. */
.wp-site-blocks > main,
.wp-site-blocks > .wp-block-template-part {
	margin-block-start: 0;
}

/* -------------------------------------------------------------------------
   2. Focus — a single visible treatment everywhere.
      Never remove this; keyboard users depend on it.
   ---------------------------------------------------------------------- */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	outline: 3px solid var(--wp--preset--color--action);
	outline-offset: 2px;
	border-radius: 2px;
}

/* Dark grounds need a light ring to stay visible. */
.sb-on-dark :where(a, button, input, select, textarea):focus-visible {
	outline-color: var(--wp--preset--color--accent);
}

.skip-link {
	position: absolute;
	top: -100vh;
	left: 0;
	z-index: 999999;
	padding: 0.85rem 1.5rem;
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--base);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	text-decoration: none;
	border-bottom-right-radius: 6px;
}

.skip-link:focus {
	top: 0;
}

.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* -------------------------------------------------------------------------
   3. Links — underlines that sit below the baseline rather than
      slicing through descenders.
   ---------------------------------------------------------------------- */

:where(.entry-content, .wp-block-post-content) a:where(:not(.wp-element-button):not(.wp-block-button__link)) {
	text-decoration-thickness: 1px;
	text-underline-offset: 0.18em;
	text-decoration-color: rgba(44, 97, 63, 0.4);
	transition: text-decoration-color var(--wp--custom--transition--base);
}

:where(.entry-content, .wp-block-post-content) a:where(:not(.wp-element-button)):hover {
	text-decoration-color: currentColor;
}

/* Buttons and nav links must not inherit the content underline. */
.wp-block-navigation a,
.wp-element-button,
.wp-block-button__link {
	text-decoration: none;
}

.wp-element-button,
.wp-block-button__link {
	transition: background-color var(--wp--custom--transition--base),
		color var(--wp--custom--transition--base),
		transform var(--wp--custom--transition--base);
}

.wp-element-button:hover,
.wp-block-button__link:hover {
	transform: translateY(-1px);
}

/* Secondary button: outlined, for lower-priority actions. */
.wp-block-button.is-style-outline > .wp-block-button__link {
	background: transparent;
	color: var(--wp--preset--color--action);
	border: 1.5px solid var(--wp--preset--color--action);
}

.wp-block-button.is-style-outline > .wp-block-button__link:hover {
	background: var(--wp--preset--color--action);
	color: var(--wp--preset--color--base);
}

/* -------------------------------------------------------------------------
   4. Header
   ---------------------------------------------------------------------- */

/* Stickiness has to live on the template-part wrapper, not on .sb-header.
   WordPress renders the header part inside a <div class="wp-block-template-part">
   that is exactly as tall as the header, and a sticky element cannot travel
   beyond its containing block — so sticking it to .sb-header gives it zero
   travel and it scrolls away immediately. */
.wp-site-blocks > .wp-block-template-part:has(.sb-header),
.wp-site-blocks > .wp-block-template-part:first-child {
	position: sticky;
	/* The admin bar is position:fixed at the top of the viewport for logged-in
	   users, so a header stuck to 0 slides underneath it. WordPress exposes the
	   bar's height as a custom property (32px, or 46px under 782px), which also
	   keeps this correct when the bar is absent. */
	top: var(--wp-admin--admin-bar--height, 0px);
	z-index: 100;
}

/* Fallback for WordPress versions that do not set the custom property. */
body.admin-bar .wp-site-blocks > .wp-block-template-part:has(.sb-header),
body.admin-bar .wp-site-blocks > .wp-block-template-part:first-child {
	top: var(--wp-admin--admin-bar--height, 32px);
}

@media screen and (max-width: 782px) {
	body.admin-bar .wp-site-blocks > .wp-block-template-part:has(.sb-header),
	body.admin-bar .wp-site-blocks > .wp-block-template-part:first-child {
		top: var(--wp-admin--admin-bar--height, 46px);
	}
}

/* Below 600px the admin bar stops being fixed and scrolls away with the page,
   so the header must sit flush again or it leaves a 46px gap. */
@media screen and (max-width: 600px) {
	body.admin-bar .wp-site-blocks > .wp-block-template-part:has(.sb-header),
	body.admin-bar .wp-site-blocks > .wp-block-template-part:first-child {
		top: 0;
	}
}

/* The frosted background lives on a pseudo-element, not on .sb-header itself.
   backdrop-filter makes an element the containing block for its
   position:fixed descendants, which collapsed the mobile menu overlay to the
   height of the header instead of the viewport. Keeping the filter on a
   childless pseudo-element preserves the effect without that side effect. */
.sb-header {
	position: relative;
	background: transparent;
	border-bottom: var(--wp--custom--rule--hairline);
}

.sb-header::before {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: rgba(255, 255, 255, 0.92);
	backdrop-filter: saturate(180%) blur(12px);
	-webkit-backdrop-filter: saturate(180%) blur(12px);
}

.sb-header__bar {
	position: relative;
	z-index: 1;
}

/* The bar carries the vertical rhythm, and shrinks in the compact state.
   Padding is on the bar rather than the header so the sticky background
   still spans the full viewport width. */
.sb-header__bar {
	padding-block: clamp(0.85rem, 1.6vw, 1.35rem);
	transition: padding-block var(--wp--custom--transition--base);
}

.sb-header .custom-logo-link,
.sb-header .wp-block-site-logo a {
	display: block;
	line-height: 0;
}

.sb-header .wp-block-site-logo img {
	/* The mark is fine line art and the "PUBLISHING" lettering is light, so
	   the logo needs a little more room than a typical wordmark to stay
	   legible at small sizes. */
	width: clamp(156px, 17vw, 198px);
	height: auto;
	transition: opacity var(--wp--custom--transition--base);
}

.sb-header .wp-block-site-logo a:hover img {
	opacity: 0.78;
}

/* -----------------------------------------------------------------
   Compact (scrolled) header.

   The `is-compact` class is toggled by assets/js/header.js past a
   scroll threshold. Only the circular fairy mark shows, and the bar
   loses height, so more of the page stays visible while scrolling.
   ----------------------------------------------------------------- */

.sb-brand__mark {
	display: none;
	margin: 0;
	line-height: 0;
}

.sb-brand__mark img {
	display: block;
	width: 46px;
	height: auto;
	transition: opacity var(--wp--custom--transition--base);
}

.sb-brand__mark a:hover img {
	opacity: 0.78;
}

.sb-header.is-compact .sb-header__bar {
	padding-block: 0.5rem;
}

.sb-header.is-compact .wp-block-site-logo {
	display: none;
}

.sb-header.is-compact .sb-brand__mark {
	display: block;
}

/* Without JS the header simply stays in its full state — the mark is the
   progressive enhancement, not the baseline. */

/* Nav links: an animated rule that grows from the left on hover, and
   stays put for the current page. */
.sb-header .wp-block-navigation-item__content {
	position: relative;
	padding-block: 0.35rem;
	color: var(--wp--preset--color--ink);
}

.sb-header .wp-block-navigation-item__content::after {
	content: "";
	position: absolute;
	left: 0;
	bottom: 0;
	width: 100%;
	height: 2px;
	background: var(--wp--preset--color--accent);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform var(--wp--custom--transition--base);
}

.sb-header .wp-block-navigation-item:hover .wp-block-navigation-item__content::after,
.sb-header .wp-block-navigation-item.current-menu-item .wp-block-navigation-item__content::after,
.sb-header .wp-block-navigation-item.current-menu-ancestor .wp-block-navigation-item__content::after {
	transform: scaleX(1);
}

/* Submenu (the Books dropdown). */
.sb-header .wp-block-navigation__submenu-container {
	border: none;
	border-radius: 10px;
	padding: 0.4rem;
	min-width: 15rem;
	background: var(--wp--preset--color--base);
	box-shadow: var(--wp--preset--shadow--lifted);
}

.sb-header .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	padding: 0.6rem 0.85rem;
	border-radius: 6px;
	width: 100%;
}

.sb-header .wp-block-navigation__submenu-container .wp-block-navigation-item__content::after {
	display: none;
}

.sb-header .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
	background: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--action);
}

/* -----------------------------------------------------------------
   Mobile overlay menu

   Full-screen, translucent so the page stays faintly visible behind
   it, with a large close control. Woo/WP already render the open and
   close buttons; this is presentation only.
   ----------------------------------------------------------------- */

.wp-block-navigation__responsive-container.is-menu-open,
.wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) {
	padding: clamp(1.25rem, 5vw, 2.5rem);
	/* Warm wash — enough to read against, still showing the page beneath.
	   !important because Woo/WP set `background-color: inherit` here at equal
	   specificity, which otherwise picks up the header's opaque white. */
	background-color: rgba(247, 244, 236, 0.9) !important;
	backdrop-filter: blur(16px) saturate(150%);
	-webkit-backdrop-filter: blur(16px) saturate(150%);
	align-items: stretch;
	justify-content: flex-start;
}

/* Give the list room below the close button and centre it in the sheet. */
/* WordPress nests two wrappers between the overlay and the menu list
   (__responsive-close, then __responsive-dialog). Both must grow, or the
   content has no height to be centred within. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-close,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-dialog {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	width: 100%;
	min-height: 0;
}

.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-container-content {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	align-items: center;
	/* Centre the list in the sheet rather than stacking it under the close
	   button with dead space below. */
	justify-content: center;
	padding-block: clamp(2rem, 8vh, 4rem);
	width: 100%;
	min-height: 0;
}

.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__container {
	gap: 0;
	width: 100%;
	max-width: 22rem;
	text-align: center;
	/* WordPress gives the list flex-grow, which pins the items to the top of
	   the sheet. Auto block margins centre it regardless of that. */
	flex: 0 0 auto;
	margin-block: auto;
}

.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item {
	width: 100%;
	justify-content: center;
	border-bottom: 1px solid rgba(74, 78, 82, 0.12);
}

.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item:last-child {
	border-bottom: 0;
}

.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--x-large);
	font-weight: 500;
	color: var(--wp--preset--color--ink);
	/* Comfortable tap target. */
	padding-block: 0.85rem;
	width: 100%;
	justify-content: center;
}

/* The desktop hover rule draws an underline bar; not wanted in the sheet. */
.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item__content::after {
	display: none;
}

.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item__content:hover {
	color: var(--wp--preset--color--action);
}

/* Submenu (Books) sits indented and quieter, always expanded in the sheet. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container {
	box-shadow: none;
	background: transparent;
	border: 0;
	padding: 0 0 0.5rem;
	min-width: 0;
}

.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__submenu-container
	.wp-block-navigation-item {
	border-bottom: 0;
}

.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__submenu-container
	.wp-block-navigation-item__content {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 400;
	color: var(--wp--preset--color--muted);
	padding-block: 0.6rem;
}

/* Open (hamburger) control. */
.wp-block-navigation__responsive-container-open {
	padding: 0.4rem;
	color: var(--wp--preset--color--ink);
}

.wp-block-navigation__responsive-container-open:hover {
	color: var(--wp--preset--color--action);
}

/* Close (X) control — enlarged and given a visible hit area, since the
   default is a small bare glyph in the corner. */
.wp-block-navigation__responsive-container-close {
	top: clamp(1.25rem, 5vw, 2.5rem);
	right: clamp(1.25rem, 5vw, 2.5rem);
	display: flex;
	align-items: center;
	justify-content: center;
	width: 46px;
	height: 46px;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.9);
	color: var(--wp--preset--color--ink);
	box-shadow: var(--wp--preset--shadow--soft);
	transition: background-color var(--wp--custom--transition--base),
		color var(--wp--custom--transition--base);
}

.wp-block-navigation__responsive-container-close:hover {
	background: var(--wp--preset--color--action);
	color: var(--wp--preset--color--base);
}

.wp-block-navigation__responsive-container-close svg {
	width: 26px;
	height: 26px;
}

/* The overlay is fixed to the viewport, so it must clear the admin bar. */
body.admin-bar .wp-block-navigation__responsive-container.is-menu-open {
	top: var(--wp-admin--admin-bar--height, 46px);
}

/* -------------------------------------------------------------------------
   5. Cart indicator in the header
   ---------------------------------------------------------------------- */

.sb-cart {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	padding: 0.5rem;
	border-radius: 999px;
	color: var(--wp--preset--color--ink);
	text-decoration: none;
	transition: background-color var(--wp--custom--transition--base);
}

.sb-cart:hover {
	background: var(--wp--preset--color--surface);
	color: var(--wp--preset--color--action);
}

.sb-cart svg {
	width: 22px;
	height: 22px;
	display: block;
}

.sb-cart__count {
	position: absolute;
	top: -1px;
	right: -3px;
	min-width: 18px;
	height: 18px;
	padding: 0 5px;
	border-radius: 999px;
	background: var(--wp--preset--color--action);
	color: var(--wp--preset--color--base);
	font-family: var(--wp--preset--font-family--body);
	font-size: 11px;
	font-weight: 700;
	line-height: 18px;
	text-align: center;
}

.sb-cart__count:empty,
.sb-cart__count[data-count="0"] {
	display: none;
}

/* -------------------------------------------------------------------------
   6. Footer
   ---------------------------------------------------------------------- */

.sb-footer {
	background: var(--wp--preset--color--ink);
	color: rgba(255, 255, 255, 0.82);
}

/* The stacked lockup's fairy mark is hairline linework. At 200px those
   white strokes fall below a device pixel and alias into looking rough,
   which reads as pixelation even though the source is vector. Giving it
   more room is the actual fix. */
.sb-footer .wp-block-site-logo img,
.sb-footer__logo img {
	width: clamp(215px, 22vw, 275px);
	height: auto;
	/* Nudge the fine strokes away from sub-pixel rendering. */
	shape-rendering: geometricPrecision;
}

.sb-footer :where(h2, h3, h4, h5, h6) {
	color: var(--wp--preset--color--base);
}

.sb-footer a {
	color: rgba(255, 255, 255, 0.82);
	text-decoration: none;
}

.sb-footer a:hover {
	color: var(--wp--preset--color--accent);
	text-decoration: underline;
	text-underline-offset: 0.18em;
}

.sb-footer .wp-block-navigation {
	gap: 0.55rem;
}

.sb-footer__legal {
	border-top: 1px solid rgba(255, 255, 255, 0.14);
}

/* -------------------------------------------------------------------------
   7. Editorial pieces
   ---------------------------------------------------------------------- */

/* Eyebrow label above a section heading. */
.sb-eyebrow {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--wp--preset--color--action);
}

/* When the eyebrow is a term list (e.g. the product category on a book page)
   its links must not pick up the content underline — at this size and letter
   spacing an underline reads as noise. */
.sb-eyebrow a {
	color: inherit;
	text-decoration: none;
}

.sb-eyebrow a:hover {
	text-decoration: underline;
	text-underline-offset: 0.25em;
}

/* A framed image with depth, for a product shot or cover. */
.sb-object img {
	border-radius: 3px 10px 10px 3px;
	box-shadow: var(--wp--preset--shadow--book);
}

/* -----------------------------------------------------------------
   Immersive hero — artwork behind the copy

   A whole-image dim would flatten the painting, so the scrim is
   left-weighted: dark enough for white type on the copy side, and
   clear on the right where the cover sits.
   ----------------------------------------------------------------- */

.sb-hero-immersive {
	position: relative;
	overflow: hidden;
}

.sb-hero-immersive::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	background:
		linear-gradient(
			100deg,
			rgba(38, 30, 26, 0.88) 0%,
			rgba(38, 30, 26, 0.74) 36%,
			rgba(38, 30, 26, 0.34) 62%,
			rgba(38, 30, 26, 0.12) 100%
		);
}

/* On narrow screens the columns stack, so the copy sits over the middle of
   the image and needs an even wash instead of a side gradient. */
@media (max-width: 781px) {
	.sb-hero-immersive::before {
		background: linear-gradient(
			180deg,
			rgba(38, 30, 26, 0.72) 0%,
			rgba(38, 30, 26, 0.84) 55%,
			rgba(38, 30, 26, 0.72) 100%
		);
	}
}

.sb-hero-immersive .wp-block-cover__inner-container {
	position: relative;
	z-index: 2;
}

.sb-hero-immersive__eyebrow {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	/* Brand green reads well against the dark scrim; it is only unusable
	   on light grounds. */
	color: var(--wp--preset--color--accent);
}

.sb-hero-immersive__meta {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--x-small);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.72);
}

.sb-hero-immersive h1 em {
	font-style: italic;
}

/* Lift the cover off the artwork so it reads as a physical object rather
   than part of the painting. */
.sb-object--floating img {
	box-shadow: 0 4px 12px rgba(20, 28, 25, 0.3), 0 28px 64px rgba(20, 28, 25, 0.45);
}

/* Outline button on a dark ground. */
.sb-btn-on-dark .wp-block-button__link,
.wp-block-button.is-style-outline.sb-btn-on-dark > .wp-block-button__link {
	color: var(--wp--preset--color--base);
	border-color: rgba(255, 255, 255, 0.65);
	background: transparent;
}

.sb-btn-on-dark .wp-block-button__link:hover,
.wp-block-button.is-style-outline.sb-btn-on-dark > .wp-block-button__link:hover {
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--action);
	border-color: var(--wp--preset--color--base);
}

/* A soft rounded frame for photography and artwork. */
.sb-media img {
	border-radius: 14px;
}

/* Emphasised pull quote, for a tagline or short testimonial. */
.sb-lede-quote {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--large);
	font-weight: 500;
	font-style: italic;
	line-height: 1.55;
	color: var(--wp--preset--color--action);
	text-align: center;
}

/* Decorative divider: a hairline rule either side of a small glyph. */
.sb-divider {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.75rem;
	color: var(--wp--preset--color--accent);
}

.sb-divider::before,
.sb-divider::after {
	content: "";
	height: 1px;
	flex: 1 1 auto;
	max-width: 7rem;
	background: currentColor;
}

/* Cards */
.sb-card {
	background: var(--wp--preset--color--base);
	border-radius: 16px;
	box-shadow: var(--wp--preset--shadow--soft);
	overflow: hidden;
	transition: box-shadow var(--wp--custom--transition--base),
		transform var(--wp--custom--transition--base);
}

.sb-card:hover {
	box-shadow: var(--wp--preset--shadow--lifted);
	transform: translateY(-3px);
}

/* -------------------------------------------------------------------------
   8. Blog
   ---------------------------------------------------------------------- */

/* The post grid is declared as a fixed 3-up in the templates, because
   combining columnCount with minimumColumnWidth made WordPress emit an
   unpredictable 2-up. Collapsing for narrower screens is done here. */
.wp-block-post-template.is-layout-grid {
	gap: var(--wp--preset--spacing--30);
}

@media (max-width: 1024px) {
	.wp-block-post-template.is-layout-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
	}
}

@media (max-width: 660px) {
	.wp-block-post-template.is-layout-grid {
		grid-template-columns: minmax(0, 1fr) !important;
	}
}

/* The blog intro sits in a wide container so its rule spans the grid; its
   text should start at the same left edge as the first card, not be centred
   inside it. */
.sb-blog-intro > * {
	margin-inline: 0;
}

.sb-blog-intro p {
	max-width: 58ch;
}

/* Cards stretch to the row height so the "Keep reading" link lands on a
   consistent baseline instead of floating wherever the excerpt ends. */
.sb-post-card {
	display: flex;
	flex-direction: column;
	height: 100%;
}

.sb-post-card .wp-block-post-excerpt {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
}

.sb-post-card .wp-block-post-excerpt__more-text {
	margin-top: auto;
	padding-top: 0.75rem;
}

.sb-post-card .wp-block-post-excerpt__more-text a {
	font-weight: 600;
	text-decoration: none;
	border-bottom: 1px solid rgba(44, 97, 63, 0.35);
}

.sb-post-card .wp-block-post-excerpt__more-text a:hover {
	border-bottom-color: currentColor;
}

.sb-post-card .wp-block-post-featured-image img {
	border-radius: 12px;
	aspect-ratio: 3 / 2;
	object-fit: cover;
	width: 100%;
}

.sb-post-card .wp-block-post-title {
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.25;
}

.sb-post-card .wp-block-post-title a {
	text-decoration: none;
	color: var(--wp--preset--color--ink);
}

.sb-post-card .wp-block-post-title a:hover {
	color: var(--wp--preset--color--action);
}

.sb-meta {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--x-small);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
}

.wp-block-query-pagination {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
}

/* -------------------------------------------------------------------------
   9. Forms — Gravity Forms and core inputs share one look
   ---------------------------------------------------------------------- */

input:where([type="text"], [type="email"], [type="url"], [type="tel"], [type="number"], [type="password"], [type="search"], [type="date"]),
select,
textarea,
.wp-block-search__input {
	width: 100%;
	padding: 0.8rem 1rem;
	background: var(--wp--preset--color--base);
	border: 1.5px solid rgba(74, 78, 82, 0.22);
	border-radius: 8px;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--medium);
	color: var(--wp--preset--color--ink);
	transition: border-color var(--wp--custom--transition--base),
		box-shadow var(--wp--custom--transition--base);
}

input:where([type="text"], [type="email"], [type="url"], [type="tel"], [type="number"], [type="password"], [type="search"]):focus,
select:focus,
textarea:focus {
	border-color: var(--wp--preset--color--action);
	box-shadow: 0 0 0 3px rgba(44, 97, 63, 0.14);
	outline: none;
}

::placeholder {
	color: rgba(74, 78, 82, 0.5);
	opacity: 1;
}

label {
	display: block;
	margin-bottom: 0.4rem;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	color: var(--wp--preset--color--ink);
}

/* -----------------------------------------------------------------
   Gravity Forms

   Selectors are doubled up on `.gform_wrapper` where
   Gravity's own stylesheet would otherwise win on specificity.
   ----------------------------------------------------------------- */

.gform_wrapper .gform_fields {
	grid-row-gap: var(--wp--preset--spacing--20);
	grid-column-gap: var(--wp--preset--spacing--20);
}

.gform_wrapper .gfield_label,
.gform_wrapper legend.gfield_label {
	display: block;
	margin-bottom: 0.4rem;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	color: var(--wp--preset--color--ink);
	letter-spacing: 0;
}

.gform_wrapper .gfield_required,
.gform_wrapper .gfield_required .gfield_required_asterisk {
	color: #a4341f;
	font-weight: 600;
}

.gform_wrapper .gfield_description {
	padding-top: 0.35rem;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--x-small);
	color: var(--wp--preset--color--muted);
	line-height: 1.5;
}

/* Inputs: match the site's field styling, overriding Gravity's. */
.gform_wrapper .ginput_container input[type="text"],
.gform_wrapper .ginput_container input[type="email"],
.gform_wrapper .ginput_container input[type="tel"],
.gform_wrapper .ginput_container input[type="url"],
.gform_wrapper .ginput_container input[type="number"],
.gform_wrapper .ginput_container select,
.gform_wrapper .ginput_container textarea {
	width: 100%;
	padding: 0.8rem 1rem;
	background: var(--wp--preset--color--base);
	border: 1.5px solid rgba(74, 78, 82, 0.22);
	border-radius: 8px;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--medium);
	color: var(--wp--preset--color--ink);
	line-height: 1.5;
	transition: border-color var(--wp--custom--transition--base),
		box-shadow var(--wp--custom--transition--base);
}

.gform_wrapper .ginput_container textarea {
	min-height: 9rem;
	resize: vertical;
}

.gform_wrapper .ginput_container input:focus,
.gform_wrapper .ginput_container select:focus,
.gform_wrapper .ginput_container textarea:focus {
	border-color: var(--wp--preset--color--action);
	box-shadow: 0 0 0 3px rgba(44, 97, 63, 0.14);
	outline: none;
}

/* Native select needs its own chevron once the default look is replaced. */
.gform_wrapper .ginput_container select {
	appearance: none;
	-webkit-appearance: none;
	background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234A4E52' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 0.9rem center;
	background-size: 18px 18px;
	padding-right: 2.6rem;
}

/* Submit button — the brand pill. */
.gform_wrapper .gform_footer input[type="submit"],
.gform_wrapper .gform_footer button[type="submit"],
.gform_wrapper .gform_page_footer input[type="button"],
.gform_wrapper .gform_page_footer input[type="submit"] {
	width: auto;
	background: var(--wp--preset--color--action);
	color: var(--wp--preset--color--base);
	border: 0;
	border-radius: 999px;
	padding: 0.95rem 2.1rem;
	margin: 0;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.03em;
	line-height: 1.2;
	text-transform: none;
	cursor: pointer;
	transition: background-color var(--wp--custom--transition--base),
		transform var(--wp--custom--transition--base);
}

.gform_wrapper .gform_footer input[type="submit"]:hover,
.gform_wrapper .gform_footer button[type="submit"]:hover {
	background: var(--wp--preset--color--ink);
	transform: translateY(-1px);
}

.gform_wrapper .gform_footer {
	padding: var(--wp--preset--spacing--20) 0 0;
	margin: 0;
	justify-content: flex-start;
}

/* Validation */
.gform_wrapper .gfield_description.validation_message,
.gform_wrapper .validation_message {
	margin-top: 0.4rem;
	padding: 0.5rem 0.75rem;
	background: #fdf3f1;
	border: 0;
	border-left: 3px solid #a4341f;
	border-radius: 6px;
	font-size: var(--wp--preset--font-size--x-small);
	color: #8f2d1b;
}

.gform_wrapper .gfield_error input,
.gform_wrapper .gfield_error select,
.gform_wrapper .gfield_error textarea {
	border-color: #a4341f;
}

.gform_wrapper .gform_validation_errors {
	border-radius: 10px;
	border: 0;
	border-left: 3px solid #a4341f;
	background: #fdf3f1;
	box-shadow: none;
	padding: 1rem 1.25rem;
}

.gform_wrapper .gform_validation_errors > h2 {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	color: #8f2d1b;
	margin: 0;
}

.gform_wrapper .gform_validation_errors > h2::before {
	display: none;
}

/* Inline confirmation, for any form not routed to a Thank You page. */
.gform_confirmation_message {
	padding: var(--wp--preset--spacing--30);
	background: var(--wp--preset--color--surface);
	border-left: 3px solid var(--wp--preset--color--action);
	border-radius: 10px;
	font-size: var(--wp--preset--font-size--large);
	font-family: var(--wp--preset--font-family--heading);
}

/* -------------------------------------------------------------------------
   10. Utilities
   ---------------------------------------------------------------------- */

/* Let a wide/full block bleed to the viewport edge on small screens. */
@media (max-width: 600px) {
	.sb-bleed-mobile {
		margin-left: calc(var(--wp--preset--spacing--20) * -1);
		margin-right: calc(var(--wp--preset--spacing--20) * -1);
		border-radius: 0;
	}
}

/* Overlay text needs a scrim to stay readable over artwork. */
.sb-scrim::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		180deg,
		rgba(74, 78, 82, 0.55) 0%,
		rgba(74, 78, 82, 0.2) 45%,
		rgba(74, 78, 82, 0.5) 100%
	);
	pointer-events: none;
}

.sb-scrim > * {
	position: relative;
	z-index: 1;
}

/* A monochrome logo can serve both the light header and the dark footer by
   being inverted, rather than needing a separate reversed asset. Only sound for
   single-colour marks — a full-colour logo must have its own reversed file. */
.sb-footer__logo--invert img {
	filter: invert(1) brightness(1.9);
}

/* -------------------------------------------------------------------------
   13. Counter band, case results, attorney profile
   ---------------------------------------------------------------------- */

/* Tabular figures stop the count-up from reflowing the line as digits change
   width — without this the number visibly jitters while it animates. */
.sb-counter {
	font-variant-numeric: tabular-nums;
	font-feature-settings: "tnum" 1;
}

/* Measured on the rendered page, not derived from the brief.
   `muted` is chosen to clear 4.5:1 on base, surface and tint — all light
   grounds. On the dark band it lands at 1.99:1, so any .sb-meta inside
   .sb-on-dark has to be re-stated rather than inherited. This affects the
   stock stat-band pattern too, which is why the rule is scoped to .sb-on-dark
   and not to the counter band alone.
   #DCEAEC on ink = 10.24:1. */
.sb-on-dark .sb-meta {
	color: var(--wp--preset--color--tint);
}

/* The brand teal is a fill, never a text ground — and it is not a text colour
   on a dark ground either: #0096a9 on ink is 3.57:1. Lightening the token
   itself keeps the teal reading, clears AA at 6.39:1, and survives a rebrand:
   there is no second hex to update when the palette changes.
   Scoped to .sb-on-dark deliberately — this mix is 1.98:1 on white. */
.sb-on-dark .sb-eyebrow {
	color: var(--wp--preset--color--tint); /* fallback where color-mix is absent */
	color: color-mix(in srgb, var(--wp--preset--color--accent) 55%, white);
}

/* Results are rows divided by rules rather than cards. A card per result reads
   as a promotional tile; a rule reads as a record, which is the tone wanted
   next to money figures. */
.sb-result + .sb-result {
	border-top: 1px solid var(--wp--preset--color--tint);
}

.sb-result {
	align-items: baseline;
}

/* Fix the figure column rather than setting a minimum on it. Not every result
   is a number — "Multi-million" and "Protected" are real entries — and with
   `min-width` a long one grows its column and shunts that row's summary out of
   line with all the others. A fixed basis lets the long ones wrap instead. */
/* 9rem clears the longest label currently in use ("Protected", 131px at
   x-large). A flex item defaults to min-width:auto, so a single unbreakable
   word wider than the basis still pushes the column out — hence sizing to the
   content rather than relying on the basis alone. A longer label than this
   would need the value raised, or the label shortened. */
.sb-result__figure {
	flex: 0 0 9rem;
	font-variant-numeric: tabular-nums;
	hyphens: auto;
	margin: 0;
}

.sb-result__body {
	flex: 1 1 22rem;
}

@media (max-width: 600px) {
	.sb-result__figure {
		min-width: 0;
	}
}

/* Headshots arrive at whatever aspect the client had to hand — one square, one
   tall. Fixing the ratio here keeps a row of profiles even, and object-fit
   crops rather than distorting. */
.sb-portrait img {
	width: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	object-position: center top;
	border-radius: 12px;
}

/* The utility strip carries the descriptor the firm wants to be found by, so it
   sits above the masthead on every page. Hidden below 782px: at phone widths it
   competes with the logo for the only line that matters. */
.sb-utility {
	border-bottom: 1px solid var(--wp--preset--color--tint);
	padding-block: 0.4rem;
	color: var(--wp--preset--color--muted);
}

.sb-utility p {
	margin: 0;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.sb-utility__brand {
	color: var(--wp--preset--color--action);
	font-weight: 600;
}

@media (max-width: 781px) {
	.sb-utility {
		display: none;
	}
}

/* -------------------------------------------------------------------------
   14. Vertical rhythm — tightened after design review
   ---------------------------------------------------------------------- */

/* The masthead was carrying more air than it earned, which pushed the H1 of
   every page below a comfortable first view. */
.sb-header__bar {
	padding-block: clamp(0.55rem, 1vw, 0.9rem);
}

.sb-utility {
	padding-block: 0.25rem;
}

/* A heading that opens a band does not need its own top margin as well as the
   band's padding — the two stack and read as a gap rather than as rhythm. */
.wp-block-group > .wp-block-heading:first-child,
.wp-block-group > .sb-eyebrow:first-child,
.wp-block-column > .wp-block-heading:first-child,
.wp-block-column > .sb-eyebrow:first-child {
	margin-block-start: 0;
}

/* Close the gap between an H1 and the lead paragraph under it. */
.wp-block-group > h1.wp-block-heading {
	margin-block-end: var(--wp--preset--spacing--10);
}

/* And between a page header and the first paragraph of the band below it. */
.wp-block-group > .wp-block-heading + p {
	margin-block-start: var(--wp--preset--spacing--10);
}

/* -------------------------------------------------------------------------
   15. Gravity Forms
   ---------------------------------------------------------------------- */

/* Gravity ships its own stylesheet and it is specific, so overrides need the
   .gform_wrapper prefix to win. Values here are tokens only —
   the form should rebrand with the rest of the site, not hold old colours. */

.gform_wrapper .gfield_label {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.02em;
	color: var(--wp--preset--color--ink);
	margin-bottom: 0.45rem;
}

/* Gravity's default asterisk is a bare red character with no explanation. */
.gform_wrapper .gfield_required {
	color: var(--wp--preset--color--action);
	font-weight: 600;
	margin-inline-start: 0.15rem;
}

.gform_wrapper .gform_fields {
	row-gap: var(--wp--preset--spacing--20);
}

/* 5px 4px is Gravity's default and it reads as cramped next to this theme's
   spacing. Matching the button's vertical rhythm instead. */
.gform_wrapper input[type="text"],
.gform_wrapper input[type="email"],
.gform_wrapper input[type="tel"],
.gform_wrapper input[type="url"],
.gform_wrapper input[type="number"],
.gform_wrapper select,
.gform_wrapper textarea {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--medium);
	color: var(--wp--preset--color--ink);
	background-color: var(--wp--preset--color--base);
	border: var(--wp--custom--rule--hairline);
	border-radius: 10px;
	padding: 0.8rem 1rem;
	transition: border-color var(--wp--custom--transition--base),
		box-shadow var(--wp--custom--transition--base);
}

.gform_wrapper textarea {
	min-height: 9rem;
	line-height: 1.6;
}

/* A visible, branded focus state — Gravity's default is a faint browser ring. */
.gform_wrapper input:focus,
.gform_wrapper select:focus,
.gform_wrapper textarea:focus {
	border-color: var(--wp--preset--color--action);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--wp--preset--color--action) 22%, transparent);
	outline: none;
}

/* Keyboard users still get the standard outline treatment. */
.gform_wrapper input:focus-visible,
.gform_wrapper select:focus-visible,
.gform_wrapper textarea:focus-visible {
	outline: 3px solid var(--wp--preset--color--action);
	outline-offset: 2px;
}

.gform_wrapper ::placeholder {
	color: var(--wp--preset--color--muted);
	opacity: 1;
}

/* The submit button is a <button class="gform_button">, not an input, so the
   theme's wp-element-button styling never reaches it. Restate the same tokens
   rather than duplicating literal values. */
.gform_wrapper .gform_footer .gform_button,
.gform_wrapper .gform-footer .gform_button {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.03em;
	line-height: 1.2;
	color: var(--wp--preset--color--base);
	background-color: var(--wp--preset--color--action);
	border: 0;
	border-radius: 999px;
	padding: 0.9rem 1.9rem;
	cursor: pointer;
	transition: background-color var(--wp--custom--transition--base),
		transform var(--wp--custom--transition--base);
}

.gform_wrapper .gform_footer .gform_button:hover,
.gform_wrapper .gform-footer .gform_button:hover {
	background-color: var(--wp--preset--color--ink);
	transform: translateY(-1px);
}

/* Validation. Gravity's default is a red block that fights the palette. */
.gform_wrapper .gfield_error input,
.gform_wrapper .gfield_error select,
.gform_wrapper .gfield_error textarea {
	border-color: var(--wp--custom--status--error);
}

.gform_wrapper .gfield_validation_message,
.gform_wrapper .validation_message {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--custom--status--error);
	background: none;
	border: 0;
	padding: 0.35rem 0 0;
}

.gform_wrapper .gform_validation_errors {
	border-radius: 10px;
	border: 1px solid var(--wp--custom--status--error);
	background: var(--wp--preset--color--surface);
	box-shadow: none;
}

.gform_wrapper .gform_validation_errors > h2 {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--ink);
}

/* The confirmation shown when a form is set to display a message inline. */
.gform_confirmation_message {
	font-size: var(--wp--preset--font-size--large);
	color: var(--wp--preset--color--ink);
}
