/*
Theme Name: eTicketing
Theme URI: https://eticketing.my/
Author: Arif (ETicketing)
Author URI: https://eticketing.my/
Description: A block theme for eticketing.my sites. Built for WordPress multisite.
Requires at least: 6.7
Tested up to: 6.9
Requires PHP: 7.4
Version: 1.4.0
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
Text Domain: eticketingtheme
Tags: full-site-editing, block-patterns, block-styles, custom-colors, custom-logo, custom-menu, editor-style, translation-ready, one-column, wide-blocks
*/

/* ==========================================================================
   Layout scaffolding
   ========================================================================== */

.wp-site-blocks {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

.wp-site-blocks > footer {
	margin-block-start: 0 !important;
}

.wp-site-blocks > main {
	margin-bottom: auto !important;
}

/* ==========================================================================
   Notice bar — the ETicketing Content plugin's, corrected from here
   ========================================================================== */

/*
 * THE BAR IS NOT THIS THEME'S (CR-P054). It is drawn by the ETicketing Content
 * plugin, which is not one of the repositories this project's workflow covers, so
 * the two things the owner asked for are set from here instead of at the source.
 * Anybody wondering later why the notice bar does not obey its own plugin should
 * find this comment first.
 *
 * BOTH RULES ARE MATCHED ON THE ID, and that is what makes them work rather than
 * a preference. The plugin prints its own rules inline in the body, after this
 * stylesheet loads in the head, so on equal weight the plugin would win on source
 * order. Its selectors are single classes; an id outweighs any of them, whatever
 * the order. Do not "tidy" these into class selectors.
 *
 * The cost of doing it from here: if a later version of that plugin changes the
 * bar's height or fixes the button itself, these rules will still be applied over
 * the top of it, silently. Check here before editing the bar anywhere else.
 */

/*
 * Three pixels taller, on the owner's ask (Q-P048-8). The plugin sets min-height
 * 50px, deliberately, so the page does not jump while the bar's text loads; this
 * keeps that guarantee and only raises the number.
 *
 * DESKTOP ONLY IN PRACTICE, and not by choice. Below 768px the bar's contents
 * stack and make it 67px tall on their own, so a 53px floor never engages there.
 * The +3px is visible exactly where the owner was looking.
 */
#etick-homepage-alert {
	min-height: 53px;
}

/*
 * The Download App button, lined up with the words beside it (Q-P048-8).
 *
 * IT IS RESTORING THE PLUGIN'S OWN INTENT, not overriding it. The button carries
 * `self-start` with an `md:self-center` meant to take over above 768px, and that
 * override was not winning — computed align-self read flex-start at every width.
 * The bar itself is align-items: center, so everything else on it — the promo
 * wording, the app icon, the close cross — centres on the same line and the
 * button alone sat 3px above them.
 *
 * Scoped to the same 768px the plugin's own `md:` prefix uses, confirmed by
 * measuring rather than assumed: at 785 the button's wrapper computes display
 * contents and the button is 132px wide; at 700 the wrapper is a column flex and
 * the button spans the row. Below that breakpoint the button is full width on its
 * own line, where align-self has nothing to do — so this changes nothing on a
 * phone, exactly as the plugin intended.
 */
@media (min-width: 768px) {
	#etick-homepage-alert-cta {
		align-self: center;
	}
}

/* ==========================================================================
   Header
   ========================================================================== */

.etick-header {
	position: sticky;
	top: 0;
	z-index: 20;
	border-bottom: 1px solid var(--wp--preset--color--additional);
	background: var(--wp--preset--color--background);
}

.etick-header .wp-block-site-logo img {
	max-height: 44px;
	width: auto;
}

.etick-header .wp-block-navigation {
	gap: var(--wp--preset--spacing--40);
}

.wp-block-site-logo a,
a:has(img) {
	border: none;
}

@media (max-width: 781px) {
	.etick-header .wp-block-navigation {
		justify-content: flex-end;
	}
}

/* --- Mobile menu toggle ---
   Core hands the menu to the toggle button below 600px; this header — and every
   stacked-column rule below — collapses at 782px instead. The 600-781.98px band
   is the gap: an inline row with no room left in it. Re-hide the container and
   re-show the button across that band so the hand-over happens once, at the
   width the rest of the header already uses. Fractional max so a device pixel
   ratio landing between the two integers cannot show neither state.
   Both selectors carry .etick-header to out-specify core and to leave any
   navigation block placed in page content alone. */

@media (min-width: 600px) and (max-width: 781.98px) {
	.etick-header .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
		display: none;
	}

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

.etick-header .wp-block-navigation__responsive-container-open {
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	border-radius: var(--wp--custom--radius--card);
	color: var(--wp--preset--color--primary);
}

.etick-header .wp-block-navigation__responsive-container-open:hover {
	color: var(--wp--preset--color--accent);
}

.etick-header .wp-block-navigation__responsive-container-open:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}

/* --- Submenus --- */

.wp-block-navigation ul.wp-block-navigation-submenu {
	background: var(--wp--preset--color--background) !important;
	border: 1px solid var(--wp--preset--color--additional) !important;
	border-radius: 12px !important;
	overflow: hidden !important;
}

.wp-block-navigation .wp-block-navigation-submenu li a {
	color: var(--wp--preset--color--primary) !important;
}

.wp-block-navigation li a:hover {
	color: var(--wp--preset--color--accent) !important;
}

/* --- Mobile menu drawer ---
   Core's overlay is one fixed full-screen box. Rather than fork its markup, the
   two elements it already nests take the two jobs a drawer needs: the fixed
   container becomes the scrim, and the __responsive-close wrapper inside it
   becomes the panel, pushed to the right edge.

   Core's padding on the open container computes to 0 in this theme. It is
   written clamp(1rem, var(--wp--style--root--padding-*), 20rem), and nothing
   here defines root padding, so the invalid var() drops the whole declaration
   to its initial value and beats the theme rule that used to sit at this spot.
   That is why the links sat flush against the edge of the screen. The padding
   now lives on the panel, where no undefined variable can reach it.

   Selectors mirror core's own specificity plus .etick-header, because core
   colours the open overlay through .wp-block-navigation:not(.has-background)
   — five classes. Anything shorter loses on load order. */

/* Core's scroll lock is `html.has-modal-open { overflow: hidden }`, applied the
   instant the menu opens. On a browser whose scrollbar takes up space — Chrome
   and Edge on Windows, which is where this was reported — removing it widens the
   layout viewport by the scrollbar's width, and the drawer is anchored to the
   right edge of that viewport, so it moves right by exactly that much as it
   arrives. Reserving the gutter for as long as the lock is on keeps the width
   constant and the drawer still.

   Scoped to .has-modal-open, so ordinary browsing on every page is untouched;
   and where scrollbars are overlays and take no space — phones, iOS — the gutter
   is zero and this changes nothing, measured. */

html.has-modal-open {
	scrollbar-gutter: stable;
}

/* .etick-header is sticky with z-index 20, so it is a stacking context: the
   drawer inside it is pinned at level 20 whatever z-index core gives the
   overlay. The booking plugin's home-page layers run as high as 1000012, which
   is why the search card painted straight through the open menu and left the
   page looking half covered. Lift the whole header while the drawer is open —
   above every in-page layer, and deliberately below the plugin's own member
   drawer at 2147483646/7, a separate modal that must keep winning when it is
   the one open. */

.etick-header:has(.wp-block-navigation__responsive-container.is-menu-open) {
	z-index: 1000015;
}

.etick-header .wp-block-navigation__responsive-container.is-menu-open {
	display: flex;
	flex-direction: row;
	align-items: stretch;
	justify-content: flex-end;
	padding: 0;
	overflow: hidden;
	height: 100vh;
	height: 100dvh;
}

.etick-header
	.wp-block-navigation:not(.has-background)
	.wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) {
	background-color: rgba(0, 0, 0, 0.45);
}

.etick-header .is-menu-open .wp-block-navigation__responsive-close {
	width: min(320px, 86vw);
	max-width: none;
	height: 100%;
	margin-left: auto;
	margin-right: 0;
	padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--40);
	overflow-y: auto;
	background: var(--wp--preset--color--background);
	color: var(--wp--preset--color--primary);
	border-left: 1px solid var(--wp--preset--color--additional);
	box-shadow: -16px 0 40px rgba(0, 0, 0, 0.18);
}

/* No motion on opening, by the owner's decision in Q-P014-9.

   The drawer used to slide in from the right over 200ms. Across four rounds the
   owner reported it arriving offset and shuffling sideways into place, on a
   phone preview and in an ordinary window alike, and none of the explanations
   tried here survived measurement. Rather than guess a fifth time, the movement
   is removed outright: the panel simply appears where it belongs, hard against
   the right edge.

   Core's own overlay animation also has to go, and not only its opacity — its
   first keyframe is translateY(.5em), which is a real 8px vertical shift and is
   almost certainly the "appears from bottom to top" the owner described on the
   home page. Replacing core's animation with an opacity-only fade of the same
   length keeps the arrival soft while guaranteeing that nothing on screen
   changes position. Selector carries .etick-header to out-specify core's two
   classes and to leave any navigation block in page content alone.

   Deliberately still inside prefers-reduced-motion: no-preference — a visitor
   who asks for no motion gets core's behaviour, which is no animation at all. */

@media (prefers-reduced-motion: no-preference) {
	.etick-header .wp-block-navigation__responsive-container.is-menu-open {
		animation: etick-drawer-fade 100ms ease-out;
	}
}

@keyframes etick-drawer-fade {
	from {
		opacity: 0;
	}

	to {
		opacity: 1;
	}
}

/* --- Drawer contents ---
   Every selector below hangs off .is-menu-open, so none of it can reach the
   desktop row. Core lays the open overlay out itself and its own selectors run
   to four classes, so each rule here carries .etick-header plus the container
   class to land above core on specificity rather than on !important.

   Two of core's choices are what made the links small and bunched to the right.
   The nav is items-justified-right, which sets
   --navigation-layout-justification-setting to flex-end, and core feeds that
   variable to align-items on both the list and each row; and the link font size
   comes from theme.json's core/navigation rule, which asks for `small` — right
   for header trim, wrong for the primary control of a drawer. */

.etick-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content,
.etick-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
	align-items: stretch;
	gap: 0;
	width: 100%;
}

/* The panel scrolls its links, not itself: core pins the close cross to the top
   of the dialog with position:absolute, so a panel that scrolled as one piece
   would carry the cross off screen once the menu is long enough. Give the
   scrolling job to the content instead and the cross stays put. */

.etick-header .is-menu-open .wp-block-navigation__responsive-close {
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

.etick-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-dialog {
	display: flex;
	flex-direction: column;
	flex: 1;
	min-height: 0;
}

.etick-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
	flex: 1;
	min-height: 0;
	overflow-y: auto;
}

/* One row per link, a hairline between them and none after the last. */

.etick-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item {
	align-items: stretch;
	border-bottom: 1px solid var(--wp--preset--color--additional);
}

.etick-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:last-child {
	border-bottom: 0;
}

.etick-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item > .wp-block-navigation-item__content {
	display: flex;
	align-items: center;
	box-sizing: border-box;
	width: 100%;
	min-height: 44px;
	padding: var(--wp--preset--spacing--10) 0;
	font-size: var(--wp--preset--font-size--normal);
}

/* Where you are. Colour alone would not carry, so the weight moves too. */

.etick-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item.current-menu-item > .wp-block-navigation-item__content {
	color: var(--wp--preset--color--accent);
	font-weight: 700;
}

/* Submenus. Core already flattens its own overlay submenus — static position,
   no border, transparent background, icon hidden — so all that is left here is
   to indent the children by a theme step instead of core's flat 2rem, and to
   make sure no radius survives from a dropdown rule. The theme's submenu card
   rules further up target ul.wp-block-navigation-submenu, which core never
   emits on a ul, so they could never reach the drawer and are left alone.
   render_menu() emits only wp:navigation-link, so the header cannot produce a
   submenu today either; this keeps the drawer honest if it ever does.
   Core's own indent rule carries five classes, so this one carries six. */

.etick-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content .has-child .wp-block-navigation__submenu-container {
	padding-left: var(--wp--preset--spacing--30);
	padding-right: 0;
	border-radius: 0;
}

/* The close cross, given the same tap target and focus ring as the open button. */

.etick-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close {
	display: flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	border-radius: var(--wp--custom--radius--card);
	color: var(--wp--preset--color--primary);
}

.etick-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close:hover {
	color: var(--wp--preset--color--accent);
}

.etick-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-close:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}

/* ==========================================================================
   Sections
   ========================================================================== */

/*
 * Sections carry their own block padding and main declares blockGap 0, so the band a
 * visitor sees between two rows is this value twice — the seam is padding-bottom meeting
 * padding-top, not a gap anybody set. Read these numbers doubled: at 1280 the 50 preset
 * is 48px, so a seam is 96px. CR-P043 stepped both rules down one preset from 60/50
 * (which showed as a 144px seam) on the owner's answer to Q-P043-1.
 *
 * --tight has to keep exactly one preset of daylight below the base. Set it to the same
 * preset and the modifier stays in the markup styling nothing, and the one row meant to
 * sit tighter than the rest silently stops doing so.
 *
 * THE TWO VALUES ARE HELD IN CUSTOM PROPERTIES rather than written straight into padding, and
 * that is load-bearing since CR-P058 T-B. The sections are alignfull now, and the booking
 * plugin's front-end stylesheet carries a blanket `.alignfull { padding: 0 !important }` below
 * 1080px — the same rule the hero has always had to work around. Only an !important can answer
 * an !important, so one rule further down re-applies the padding in that band. Holding the
 * numbers in properties is what lets that rule say `var(--etick-section-pad-top)` instead of
 * repeating these presets, so there is still exactly one place each number is written. Change a
 * value here and the override follows it; write a number into the override instead and the two
 * drift apart the first time anybody edits one.
 */
.etick-section {
	--etick-section-pad-top: var(--wp--preset--spacing--50);
	--etick-section-pad-bottom: var(--wp--preset--spacing--50);

	padding-block: var(--etick-section-pad-top) var(--etick-section-pad-bottom);
}

.etick-section--tight {
	--etick-section-pad-top: var(--wp--preset--spacing--40);
	--etick-section-pad-bottom: var(--wp--preset--spacing--40);
}

/*
 * A centred section header (CR-P048 T-C, item 6; reused by T-E and T-F).
 *
 * THE HEADER, NOT THE SECTION. Only the heading and a paragraph sitting directly under it are
 * centred; whatever the content plugin draws below keeps the alignment the plugin gives it. The
 * owner asked for three headers to be centred, and centring a whole row is a different and much
 * larger change than the one that was asked for.
 *
 * The direct-child combinator is what keeps it that small. Without it this would reach every
 * heading and paragraph the plugin renders inside its own cards, and a row of left-aligned
 * destination cards would silently become a row of centred ones.
 *
 * THE EYEBROW IS NAMED SEPARATELY because it sits ABOVE the heading (CR-P048 T-F). The two
 * selectors above reach a heading, and a paragraph directly after one, which is the shape both
 * T-C and T-E have. The terminal section puts its eyebrow first instead, so it matches neither,
 * and without this line it would be the one thing in a centred header still sitting against the
 * left edge. Still a direct child, so the rule stays as narrow as it was.
 */
.etick-section--centred > :is(h2, h3),
.etick-section--centred > :is(h2, h3) + p,
.etick-section--centred > .etick-eyebrow {
	text-align: center;
}

/*
 * The eyebrow — a heading that does not look like one (CR-P048 T-E, item 8; reused by T-F).
 *
 * Small, uppercase and widely letter-spaced, read off the artwork the owner supplied for the bus
 * partner strip and the terminal section. It is applied to a real <h2> rather than to a paragraph
 * dressed up as one, because both sections had a heading and screen readers navigate by headings:
 * a header made visually smaller should not vanish out of the page's outline.
 *
 * NO COLOUR IS SET HERE. The bus partner eyebrow takes the body colour and the terminal one takes
 * the palette's accent, so the colour is chosen per use in the markup rather than baked in - each
 * site picks its own palette and this file is shared by all of them.
 *
 * The letter-spacing adds a trailing gap after the last letter, which reads as an off-centre line
 * when the text is centred. The negative margin-right of the same size takes it back.
 */
.etick-eyebrow {
	font-weight: 600;
	line-height: 1.4;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	margin-right: -0.12em;
}

/*
 * The bus partner logos on phones (CR-P063).
 *
 * THE GAPS ABOVE AND BELOW THE LOGOS WERE EMPTY PICTURE BOX, NOT SPACING. The content plugin pins
 * .etick-content__image to a flat 160px at 768px and under, whatever height the tool asks for, and
 * this tool asks for 100px. The logos are wide and short and centred in their box (CR-P114), so at
 * 375px the tallest drew 76px high in a 160px box and the title-to-logo and logo-to-link gaps both
 * read 74px, against 41px on a computer. The block's own spacing (24px plus the slide's 7px) was
 * never the problem and is left alone, so it stays a setting the editor can change.
 *
 * This hands the box back the tool's own height, so the Image height on the tool's form is what a
 * phone shows too. Same breakpoint as the plugin's pin, so nothing above 768px is touched. The 160px
 * fallback is the plugin's pinned value, for a tool that prints no height at all.
 */
@media (max-width: 768px) {
	.etick-bus-partners .etick-content__image {
		height: var(--etick-image-h, 160px);
	}
}

/*
 * The app download band (CR-P048 T-D, item 5; made a card in CR-P062 T-B).
 *
 * ALMOST NONE OF THIS SECTION'S LOOK IS IN THIS FILE, AND THAT IS THE POINT. The card's colour,
 * border, corners, padding and shadow, the label above the heading, the colour on RM30, the
 * outline round the points line and the width of the store-button row are all block settings in
 * parts/rewards.html, so a site can change every one of them from the editor sidebar - which is
 * what the owner asked for. Only what a block cannot express lives here. Do not move a setting
 * from the markup into this file to "tidy" it; that takes it out of the sidebar.
 *
 * The flyer is 660px wide and must never be drawn larger than that - upscaling a photograph of
 * artwork is where this section would look cheap. It is a max, not a width, so the picture still
 * shrinks with its column; below about 782px core stacks the two columns, words first, and the
 * picture takes the full width of the card, where the cap centres it rather than leaving it hard
 * against the left edge.
 *
 * The card's height comes from the taller of the two columns and is not set here. Both columns
 * are vertically centred against each other in the markup, so the words sit beside the middle of
 * the picture rather than at its top.
 */
.etick-appdl__flyer {
	margin-inline: auto;
}

.etick-appdl__flyer img {
	max-width: 660px;
	width: 100%;
	height: auto;
}

/*
 * RM30 keeps its colour through an editor save; its transparent background may not (CR-P062 T-B).
 *
 * The editor's own text-colour format writes the colour as a class and the background as an
 * inline rgba(0, 0, 0, 0). WordPress's post filter strips any inline value with brackets in it for
 * a user without unfiltered_html - on a multisite, every site admin who is not a super admin - so
 * the first time such a user saves this part the rgba goes, and the browser paints its default
 * yellow highlight behind RM30. This puts transparent back. A background a site picks on purpose
 * still wins, because an inline style outranks any selector.
 */
.etick-appdl mark.has-inline-color {
	background-color: transparent;
}

/*
 * The row under the search card, asymmetric on the owner's ask (CR-P044): less below than the
 * base so it runs into the next row sooner.
 *
 * THE TOP WAS THE 60 PRESET UNTIL CR-P048 T-B (item 3), a preset ABOVE the base, put there so
 * the search card was not sitting on the "Why book with us" heading. That heading is gone, on
 * the same owner's later instruction, and the extra air went with it: a row that starts with a
 * heading needs the card held off it, a row that starts with its own content does not. Back at
 * the base 50 the gap reads as one seam like every other on the page. This is a reversal of one
 * half of CR-P044 and it is deliberate - it is what the same gap looks like without a heading in
 * it, not a regression, and nobody should "restore" the 60 without restoring the heading too.
 *
 * The bottom half is untouched and is still CR-P044's.
 *
 * Matched on the bare .etick-searchbar, NOT .etick-searchbar--overlap. front-page.php only
 * adds the modifier when the banner is switched on; with the banner off the card is still
 * here and still wants this spacing.
 *
 * ORDER IS LOAD-BEARING: this must stay above the 561-900 media query further down, which
 * gives this same element padding-top: 132px to clear the wrapped search card (CR-P008).
 * The two selectors weigh the same, so source order is the only thing keeping that
 * clearance. Move this below it and the card overlaps the row in that band.
 */
.etick-searchbar + .etick-section {
	--etick-section-pad-top: var(--wp--preset--spacing--50);
	--etick-section-pad-bottom: var(--wp--preset--spacing--40);
}

/*
 * What the booking plugin takes away below 1080px, given straight back (CR-P058 T-B).
 *
 * That plugin's front-end stylesheet carries a blanket `.alignfull { padding: 0 !important }`
 * inside `@media (max-width: 1080px)`. The hero has worked around it since CR-P020 — see the
 * comment on .wp-block-group.etick-hero.alignfull — and the sections walked into the same trap
 * the moment CR-P058 T-B made them full width so their bands could reach both edges. Below
 * 1080px every one of them lost all four sides at once: no rhythm between rows, and words flat
 * against the edge of a phone screen.
 *
 * Only an !important answers an !important, so this restates the padding rather than raising
 * specificity. NO NUMBER IS REPEATED HERE: the block values come from the custom properties set
 * further up, so a section keeps whatever padding its own modifiers gave it - base, --tight, the
 * asymmetric one under the search card - and the horizontal value is the same preset the block
 * markup carries inline.
 *
 * Scoped to the plugin's own breakpoint on purpose. Above 1080px nothing is being stripped, so
 * nothing needs an !important, and the ordinary rules are left to do their job.
 */
@media (max-width: 1080px) {
	.wp-block-group.etick-section.alignfull {
		padding:
			var(--etick-section-pad-top)
			var(--wp--preset--spacing--30)
			var(--etick-section-pad-bottom) !important;
	}
}

/*
 * Core sets margin-block-start on every child of a constrained layout and cancels it on
 * :first-child, since nothing sits above the first thing. The booking plugin prints an
 * inline <style> as the section's first child, which pushes the real content out of
 * :first-child, so it keeps a 24px gap meant to hold it off a heading that is not there.
 * The row then sits low in its own band — 72px above its contents against 48px below.
 *
 * Aimed at the cause rather than at the two rows that show it today (the review row and
 * the partner strip, both headingless by design), so a third one cannot arrive broken.
 */
.etick-section > style:first-child + * {
	margin-block-start: 0;
}

/*
 * .etick-hero-part is the wrapper core puts around the banner template part (CR-P020 T-B).
 * Before the banner moved into a part it was a direct child of main and the search card's
 * sibling, so these rules could say `.etick-hero:has(+ .etick-searchbar--overlap)`. It is a
 * grandchild now, so the adjacency is tested on the wrapper and the padding applied to the
 * band inside it. render_block_core_template_part() always emits that wrapper - it falls
 * back to the area tag when tagName is absent, never to nothing - so the class is reliable.
 */

/*
 * No gap between the menu and the banner on the pages that are not the home page (CR-P040).
 *
 * On an inner page the banner is a TOP-LEVEL block: patterns/site-banner.php emits it between
 * the header and main, so its wrapper is a direct child of .wp-site-blocks and WordPress puts
 * its site-wide block gap above it - measured at 24px against a --wp--style--block-gap of 24px,
 * which is the whole of the reported gap. On the home page the same wrapper sits INSIDE main,
 * which patterns/front-page.php declares with blockGap 0, so nothing is added there and the
 * banner has always been flush.
 *
 * THE DIRECT-CHILD COMBINATOR IS LOAD-BEARING, not tidiness. .etick-hero-part is the wrapper on
 * the home page too, one level deeper; a bare .etick-hero-part rule would reach it and make the
 * home page's flush banner depend on this rule rather than on main's own blockGap. Scoped to a
 * direct child it can only ever match the inner-page case, so the home page stays right by
 * construction. Do not "simplify" this selector.
 *
 * WHY NOT PUT THE BANNER BACK INSIDE main: because main carries top padding on every inner
 * template, which is what CR-P036 T-C moved it out to avoid. Closing the gap here is the other
 * half of that decision rather than a reversal of it.
 */
.wp-site-blocks > .etick-hero-part {
	margin-top: 0;
}

/* --- Hero band runs edge to edge, content stays in the column --- */

/*
 * The booking plugin's front-end stylesheet carries a blanket
 * `.alignfull { padding: 0 !important }` inside `@media (max-width: 1080px)`,
 * which strips the padding the hero declares in its own block markup and pushes
 * the headline against the viewport edge. Restated here with matching weight and
 * higher specificity so it wins whichever stylesheet loads last. Keep these
 * values in step with the padding on the hero group in patterns/front-page.php.
 *
 * The +30px on each vertical side is CR-P020 T-A: the owner asked for a banner
 * about 60px taller (Q-P020-1). It is added to the presets rather than replacing
 * them so the band still scales with the viewport - the presets are clamps, and a
 * flat value would hand a phone the same padding as a desktop. Measured 248px to
 * 308px at 1265px wide.
 */
.wp-block-group.etick-hero.alignfull {
	padding:
		calc(var(--wp--preset--spacing--50) + 30px)
		var(--wp--preset--spacing--30)
		calc(var(--wp--preset--spacing--60) + 30px) !important;
}

/*
 * The banner's words line up with every section under them (CR-P048 T-A, item 1).
 *
 * The two disagreed by exactly 24px and both were behaving as written. A section is a
 * constrained group INSIDE main, so main limits it to the 1120px content column and the
 * section then adds its own --wp--preset--spacing--30 of padding inside that - its words
 * start 24px in from the column edge. The banner is alignfull, so it spans the window and
 * centres its own 1120px column across the whole of it - its words start AT the column edge.
 * Measured at a 1280 window before this rule: headline 73px from the left, section headings 97.
 *
 * The banner gives way rather than the sections, because the sections' padding is what keeps
 * their words off the edge of a phone screen. Narrowing the banner's inner column by that
 * padding on each side lands both at the same place at every width, with no magic number -
 * the rule is written in the same two variables the discrepancy is made of.
 *
 * EVERY DIRECT CHILD, not the columns block by name. The banner is editable (CR-P020 T-B) and
 * a site that has rewritten it may have no columns block in there at all; this has to hold for
 * whatever that site arranged. The :where() copies core's own constrained-layout selector so
 * an aligned child still escapes the column exactly as core intends.
 *
 * Specificity is why this wins: core emits its rule as .wp-container-<hash> > :where(...),
 * one class, and this is three. It does not need !important and should not be given one.
 *
 * EVERY SECTION SHARES THIS RULE SINCE CR-P058 T-B, and sharing it is the point rather than
 * tidiness. The sections became alignfull so their background bands reach both edges of the
 * screen instead of stopping at the text column, and the moment a section goes full width it
 * inherits the banner's exact problem: its own horizontal padding leaves the 1120 column and its
 * words slide 24px left. One rule covering both is what stops the banner and the sections drifting
 * apart again - the fault CR-P048 T-A existed to fix and the owner signed off in Q-P048-3.
 *
 * A section that is NOT alignfull is untouched by this and still lands in the same place, because
 * a constrained section's padding sits inside the column and reaches the same 97px. Both shapes
 * therefore agree, which is what allows a section to be switched between them safely.
 */
.wp-block-group.etick-hero.alignfull > :where(:not(.alignleft):not(.alignright):not(.alignfull)),
.wp-block-group.etick-section.alignfull > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
	max-width: calc(var(--wp--style--global--content-size) - 2 * var(--wp--preset--spacing--30));
}

/*
 * The banner with its words left off, on the inner pages only (CR-P037 T-A).
 *
 * EVERY CHILD OF THE BAND, not the heading and paragraph by name. On a site that has edited its
 * banner the contents are whatever that site arranged - a different heading, extra blocks, no
 * columns at all - so naming the blocks would work on an untouched banner and quietly fail on an
 * edited one, which is the half this feature exists to get right. Hiding the band's children
 * makes no assumption about what they are.
 *
 * THE PICTURE SURVIVES because it was never a child: it is a background-image on the band itself,
 * set from --etick-hero-bg by Etick_Dynamic_Styles. So is the shade. What goes is only what was
 * written on top.
 *
 * THE HEIGHT IS THE BAND'S OWN PADDING, declared above on .etick-hero.alignfull, so the band
 * still occupies a band's worth of the page with nothing in it.
 */
.etick-hero-part--wordless .wp-block-group.etick-hero > * {
	/*
	 * HIDDEN BUT STILL TAKING UP ITS SPACE, and the difference is the whole of CR-P039.
	 *
	 * display: none was the first attempt (CR-P037 T-A) and it took the words' HEIGHT away with
	 * them, so the band fell from 260px to 180px and stopped matching the banner on the home
	 * page - which is what the owner reported. visibility: hidden leaves the box exactly where it
	 * was and only stops it being drawn, so the wordless band is the same height as the same
	 * banner with its words, at every width, on every site, whatever a site has written in it.
	 *
	 * A MIN-HEIGHT WAS THE OTHER WAY AND IS WORSE. It needs a number per breakpoint, and the
	 * number is not one number: measured with the words in, this band is 260px at 1280 and 212px
	 * at 375, because the padding presets clamp and the wording wraps differently. Any single
	 * value is wrong at one end, and every value goes stale the moment the padding or the
	 * headline changes. This has nothing to keep in step.
	 *
	 * IT STILL HIDES PROPERLY. visibility: hidden takes the words out of the accessibility tree
	 * and out of tab order exactly as display: none did, so nothing is read out or focusable that
	 * a visitor cannot see - which was the point of the switch.
	 */
	visibility: hidden;
}

/*
 * The banner with its words left off on phones, on every page including the home page (CR-P068
 * T-A, Q-P068-2). The rule above, narrowed to the phone breakpoint the banner already uses, and for
 * the same reasons: every child of the band so an edited banner is covered, visibility rather than
 * display so the band keeps the height it has with words (CR-P039). At 782px and above nothing here
 * applies, so computers keep their words.
 */
@media (max-width: 781px) {
	.etick-hero-part--phone-wordless .wp-block-group.etick-hero > * {
		visibility: hidden;
	}

	/*
	 * The banner's words held to the left half on phones (CR-P068 T-B). Q-P068-1: "the banner show
	 * full, only the text halves" - so the band, its colour and its picture are left exactly as
	 * they are, and only what is written on top is narrowed. Every direct child, for the edited-
	 * banner reason above.
	 *
	 * 50% OF THE BAND'S CONTENT BOX, from its left padding. The max-width outranks the column rule
	 * above (.wp-block-group.etick-hero.alignfull > :where(...), three classes) on specificity. The
	 * margins need !important because core's constrained layout centres children with
	 * margin-left and margin-right auto !important; left as it is, the half-width words would sit
	 * in the middle of the band rather than on its left.
	 */
	.etick-hero-part--phone-half .wp-block-group.etick-hero.alignfull > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
		max-width: 50%;
		margin-left: 0 !important;
		margin-right: auto !important;
	}
}

/* --- Optional photo behind the hero band --- */

/*
 * Only reached when a site has switched a banner picture on. Which picture arrives as
 * --etick-hero-bg from Etick_Dynamic_Styles, because that is per-site and this file is shared by
 * every site on the network.
 *
 * The shade sits above the photo in the same background-image list rather than on a pseudo-element,
 * which keeps it out of the z-index fight with .etick-searchbar--overlap (z-index: 5) sitting on
 * this band. The palette colour stays declared in the block markup underneath, so a slow or failed
 * image load shows the plain band rather than white.
 *
 * Matched on .alignfull for the same reason the padding rule above is: the booking plugin's
 * stylesheet is heavy-handed about this band, so the theme states its case with equal specificity.
 *
 * The strong end holds to 55% rather than easing off immediately, because the text column is the
 * left 60% and the intro paragraph is the palest thing in it. That was settled against the photo
 * bundled at the time, hero-background.jpg: easing from 0% dropped the intro to 3.9:1 at the right
 * of its own column, under the 4.5:1 needed; holding to 55% put it at 6.4:1.
 *
 * Re-measured for CR-P025, which changed the bundled picture to website-banner.webp. Sampled per
 * pixel under the real glyph boxes on the live home page, compositing this gradient over the
 * picture exactly as declared here. Desktop, 1440px viewport, band 1425x309: headline 7.85:1 at
 * its worst pixel, intro 6.33:1. Narrow, 375px viewport, band 375x298 under the flat rule below:
 * headline 12.29:1, intro 10.24:1. All four clear 4.5:1, so holding to 55% survives the swap.
 *
 * What does not clear it is the right-hand end of the band, where the shade has eased to 0.42: the
 * brightest pixel there measures 3.15:1 against white at 1440px. Nothing the theme puts in the band
 * reaches that far - the intro ends at 43% of the band width - but CR-P020 made the band editable,
 * so a site that drops text into its right end lands under 4.5:1. That is not new and not this
 * picture's doing: the same measurement against the old photo gives 3.18:1. The shade is fixed,
 * the picture is not.
 *
 * ## What replaced it, and what it is still here for (CR-P026 T-C, then CR-P028 T-A, twice)
 *
 * The owner asked for the shade to come off the picture (Q-P026-1) and chose, of the three ways
 * out, to keep the words where they are and put them on a solid panel. Q-P028-1 then took the
 * panel away as well and chose the way out CR-P026 had not: move the words below the picture, and
 * for one change the band the theme writes carried no words at all.
 *
 * The words did not stay below the picture. Q-P028-3 and Q-P028-4 asked for them back on it, and
 * Q-P028-5 chose the third of the ways out CR-P028 had set out: a dark edge drawn tight around
 * every line, so the picture shows through all around the letters. The band is one band again, the
 * words are on the picture again, and etick-hero--unshaded is what cancels the gradient below.
 * Whether the words then get a dark edge is a per-site choice (Q-P030-11), which is why those are
 * two classes rather than one: switching the edge off must not hand the band its wash back.
 *
 * This rule is not dead, and deleting it would be a readability regression on real sites. It still
 * runs on every band the theme cannot vouch for: a site that edited its banner keeps the markup it
 * saved, words and all, and CR-P020 Q-P020-4 put the editor in charge from the first edit. Those
 * words sit straight on the picture, and this gradient is the only thing between them and it. The
 * measurements above are theirs now.
 *
 * That covers banners edited before CR-P026 and banners edited after it alike, and the second case
 * is the one worth spelling out. A banner saved between CR-P026 and CR-P028 has etick-hero--panel
 * and a .etick-hero__panel div frozen into its markup. Renaming the class this rule is cancelled
 * by hands those banners their shade back, and dropping the panel fill below leaves their words
 * sitting on it - which is exactly the state CR-P020 measured at 7.85:1 and 6.33:1. They lose an
 * opaque box they had for two changes and are readable without it. There is no ordering of those
 * two edits that leaves a stored banner with the shade gone and its words bare.
 */
.wp-block-group.etick-hero--image.alignfull {
	background-image:
		linear-gradient(
			to right,
			var(--wp--custom--hero--shade-strong) 0%,
			var(--wp--custom--hero--shade-strong) 55%,
			var(--wp--custom--hero--shade-soft) 100%
		),
		var(--etick-hero-bg);
	/*
	 * Which part of the picture survives the crop (CR-P030 T-A). --etick-hero-focus is per-site and
	 * arrives from Etick_Dynamic_Styles, and only from sites that have moved it: center is both the
	 * fallback here and the value the setting defaults to, so a site that has never touched it is
	 * positioned by this line exactly as it always was.
	 */
	background-position: var(--etick-hero-focus, center);
	background-repeat: no-repeat;
	background-size: cover;
}

/*
 * Below 782px the columns stack and the text runs the full width, so a shade that lightens towards
 * the right would leave the end of the intro sitting on bare photo. Flat and strong instead.
 */
@media (max-width: 781px) {
	.wp-block-group.etick-hero--image.alignfull {
		background-image:
			linear-gradient(
				var(--wp--custom--hero--shade-strong),
				var(--wp--custom--hero--shade-strong)
			),
			var(--etick-hero-bg);
	}
}

/* --- The words' dark edge, and the shade coming off where it applies (CR-P028 T-A) --- */

/*
 * Q-P026-1 took the shade off the picture. etick-hero--unshaded is the class
 * Etick_Banner_Part::markup() puts on a band it wrote - there and nowhere else - and it is what
 * makes taking the shade off safe. An edited banner never reaches markup(), so it never gets this
 * class, so this rule never fires on it and the gradient above keeps doing its job over words that
 * have nothing else between them and the photo.
 *
 * It used to be the same class that drew the words' dark edge. CR-P030 T-C split them, because
 * Q-P030-11 made the edge a per-site choice and one class doing both jobs would have meant
 * switching the edge off also handed the band its wash back - which Q-P025-1 asked to be rid of.
 * The promise that used to be "the shade cannot go without the edge arriving" is therefore gone,
 * knowingly: a site may now choose words on a bare picture, and the wizard states what that costs.
 *
 * Restating the whole background-image rather than unsetting it, because the shade and the picture
 * share one layer list; there is no property that drops the first layer and keeps the second. The
 * flat-shade override for narrow viewports is matched too - it is the same declaration on the same
 * element at one class less specificity, so without this it would come back below 781px and put the
 * shade over the picture on exactly the phones that most need the picture unobscured.
 */
.wp-block-group.etick-hero--image.etick-hero--unshaded.alignfull {
	background-image: var(--etick-hero-bg);
}

/*
 * The edge itself, and the whole of what Q-P028-5 chose.
 *
 * A real 2px outline around every glyph in an opaque dark colour, so the pixels immediately
 * around every letter are that colour and nothing else, whatever the picture does. Then one
 * blurred copy underneath, which is what stops the ring reading as a hard sticker cut out of
 * the page.
 *
 * IT WAS EIGHT OFFSET COPIES OF THE TEXT until CR-P048 T-A (item 2) - one nudged 2px in each
 * of the eight compass directions. Eight copies approximate a circle, and an approximation is
 * exactly what the owner could see: zoom in and the gaps between the eight positions show up
 * as scallops around the curve of each letter, which was reported as the edge looking "dotty".
 * Adding more copies would only move the zoom level at which it shows. A stroke is computed by
 * the browser from the glyph outline at whatever size the letter is actually being drawn, so
 * it is smooth at any zoom, on any font, at any size, by construction rather than by having
 * enough copies.
 *
 * PAINT-ORDER IS LOAD-BEARING, not a nicety. -webkit-text-stroke paints the stroke OVER the
 * fill by default, and a stroke is centred on the outline, so half of it eats into the letter
 * and the text comes out thin and clogged at small sizes. `paint-order: stroke fill` puts the
 * stroke behind the fill, where only the outer half shows.
 *
 * WHICH IS WHY THE WIDTH IS 4px FOR A 2px EDGE. Half of a centred 4px stroke sits outside the
 * glyph. That 2px is the guarantee Q-P028-5 made to the owner in those words, so the number is
 * not free to change: 2px of solid colour around every letter, and beyond it the picture is
 * untouched - a pale busy photograph can still make the words hard to pick out even though
 * each letter has its own edge. That limit was stated in the question and is repeated here
 * rather than left in the change request.
 *
 * The colour is the same fixed value the shade and the box before it used - the picture's own
 * furniture, dark in all nine palettes - rather than a preset that would go light on a light
 * palette and put white letters on a white edge.
 *
 * Not applied inside the reward card: it sits on its own solid background and keeps the palette's
 * own text colours, exactly as it did under the shade and under the box.
 *
 * TWO SWITCHES, ONE PER SIDE OF THE PHONE BREAKPOINT (CR-P069). hero_text_edge now answers for
 * computers only: etick-hero--edge on the band, read at 782px and up. hero_text_edge_phone answers
 * for phones: etick-hero-part--phone-edge, put on the part's wrapper at render by
 * Etick_Banner_Part::add_wrapper_classes() so a saved template or an edited part is reached, read at
 * 781px and below. The phone rule also asks for etick-hero--unshaded, so it lands on the same bands
 * the computer edge can: ones the theme wrote with a picture. A banner still wearing the dark wash
 * gets no edge on top of it at either width. Phones start with no edge (Q-P069-1: every site, off on
 * phones unless ticked), which on the bundled artwork leaves white words on white - the wizard says so.
 */
@media (min-width: 782px) {
	.etick-hero--edge :is(h1, h2, h3, h4, h5, h6, p, li, cite, figcaption):not(.etick-card *) {
		-webkit-text-stroke: 4px var(--wp--custom--hero--edge, #0C0E12);
		paint-order: stroke fill;
		text-shadow: 0 0 8px var(--wp--custom--hero--edge, #0C0E12);
	}
}

@media (max-width: 781px) {
	.etick-hero-part--phone-edge .etick-hero--unshaded :is(h1, h2, h3, h4, h5, h6, p, li, cite, figcaption):not(.etick-card *) {
		-webkit-text-stroke: 4px var(--wp--custom--hero--edge, #0C0E12);
		paint-order: stroke fill;
		text-shadow: 0 0 8px var(--wp--custom--hero--edge, #0C0E12);
	}
}

/*
 * The eight copies, kept for browsers with no paint-order (CR-P048 T-A).
 *
 * Without the guard a browser that understands -webkit-text-stroke but not paint-order paints
 * the stroke over the fill and thins the letters; one that understands neither drops the edge
 * entirely and leaves white text on a photograph. Losing the edge is a legibility failure, not
 * a cosmetic one, so the old rule stays as the floor rather than being deleted. It scallops
 * under zoom exactly as before - that is the trade, and it is the better one here.
 *
 * Split by the phone breakpoint the same way as the rule above (CR-P069), so a browser on this
 * floor follows the same two switches.
 */
@supports not (paint-order: stroke) {
	@media (min-width: 782px) {
		.etick-hero--edge :is(h1, h2, h3, h4, h5, h6, p, li, cite, figcaption):not(.etick-card *) {
			-webkit-text-stroke: 0;
			text-shadow:
				-2px -2px 0 var(--wp--custom--hero--edge, #0C0E12),
				0 -2px 0 var(--wp--custom--hero--edge, #0C0E12),
				2px -2px 0 var(--wp--custom--hero--edge, #0C0E12),
				2px 0 0 var(--wp--custom--hero--edge, #0C0E12),
				2px 2px 0 var(--wp--custom--hero--edge, #0C0E12),
				0 2px 0 var(--wp--custom--hero--edge, #0C0E12),
				-2px 2px 0 var(--wp--custom--hero--edge, #0C0E12),
				-2px 0 0 var(--wp--custom--hero--edge, #0C0E12),
				0 0 8px var(--wp--custom--hero--edge, #0C0E12);
		}
	}

	@media (max-width: 781px) {
		.etick-hero-part--phone-edge .etick-hero--unshaded :is(h1, h2, h3, h4, h5, h6, p, li, cite, figcaption):not(.etick-card *) {
			-webkit-text-stroke: 0;
			text-shadow:
				-2px -2px 0 var(--wp--custom--hero--edge, #0C0E12),
				0 -2px 0 var(--wp--custom--hero--edge, #0C0E12),
				2px -2px 0 var(--wp--custom--hero--edge, #0C0E12),
				2px 0 0 var(--wp--custom--hero--edge, #0C0E12),
				2px 2px 0 var(--wp--custom--hero--edge, #0C0E12),
				0 2px 0 var(--wp--custom--hero--edge, #0C0E12),
				-2px 2px 0 var(--wp--custom--hero--edge, #0C0E12),
				-2px 0 0 var(--wp--custom--hero--edge, #0C0E12),
				0 0 8px var(--wp--custom--hero--edge, #0C0E12);
		}
	}
}

/*
 * Whole-picture fit (CR-P026 T-B). The band above keeps its own height and crops the picture into
 * it; this one does the opposite - the picture is shown entire and its shape sets the height.
 *
 * Reached only when Etick_Banner_Part::markup() put etick-hero--whole on the band, which it does
 * only when Etick_Home_Sections::hero_bg_ratio() answered with a shape. The same answer is what
 * makes Etick_Dynamic_Styles emit --etick-hero-ratio. So the property is never missing here: the
 * two arrive together or neither does, and a band asked to take its height from nothing - which
 * would collapse it - is not a state this theme can reach.
 *
 * background-size: contain replaces cover for the picture, which is the whole of showing it whole.
 * The shade above it in the same layer list is a gradient, and a gradient has no shape of its own
 * for contain to preserve, so it fills the band as before rather than being letterboxed with the
 * picture. The palette colour underneath is declared in the block markup and stays: aspect-ratio
 * sets a preferred height, not a floor, so a band whose contents are taller than its own shape
 * grows to fit them and letterboxes the picture inside itself, and bare white must not show there.
 *
 * The vertical padding of the band rule above is dropped, and only that - the horizontal padding
 * is what keeps the words off the viewport edge and is as necessary here as anywhere. That padding
 * exists to give the text room to breathe; here the picture decides the height and padding on top
 * of the ratio would only push the words out of the shape they are meant to sit in.
 *
 * Phones stay on the fixed band, which is the owner's answer to Q-P026-2. This picture is 5.5
 * times wider than it is tall, so shown whole at 375px it is a 69px ribbon with roughly 10px
 * lettering drawn into it, under a search card that is around 380px tall there and climbs onto the
 * band by design. That is why the whole thing is a min-width query rather than a phone override:
 * below the boundary none of it applies and the band rules stand exactly as they were, with no
 * padding or sizing restated here to drift out of step with them.
 *
 * The boundary is 768px because that is where the owner's answer put it - phones keep today's
 * band, tablets and desktops show the whole picture - and 768 is tablet portrait. It is deliberately
 * not the 781px this file uses elsewhere for "the columns have stacked": that would hand a tablet
 * the phone's banner, which is not what was chosen. Whether a tablet's search card leaves enough of
 * the picture visible at that width is measured in T-D, not assumed here.
 */
@media (min-width: 768px) {
	.wp-block-group.etick-hero--whole.alignfull {
		/*
		 * width: 100% is load-bearing, not tidiness. A full-bleed band has no width of its own -
		 * core leaves it auto and lets it stretch - and an auto width beside an aspect-ratio is an
		 * invitation for the browser to solve the ratio the other way round and derive the width
		 * from the height. It does exactly that where something else still forces a tall band: at
		 * 768px the search card's clearance rule below holds padding-bottom at 162px, and the band
		 * came out 162 x 1995 / 366 = 883px wide inside a 753px parent, which is a horizontal
		 * scrollbar across the whole page. Pinning the width to the parent's leaves the ratio one
		 * job, the one it is here for: the height.
		 */
		width: 100%;
		aspect-ratio: var(--etick-hero-ratio);
		background-size: contain;
		padding-top: 0 !important;
		padding-bottom: 0 !important;
	}
}

/*
 * Text on a photo has to be light whatever the palette says, because the shade above the photo is
 * dark in all nine. Everything in the band except the reward card, which sits on its own solid
 * background and keeps its palette colours.
 *
 * This used to say `.wp-block-column > h1` and `> p` - direct children of the column only. That
 * was enough while the banner was generated markup nobody could add to. CR-P020 T-B made the band
 * editable, and the first thing added to it was a paragraph below the columns, which no rule
 * reached: it kept its palette grey and measured 4.0:1 against the shade, under the 4.5:1 body
 * text needs, which is what "not showing" looked like on the page. Anything a site adds to the
 * band is covered now, wherever in it they put it.
 *
 * The paragraph needs !important because core prints its preset colour classes with it, and
 * .has-secondary-color would otherwise win.
 *
 * These two rules were briefly reaching edited banners only, while CR-P028 T-A had the words below
 * the picture. Q-P028-3 and Q-P028-5 put them back on it, so they are load-bearing again for every
 * banner the theme writes as well - white on the picture, with the dark edge above drawn around it.
 */
.etick-hero--image :is(h1, h2, h3, h4, h5, h6):not(.etick-card *) {
	color: var(--wp--custom--hero--on-image);
}

.etick-hero--image :is(p, li, cite, figcaption):not(.etick-card *) {
	color: var(--wp--custom--hero--on-image-muted) !important;
}

/*
 * The banner's type sizes, from the owner's banner picture (CR-P071 T-B). Etick_Banner_Part writes
 * them onto the headline and the intro as block styles, so the editor shows and changes them there.
 * Fluid, and the floor matters more than the ceiling: with the words held to half the band on
 * phones (CR-P068) the column at 375 is 156px, and "Malaysia's" has to fit in it unbroken.
 *
 * THE SAME TWO VALUES ARE IN THE PAGE, as Etick_Banner_Part::HEAD_SIZE and INTRO_SIZE, written as
 * the fallback of these properties so a browser holding an older copy of this file still draws
 * the banner big (CR-P072). Change both together.
 */
.etick-hero {
	--etick-hero-head-size: clamp(1.375rem, 0.5rem + 3.9vw, 3.75rem);
	--etick-hero-intro-size: clamp(0.95rem, 0.6rem + 1.1vw, 1.375rem);
}

/*
 * The stock headline's two lines, and the step (CR-P071 T-B). On computers the headline breaks
 * after "Largest", and the second line and the intro start a little right of the first, as the
 * owner's picture draws them (Q-P071-2: "Keep the step, like the picture"). Measured off that
 * picture as about 0.8 of the headline's size. The step goes on the later lines rather than
 * pulling the first one out, so nothing reaches past the band's padding at narrow computer widths.
 *
 * Since CR-P073 T-A each part is the site's choice, for any headline: etick-hero__rows breaks it
 * into its two rows, etick-hero__row2-in pushes the second row in, etick-hero__intro-in pushes an
 * intro line in, each written only when its switch in the setup wizard is on. The push-in stays 0.8
 * of the headline's size.
 *
 * Phones get none of it (Q-P073-3: "Computers only"): the words wrap to fit and line up on one edge.
 *
 * etick-hero__stepped is what CR-P071 wrote for all three at once. The theme no longer writes it,
 * but a banner saved in the site editor while it did keeps it in its markup, so it keeps its look.
 */
@media (min-width: 782px) {
	.etick-hero__rows .etick-hero__line,
	.etick-hero__stepped .etick-hero__line {
		display: block;
	}

	.etick-hero__stepped .etick-hero__line + .etick-hero__line,
	.etick-hero__stepped ~ p {
		padding-left: calc(var(--etick-hero-head-size) * 0.8);
	}

	/*
	 * THE PUSH-INS LINE UP WITH THE PAGE (CR-P079, Q-P079-2: "Line the words up with the logo and
	 * search box too" - was 0.8 of the headline's size, CR-P071). Row 1's ink starts at the header
	 * logo's left edge, row 2's at the search card's and the intro's 0.31 headline sizes past it, as
	 * on a band whose words are sized with the picture (CR-P078). The edges and side bearings are the
	 * ones the scaled block below explains; cqw is the part's wrapper, which is the band's width.
	 *
	 * A fixed band's words sit in the columns block, 1072 wide and centred in the band's padding, so
	 * they start at spacing-30 + max(0, (width - 1120) / 2) - on the logo's edge up to about 1120 and
	 * up to 24px right of it wider (measured 176.3 against the logo's 152.3 at 1440). The words move
	 * left by that difference and by row 1's first-letter bearing, only when they sit on the left.
	 */
	.etick-hero-part {
		container-type: inline-size;
	}

	.etick-hero-part .wp-block-group.etick-hero.alignfull {
		--etick-hero-logo-x: calc(var(--wp--preset--spacing--30) + max(0px, (100cqw - var(--wp--style--global--content-size) - 2 * var(--wp--preset--spacing--30)) / 2));
		--etick-hero-card-x: calc(var(--wp--preset--spacing--30) + 16px + max(0px, (100cqw - var(--wp--style--global--content-size)) / 2));
		--etick-hero-col-x: calc(var(--wp--preset--spacing--30) + max(0px, (100cqw - var(--wp--style--global--content-size)) / 2));
	}

	.etick-hero-part:not(.etick-hero-part--scale, .etick-hero-part--x-center, .etick-hero-part--x-right) .wp-block-group.etick-hero :is(h1, h2, h3, h4, h5, h6, p) {
		position: relative;
		left: calc(var(--etick-hero-logo-x) - var(--etick-hero-col-x) - 0.03125 * var(--etick-hero-head-size));
	}

	.etick-hero__row2-in .etick-hero__line + .etick-hero__line {
		padding-left: calc(var(--etick-hero-card-x) - var(--etick-hero-logo-x) + (0.03125 - 0.0625) * var(--etick-hero-head-size));
	}

	p.etick-hero__intro-in {
		padding-left: calc(var(--etick-hero-card-x) - var(--etick-hero-logo-x) + (0.31 + 0.03125) * var(--etick-hero-head-size) - 0.078125 * var(--etick-hero-intro-size));
	}
}

/*
 * Where the banner's words sit, on computers (CR-P073 T-B). Nine fixed spots (Q-P073-2), read off
 * the classes Etick_Banner_Part::add_wrapper_classes() puts on the part's wrapper. Phones are not
 * touched (Q-P073-3): below 782px none of this applies and the words stay on the left, wrapped.
 *
 * ACROSS is the words' alignment inside the column every section lines up with (CR-P048 T-A).
 * Pushing lines in only makes sense against a left edge, so centre and right take it off.
 *
 * UP AND DOWN MOVES THE WORDS, NOT THE BAND. A band keeps exactly the height it has today, so the
 * search card and everything under it stay where they are. Two kinds of band:
 *
 * - A fixed band (and a whole-picture band at 782-900, where the search card's clearance holds its
 *   foot open) is its padding and the words, with no room to spare. The words move inside that
 *   padding, by a relative offset: --etick-hero-above is the room over them, --etick-hero-below
 *   the room under them down to where the search card starts to cover the band. Top and bottom
 *   leave one spacing-30 (24px) between the words and that edge. Middle is the band's own padding,
 *   which is where the words have always been: 78px over and 65px under at 1280, near enough
 *   centred that no site moves on the day this ships.
 * - A whole-picture band from 901px takes its height from the picture, and the room under the
 *   words is free space. Middle and bottom make the band a flex column and hand that space out,
 *   keeping the words off the part of the band the search card covers (--etick-hero-reach) as far
 *   as the room allows. Top is the band as it has always been.
 *
 * THE NUMBERS ARE TODAY'S, restated: the base padding on .etick-hero.alignfull above, the 162px
 * clearance and the card's reach into the band from the search card rules further down. The card
 * covers the band by half its own height - measured 37px at 1280 (a 74px card) and 108px at 800
 * (216px, wrapped) - which is the plugin's half-drop. Change them together.
 */
@media (min-width: 782px) {
	.wp-block-group.etick-hero.alignfull {
		--etick-hero-above: calc(var(--wp--preset--spacing--50) + 30px);
		--etick-hero-below: calc(var(--wp--preset--spacing--60) + 30px);
		--etick-hero-reach: 0px;
	}

	.etick-hero-part:has(+ .etick-searchbar--overlap) .wp-block-group.etick-hero.alignfull {
		--etick-hero-below: calc(var(--wp--preset--spacing--60) + 30px - 37px);
		--etick-hero-reach: 37px;
	}

	.wp-block-group.etick-hero--whole.alignfull,
	.etick-hero-part:has(+ .etick-searchbar--overlap) .wp-block-group.etick-hero--whole.alignfull {
		--etick-hero-above: 0px;
		--etick-hero-below: 0px;
	}

	.etick-hero-part[class*="etick-hero-part--y-"] .wp-block-group.etick-hero.alignfull > * {
		position: relative;
	}

	.etick-hero-part--y-top .wp-block-group.etick-hero.alignfull > * {
		top: calc(-1 * max(0px, var(--etick-hero-above) - var(--wp--preset--spacing--30)));
	}

	.etick-hero-part--y-middle .wp-block-group.etick-hero--whole.alignfull > * {
		top: calc((var(--etick-hero-below) - var(--etick-hero-above)) / 2);
	}

	.etick-hero-part--y-bottom .wp-block-group.etick-hero.alignfull > * {
		top: max(0px, var(--etick-hero-below) - var(--wp--preset--spacing--30));
	}

	/*
	 * The whole-picture band's free space, handed out by a spacer under the words, not by padding.
	 * Padding counts even where the picture leaves no room, and made the band taller: in T-C a
	 * bottom padding of the card's reach plus 24px took the main site's home band from 185 to
	 * 198px at 901 and an inner page's from 168 to 176px at 820. The spacer (::after) starts at
	 * nothing and may only grow into room that is there, so the band is never taller than today.
	 *
	 * The spacer takes the room first, up to the card's reach (middle) or the reach and 24px
	 * (bottom); whatever room is left goes to the words' auto margins - both for middle, which
	 * centres them over the card, the top one for bottom, which sets them on the spacer. A band
	 * with less room than that simply keeps its words where top would.
	 *
	 * width: 100% because a flex item with auto side margins - which core's constrained layout
	 * gives every child - shrinks to its content; the column's max-width still caps it, so it
	 * lands where it did as a block.
	 */
	.etick-hero-part--y-middle .wp-block-group.etick-hero--whole.alignfull,
	.etick-hero-part--y-bottom .wp-block-group.etick-hero--whole.alignfull {
		display: flex;
		flex-direction: column;
	}

	.etick-hero-part--y-middle .wp-block-group.etick-hero--whole.alignfull::after,
	.etick-hero-part--y-bottom .wp-block-group.etick-hero--whole.alignfull::after {
		content: "";
		flex: 1 1 0;
		max-height: var(--etick-hero-reach);
	}

	.etick-hero-part--y-bottom .wp-block-group.etick-hero--whole.alignfull::after {
		max-height: calc(var(--etick-hero-reach) + var(--wp--preset--spacing--30));
	}

	.etick-hero-part--y-middle .wp-block-group.etick-hero--whole.alignfull > * {
		margin-top: auto;
		margin-bottom: auto;
	}

	.etick-hero-part--y-bottom .wp-block-group.etick-hero--whole.alignfull > * {
		margin-top: auto;
	}

	.etick-hero-part--y-middle .wp-block-group.etick-hero--whole.alignfull > *,
	.etick-hero-part--y-bottom .wp-block-group.etick-hero--whole.alignfull > * {
		width: 100%;
	}

	.etick-hero-part--x-center .wp-block-group.etick-hero :is(h1, h2, h3, h4, h5, h6, p) {
		text-align: center;
	}

	.etick-hero-part--x-right .wp-block-group.etick-hero :is(h1, h2, h3, h4, h5, h6, p) {
		text-align: right;
	}

	.etick-hero-part:is(.etick-hero-part--x-center, .etick-hero-part--x-right) .wp-block-group.etick-hero :is(.etick-hero__line, p) {
		padding-left: 0;
	}
}

/*
 * 782-900, where the search card wraps and the band's foot is held open at 162px for it (below).
 * The card covers 108px of that, so 54px is the room under the words, on either kind of band.
 */
@media (min-width: 782px) and (max-width: 900px) {
	.etick-hero-part:has(+ .etick-searchbar--overlap) .wp-block-group.etick-hero.alignfull,
	.etick-hero-part:has(+ .etick-searchbar--overlap) .wp-block-group.etick-hero--whole.alignfull {
		--etick-hero-below: calc(162px - 108px);
		--etick-hero-reach: 108px;
	}
}

/*
 * The words sized and placed with the picture (CR-P074 T-A), on a whole-picture band on computers.
 * Etick_Banner_Part::add_wrapper_classes() writes etick-hero-part--scale in place of the nine spots
 * when a site ticks it and its band shows the whole picture.
 *
 * EVERY NUMBER IS A SHARE OF THE BAND'S WIDTH, taken from the owner's mock-up (942 x 192, their
 * poster shown whole with 3px cut off the top). A whole-picture band's height is a fixed share of
 * its width, so one unit places the words across and down alike, and the banner looks like the
 * mock-up at every width (Q-P074-2: "Keep growing, exactly like the picture" - no cap). The unit
 * is cqw of the part's wrapper, which is exactly the band's width; vw would count the scrollbar.
 * The wrapper, not the band, is the container because a box cannot size its own padding in
 * units of itself.
 *
 * From the mock-up, measured against Poppins in the browser: headline 38.13px at 942 (4.048%),
 * weight 600 - the two rows' ink widths match 600 to within a pixel, 700 is 2px wider on the
 * first row; intro 17.8px (1.890%), weight 400, pure white. Text starts, ink less each glyph's side
 * bearing: row 1 at 4.66%, row 2 5.18% further in, the intro 6.46% further in (it does not line
 * up with row 2). Baselines at 7.97%, 13.75% and 17.01% down the band. With Poppins' line box
 * (1.05em over the baseline, 0.35em under) that is the padding-top, line-heights and zero intro
 * margin below; T-C measures the result against the mock-up.
 *
 * ACROSS, ROW 1 STARTS AT THE LOGO (CR-P075 T-A, "make join inline with logo"): the header is full
 * width with spacing-30 each side and centres the 1120 content column inside that, so
 * spacing-30 + max(0, (width - 1120 - 2 x spacing-30) / 2). Measured 392.3 at a 1905 band, 72.3 at
 * 1265, 24 at 1009.
 * ROW 2 STARTS AT THE SEARCH CARD (CR-P078, "make the rm30 inline with the search box/form"): the
 * search group sits in main's 1120 column with spacing-30 each side, and the booking plugin's
 * .etick-search-design-2-wrap adds 16px of its own (a plugin number - re-measure if it moves), so
 * spacing-30 + 16px + max(0, (width - 1120) / 2). Measured 432.3, 192.3, 112.3, 40 at 1920, 1440,
 * 1280, 1024 - 40px right of the logo on wide screens, 16px from about 1168 down.
 * THE INTRO STARTS JUST RIGHT OF ROW 2, AS IN THE OWNER'S PICTURE (Q-P078-1): the picture puts its
 * ink 1.62 headline sizes in from row 1's and row 2's 1.31 (CR-P077), so the intro is 0.31 headline
 * sizes past the card's edge.
 * Each line's box starts a Poppins side bearing left of its edge so the INK lands on it: J 0.03125em,
 * R 0.0625em (weight 600), D 0.078125em (400), read off canvas measureText at 1000px. They are for
 * the stock wording's first letters; a site that types other words is out by a pixel or two at most.
 * Sizes, weight, colour and the vertical placement stay the mock-up's.
 *
 * CLEAR OF THE SEARCH CARD. The mock-up's words end 3.31% above the band's foot, and from 901px
 * the card reaches 37px into the band, so at every width from there the words lift just enough to keep
 * 32px of clear space above it (CR-P076, the owner asked for a bit more than Q-P075-2's 24px; the
 * lift is zero only above about 2085px, where 3.31% of the band passes 37 + 32). At 782-900 the card's
 * own clearance holds the band's foot open - the words end 54px above the card there - so nothing
 * lifts.
 *
 * ROOM AT THE TOP WINS OVER THE 32px (Q-P076-1, "Keep a little room at the top"). Unlifted, the
 * headline's highest ink sits 4.56% of the band's width below its top (measured, Poppins 600), so
 * the lift stops at 4.56cqw - 12px and the letters never come closer than 12px to the top. That
 * bites below about 1020px, where the space over the card eases from 32 to about 22 at 901.
 *
 * THE LINES SIT AS FAR APART AS IN THE OWNER'S PICTURE WHERE THERE IS ROOM (CR-P077, Q-P077-1:
 * "Picture's spacing, but closer on small laptops"). The picture's baselines are 6.36% and 3.61% of
 * the band apart against the mock-up's 5.78% and 3.26%, so its words run 0.93% of the band further
 * down. --etick-hero-more is how much of that a width gets: all of it wherever the lift has room to
 * spare under the 12px top rule; none where that rule already bites, so the space over the card
 * never drops below what it was; and none at 782-900, where the words set the band's height (it
 * measured 8px taller there with the picture's spacing) and the band must not grow. The room to spare is
 * (4.56cqw - 12px) - (reach + 32px - 3.31cqw) = 7.87cqw - reach - 44px: all of it from about a
 * 1167px band, none below about 1029. It splits as 0.6237 into the headline's line-height and 0.129
 * into the intro's (0.58% and 0.12% of the band at full), and the padding-top gives back half the
 * headline's share so row 1 stays where it was.
 */
@media (min-width: 782px) {
	.etick-hero-part--scale .wp-block-group.etick-hero--whole.alignfull {
		--etick-hero-head-size: 4.048cqw;
		--etick-hero-intro-size: 1.89cqw;
		--etick-hero-more: 0px;

		padding-top: calc(3.664cqw - 0.3118 * var(--etick-hero-more)) !important;
		padding-left: calc(var(--etick-hero-logo-x) - 0.03125 * var(--etick-hero-head-size)) !important;
	}

	.etick-hero-part--scale .wp-block-group.etick-hero--whole.alignfull > * {
		position: relative;
		max-width: none;
		margin-left: 0 !important;
		margin-right: 0 !important;
	}

	.etick-hero-part--scale .wp-block-group.etick-hero--whole h1 {
		margin: 0;
		line-height: calc(5.78cqw + 0.6237 * var(--etick-hero-more));
		font-weight: 600 !important;
	}

	.etick-hero-part--scale .wp-block-group.etick-hero--whole p {
		line-height: calc(2.249cqw + 0.129 * var(--etick-hero-more));
	}

	.etick-hero-part--scale .wp-block-group.etick-hero--whole h1 + p {
		margin-top: 0;
	}

	.etick-hero-part--scale .wp-block-group.etick-hero--whole .etick-hero__row2-in .etick-hero__line + .etick-hero__line {
		padding-left: calc(var(--etick-hero-card-x) - var(--etick-hero-logo-x) + (0.03125 - 0.0625) * var(--etick-hero-head-size));
	}

	.etick-hero-part--scale .wp-block-group.etick-hero--whole p.etick-hero__intro-in {
		padding-left: calc(var(--etick-hero-card-x) - var(--etick-hero-logo-x) + (0.31 + 0.03125) * var(--etick-hero-head-size) - 0.078125 * var(--etick-hero-intro-size));
	}

	.etick-hero-part--scale .wp-block-group.etick-hero--whole.etick-hero--image p {
		color: var(--wp--custom--hero--on-image) !important;
	}
}

@media (min-width: 901px) {
	.etick-hero-part--scale .wp-block-group.etick-hero--whole.alignfull {
		--etick-hero-more: clamp(0px, 7.87cqw - var(--etick-hero-reach) - 44px, 0.93cqw);
	}

	.etick-hero-part--scale .wp-block-group.etick-hero--whole.alignfull > * {
		top: calc(-1 * max(0px, min(var(--etick-hero-reach) + 32px - 3.31cqw + var(--etick-hero-more), 4.56cqw - 12px)));
	}
}

/*
 * The card sits on the photo, so it needs to lift off it. The drop shadow does that on a light
 * card; on a dark one it does nothing, and the card's edge measured 1.07:1 against the shaded
 * photo - no edge at all. So a hairline goes inside the shadow as well.
 *
 * --etick-hero-card-rim is per-site, from Etick_Dynamic_Styles: a light hairline when the site's
 * own card colour is dark, transparent when it is not, so the light schemes are untouched. The
 * transparent fallback covers the moment before that inline block is read.
 *
 * CR-P028 T-A briefly moved the reward card off the picture with the words, which would have left
 * this rule reaching edited banners only. It was kept rather than deleted on the argument that
 * those banners still need it - and Q-P028-3 then put the card back on the picture, so it is
 * load-bearing for every banner again. Worth remembering as the reason not to delete a rule merely
 * because the current layout has stopped needing it.
 */
.etick-hero--image .etick-card {
	box-shadow:
		0 0 0 1px var(--etick-hero-card-rim, transparent),
		0 8px 24px var(--wp--custom--hero--card-shadow);
}

/* --- Search bar straddles the seam between hero and page body --- */

/*
 * The pull-up only exists to sit the card on the hero, so it rides on the
 * --overlap modifier, which patterns/front-page.php only emits when the hero is
 * actually above it. Without the hero the card keeps its normal place instead of
 * climbing into the header.
 *
 * The booking plugin already hangs the card half below wherever its own wrapper
 * sits — `.etick-search-design-2-wrap { transform: translateY(50%) }` in its
 * search-trip-design-2 view. A transform does not move the layout box, so the
 * theme's job is only to land this wrapper's BOTTOM edge on the seam: cancel the
 * stack gap, then lift by a whole card height. The plugin's transform supplies
 * the visible half. Lifting by half a card, as this did before CR-P008, put the
 * card flush under the banner with none of it on top.
 *
 * The card's height is the plugin's, not the theme's, and changes as its fields
 * wrap. Measured in a browser on this install — re-measure rather than trusting
 * these if the plugin changes.
 *
 * Re-measured for CR-P026 T-D, which gave the banner a second fit to be right in.
 * Every row below was taken on the live home page with a picture on and the reward
 * card on, in both fits, against the panel CR-P026 T-C put the words in:
 *
 *   viewport   fit     card    lift     on the banner       band
 *   375        band    395px   -76px    52px  = a tenth     346px
 *   375        whole   395px   -76px    52px  = a tenth     346px
 *   560        band    395px   -76px    52px  = a tenth     356px
 *   560        whole   395px   -76px    52px  = a tenth     356px
 *   768        band    216px   -240px   108px = half        416px
 *   768        whole   216px   -240px   108px = half        338px
 *   901        band     74px   -98px    37px  = half        452px
 *   901        whole    74px   -98px    37px  = half        272px
 *   1024       band     74px   -98px    37px  = half        431px
 *   1024       whole    74px   -98px    37px  = half        251px
 *   1440       band     74px   -98px    37px  = half        448px
 *   1440       whole    74px   -98px    37px  = half        268px
 *   1920       band     74px   -98px    37px  = half        448px
 *   1920       whole    74px   -98px    37px  = half        349px
 *
 * The card lands identically in both fits at every width, which is the answer to
 * the question T-D was set: whole fit changes the band's height underneath it and
 * changes nothing about where the card sits. The lift is measured from the band's
 * bottom edge, and whole fit moves that edge without moving the card relative to
 * it. No lift value needed changing.
 *
 * Two numbers did move, both at the phone end and neither from this change: the
 * plugin's card measures 395px where CR-P008 recorded about 380, so the tenth the
 * owner asked for (Q-P008-1) now works out at 52px rather than 36. Still a tenth,
 * still the owner's proportion; the card grew, and the lift is stated in card
 * heights, so it followed on its own.
 *
 * The case Q-P026-2 was really about does not occur: at no width does the card
 * swallow the band whole. Whole fit is shortest at 1024, where the band is 251px
 * against a 74px card showing 37px — the panel keeps the band taller than the
 * picture alone would, and the phone fallback keeps the ribbon widths out of it.
 *
 * The tight spot, recorded because it is thin rather than because it is broken: at
 * 901, 1024 and 1440 in whole fit the card's top edge crosses the words' panel and
 * covers its bottom 37px. The panel's own padding is 32px of that, so what is
 * actually reached is the last line's half-leading — measured glyph-accurately at
 * 1440, the letters clear the card's top edge by 1.8px and nothing is clipped. That
 * clearance is the plugin's card height minus the theme's lift, so it is the first
 * thing to re-measure if the plugin's fields ever wrap differently.
 *
 * The 901px boundary is where the fields wrap on this install, not a plugin
 * breakpoint — the wrap is content-driven, so it is a measurement, not a rule.
 */
.etick-searchbar {
	position: relative;
	z-index: 5;
}

.etick-searchbar--overlap {
	--etick-searchbar-card: 74px;
	--etick-searchbar-lift: calc(var(--wp--style--block-gap, 24px) + var(--etick-searchbar-card));

	margin-top: calc(-1 * var(--etick-searchbar-lift));
}

/*
 * Wrapped onto three rows. Half a 216px card is more than the hero's own lower
 * padding, so the hero grows enough to keep its last line clear of the card —
 * only when an overlapping search bar actually follows it, so a site with the
 * search section switched off keeps its normal banner.
 */
@media (min-width: 561px) and (max-width: 900px) {
	.etick-searchbar--overlap {
		--etick-searchbar-card: 216px;
	}

	/*
	 * Both sides need 108px of clear space — half the wrapped card — plus room to
	 * breathe. Stated absolutely rather than as `spacing-60 + n`, because that
	 * preset is a clamp that shrinks as the viewport narrows and would leave the
	 * card almost touching the heading at the bottom of this band.
	 */
	.etick-hero-part:has(+ .etick-searchbar--overlap) .wp-block-group.etick-hero.alignfull {
		/*
		 * 132px is CR-P008's clearance for the wrapped card and is the floor here;
		 * the extra 30px is CR-P020 T-A, so this band grows by the same 60px as the
		 * rest. Stated absolutely because it overrides the base padding outright, so
		 * the base rule's +30px never reaches this band on its own.
		 */
		padding-bottom: 162px !important;
	}

	/*
	 * Set as the custom property rather than as padding-top directly (CR-P058 T-B). This band
	 * sits inside the plugin's max-width:1080px range, where the section's padding is re-applied
	 * by an !important rule that reads these properties; writing padding-top here instead would
	 * lose to that !important and the wrapped search card would land on the row below.
	 */
	.etick-searchbar--overlap + .etick-section {
		--etick-section-pad-top: 132px;
	}
}

/*
 * Phone. The plugin drops its own half-drop here, so the card lands where this
 * wrapper puts it, and the card is nearly as tall as the banner — a half overlap
 * would bury the headline. The owner asked for about a tenth of it on the banner
 * (Q-P008-1): 36px of a ~363px card, plus the 16px of padding the plugin wraps
 * around the card at this size, which sits between the wrapper edge and the card
 * itself.
 */
@media (max-width: 560px) {
	.etick-searchbar--overlap {
		--etick-searchbar-lift: calc(var(--wp--style--block-gap, 24px) + 36px + 16px);
	}

	.etick-hero-part:has(+ .etick-searchbar--overlap) .wp-block-group.etick-hero.alignfull {
		padding-bottom: 60px !important;
	}

	/*
	 * CR-P168 T-D. The reasons-to-book row is inside the search card on a phone (front-page.php
	 * fills the card's slot), so its own section below is not shown here - the row appears once.
	 * Keyed on the card REALLY holding it (.etick-d2-usp is printed only when filled), so with
	 * search design 1, or the slot empty for any reason, the section stays where it was.
	 */
	.etick-searchbar:has(.etick-d2-usp) + .etick-section {
		display: none;
	}

	/* The hidden section was what held the next section off the card; the search group keeps
	   that air itself instead, the same bottom spacing the section had. */
	.etick-searchbar:has(.etick-d2-usp) {
		padding-bottom: var(--wp--preset--spacing--40);
	}

	/* Inside the card the row sits under Search Bus: the strip's own 1rem padding is the card's
	   job there, so only a little air above it is kept. Its 1rem scroll padding (the content
	   plugin's, CR-P168 T-A) matches that padding, so it goes too - left in, every item the row
	   moves to rests 16px in and is cut off on the right. One class more than that rule, so this
	   wins whichever stylesheet loads last. */
	.etick-d2-usp .etick-content[data-layout='banner'] .etick-content__row.etick-content__banner {
		padding: 0.35rem 0 0;
		scroll-padding-inline: 0;
	}
}

/* --- Cards --- */

.etick-card {
	height: 100%;
	border: 1px solid var(--wp--preset--color--additional);
	border-radius: var(--wp--custom--radius--card, 16px);
}

/* ==========================================================================
   Footer
   ========================================================================== */

.etick-footer {
	background: var(--wp--preset--color--background-secondary);
	border-top: 1px solid var(--wp--preset--color--additional);
}

.etick-footer__bottom {
	border-top: 1px solid var(--wp--preset--color--additional);
}

.etick-site-blurb {
	max-width: 42ch;
	color: var(--wp--preset--color--secondary);
}

/* --- Link columns (etick/footer-links) --- */

.etick-footer-links {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
	gap: var(--wp--preset--spacing--40);
}

.etick-footer-links__heading {
	margin: 0 0 var(--wp--preset--spacing--20);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--primary);
}

.etick-footer-links__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--10);
}

.etick-footer-links__item a {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--secondary);
	text-decoration: none;
}

.etick-footer-links__item a:hover {
	color: var(--wp--preset--color--accent);
}

/*
 * Desktop: the first link in each column shares a line with the site blurb.
 *
 * The blurb sits under the brand, and the brand's height is per-site — a logo
 * capped at 170px wide, so its aspect ratio decides, or the site title as
 * text — so no fixed offset can line the two up across the network. Instead
 * the columns row becomes a three-row grid: the brand column is subgridded
 * onto it (brand, blurb, social links) and the links column starts at row 2,
 * directly under whatever height the brand rendered at. 2fr 3fr is the 40/60
 * split from parts/footer.html with the gap taken out first, which is exactly
 * how the flex row divided it. The last row is 1fr so the link lists, taller
 * than the blurb, grow that row instead of pushing the social links down.
 *
 * The link block is then pulled up by its heading and the heading's gap and
 * pushed down by the blurb's own gap, so the first link row lands where the
 * blurb does. The last term centres the list's taller line box on the blurb's
 * line, so the two texts share a baseline rather than just a box top. 1lh is
 * the list's own line height; every other term is a theme token. Headings keep
 * their gap to the links — they move with them.
 */
@media (min-width: 782px) {
	.etick-footer .wp-block-columns {
		display: grid;
		grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
		grid-template-rows: auto auto 1fr;
		row-gap: 0;
	}

	.etick-footer .wp-block-columns > .wp-block-column:first-child {
		grid-column: 1;
		grid-row: 1 / -1;
		display: grid;
		grid-template-rows: subgrid;
	}

	.etick-footer .wp-block-columns > .wp-block-column:last-child {
		grid-column: 2;
		grid-row: 2 / -1;
	}

	.etick-footer .etick-footer-links {
		margin-top: calc(
			var(--wp--style--block-gap)
			- var(--wp--custom--typography--line-height--tight) * var(--wp--preset--font-size--small)
			- var(--wp--preset--spacing--20)
			- (1lh - var(--wp--custom--typography--line-height--normal) * var(--wp--preset--font-size--small)) / 2
		);
	}
}

/* --- Copyright (etick/copyright) --- */

/*
 * The two credits are pushed to opposite ends of the bar. The literal space
 * that render_copyright() emits between the spans is a whitespace-only text
 * node, so it generates no flex item and contributes nothing here — it stays
 * in the PHP as the fallback for any context that does not lay this out as a
 * flex row. With no "Powered by" credit set there is a single item, and
 * space-between leaves a lone item at flex-start: the left edge, unchanged.
 */
.etick-copyright {
	margin: 0;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--secondary);
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--20) var(--wp--preset--spacing--40);
}

.etick-copyright a {
	color: var(--wp--preset--color--secondary);
	text-decoration: underline;
}

/*
 * Narrow. Once the two credits no longer fit on one line they each wrap onto
 * a line of their own, and space-between puts a lone item at flex-start — so
 * both end up jammed against the left edge with the credit stranded far from
 * the right. Measured on this install that starts at about 695px, so stack and
 * centre from WP's own 781px column breakpoint, which is also where the two
 * footer columns above collapse: the whole footer then folds as one piece.
 * The collision width follows the length of the copyright line, which is a
 * per-site setting, so this is a margin over a measurement rather than an
 * exact boundary.
 */
@media (max-width: 781px) {
	.etick-copyright {
		flex-direction: column;
		align-items: center;
		text-align: center;
	}
}

/* --- Social (etick/social-links) --- */

.wp-block-social-links .wp-social-link span:not(.screen-reader-text) {
	font-size: var(--wp--preset--font-size--small);
}

/* --- App badges (etick/app-badges) --- */

.etick-app-badges {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--20);
}

.etick-app-badge {
	display: inline-flex;
	align-items: center;
	padding: var(--wp--preset--spacing--20) var(--wp--preset--spacing--40);
	border-radius: var(--wp--custom--radius--pill, 500px);
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--accent-contrast);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	text-decoration: none;
}

/*
 * A site that has uploaded badge artwork gets the picture on its own (CR-P021 T-A). The pill
 * above is the fallback for a site that has pasted a store link but not uploaded a badge yet,
 * so its chrome - accent fill, padding, pill radius - has to come back off here rather than
 * sit behind someone's badge.
 */
.etick-app-badge--image {
	padding: 0;
	background: none;
	border-radius: 0;
}

/*
 * THE TWO BUTTONS SHARE THE ROW EQUALLY AND THE PICTURES FILL THEM (CR-P051 T-A, CR-P052 T-A).
 * Q-P051-1 first chose to widen the buttons but leave the pictures at their own size; seeing that
 * in place, the owner asked for the pictures to fill their buttons too, which is CR-P052.
 *
 * ONLY THE PICTURE VARIANT. The text pill a site falls back to keeps its natural width. The owner
 * was looking at a row of badges when they asked for this, not at pills.
 *
 * THERE IS NO min-width GUARD ANY MORE AND THAT IS DELIBERATE. CR-P051 needed one, because the
 * picture was pinned to 40 tall and a button narrower than the artwork squeezed it out of shape.
 * Once the height follows the width that cannot happen: a narrow row just scales the pair down
 * together, still in proportion. Measured on the narrowest phone in normal use they come out 156
 * by 46, above the size both stores treat as a comfortable minimum for something meant to be
 * tapped. Putting the guard back would only make them wrap instead, which is not what was asked
 * for.
 */
.etick-app-badge--image {
	flex: 1;
}

/*
 * THE PICTURE FILLS ITS BUTTON (CR-P052 T-A). CR-P051 widened each button to half the row but
 * left the badge sitting at its own size in the middle of it, and the owner asked for the badge
 * to fill instead. width does the filling; height: auto is the part that keeps the stores happy,
 * because both forbid their badge being reshaped, so the height has to follow the width rather
 * than be pinned. The img carries width and height attributes, so the proportions are known
 * before the file arrives and nothing jumps as it loads.
 *
 * THIS GIVES UP A DELIBERATE 40px HEIGHT and the reason for it is worth keeping in view. CR-P021
 * pinned every badge to one height so that two badges of different proportions would still read
 * as a pair. Filling the button means the height is whatever each picture's own shape makes it.
 * The theme's own two badges are the same shape as each other and stay level; a site that uploads
 * two differently shaped badges will now get two different heights. Named in CR-P052 rather than
 * guarded against, because the only guards available are stretching artwork, which the stores
 * forbid, or a rule nobody has asked for.
 */
.etick-app-badge__img {
	display: block;
	width: 100%;
	height: auto;
}

/*
 * A LONE BADGE IS LEFT EXACTLY AS IT WAS (CR-P051 T-A). A site with only one of the two store
 * links has nothing to share the row with, so its badge keeps the size and the place it has
 * always had, rather than being blown up to the full width of the row.
 *
 * THE PICTURE RULE HAS TO BE UNDONE TOO, not just the flex, and this is the one that bites.
 * width: 100% inside a button sized to its own contents has nothing to resolve against and
 * collapses - measured at 0 by 0, an invisible badge, on a site with one store link. Handing the
 * picture back its own width and the 40px height is what the button then sizes itself to.
 */
.etick-app-badge--image:only-child {
	flex: 0 1 auto;
}

.etick-app-badge--image:only-child .etick-app-badge__img {
	width: auto;
	height: 40px;
}

.etick-app-badge:hover {
	background: var(--wp--preset--color--accent-second);
	color: var(--wp--preset--color--accent-contrast);
}

/* --- Contact details (etick/contact-info) --- */

.etick-contact-info {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--20);
}

.etick-contact-info strong {
	display: block;
	font-size: var(--wp--preset--font-size--tiny);
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--secondary);
}

/* ==========================================================================
   Blog
   ========================================================================== */

ul.wp-block-categories-list {
	list-style: none;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--30);
}

.wp-block-query-pagination-numbers {
	display: flex;
	gap: var(--wp--preset--spacing--30);
}

/* ==========================================================================
   Interaction polish
   ========================================================================== */

.wp-element-button,
.wp-block-button a {
	transition: background-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
	box-sizing: border-box;
}

.wp-element-button:hover,
.wp-block-button:hover a {
	transform: translateY(-1px);
}

.wp-element-button:active,
.wp-block-button:active a {
	transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
	.wp-element-button,
	.wp-block-button a {
		transition: none;
	}

	.wp-element-button:hover,
	.wp-block-button:hover a {
		transform: none;
	}
}

/* ==========================================================================
   Helpers
   ========================================================================== */

.border-radius-default {
	border-radius: var(--wp--custom--radius--card, 16px);
}

.overflow-hidden {
	overflow: hidden;
}

.full-height {
	height: 100%;
}

.is-style-etick-rounded {
	border-radius: var(--wp--custom--radius--card, 16px);
	overflow: hidden;
}

@media (max-width: 781px) {
	.mobile-hide {
		display: none !important;
	}

	.mobile-order-1 { order: 1; }
	.mobile-order-2 { order: 2; }
	.mobile-order-3 { order: 3; }

	.mobile-align-none {
		float: none !important;
		margin-inline-start: 0 !important;
	}

	.mobile-no-br br {
		display: none;
	}

	.mobile--no-padding-top {
		padding-top: 0 !important;
	}

	.mobile--no-padding-bottom {
		padding-bottom: 0 !important;
	}
}

/* --- Editor only: a block whose PHP render came back empty --- */

/*
 * Reached through add_editor_style( 'style.css' ), so it styles the panel that
 * assets/js/blocks-editor.js hands ServerSideRender in place of its default
 * "Block rendered as empty." message (CR-P020 T-B). Deliberately quiet - dashed
 * rather than coloured - because an empty block here is a box waiting to be filled
 * in, not an error. Nothing on the front end carries this class.
 */
.etick-block-empty {
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding: var(--wp--preset--spacing--30, 24px);
	border: 1px dashed currentColor;
	border-radius: 4px;
	opacity: 0.6;
	font-size: var(--wp--preset--font-size--small, 14px);
	line-height: 1.5;
	text-align: left;
}

.etick-block-empty__source {
	opacity: 0.8;
	font-style: italic;
}
