/*
Theme Name: Borderlessly European
Theme URI: https://borderlessly.eu
Author: Borderlessly European
Author URI: https://borderlessly.eu
Description: Tema de bloques a medida para Borderlessly European. Diseño azul corporativo, minimalista y mobile-first. Incluye patrones reutilizables para la home, las 4 páginas de servicio, "Why Us" y contacto.
Requires at least: 6.4
Tested up to: 6.6
Requires PHP: 7.4
Version: 1.0.17
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: borderlessly-european
Tags: full-site-editing, block-patterns, blue, one-column, custom-colors, custom-logo
*/

/* ==========================================================================
   Custom CSS — solo lo que theme.json no puede hacer (hover, gradientes,
   overlays, decoraciones). Los colores/tipografías/espaciados base viven
   en theme.json.
   ========================================================================== */

:root {
	--be-navy: #264788;
	--be-primary: #2e60ba;
	--be-bright: #437cd7;
	--be-light: #e8f1fc;
	--be-soft: #c7daf5;
	--be-ink: #162853;
}

/* Suavizado de fuentes */
body {
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

/* --- Botones: transición + hover --- */
.wp-element-button,
.wp-block-button__link {
	transition: transform .15s ease, background-color .15s ease, box-shadow .15s ease, color .15s ease;
}
.wp-block-button__link:hover {
	transform: translateY(-1px);
	box-shadow: 0 8px 20px rgba(46,96,186, .25);
}

/* Botón "outline" (variación registrada en functions.php) */
.wp-block-button.is-style-be-outline .wp-block-button__link {
	background-color: transparent;
	border: 2px solid var(--be-primary);
	color: var(--be-primary);
}
.wp-block-button.is-style-be-outline .wp-block-button__link:hover {
	background-color: var(--be-primary);
	color: #fff;
}

/* Botón blanco sobre fondo azul (variación) */
.wp-block-button.is-style-be-white .wp-block-button__link {
	background-color: #fff;
	color: var(--be-primary);
}
.wp-block-button.is-style-be-white .wp-block-button__link:hover {
	background-color: var(--be-light);
	color: var(--be-navy);
}

/* --- Tarjeta de servicio (variación de grupo) --- */
.wp-block-group.is-style-be-card {
	background: #fff;
	border: 1px solid var(--be-soft);
	border-radius: 16px;
	box-shadow: 0 6px 24px rgba(22,40,83, .06);
	transition: transform .18s ease, box-shadow .18s ease;
	height: 100%;
}
.wp-block-group.is-style-be-card:hover {
	transform: translateY(-4px);
	box-shadow: 0 16px 40px rgba(22,40,83, .12);
}

/* Iconos SVG (van dentro de bloques core/html) */
.be-icon svg {
	width: 44px;
	height: 44px;
	stroke: var(--be-primary);
	fill: none;
	stroke-width: 1.8;
	stroke-linecap: round;
	stroke-linejoin: round;
}
.be-icon--light svg { stroke: #fff; }

/* Foto de cabecera en las tarjetas de /tours.
   Rendered by the plugin's [be_tour_thumb] shortcode, which wraps (and falls
   back to) the card's .be-icon. The negative margins bleed the photo to the
   card's edges, so they mirror the card group's inline padding exactly —
   2rem top / 1.5rem sides. If that padding changes, change these with it.
   The radius is the card's 16px minus its 1px border, so the photo sits
   inside the border rather than over it. */
/* Selector deliberately over-specified: a bare `.be-tour-thumb` loses the
   margin outright. Core's constrained-layout rule (`:root :where(...)`, also
   0,1,0) sets margin-inline: auto, and the per-container blockGap rule
   (`.wp-container-… > *`) sets margin-block-start: 0 — both come after the
   theme stylesheet, so an equal-specificity rule here is silently dropped.
   Measured: the photo sat inside the padding at 33px/25px instead of bleeding.
   The inline axis additionally needs !important, because that same core rule
   declares `margin-left/right: auto !important` — no amount of specificity
   beats it. Raising specificity alone got the top bleed and left the sides
   inset by 24px. */
.wp-block-group.is-style-be-card > .be-tour-thumb {
	margin: -2rem -1.5rem 0.4rem;
	margin-inline: -1.5rem !important;
	border-radius: 15px 15px 0 0;
	overflow: hidden;
	background: var(--be-light);
}
/* Distintivo sobre la foto de la tarjeta ("Family favorite").
   Editorial copy, supplied per card as [be_tour_thumb badge="..."] — it is not
   a property of the tour and deliberately does not live in BE_Tours.
   It is clipped by the thumb's existing `overflow: hidden`, so it can never
   push the card wider; `max-width` keeps a long label inside the photo rather
   than letting it run under the rounded corner. */
.wp-block-group.is-style-be-card > .be-tour-thumb {
	position: relative;
}
.be-tour-thumb__badge {
	position: absolute;
	top: 0.7rem;
	left: 0.7rem;
	display: inline-flex;
	align-items: center;
	gap: 0.3rem;
	max-width: calc(100% - 1.4rem);
	padding: 0.3rem 0.65rem;
	border-radius: 999px;
	background: rgba(255,255,255, .94);
	color: var(--be-ink);
	font-size: 0.78rem;
	font-weight: 700;
	line-height: 1.25;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	box-shadow: 0 2px 10px rgba(22,40,83, .22);
}
.be-tour-thumb__star {
	color: var(--be-primary);
	font-size: 0.95em;
}

.be-tour-thumb__image {
	display: block;
	width: 100%;
	height: auto;
	/* cover, unlike the tour pages' large gallery image: this is an index
	   chip at a fixed 3:2 so the seven cards line up, not the photo itself. */
	aspect-ratio: 3 / 2;
	object-fit: cover;
}

/* Alineacion inferior de las tarjetas de /tours.
   The cards are already equal height, but a tour title runs to one or two
   lines, so the price, the meta line and the button used to start at a
   different height in every card (measured 1258 vs 1229 at 1280px — exactly
   one title line). Making the card a flex column and giving the price
   paragraph `margin-top: auto` collects all the slack immediately under the
   title, so that block hangs off the bottom of every card and the buttons
   line up. The titles do not move: they still start right under the photo.

   `margin-inline: 0 !important` is load-bearing, not tidying. Core's
   constrained-layout rule declares `margin-left/right: auto !important` on
   every direct child, and in a flex column auto inline margins stop an item
   stretching — the full-width button would shrink to the width of its text.
   The photo is excluded so its negative bleed margins above survive.

   The meta line is held at two lines because it is the one part that wraps
   differently between cards (it does at 1024px), which would otherwise push
   the price back out of line even with the buttons aligned. `lh` is exactly
   one line box; a browser too old for it simply gets today's behaviour. */
#choose-tour .wp-block-group.is-style-be-card {
	display: flex;
	flex-direction: column;
}
#choose-tour .wp-block-group.is-style-be-card > *:not(.be-tour-thumb) {
	margin-inline: 0 !important;
	max-width: 100%;
}
#choose-tour .wp-block-group.is-style-be-card > .wp-block-heading + p {
	margin-top: auto;
}
#choose-tour .wp-block-group.is-style-be-card > .wp-block-heading + p + p {
	min-height: 2lh;
}

/* --- Hero: overlay azul sobre la imagen de fondo --- */
.be-hero {
	position: relative;
	background-color: var(--be-navy);
	background-size: cover;
	background-position: center;
}
.be-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(100deg, rgba(38,71,136,.92) 0%, rgba(46,96,186,.78) 45%, rgba(46,96,186,.25) 100%);
	z-index: 0;
}
.be-hero > * { position: relative; z-index: 1; }

/* Degradado sutil para bandas azules */
.be-gradient {
	background: linear-gradient(135deg, var(--be-navy) 0%, var(--be-primary) 100%);
}

/* Subrayado decorativo bajo títulos centrados */
.be-underline::after {
	content: "";
	display: block;
	width: 56px;
	height: 3px;
	margin: 14px auto 0;
	border-radius: 2px;
	background: currentColor;
	opacity: .85;
}

/* Logo del header/footer */
.be-logo img {
	height: 46px;
	width: auto;
	display: block;
}

/* Navegación: peso y espaciado del menú */
.wp-block-navigation {
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 500;
}

/* Inputs de formularios (Fluent Forms / WPForms) heredan el estilo de marca */
.be-form input[type="text"],
.be-form input[type="email"],
.be-form input[type="tel"],
.be-form select,
.be-form textarea,
.fluentform .ff-el-input--content input:not([type=checkbox]):not([type=radio]),
.fluentform .ff-el-input--content textarea,
.fluentform .ff-el-input--content select {
	border-radius: 10px !important;
	border: 1px solid var(--be-soft) !important;
}

/* Responsive: tipografías un poco menores en móvil */
@media (max-width: 600px) {
	.be-hero { text-align: center; }
}

/* Formulario de consulta en 2 etapas: paginación con JS (consultation-form-steps.js) */
.be-hidden-until-next {
	display: none !important;
}

/* Phone number: country-code+flag dropdown sits to the left of the number
   input, both on the row below the "Phone Number" label. consultation-form-
   steps.js wraps the two fields in a ".be-phone-row" flex row at runtime,
   because Fluent Forms' own CSS makes each field's parent a
   "display:flex; flex-direction:column" cell, which overrides any
   "display:inline-block" set directly on the fields themselves. The code
   field's own "Code" label is visually hidden (still in the DOM for screen
   readers) so only "Phone Number" reads as the row's label. */
.be-phone-row {
	display: flex;
	align-items: flex-end;
	gap: 0.75rem;
}
.be-phone-row-label {
	display: block;
}
.be-phone-row > .be-phone-code {
	width: auto;
	flex: 0 0 auto;
}
.be-phone-row > .be-phone-number {
	width: auto;
	flex: 1 1 auto;
}
.be-phone-code .ff-el-input--label {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}
.be-phone-code select {
	width: auto;
	max-width: 100%;
	padding-right: 1.75rem;
}
@media (max-width: 480px) {
	.be-phone-row {
		flex-direction: column;
		align-items: stretch;
		gap: 0;
	}
	.be-phone-row > .be-phone-code,
	.be-phone-row > .be-phone-number {
		width: 100%;
	}
	.be-phone-row > .be-phone-code select {
		width: 100%;
	}
}

/* Consultation form: hide the decorative paper-plane image on mobile, where
   the columns block stacks and the image would otherwise push the form
   down the page for no benefit. */
@media (max-width: 781px) {
	.wp-block-column:has(.wp-image-114) {
		display: none;
	}
}

.be-kudos-message p,
.be-form-note p {
	background-color: var(--be-light);
	border: 1px solid var(--be-soft);
	border-radius: 10px;
	padding: 1rem 1.25rem;
	color: var(--be-ink);
	margin-bottom: 1rem;
}

/* --- Tarjeta de reserva de tour (estilo GetYourGuide, /tours) --- */
.be-booking {
	background: #fff;
	border: 1px solid var(--be-soft);
	border-radius: 16px;
	box-shadow: 0 6px 24px rgba(22,40,83, .06);
	padding: 1.5rem;
	position: sticky;
	top: 1.5rem;
}
.be-booking__price {
	font-size: 0.95rem;
	color: var(--be-ink);
	margin-bottom: 1rem;
}
.be-booking__price strong {
	font-size: 1.9rem;
	font-weight: 700;
	color: var(--be-ink);
}
.be-booking__label {
	display: block;
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--be-ink);
	margin: 0.9rem 0 0.4rem;
}
.be-booking__hint {
	font-weight: 400;
	color: var(--be-muted, #6b7280);
}
.be-booking__date {
	box-sizing: border-box;
	width: 100%;
	border-radius: 10px;
	border: 1px solid var(--be-soft);
	padding: 0.6rem 0.75rem;
	font-size: 0.95rem;
}
.be-booking__date:disabled {
	background: var(--be-light);
	color: var(--be-muted, #6b7280);
	cursor: not-allowed;
}
/* Route picker, on tours that run more than one route for one deposit (the
   speedboat — see patterns/tour-speedboat.php). Deliberately matched to
   .be-booking__date rather than to .be-slot: it is a field the visitor fills
   in, not a departure they pick, and the two sit directly above each other. */
.be-booking__variant {
	box-sizing: border-box;
	width: 100%;
	border-radius: 10px;
	border: 1px solid var(--be-soft);
	background: #fff;
	color: var(--be-ink);
	padding: 0.6rem 0.75rem;
	font-size: 0.95rem;
}
/* Availability note for departure-aware tours; built in JS (tour-booking.js,
   initDepartures()) and inserted right after .be-booking__date, so it isn't
   in the pattern markup. */
.be-booking__availability {
	color: var(--be-muted, #6b7280);
	font-size: 0.78rem;
	margin: 0.4rem 0 0;
}
.be-booking__availability.is-error {
	color: #b42318;
}

/* Inline month calendar (tour-booking.js, buildCalendar()) that stands in
   for .be-booking__date on tours with admin-created departures — no browser
   lets a native <input type="date"> grey out individual days. Mobile-first:
   day buttons stay >=40px on the smallest supported width (~320px) since
   the card is full-width there; the sticky-sidebar layout only kicks in
   above 781px (see the .be-booking media query below). */
.be-calendar {
	margin: 0.6rem 0 0.9rem;
}
.be-calendar__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.5rem;
	margin-bottom: 0.5rem;
}
.be-calendar__month {
	margin: 0;
	font-size: 0.9rem;
	font-weight: 600;
	color: var(--be-ink);
	text-align: center;
	flex: 1 1 auto;
}
.be-calendar__nav {
	flex: 0 0 auto;
	width: 40px;
	height: 40px;
	min-width: 40px;
	border-radius: 10px;
	border: 1px solid var(--be-soft);
	background: #fff;
	color: var(--be-primary);
	font-size: 1.2rem;
	line-height: 1;
	cursor: pointer;
}
.be-calendar__nav:hover:not(:disabled) {
	background: var(--be-light);
}
.be-calendar__nav:disabled {
	color: var(--be-muted, #6b7280);
	border-color: var(--be-soft);
	background: #fff;
	opacity: 0.45;
	cursor: not-allowed;
}
.be-calendar__grid {
	width: 100%;
	border-collapse: separate;
	border-spacing: 2px;
	table-layout: fixed;
}
.be-calendar__grid th {
	font-size: 0.7rem;
	font-weight: 600;
	color: var(--be-muted, #6b7280);
	text-transform: uppercase;
	letter-spacing: 0.02em;
	padding: 0.25rem 0;
}
.be-calendar__grid td {
	padding: 0;
	text-align: center;
}
.be-calendar__day {
	box-sizing: border-box;
	width: 100%;
	min-width: 40px;
	min-height: 40px;
	border-radius: 8px;
	border: 1px solid var(--be-soft);
	background: #fff;
	color: var(--be-ink);
	font: inherit;
	font-size: 0.85rem;
	cursor: pointer;
	transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.be-calendar__day:hover:not(:disabled) {
	background: var(--be-light);
	border-color: var(--be-primary);
}
/* Unavailable days: never colour alone — no border, muted text and a
   not-allowed cursor carry the "can't click this" signal too. */
.be-calendar__day.is-disabled {
	border-color: transparent;
	background: transparent;
	color: var(--be-muted, #6b7280);
	opacity: 0.55;
	cursor: not-allowed;
}
.be-calendar__day.is-today:not(.is-disabled) {
	border-color: var(--be-primary);
	font-weight: 700;
}
.be-calendar__day.is-selected {
	background: var(--be-primary);
	border-color: var(--be-primary);
	color: #fff;
	font-weight: 600;
}
.be-calendar__day:focus-visible {
	outline: 2px solid var(--be-primary);
	outline-offset: 2px;
}
@media (max-width: 360px) {
	.be-calendar__grid th {
		font-size: 0.62rem;
	}
	.be-calendar__day {
		font-size: 0.78rem;
	}
}

/* Popover shell (tour-booking.js, initDepartures()) that the .be-calendar
   above now opens inside, instead of sitting permanently expanded in the
   card. .be-booking__datefield is the positioning root for the popover;
   the trigger stands in visually for the hidden .be-booking__date input. */
.be-booking__datefield {
	position: relative;
	margin: 0.6rem 0 0.9rem;
}
.be-booking__datetrigger {
	box-sizing: border-box;
	display: block;
	width: 100%;
	min-height: 44px;
	text-align: left;
	border-radius: 10px;
	border: 1px solid var(--be-soft);
	background: #fff;
	color: var(--be-ink);
	font: inherit;
	font-size: 0.95rem;
	padding: 0.6rem 0.75rem;
	cursor: pointer;
}
.be-booking__datetrigger:hover {
	border-color: var(--be-primary);
}
.be-booking__datetrigger[aria-expanded="true"] {
	border-color: var(--be-primary);
}
.be-booking__datetrigger:focus-visible {
	outline: 2px solid var(--be-primary);
	outline-offset: 2px;
}
/* left/right (not a fixed width) so the popover always matches the card's
   own content width — the card is already proven not to overflow at the
   ~320px minimum, so tying the popover to it sidesteps working out a
   separate mobile-safe width for the popover itself. */
.be-booking__datepopover {
	position: absolute;
	left: 0;
	right: 0;
	top: calc(100% + 0.4rem);
	z-index: 20;
	background: #fff;
	border: 1px solid var(--be-soft);
	border-radius: 12px;
	box-shadow: 0 12px 32px rgba(22,40,83, .16);
	padding: 0.9rem;
}
.be-booking__datepopover .be-calendar {
	margin: 0;
}

.be-booking__slots {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}
.be-slot {
	border-radius: 999px;
	border: 1px solid var(--be-soft);
	background: #fff;
	color: var(--be-ink);
	padding: 0.4rem 0.9rem;
	font-size: 0.85rem;
	cursor: pointer;
	transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.be-slot[hidden] {
	display: none !important;
}
.be-slot.is-selected {
	background: var(--be-primary);
	border-color: var(--be-primary);
	color: #fff;
}
.be-booking__stepper {
	display: flex;
	align-items: center;
	gap: 1rem;
}
.be-stepper__btn {
	width: 34px;
	height: 34px;
	border-radius: 50%;
	border: 1px solid var(--be-soft);
	background: #fff;
	color: var(--be-primary);
	font-size: 1.1rem;
	line-height: 1;
	cursor: pointer;
}
.be-stepper__btn:hover {
	background: var(--be-light);
}
.be-stepper__value {
	min-width: 1.5rem;
	text-align: center;
	font-weight: 600;
	color: var(--be-ink);
}
.be-booking__breakdown {
	margin: 1.1rem 0 0.9rem;
	padding: 0.85rem 1rem;
	background: var(--be-light);
	border: 1px solid var(--be-soft);
	border-radius: 10px;
}
.be-booking__breakdown-row {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 0.75rem;
	margin: 0;
	font-size: 0.85rem;
	color: var(--be-ink);
}
.be-booking__breakdown-row + .be-booking__breakdown-row {
	margin-top: 0.45rem;
}
.be-booking__breakdown-row strong {
	font-size: 1rem;
	white-space: nowrap;
}
.be-booking__breakdown-row--deposit strong {
	color: var(--be-primary);
	font-size: 1.15rem;
}
.be-booking__breakdown-row--balance {
	color: var(--be-muted, #6b7280);
	font-size: 0.8rem;
}
.be-booking__breakdown-row--balance strong {
	font-size: 0.9rem;
	font-weight: 600;
	color: var(--be-muted, #6b7280);
}
.be-booking__consent {
	display: flex;
	align-items: flex-start;
	gap: 0.55rem;
	margin: 1rem 0;
}
.be-booking__consent-input {
	flex: 0 0 auto;
	width: 1.05rem;
	height: 1.05rem;
	margin-top: 0.15rem;
	accent-color: var(--be-primary);
}
.be-booking__consent label {
	font-size: 0.78rem;
	line-height: 1.4;
	color: var(--be-muted, #6b7280);
}
.be-booking__consent label a {
	color: var(--be-primary);
	text-decoration: underline;
}
.be-booking__cta.wp-element-button {
	box-sizing: border-box;
	display: block;
	width: 100%;
	text-align: center;
	background-color: var(--be-primary);
	color: #fff;
	border: none;
	border-radius: 10px;
	padding: 0.75rem 1rem;
	font: inherit;
	cursor: pointer;
	transition: background-color .15s ease, opacity .15s ease;
}
.be-booking__cta.wp-element-button:hover:not(:disabled) {
	background-color: var(--be-primary-dark, var(--be-primary));
	opacity: 0.92;
}
.be-booking__cta.wp-element-button:disabled,
.be-booking__cta.wp-element-button.is-busy {
	cursor: not-allowed;
	opacity: 0.65;
}
.be-booking__error {
	color: #b42318;
	font-size: 0.8rem;
	margin: 0.5rem 0 0;
}
.be-booking__error:empty {
	display: none;
	margin: 0;
}
.be-booking__note {
	color: var(--be-muted, #6b7280);
	font-size: 0.78rem;
	margin-top: 0.75rem;
}
@media (max-width: 781px) {
	.be-booking {
		position: static;
		top: auto;
	}
}

/* --- "← Back to all tours" link at the top of each /tours/<tour> page. --- */
.be-tour-details__close {
	margin: 0 0 1.5rem;
}
.be-tour-details__close a {
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--be-primary);
	text-decoration: none;
}
.be-tour-details__close a:hover {
	text-decoration: underline;
}

/* --- Tour photo gallery (BE_Tour_Images / [be_tour_gallery]) --------------
   Sits at the top of the 60% information column on /tours/<tour>, above
   "What's included". Rendered server-side by the plugin and absent entirely
   when a tour has no photos, so there is no empty state to style.
   The thumb strip scrolls horizontally rather than wrapping, so the amount of
   vertical space the gallery takes does not depend on how many photos the
   owner uploads. */
.be-gallery {
	margin: 0 0 2rem;
}
.be-gallery__main {
	position: relative;
	border-radius: 14px;
	overflow: hidden;
	box-shadow: 0 10px 30px rgba(22, 40, 83, 0.12);
	background: var(--be-light, #e8f1fc);
}
.be-gallery__image {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 3 / 2;
	/* contain, never cover: the whole photo must be visible whatever its own
	   aspect ratio. The fixed box is kept so the frame does not resize under
	   the pointer while stepping through with the arrows - the spare space
	   shows .be-gallery__main's pale background instead. */
	object-fit: contain;
}
.be-gallery__thumbs {
	display: flex;
	gap: 0.6rem;
	margin: 0.75rem 0 0;
	padding: 0 0 0.25rem;
	list-style: none;
	overflow-x: auto;
	scrollbar-width: thin;
}
.be-gallery__thumbs-item {
	margin: 0;
	flex: 0 0 auto;
}
.be-gallery__thumb {
	display: block;
	/* Load-bearing, not cosmetic. Each thumb holds a .screen-reader-text span
	   that is position:absolute with no left/top, so it stays at its static
	   position -- for thumb N that is hundreds of px inside the horizontally
	   scrolled strip. Without a positioned ancestor INSIDE the scroller its
	   containing block is outside .be-gallery__thumbs, so it escapes the
	   overflow-x clip and drags the document's scrollable width out with it
	   (2503px on /tours/kornati-telascica at a 393px viewport). On Android
	   that inflates the initial containing block to the content width, and
	   the lightbox -- position:fixed, inset:0, centred -- then centres itself
	   in a 1572x2908 box instead of the screen, putting the photo far
	   off-view while the backdrop and close button still render.
	   Fixed 2026-08-04; verified the ICB stays 393px with this line. */
	position: relative;
	padding: 0;
	border: 2px solid transparent;
	border-radius: 8px;
	background: none;
	cursor: pointer;
	overflow: hidden;
	line-height: 0;
	opacity: 0.72;
	transition: opacity 0.15s ease, border-color 0.15s ease;
}
.be-gallery__thumb:hover {
	opacity: 1;
}
.be-gallery__thumb.is-active {
	opacity: 1;
	border-color: var(--be-primary, #2e60ba);
}
.be-gallery__thumb:focus-visible {
	outline: 2px solid var(--be-primary, #2e60ba);
	outline-offset: 2px;
}
.be-gallery__thumb-image {
	display: block;
	width: 84px;
	height: 64px;
	object-fit: cover;
}
@media (max-width: 781px) {
	.be-gallery__thumb-image {
		width: 68px;
		height: 52px;
	}
}

/* The whole photo is a link to the full-size file (see BE_Tour_Images::render);
   tour-gallery.js turns that click into the lightbox below. */
.be-gallery__zoom {
	display: block;
	cursor: zoom-in;
}

/* Prev/next arrows. Built by tour-gallery.js and appended INSIDE
   .be-gallery__main, so they sit over the photo and are clipped by its rounded
   corners — never in the margin beside the frame. Kept permanently visible
   rather than revealed on hover: on a touch screen there is no hover, and this
   is the primary way through the photos on a phone. */
.be-gallery__nav {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.88);
	color: var(--be-ink, #162853);
	box-shadow: 0 2px 10px rgba(22, 40, 83, 0.28);
	cursor: pointer;
	transition: background 0.15s ease, transform 0.15s ease;
}
.be-gallery__nav svg {
	width: 20px;
	height: 20px;
}
.be-gallery__nav:hover {
	background: #fff;
}
.be-gallery__nav:focus-visible {
	outline: 2px solid var(--be-primary, #2e60ba);
	outline-offset: 2px;
}
.be-gallery__nav--prev {
	left: 0.7rem;
}
.be-gallery__nav--next {
	right: 0.7rem;
}
@media (max-width: 781px) {
	.be-gallery__nav {
		width: 32px;
		height: 32px;
	}
	.be-gallery__nav svg {
		width: 17px;
		height: 17px;
	}
}

/* --- Lightbox: the photo popped out of the frame, over the whole page. -----
   Built by tour-gallery.js and appended to <body>.

   `display: none` here and `display: flex` on .is-open is deliberate and the
   toggle is a CLASS, not the `hidden` attribute — a class that carries its own
   `display` beats the UA's `[hidden] { display: none }`, the trap that already
   caught .be-slot and .be-booking__datepopover in this file. */
.be-lightbox {
	display: none;
	position: fixed;
	inset: 0;
	z-index: 999999;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	padding: 3.5vh 3vw;
	background: rgba(22, 40, 83, 0.94);
}
.be-lightbox.is-open {
	display: flex;
}
/* Stop the page behind scrolling while the viewer is open. */
html.be-lightbox-open {
	overflow: hidden;
}
.be-lightbox__figure {
	display: flex;
	flex: 1 1 auto;
	align-items: center;
	justify-content: center;
	min-width: 0;
	max-height: 100%;
}
.be-lightbox__image {
	display: block;
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: 88vh;
	border-radius: 10px;
	box-shadow: 0 24px 60px rgba(22, 40, 83, 0.55);
}
.be-lightbox__close {
	position: absolute;
	top: 0.9rem;
	right: 1rem;
	z-index: 2;
	width: 42px;
	height: 42px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.14);
	color: #fff;
	font-size: 1.6rem;
	line-height: 1;
	cursor: pointer;
}
.be-lightbox__close:hover {
	background: rgba(255, 255, 255, 0.3);
}
.be-lightbox__nav {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 46px;
	height: 46px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.14);
	color: #fff;
	cursor: pointer;
	transition: background 0.15s ease;
}
.be-lightbox__nav:hover {
	background: rgba(255, 255, 255, 0.3);
}
.be-lightbox__nav svg {
	width: 24px;
	height: 24px;
}
.be-lightbox__close:focus-visible,
.be-lightbox__nav:focus-visible {
	outline: 2px solid #fff;
	outline-offset: 2px;
}
.be-lightbox__count {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 1rem;
	margin: 0;
	text-align: center;
	color: rgba(255, 255, 255, 0.75);
	font-size: 0.8rem;
	letter-spacing: 0.04em;
}
@media (max-width: 781px) {
	.be-lightbox {
		padding: 2.5vh 0.5rem;
		gap: 0.25rem;
	}
	.be-lightbox__nav {
		width: 38px;
		height: 38px;
	}
	.be-lightbox__image {
		max-height: 78vh;
	}
}

/* The "Other" header dropdown holds only short items ("Tours", "IBDP
   Tutoring"), so it should size to its longest label, not to a fixed box. Core nav
   CSS forces every open submenu to min-width:200px / width:auto, and because
   the nav is right-justified the submenu is pinned with left:auto;right:0 —
   so those 200px extend leftward and visually overlap the "Services" menu.
   The core rules that do this are applied on :hover / [aria-expanded=true] /
   :focus-within at specificity (0,4,0)-(0,5,0), so each state is matched here
   with one extra class to win. Result: the box shrinks to fit its widest item. */
.wp-block-navigation .be-tours-submenu.has-child > .wp-block-navigation__submenu-container,
.wp-block-navigation .be-tours-submenu.has-child:hover > .wp-block-navigation__submenu-container,
.wp-block-navigation .be-tours-submenu.has-child:focus-within > .wp-block-navigation__submenu-container,
.wp-block-navigation .be-tours-submenu.has-child .wp-block-navigation-submenu__toggle[aria-expanded="true"] ~ .wp-block-navigation__submenu-container {
	min-width: 0;
	width: max-content;
}


/* Form 6 (IB Tutoring Enquiry): section heading introducing the student's
   details. Deliberately NOT boxed like .be-form-note - it labels the section
   below it rather than calling out a message. */
.be-student-heading p {
	margin-top: 0.5rem;
	margin-bottom: 0.75rem;
	color: var(--be-muted);
	font-size: 0.95rem;
}
.be-student-heading strong {
	color: var(--be-primary);
	font-size: 1.05rem;
}

/* --- "Book a Consultation" CTA: header on desktop, overlay menu on mobile ---

   The CTA exists twice, in two different places in the DOM, because a
   wp:navigation block only renders its own menu items inside the mobile
   overlay — a sibling wp:buttons block can never be moved in there by CSS:

     - desktop: the wp:buttons block beside the nav (template part 120,
       classed ".be-header-cta")
     - mobile:  a navigation-link in menu 159 (classed ".be-nav-cta"), which
       lands at the bottom of the expanded overlay with the page links

   Each is hidden at the breakpoint where the other shows, so exactly one is
   ever visible. 600px is core's own breakpoint for overlayMenu "mobile" —
   if the nav block's overlay setting is ever changed, change this with it or
   the CTA shows twice (or not at all).

   Keep the two labels and hrefs in step; they are the same button to a
   visitor. */
.wp-block-navigation-item.be-nav-cta {
	display: none;
}

@media (max-width: 600px) {
	/* Both selectors needed: core's block library declares
	   ".wp-block-buttons { display: flex }" at the same specificity and is
	   enqueued after the theme stylesheet, so a bare ".be-header-cta" loses
	   the tie and the button stays visible on the phone. */
	.wp-block-buttons.be-header-cta {
		display: none;
	}

	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item.be-nav-cta {
		display: block;
		margin-top: 0.75rem;
	}

	/* Painted to match .is-style-be-white (white on navy), since the overlay
	   background is navy and a plain link would read as another page link. */
	.wp-block-navigation__responsive-container.is-menu-open .be-nav-cta > .wp-block-navigation-item__content {
		display: inline-block;
		background-color: #fff;
		color: var(--be-primary);
		font-family: var(--wp--preset--font-family--heading);
		font-weight: 600;
		border-radius: 10px;
		padding: 0.85rem 1.6rem;
		text-decoration: none;
	}

	.wp-block-navigation__responsive-container.is-menu-open .be-nav-cta > .wp-block-navigation-item__content:hover,
	.wp-block-navigation__responsive-container.is-menu-open .be-nav-cta > .wp-block-navigation-item__content:focus {
		background-color: var(--be-light);
		color: var(--be-navy);
	}
}

/* --- Google Maps meeting-point embeds (owner-added, in the pages only) ---

   Google's "embed a map" snippet hardcodes width="400" height="300" with no
   responsive CSS, and the seven tour pages paste it verbatim into a wp:html
   block. At a 390px phone that is 20px of page padding + 400px = 420px of
   content, i.e. 30px of horizontal overflow.

   That is not merely a stray sideways scroll. On Android, Chrome grows the
   *initial containing block* to the overflowing width, and every
   "position: fixed" overlay is measured against that inflated box — so the
   nav's mobile overlay (fixed, inset:0, right-justified) rendered ~30px past
   the right edge of the screen and its items ran off it. Exactly the same
   failure mode as the .be-gallery__thumb sr-only-span bug of 2026-08-04, from
   a different source. Measured 2026-08-06: innerWidth 421 at a 390px viewport.

   Fixed here rather than in the page content on purpose: these embeds are the
   owner's own block-editor edits and are NOT in the tour patterns, so
   rewriting post_content would put them in the path of the next pattern push.
   CSS also catches the next map he pastes in, since Google always emits the
   same fixed width. */
.wp-site-blocks iframe {
	max-width: 100%;
}
.wp-site-blocks iframe[src*="/maps/embed"] {
	display: block;
	width: 100%;
}

/* --- Mobile overlay: collapsible submenus (2026-08-06) ---

   Core renders the mobile overlay with every submenu permanently expanded:
   ".is-menu-open ... .has-child .wp-block-navigation__submenu-container"
   forces opacity/visibility/position, and a separate rule sets
   "display: none" on ".wp-block-navigation__submenu-icon" — i.e. it hides the
   disclosure button precisely because nothing is collapsed. That is what made
   the overlay a flat 14-item list.

   The block's own "open on click" attribute is NOT the fix: it also drops the
   <a> in favour of a <button> on desktop, so the desktop menu would stop
   opening on hover. This is CSS only, scoped to the open overlay under 600px,
   and rides on markup core already ships — the toggle <button> is in the DOM
   either way, with aria-expanded bound to core's Interactivity store.

   No JS of ours is involved. Core's own view module owns the state, so the
   keyboard, focus and aria handling stay core's.

   Touch is safe: core's openMenuOnHover()/closeMenuOnHover() return early on
   pointerType "touch", and additionally do nothing while the overlay is open
   — so inside the overlay the click toggle is the only thing that opens a
   submenu. Verified in a touch-emulating context, not assumed.

   Layout: the <li> is flex-column in the overlay (a, button, ul stacked), so
   it is re-laid-out as a grid to put the <a> and the toggle in the SAME cell
   (row 1) with the submenu below (row 2). The toggle is stretched over the
   whole row, so tapping the label toggles rather than following its dead
   href="#" — a chevron alone is an ~11px target and the word beside it would
   look broken. The anchor gets padding-inline-end so the right-aligned label
   never sits under the chevron. */
@media (max-width: 600px) {
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item.has-child {
		display: grid;
		grid-template-columns: minmax(0, 1fr);
		justify-items: end;
	}

	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item.has-child > .wp-block-navigation-item__content {
		grid-area: 1 / 1;
		padding-inline-end: 1.35em;
	}

	/* Un-hide the disclosure button and stretch it across row 1, on top of the
	   label. width/height are reset because core sizes the icon button to a
	   .6em square, which would otherwise ignore the stretch. */
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item.has-child > .wp-block-navigation-submenu__toggle.wp-block-navigation__submenu-icon {
		grid-area: 1 / 1;
		display: flex;
		align-items: center;
		justify-content: flex-end;
		justify-self: stretch;
		align-self: stretch;
		width: auto;
		height: auto;
		/* A menu row is only ~23px of text. The padding/negative-margin pair
		   grows the tap target to ~40px without moving anything: the row gap
		   is 24px, so 8.8px of bleed each side stays inside it and never
		   overlaps the neighbouring row's target. */
		padding-block: 0.55rem;
		margin-block: -0.55rem;
		padding-inline: 0;
		margin-inline: 0;
		background: transparent;
		z-index: 1;
	}

	/* The SVG sizes off the button, which is now auto rather than .6em. */
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item.has-child > .wp-block-navigation-submenu__toggle > svg {
		width: 0.85em;
		height: 0.85em;
		transition: transform 0.18s ease;
	}

	/* Collapsed by default; core rotates the chevron 180deg when expanded. */
	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item.has-child > .wp-block-navigation__submenu-container {
		grid-area: 2 / 1;
		justify-self: stretch;
		display: none;
	}

	.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item.has-child > .wp-block-navigation-submenu__toggle[aria-expanded="true"] ~ .wp-block-navigation__submenu-container {
		display: flex;
	}
}
