/*
Theme Name: Lanik Energy Solution
Theme URI: https://les.eu
Author: Jan Geci
Description: Block (FSE) theme for Lanik Energy Solution. Custom dynamic blocks, with post types and fields registered in code.
Version: 1.0.0
Requires at least: 6.7
Tested up to: 7.0
Requires PHP: 8.1
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: les
Tags: full-site-editing, block-patterns, editor-style, translation-ready, wide-blocks
*/

/*
 * In a block theme, ~95% of styling lives in theme.json.
 * Only put here what theme.json cannot express:
 * keyframes, complex pseudo-selectors, :has(), scroll-driven animations.
 *
 * Do not move colors, spacing or typography here - those belong in theme.json.
 */

/* ─────────────────────────────────────────────────────────────────────────
   Header and footer

   These two parts carry the only styling theme.json genuinely cannot
   express: sticky positioning, the flat link treatment inside the dark
   bands, and the scroll-driven reveal on the call button. Colors below are
   read back from theme.json presets, never redeclared.
   ───────────────────────────────────────────────────────────────────────── */

/* — the dark contact strip — */

.les-topbar {
	color: var(--wp--custom--text-on-ink);
	font-size: var(--wp--preset--font-size--small);
}

/*
 * The strip needs an exact height, because the sticky header above is pulled up
 * by that same token. It is set on the inner row rather than on .les-topbar
 * itself: WordPress centres a constrained container with `margin-inline: auto`,
 * and an auto margin cancels stretch, so making the outer element a grid or
 * flex box collapses the row to its content width and centres it.
 */
.les-topbar > .wp-block-group {
	min-height: var(--wp--custom--bar--height);
	align-items: center;
}

/*
 * Everything before the address hugs the left; the address takes the rest.
 * Scoped through .les-topbar to outrank the generated .wp-container-* rule
 * that zeroes margins on flex children.
 */
.les-topbar .les-topbar__address {
	margin-inline-start: auto;
}

.les-eyebrow {
	margin: 0;
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 600;
	letter-spacing: var(--wp--custom--eyebrow--tracking);
	text-transform: uppercase;
	color: var(--wp--custom--text-muted);
}

/*
 * The accent eyebrow is deep blue on the page and light blue on a dark band —
 * one modifier, two grounds, because it is the same element in the design.
 */
.les-eyebrow--accent {
	color: var(--wp--preset--color--accent-deep);
}

.les-topbar .les-eyebrow,
.has-ink-background-color .les-eyebrow--accent {
	color: var(--wp--preset--color--accent-light);
}

.les-topbar__text {
	margin: 0;
}

/*
 * Buttons used as plain links. A bound href has to live on an anchor, and
 * core/button is the only core block whose url attribute accepts a binding —
 * so the block is stripped back to look like the text link it stands in for.
 */
.les-barlink .wp-block-button__link {
	padding: 0;
	background: none;
	border: 0;
	color: inherit;
	font-family: inherit;
	font-size: inherit;
	font-weight: inherit;
	letter-spacing: inherit;
}

.les-barlink .wp-block-button__link:hover {
	background: none;
	color: var(--wp--preset--color--accent-light);
	text-decoration: underline;
}

.les-barlink--stack {
	color: var(--wp--custom--text-on-ink);
}

/* — the sticky white header — */

/*
 * Sticky is bounded by the containing block, and a template part's own wrapper
 * is only as tall as its content — so sticking the white band itself would pin
 * it for the ~100px the wrapper occupies and no further. The wrapper is what
 * sticks instead, since its containing block is .wp-site-blocks.
 *
 * Pulling it up by exactly the contact strip's height lets the strip scroll
 * away while the white band comes to rest against the top of the viewport,
 * which is what the design does. That is why the strip's height is a fixed
 * token rather than whatever its contents happen to add up to.
 */
.wp-site-blocks > header.wp-block-template-part {
	position: sticky;
	top: calc(-1 * var(--wp--custom--bar--height));
	z-index: 20;
}

.les-header {
	background: #fff;
	border-block-end: 1px solid var(--wp--custom--divider);
}

/* The lockup is two lines deep, so it needs more height than a wordmark. */
.les-header .wp-block-site-logo img {
	display: block;
	height: 2rem;
	width: auto;
}

/* The menu and everything after it sit at the far end of the bar. */
.les-header .les-nav {
	margin-inline-start: auto;
}

/*
 * The design sets 13px. Seven Slovak labels plus the logo, the language pair
 * and the call button leave little slack at 1240px, so the size eases down on
 * narrower desktops instead of the row wrapping.
 */
.les-nav .wp-block-navigation-item__content {
	font-family: var(--wp--preset--font-family--heading);
	font-size: clamp(0.75rem, 0.55rem + 0.35vw, 0.8125rem);
	font-weight: 600;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	padding-block-end: 3px;
	border-block-end: 2px solid transparent;
	text-decoration: none;
}

.les-nav .wp-block-navigation-item__content:hover {
	color: var(--wp--preset--color--accent-deep);
}

.les-nav .current-menu-item > .wp-block-navigation-item__content,
.les-nav .current_page_item > .wp-block-navigation-item__content {
	color: var(--wp--preset--color--accent-deep);
	border-block-end-color: var(--wp--preset--color--accent);
}

ul.les-langs {
	display: flex;
	gap: 0.4rem;
	margin: 0;
	padding: 0;
	list-style: none;
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.les-langs > li:not(:last-child)::after {
	content: "/";
	margin-inline-start: 0.4rem;
	color: color-mix(in srgb, var(--wp--preset--color--contrast) 35%, transparent);
}

.les-langs a {
	text-decoration: none;
	text-transform: uppercase;
	color: color-mix(in srgb, var(--wp--preset--color--contrast) 45%, transparent);
}

.les-langs .current-lang a {
	color: var(--wp--preset--color--accent-deep);
}

/*
 * The call button is hidden at the top of the page and slides open once the
 * page has scrolled — a scroll-driven animation rather than a scroll listener,
 * so nothing runs on the main thread.
 *
 * It stays open by default. Only inside @supports does it start closed, so a
 * browser without scroll timelines shows a usable button instead of a button
 * that never appears.
 */
.les-callbtn {
	overflow: hidden;
	white-space: nowrap;
}

@supports (animation-timeline: scroll()) {
	/*
	 * visibility is in here so the collapsed button leaves the tab order.
	 * max-width and opacity hide it from the eye but not from the keyboard
	 * or a screen reader, which would otherwise land on an invisible link.
	 */
	@keyframes les-reveal-call {
		from {
			max-width: 0;
			opacity: 0;
			visibility: hidden;
		}

		to {
			max-width: 14rem;
			opacity: 1;
			visibility: visible;
		}
	}

	.les-callbtn {
		animation: les-reveal-call linear both;
		/* Explicitly the document scroller: `scroll()` alone resolves to the
		   nearest scroll container, which here never scrolls. */
		animation-timeline: scroll(root block);
		animation-range: 0 3rem;
	}
}

@media (prefers-reduced-motion: reduce) {
	.les-callbtn {
		animation: none;
		max-width: none;
		opacity: 1;
	}
}

/* — the footer — */

.les-cta,
.les-footer {
	color: var(--wp--custom--text-on-ink);
}

.les-footer {
	border-block-start: 1px solid var(--wp--custom--divider-on-ink);
}

.les-on-ink {
	color: var(--wp--custom--text-on-ink);
}

/* An outlined button on the dark ground borrows its edge from the text. */
.les-btn-on-ink .wp-block-button__link {
	border-color: color-mix(in srgb, var(--wp--preset--color--paper) 40%, transparent);
	color: var(--wp--preset--color--paper);
}

.les-btn-on-ink .wp-block-button__link:hover {
	background: color-mix(in srgb, var(--wp--preset--color--paper) 12%, transparent);
	color: var(--wp--preset--color--paper);
}

.les-footer__brand {
	margin: 0 0 0.6rem;
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 600;
	font-size: 1.375rem;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--paper);
}

.les-footer__links {
	margin: 0;
	padding: 0;
	list-style: none;
}

.les-footer__links a {
	color: var(--wp--custom--text-on-ink);
	text-decoration: none;
}

.les-footer__links a:hover {
	color: var(--wp--preset--color--paper);
	text-decoration: underline;
}

.les-footer__legal {
	margin-block-start: 2rem;
	letter-spacing: 0.04em;
}


/* ─────────────────────────────────────────────────────────────────────────
   Blueprint frame

   The recurring motif of the design: a hairline box with a small cross
   registration mark straddling each corner. Used on images, cards, panels
   and the enquiry form.

   The four marks are drawn as background gradients on two pseudo-elements
   rather than as four extra elements, so any block can opt in with nothing
   but a class — no wrapper markup to keep in sync across ten blocks.
   ───────────────────────────────────────────────────────────────────────── */

/* core/* blocks opt in through the Styles panel; see les_register_block_styles. */
.is-style-blueprint,
.les-blueprint {
	position: relative;
	border: 1px solid var(--wp--custom--divider);
	border-radius: 0;
}

.is-style-blueprint::before,
.is-style-blueprint::after,
.les-blueprint::before,
.les-blueprint::after {
	content: "";
	position: absolute;
	left: -6px;
	right: -6px;
	height: 11px;
	pointer-events: none;
	color: var(--wp--custom--text-muted);

	/* Per corner: a 1px vertical bar and a 1px horizontal bar, crossing. */
	background-image:
		linear-gradient(currentColor, currentColor),
		linear-gradient(currentColor, currentColor),
		linear-gradient(currentColor, currentColor),
		linear-gradient(currentColor, currentColor);
	background-repeat: no-repeat;
	background-size: 1px 11px, 11px 1px, 1px 11px, 11px 1px;
	background-position:
		left 5px top 0,
		left 0 top 5px,
		right 5px top 0,
		right 0 top 5px;
}

.is-style-blueprint::before,
.les-blueprint::before {
	top: -6px;
}

.is-style-blueprint::after,
.les-blueprint::after {
	bottom: -6px;
}

/* On the dark ground the marks and the hairline borrow the light ink. */
.has-ink-background-color .les-blueprint,
.les-blueprint.has-ink-background-color {
	border-color: var(--wp--custom--divider-on-ink);
}

.has-ink-background-color .les-blueprint::before,
.has-ink-background-color .les-blueprint::after,
.les-blueprint.has-ink-background-color::before,
.les-blueprint.has-ink-background-color::after {
	color: var(--wp--custom--text-on-ink);
}

/* A framed image should fill its frame, not sit inside padding. */
.les-blueprint > img,
.les-blueprint > figure,
.les-blueprint > .wp-block-image {
	display: block;
	margin: 0;
}

/*
 * Hairline-separated cell grids — the other repeating motif. One background
 * shows through a 1px gap between opaque cells, so the rules never double up
 * at the joins the way per-cell borders do.
 */
.les-rules {
	display: grid;
	gap: 1px;
	background: var(--wp--custom--divider);
	border: 1px solid var(--wp--custom--divider);
}

.les-rules > * {
	background: var(--wp--preset--color--base);
}

.has-ink-background-color .les-rules {
	background: var(--wp--custom--divider-on-ink);
	border-color: var(--wp--custom--divider-on-ink);
}

.has-ink-background-color .les-rules > * {
	background: var(--wp--preset--color--ink);
}

/* — service page head — */

.les-service-head {
	border-block-end: 1px solid var(--wp--custom--divider);
}

.les-service-head__eyebrow p {
	margin: 0;
}

.les-service-head__lead {
	max-width: 50ch;
	font-size: 1.0625rem;
	line-height: 1.6;
	color: color-mix(in srgb, var(--wp--preset--color--contrast) 78%, transparent);
}

/* The excerpt block prints an empty paragraph when there is no excerpt. */
.les-service-head__lead:empty {
	display: none;
}

/* ─────────────────────────────────────────────────────────────────────────
   Mobile menu below 992px

   The navigation block's "mobile" overlay setting has its breakpoint hard-wired
   at 600px in core, and there is no attribute for it. Rather than switching the
   block to "always" — which would mean re-implementing the whole desktop bar —
   the two core rules that reveal the inline menu are put back to their mobile
   state for the 600–991px band. Everything below 600px and above 992px is left
   to core.

   Keep these selectors in step with wp-includes/blocks/navigation/style.min.css
   if a WordPress upgrade changes them.
   ───────────────────────────────────────────────────────────────────────── */

@media (min-width: 600px) and (max-width: 991.98px) {

	.les-nav .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
		position: fixed;
		inset: 0;
		display: none;
		width: auto;
		z-index: auto;
	}

	.les-nav .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
	}
}

@media (max-width: 991.98px) {

	/* The burger belongs at the end of the bar, after the language switcher. */
	.les-header .les-nav {
		order: 3;
		margin-inline-start: 0;
	}

	.les-header .les-header__end {
		order: 2;
		margin-inline-start: auto;
	}

	/*
	 * The number is already a tap target in the strip above, and at this width
	 * the button would crowd the burger. Scoped through two ancestors to outrank
	 * the generated .wp-block-buttons-is-layout-flex rule.
	 */
	.les-header .les-header__end .les-callbtn {
		display: none;
	}

	.les-nav .wp-block-navigation__responsive-container.is-menu-open {
		font-family: var(--wp--preset--font-family--heading);
	}

	.les-nav .is-menu-open .wp-block-navigation-item__content {
		font-size: var(--wp--preset--font-size--large);
		letter-spacing: 0.04em;
		border-block-end: 0;
	}
}

/*
 * The open overlay must clear the page, and it cannot do that on its own: the
 * header wrapper is `position: sticky`, which always creates a stacking
 * context, so the overlay's z-index only ever ranks it inside that context and
 * the page content below paints over it. Raising the wrapper itself while the
 * menu is open lifts the whole context instead.
 */
.wp-site-blocks > header.wp-block-template-part:has(.is-menu-open) {
	z-index: 100000;
}

/* The contact strip stacks rather than squeezing the address onto the row. */

/*
 * Client logos come from the old site as small JPEGs on a white ground, and
 * white cannot be keyed out of them — Bekaert is white lettering inside a blue
 * field, so a luminance key would eat the wordmark. The cell takes the white
 * instead, which reads as a deliberate logo plate rather than a seam.
 */
.les-logo-wall__cell:has(.les-logo-wall__logo) {
	background: #fff;
}

/* ─────────────────────────────────────────────────────────────────────────
   Button edges

   Every button is square — the radius is set to 0 on the button element in
   theme.json, so this needs no override. Only the border weight is corrected
   here.
   ───────────────────────────────────────────────────────────────────────── */

/*
 * Core's outline style draws a 2px edge; the design's is a hairline. Same
 * weight as the blueprint frame, so the two read as one family.
 */
.wp-block-button.is-style-outline > .wp-block-button__link,
.wp-block-button .wp-block-button__link.is-style-outline {
	border-width: 1px;
}

/*
 * A preset background class beats theme.json's hover, which is defined at the
 * same specificity and printed earlier — so a button given an explicit colour
 * simply stops reacting. The pale fill on the dark band brightens rather than
 * darkens: its text is ink, and darkening would take the contrast with it.
 */
.wp-block-button__link.has-accent-soft-background-color:hover,
.wp-block-button__link.has-accent-soft-background-color:focus-visible {
	background-color: var(--wp--preset--color--accent-light);
}

/*
 * Without this the outline button inherits theme.json's filled hover and goes
 * dark blue behind text that stays dark — which reads as no hover at all. The
 * design tints a secondary button with its own ink instead, so it works on
 * either ground; .les-btn-on-ink overrides it for the dark band.
 */
.wp-block-button.is-style-outline:not(.les-btn-on-ink) > .wp-block-button__link:hover,
.wp-block-button.is-style-outline:not(.les-btn-on-ink) > .wp-block-button__link:focus-visible {
	background: color-mix(in srgb, currentcolor 8%, transparent);
	border-color: currentcolor;
	color: inherit;
}

/* ─────────────────────────────────────────────────────────────────────────
   Phone layout

   The contact strip drops the address so it stays one row tall. That is what
   lets the header stick: the sticky wrapper is pulled up by exactly one strip
   height, and a strip that wrapped onto two rows would leave the remainder
   hanging above the header. The number and the e-mail stay — they are the two
   things someone on a phone actually taps.
   ───────────────────────────────────────────────────────────────────────── */

@media (max-width: 781px) {

	/* Scoped through the strip to outrank the generated flex-layout rule. */
	.les-topbar .les-topbar__address {
		display: none;
	}
}

/* ─────────────────────────────────────────────────────────────────────────
   Mobile menu: button, overlay, motion
   ───────────────────────────────────────────────────────────────────────── */

@media (max-width: 991.98px) {

	/*
	 * Core draws the open button as two bars. Three is what a burger is
	 * expected to look like, so the icon is replaced with one drawn here —
	 * cheaper than filtering core's markup and it animates.
	 */
	.les-nav .wp-block-navigation__responsive-container-open svg {
		display: none;
	}

	.les-nav .wp-block-navigation__responsive-container-open {
		width: 24px;
		height: 24px;
		background-image:
			linear-gradient(currentcolor, currentcolor),
			linear-gradient(currentcolor, currentcolor),
			linear-gradient(currentcolor, currentcolor);
		background-repeat: no-repeat;
		background-size: 22px 2px;
		background-position: left top 5px, left center, left bottom 5px;
	}

	@media (prefers-reduced-motion: no-preference) {

		.les-nav .wp-block-navigation__responsive-container-open {
			transition: background-size 0.18s ease, opacity 0.18s ease;
		}

		/* The middle bar shortens on approach — a small sign it is live. */
		.les-nav .wp-block-navigation__responsive-container-open:hover,
		.les-nav .wp-block-navigation__responsive-container-open:focus-visible {
			background-size: 22px 2px, 15px 2px, 22px 2px;
		}
	}

	/* The overlay's own padding, which core leaves at zero here. */
	.les-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
		padding-inline: var(--wp--preset--spacing--30);
	}

	.les-nav .wp-block-navigation__responsive-container-close {
		inset-block-start: 1.35rem;
		inset-inline-end: var(--wp--preset--spacing--30);
	}
}

/*
 * The overlay exists only below the breakpoint, so its motion belongs inside
 * the same query. Left outside it, the `opacity: 0` resting state applied to
 * the desktop bar too and hid the menu entirely.
 */
@media (max-width: 991.98px) {

	/*
	 * Core fades the overlay in with a 0.1s animation and closes it with none at
	 * all — it simply stops being displayed. Replacing the animation with a
	 * transition gives both directions the same easing; `allow-discrete` is what
	 * lets `display` take part, so the closing frame is not cut off. Browsers
	 * without it fall back to core's instant close.
	 */
	@media (prefers-reduced-motion: no-preference) {

		.les-nav .wp-block-navigation__responsive-container {
			opacity: 0;
			transition:
				opacity 0.22s ease,
				display 0.22s allow-discrete;
		}

		.les-nav .wp-block-navigation__responsive-container.is-menu-open {
			opacity: 1;
			animation: none;
		}

		@starting-style {

			.les-nav .wp-block-navigation__responsive-container.is-menu-open {
				opacity: 0;
			}
		}

		/* The items arrive just behind the overlay rather than with it. */
		.les-nav .is-menu-open .wp-block-navigation-item {
			animation: les-menu-item 0.26s ease both;
		}

		.les-nav .is-menu-open .wp-block-navigation-item:nth-child(1) { animation-delay: 0.04s; }
		.les-nav .is-menu-open .wp-block-navigation-item:nth-child(2) { animation-delay: 0.07s; }
		.les-nav .is-menu-open .wp-block-navigation-item:nth-child(3) { animation-delay: 0.1s; }
		.les-nav .is-menu-open .wp-block-navigation-item:nth-child(4) { animation-delay: 0.13s; }
		.les-nav .is-menu-open .wp-block-navigation-item:nth-child(5) { animation-delay: 0.16s; }
		.les-nav .is-menu-open .wp-block-navigation-item:nth-child(6) { animation-delay: 0.19s; }
		.les-nav .is-menu-open .wp-block-navigation-item:nth-child(7) { animation-delay: 0.22s; }

		@keyframes les-menu-item {

			from {
				opacity: 0;
				transform: translateY(0.4rem);
			}

			to {
				opacity: 1;
				transform: none;
			}
		}
	}
}
