/* =========================================================================
 * blx-site.css — the guest-facing design system.
 *
 * WHY THIS FILE EXISTS, AND WHY IT IS NOT AN OVERRIDE
 *
 * The front end used to be a 48KB dark-first stylesheet with an 11KB "powder"
 * sheet layered on top to make it light. That arrangement guarantees the gaps
 * it produced: every new component is styled dark first and then has to be
 * remembered a second time in the light sheet, and whatever is forgotten shows
 * up as a white card on a white page, or black text on black. The sign-in card
 * being unstyled under powder was not a bug in that sheet — it was the
 * architecture reporting itself.
 *
 * So this is light-FIRST and token-driven. One palette block, declared once.
 * Dark is a token swap under `.blxn-dark`, not a parallel stylesheet, which
 * means a component can only be styled once and cannot be half-converted.
 *
 * It also uses its own `blxn-` class namespace rather than reusing the old
 * `blx-` marketing classes. That is deliberate: the old sheet still styles the
 * quote planner and the booking widget, and sharing class names with it would
 * mean every rule here fighting a specificity battle it can only win by
 * escalating. A separate vocabulary lets the redesigned surfaces be
 * authoritative and the un-redesigned ones keep working, untouched.
 *
 * SCALE
 *   Type and space both move on a ratio rather than by eye, so a section
 *   written next year sits on the same grid as one written today.
 * ====================================================================== */

/*
 * body.blxn, not .blxn — and the reason is the whole reason this pass exists.
 *
 * The legacy sheet declares `body.blx{background:var(--bg);color:var(--text)}`
 * at specificity (0,1,1). A bare `.blxn` is (0,1,0) and LOSES, so on a default
 * install the page kept the old near-black background while these components
 * painted near-black headings on top of it — #0e0d0c on #0a0a0a, a contrast
 * ratio of 1.02:1. The redesign would have shipped invisible.
 *
 * The custom properties are namespaced for the same reason: --line, --serif
 * and --maxw all exist in the legacy sheet on :root, and declaring them again
 * on <body> silently re-colours every legacy component that inherits them.
 */
body.blxn {
	/* ---- ink & paper ------------------------------------------------- */
	--blxn-paper: #fbfaf7;          /* the page — warm, not clinical white */
	--blxn-paper-2: #f3f1ec;        /* banded sections, cards at rest */
	--blxn-paper-3: #e9e6de;        /* hairline fills, hovers */
	--blxn-ink: #1a1917;            /* body copy */
	--blxn-ink-strong: #0e0d0c;     /* headings */
	--blxn-ink-soft: #6b6760;       /* captions, meta, eyebrows */
	--blxn-line: #ded9cf;
	--blxn-line-2: #c9c3b6;

	/* ---- accent ------------------------------------------------------ */
	/* Brass rather than the old bright gold: on paper the bright value is
	   close to unreadable, and the darker tone carries the same idea while
	   passing contrast as a text colour. */
	--blxn-brass: #8a6a12;
	--blxn-brass-2: #b58a1a;
	--blxn-brass-wash: rgba(181, 138, 26, .10);
	--blxn-brass-line: rgba(181, 138, 26, .32);

	/* ---- type -------------------------------------------------------- */
	--blxn-serif: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
	--blxn-sans: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

	--blxn-t-hero: clamp(38px, 6.2vw, 76px);
	--blxn-t-h2: clamp(27px, 3.5vw, 44px);
	--blxn-t-h3: clamp(18px, 1.5vw, 21px);
	--blxn-t-lead: clamp(16px, 1.35vw, 19px);
	--blxn-t-body: 16px;
	--blxn-t-small: 14px;
	--blxn-t-eyebrow: 12px;

	/* ---- space ------------------------------------------------------- */
	--blxn-s1: 4px;
	--blxn-s2: 8px;
	--blxn-s3: 12px;
	--blxn-s4: 16px;
	--blxn-s5: 24px;
	--blxn-s6: 32px;
	--blxn-s7: 48px;
	--blxn-s8: 64px;
	--blxn-s9: 96px;
	--blxn-section-y: clamp(56px, 8vw, 112px);
	--blxn-maxw: 1240px;
	--blxn-radius: 3px;
	--blxn-radius-lg: 6px;

	--blxn-shadow: 0 1px 2px rgba(26, 25, 23, .04), 0 4px 16px -8px rgba(26, 25, 23, .12);
	--blxn-shadow-lg: 0 24px 60px -32px rgba(26, 25, 23, .32);

	background: var(--blxn-paper);
	color: var(--blxn-ink);
	font-family: var(--blxn-sans);
	font-size: var(--blxn-t-body);
	line-height: 1.65;
	-webkit-font-smoothing: antialiased;
}

/* The dark treatment: the SAME components, different values. Nothing below
   this line in the file is written twice. */
body.blxn-dark,
body.blxn .blxn-dark {
	--blxn-paper: #0f0e0c;
	--blxn-paper-2: #171613;
	--blxn-paper-3: #201e1a;
	--blxn-ink: #ddd9d0;
	--blxn-ink-strong: #f6f4ef;
	--blxn-ink-soft: #948f85;
	--blxn-line: #2a2823;
	--blxn-line-2: #3b382f;
	--blxn-brass: #d9b558;
	--blxn-brass-2: #e3c25a;
	--blxn-brass-wash: rgba(227, 194, 90, .10);
	--blxn-brass-line: rgba(227, 194, 90, .30);
	background: var(--blxn-paper);
	color: var(--blxn-ink);
}

/* =========================================================================
 * Primitives
 * ====================================================================== */

.blxn *,
.blxn *::before,
.blxn *::after {
	box-sizing: border-box;
}

.blxn img {
	max-width: 100%;
	display: block;
}

.blxn-wrap {
	width: 100%;
	max-width: var(--blxn-maxw);
	margin-inline: auto;
	padding-inline: clamp(20px, 5vw, 48px);
}

/* Paints its own ground. Relying on the body's background means any theme or
   legacy sheet that wins the body rule leaves these sections transparent over
   whatever is behind them. */
.blxn-section {
	padding-block: var(--blxn-section-y);
	background: var(--blxn-paper);
	color: var(--blxn-ink);
}

.blxn-section--band {
	background: var(--blxn-paper-2);
}

/* A rule, not a border: used to separate without boxing anything in. */
.blxn-section + .blxn-section:not(.blxn-section--band) {
	border-top: 1px solid var(--blxn-line);
}

.blxn-eyebrow {
	display: block;
	font-size: var(--blxn-t-eyebrow);
	font-weight: 600;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--blxn-brass);
}

.blxn-h1,
.blxn-h2,
.blxn-h3 {
	font-family: var(--blxn-serif);
	font-weight: 600;
	color: var(--blxn-ink-strong);
	letter-spacing: -.01em;
	line-height: 1.08;
	margin: 0;
	text-wrap: balance;
}

.blxn-h1 { font-size: var(--blxn-t-hero); }
.blxn-h2 { font-size: var(--blxn-t-h2); }

.blxn-h3 {
	font-family: var(--blxn-sans);
	font-size: var(--blxn-t-h3);
	font-weight: 600;
	line-height: 1.3;
	letter-spacing: 0;
}

.blxn-lead {
	font-size: var(--blxn-t-lead);
	line-height: 1.6;
	color: var(--blxn-ink-soft);
	max-width: 62ch;
	text-wrap: pretty;
}

.blxn-p {
	margin: 0;
	color: var(--blxn-ink-soft);
	text-wrap: pretty;
}

/* Section headers, in the two arrangements the pages actually use. */
.blxn-head {
	margin-bottom: var(--blxn-s7);
}
.blxn-head .blxn-h2 {
	margin-top: var(--blxn-s3);
}
.blxn-head--center {
	text-align: center;
	max-width: 68ch;
	margin-inline: auto;
}
.blxn-head--row {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--blxn-s5);
	flex-wrap: wrap;
}

/* =========================================================================
 * Buttons
 *
 * Two weights only. A page with four button styles is a page where nothing
 * reads as the primary action.
 * ====================================================================== */

.blxn-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--blxn-s2);
	/* 48px tall: a thumb target, not a mouse target. */
	min-height: 48px;
	padding: 13px 26px;
	border: 1px solid transparent;
	border-radius: var(--blxn-radius);
	font-family: var(--blxn-sans);
	font-size: var(--blxn-t-small);
	font-weight: 600;
	letter-spacing: .08em;
	text-transform: uppercase;
	text-decoration: none;
	cursor: pointer;
	transition: background-color .18s ease, color .18s ease, border-color .18s ease, transform .18s ease;
}

/* Prefixed with .blxn (0,2,0) so they beat the legacy `.blx a{color:inherit}`
   at (0,1,1). Without this the header and footer Reserve buttons inherit the
   page's link colour and render dark-on-dark. */
.blxn .blxn-btn--primary {
	background: var(--blxn-ink-strong);
	color: var(--blxn-paper);
}
.blxn .blxn-btn--primary:hover,
.blxn .blxn-btn--primary:focus-visible {
	background: var(--blxn-brass);
	color: #fff;
}

.blxn .blxn-btn--ghost {
	background: transparent;
	color: var(--blxn-ink-strong);
	border-color: var(--blxn-line-2);
}
.blxn .blxn-btn--ghost:hover,
.blxn .blxn-btn--ghost:focus-visible {
	border-color: var(--blxn-ink-strong);
	background: var(--blxn-paper-3);
}

/* On photography, where the surface behind is unknown. */
.blxn .blxn-ondark .blxn-btn--primary {
	background: #fff;
	color: #14130f;
}
.blxn .blxn-ondark .blxn-btn--primary:hover {
	background: var(--blxn-brass-2);
	color: #14130f;
}
.blxn .blxn-ondark .blxn-btn--ghost {
	color: #fff;
	border-color: rgba(255, 255, 255, .55);
}
.blxn .blxn-ondark .blxn-btn--ghost:hover {
	background: rgba(255, 255, 255, .12);
	border-color: #fff;
}

.blxn-btn:active {
	transform: translateY(1px);
}

/* One focus treatment for everything interactive. */
.blxn a:focus-visible,
.blxn button:focus-visible,
.blxn input:focus-visible,
.blxn select:focus-visible,
.blxn textarea:focus-visible {
	outline: 2px solid var(--blxn-brass);
	outline-offset: 3px;
	border-radius: var(--blxn-radius);
}

.blxn .blxn-textlink {
	color: var(--blxn-brass);
	font-size: var(--blxn-t-small);
	font-weight: 600;
	letter-spacing: .06em;
	text-transform: uppercase;
	text-decoration: none;
	white-space: nowrap;
	border-bottom: 1px solid var(--blxn-brass-line);
	padding-bottom: 2px;
}
.blxn-textlink:hover {
	border-bottom-color: var(--blxn-brass);
}

/* =========================================================================
 * Hero
 *
 * The old hero put white text on a photograph with a flat 45% black wash,
 * which is legible on the picture it was designed against and a coin toss on
 * any other. A gradient anchored to the text side holds contrast whatever the
 * operator uploads.
 * ====================================================================== */

/* Same-origin navigations cross-fade in browsers with cross-document view
   transitions — the other half of the pair declared in the widget's CSS, so
   home → booking (an airport tile, a Reserve button) glides instead of
   cutting. Ignored everywhere else. */
@view-transition{ navigation: auto; }

.blxn-hero {
	position: relative;
	display: flex;
	align-items: flex-end;
	min-height: min(86vh, 780px);
	background: #14130f;
	overflow: hidden;
}

.blxn-hero__bg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.blxn-hero__scrim {
	position: absolute;
	inset: 0;
	background:
		linear-gradient(to top, rgba(12, 11, 9, .88) 0%, rgba(12, 11, 9, .55) 38%, rgba(12, 11, 9, .12) 68%, rgba(12, 11, 9, .30) 100%);
}

.blxn-hero__inner {
	position: relative;
	width: 100%;
	padding-block: clamp(48px, 9vw, 104px);
}

/* Measured against the HEADLINE's size, not the body's. A 40ch limit is a
   comfortable paragraph at 16px and a four-line stack at 76px — the ch unit
   follows the element it is set on, and this element's child is six times
   larger. Sized in px so the hero reads as two or three lines at every
   width, with the lead paragraph given its own narrower measure below. */
.blxn-hero__col {
	max-width: min(100%, 780px);
}

.blxn-hero .blxn-h1 {
	color: #fff;
	margin-top: var(--blxn-s4);
}

.blxn-hero .blxn-lead {
	color: rgba(255, 255, 255, .84);
	margin-top: var(--blxn-s5);
	max-width: 52ch;
}

.blxn-hero .blxn-eyebrow {
	color: var(--blxn-brass-2);
}

.blxn-cta-row {
	display: flex;
	flex-wrap: wrap;
	gap: var(--blxn-s3);
	margin-top: var(--blxn-s7);
}

/* The shorter hero used by Fleet and Tours — tall enough that an uploaded
   photograph reads as a place, not a letterbox strip. */
.blxn-subhero {
	min-height: min(64vh, 580px);
}

/* =========================================================================
 * Cards & grids
 * ====================================================================== */

.blxn-grid {
	display: grid;
	gap: var(--blxn-s5);
}
.blxn-grid--2 { grid-template-columns: repeat(2, 1fr); }
.blxn-grid--3 { grid-template-columns: repeat(3, 1fr); }
.blxn-grid--4 { grid-template-columns: repeat(4, 1fr); }

/* A destination: photograph, name, and the reason to click. */
.blxn-dest {
	position: relative;
	display: block;
	aspect-ratio: 4 / 5;
	overflow: hidden;
	border-radius: var(--blxn-radius-lg);
	text-decoration: none;
	background: var(--blxn-paper-3);
}
.blxn-dest img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform .7s cubic-bezier(.2, .7, .3, 1);
}
.blxn-dest:hover img {
	transform: scale(1.045);
}
.blxn-dest__scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(to top, rgba(12, 11, 9, .82) 4%, rgba(12, 11, 9, .28) 46%, rgba(12, 11, 9, 0) 72%);
}
.blxn-dest__cap {
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	padding: var(--blxn-s5);
	color: #fff;
}
.blxn-dest__region {
	display: block;
	font-size: var(--blxn-t-eyebrow);
	font-weight: 600;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, .74);
}
.blxn-dest__cap .blxn-h3 {
	font-family: var(--blxn-serif);
	font-size: clamp(24px, 2.4vw, 32px);
	color: #fff;
	margin-top: var(--blxn-s1);
}
.blxn-dest__go {
	display: inline-block;
	margin-top: var(--blxn-s3);
	font-size: var(--blxn-t-small);
	font-weight: 600;
	letter-spacing: .06em;
	color: var(--blxn-brass-2);
}

/* A numbered cell: occasions, reasons, anything enumerated. */
.blxn-cell {
	padding-top: var(--blxn-s5);
	border-top: 1px solid var(--blxn-line);
}
.blxn-cell__num {
	display: block;
	font-family: var(--blxn-serif);
	font-size: 15px;
	font-weight: 600;
	color: var(--blxn-brass);
	letter-spacing: .1em;
}
.blxn-cell .blxn-h3 {
	margin: var(--blxn-s3) 0 var(--blxn-s2);
}

/* An airport, or any short code-led tile. */
.blxn-tile {
	display: block;
	padding: var(--blxn-s5);
	border: 1px solid var(--blxn-line);
	border-radius: var(--blxn-radius-lg);
	background: var(--blxn-paper);
	text-decoration: none;
	color: inherit;
	transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.blxn-tile:hover {
	border-color: var(--blxn-brass-line);
	box-shadow: var(--blxn-shadow);
	transform: translateY(-2px);
}
.blxn-tile__code {
	display: block;
	font-family: var(--blxn-serif);
	font-size: 34px;
	font-weight: 700;
	color: var(--blxn-brass);
	line-height: 1;
}
.blxn-tile .blxn-h3 {
	margin: var(--blxn-s3) 0 var(--blxn-s1);
}

/* The two-column feature: copy beside a picture. */
.blxn-feature {
	display: grid;
	grid-template-columns: 1fr 1.15fr;
	gap: clamp(32px, 5vw, 72px);
	align-items: center;
}
.blxn-feature__media {
	display: block;
	position: relative;
	overflow: hidden;
	border-radius: var(--blxn-radius-lg);
	aspect-ratio: 5 / 4;
}
.blxn-feature__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform .7s cubic-bezier(.2, .7, .3, 1);
}
.blxn-feature__media:hover img {
	transform: scale(1.04);
}

/* A specification row — vehicle, capacity. */
.blxn-spec {
	margin: var(--blxn-s6) 0;
	border-top: 1px solid var(--blxn-line);
}
.blxn-spec__row {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: var(--blxn-s4);
	padding: var(--blxn-s3) 0;
	border-bottom: 1px solid var(--blxn-line);
}
.blxn-spec__name {
	font-weight: 600;
	color: var(--blxn-ink-strong);
}
.blxn-spec__meta {
	font-size: var(--blxn-t-small);
	color: var(--blxn-ink-soft);
	text-align: right;
}

/* A point: number beside prose. */
.blxn-point {
	display: flex;
	gap: var(--blxn-s4);
	align-items: flex-start;
}
.blxn-point__n {
	flex: none;
	width: 38px;
	font-family: var(--blxn-serif);
	font-size: 19px;
	font-weight: 600;
	color: var(--blxn-brass);
	padding-top: 2px;
}

/* Named organisations, set as type rather than as fake logos. */
.blxn-clients {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--blxn-s3) var(--blxn-s6);
	max-width: 92ch;
	margin-inline: auto;
}
.blxn-clients span {
	font-family: var(--blxn-serif);
	font-size: clamp(16px, 1.5vw, 20px);
	color: var(--blxn-ink-soft);
	white-space: nowrap;
}
.blx-note,
.blxn-note {
	margin-top: var(--blxn-s6);
	text-align: center;
	font-size: var(--blxn-t-small);
	color: var(--blxn-ink-soft);
}

/* =========================================================================
 * Closing call to action
 * ====================================================================== */

.blxn-close {
	/*
	 * A literal, deliberately. This band's job is to be the page's dark
	 * full-stop in BOTH themes — but under the dark tokens --blxn-ink-strong
	 * flips to near-white, which would have painted a glowing cream slab
	 * with white type on it. The one component whose colour IS its identity
	 * does not read from the palette that exists to change identities.
	 */
	background: #0e0d0c;
	color: #fff;
	padding-block: clamp(56px, 8vw, 104px);
	text-align: center;
}
.blxn-close .blxn-h2 {
	color: #fff;
}
.blxn-close .blxn-lead {
	color: rgba(255, 255, 255, .78);
	margin: var(--blxn-s4) auto 0;
	text-align: center;
}
.blxn-close .blxn-cta-row {
	justify-content: center;
	margin-top: var(--blxn-s6);
}

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

.blxn-header {
	position: sticky;
	top: 0;
	z-index: 50;
	background: rgba(251, 250, 247, .92);
	backdrop-filter: saturate(1.4) blur(12px);
	border-bottom: 1px solid var(--blxn-line);
}
/* The translucent chrome wash cannot come from a token — alpha is baked into
   the value — so the dark theme restates it. */
body.blxn-dark .blxn-header {
	background: rgba(15, 14, 12, .88);
}
.blxn-header .blxn-wrap {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--blxn-s5);
	min-height: 76px;
}
.blxn-brand {
	display: flex;
	flex-direction: column;
	justify-content: center;
	/* The brand is the way back to the home page, and on a phone it is the
	   only link in the header besides the burger. Sized as a target. */
	min-height: 44px;
	text-decoration: none;
	color: var(--blxn-ink-strong);
	line-height: 1.2;
}
.blxn-brand__name {
	display: block;
	font-family: var(--blxn-serif);
	font-size: clamp(19px, 2vw, 24px);
	font-weight: 600;
	letter-spacing: .01em;
}
.blxn-brand__sub {
	display: block;
	margin-top: 2px;
	font-size: 11px;
	letter-spacing: .13em;
	text-transform: uppercase;
	color: var(--blxn-ink-soft);
	/* An operator may list six towns here. One line or none — a service area
	   that wraps doubles the height of a sticky header on every phone. */
	max-width: 46ch;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.blxn-nav {
	display: flex;
	align-items: center;
	gap: var(--blxn-s5);
}
/* :not(.blxn-btn) is load-bearing. A bare `.blxn-nav a` is specificity
   (0,1,1) and beats `.blxn-btn--primary` at (0,1,0), so the Reserve button
   sitting inside the nav took the link colour and rendered near-black text
   on a near-black background — the most important button on the site, all
   but invisible, on every page. Excluding buttons here keeps the component
   authoritative about its own colours wherever it is placed. */
.blxn-nav a:not(.blxn-btn) {
	font-size: var(--blxn-t-small);
	font-weight: 500;
	color: var(--blxn-ink);
	text-decoration: none;
	padding-block: var(--blxn-s2);
}
.blxn-nav a:not(.blxn-btn):hover {
	color: var(--blxn-brass);
}
.blxn-burger {
	display: none;
	flex-direction: column;
	justify-content: center;
	gap: 5px;
	width: 48px;
	height: 48px;
	padding: 0 12px;
	background: none;
	border: 0;
	cursor: pointer;
}
.blxn-burger span {
	display: block;
	height: 1.5px;
	background: var(--blxn-ink-strong);
	transition: transform .22s ease, opacity .22s ease;
}
.blxn-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.blxn-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.blxn-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

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

.blxn-footer {
	background: var(--blxn-paper-2);
	border-top: 1px solid var(--blxn-line);
	padding-block: var(--blxn-s9) var(--blxn-s6);
}
.blxn-footer__cols {
	display: grid;
	grid-template-columns: 1.4fr repeat(3, 1fr);
	gap: var(--blxn-s7) var(--blxn-s5);
}
.blxn-footer__name {
	display: block;
	font-family: var(--blxn-serif);
	font-size: 22px;
	font-weight: 600;
	color: var(--blxn-ink-strong);
	margin-bottom: var(--blxn-s3);
}
.blxn-footer p {
	margin: 0 0 var(--blxn-s2);
	font-size: var(--blxn-t-small);
	color: var(--blxn-ink-soft);
}
.blxn-colhead {
	display: block;
	font-size: var(--blxn-t-eyebrow);
	font-weight: 700;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--blxn-ink-strong);
	margin-bottom: var(--blxn-s4);
}
.blxn-links {
	display: flex;
	flex-direction: column;
	gap: var(--blxn-s3);
	align-items: flex-start;
}
/* Same trap as the nav: the footer's Reserve button lives in this list. */
.blxn-links a:not(.blxn-btn) {
	font-size: var(--blxn-t-small);
	color: var(--blxn-ink-soft);
	text-decoration: none;
}
.blxn-links a:not(.blxn-btn):hover {
	color: var(--blxn-brass);
}
.blxn-footer__base {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: var(--blxn-s4);
	margin-top: var(--blxn-s8);
	padding-top: var(--blxn-s5);
	border-top: 1px solid var(--blxn-line);
	font-size: 13px;
	color: var(--blxn-ink-soft);
}

/* =========================================================================
 * Reveal on scroll — opt-in, and off entirely for anyone who asked for less
 * motion. Content is visible by default so a JavaScript failure can never
 * leave the page blank.
 * ====================================================================== */

@media (prefers-reduced-motion: no-preference) {
	/* Gated on the `blxn-js` class, which the script adds to <html> as its
	   first act. Without that gate the hidden state is the DEFAULT state, and
	   a script that 404s, is blocked, or throws before its observer is wired
	   leaves every revealed section permanently invisible — a blank page
	   caused by a decoration. */
	.blxn-js .blxn-reveal {
		opacity: 0;
		transform: translateY(14px);
		transition: opacity .6s ease, transform .6s cubic-bezier(.2, .7, .3, 1);
	}
	.blxn-js .blxn-reveal.is-in {
		opacity: 1;
		transform: none;
	}
}

/* =========================================================================
 * Responsive
 *
 * Written as the layout genuinely changing, not as things being hidden.
 * ====================================================================== */

@media (max-width: 1000px) {
	.blxn-grid--4 { grid-template-columns: repeat(2, 1fr); }
	.blxn-feature { grid-template-columns: 1fr; }
	.blxn-feature__media { order: -1; aspect-ratio: 16 / 10; }
	.blxn-footer__cols { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 1024px) {
	/* Text links become tap targets. 23px is a comfortable line of type and
	   an uncomfortable thing to hit with a thumb. */
	.blxn-links a,
	.blxn-textlink {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}

	/* On a phone the name is the header; the service area is a line the page
	   itself says better, twice. */
	.blxn-brand__sub { display: none; }

	.blxn-nav {
		position: fixed;
		inset: 76px 0 auto;
		/* Nine links and a button is ~470px. On a phone in landscape there is
		   less than 300px below the header, and the Reserve button is last —
		   without this it is simply off-screen and unreachable. */
		max-height: calc(100dvh - 76px);
		overflow-y: auto;
		overscroll-behavior: contain;
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		padding: var(--blxn-s4) clamp(20px, 5vw, 48px) var(--blxn-s6);
		background: var(--blxn-paper);
		border-bottom: 1px solid var(--blxn-line);
		box-shadow: var(--blxn-shadow-lg);
		transform: translateY(-8px);
		opacity: 0;
		visibility: hidden;
		transition: opacity .2s ease, transform .2s ease, visibility .2s;
	}
	.blxn-nav.is-open {
		transform: none;
		opacity: 1;
		visibility: visible;
	}
	.blxn-nav a {
		padding-block: var(--blxn-s4);
		border-bottom: 1px solid var(--blxn-line);
		font-size: 16px;
	}
	.blxn-burger { display: flex; }

	.blxn-grid--3,
	.blxn-grid--4,
	.blxn-grid--2 { grid-template-columns: 1fr; }

	.blxn-dest { aspect-ratio: 16 / 11; }

	.blxn-head--row { align-items: flex-start; }

	/* A full-width button beats two half-width ones a thumb has to aim at. */
	.blxn-cta-row .blxn-btn { flex: 1 1 100%; }

	.blxn-footer__cols { grid-template-columns: 1fr; gap: var(--blxn-s6); }
	.blxn-hero { min-height: 78vh; }
}

@media print {
	.blxn-header,
	.blxn-burger,
	.blxn-close { display: none; }
	.blxn { background: #fff; }
}

/* =========================================================================
 * The finishing pass — details that separate "clean" from "considered".
 * Nothing structural: rhythm, texture and reward states only.
 * ====================================================================== */

body.blxn ::selection {
	background: var(--blxn-brass-wash);
	color: var(--blxn-brass);
}

/* An eyebrow in a section head announces itself with a short brass rule —
   the recurring signature that ties the pages together. */
.blxn-head .blxn-eyebrow::before {
	content: "";
	display: inline-block;
	width: 26px;
	height: 1px;
	background: var(--blxn-brass-2);
	vertical-align: middle;
	margin-right: 12px;
	transform: translateY(-1px);
}
.blxn-head--center .blxn-eyebrow::before {
	display: none;
}

/* Enumerated marks in serif italic — the typographic wink that says these
   numbers are furniture, not data. */
.blxn-cell__num,
.blxn-point__n {
	font-style: italic;
	font-weight: 500;
}

/* A destination card rewards the hover: the caption lifts a breath and the
   "get a price" line brightens. The photograph already moves; the text
   answering it is what makes the card feel alive rather than animated. */
.blxn-dest__cap {
	transition: transform .5s cubic-bezier(.2, .7, .3, 1);
}
.blxn-dest:hover .blxn-dest__cap {
	transform: translateY(-4px);
}
.blxn-dest__go {
	transition: color .25s ease;
}
.blxn-dest:hover .blxn-dest__go {
	color: #fff;
}

/* Airport tiles: the code answers the hover in brass-2. */
.blxn-tile__code {
	transition: color .25s ease;
}
.blxn-tile:hover .blxn-tile__code {
	color: var(--blxn-brass-2);
}

/* The closing band gets one brass hairline at its top edge — the page's
   full-stop, and the only place the accent runs full width. */
.blxn-close {
	position: relative;
}
.blxn-close::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 1px;
	background: linear-gradient(90deg, transparent, var(--blxn-brass-2) 30%, var(--blxn-brass-2) 70%, transparent);
	opacity: .55;
}

/* Long-form numerals (prices, codes) sit better tabular. */
.blxn-spec__meta,
.blxn-tile__code {
	font-variant-numeric: tabular-nums;
}

/* =========================================================================
 * The booking pop-over — the dispatch board's pop, over the guest site.
 * ====================================================================== */
html.blx-bookpop-lock, html.blx-bookpop-lock body { overflow: hidden; }
.blx-bookpop {
	position: fixed; inset: 0; z-index: 2147482800;
	transform: translateY(34px) scale(.965); opacity: 0; border-radius: 14px;
	overflow: hidden; will-change: transform;
	box-shadow: 0 40px 120px -40px rgba(0, 0, 0, .55);
	transition: transform .5s cubic-bezier(.22, .8, .25, 1), opacity .32s ease, border-radius .5s;
}
.blx-bookpop.open { transform: none; opacity: 1; border-radius: 0; }
.blx-bookpop.sheet {
	transform: translateY(100%); opacity: 1; border-radius: 18px 18px 0 0;
	transition: transform .42s cubic-bezier(.22, .8, .25, 1), border-radius .42s;
}
.blx-bookpop.sheet.open { transform: none; border-radius: 0; }
.blx-bookpop .bp-frame {
	width: 100%; height: 100%; border: 0; display: block;
	opacity: 0; transition: opacity .3s .08s;
}
.blx-bookpop.ready .bp-frame { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
	.blx-bookpop, .blx-bookpop.sheet { transition: opacity .15s; transform: none; }
	.blx-bookpop .bp-frame { transition: none; opacity: 1; }
}
