/*
 * patterns.css — hand-authored component shapes for the block patterns in patterns/.
 * Unlike theme.css (fully generated from design/tokens/tokens.json), this file holds
 * one-off organic border-radius/gradient shapes from design/moodboards/concept-c-warm-organisch.html
 * that aren't expressible as design tokens — everything color/spacing/font here still
 * references the CSS custom properties from theme.css, only the shapes themselves are hardcoded.
 */

/*
 * WordPress core already injects its own skip link for block themes
 * (`#wp-skip-link`, targets `#main` — see the `anchor: main` groups in
 * templates/*.html), styled with core's `.screen-reader-text`/`:focus` rules.
 * Re-themed here (primary color, pill radius) instead of adding a second,
 * redundant skip link — two in the tab order would be worse than one, even an
 * unstyled one.
 */
.skip-link.screen-reader-text:focus {
	background: var(--color-primary);
	color: var(--color-primary-on);
	border-radius: var(--radius-sm);
	z-index: 100;
}

.odv-hero-wrap {
	position: relative;
	overflow: hidden;
}
.odv-hero-wrap::before {
	content: "";
	position: absolute;
	top: -20%;
	right: -10%;
	width: 55%;
	aspect-ratio: 1;
	background: var(--color-surface-alt);
	border-radius: 42% 58% 60% 40% / 45% 40% 60% 55%;
	z-index: 0;
}
.odv-hero-content {
	position: relative;
	z-index: 1;
}
.odv-hero-blob {
	aspect-ratio: 0.85;
	border-radius: 45% 55% 60% 40% / 55% 45% 55% 45%;
	background: linear-gradient(160deg, var(--color-primary), var(--color-accent));
	box-shadow: var(--shadow-md);
	display: flex;
	align-items: center;
	justify-content: center;
	color: #fff;
	font-size: 0.85rem;
	text-align: center;
	padding: var(--space-md);
}

/* 2026-07-08: the concept's original `.trust` CSS (design/moodboards/concept-c-
   warm-organisch.html) assumed three roughly-equal-length one-line claims in a
   wrapping flex row. The real copy has one long compound claim (NOF + insurance)
   next to two much shorter ones, so that layout wrapped into an uneven, lopsided
   pair-plus-single arrangement — even at the full 72rem content width, the three
   items together don't fit on one line regardless of font-size, so a centered
   vertical stack (one claim per line) is used instead: robust to any future claim
   length, not just this one, since it makes no equal-width assumption. */
.odv-trust-list {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-sm);
	list-style: none;
	margin: 0;
	padding: 0;
	color: var(--color-text-muted);
	font-size: 0.92rem;
	text-align: center;
}
.odv-trust-list li::before {
	/* A hex escape ("\25E6 ") consumes a single trailing space as its own
	   terminator, so it never reaches the rendered content — used the literal
	   character instead, matching the concept file, to actually get the gap. */
	content: "◦ ";
	color: var(--color-accent);
	font-weight: 800;
}

.odv-card {
	background: var(--color-surface);
	border-radius: var(--radius-lg);
	padding: var(--space-lg);
	box-shadow: var(--shadow-sm);
	height: 100%;
}
.odv-card-icon {
	width: 44px;
	height: 44px;
	border-radius: 45% 55% 60% 40%;
	background: var(--color-primary);
	margin-bottom: var(--space-sm);
}

.odv-section-alt {
	background: var(--color-surface-alt);
	border-radius: var(--radius-lg);
	margin-inline: var(--space-md);
	padding: var(--space-lg);
}
.odv-about-photo {
	aspect-ratio: 4 / 5;
	border-radius: 50% 50% 45% 55% / 55% 45% 55% 45%;
	background: linear-gradient(160deg, var(--color-accent), var(--color-surface-alt));
	box-shadow: var(--shadow-md);
	display: flex;
	align-items: center;
	justify-content: center;
	color: #fff;
	font-size: 0.85rem;
	text-align: center;
	padding: var(--space-md);
}

.odv-cta-banner {
	background: var(--color-primary);
	color: #fff;
	text-align: center;
	padding: var(--space-xl) var(--space-lg);
	border-radius: var(--radius-lg);
	margin-inline: var(--space-md);
}
.odv-cta-banner h2 {
	color: #fff;
}
.odv-cta-banner p {
	opacity: 0.9;
}
.odv-cta-banner .wp-block-button:not(.is-style-outline) .wp-block-button__link {
	background: #fff;
	color: var(--color-primary);
}
.odv-cta-banner .wp-block-button.is-style-outline .wp-block-button__link {
	border-color: rgba(255, 255, 255, 0.6);
	color: #fff;
}

/*
 * Sticky header — not in the approved concept (no precedent to match), a new ask.
 * Judgment call: solid surface background so scrolled content doesn't show through
 * while stuck, and a shadow that only appears once scrolled (toggled by a small
 * script, assets/header-sticky.js) rather than being always-on.
 */
.odv-sticky-header {
	position: sticky;
	top: 0;
	z-index: 50;
	background: var(--color-surface);
	transition: box-shadow 0.2s ease;
}
.odv-sticky-header.is-scrolled {
	box-shadow: var(--shadow-sm);
}

/*
 * Mobile nav (overlay) background — scoped to the open overlay state only, not the
 * desktop inline row (WordPress's own responsive-container CSS uses
 * background-color:inherit even on desktop, so setting this on the wp:navigation
 * block itself would incorrectly tint the desktop nav bar too — scoping to
 * .is-menu-open avoids that).
 */
.wp-block-navigation__responsive-container.is-menu-open {
	background-color: var(--color-accent) !important;
	color: var(--color-accent-on) !important;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content,
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close {
	color: var(--color-accent-on);
}

/*
 * Header brand — logo + wordmark act as a single "home" link, matching the concept's
 * .brand (no separate "Home" nav item — the logo/wordmark is the home link).
 */
.odv-brand {
	align-items: center;
	gap: var(--space-xs);
}
/* 2026-07-08: swapped the icon-only logo + separately-styled site-title text for
   the owner-supplied icon+wordmark lockup (one image, no separate title element —
   its alt text still carries the site name for accessibility). Height tuned down
   from the old 46px (icon-only) since this graphic is much wider (~3.5:1). */
.odv-brand .wp-block-site-logo img {
	height: 40px;
	width: auto;
}

/*
 * Header nav — 0.92rem matches the concept's nav.links CSS exactly (not one of our
 * defined font-size tokens, a one-off value from the concept). Combined with the
 * blockGap reduction on the block itself (header.html), this fixes a real overflow:
 * at the 72rem content width, logo + full 6-item nav (at the previous 16px/24px-gap
 * defaults) + the CTA button needed ~1253px total, ~100px more than the 1152px
 * available — not a viewport-width issue, since content width is capped regardless
 * of how wide the browser gets.
 */
.odv-header-nav {
	font-size: 0.92rem;
}

/*
 * Header nav breakpoint override. WordPress's overlayMenu:"mobile" hardcodes the
 * hamburger→inline switch at 600px (its two @media (min-width:600px) rules: one
 * reveals the inline container, one hides the open button). But our 6-item nav
 * (incl. the long "Veelgestelde vragen") + logo + CTA only fits inline above the
 * 72rem (1152px) content width; between ~600–1200px the inline row overflowed —
 * items clipped at the edge and the CTA wrapped down over the hero. We raise the
 * switch to 1200px by re-applying core's collapsed/overlay behavior below it.
 * !important is needed to beat core's own min-width:600px rules in the 600–1200
 * range (same pattern core itself uses for .is-menu-open). Below 1200px the
 * header shows logo + hamburger + CTA; the full overlay opens on tap.
 */
@media (max-width: 1200px) {
	.odv-header-nav .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex !important;
	}
	.odv-header-nav .wp-block-navigation__responsive-container:not(.is-menu-open) {
		display: none !important;
	}
}

/*
 * Buttons — pill shape/padding/weight/colors are now set at the root in theme.json
 * (styles.elements.button + styles.blocks.core/button.variations.outline), so every
 * button block gets them by default without per-instance attributes or a stylesheet
 * rule that could lose a specificity/cascade fight with core's own block styles.
 * Only box-shadow (not exposed cleanly via theme.json) and hover states stay here.
 */
.wp-block-button:not(.is-style-outline) .wp-block-button__link {
	box-shadow: var(--shadow-sm);
}
/* Hover states: the concept is a static mockup with no :hover spec — this is a judgment
   call, not an approved spec. Stays within the existing token palette. */
.wp-block-button:not(.is-style-outline) .wp-block-button__link:hover {
	filter: brightness(1.08);
}
.wp-block-button.is-style-outline .wp-block-button__link:hover {
	background: var(--color-surface-alt);
}

@media (max-width: 782px) {
	.odv-hero-wrap::before {
		display: none;
	}
}

/*
 * Detail hero (Behandeling-template) — a lighter variant of the homepage hero:
 * less vertical padding, no buttons (deliberate — see behandeling-template-plan.md,
 * "no booking CTA competing at the very top; keep focus on the topic").
 */
.odv-detail-hero {
	padding-top: var(--space-lg) !important;
	padding-bottom: var(--space-lg) !important;
}

/*
 * Behandeling-template "Lees ook" cross-links — reuses the content-page's dot
 * marker so it reads as part of the same design language, in a plain list
 * rather than full paragraph text.
 */
.odv-cross-links {
	margin: var(--space-lg) 0;
}
.odv-cross-links h3 {
	font-family: var(--font-heading);
	margin: 0 0 var(--space-sm);
}
.odv-cross-links ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-sm) var(--space-lg);
}
.odv-cross-links li {
	position: relative;
	padding-left: 1rem;
}
.odv-cross-links li::before {
	content: "\2192";
	position: absolute;
	left: 0;
	color: var(--color-accent);
}
.odv-cross-links a {
	color: var(--color-text);
	text-decoration: underline;
}

/*
 * Real footer — replaces the one-line placeholder. Matches the concept's
 * footer.site/.footer-grid/.footer-col/.footer-links/.footer-bottom/.footer-legal.
 */
.odv-footer {
	background: var(--color-surface-alt);
	padding-top: var(--space-xl);
	padding-bottom: var(--space-lg);
	margin-top: var(--space-2xl);
	border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.odv-footer-grid {
	display: grid;
	grid-template-columns: 1.3fr 1fr 1fr 1fr;
	gap: var(--space-lg);
	padding-bottom: var(--space-lg);
}
.odv-footer-logo img {
	height: 40px;
	width: auto;
	margin-bottom: var(--space-sm);
}
/* Note: the concept's own footer CSS uses text-muted throughout, but this footer's
   background is surface-alt, and text-muted-on-surface-alt is 4.48:1 — fails WCAG AA
   (needs 4.5:1) for normal-size text. Same bug class as the About-teaser fix from the
   previous round. Using the full "text" color here instead, not a new/invented color. */
.odv-footer-brand p {
	color: var(--color-text);
	font-size: 0.88rem;
	margin: 0.3rem 0;
}
/* Trust badge — text-only (no official NOF logo asset supplied), styled as a
   small bordered pill so it reads as a credential, not just another line of text.
   Selector is two classes deep (beats ".odv-footer-brand p"'s class+element
   specificity) so it doesn't need !important to win the margin/color reset. */
.odv-footer-brand .odv-badge {
	display: inline-block;
	margin: var(--space-xs) 0 0;
	padding: 0.25rem 0.75rem;
	font-size: 0.78rem;
	font-weight: 700;
	border: 1px solid var(--color-border);
	border-radius: var(--radius-full);
	color: var(--color-text);
}
.odv-footer-col h3 {
	font-weight: 700;
	font-size: 0.8rem;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--color-text);
	margin: 0 0 var(--space-sm);
}
.odv-footer-links {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}
.odv-footer-links a {
	color: var(--color-text);
	text-decoration: none;
	font-size: 0.9rem;
}
.odv-footer-links a:hover {
	text-decoration: underline;
}
.odv-footer-muted {
	color: var(--color-text);
	font-size: 0.85rem;
	font-style: italic;
	margin: 0;
}
.odv-footer-bottom {
	display: flex;
	justify-content: space-between;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--space-sm);
	border-top: 1px solid var(--color-border);
	padding-top: var(--space-md);
	font-size: 0.85rem;
	color: var(--color-text);
}
.odv-footer-legal {
	list-style: none;
	display: flex;
	gap: var(--space-md);
	margin: 0;
	padding: 0;
}
.odv-footer-legal a {
	color: var(--color-text);
	text-decoration: none;
}
.odv-footer-legal a:hover {
	text-decoration: underline;
}
@media (max-width: 64rem) {
	.odv-footer-grid {
		grid-template-columns: 1fr 1fr;
	}
}
@media (max-width: 40rem) {
	.odv-footer-grid {
		grid-template-columns: 1fr;
	}
}

/*
 * Pricing cards (Tarieven) — replaces a raw HTML table with the site's own card
 * visual language.
 */
.odv-pricing-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--space-md);
	max-width: 42rem;
	margin: 0 auto;
}
.odv-price-card {
	background: var(--color-surface);
	border: 1px solid var(--color-border);
	border-radius: var(--radius-lg);
	padding: var(--space-lg);
	text-align: center;
	box-shadow: var(--shadow-sm);
}
.odv-price-card--alt {
	background: var(--color-surface-alt);
}
/* h3/price-desc use "text" not "text-muted": the --alt card's background is
   surface-alt, where text-muted fails AA (4.48:1) — using "text" on both card
   variants keeps them visually consistent rather than only fixing one. */
.odv-price-card h3 {
	font-family: var(--font-body);
	font-weight: 700;
	font-size: 0.95rem;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--color-text);
	margin: 0 0 var(--space-sm);
}
.odv-price-card .odv-price {
	font-family: var(--font-heading);
	font-size: 2.25rem;
	color: var(--color-primary);
	margin: 0;
}
.odv-price-card .odv-price span {
	font-size: 1.1rem;
}
.odv-price-card .odv-price-desc {
	color: var(--color-text);
	font-size: 0.88rem;
	margin-top: var(--space-sm);
}
@media (max-width: 40rem) {
	.odv-pricing-grid {
		grid-template-columns: 1fr;
	}
}

/*
 * Content-page pattern — for text-heavy pages (Wat is osteopathie?, the Tarieven
 * body below the pricing cards, Privacyverklaring, FAQ): a readable ~42rem column
 * instead of the full 72rem site width, a small eyebrow label above the H1, and an
 * accent-colored dot marker instead of default browser bullets.
 */
.odv-content-page {
	max-width: 42rem;
	margin: 0 auto;
}
/* Breadcrumbs — Rank Math's own markup (nav > p > a/span), minimally themed:
   small and muted so it reads as wayfinding, not competing with the H1 below it. */
.odv-breadcrumbs {
	margin-bottom: var(--space-sm);
}
.odv-breadcrumbs .rank-math-breadcrumb p {
	font-size: 0.85rem;
	color: var(--color-text-muted);
	margin: 0;
}
.odv-breadcrumbs .rank-math-breadcrumb a {
	color: var(--color-text-muted);
	text-decoration: underline;
}
.odv-breadcrumbs .rank-math-breadcrumb .last {
	color: var(--color-text);
}

/* Standalone (not scoped to .odv-content-page) so the Behandeling-template
   detail hero can reuse the same eyebrow label above its H1. */
.odv-eyebrow {
	text-transform: uppercase;
	letter-spacing: 0.08em;
	font-size: 0.78rem;
	color: var(--color-primary);
	font-weight: 700;
	display: block;
	margin-bottom: var(--space-xs);
}
.odv-content-page h1 {
	font-size: 2.1rem;
	margin: var(--space-xs) 0 var(--space-lg);
}
.odv-content-page h2 {
	font-size: 1.4rem;
	margin: var(--space-xl) 0 var(--space-sm);
}
.odv-content-page p {
	margin: 0 0 var(--space-md);
	color: var(--color-text);
}
.odv-content-page ul {
	list-style: none;
	padding-left: 0;
	margin: 0 0 var(--space-md);
}
.odv-content-page ul li {
	position: relative;
	padding-left: 1.4rem;
	margin-bottom: 0.5rem;
	color: var(--color-text);
}
.odv-content-page ul li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.55em;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--color-accent);
}

/*
 * WPForms (Contact page) — the "modern" markup theme WPForms ships with is
 * themed entirely through its own CSS custom properties (set inline by the
 * plugin on :root); its actual selectors are more specific than a plain
 * ".wpforms-form button" override, so fighting them field-by-field doesn't
 * work. `html:root` outranks the plugin's own `:root` block regardless of
 * stylesheet order, and lets WPForms' hover/focus/checkbox states (already
 * built on these same variables) keep working instead of re-implementing
 * them by hand.
 */
html:root {
	--wpforms-field-border-radius: var(--radius-sm);
	--wpforms-field-border-color: var(--color-border);
	--wpforms-field-background-color: var(--color-surface);
	--wpforms-field-text-color: var(--color-text);
	--wpforms-label-color: var(--color-text);
	--wpforms-label-sublabel-color: var(--color-text-muted);
	--wpforms-label-error-color: #b3261e;
	--wpforms-button-border-radius: var(--radius-full);
	--wpforms-button-background-color: var(--color-primary);
	--wpforms-button-border-color: var(--color-primary);
	--wpforms-button-text-color: var(--color-primary-on);
	--wpforms-field-size-font-size: 1rem;
	--wpforms-label-size-font-size: 0.95rem;
	--wpforms-button-size-font-size: 1rem;
}
.wpforms-form .wpforms-field {
	margin-bottom: var(--space-md);
}
.wpforms-form textarea {
	min-height: 8rem;
	resize: vertical;
}
.wpforms-form .wpforms-field-checkbox fieldset {
	border: 0;
	padding: 0;
	margin: 0;
}
.wpforms-form .wpforms-submit-container {
	margin-top: var(--space-sm);
}

/*
 * Complianz cookie banner — same CSS-custom-property theming approach as
 * WPForms above; only the accept button and links stood out against the
 * site's palette (deny/settings stay neutral grey, which already reads fine).
 */
html:root {
	--cmplz_button_accept_background_color: var(--color-primary);
	--cmplz_button_accept_border_color: var(--color-primary);
	--cmplz_button_accept_text_color: var(--color-primary-on);
	--cmplz_button_border_radius: var(--radius-full);
	--cmplz_hyperlink_color: var(--color-primary);
}
/*
 * Complianz adds a "cmplz-hidden" class to the <a> for document types set to
 * "none" (e.g. impressum, intentionally unused on this Dutch site — see
 * docs/internal/tech-decisions.md) but never hides the surrounding <li>,
 * leaving an empty bullet in the banner's document-links list.
 */
.cmplz-documents li:has(.cmplz-hidden) {
	display: none;
}

/*
 * Testimonials ([odv_testimonials] shortcode) — card styling consistent with
 * .odv-card, an accent-colored opening quote mark instead of a Google-style
 * star rating (manual quotes must not be dressed up as verified Google
 * reviews — see docs/internal/reviews-widget-spec.md).
 */
.odv-testimonials-wrap {
	margin: var(--space-xl) 0;
}
.odv-testimonials {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--space-md);
	margin-top: var(--space-lg);
}
.odv-testimonial {
	background: var(--color-surface);
	border-radius: var(--radius-lg);
	padding: var(--space-lg);
	box-shadow: var(--shadow-sm);
	margin: 0;
}
.odv-testimonial::before {
	content: "\201C";
	display: block;
	font-family: var(--font-heading);
	font-size: 2.75rem;
	line-height: 1;
	color: var(--color-accent);
	margin-bottom: var(--space-xs);
}
.odv-testimonial p {
	margin: 0 0 var(--space-sm);
	color: var(--color-text);
	font-style: italic;
}
.odv-testimonial cite {
	display: block;
	font-style: normal;
	font-weight: 700;
	font-size: 0.85rem;
	color: var(--color-text-muted);
}
@media (max-width: 64rem) {
	.odv-testimonials {
		grid-template-columns: 1fr 1fr;
	}
}
@media (max-width: 40rem) {
	.odv-testimonials {
		grid-template-columns: 1fr;
	}
}

/*
 * Callout / info box — bordered surface-alt card for a single flagged notice
 * inside a .odv-content-page reading column (e.g. the Algemene voorwaarden
 * placeholder notice, the Behandeling-template "let op" block). Deliberately
 * plain (no icon system exists yet) — a left accent border is enough to read
 * as "distinct from body copy" without inventing new visual language.
 */
.odv-callout {
	background: var(--color-surface-alt);
	border-left: 3px solid var(--color-primary);
	border-radius: var(--radius-sm);
	padding: var(--space-md);
	margin: 0 0 var(--space-lg);
}
.odv-callout p {
	margin: 0;
	color: var(--color-text);
}

/*
 * Contact page two-column layout — Praktijkgegevens/CTA on the left, the
 * form on the right (matches the client's own request for this page).
 */
.odv-contact-columns {
	gap: var(--space-lg);
}
@media (max-width: 40rem) {
	.odv-contact-columns {
		gap: var(--space-md);
	}
}
