/*
Theme Name: VetBook Theme
Description: Modern, responsive block theme for the platform. Presentation only – all logic lives in the vetbook plugin; switching themes must not break anything.
Version: 0.3.1
Requires at least: 6.7
Requires PHP: 8.3
License: Proprietary
Text Domain: vetbook-theme
*/
/*
 * The home-page rules used to live here as well as in the plugin's
 * assets/frontend/home.css. Both loaded, this file loaded last, and the two
 * copies had drifted onto different token systems - --wp--preset--* here,
 * --vb-* there - so the page rendered a mix of the two depending on which
 * copy happened to declare a given property, and editing home.css appeared
 * to do nothing at all.
 *
 * home.css is the maintained copy: audit P3 moved it into the plugin so the
 * [vb_home] markup renders styled on any theme, and it is enqueued wherever
 * that markup renders. The duplicates are gone from here. .vb-section and
 * .vb-section__title stay, because Guides.php uses them away from the home
 * page, where vb-home is not enqueued.
 */

/* ==========================================================================
   Theme chrome. Tokens come from theme.json (--wp--preset--*); this
   file only adds what theme.json cannot express (sticky header, hero,
   section bands, hover/motion). Plugin components carry their own --vb-*
   tokens so they stay theme-agnostic.
   ========================================================================== */

/* AniLevia (#408): AniLevia Sans for text, navigation, forms and headings -
   a subset of Source Sans 3 (Adobe), renamed because the SIL Open Font
   License reserves the name "Source" for unmodified versions;
   Cormorant Garamond 600 only for the word mark and the hero's one display
   line. Self-hosted subsets (Latin + Latin Extended), SIL Open Font
   License 1.1 - licences next to the files (no external CDN / GDPR). */
@font-face {
	font-family: "AniLevia Sans";
	font-style: normal;
	font-weight: 400 700;
	font-display: swap;
	src: url("assets/fonts/anilevia-sans-var.woff2") format("woff2");
}
@font-face {
	font-family: "Cormorant Garamond";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("assets/fonts/cormorant-garamond-600.woff2") format("woff2");
}

:where(body) {
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

/* No scroll-margin on [id] any more (25.09.2026). It reserved the header's
   height for every jump target, and html's scroll-padding-top in the plugin's
   site.css reserves it too - for jumps and for focus alike. A fragment scroll
   adds the two: measured 99-173px of empty page between the header and the
   target (the form on the businesses page, the profile's section bar). One
   reservation, measured from the header's real height, is the rule now. */

/* ----- Header -------------------------------------------------------------- */
.vb-site-header {
	position: sticky;
	top: 0;
	z-index: 100;
	background: var(--vb-header-glass, rgba(255, 255, 255, 0.85));
	backdrop-filter: saturate(180%) blur(10px);
	-webkit-backdrop-filter: saturate(180%) blur(10px);
	box-shadow: 0 8px 24px -20px rgba(48, 39, 43, 0.35);
	padding-block: 0.6rem;
	/* The status bar, the Dynamic Island and the rounded corner above them.
	   In a browser tab this env() is 0 and the rule changes nothing; in the
	   installed app the manifest asks for viewport-fit=cover, so without it
	   the header sits under the clock. Unconditional rather than behind
	   display-mode: standalone, because two copies of one number are two
	   numbers that drift - the bottom bar already carries that lesson in its
	   own comment. */
	padding-top: calc(0.6rem + env(safe-area-inset-top, 0px));
	/* Landscape on a notched phone: the notch moves to a side and the header
	   row would run under it. */
	padding-left: env(safe-area-inset-left, 0px);
	padding-right: env(safe-area-inset-right, 0px);
}

/* The page gutter, not the spacing preset: live the preset resolves to
   WordPress's own 0.67rem rather than this theme's 1.5rem, and the brand sat
   11px from the edge of every phone and tablet. The root padding is set in
   theme.json as a value, so header and content share one edge. */
.vb-site-header__inner {
	max-width: var(--wp--style--global--wide-size, 1200px);
	margin-inline: auto;
	padding-inline: var(--wp--style--root--padding-left, 1.5rem);
	width: 100%;
}

.vb-brand {
	gap: 0.6rem !important;
}

.vb-brand__mark {
	display: inline-flex;
	line-height: 0;
}

/* AniLevia (#408): the seal - band "A", dog and cat in the ring - in every
   header and footer, its light variant on the dark scheme (owner,
   11.10.2026: the logo in the app's header too, not the small "A"). The
   small "A" stays the favicon. */
.vb-brand__mark {
	color: var(--vb-accent-text, #68192e);
}

.vb-brand__letter {
	fill: var(--vb-base, #fbf7f2);
}

:root[data-theme="dark"] .vb-brand__mark {
	color: var(--vb-primary, #d9a9b7);
}

.vb-brand__mark svg {
	display: block;
}

/* Two classes deep, so no general rule shows a hidden one. */
.vb-brand__mark .vb-brand__a,
.vb-brand__mark .vb-brand__seal--dark {
	display: none;
}

.vb-brand__mark .vb-brand__seal {
	inline-size: 40px;
	block-size: 40px;
}

.vb-brand__mark .vb-brand__seal--light {
	display: block;
}

:root[data-theme="dark"] .vb-brand__mark .vb-brand__seal--light {
	display: none;
}

:root[data-theme="dark"] .vb-brand__mark .vb-brand__seal--dark {
	display: block;
}

@media (min-width: 37.5rem) {
	.vb-brand__mark .vb-brand__seal {
		inline-size: 44px;
		block-size: 44px;
	}
}

/* The word mark: the brand's name as text - read out, copied, translated
   never - set as the package draws it, Cormorant Garamond 600 in capitals,
   a little letter-spaced, in Bordeaux (#408). */
.vb-site-header .wp-block-site-title a,
.vb-site-footer__name {
	font-family: var(--vb-serif, "Cormorant Garamond", Georgia, serif);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--vb-accent-text, #68192e);
	text-decoration: none;
}

/* ----- Page head band ------------------------------------------------------ */
/* No tinted "page header" rectangle: the H1 sits free in the content flow
   with generous spacing (whitespace separates, not a box). */
.vb-page-head {
	margin-block-start: 0 !important;
	padding-block: clamp(1.8rem, 1.2rem + 2vw, 3rem) 0;
}

.vb-page-head__title {
	margin: 0;
}

.vb-page-head__meta {
	margin: 0.6rem 0 0;
	color: var(--wp--preset--color--muted);
}

.vb-main {
	padding-bottom: var(--wp--preset--spacing--60, 4rem);
}

/* Practice profile + page content get breathing room below the band. */
.vb-main > .wp-block-post-content {
	margin-block-start: var(--wp--preset--spacing--50, 3rem);
}

@keyframes vb-float {
	50% {
		transform: translateY(-14px) rotate(4deg);
	}
}


@keyframes vb-bob {
	50% {
		transform: translateY(-9px);
	}
}

/* Nur Deckkraft - dieselbe Einblendung wie in home.css. Diese Datei laedt
   danach, und die spaeter definierte @keyframes gewinnt: eine Bewegung hier
   haette die Korrektur dort still aufgehoben. */
@keyframes vb-rise {
	from {
		opacity: 0;
	}
}


/* Inline icon baseline */
.vb-ic {
	display: inline-block;
	vertical-align: -0.18em;
	flex: none;
}


/* ----- Buttons / chips ----------------------------------------------------- */
.wp-element-button,
.wp-block-button__link {
	transition: transform 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease;
}

.wp-block-button.is-style-fill .wp-block-button__link:hover {
	transform: translateY(-1px);
	box-shadow: 0 10px 20px -10px rgba(104, 25, 46, 0.7);
}

.is-style-outline .wp-block-button__link,
.vb-btn-ghost .wp-block-button__link {
	background: transparent;
	color: var(--vb-accent-text, #68192e);
	/* --vb-accent-text, not the preset: an outline button has no fill, so
	   the border IS the component, and a border that does not turn with the
	   theme measured 2.80:1 on the dark ground - below the 3:1 that WCAG
	   asks of a control's only visual boundary. The same token the label
	   already uses gives 5.4:1 light and 8.7:1 dark, and border and text
	   agreeing is what an outline button should look like anyway. */
	border: 1.5px solid var(--vb-accent-text, #68192e);
}

.is-style-outline .wp-block-button__link:hover {
	background: var(--wp--preset--color--primary);
	color: #fff;
}

/* ----- Sections ------------------------------------------------------------ */
.vb-section {
	padding-block: clamp(2rem, 1.4rem + 2vw, 3.25rem);
}

/* One consistent gap below every section heading (rhythm: padding → title →
   1.5rem → content → padding). Content blocks add no extra top margin. */
.vb-section__title {
	margin: 0 0 1.5rem;
}

/* ----- Footer -------------------------------------------------------------- */
.vb-site-footer {
	margin-block-start: 0 !important;
	padding-block: var(--wp--preset--spacing--50, 3rem);
}

/* Heller Grund, wie die verbindliche Vorschaugrafik den Fuss zeigt.
   Bis zum 18.09.2026 war er dunkelgruen und per !important gegen die
   Block-Presets gepinnt - der Grund dafuer war, dass "ink"/"base" im
   Dunkelmodus rotieren und den Fuss hellminz unter fast weisser Schrift
   werden liessen. Die Presets sind jetzt ganz aus dem Markup heraus, und
   der Fuss nimmt dieselben Flaechen-Token wie der Rest der Seite: hell im
   hellen Schema, dunkel im dunklen, ohne Sonderfall. */
.vb-site-footer {
	background-color: var(--vb-surface, #f2e7df);
	color: var(--vb-ink, #30272b);
	border-top: 1px solid var(--vb-line, #d9c7c1);
}

.vb-site-footer__grid {
	gap: 2rem;
	align-items: flex-start;
}

.vb-site-footer__brand {
	max-width: 38ch;
}

/* Die Fussfarben stehen in site.css und kommen von Token. Bis zum
   18.09.2026 lag hier eine zweite Kopie derselben Regeln mit fest
   eingetragenem Weiss - das Theme laedt nach dem Plugin, also gewann sie,
   und die Token-Fassung kam nie zum Zug. Als der Fuss hell wurde, standen
   die achtzehn Links mit 1,10:1 darauf. Zwei Kopien derselben Regel sind
   der Fehler, nicht ihre Werte. */

/* 404 */
.vb-404 {
	padding-block: clamp(3rem, 2rem + 5vw, 6rem);
}

/* ----- Motion preferences -------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		transition-duration: 0.001ms !important;
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
	}
}


/* The site title is a link, and next to the logo in the header it measured
   57x17 with the logo 13px away - under WCAG 2.5.8's minimum and inside its
   spacing exception's reach. The last two of the 105 undersized targets the
   audit found on 3.9.2026. Core's block, so the theme owns it. */
.wp-block-site-title a {
	display: inline-flex;
	align-items: center;
	min-height: var(--vb-tap-min, 24px);
}
