/*
 * stardust-theme.css — the booking site's own layer, on top of the marketing
 * site's Axis build.
 *
 * Load order in chrome-head.php is: Bootstrap 5.3.8 -> assets/css/main.css ->
 * this file. `main.css` is the Stardust marketing site's stylesheet copied
 * verbatim (TECK-net/stardust-sportfishing public/assets/css/main.css), so the
 * header, navmenu, footer, page-title band, scroll-top button, the ocean
 * palette and the type scale are now literally the same rules both sites run.
 * Update it by re-copying that file; do not hand-edit it here.
 *
 * What is left in THIS file is only what a booking site needs and a marketing
 * site has no concept of: the trip schedule table, the row states, the
 * list/calendar switcher, and the Bootstrap control theming for checkout.
 *
 * Before 2026-09-03 this file was a hand-port of Axis against Bootstrap 3 — ~880
 * lines reproducing the chrome. The framework migration (ops#226) made the real
 * thing loadable, so the reproduction is gone.
 */

/*--------------------------------------------------------------
# Schedule palette
#
# These four are NOT Axis's; they were added for the Resos schedule table and
# were lost when the hand-port's :root block went. main.css owns the brand
# palette (--accent-color et al) and knows nothing about a .scale-table, so the
# schedule's own tokens live here. Values are the marketing site's .sched-table
# colours, so both schedules stay the same design.
--------------------------------------------------------------*/
:root {
	--sched-bar-color: rgb(26, 42, 58);
	--sched-month-color: rgb(26, 143, 209);
	--sched-month-border: #1565a0;
	--sched-shade: #ebeff4;
}

/*--------------------------------------------------------------
# Mobile nav toggle hit area
#
# Axis ships this as an inline <i> with line-height: 0, so the element's box
# collapses to zero height and only the painted glyph looks tappable. Kept as an
# override rather than fixed in main.css, which is a verbatim copy.
--------------------------------------------------------------*/
@media (max-width: 1199px) {
	.mobile-nav-toggle {
		line-height: 1;
		display: inline-flex;
		align-items: center;
		justify-content: center;
		width: 44px;
		height: 44px;
	}
}

/*--------------------------------------------------------------
# Content
--------------------------------------------------------------*/
.resos-content {
	color: var(--default-color);
	background-color: var(--background-color);
	padding: 20px 0 60px;
	overflow: visible;
}

/*--------------------------------------------------------------
# Bootstrap controls, on brand
#
# BS5's default primary is #0d6efd. These repaint the controls a customer
# actually meets in checkout to the brand navy; they restructure nothing.
--------------------------------------------------------------*/
.btn-primary,
a.btn-primary:link,
a.btn-primary:visited {
	--bs-btn-bg: var(--accent-color);
	--bs-btn-border-color: var(--accent-color);
	--bs-btn-color: var(--contrast-color);
	--bs-btn-hover-bg: color-mix(in srgb, var(--accent-color), #000 12%);
	--bs-btn-hover-border-color: color-mix(in srgb, var(--accent-color), #000 20%);
	--bs-btn-hover-color: var(--contrast-color);
	--bs-btn-active-bg: color-mix(in srgb, var(--accent-color), #000 20%);
	--bs-btn-active-border-color: color-mix(in srgb, var(--accent-color), #000 28%);
	--bs-btn-disabled-bg: color-mix(in srgb, var(--accent-color), transparent 45%);
	--bs-btn-disabled-border-color: color-mix(in srgb, var(--accent-color), transparent 45%);
}

/* btn-default was swept to btn-outline-secondary; brand its outline too. */
.btn-outline-secondary {
	--bs-btn-color: var(--accent-color);
	--bs-btn-border-color: color-mix(in srgb, var(--accent-color), transparent 65%);
	--bs-btn-hover-bg: var(--accent-color);
	--bs-btn-hover-border-color: var(--accent-color);
	--bs-btn-hover-color: var(--contrast-color);
}

.form-control:focus,
.form-select:focus {
	border-color: var(--accent-color);
	box-shadow: 0 0 0 .25rem color-mix(in srgb, var(--accent-color), transparent 75%);
}

.pagination {
	--bs-pagination-color: var(--accent-color);
	--bs-pagination-active-bg: var(--accent-color);
	--bs-pagination-active-border-color: var(--accent-color);
	--bs-pagination-focus-box-shadow: 0 0 0 .25rem color-mix(in srgb, var(--accent-color), transparent 75%);
}

.progress { --bs-progress-bar-bg: var(--accent-color); }

/* .panel is a SITE class here, not Bootstrap's — BS5 has no .panel, and
   style-dev.css paints it a pale blue with a heavy drop shadow. Axis's surfaces
   are flat cards on a hairline border, so it is restyled rather than renamed to
   .card, which would lose this rule. */
.panel {
	background: var(--surface-color);
	border: 1px solid color-mix(in srgb, var(--default-color), transparent 88%);
	border-radius: 6px;
	box-shadow: none;
}

.panel h3 { margin-top: 0; }

/*--------------------------------------------------------------
# List / Calendar view switcher
#
# Two Bootstrap 3 buttons; the active one is filled with the brand navy so the
# current view is obvious without reading the labels. `.active` is a colour and
# colour is not information, so view-switch.php also emits aria-current.
--------------------------------------------------------------*/
.view-switch {
	margin: 0 0 28px;
}

.view-switch .btn {
	font-family: var(--nav-font);
	font-size: 14px;
	padding: 9px 22px;
	border-color: color-mix(in srgb, var(--accent-color), transparent 65%);
	color: var(--accent-color);
	background: var(--surface-color);
}

.view-switch .btn i {
	margin-right: 7px;
}

.view-switch .btn:hover,
.view-switch .btn:focus {
	background: color-mix(in srgb, var(--accent-color), transparent 92%);
	color: var(--accent-color);
	border-color: var(--accent-color);
}

/* Bootstrap 3 paints .btn-default.active grey from its own rule, which beats a
   bare .active here, so the filled state is scoped the same way. */
.view-switch .btn.active,
.view-switch .btn.active:hover,
.view-switch .btn.active:focus {
	background: var(--accent-color);
	border-color: var(--accent-color);
	color: var(--contrast-color);
	box-shadow: none;
}

@media (max-width: 480px) {
	.view-switch .btn { padding: 9px 14px; font-size: 13px; }
}

/* Chad, 2026-09-03: the list view's outlines read heavier than the calendar's,
   which draws its grid at 1px #b9c6d2. Same value here, as a token, so the two
   views agree and a future recolour is one edit. The old rules were 2-3px in
   #333/#555/#999 -- three greys and three weights on one table. */
:root { --sched-rule: #b9c6d2; }

/*--------------------------------------------------------------
# Trip schedule (.scale-table)
#
# Repainted to the marketing site's own trip schedule (.sched-table): a navy
# title bar, a blue month bar, navy column heads, alternating row shading. The
# green Book dot is already identical in both — the marketing table's
# `a.book-dot` was derived from `.myButton_lite` here — so it is left alone.
#
# The month bar was orange (#FF8C00), which is the one colour on this page that
# read as a different brand entirely.
--------------------------------------------------------------*/
.scale-table {
	border-collapse: separate;
	border-spacing: 0;
	width: 100%;
	margin-top: 16px;
	margin-bottom: 32px;
	/* The old rule pulled a tiled `white_wall.png` off the SiteNinja asset host
	   that no longer serves it. */
	background: var(--surface-color);
	border: 1px solid var(--sched-rule);
	font-family: var(--default-font);
}

.scale-title {
	background: var(--sched-bar-color);
	color: var(--contrast-color);
	font-family: var(--heading-font);
	font-size: 24px;
	font-weight: 700;
	text-align: center;
	text-shadow: none;
	padding: 18px 20px;
	border-bottom: 1px solid var(--sched-rule);
	border-radius: 0;
}

.scale-title .schedule-title { font-size: 24px; font-weight: 700; }

.schedule-instructions {
	font-size: 14px;
	font-weight: 400;
	text-shadow: none;
	margin-top: 12px;
	margin-bottom: 0;
}

.scale-break {
	background: var(--sched-month-color);
	color: var(--contrast-color);
	font-family: var(--heading-font);
	font-size: 17px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-align: center;
	text-shadow: none;
	padding: 10px 20px;
	border-top: 1px solid var(--sched-rule);
	border-bottom: 1px solid var(--sched-month-border);
}

.scale-head {
	background-color: var(--sched-bar-color);
	color: var(--contrast-color);
	font-family: var(--heading-font);
	font-size: 12px;
	font-weight: 700;
	text-transform: uppercase;
	text-align: center;
	padding: 8px 10px;
	border-top: none;
	border-bottom: 1px solid var(--sched-rule);
}

/* Simon, 2026-09-04, on John's "the schedule reads too heavy": the table is
   doing the same job twice. It zebra-stripes -- measured live, 61 cells at
   #ebeff4 against 68 white -- AND it rules every edge, so the fill separates
   the rows and the borders separate them again. Two devices, one job.

   The 2026-09-03 sweep above lightened the HORIZONTALS to 1px var(--sched-rule)
   and stopped there, because that is all it declared. It missed that
   sales/css/style-dev.css also paints VERTICALS, in near-black #333, via
   :first-child / :last-child / .scale-group -- and border-top on a shorthand-free
   rule does not touch them. Measured on dev: 178 of those lines, a dark bar
   beside every cell in the table. That is the cage, and it is the whole
   complaint.

   Subtraction only. Nothing here adds a colour or a weight; it deletes the
   verticals and brings the one remaining #333 -- the in-cell rule between a
   trip's two comment blocks -- onto the same token as everything else. The
   horizontals are already right and are left alone, including the blue day bar
   under .scale-break, which is the per-day separation Chad asked for. */
.scale-data:first-child,
.scale-data:last-child,
.scale-group {
	border-left: 0;
	border-right: 0;
}

.trip-info-break {
	border-color: var(--sched-rule);
}

/* Same shape one more time, found by Simon after the above was staged: the
   pager cell that closes the table. Its border-top came onto the token with
   everything else; its other three sides stayed at #666, because they were
   never declared here either. They sit directly on .scale-table's own 1px
   border, so they were painting a darker second line over it -- nothing is
   lost by dropping them. That is every #333 and #666 off the table. */
.scale-foot {
	border-right: 0;
	border-bottom: 0;
	border-left: 0;
}

.scale-data,
.scale-group {
	font-family: var(--default-font);
	border-top: 1px solid var(--sched-rule);
}

/* .scale-light / .scale-dark are emitted on every row by schedule.php and have
   never had a rule behind them, so the table has always been flat. */
.scale-light > td,
td.scale-light { background-color: #ffffff; }

.scale-dark > td,
td.scale-dark { background-color: var(--sched-shade); }

.scale-foot {
	background-color: var(--sched-bar-color);
	color: #adb5bd;
	font-family: var(--heading-font);
	font-size: 12px;
	text-align: center;
	padding: 10px;
	border-top: 1px solid var(--sched-rule);
	border-radius: 0;
}

.scale-foot a,
.scale-foot a:link,
.scale-foot a:visited { color: #ffffff; }

/* The filter controls sit INSIDE the navy title bar, where the brand navy is
   1.2:1 against the background and a .btn-primary is invisible. Same remedy the
   marketing site uses on its dark sections: the accent lightens, and the label
   goes navy on it. */
.scale-title .btn-outline-secondary,
.scale-title .btn-outline-secondary:focus {
	--bs-btn-color: #e8ebf5;
	--bs-btn-border-color: rgba(232, 235, 245, .55);
	--bs-btn-hover-bg: #e8ebf5;
	--bs-btn-hover-border-color: #e8ebf5;
	--bs-btn-hover-color: #25294a;
}

.scale-title label,
.scale-title .filter-label {
	color: var(--contrast-color);
	font-weight: 600;
	font-size: 13px;
}

/*--------------------------------------------------------------
# Row states: bookable, call-only, inert
#
# schedule.php tags every trip cell with what the row can actually DO, from the
# button it chose. Before this, all three looked identical: a pointer cursor and
# a yellow highlight on a charter row that then did nothing when clicked, because
# its placeholder button deliberately carries no id.
--------------------------------------------------------------*/

/* Bookable and call-only rows are genuinely clickable. */
.trip-book,
.trip-call { cursor: pointer; }

/* The trip name is the thing a visitor reads, so it is the thing that should
   look like the link. Underline appears on row hover rather than at rest, so a
   40-row schedule is not a wall of underlines. */
.trip-book .trip-info strong,
.trip-call .trip-info strong {
	text-decoration-color: transparent;
	text-decoration-line: underline;
	text-underline-offset: 3px;
	transition: text-decoration-color .15s ease;
}

.trip-book.highlight .trip-info strong {
	text-decoration-color: var(--accent-color);
	color: var(--accent-color);
}

.trip-call.highlight .trip-info strong {
	text-decoration-color: #b8860b;
}

/* The green dot is a 24px target in a full-width row; growing it on hover says
   "this row is the button" without changing the layout. */
.trip-book.highlight .myButton_lite {
	transform: scale(1.18);
	box-shadow: inset 0 1px 0 0 #459900, 0 0 0 3px rgba(17, 209, 0, .25);
}

.myButton_lite { transition: transform .12s ease, box-shadow .12s ease; }

/* Font Awesome is gone (see the icons note below); `fa-lg` was its 1.33em
   sizing class and Bootstrap Icons ships no equivalent. */
.bi-lg { font-size: 1.33em; line-height: .75em; vertical-align: -.075em; }

/* Call-only: the phone glyph is the affordance, so lift it the same way. */
.trip-call.highlight .call-btn { transform: scale(1.15); }
.call-btn { transition: transform .12s ease; display: inline-block; }

/* Inert rows — charter, offline, expired. Muted to 55%, which is what the
   marketing site does to its own sold-out rows (table.sched-table
   tr.sched-data.sold-out), so the two schedules agree on what "not available"
   looks like. No pointer, and the highlight is suppressed to a flat grey so a
   dead row never lights up as though it were live. */
.trip-inert { cursor: default; }

.trip-inert > * { opacity: .55; }

.trip-inert.highlight {
	background: #eceff2 !important;
}

.trip-inert.highlight .trip-info strong { text-decoration: none; }

/* Sold out, or past the online cutoff. John, 2026-09-03: the calendar mutes
   these entries and the list view did not, so the same trip read as available
   in one view and unavailable in the other.

   Muted to the same 55%, with one difference from the calendar: the phone
   control keeps full strength. The calendar offers nothing on a full trip, but
   this row still does -- it raises the "please call" alert -- and dimming the
   one remaining action to 55% would say "dead end" about a row that is not
   one. */
.trip-call > * { opacity: .55; }
.trip-call .call-btn { opacity: 1; }

/* The red placeholder is not a button and must not read as one. */
.trip-inert .myButton_red {
	cursor: default;
	filter: grayscale(.45);
}

.trip-info strong { font-size: 14px; }

/* Jr/Sr/military fares under the adult price (ported from
   Santa-Barbara-Landing-Resos 943855a). Quieter than the adult fare: it is
   the qualifier, not the number the customer is scanning for. */
.trip-price .trip-discounts {
	font-weight: 400;
	font-size: .85em;
}

.chartered,
.call_now,
.charter-alert { color: #cc0000; }

.font_green13 { color: #009900; }
.font_red13 { color: #cc0000; }


/*--------------------------------------------------------------
# Header crowding
#
# This nav has seven items where the marketing site has six, and longer labels,
# so at lg the phone butts against the last nav link and the sister mark runs
# off the container. main.css is a verbatim copy and is not the place to fix a
# difference that only exists on this site.
--------------------------------------------------------------*/
.header .header-phone {
	margin-left: 18px;
}

@media (min-width: 1200px) and (max-width: 1499px) {
	.header .header-sister { display: none !important; }
}

/*--------------------------------------------------------------
# Booking control target size and affordance
#
# From Simon's design review, 2026-09-03 (P1). The green booking dot measured
# 18x18 at every viewport and is the only way to book a trip. The 18 was never
# chosen: schedule.css gives .myButton_lite `padding: 8px` and a 1px border and
# the anchor is EMPTY, so 8+8+1+1 = 18. Emergent, not designed.
#
# WCAG 2.2 SC 2.5.8 wants 24x24 minimum. The dot now meets it, and the anchor
# also stretches to fill its cell so the pointer target is the full cell without
# the dot growing to match. The row-level click handler already existed; this
# makes the LINK itself the target, which is what a pointer and a screen reader
# both act on.
--------------------------------------------------------------*/
.scale-data .myButton_lite,
.scale-data .myButton_red {
	box-sizing: border-box;
	width: 24px;
	height: 24px;
	padding: 0;
	position: relative;
}

/* Stretch the hit area over the whole book cell without moving the dot. The
   cell measured 31.7x106.5 on mobile, 63.4x106.5 on desktop, so this is a real
   target rather than a 24px one. */
td.scale-data:first-child { position: relative; }

.scale-data .myButton_lite::after {
	content: "";
	position: absolute;
	inset: -41px -12px;          /* fills the cell; cell is ~106px tall */
}

/* The phone control had the same problem at 14x13, and was #FF0000 against the
   page's #C20404 -- a second red in one column. */
.call-btn {
	box-sizing: border-box;
	min-width: 24px;
	min-height: 24px;
	line-height: 24px;
	color: #c20404;
	text-align: center;
}

.call-btn:focus-visible,
.myButton_lite:focus-visible {
	outline: 3px solid var(--accent-color);
	outline-offset: 2px;
}

/*--------------------------------------------------------------
# Search Now is the primary action and must not look like the disabled one
#
# Simon P3: it passed AA on both counts (5.06:1 and 5.26:1) but sat in
# periwinkle beside two white-on-dark buttons, so the primary action read as the
# weakest. Not a contrast fix -- a hierarchy fix.
--------------------------------------------------------------*/
.scale-title .btn-primary,
.scale-title .btn-primary:focus {
	background-color: #ffffff;
	border-color: #ffffff;
	color: #16202b;
	--bs-btn-bg: #ffffff;
	--bs-btn-border-color: #ffffff;
	--bs-btn-color: #16202b;
	--bs-btn-hover-bg: #dce3f2;
	--bs-btn-hover-border-color: #dce3f2;
	--bs-btn-hover-color: #16202b;
	font-weight: 600;
}

/*--------------------------------------------------------------
# Mobile horizontal overflow
#
# Simon P2: documentElement.scrollWidth 394 vs clientWidth 390 at 390px, traced
# to .header-cta. The nav's phone + Book Now sit in a flex row that does not
# shrink, so 4px escapes the viewport. Only at 390.
--------------------------------------------------------------*/
@media (max-width: 420px) {
	.header .header-cta { min-width: 0; flex-shrink: 1; }
	.header .header-phone { margin-left: 0; }
	.header .btn-getstarted { padding: 6px 14px; }
}

body { overflow-x: hidden; }

/*--------------------------------------------------------------
# Mobile: Load / Price / Spots as stacked pairs
#
# Simon's spec, 2026-09-03 (P2). The three pairs were laid inline on one line;
# the third wrapped, orphaning "$165.60" from the word "Price" — the number a
# customer is scanning for. Stacking each value under its own label fixes it by
# construction: a value cannot separate from a label it sits beneath. Keeps the
# trio to one line, which matters on a page already ~14,500px tall on a phone.
#
# Departs and Returns are left alone; they read correctly as inline pairs.
--------------------------------------------------------------*/
@media (max-width: 767.98px) {
	.scale-data .trip-load,
	.scale-data .trip-price,
	.scale-data .trip-spots {
		flex: 1 1 0;
		max-width: none;
		text-align: center !important;
		white-space: nowrap;
		padding-left: 4px;
		padding-right: 4px;
	}

	.scale-data .trip-load .lbl,
	.scale-data .trip-price .lbl,
	.scale-data .trip-spots .lbl {
		display: block !important;
		float: none !important;
		clear: none !important;
		font-size: 12px;
		font-weight: 600;
		text-transform: uppercase;
		letter-spacing: .04em;
		color: color-mix(in srgb, var(--default-color), transparent 35%);
		margin-bottom: 1px;
	}

	.scale-data .trip-load,
	.scale-data .trip-price,
	.scale-data .trip-spots {
		font-size: 16px;
		font-weight: 600;
	}

	/* The column is nowrap so Load / Price / Spots stay on one line; the
	   discount sub-line is a third of the width and must be allowed to wrap. */
	.scale-data .trip-price .trip-discounts {
		white-space: normal;
		font-size: 12px;
	}
	/* ...but a fare and its label never split: "Sr:" on one line and
	   "$165.60" on the next reads as two facts. */
	.scale-data .trip-price .trip-discounts span {
		white-space: nowrap;
	}
}

/*--------------------------------------------------------------
# Schedule filter controls
#
# BS5's .form-select is width: 100%, so adding that class in the framework sweep
# stretched the boat filter across the whole panel and pushed its own label onto
# the line above. It should be only as wide as its content.
#
# .form-inline went the same way: Bootstrap 5 removed it, so the form stopped
# laying its children out inline. The form now carries d-flex/gap utilities
# instead — see get_filter_pod() in includes/schedule.php.
--------------------------------------------------------------*/
/* Scoped to the filter form, NOT to .scale-title: the list view renders this
   pod inside the table's title bar, but calendar.php echoes it straight into
   the page, so a .scale-title-scoped rule reached only one of the two views. */
#filter-form .filter-select,
#filter-form select.form-select {
	width: auto;
	min-width: 190px;
	max-width: 100%;
	display: inline-block;
}

/* The datepicker's real input is a hidden anchor for the popup; the visible
   control is the calendar button beside it. Left full-width it would take a
   whole flex row of its own. */
#filter-form #filter-month {
	width: 0;
	height: 0;
	padding: 0;
	border: 0;
	opacity: 0;
	position: absolute;
}

@media (max-width: 575.98px) {
	#filter-form .filter-select,
	#filter-form select.form-select { width: 100%; }
}

/*--------------------------------------------------------------
# Trip details header (vouchers flow)
#
# The five-column grid renders from md up; below that a stacked block of
# sentences replaces it, ported from Searcher-Resos. Reflowing the grid was the
# problem: at 390px Description took a full row, Price took another and floated
# right, and Load/Spots sat as an orphaned half-and-half pair under a blue
# header band that no longer lined up with anything.
--------------------------------------------------------------*/
.trip-details-xs {
	padding: 14px 12px;
	line-height: 1.6;
}

.trip-details-xs strong {
	display: block;
	font-size: 1.05rem;
	margin-bottom: 4px;
	color: var(--heading-color);
}

/* The header band is grid furniture; with the grid hidden it has nothing to
   label, so it goes too rather than sitting as a bare blue bar. */
@media (max-width: 767.98px) {
	.trip-details-head { display: none !important; }
}

/*--------------------------------------------------------------
# Bootstrap's info/primary palette, brought onto the brand
#
# Simon's review, 2026-09-03, and this one is a defect not a preference:
# the trip-details header band was Bootstrap's stock $primary #0d6efd carrying
# Bootstrap's stock info text #055160 — measured 1.98:1 on the live page,
# against WCAG AA's 4.5:1 for body text, on the page a customer reaches from
# the Book link.
#
# Both blues were EXACT Bootstrap defaults with zero distance from stock, so
# nothing had ever overridden them. The finding is not that the blues clash,
# it is that two of them are the framework's and none is the site's.
#
# Done at the TOKENS, not on the panel's selectors. 27 .bg-primary bands and 14
# .alert-info panels across all three flows use this same idiom; restyling one
# panel would leave the other 40 stock and the next page would arrive here
# again. Overriding --bs-* means every component inherits the site palette.
#
# --sd-surface is the brand navy desaturated and lifted, not a picked light
# blue, so the panel reads as the same family as the chrome.
--------------------------------------------------------------*/
:root {
	--sd-navy: #072b46;          /* brand navy — logo, nav */
	--sd-surface: #eef3f7;       /* panel ground */
	--sd-surface-line: #d3dfe8;  /* 1px panel border */
	--sd-ink: #16202b;           /* body and title */

	/* Bootstrap's own tokens, repointed. .bg-primary reads --bs-primary-rgb
	   through rgba(), so the rgb triplet is the one that matters. */
	--bs-primary: var(--sd-navy);
	--bs-primary-rgb: 7, 43, 70;
	--bs-info-bg-subtle: var(--sd-surface);
	--bs-info-border-subtle: var(--sd-surface-line);
	--bs-info-text-emphasis: var(--sd-ink);
}

/* Bootstrap sets no colour on .bg-primary — the #055160 was inherited from the
   surrounding .alert-info. A dark band needs its own light text or it inherits
   whatever the panel sets, which is exactly how 1.98:1 happened. */
.bg-primary {
	color: #ffffff;
}

.alert-info {
	--bs-alert-bg: var(--sd-surface);
	--bs-alert-border-color: var(--sd-surface-line);
	--bs-alert-color: var(--sd-ink);
}

/* Measured after (all AA at 4.5:1 for body text):
     header label  #ffffff on #072b46   14.55:1   was 1.98:1
     panel title   #16202b on #eef3f7   14.74:1
     table body    #16202b on #eef3f7   14.74:1
     band on panel #072b46 on #eef3f7   13.03:1  */

/*--------------------------------------------------------------
# Banner crop
#
# John, via Simon, 2026-09-03. main.css sets the banner with the shorthand
# `... center / cover`, which centres BOTH layers. At 50% the visible slice of
# the 2048x1189 photo is the cabin band — the part of the hull carrying the
# obsolete SEA Landing mark, and none of the boat's own name. 72% brings the
# bow lettering into frame.
#
# TWO positions, not one: the first is the navy gradient, the second the photo.
# Collapsing this to a single value moves the gradient with it.
#
# Overridden HERE rather than edited in main.css, which is a verbatim copy of
# the marketing site's stylesheet and must stay re-copyable.
#
# Settled at 68%. John, 2026-09-04: "68% sounds good on the hero image."
#
# It was 72%, which clips the top of the STARDUST lettering on the bow at 2560px
# and above -- the band there is only ~209 source rows tall. Simon measured 68%
# as clear at 390, 768, 1024, 1440, 1680, 1920 and 2560. The cost John took
# knowingly is that 68% lifts the band enough at 1440 to bring the top of the
# old SEA Landing mark back into frame, dimmed under the gradient but legible.
#
# Two layers here, gradient first and photo second, so only the SECOND position
# moves. Editing the first one moves the gradient and does nothing visible.
--------------------------------------------------------------*/
/* Coral Sea (2026-11-09, Henry): 45%, not Stardust's 68%. The banner photo here
   is coral-sea-hero.jpg (1600x900), whose CORAL SEA lettering sits at rows
   418-442. At 68% the band showed hull and waterline only (rows 425-700 at
   1920px, 472-678 at 2560px). At 45% it shows the anglers on deck, the
   lettering and the hull at 390, 768, 1024, 1440, 1680, 1920 and 2560px
   (computed for a ~330px band, the height Simon measured). */
.page-title.dark-background {
	background-position: 0% 0%, 50% 45%;
}

/*--------------------------------------------------------------
# Terms links stay underlined
#
# This deliberately contradicts the Bootstrap/Axis convention that the rest of
# the site follows (stardust-theme.css resets `a { text-decoration: none }`
# because BS5's Reboot underlines everything).
#
# It is not an aesthetic call. John, 2026-09-03: chargebacks have been lost over
# this before. If the Terms link does not LOOK like a link, a customer disputing
# a charge can argue the terms were never made available to them, and the
# consent checkbox beside it is worth less as evidence. Colour alone does not
# carry that -- it is the one signal a colour-blind customer, a greyscale print,
# or a screenshot in a dispute file will not have.
#
# :not(.btn) matters: the Continue Reservation control is also an <a> pointing at
# terms.php, and underlining a button would be wrong.
--------------------------------------------------------------*/
a[href*="terms"]:not(.btn),
a[href*="Terms"]:not(.btn) {
	text-decoration: underline;
	text-underline-offset: 2px;
}

a[href*="terms"]:not(.btn):hover {
	text-decoration: underline;
}

/*--------------------------------------------------------------
# Print
#
# The gift-card receipt says "Please print this page for your records", and
# printing it produced two pages: the nav, the banner photo and the whole navy
# footer, with the coupon code somewhere in the middle. John, 2026-09-03.
#
# .no-print is on the shared chrome, so this covers every page's print view, not
# just the receipt that prompted it. Nothing in the chrome is worth ink: the
# customer is holding the page, they do not need a nav.
--------------------------------------------------------------*/
@media print {
	.no-print { display: none !important; }

	/* Belt and braces for anything the class does not reach. */
	#header, #footer, .scroll-top, #preloader, .view-switch { display: none !important; }

	/* Dark surfaces cost a page of toner and read worse on paper. */
	.dark-background,
	.footer,
	.scale-title,
	.scale-break,
	.scale-head {
		background: #ffffff !important;
		color: #000000 !important;
	}

	/* Give the sheet its margins back -- the content wrapper's padding is sized
	   for a viewport, not a page. */
	.resos-content { padding: 0 !important; }
	body { background: #ffffff !important; }

	/* Keep a voucher or a receipt from being split across a page break. */
	.trip-selected,
	.panel,
	.card,
	.manifest-wrap { break-inside: avoid; page-break-inside: avoid; }

	a[href]::after { content: ""; }   /* no URL dumps beside every link */
}
