/*
Theme Name: Billdu
Theme URI: https://billdu.com/
Author: Tomáš Pánik
Author URI: https://billdu.com/
Description: A block theme that mirrors the Billdu Design System.
Requires at least: 7.0
Tested up to: 7.1
Requires PHP: 8.4
Version: 0.0.1
License: UNLICENSED
Text Domain: billdu
Tags: one-column, full-site-editing, block-themes, block-patterns, style-variations, custom-colors, custom-menu, editor-style, featured-images, threaded-comments, translation-ready, wide-blocks, block-styles
*/

:root {
	color-scheme: light;
}

/* form controls (theme.json doesn't reach <input>) */
input,
select,
textarea {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--md);
}

/* primary fill buttons get a trailing arrow, outline and small buttons do not */
.wp-block-button:not(.is-style-outline):not(.is-style-small)
	> .wp-block-button__link::after {
	content: '\2192'; /* -> */
	margin-left: 0.5em;
}

/* primary hover, an inset ring in the orange text colour */
.wp-block-button:not(.is-style-outline):not(.is-style-small)
	> .wp-block-button__link:hover {
	box-shadow: inset 0 0 0 2px currentColor;
}

/* secondary (outline) buttons */
.wp-block-button.is-style-outline > .wp-block-button__link {
	border: 0;
	padding: 12px 28px;
	box-shadow: inset 0 0 0 2px currentColor;
}

/* small buttons */
.wp-block-button.is-style-small > .wp-block-button__link {
	border: 0;
	padding: 8px 18px;
	box-shadow: inset 0 0 0 2px currentColor;
	background-color: transparent;
	font-size: var(--wp--preset--font-size--sm);
}

/* default text color at zero specificity */
:where(.wp-block-button.is-style-small > .wp-block-button__link) {
	color: var(--wp--preset--color--primary);
}

:where(.wp-block-button.is-style-small > .wp-block-button__link:hover) {
	color: var(--wp--preset--color--foreground);
}

/* a core/group with a link set is wrapped in this anchor on the server */
a.billdu-group-link {
	display: contents;
	color: inherit;
}

/* the header template part renders as an extra <header class="wp-block-template-part">
   box that wraps the sticky bar and is only as tall as the header itself */
header.wp-block-template-part {
	display: contents;
}

/* sticky header: a transparent underline */
header.is-position-sticky,
header .is-position-sticky {
	border-bottom: 1px solid transparent;
	transition: border-bottom-color 0.2s ease;
}

header.is-position-sticky.is-stuck,
header .is-position-sticky.is-stuck {
	border-bottom-color: var(--wp--preset--color--separator, #e5e7f0);
}

/* anchor targets (TOC links, etc.) */
html {
	scroll-padding-top: calc(var(--billdu-header-offset, 0px) + 0.25rem);
}

/* WebKit/Safari miscomputes intrinsic widths in the header's nested flex
   layout (group > buttons next to the wrapping mega menu nav) and squeezes
   buttons until their labels wrap mid-text, while Chrome keeps them on one
   line */
.wp-block-template-part .wp-block-button__link,
.billdu-megamenu .wp-block-button__link {
	white-space: nowrap;
}

.wp-block-template-part .wp-block-buttons .wp-block-button,
.billdu-megamenu .wp-block-buttons .wp-block-button {
	flex-shrink: 0;
}

/* author box: a card appended to the end of single posts */
.billdu-author-box {
	display: flex;
	gap: var(--wp--preset--spacing--40, 24px);
	align-items: flex-start;
	margin-top: var(--wp--preset--spacing--60, 40px);
	padding: var(--wp--preset--spacing--40, 24px);
	background-color: var(--wp--preset--color--surface-soft, #f6f7fb);
	border: 1px solid var(--wp--preset--color--separator, #e5e7f0);
	border-radius: 16px;
}

.billdu-author-box__photo {
	flex-shrink: 0;
	line-height: 0;
}

.billdu-author-box__img {
	width: 88px;
	height: 88px;
	border-radius: 50%;
	object-fit: cover;
}

.billdu-author-box__body {
	min-width: 0;
}

.billdu-author-box__eyebrow {
	margin: 0;
	font-size: var(--wp--preset--font-size--xs, 0.75rem);
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--text-weak, #6b7280);
}

.billdu-author-box__name {
	margin: 2px 0 0;
	font-size: var(--wp--preset--font-size--lg, 1.25rem);
	line-height: 1.2;
}

.billdu-author-box__name a {
	color: inherit;
	text-decoration: none;
}

.billdu-author-box__name a:hover {
	text-decoration: underline;
}

.billdu-author-box__role {
	margin: 4px 0 0;
	font-size: var(--wp--preset--font-size--sm, 0.875rem);
	color: var(--wp--preset--color--primary, #1f3aff);
	font-weight: 600;
}

.billdu-author-box__bio {
	margin-top: var(--wp--preset--spacing--20, 12px);
	color: var(--wp--preset--color--text-weak, #4b5563);
}

.billdu-author-box__bio :where(p):first-child {
	margin-top: 0;
}

.billdu-author-box__bio :where(p):last-child {
	margin-bottom: 0;
}

.billdu-author-box__linkedin {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin-top: var(--wp--preset--spacing--20, 12px);
	font-size: var(--wp--preset--font-size--sm, 0.875rem);
	font-weight: 600;
	color: var(--wp--preset--color--primary, #1f3aff);
	text-decoration: none;
}

.billdu-author-box__linkedin:hover {
	text-decoration: underline;
}

.billdu-author-box__linkedin-icon {
	flex-shrink: 0;
}

@media (max-width: 600px) {
	.billdu-author-box {
		flex-direction: column;
	}
}

/* author header: a compact one-line byline (see core/author-header/) */
.billdu-author-header {
	display: flex;
	align-items: center;
	gap: 12px;
	flex-wrap: wrap;
	font-size: var(--wp--preset--font-size--sm, 0.875rem);
	color: var(--wp--preset--color--text-weak, #6b7280);
}

/* the "Align text" control centres/right-aligns the byline row */
.billdu-author-header.has-text-align-center {
	justify-content: center;
}

.billdu-author-header.has-text-align-right {
	justify-content: flex-end;
}

.billdu-author-header.has-text-align-left {
	justify-content: flex-start;
}

.billdu-author-header__img {
	width: 40px;
	height: 40px;
	border-radius: 50%;
	object-fit: cover;
	display: block;
}

.billdu-author-header__meta {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
}

.billdu-author-header__name {
	font-weight: 600;
	color: var(--wp--preset--color--foreground, #111827);
}

/* a "·" divider between every meta piece after the first */
.billdu-author-header__meta > * + *::before {
	content: '·';
	margin: 0 0.5em;
	color: var(--wp--preset--color--text-weak, #9ca3af);
}

.billdu-author-header__item {
	white-space: nowrap;
}

.billdu-author-header__item time {
	color: inherit;
}

/* library images on the front end ship with `billdu-lazy is-loading` and fade in
   once loaded; nothing is painted behind them while they load
   (see inc/lazy-load/ and assets/js/lazy-load.js) */
img.billdu-lazy {
	transition: opacity 0.4s ease;
}

/*
 * Transparent from the FIRST paint. This class is emitted by the server, not by
 * JavaScript -- if a script added it, the browser would paint the image, the
 * deferred script would hide it, and the load event would fade it back in, which
 * reads as a flash on every image.
 *
 * The animation is a failsafe for JavaScript being enabled but the reveal script
 * never arriving (blocked, 404, runtime error): it forces the image visible after
 * the delay, so a broken script can never permanently hide content. Nothing
 * animates on the normal path, because the script removes this class long before
 * the delay elapses. JavaScript being disabled is handled separately, by the
 * <noscript> stylesheet in inc/lazy-load/.
 */
img.billdu-lazy.is-loading {
	opacity: 0;
	animation: billdu-lazy-failsafe 0s linear 10s forwards;
}

/* The reveal script is running, so it owns the images -- including the ones
   below the fold that are legitimately still waiting to be fetched. Leaving the
   failsafe armed here would reveal those after 10s and they would then pop in
   without a fade when scrolled to. */
.billdu-lazy-js img.billdu-lazy.is-loading {
	animation: none;
}

@keyframes billdu-lazy-failsafe {
	to {
		opacity: 1;
	}
}

img.billdu-lazy.is-loaded {
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
	img.billdu-lazy {
		transition: none;
	}
}

/* query pagination (icon-only) */
.wp-block-query-pagination {
	gap: var(--wp--preset--spacing--20, 12px);
	align-items: center;
}

.wp-block-query-pagination-previous,
.wp-block-query-pagination-next {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	background-color: #fff;
	border: 1px solid var(--wp--preset--color--separator, #e5e7f0);
	box-shadow: 0 1px 3px rgba(16, 24, 40, 0.12);
	color: var(--wp--preset--color--primary, #1f3aff);
	text-decoration: none;
	font-size: 0; /* collapse the bare "Previous/Next Page" text node */
	transition:
		border-color 0.2s ease,
		box-shadow 0.2s ease;
}

.wp-block-query-pagination-previous:hover,
.wp-block-query-pagination-next:hover {
	border-color: var(--wp--preset--color--primary, #1f3aff);
	box-shadow: 0 2px 6px rgba(16, 24, 40, 0.18);
	text-decoration: none; /* override the global a:hover underline */
}

/* the arrow glyph */
.wp-block-query-pagination .wp-block-query-pagination-previous-arrow,
.wp-block-query-pagination .wp-block-query-pagination-next-arrow {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	margin: 0; /* override core's margin-right/left:1ch */
	font-size: var(--wp--preset--font-size--xl, 20px);
	line-height: 1;
	color: inherit;
}

/* categories overlay in related articles */
.wp-block-group.is-media-frame {
	position: relative;
}
.wp-block-post-terms.is-overlay-badge {
	position: absolute;
	left: 16px;
	bottom: 16px;
	z-index: 2;
}

/* footer-mascot pattern: mascot rises above the brand-blue panel */
.wp-block-image.billdu-footer-mascot {
	margin-top: clamp(-200px, -13vw, -80px);
	line-height: 0;
}
.wp-block-image.billdu-footer-mascot img {
	display: block;
	width: 100%;
	max-width: 600px;
	height: auto;
	margin-inline: auto;
}
@media (max-width: 781px) {
	/* columns stack, so keep the mascot inside the panel */
	.wp-block-image.billdu-footer-mascot {
		margin-top: 0;
		max-width: 320px;
		margin-inline: auto;
	}
}

/*
 * hero ornament: a decorative image that sits behind the hero content */
.billdu-hero-ornament-host {
	position: relative;
	/* own stacking context so the z-index:-1 ornament stays scoped behind the
	   content, never slipping behind an ancestor background */
	isolation: isolate;
}
.wp-block-image.billdu-hero-ornament {
	position: absolute;
	inset: 0;
	z-index: -1;
	display: flex;
	align-items: center;
	justify-content: center;
	margin: 0;
	overflow: hidden;
	pointer-events: none;
}
.wp-block-image.billdu-hero-ornament img {
	max-width: 100%;
	height: auto;
}

/*
 * arrow after a button label, added with CSS instead of inline SVG */
.wp-block-button.billdu-btn-arrow .wp-block-button__link::after {
	content: '';
	display: inline-block;
	width: 1.15em;
	height: 1.15em;
	margin-left: 0.5em;
	vertical-align: -0.2em;
	background-color: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23000'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M4%2012h16M13%205l7%207-7%207'/%3E%3C/svg%3E")
		no-repeat center / contain;
	mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23000'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M4%2012h16M13%205l7%207-7%207'/%3E%3C/svg%3E")
		no-repeat center / contain;
}

/* mobile scroller (core/group block style, see functions.php) */
@media (max-width: 767px) {
	/* .wp-block-group is carried for specificity */
	.wp-block-group.is-style-mobile-scroller {
		display: flex;
		flex-wrap: nowrap;
		/* the scroller owns the gap on mobile so the peek maths below is exact;
		   re-point --billdu-scroller-gap to change it */
		gap: var(--billdu-scroller-gap, var(--wp--preset--spacing--40, 16px));
		overflow-x: auto;
		/* a swipe that runs out of cards must not scroll the page sideways */
		overscroll-behavior-inline: contain;
		scroll-snap-type: x mandatory;
		/* the dots report the position, so the native bar is redundant */
		scrollbar-width: none;
		margin-inline-end: calc(
			-1 * var(--billdu-scroller-bleed, 0px)
		) !important;
	}
	.wp-block-group.is-style-mobile-scroller::-webkit-scrollbar {
		display: none;
	}

	/* one full card plus a quarter of the next, minus the one gap between them */
	.wp-block-group.is-style-mobile-scroller > * {
		flex: 0 0
			calc(
				(100% - var(--billdu-scroller-bleed, 0px) -
						var(
							--billdu-scroller-gap,
							var(--wp--preset--spacing--40, 16px)
						)) /
					var(--billdu-scroller-cards, 1.25)
			);
		/* flex items floor at their content width without this, so a long
		   unbroken word would widen the card past its share */
		min-width: 0;
		scroll-snap-align: start;
		/* core zeroes the margins of grid children only */
		margin: 0;
	}

	.is-style-mobile-scroller + .billdu-scroller-dots {
		display: flex;
	}
}

/* injected after the track by assets/js/mobile-scroller.js, so it only exists
   where the scroller is live */
.billdu-scroller-dots {
	display: none;
	justify-content: center;
	gap: 8px;
	margin-block-start: var(--wp--preset--spacing--50, 20px);
}

.billdu-scroller-dots__dot {
	appearance: none;
	width: 8px;
	height: 8px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: var(--wp--preset--color--primary-lighter, #ccd4fc);
	cursor: pointer;
	transition:
		background-color 0.15s ease,
		transform 0.15s ease;
}

.billdu-scroller-dots__dot.is-active {
	background: var(--wp--preset--color--primary, #0028f2);
	transform: scale(1.25);
}

/* media frame: acts as the lavender placeholder box + overlay-badge context */
.billdu-blog-hub .is-media-frame {
	position: relative;
	background: var(--wp--preset--color--primary-light);
	overflow: hidden;
}
.billdu-blog-hub .is-media-frame .wp-block-post-featured-image {
	margin: 0;
	height: 100%;
}
.billdu-blog-hub .is-media-frame .wp-block-post-featured-image a {
	display: block;
	height: 100%;
}
.billdu-blog-hub .is-media-frame img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.billdu-blog-hub .wp-block-post-terms.is-overlay-badge {
	position: absolute;
	left: 16px;
	bottom: 16px;
	z-index: 2;
	margin: 0;
	width: max-content;
}

/* section eyebrow (orange "POPULAR") */
.billdu-blog-hub .billdu-eyebrow {
	line-height: 1;
}

/* popular articles - big featured card (left column) */
.billdu-blog-hub .billdu-featured-main .wp-block-post-template {
	margin: 0;
	padding: 0;
	list-style: none;
}
.billdu-blog-hub .billdu-featured-main .is-media-frame {
	min-height: 420px;
	border-radius: 30px;
}
.billdu-blog-hub .billdu-featured-main .wp-block-post-title,
.billdu-blog-hub .billdu-featured-main .wp-block-post-title a {
	text-transform: uppercase;
	line-height: 1.15;
}

/* popular articles - right list of small horizontal cards */
.billdu-blog-hub .billdu-featured-list .wp-block-post-template {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--50);
	margin: 0;
	padding: 0;
	list-style: none;
}
.billdu-blog-hub .billdu-featured-item {
	align-items: stretch;
}
.billdu-blog-hub .billdu-featured-list .is-media-frame {
	border-radius: 20px;
	min-height: 150px;
	align-self: stretch;
}
.billdu-blog-hub .billdu-featured-list .wp-block-post-title,
.billdu-blog-hub .billdu-featured-list .wp-block-post-title a {
	line-height: 1.25;
}

/* main grid cards */
.billdu-blog-hub .billdu-grid .is-media-frame {
	aspect-ratio: 3 / 2;
	border-radius: 20px;
}

/* orange gradient CTA banner */
.billdu-blog-hub .billdu-cta-orange {
	position: relative;
	overflow: hidden;
	text-align: center;
}
.billdu-blog-hub .billdu-cta-orange > :not(.billdu-cta-thumb) {
	position: relative;
	z-index: 2;
}
.billdu-blog-hub .billdu-cta-thumb {
	position: absolute;
	margin: 0;
	pointer-events: none;
	z-index: 1;
	width: 118px;
}
.billdu-blog-hub .billdu-cta-thumb img {
	width: 100%;
	height: auto;
}
.billdu-blog-hub .billdu-cta-thumb--tl {
	top: 18px;
	left: 40px;
	transform: rotate(-6deg);
}
.billdu-blog-hub .billdu-cta-thumb--br {
	bottom: 20px;
	right: 52px;
}

/* filter tab bar */
.billdu-blog-hub .billdu-filter-bar {
	gap: var(--wp--preset--spacing--40);
}
.billdu-blog-hub .billdu-filter-tabs {
	background: var(--wp--preset--color--secondary-light);
	border-radius: 999px;
	padding: 6px;
}
.billdu-blog-hub .billdu-tab {
	display: inline-flex;
	align-items: center;
	padding: 11px 22px;
	border-radius: 999px;
	font-weight: 600;
	font-size: 16px;
	color: var(--wp--preset--color--secondary);
	text-decoration: none;
	line-height: 1;
	white-space: nowrap;
	transition:
		background 0.15s ease,
		color 0.15s ease;
}
.billdu-blog-hub .billdu-tab:hover {
	color: var(--wp--preset--color--primary);
}
.billdu-blog-hub .billdu-tab.is-active {
	background: var(--wp--preset--color--orange);
	color: #fff;
}
.billdu-blog-hub .billdu-search-btn {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 52px;
	height: 52px;
	border-radius: 50%;
	background: var(--wp--preset--color--secondary-light);
	color: var(--wp--preset--color--secondary);
	text-decoration: none;
	transition:
		color 0.15s ease,
		box-shadow 0.15s ease;
}
.billdu-blog-hub .billdu-search-btn svg {
	width: 22px;
	height: 22px;
}
.billdu-blog-hub .billdu-search-btn:hover {
	color: var(--wp--preset--color--primary);
	box-shadow: inset 0 0 0 2px var(--wp--preset--color--secondary-lighter);
}

/* load more (styled query-pagination-next) */
.billdu-blog-hub .billdu-loadmore {
	margin-top: var(--wp--preset--spacing--90);
	width: 100%;
}
.billdu-blog-hub .billdu-loadmore .wp-block-query-pagination-next {
	background: var(--wp--preset--color--orange);
	color: #fff;
	border: 0;
	border-radius: 999px;
	padding: 15px 36px;
	font-weight: 800;
	font-size: 16px;
	line-height: 1;
	box-shadow: none;
	text-decoration: none;
	transition: box-shadow 0.15s ease;
}
.billdu-blog-hub .billdu-loadmore .wp-block-query-pagination-next:hover {
	box-shadow: inset 0 0 0 999px rgba(0, 0, 0, 0.08);
}
.billdu-blog-hub .billdu-loadmore .wp-block-query-pagination-next span {
	font-size: 16px;
}

/* mobile */
@media (max-width: 781px) {
	.billdu-blog-hub .billdu-filter-bar {
		flex-wrap: wrap;
	}
	.billdu-blog-hub .billdu-cta-thumb {
		width: 70px;
	}
	.billdu-blog-hub .billdu-featured-main .is-media-frame {
		min-height: 240px;
	}
}

/* ---------------------------------------------------------------------------
   Link opt-outs.

   theme.json styles.elements.link underlines every link and turns it orange on
   hover. That is right for prose, but wrong for UI chrome, so everything listed
   here opts back out. WordPress emits the global rule as
   `a:where(:not(.wp-element-button))`, which has ZERO specificity, so a plain
   class selector below wins without !important. Buttons are already excluded by
   that :where(), so they are deliberately not listed.

   Colours are left alone on purpose: each component keeps whatever hover colour
   it already defines (the footer keeps its own blue).
   --------------------------------------------------------------------------- */

/* whole template parts: header (megamenu, navigation, logo, switchers), footer,
   and the blog-toc / blog-cta parts on single posts */
.wp-block-template-part a,
.wp-block-template-part a:hover,
.wp-block-navigation a,
.wp-block-navigation a:hover,
.wp-block-site-title a,
.wp-block-site-title a:hover,
/* query-loop card furniture: titles, terms, dates, thumbnails, pagination */
.wp-block-post-title a,
.wp-block-post-title a:hover,
.wp-block-post-terms a,
.wp-block-post-terms a:hover,
.wp-block-post-date a,
.wp-block-post-date a:hover,
.wp-block-post-featured-image a,
.wp-block-post-featured-image a:hover,
.wp-block-query-pagination a,
.wp-block-query-pagination a:hover,
a.page-numbers,
a.page-numbers:hover,
a.wp-block-read-more,
a.wp-block-read-more:hover,
a.wp-block-post-excerpt__more-link,
a.wp-block-post-excerpt__more-link:hover,
.billdu-blog-hub a,
.billdu-blog-hub a:hover,
/* anchors wrapping something that is not text — an underline reads as broken */
a.billdu-group-link,
a.billdu-group-link:hover,
.wp-block-image a,
.wp-block-image a:hover,
a.billdu-portraits__item,
a.billdu-portraits__item:hover,
a.billdu-search-btn,
a.billdu-search-btn:hover,
a.billdu-icon__link,
a.billdu-icon__link:hover,
a.billdu-news-tooltip__link,
a.billdu-news-tooltip__link:hover,
a.skip-link,
a.skip-link:hover,
/* component chrome */
a.billdu-megamenu__link,
a.billdu-megamenu__link:hover,
.billdu-megamenu__panel a,
.billdu-megamenu__panel a:hover,
a.billdu-tab,
a.billdu-tab:hover,
.billdu-loadmore a,
.billdu-loadmore a:hover,
a.billdu-pricing-plan__cta,
a.billdu-pricing-plan__cta:hover,
a.billdu-toc__link,
a.billdu-toc__link:hover,
.billdu-breadcrumbs a,
.billdu-breadcrumbs a:hover,
.billdu-region-switcher a,
.billdu-region-switcher a:hover,
.billdu-language-switcher a,
.billdu-language-switcher a:hover,
.billdu-author-header a,
.billdu-author-header a:hover,
a.billdu-author-box__linkedin,
a.billdu-author-box__linkedin:hover {
	text-decoration: none;
}

/*
 * The footer keeps the link colours it had before the prose-link change in
 * theme.json. Blocks inside it that set their own link colour are untouched.
 *
 * Scoped to <footer> only. Covering every .wp-block-template-part also hit the
 * header, where the megamenu relies on `color: inherit` at the same (0,1,0)
 * specificity -- and style.css loads last, so it won and changed the header.
 *
 * The `:where(a)` is deliberate: it makes these rules specificity (0,1,0), the
 * same as the theme.json rule they override, so they win only on source order
 * (style.css is the last stylesheet). A block that sets its own link colour is
 * (0,1,1) -- `.wp-elements-N a:where(...)` -- and still beats this.
 */
:where(footer).wp-block-template-part :where(a) {
	color: var(--wp--preset--color--foreground);
}

:where(footer).wp-block-template-part :where(a:hover) {
	color: var(--wp--preset--color--primary-hover);
}
