/*
 * Header, footer, cards, pills, the sticky CTA.
 *
 * Loads last, so it may build on both tokens.css and base.css. Like base.css it
 * declares no colour of its own - every value here is a token.
 *
 * MOBILE FIRST, and in this file that is not a formality. The navigation's
 * DEFAULT state is the phone's: a panel below the header that the burger opens.
 * The desktop row is restored at 1100 px. The mockups are authored the other way
 * round, with `max-width: 920px` blocks, and reading them backwards is the
 * translation this file performs (config/review-rules.md rule 7).
 */

/*
 * The room the sticky bar takes at the bottom of a phone screen, written down
 * once because two rules need the same number and must never drift apart: the
 * spacer that keeps the page scrollable past the bar, and the cap on how tall
 * the burger menu is allowed to grow.
 *
 * TWO NUMBERS, NOT ONE, since WPS-066 - and the second one is why the cookie
 * notice floated 11 px above the bar instead of resting on it (Andrius on dev).
 *
 * --sticky-cta-height is the bar itself: a 1 px border, 10 px of padding, a
 * 50 px row and a bottom padding that grows into the iPhone's home indicator.
 * 71 px on a phone with no inset, measured.
 *
 * --sticky-cta-room is that height PLUS 11 px of breathing space, so the last
 * element on the page does not end flush against the bar. 82 px, the number the
 * mockups draw for the spacer.
 *
 * They used to be one value, and everything that needed either of them asked
 * for the room. The spacer wants the room; anything STACKED ON the bar wants
 * the height, and asking for the room leaves it hovering by exactly the
 * difference. One name cannot mean both.
 *
 * Not design tokens: this is the component's own arithmetic rather than a value
 * the design system carries, and tokens.css takes only what was transferred.
 */
:root {
	--sticky-cta-height: calc( 61px + max( 10px, env( safe-area-inset-bottom ) ) );
	--sticky-cta-room: calc( var( --sticky-cta-height ) + 11px );
}

/* ---------------------------------------------------------------------------
 * Logo set
 *
 * Three parts that behave as one: the mark, the two-coloured wordmark, and the
 * handwritten line under it. Sizes are measured off the mockup rather than
 * chosen - the header renders the mark at 46 px and the footer at 38 px, and
 * everything else scales with them.
 *
 * The wordmark's second word is --color-brand-red. That colour is a LOGOTYPE
 * here: WCAG 1.4.3 exempts a brand name from the contrast floor, which is why it
 * may sit at 4.27:1 against the header fill while no other text in this theme
 * would be allowed to.
 */

.site-logo {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	gap: 9px;
	text-decoration: none;
}

.site-logo__mark {
	width: 46px;
	height: 46px;
}

.site-logo__text {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
}

.site-logo__name {
	font-size: 18.5px;
	font-weight: var( --fw-black );
	line-height: 1.05;
	letter-spacing: -0.01em;
	white-space: nowrap;
}

.site-logo__name-a {
	color: var( --text-link );
}

.site-logo__name-b {
	color: var( --color-brand-red );
}

.site-logo__sub {
	margin-top: 1px;
	color: var( --text-body );
	font-family: var( --font-accent );
	font-size: 15px;
	font-weight: 600;
	line-height: 1.15;
	white-space: nowrap;
}

/*
 * The footer logo is 38 px tall, so its link needs the same treatment as the
 * social marks: the target reaches 44 px through a ::before, the mark stays the
 * size the design drew it (invariant I8.2).
 */
.site-logo--small {
	position: relative;
}

.site-logo--small::before {
	content: '';
	position: absolute;
	top: -3px;
	right: -3px;
	bottom: -3px;
	left: -3px;
}

.site-logo--small .site-logo__mark {
	width: 38px;
	height: 38px;
}

.site-logo--small .site-logo__name {
	font-size: 16.5px;
}

.site-logo--small .site-logo__sub {
	color: var( --text-meta );
	font-size: 13.5px;
}

/* ---------------------------------------------------------------------------
 * The promotion bar and block (WPS-083)
 *
 * WHY THIS IS HERE AND NOT IN A PAGE STYLESHEET. The bar is drawn above the
 * header on every page and the block on the voucher page, and the theme
 * enqueues exactly ONE page stylesheet per request - a component that appears
 * on more than one page has no page to live in.
 *
 * EVERY COLOUR COMES THROUGH A --promo-* ROLE, never a hex. Season palettes
 * are the one deliberate exception to invariant I9, so a season that wants a
 * different costume overrides the roles on .promo--<key> and nothing else has
 * to change. tokens.css holds the values because the raw-hex gate's exemption
 * is keyed to that file's name.
 *
 * NO .promo--launch BLOCK BELOW, AND THAT IS THE POINT. Launch wears the brand
 * palette, so the token defaults already ARE its costume; a rule restating
 * them would be a rule that paints nothing. The four calendar seasons each
 * override the roles once, at the end of this section, from the --season-*
 * tokens - no hex here, so the G4 gate stays meaningful.
 *
 * THE BAR IS NOT STICKY AND CARRIES NO z-index. It sits in normal flow above
 * a sticky header, which means it scrolls away and the header - at 50 - paints
 * over it on the way past. Lifting the bar above the header would put a
 * marketing strip over the navigation for the length of that scroll.
 */

.promo-bar {
	background: var( --promo-bar-bg );
	color: var( --promo-bar-ink );
}

.promo-bar__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 4px 12px;
	min-height: 61px;
	padding-block: 9px;
	text-align: center;
}

.promo-bar__icon {
	flex-shrink: 0;
	color: var( --promo-bar-accent );
	font-size: 18px;
}

.promo-bar__text {
	font-size: 13.5px;
	font-weight: 600;
}

/*
 * AS-172. The bar exists for exactly one tap, and that tap was 110.8 x 17px -
 * the same shape as AS-146 and the same fix: a ::before grows the touch target
 * to 44px without touching the size the design drew. The bar's min-height
 * above is the other half of it; a 44px target inside a 40px bar has its last
 * pixels eaten by the sticky header the moment the page moves.
 */
.promo-bar__cta {
	position: relative;
	color: var( --promo-bar-accent );
	font-size: 13.5px;
	font-weight: var( --fw-bold );
	text-decoration: none;
	white-space: nowrap;
}

.promo-bar__cta::before {
	content: '';
	position: absolute;
	top: -14px;
	right: -12px;
	bottom: -14px;
	left: -12px;
}

.promo-bar__cta:hover,
.promo-bar__cta:focus-visible {
	text-decoration: underline;
}

.promo-block-wrap {
	padding-top: clamp( 14px, 2vw, 20px );
}

.promo-block {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: var( --space-3 );
	padding: clamp( 18px, 2.6vw, 26px );
	overflow: hidden;
	background: var( --promo-surface );
	border-radius: clamp( 16px, 2vw, 22px );
	color: var( --promo-surface-ink );
}

/*
 * The oversized glyph in the corner is decoration, not content: aria-hidden in
 * the markup, pointer-events off here so it cannot steal the tap that lands
 * near it. Shared by the voucher-page block and the front page's #akcija
 * section, which draw the same glyph at two sizes - hence the custom property
 * rather than two copies of five declarations.
 */
.promo-decor {
	position: absolute;
	color: var( --promo-surface-accent );
	font-size: var( --promo-decor-size, 150px );
	line-height: 1;
	opacity: var( --promo-decor-opacity, 0.12 );
	pointer-events: none;
}

.promo-block__decor {
	top: -26px;
	right: -18px;
}

.promo-block__row {
	position: relative;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 14px 22px;
}

/*
 * The season badge, identical in both promotion places. It lives here rather
 * than in a page stylesheet for the usual reason - the theme loads exactly one
 * of those - and it is one class rather than two because the alternative was
 * copying the declarations, which WPS-084 rules out by name.
 */
.promo-badge {
	display: inline-flex;
	flex-shrink: 0;
	align-items: center;
	gap: 7px;
	padding: 7px 14px;
	background: var( --promo-badge-bg );
	border-radius: var( --radius-pill );
	color: var( --promo-badge-ink );
	font-size: 11.5px;
	font-weight: var( --fw-black );
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.promo-badge .material-symbols-outlined {
	font-size: 15px;
}

/*
 * The lead GROWS so that the price pair beside it ends up at the right edge,
 * which is where the mockup draws it. The mockup gets there with
 * `margin-left: auto` on the pair; measured on the built page that is
 * invariant I8.4's own defect - once the row wraps, an auto margin throws the
 * pair 248.69px in from the content edge instead of leaving it at the start.
 * A growing sibling reads the same on one line and wraps correctly.
 */
.promo-block__lead {
	flex: 1 1 auto;
	margin: 0;
	font-size: clamp( 15px, 2vw, 17px );
	font-weight: var( --fw-bold );
	line-height: 1.4;
}

/*
 * The offer's pair: struck base price, promotion price (the mockup's
 * akcijaKupSenaStyle and akcijaKupNaujaStyle). Printed only when there is a
 * pair to print. An element left in place with nothing in it is still 0x0
 * WITH the row's gap either side, which in the mockup moved the price eight
 * pixels sideways - the reason this is a condition in the template rather
 * than an always-present span.
 */
.promo-block__pair {
	display: inline-flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 9px;
}

.promo-block__was {
	color: var( --promo-surface-sub );
	font-size: 17px;
	font-weight: 600;
	text-decoration: line-through;
}

.promo-block__now {
	color: var( --promo-surface-accent );
	font-size: clamp( 24px, 3.2vw, 30px );
	font-weight: var( --fw-black );
	line-height: 1;
}

.promo-block__terms {
	position: relative;
	margin: 0;
	color: var( --promo-surface-sub );
	font-size: 12.5px;
	line-height: 1.5;
	opacity: 0.85;
}

/*
 * The price pair everywhere else (WPS-085 section 4): the base price struck
 * through, the promotion price beside it, in that order. It inherits the
 * slot's own size and weight - a 30 px voucher price stays 30 px, a 17 px
 * price-list figure stays 17 px - and only the struck part is styled here:
 * meta grey, lighter, three quarters of the slot's size. The <s> element
 * carries its own line-through; the rule restates it so a reset cannot take
 * it away.
 */
.price-pair {
	display: inline-flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.35em;
}

.price-pair__was {
	color: var( --text-meta );
	font-size: 0.72em;
	font-weight: 600;
	text-decoration: line-through;
}

/*
 * The four calendar seasons' costumes - every role the launch defaults
 * define, overridden from the --season-* tokens. A season class is set on
 * the bar, the block and the #akcija panel by the templates, so the roles
 * resolve where they are painted and nowhere else.
 */
.promo--christmas {
	--promo-bar-bg: var( --season-christmas-bar );
	--promo-bar-ink: var( --color-surface );
	--promo-bar-accent: var( --season-christmas-accent );
	--promo-surface: var( --season-christmas-bar );
	--promo-surface-ink: var( --color-surface );
	--promo-surface-sub: var( --season-christmas-sub );
	--promo-surface-accent: var( --season-christmas-accent );
	--promo-badge-bg: var( --color-brand-red );
	--promo-badge-ink: var( --color-surface );
	--promo-action-bg: var( --color-surface );
	--promo-action-ink: var( --season-christmas-bar );
	--promo-cta-border: var( --season-christmas-outline );
	--promo-cta-ink: var( --color-surface );
	--promo-card-bg: var( --season-christmas-card );
	--promo-card-ink: var( --season-christmas-bar );
	--promo-card-eyebrow: var( --color-brand-red );
}

.promo--valentines {
	--promo-bar-bg: var( --season-valentines-accent );
	--promo-bar-ink: var( --color-surface );
	--promo-bar-accent: var( --season-valentines-bar-accent );
	--promo-surface: var( --season-valentines-surface );
	--promo-surface-ink: var( --color-ink );
	--promo-surface-sub: var( --season-valentines-sub );
	--promo-surface-accent: var( --season-valentines-accent );
	--promo-badge-bg: var( --season-valentines-accent );
	--promo-badge-ink: var( --color-surface );
	--promo-action-bg: var( --season-valentines-accent );
	--promo-action-ink: var( --color-surface );
	--promo-cta-border: var( --season-valentines-accent );
	--promo-cta-ink: var( --season-valentines-accent );
	--promo-card-bg: var( --color-surface );
	--promo-card-ink: var( --color-ink );
	--promo-card-eyebrow: var( --season-valentines-accent );
}

.promo--black-friday {
	--promo-bar-bg: var( --season-black-friday-bar );
	--promo-bar-ink: var( --color-surface );
	--promo-bar-accent: var( --season-black-friday-accent );
	--promo-surface: var( --season-black-friday-bar );
	--promo-surface-ink: var( --color-surface );
	--promo-surface-sub: var( --season-black-friday-sub );
	--promo-surface-accent: var( --season-black-friday-accent );
	--promo-badge-bg: var( --season-black-friday-accent );
	--promo-badge-ink: var( --color-ink );
	--promo-action-bg: var( --season-black-friday-accent );
	--promo-action-ink: var( --color-ink );
	--promo-cta-border: var( --season-black-friday-outline );
	--promo-cta-ink: var( --color-surface );
	--promo-card-bg: var( --color-ink );
	--promo-card-ink: var( --color-surface );
	--promo-card-eyebrow: var( --season-black-friday-accent );
}

.promo--summer {
	--promo-bar-bg: var( --season-summer-bar );
	--promo-bar-ink: var( --color-surface );
	--promo-bar-accent: var( --season-summer-bar-accent );
	--promo-surface: var( --season-summer-surface );
	--promo-surface-ink: var( --color-ink );
	--promo-surface-sub: var( --season-summer-sub );
	--promo-surface-accent: var( --season-summer-bar );
	--promo-badge-bg: var( --season-summer-bar );
	--promo-badge-ink: var( --color-surface );
	--promo-action-bg: var( --action-primary );
	--promo-action-ink: var( --color-surface );
	--promo-cta-border: var( --season-summer-bar );
	--promo-cta-ink: var( --season-summer-sub );
	--promo-card-bg: var( --color-surface );
	--promo-card-ink: var( --color-ink );
	--promo-card-eyebrow: var( --season-summer-bar );
}

/* ---------------------------------------------------------------------------
 * Header
 */

.site-header {
	position: sticky;
	top: 0;
	z-index: 50;
	background: var( --tint-header );
	border-bottom: 1px solid var( --border-hairline );
}

/*
 * A logged-in preview user's admin toolbar covers the top of the viewport while
 * it is fixed; the sticky header stops below it. --admin-bar-fixed-height is
 * declared in base.css and is 0 for every public visitor and on narrow phones,
 * where the toolbar scrolls away with the page. The open phone navigation below
 * and the anchor padding in base.css give back the same pixels.
 */
body.admin-bar .site-header {
	top: var( --admin-bar-fixed-height, 0px );
}

/*
 * `position: relative` is load-bearing: on the phone the navigation panel is
 * absolutely positioned against this box, so it opens flush with the header's
 * bottom edge across the full width.
 */
.site-header__inner {
	position: relative;
	display: flex;
	align-items: center;
	gap: clamp( 6px, 1.4vw, 12px );
	padding-block: 10px;
}

/*
 * The language chip. One language, so it is a label rather than a control -
 * aria-hidden because <html lang> already tells assistive technology what
 * language this is, and a decorative "LT" would only repeat it. WPML turns this
 * into a real switcher in F8 and the geometry stays put.
 */
.site-lang {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	margin-left: auto;
	border-radius: 50%;
	color: var( --text-meta );
	font-size: 13.5px;
	font-weight: var( --fw-black );
}

/*
 * The cart icon (WPS-047). A tool with state, like the language chip beside
 * it, so it sits outside .site-nav rather than inside the collapsible menu -
 * see that chip's own comment above.
 */
/*
 * 44px, not the mockup's 38-40px: the language chip beside it is decorative
 * text (aria-hidden, no touch target to measure), but this is a real link,
 * and qa-measure's I8.2 floor applies to every size the header ships this
 * icon at. The icon itself stays the mockup's 22px; only the tappable circle
 * around it grows.
 */
.site-cart {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	color: var( --text-meta );
	text-decoration: none;
	flex: 0 0 auto;
}

.site-cart:hover {
	background: var( --surface-card );
	color: var( --color-accent-text );
}

.site-cart .material-symbols-outlined {
	font-size: 22px;
}

.site-cart__badge {
	position: absolute;
	top: 1px;
	right: 0;
	min-width: 18px;
	height: 18px;
	padding: 0 5px;
	box-sizing: border-box;
	border-radius: var( --radius-pill );
	background: var( --color-brand-red );
	color: var( --color-surface );
	font-size: 11px;
	font-weight: var( --fw-black );
	line-height: 18px;
	text-align: center;
}

.site-header__burger {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	background: var( --surface-card );
	border: 1px solid var( --border-control );
	border-radius: var( --radius-sm );
	color: var( --text-heading );
	cursor: pointer;
}

/* ---------------------------------------------------------------------------
 * Navigation
 *
 * Closed is the default, and it is closed with `visibility`, not only with
 * `max-height`. A panel hidden by height alone still holds every link in the tab
 * order, so a keyboard user tabs into a menu they cannot see - which is worse
 * than no menu at all. The visibility transition is delayed until the height
 * animation finishes, so closing still animates.
 */

.site-nav {
	position: absolute;
	top: 100%;
	right: 0;
	left: 0;
	display: flex;
	flex-direction: column;
	align-items: stretch;
	max-height: 0;
	padding: 4px var( --gutter ) var( --space-4 );
	overflow: hidden;
	visibility: hidden;
	opacity: 0;
	background: var( --tint-menu );
	border-bottom: 1px solid var( --border-hairline );
	box-shadow: var( --shadow-sheet );
	transition:
		max-height 0.25s var( --ease ),
		opacity var( --dur ) var( --ease ),
		visibility 0s linear 0.25s;
}

/*
 * Open, and never taller than the room it actually has.
 *
 * The panel is absolutely positioned against a header that is stuck to the top
 * of the viewport, so it does not scroll with the page: whatever hangs below the
 * fold hangs there permanently. On a phone held sideways - 844x390 - the six
 * entries plus the buttons come to 361 px against 324 px of room, and the last
 * two were unreachable. The sticky bar then took another 71 px off the bottom
 * and turned two more into the same thing, which is how I8.6 found this.
 *
 * min() takes the smaller of the design's 560 px and the room left between the
 * header's lower edge and the bar - the same --sticky-cta-room the spacer uses,
 * so the two can never drift apart. Below that, the panel scrolls. dvh rather
 * than vh because a phone's address bar takes its cut from the same space.
 *
 * WHERE THE HEADER'S LOWER EDGE IS gets measured, not assumed. It used to be
 * `100%` - this panel's containing block, the header row it hangs from - which
 * is only right while the header sits at the very top of the viewport. On an
 * unscrolled page the informational strip (or the promotion bar) sits above it,
 * and a signed-in user also has the WordPress toolbar there: at 844x390 the
 * panel then reached 29 px into the bar and the last entry ended under it.
 * main.js writes the row's real lower edge into --site-nav-top when the menu
 * opens, and again on scroll and resize while it is open. That measurement
 * already includes the toolbar, so the toolbar is not subtracted again. The
 * fallback, used only by a panel opened without main.js (the burger has no
 * other way to open), keeps the arithmetic: the header row plus the toolbar's
 * height while it is fixed (--admin-bar-fixed-height, 0 for every visitor).
 */
.site-header__inner[data-nav-open="true"] .site-nav {
	max-height: min( 560px, calc( 100dvh - var( --site-nav-top, calc( 100% + var( --admin-bar-fixed-height, 0px ) ) ) - var( --sticky-cta-room ) ) );
	overflow-y: auto;
	visibility: visible;
	opacity: 1;
	transition-delay: 0s;
}

.site-nav__list {
	display: flex;
	flex-direction: column;
	margin: 0;
	padding: 0;
	list-style: none;
}

.site-nav__list a {
	display: block;
	padding: 15px 2px;
	border-bottom: 1px solid var( --border-hairline );
	color: var( --text-body );
	font-size: var( --fs-body );
	font-weight: 600;
	text-decoration: none;
}

.site-nav__list a:hover {
	color: var( --text-link );
}

.site-nav__cta,
.site-nav__login {
	margin-top: 14px;
	justify-content: center;
}

/*
 * The signed-in state of the same button (WPS-109). It gets no box of its own -
 * the mockup draws the chip as this exact pill with a name in it - so the only
 * thing this rule owns is what a name can do that a fixed label cannot: run
 * long. A customer called Konstancija leaves the header no room for anything
 * else, and on the phone the burger panel would wrap the pill onto two lines.
 * The cap is in ch rather than px so it scales with the font rather than with a
 * guess about it.
 */
.site-nav__login-name {
	max-width: 18ch;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

/*
 * The phone does not get a second booking button.
 *
 * Below 1100 px the sticky bar at the bottom of the screen carries that action and
 * is visible without opening anything, so repeating it inside the burger menu is
 * the duplicate primary action invariant I12 forbids - and the more expensive of
 * the two copies to keep, because the menu one takes a tap to reach at all. The
 * mockups hide exactly this element at exactly this width, for exactly this
 * reason. The self-service link stays: it is a different action, and the bar does
 * not carry it.
 *
 * The pair is written mobile-first, which is why the desktop side has to restore
 * inline-flex rather than simply not hiding it - .btn's own display would not come
 * back on its own.
 */
.site-nav__cta {
	display: none;
}

/* ---------------------------------------------------------------------------
 * THE DESKTOP CHROME BREAKPOINT: 1100px, raised from 921px in WPS-059.
 *
 * Andrius found the header two rows tall on dev, the booking button dropped
 * under the links, ~119px instead of ~67px. It was not a narrow window: it did
 * that at EVERY width from 921px up, including 1600px, because the width the
 * row has to fit into stops growing long before the viewport does.
 *
 * THE BUDGET, MEASURED ON DEV. --container caps at 1100px and --gutter at
 * 32px, so from 1100px up the header's content box is 1036px and never wider.
 * The logo (191), the language chip (37), the cart (44) and three 12px gaps
 * take 308 of it, so .site-nav has exactly 728px - at 1100px, at 1600px, at
 * any width. The row wanted 744. Sixteen px over a budget that no amount of
 * screen can raise: that is why it wrapped everywhere.
 *
 * Two things were spending it, and both are departures from the mockup rather
 * than the mockup's own geometry (the mockup's row needs 709 and fits):
 *
 *   1. The login button was grouped with the booking button and inherited its
 *      22px side padding, where the mockup gives login 15px. Twenty px, spent
 *      by a shared CSS rule rather than by a decision. Given back below.
 *   2. The link gap's ceiling was 20px, seven gaps wide across the row. Pulled
 *      to 16px here, which is the whole of the remaining deviation and the
 *      only thing on this list the mockup did not ask for. Keeping 20px would
 *      have left the row 4px over - still broken, just less visibly.
 *
 * The 44px min-width on the links stays: it is invariant I8.2's floor and it
 * costs 13px, which the budget above can now afford.
 *
 * WHY THE BREAKPOINT HAD TO MOVE TOO. Trimming makes the row 704px, which fits
 * 728 - but only once the container is at its full 1100px. Below that the
 * content box shrinks with the viewport while the row does not: at 921px the
 * nav has 549px for something that cannot go under ~700. No font size or gap
 * saves that, so between 921px and 1099px the desktop header could never have
 * fitted, in this theme or in the mockup, which wraps in exactly that range
 * (measured). That band belongs to the burger, and now has it.
 *
 * THE STICKY BAR AND THE MESSENGER BUBBLE MOVE WITH IT, further down this
 * file. The three are one switch: below it the burger hides the booking
 * button, so the bar must be on screen to carry that action (invariant I12
 * counts one primary action, and zero is just as wrong as two); above it the
 * header carries it and the bar goes away. Splitting them would have left
 * 921-1099px with a burger, no bar and no way to book without opening a menu.
 */
@media ( min-width: 1100px ) {

	.site-nav__cta {
		display: inline-flex;
	}

	.site-header__burger {
		display: none;
	}

	.site-lang {
		order: 3;
		margin-left: 0;
	}

	.site-cart {
		order: 4;
	}

	.site-nav {
		position: static;
		order: 2;
		flex-direction: row;
		flex-wrap: wrap;
		align-items: center;
		max-height: none;
		margin-left: auto;
		padding: 0;
		overflow: visible;
		visibility: visible;
		opacity: 1;
		background: none;
		border: 0;
		box-shadow: none;
		gap: 4px clamp( 10px, 1.8vw, 16px );
	}

	.site-nav__list {
		flex-direction: row;
		flex-wrap: wrap;
		gap: 4px clamp( 10px, 1.8vw, 16px );
	}

	/*
	 * Two adjustments to the mockup's 6px/2px padding, both to clear the 44 px
	 * target floor, and both chosen to move as little as possible:
	 *
	 *   HEIGHT: 11 px of padding takes the target from 35 px to 45 px and
	 *   changes nothing visible - the row's height is set by the 46 px logo
	 *   beside it, and the links are centred in that row either way.
	 *
	 *   WIDTH: the shortest labels measured 31 px and 43 px wide. min-width
	 *   pads only those two out to 44 px rather than adding padding to every
	 *   link, which would have stretched the whole row's rhythm. Centring keeps
	 *   the short label in the middle of its own box instead of leaving a gap on
	 *   one side.
	 *
	 * The floor is not a phone-only rule: at 1100 px the burger is gone and this
	 * row is what a finger on a tablet in landscape actually hits.
	 */
	.site-nav__list a {
		min-width: 44px;
		padding: 11px 2px;
		border-bottom: 0;
		font-size: 14.5px;
		text-align: center;
	}

	/*
	 * The header's buttons are the SMALL size, and that is what sets the
	 * header's height. Measured: with the base button the row came out 72 px
	 * tall against the mockup's 66, because a 52 px button is taller than the
	 * 46 px logo beside it. At this size the button is 46.4 px - still clear of
	 * the 44 px floor, and the logo is what defines the row again.
	 *
	 * The phone keeps the base size: there the buttons are full width at the
	 * bottom of the open menu, where bigger is right.
	 */
	.site-nav__cta,
	.site-nav__login {
		margin-top: 0;
		font-size: var( --fs-caption );
	}

	.site-nav__cta {
		padding: 11px 22px;
	}

	/*
	 * The login button is the SECONDARY action and the mockup pads it to
	 * match: 15px a side against the booking button's 22px. Sharing one rule
	 * with the CTA had quietly given it the primary button's width - 137px
	 * where the design draws 117 - and that alone put the row over its budget
	 * (see the note above this block). 11px top and bottom rather than the
	 * mockup's 10px keeps the target at 48px for I8.2; only the sides move.
	 */
	.site-nav__login {
		padding: 11px 15px;
	}
}

/* ---------------------------------------------------------------------------
 * Footer
 */

.site-footer {
	background: var( --surface-soft );
	padding-block: clamp( 28px, 4vw, 44px ) clamp( 52px, 8vw, 88px );
}

/*
 * The phone is the base and 640 px restores the multi-column footer, which is
 * the mobile-first reading of the mockups' `max-width: 920px` block (review
 * rule 7). All FOUR of that block's footer rules now have a counterpart here.
 *
 * The fourth used to have none. `.f-col { flex: 1 1 40%; min-width: 130px }`
 * exists to stand the mockup's two link columns side by side under the brand,
 * and this footer had one column with one link in it, so there was nothing for
 * it to arrange. WPS-059 gave the footer its second column, and the rule came
 * with it.
 */
.site-footer__inner {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 20px 18px;
}

.site-footer__brand {
	display: flex;
	flex: 1 1 100%;
	flex-direction: column;
	gap: 14px;
}

.site-footer__tagline {
	margin: 0;
	color: var( --text-meta );
	font-size: 13px;
	line-height: var( --lh-body );
}

.site-social {
	display: flex;
	margin: 0;
	padding: 0;
	gap: 10px;
	list-style: none;
}

/*
 * The mark stays 38 px because that is the design, and the touch target reaches
 * 44 px through a ::before that extends past it. Growing the circle instead
 * would be the easy fix and the wrong one - invariant I8.2 names this exact
 * technique and adds "do not enlarge the visual".
 */
.site-social__link {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	background: var( --surface-card );
	border-radius: 50%;
	box-shadow: var( --shadow-soft );
	color: var( --text-heading );
	text-decoration: none;
}

.site-social__link::before {
	content: '';
	position: absolute;
	top: -3px;
	right: -3px;
	bottom: -3px;
	left: -3px;
}

.site-social__link:hover {
	color: var( --text-link );
}

.site-footer__col,
.site-footer__contacts {
	display: flex;
	flex-direction: column;
	gap: 8px;
	color: var( --text-body );
	font-size: var( --fs-caption );
}

/*
 * The mockup's own `.f-col` rule: on a phone the two link columns share one
 * row under the full-width brand instead of stacking into a tall ladder.
 * `min-width` keeps the narrower of the two from collapsing to its longest
 * word. Both are handed back at 640 px, where the columns line up beside the
 * brand rather than under it.
 */
.site-footer__col {
	flex: 1 1 40%;
	min-width: 130px;
}

/*
 * Hidden on the phone, both of them - the mockups' `.f-tag, .f-contact` rule.
 * The sticky bar already carries the phone number, and a second copy of the
 * primary action is what invariant I12 forbids.
 *
 * THE PRICE, MEASURED: the e-mail address goes with the column, and the sticky
 * bar has no `mailto:` to replace it (it carries call, Messenger and booking).
 * On four of the six built pages the footer link is the only one on the page, so
 * they drop to zero. The address stays one route away - every page keeps a
 * header link to /kontaktai/, which has two of its own plus the form - but at
 * 390 px that link sits inside the closed burger, so it is two taps, not one.
 * The mockups accept this; the finding is filed for the design round.
 */
.site-footer__tagline,
.site-footer__contacts {
	display: none;
}

.site-footer__heading {
	margin: 0;
	color: var( --text-heading );
	font-size: var( --fs-eyebrow );
	font-weight: var( --fw-bold );
	letter-spacing: var( --ls-label );
	text-transform: uppercase;
}

.site-footer__list {
	display: flex;
	flex-direction: column;
	margin: 0;
	padding: 0;
	list-style: none;
}

.site-footer__contacts p {
	margin: 0;
}

/*
 * Padding pulled back by an equal negative margin: the target clears 44 px
 * without the links drifting apart visually. 14px text at line-height 1.6 is
 * 22.4 px, so 11 px on each side lands at 44.4 px - measured, not guessed.
 *
 * THAT SOLVED THE HEIGHT AND LEFT THE WIDTH, which is the half WPS-060 found
 * still open: `inline-block` makes the box exactly as wide as the word, so
 * "DUK" measured 25.5 x 44.4 px and "Testas" 33.7 - short of the 44 px floor
 * on the axis nobody had checked. `block` hands each link its column instead
 * (170 px at 390 px), and the two footer columns sit at x=16 and x=204, so a
 * full-width target in one cannot reach into the other. Every contact link is
 * alone in its own <p>, so none of them is an inline word inside a sentence
 * that this would break onto its own line.
 *
 * Worth naming because three tasks in a row recorded it as a HEADER finding
 * (WPS-069, WPS-074, and this round's own first pass): the elements measure at
 * y ~ 7100 px on the front page. They are the footer menu. The header's own
 * nav is behind the hamburger at 390 px and is not rendered at all.
 */
.site-footer__list a,
.site-footer__contacts a {
	display: block;
	padding: 11px 0;
	margin: -11px 0;
	color: var( --text-body );
	text-decoration: none;
}

.site-footer__list a:hover,
.site-footer__contacts a:hover {
	color: var( --text-link );
}

.site-footer__rule {
	width: 100%;
	height: 1px;
	margin: 0;
	background: var( --border-control );
	border: 0;
}

/*
 * The smile thought (WPS-069 §3): a fixed per-page quote between the footer
 * rule and the legal line. The map lives in inc/template-tags.php
 * (sypsena_smile_thoughts) rather than an options screen - it changes rarely
 * enough that hand-editing the map beats building admin UI for it, and Diana
 * still edits it without touching a template's markup.
 */
.ft-mintis {
	width: 100%;
	max-width: 620px;
	margin: 0 auto;
	padding: 20px 16px 4px;
	box-sizing: border-box;
	text-align: center;
}

.ft-mintis__glyph {
	display: block;
	margin: 0;
	font-size: 34px;
	line-height: 0.55;
	color: var( --text-meta );
	opacity: 0.45;
}

.ft-mintis__text {
	margin: 8px 0 2px;
	font-style: italic;
	font-size: 15px;
	line-height: 1.55;
	color: var( --text-body );
}

.ft-mintis__author {
	margin: 2px 0 0;
	font-size: 13px;
	font-style: normal;
	color: var( --text-meta );
	opacity: 0.7;
}

/*
 * The in-content variant (404, order-confirmation): a bigger glyph and no
 * footer padding, since it sits inside the page's own section rhythm rather
 * than between the footer rule and the legal line.
 */
.ft-mintis--note {
	padding: 0;
}

.ft-mintis--note .ft-mintis__glyph {
	font-size: 40px;
}

.ft-mintis--note .ft-mintis__text {
	font-size: clamp( 18px, 2.2vw, 20px );
}

.site-footer__legal {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	width: 100%;
	gap: 10px 24px;
	color: var( --text-meta );
	font-size: var( --fs-meta );
}

.site-footer__legal p {
	margin: 0;
}

.site-footer__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px 18px;
}

/* 13px at line-height 1.6 is 20.8 px, so this pair needs 12 px a side. */
/*
 * The 44px min-width is invariant I8.2's floor, and it is here because of a
 * translation rather than a design: every Lithuanian label in this row is
 * wider than 44px on its own, and the first English one - "Terms", the
 * terms-page link - was 38px (WPS-080, measured on /en/kontaktai/ at 390px). A
 * label that shrinks with its language must not take the tap target with it.
 * Centred, so the short word sits in the middle of its box rather than at
 * its left edge; the Lithuanian labels fill the box and do not move.
 */
.site-footer__meta a {
	display: inline-block;
	min-width: 44px;
	padding: 12px 0;
	margin: -12px 0;
	color: var( --text-meta );
	text-align: center;
	text-decoration: none;
	white-space: nowrap;
}

.site-footer__meta a:hover {
	color: var( --text-link );
}

/*
 * From 640 px up the footer is the wide one: the bigger gap, the brand back in
 * its 300 px column, the link columns beside it rather than under it, and both
 * blocks the phone hides back on screen.
 *
 * 640 px, lowered from 921 px in WPS-059. Andrius found the footer on a tablet
 * with the brand stretched across the full width, the link column dropped
 * underneath it and the right-hand two thirds of the row empty - measured at
 * 900 px: an 836 px brand and 64 px of nothing beside it. The cause was that
 * `flex: 1 1 100%` on the brand held until 921 px, so every width from a large
 * phone to a landscape tablet got the phone's stacked layout while having
 * desktop room to spare. There is nothing at 921 px that the footer needs: it
 * is the HEADER's number (and now not even that - see the chrome breakpoint
 * note), inherited here because both were read out of the same mockup block.
 * The footer's own question is only "is there room for a second column", and
 * the answer turns out to be yes from about 640 px.
 *
 * The contacts column comes back at the same point. It is hidden on a phone
 * because the sticky bar carries the number and the row has no space for a
 * fourth block - neither is true here.
 */
@media ( min-width: 640px ) {

	/*
	 * The gap has to shrink with the viewport here, and that is not tidiness.
	 * .site-footer__inner is `justify-content: space-between`, so the moment
	 * the row is one pixel too narrow the blocks do not merely wrap - the
	 * survivors are thrown to opposite edges and the rest land alone on the
	 * next line. Measured at 640px with a flat 48px gap: the brand at the far
	 * left, one link column at the far right, the other underneath. A gap that
	 * gives way first keeps the row a row.
	 */
	.site-footer__inner {
		gap: 28px clamp( 24px, 4vw, 48px );
	}

	.site-footer__brand {
		flex: 0 1 auto;
		max-width: 300px;
	}

	.site-footer__col {
		flex: 0 1 auto;
		min-width: 0;
	}

	.site-footer__tagline {
		display: block;
	}
}

/*
 * The contacts column joins last, because it is the widest of the four blocks
 * and the row cannot hold it before this. Measured: brand (300) plus the two
 * link columns (109 and 89) plus this one (180) plus three gaps needs ~790px
 * of content box, which arrives at about 890px of viewport. Letting it in at
 * 640px with the others was what broke the row above.
 */
@media ( min-width: 900px ) {

	.site-footer__contacts {
		display: flex;
	}
}

/* ---------------------------------------------------------------------------
 * Sticky action bar
 *
 * The phone's permanent three ways to reach Diana. Visible by DEFAULT and hidden
 * from 1100 px up (WPS-059 raised it from the mockups' 921 px - see the chrome
 * breakpoint note above): above that width the header's own booking button is
 * on screen at all times and a second bar would be one primary action too many
 * (invariant I12).
 *
 * The whole component is 50 px tall inside 10 px of padding, and that is not a
 * coincidence in three places at once: the two round buttons declare 50 px, the
 * action button reaches it through 15 px of padding around a 20 px line box, and
 * the design draws them level. Change one and the row stops being a row.
 */

.cta-sticky__bar {
	position: fixed;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 60;
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 10px clamp( 12px, 4vw, 16px );
	background: var( --surface-card );
	border-top: 1px solid var( --tint-line );
	box-shadow: var( --shadow-bar );

	/*
	 * The iPhone's home indicator lives in the bottom inset. Without this the bar
	 * ends where the screen ends and the gesture area sits on top of the buttons;
	 * max() keeps the design's 10 px on every phone that has no inset.
	 */
	padding-bottom: max( 10px, env( safe-area-inset-bottom ) );
	transition: transform 0.2s ease, visibility 0s linear 0s;
}

/* The bar steps aside while a page booking button is on screen (main.js
 * setUpStickyRetreat(), WPS-122). visibility follows the slide so the hidden
 * bar's links leave the tab order and cannot take a tap. */
.cta-sticky[data-retreated] .cta-sticky__bar {
	visibility: hidden;
	transform: translateY( 110% );
	transition: transform 0.2s ease, visibility 0s linear 0.2s;
}

@media ( prefers-reduced-motion: reduce ) {
	.cta-sticky__bar,
	.cta-sticky[data-retreated] .cta-sticky__bar {
		transition: none;
	}
}

/*
 * The compensation, and the only reason the last link in the footer is reachable
 * at all: the bar is out of flow, so without an in-flow block of the same height
 * the page simply ends underneath it.
 *
 * The height is --sticky-cta-room, declared at the top of this file because the
 * burger menu's cap has to be the same number. On a phone with an inset it grows
 * by exactly as much as the bar does, which a literal 82 px would not.
 */
.cta-sticky__spacer {
	height: var( --sticky-cta-room );
}

.cta-sticky__round {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: 50px;
	height: 50px;
	background: var( --surface-card );
	border: 1px solid var( --border-control );
	border-radius: 50%;
	color: var( --text-heading );
	text-decoration: none;
	transition: background var( --dur ) var( --ease ), border-color var( --dur ) var( --ease );
}

.cta-sticky__round:hover {
	border-color: var( --color-accent );
	color: var( --text-link );
}

/*
 * Meta's blue, on both the fill and the border. The mockup draws this button with
 * no border at all; matching that literally would make it 2 px smaller than the
 * one beside it, because everything here is border-box. Painting the border in
 * the same colour is the same picture and the same 50 px.
 */
.cta-sticky__round--messenger {
	background: var( --color-brand-messenger );
	border-color: var( --color-brand-messenger );
	color: var( --color-surface );
}

/* colour is restated rather than inherited: .cta-sticky__round:hover turns the
 * outlined button's glyph blue at the same specificity, and only the properties
 * named here win over it. */
.cta-sticky__round--messenger:hover {
	background: var( --color-brand-messenger-hover );
	border-color: var( --color-brand-messenger-hover );
	color: var( --color-surface );
}

/*
 * The wide button - booking on thirteen pages, Messenger on the booking page.
 * It carries .btn for the pill shape and the weight, and overrides what the
 * header's buttons settled differently: it fills the row and it is a step larger.
 *
 * THE HEIGHT IS DECLARED, not left to the content, and that is the fix for a
 * defect this component had until it was measured. Padding around a line box
 * gives a height that depends on what is inside: the booking state holds a 20 px
 * icon and came out at 50 px, the Messenger state holds the 24 px brand mark and
 * came out at 54 px, so the same component was two different sizes on two pages -
 * invariant I8.5. One number here makes both states 50 px, which is also what the
 * round buttons beside them measure, and it is why the bar is 71 px on every page.
 */
.cta-sticky__action {
	flex: 1;
	min-width: 0;
	height: 50px;
	padding: 0 15px;
	border: 0;
	font-size: var( --fs-body );
	line-height: 1.25;
}

.cta-sticky__action--messenger {
	background: var( --color-brand-messenger );
	color: var( --color-surface );
}

.cta-sticky__action--messenger:hover {
	background: var( --color-brand-messenger-hover );
}

/* 20 px in the action button, the row's 24 px in the round ones - the mockup's
 * sizes. flex is what keeps a narrow phone from squeezing them (invariant I8.3). */
.cta-sticky__action .material-symbols-outlined {
	font-size: 20px;
}

.cta-sticky svg,
.cta-sticky .material-symbols-outlined {
	flex: 0 0 auto;
}

/*
 * 1100px, not 921px, and it has to be the same number the header uses - see
 * "THE DESKTOP CHROME BREAKPOINT" above. This bar is what carries booking
 * while the burger is hiding the header's own button, so it may only stand
 * down at the width where that button comes back.
 */
@media ( min-width: 1100px ) {

	.cta-sticky {
		display: none;
	}
}

/* ---------------------------------------------------------------------------
 * Cookie consent bar
 *
 * Fixed on every screen size, unlike the sticky action bar it shares the
 * bottom edge with on narrow screens: this one never disappears above
 * its breakpoint, because dismissing it is a one-time choice a visitor makes once,
 * not a screen-size-dependent piece of chrome. WHAT it looks like DOES
 * change at that breakpoint though (Andrius's decision 2026-08-24, after
 * comparing three options in Claude Design): mobile/tablet keeps the
 * full-width bar below; desktop switches to a centred floating card so it
 * can never collide with the desktop Messenger entry point, which - once
 * built - will sit in the opposite (bottom-right) corner.
 *
 * STACKS ABOVE the sticky action bar on narrow screens rather than under it,
 * on the exact breakpoint and room variable that bar already declares
 * (--sticky-cta-room, above) - a second hardcoded height here would silently
 * drift from the first the day either bar's own padding changes.
 *
 * NO SPACER. cta-sticky's is permanent because that bar never leaves; this
 * one is dismissed on the first click, so template-parts/cookie-bar.php
 * documents the trade rather than adding show/hide logic to a spacer too.
 *
 * TWO ROWS, ALWAYS CENTRED (Andrius's second desktop finding, 2026-08-25):
 * icon+text+link (.cookie-bar__info) stack above the button as a column,
 * both centred via align-items - not a flex-basis trick on the button, which
 * would have stretched its pill shape across the whole card. The link lives
 * INSIDE .cookie-bar__text's own markup (template-parts/cookie-bar.php), so
 * it wraps as ordinary inline text next to the sentence rather than as a
 * third flex item - it shares a line with the text when there is room, and
 * drops to its own line when there is not (see the width finding below -
 * at 420px there wasn't enough room).
 *
 * WIDER CARD, THIRD DESKTOP FINDING (2026-08-25): the link still dropped to
 * its own line inside the 420px card - icon+text+link need ~446px unwrapped
 * and only ~384px of content width was available after the border and
 * padding below. max-width goes 420px -> 500px (measured in Playwright:
 * 460px is the first width that stops wrapping; 500px keeps ~40px of slack
 * for font-rendering differences between environments). The button below is
 * untouched by this change.
 *
 * BUTTON REJOINS THE LINE, FIFTH DESKTOP FINDING (2026-08-25): once the card
 * was wide enough, Andrius asked for the opposite of the second finding
 * above - "on tablet and desktop the button fits on one line with the
 * text, so change it that way; on mobile it doesn't fit, so leave that as
 * it is." .cookie-bar goes back from flex-direction:column to row+wrap (the
 * button is a flex sibling of .cookie-bar__info again, not a separate block
 * below it) - ordinary CSS wrapping now decides per available width instead
 * of a fixed structural split. max-width goes 500px -> 600px (measured:
 * 553px is the first width where the button no longer fits alongside
 * icon+text+link), so the full-width bar has room from ~800px up and the
 * desktop card has room from its own floor. At true mobile widths
 * .cookie-bar__info's own internal wrap already claims the full available
 * width, so the button still lands on its own line below with no extra
 * rule needed to force it there.
 */

.cookie-bar {
	position: fixed;
	right: 0;
	/*
	 * The HEIGHT, not the room: this bar sits ON the action bar, so it wants the
	 * bar's own height. Asking for the room left it floating 11 px above, with a
	 * stripe of page showing between the two - Andrius's finding on a tablet.
	 */
	bottom: var( --sticky-cta-height );
	left: 0;
	z-index: 65;
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: 10px;
	padding: 12px clamp( 16px, 4vw, 32px );
	background: var( --color-fill );
	border-top: 1px solid var( --border-hairline );
	box-shadow: var( --shadow-bar );
	text-align: center;
}

.cookie-bar[hidden] {
	display: none;
}

.cookie-bar__info {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 8px 16px;
}

.cookie-bar__icon {
	flex: 0 0 auto;
	font-size: 18px;
	color: var( --text-meta );
}

.cookie-bar__text {
	margin: 0;
	font-size: var( --fs-caption );
	font-weight: var( --fw-medium );
	color: var( --text-body );
}

.cookie-bar__link {
	color: var( --text-link );
	font-weight: var( --fw-bold );
}

/*
 * Desktop: the bar becomes a floating card, centred at the bottom of the
 * viewport rather than spanning it. --radius-lg and --shadow-floating are
 * the same pairing the design system already uses for lifted, detached
 * surfaces - this is that category now, not a bottom-anchored bar.
 *
 * CENTRING FIX, found while verifying the width fix above (2026-08-25): this
 * used to override left/right to 50%/auto and centre with a
 * transform:translateX(-50%), on the wrong assumption that margin:auto does
 * nothing for a fixed-position element - it works fine once left and right
 * are both definite (0 here, inherited from the full-width bar above) and
 * width is left auto, exactly as it would on a static block. The transform
 * trick was more than just unnecessary: with left:50% and right:auto, the
 * browser's shrink-to-fit width for the box is computed from only the HALF
 * of the viewport to the right of that 50% point, not the full width - at
 * the breakpoint itself that halved budget was too narrow for
 * icon+text+link to stay on one line even after widening max-width to
 * 500px, so the very bug this file exists to fix was still reachable just
 * by narrowing the browser window. margin:auto has no such asymmetry: it
 * always sees the full available width up to max-width, so a card that
 * fits at 1440px now fits identically at its floor (verified in Playwright).
 *
 * THE FLOOR IS 1100px SINCE WPS-059, and it follows the sticky bar rather
 * than choosing for itself. Below it the full-width bar sits at
 * `bottom: var( --sticky-cta-room )`, i.e. stacked on top of the action bar;
 * the moment it becomes a floating card it drops to `bottom: 16px`, which is
 * the action bar's own space. Left at 921px while the bar moved to 1100px,
 * the two would have overlapped across the whole 921-1099px band - the exact
 * collision the room variable exists to prevent.
 */
/*
 * THE CARD, from 640 px up - not from the chrome breakpoint.
 *
 * Two different questions were being answered by one number, and WPS-059 moved
 * it for the wrong one of them. WHAT the notice looks like is a question about
 * the room it has: the card is capped at 600 px and needs about that much, so
 * it can appear as soon as the viewport can hold it. WHERE it sits is a question
 * about the action bar underneath it, which is the chrome breakpoint's business.
 * Tying the look to the chrome breakpoint gave every tablet the phone's flat
 * full-width strip, and it read as part of the page rather than as a notice on
 * top of it - which is exactly what Andrius reported.
 *
 * The border, the radius and --shadow-floating are what separate it: at this
 * size the notice is an object lifted off the page, and the mockup draws it that
 * way (measured: rgba(23,28,33,0.18) 0 12px 32px, 20 px radius, 602 px wide).
 */
@media ( min-width: 640px ) {

	.cookie-bar {
		margin: 0 auto;
		max-width: 600px;
		padding: 16px 18px;
		border: 1px solid var( --border-hairline );
		border-radius: var( --radius-lg );
		box-shadow: var( --shadow-floating );

		/*
		 * Clear of the action bar, plus the same 16 px it gets from the bottom
		 * of the screen once the bar is gone. A card resting flat on the bar
		 * would read as one object with it.
		 */
		bottom: calc( var( --sticky-cta-height ) + 16px );
	}
}

/* Above the chrome breakpoint there is no action bar left to sit on. */
@media ( min-width: 1100px ) {

	.cookie-bar {
		bottom: 16px;
	}
}

/* ---------------------------------------------------------------------------
 * The article card
 *
 * WHY THIS IS HERE AND NOT IN A PAGE STYLESHEET. It is drawn by one template
 * part, template-parts/article-card.php, and TWO pages print it: the index at
 * /category/suzinok/ and, from WPS-026, every single article under
 * /suzinok/<slug>/. Only one page stylesheet is ever enqueued (inc/assets.php),
 * so while these rules lived in suzinok.css the cards under an article had no
 * card styling at all - measured: the link computed to `display: inline`, no
 * border, no background, underlined in link blue, and the 44 px arrow collapsed
 * to 24x19.5. None of the machine gates catch that, because nothing about it
 * breaks a contrast ratio, a target size or a scroll width.
 *
 * The same argument the template part's own docblock makes about markup - a
 * card that exists twice is a card that drifts - applies to its stylesheet, and
 * this is where a component shared by more than one page belongs.
 *
 * The selector lists that pair .str-card with .str-featured move whole rather
 * than being split, so the shared declarations keep exactly one home. The
 * featured card itself stays an index-only layout and its own rules stay in
 * suzinok.css with the grid, the hero and the empty state.
 */

.str-featured__link,
.str-card__link {
	display: block;
	height: 100%;
	border: 1px solid var( --color-border );
	border-radius: var( --radius-xl );
	background: var( --surface-card );
	color: inherit;
	text-decoration: none;
	overflow: hidden;
	transition:
		border-color var( --dur ) var( --ease ),
		box-shadow var( --dur ) var( --ease ),
		transform var( --dur ) var( --ease );
}

.str-featured__link:hover,
.str-card__link:hover {
	border-color: var( --color-border-strong );
	box-shadow: var( --shadow-card );
}

.str-featured__image,
.str-card__image {
	display: block;
	width: 100%;
	height: auto;
}

.str-featured__topic,
.str-card__topic {
	margin: 0;
	color: var( --text-meta );
	font-size: var( --fs-eyebrow );
	font-weight: var( --fw-bold );
	letter-spacing: var( --ls-label );
	text-transform: uppercase;
}

.str-card__body {
	display: flex;
	flex-direction: column;
	padding: var( --space-6 );
}

.str-card__title {
	margin: var( --space-2 ) 0 var( --space-2 );
	color: var( --text-heading );
	font-size: var( --fs-h3 );
	line-height: var( --lh-snug );
}

.str-card__excerpt {
	margin: 0 0 var( --space-4 );
	color: var( --text-body );
	font-size: var( --fs-sm );
	line-height: var( --lh-relaxed );
}

.str-featured__meta,
.str-card__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px;
	margin: 0;
	color: var( --text-meta );
	font-size: var( --fs-meta );
}

.str-card__meta-icon {
	font-family: var( --font-icon );
	font-size: 16px;
}

.str-card__date--updated {
	font-weight: var( --fw-bold );
}

/*
 * The arrow is decoration: the whole card is the link, so the arrow must not be
 * a second target and must not be announced. It sits inside the card rather
 * than floating over it, so it can never cover the text it points at.
 */
.str-card__arrow {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	margin: 0 var( --space-6 ) var( --space-6 );
	border: 1px solid var( --color-border );
	border-radius: var( --radius-pill );
	color: var( --text-heading );
}

.str-card__arrow .material-symbols-outlined {
	font-family: var( --font-icon );
	font-size: 20px;
}

.str-card__link:hover .str-card__arrow {
	border-color: var( --action-primary );
	background: var( --action-primary );
	color: var( --color-surface );
}

/* ---------------------------------------------------------------------------
 * The quiz band
 *
 * WHY THIS IS HERE AND NOT IN A PAGE STYLESHEET, AHEAD OF ITS SECOND USE. Only
 * one page prints it today - /duk/ - but the mockups draw the identical bar a
 * second time on Kainos.dc.html (WPS-019's own scope note), and that second
 * page is not built yet only because WPS-096 has not decided it. The article
 * card already taught this codebase what happens when a shared component's
 * rules wait for a second consumer before they get a shared home: they sit in
 * a page stylesheet that only one page loads, the second page renders the
 * markup with none of its styling, and nothing in the automated gates notices
 * because nothing about it fails a contrast ratio, a target size or a scroll
 * width (see "The article card" above). Placing it here now costs one small
 * block in a shared file; leaving it in duk.css would cost a repeat of that
 * exact finding whenever WPS-096 is decided.
 *
 * TWO VALUES SNAPPED TO THE CANON, not carried from the mockup as drawn (the
 * hex the mockup actually paints is in docs/design-zurnalas.md rather than
 * repeated here - a hex spelled out in a comment is still a colour that left
 * tokens.css, qa-grep G4):
 *
 *   BORDER COLOUR. The mockup paints a fourth grey the palette has no name
 *   for and that no other card on the site uses - every other bordered card
 *   already reaches for --color-border. Read as an unintentional near-miss
 *   rather than a second border colour worth naming, the same kind of
 *   correction WPS-022 made for a radius the mockup drew one step outside the
 *   scale.
 *
 *   RADIUS. 18px, which sits between the 12-16 icon-box band and the 20-28
 *   card band and inside neither (qa-tokens T4). This bar is a card that
 *   happens to be one row tall rather than an icon box, so it takes
 *   --radius-lg the way every other bordered card on the site does.
 */

.quiz-band {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 12px 16px;
	padding: clamp( 16px, 2.4vw, 22px ) clamp( 16px, 2.6vw, 26px );
	border: 1px solid var( --color-border );
	border-radius: var( --radius-lg );
	background: var( --color-surface );
	color: inherit;
	text-decoration: none;
	transition: border-color var( --dur ) var( --ease );
}

.quiz-band:hover {
	border-color: var( --color-accent );
}

.quiz-band__icon {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: var( --tint-ice );
}

.quiz-band__icon .material-symbols-outlined {
	font-family: var( --font-icon );
	font-size: 21px;
	color: var( --color-accent-text );
}

.quiz-band__text {
	flex: 1 1 260px;
	min-width: 0;
	font-size: 14.5px;
	line-height: 1.55;
	color: var( --text-body );
}

.quiz-band__text b {
	color: var( --text-heading );
}

.quiz-band__cta {
	display: inline-flex;
	align-items: center;
	flex-shrink: 0;
	gap: 6px;
	font-size: var( --fs-caption );
	font-weight: var( --fw-black );
	color: var( --color-accent-text );
}

.quiz-band__cta .material-symbols-outlined {
	font-family: var( --font-icon );
	font-size: 17px;
}

/* ---------------------------------------------------------------------------
 * Booking card (WPS-122, DS BookingCard)
 *
 * Shared by template-parts/booking-card.php on the front page and About Diana -
 * components.css because the theme loads one page stylesheet per request, and
 * a component styled in one page's file stops matching the other page.
 * One visit, one price, one action; the numbers come from sypsena_visit().
 */
.bcard {
	display: flex;
	flex-direction: column;
	padding: clamp( 18px, 3vw, 26px );
	background: var( --surface-card );
	border-radius: var( --radius-xl );
	box-shadow: var( --shadow-card );
	gap: var( --space-4 );
}

/* Inside the front page's and About's booking panel the panel already is the
 * white card (it also holds the Live A availability panel), so the card lays
 * flat in it rather than drawing a second card inside the first. */
.fp-booking__card > .bcard,
.ap-booking__card > .bcard {
	padding: 0;
	background: none;
	border-radius: 0;
	box-shadow: none;
}

.bcard__summary {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	padding: 14px 16px;
	background: var( --tint-sky-soft );
	border-radius: var( --radius-md );
	gap: var( --space-3 );
}

.bcard__what {
	display: flex;
	flex-direction: column;
	min-width: 0;
	gap: 3px;
}

.bcard__what p,
.bcard__price,
.bcard__fine {
	margin: 0;
}

.bcard__who {
	color: var( --text-link );
	font-size: var( --fs-eyebrow );
	font-weight: var( --fw-bold );
	letter-spacing: var( --ls-eyebrow );
	text-transform: uppercase;
}

.bcard__service {
	color: var( --text-heading );
	font-size: 18px;
	font-weight: var( --fw-black );
	line-height: 1.25;
}

.bcard__time {
	display: flex;
	align-items: center;
	gap: 6px;
	color: var( --text-meta );
	font-size: var( --fs-caption );
}

.bcard__time .material-symbols-outlined {
	font-size: 20px;
}

.bcard__price {
	color: var( --text-link );
	font-size: var( --fs-price );
	font-weight: var( --fw-black );
	line-height: 1;
	white-space: nowrap;
	text-align: right;
}

.bcard__list {
	display: flex;
	flex-direction: column;
	margin: 0;
	padding: 0;
	gap: 10px;
	color: var( --text-body );
	font-size: var( --fs-sm );
	line-height: 1.5;
	list-style: none;
}

.bcard__list li {
	display: flex;
	align-items: flex-start;
	gap: 10px;
}

.bcard__list .material-symbols-outlined {
	flex-shrink: 0;
	color: var( --color-green-ink );
	font-size: 20px;
}

.bcard__list b {
	color: var( --text-heading );
}

/* A 44 px tall target inside a line of text, without moving the line (I8.2). */
.bcard__more {
	display: inline-block;
	padding: 12px 0;
	margin: -12px 0;
	color: var( --text-link );
	font-weight: var( --fw-bold );
}

.bcard__cta {
	justify-content: center;
	min-height: 48px;
}

.bcard__fine {
	color: var( --text-meta );
	font-size: var( --fs-meta );
	line-height: var( --lh-snug );
	text-align: center;
}

/* ---------------------------------------------------------------------------
 * Soft help note
 *
 * A tinted panel holding one reassuring sentence and, usually, a mailto link.
 * It started life as .nf-note inside 404.css; WPS-043's order-received screen
 * needs the identical thing, and the theme loads exactly ONE page stylesheet
 * per request, so a second copy in a second page file would not be a shortcut -
 * it would be two definitions of one component drifting apart.
 */

.note-soft {
	display: flex;
	align-items: flex-start;
	gap: var( --space-3 );
	max-width: 640px;
	margin: 0;
	padding: 14px 18px;
	border-radius: var( --radius-md );
	background: var( --tint-panel );
	color: var( --text-body );
	font-size: var( --fs-caption );
	line-height: var( --lh-body );
}

.note-soft__icon {
	flex-shrink: 0;
	font-size: 19px;
	color: var( --text-link );
}

/*
 * NOT .legal-card dd a's inline-block/padding pair (legal.css).
 * That link sits alone as a definition-list value; this one has a period
 * immediately after it with no space, and inline-block turned out to give
 * Chromium a line-break opportunity right after the link even without one -
 * measured at 1440 px, where the lone "." wrapped onto its own line. Staying
 * `inline` (the mockup's own AS-146 technique: an absolutely positioned
 * ::before, invisible, widening only the hit area) keeps the anchor and its
 * trailing punctuation exactly as breakable as plain text, which is to say
 * not breakable there at all.
 */
.note-soft__mail {
	position: relative;
	font-weight: 600;
}

.note-soft__mail::before {
	content: '';
	position: absolute;
	top: -14px;
	right: -6px;
	bottom: -14px;
	left: -6px;
}

/* ---------------------------------------------------------------------------
 * Floating Messenger button (WPS-049)
 *
 * Desktop only - below 1100px cta-sticky already puts a Messenger entry point
 * on screen, and a second one fixed in the opposite corner would be the
 * duplicate invariant I12 forbids. All fourteen mockups draw this in the
 * bottom-right corner; the cookie bar's own CSS (above) already reserves that
 * corner for it on desktop.
 */

.fab-msg {
	display: none;
	position: fixed;
	right: 22px;
	bottom: 22px;
	z-index: 70;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	border-radius: 50%;
	background: var( --color-brand-messenger );
	color: var( --color-surface );
	box-shadow: var( --shadow-floating );
	text-decoration: none;
}

.fab-msg:hover {
	background: var( --color-brand-messenger-hover );
}

/*
 * The third member of the chrome switch (see the header's note): the bubble
 * appears only where the sticky bar has gone, because the bar carries
 * Messenger itself and two of them on one screen is the duplicate this
 * bubble's own media query has always existed to prevent.
 */
@media ( min-width: 1100px ) {

	.fab-msg {
		display: flex;
	}
}
