/**
 * Joerrens Booking - Public CSS
 *
 * Additions on top of joerrens-ui.css. Mainly Flatpickr look & half-day hints.
 */

.jb-form-wrap {
	max-width: 760px;
	margin: 0 auto;
}

.jb-form .jo-card + .jo-card {
	margin-top: var(--jo-gap);
}

/* Date inputs read-only so user can't type, only pick */
.jb-date {
	cursor: pointer;
	background-color: var(--jo-bg);
}

/* Price box animation */
.jb-price-box {
	transition: background-color .15s ease;
}

.jb-price-value {
	font-size: 18px;
	font-weight: 600;
	color: var(--jo-text);
	margin: 0;
}

.jb-price-value--loading {
	color: var(--jo-text-muted);
	font-weight: 400;
	font-size: 14px;
}

/* ============================================
   Own calendar (v1.0.8+)
   ============================================ */

.jb-cal {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: start;
	gap: var(--jo-gap-sm);
	width: 100%;
	padding: var(--jo-gap-sm);
	border: 1px solid var(--jo-border);
	border-radius: var(--jo-radius-lg);
	background: #fff;
}

.jb-cal__nav {
	width: 36px;
	height: 36px;
	border: 0;
	border-radius: 50%;
	background: transparent;
	font-size: 22px;
	line-height: 1;
	cursor: pointer;
	color: var(--jo-text);
	align-self: center;
}

.jb-cal__nav:hover:not(:disabled) {
	background: var(--jo-bg-subtle);
}

.jb-cal__nav:disabled {
	opacity: .25;
	cursor: default;
}

.jb-cal__months {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
	gap: 60px;
}

.jb-cal__month {
	min-width: 0;
}

.jb-cal__month-head {
	text-align: center;
	font-size: 15px;
	font-weight: 600;
	margin-bottom: 8px;
	color: var(--jo-text);
}

.jb-cal__weekdays,
.jb-cal__days {
	display: grid;
	grid-template-columns: repeat(7, 1fr);
}

.jb-cal__weekdays {
	margin-bottom: 4px;
}

.jb-cal__weekday {
	text-align: center;
	font-size: 11px;
	font-weight: 500;
	color: var(--jo-text-muted);
	text-transform: uppercase;
	letter-spacing: .05em;
	padding: 4px 0;
}

/*
   Day cell visual system.

   Contrast matters more than shape: free days read as the darkest, most
   confident element on the calendar; unavailable days fade back without
   shouting (no strike-through — too noisy when combined with opacity);
   the selected range pops as a filled pill.

   Layered states, strongest wins:
	 base          — free, clickable (.jb-cal__day)
	 hover         — subtle gray pill on mouse-over
	 unavailable   — past / booked / not-valid-arrival/departure (lighter, normal weight)
	 in-range      — gray pill between arrival and departure
	 arrival/dep   — filled black pill, white text
	 half-day      — diagonal split (someone arrives/leaves that day)
*/

.jb-cal__day {
	appearance: none;
	background: transparent;
	border: 1px solid transparent;
	border-radius: var(--jo-radius);
	aspect-ratio: 1 / 1;
	font: inherit;
	font-size: 13px;
	font-weight: 700;
	color: var(--jo-text);
	cursor: pointer;
	padding: 0;
	margin: 1px;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background-color .08s ease, border-color .08s ease, color .08s ease;
}

.jb-cal__day:hover:not(:disabled):not(.jb-cal__day--blank) {
	background: var(--jo-bg-muted);
	border-color: var(--jo-bg-muted);
}

.jb-cal__day--blank {
	cursor: default;
	pointer-events: none;
}

/* Unavailable states — past dates and booked days.
   Light gray, normal weight, no strike-through. The low contrast alone
   communicates "can't click this" without needing extra ornamentation. */
.jb-cal__day.is-past,
.jb-cal__day.is-blocked {
	color: var(--jo-text-subtle);
	cursor: not-allowed;
	font-weight: 400;
}

/* Valid day but not a legal arrival or departure (fix-season rules etc.).
   Same visual language as is-past/is-blocked so the user doesn't have to
   learn a second "unavailable" style. Pointer-events stay on so the
   tooltip ("Only Saturdays in high season" etc.) still shows on hover. */
.jb-cal__day.is-not-arrival,
.jb-cal__day.is-not-departure {
	color: var(--jo-text);
	cursor: not-allowed;
	font-weight: 700;
	pointer-events: auto;
}

/* While the user has picked an arrival and is hovering a candidate
   departure: highlight the valid end-of-range day. Lighter than the
   committed pill to signal "preview, not chosen yet". */
.jb-cal__day.is-valid-departure {
	background: var(--jo-bg-subtle);
	border-color: var(--jo-border);
	font-weight: 600;
}

/* Committed selection endpoints — filled black pill, white number. */
.jb-cal__day.is-arrival,
.jb-cal__day.is-departure {
	background: var(--jo-action);
	border-color: var(--jo-action);
	color: #fff;
	font-weight: 700;
}

/* Days between arrival and departure — connected gray pill. */
.jb-cal__day.is-in-range {
	background: var(--jo-bg-muted);
	border-color: var(--jo-bg-muted);
}

/* Half-day data is still flagged on the cell (see JS: is-half-arrival /
   is-half-departure) but no longer gets its own visual. Whether the day
   is clickable is decided purely by the arrival/departure validity logic.
   If the day is a valid arrival in the current state, it reads as a
   normal free day; if not, JS adds is-not-arrival/is-not-departure and
   it greys out like any other unavailable day. One mental model instead
   of two. */


/* Custom tooltip on half-day cells. Uses data-tooltip attr (set by JS) so
   the text is i18n-aware without fighting the browser's native title popup.
   Rendered via ::after on hover/focus for mouse + keyboard users. */
.jb-cal__day[data-tooltip] {
	position: relative;
}

.jb-cal__day[data-tooltip]::after {
	content: attr(data-tooltip);
	position: absolute;
	bottom: calc(100% + 8px);
	left: 50%;
	transform: translateX(-50%) translateY(4px);
	background: #2b2f33;
	color: #fff;
	font-size: 12px;
	line-height: 1.35;
	padding: 6px 10px;
	border-radius: 4px;
	width: max-content;
	max-width: 180px;
	white-space: normal;
	text-align: center;
	pointer-events: none;
	opacity: 0;
	transition: opacity .12s ease, transform .12s ease;
	z-index: 20;
	box-shadow: 0 4px 12px rgba(0, 0, 0, .18);
}

.jb-cal__day[data-tooltip]::before {
	content: '';
	position: absolute;
	bottom: calc(100% + 3px);
	left: 50%;
	transform: translateX(-50%) translateY(4px);
	border: 5px solid transparent;
	border-top-color: #2b2f33;
	pointer-events: none;
	opacity: 0;
	transition: opacity .12s ease, transform .12s ease;
	z-index: 21;
}

.jb-cal__day[data-tooltip]:hover::after,
.jb-cal__day[data-tooltip]:focus-visible::after,
.jb-cal__day[data-tooltip]:hover::before,
.jb-cal__day[data-tooltip]:focus-visible::before {
	opacity: 1;
	transform: translateX(-50%) translateY(0);
}

/* ============================================
   Modal flow (v1.0.7+)
   ============================================ */

.jb-wrap {
	max-width: 420px;
	margin: 0 auto;
	text-align: center;
}

.jb-entry {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--jo-gap-sm);
	background: transparent;
	border: 0;
	box-shadow: none;
	padding: 0;
}

.jb-entry .jo-btn {
	min-width: 260px;
}

.jb-modal {
	position: fixed;
	inset: 0;
	z-index: 999999;
	display: none;
	align-items: flex-start;
	justify-content: center;
	padding: 20px;
	overflow-y: auto;
}

.jb-modal.is-open {
	display: flex;
}

.jb-modal__overlay {
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, 0.55);
	z-index: 1;
}

.jb-modal__panel {
	position: relative;
	z-index: 2;
	background: #fff;
	border-radius: var(--jo-radius-lg);
	box-shadow: 0 12px 48px rgba(0, 0, 0, 0.18);
	width: 100%;
	max-width: 1040px;
	padding: 32px 28px 28px;
	margin: 40px auto;
	text-align: left;
}

.jb-modal__close {
	position: absolute;
	top: 12px;
	right: 14px;
	width: 32px;
	height: 32px;
	border: 0;
	background: transparent;
	font-size: 28px;
	line-height: 1;
	cursor: pointer;
	color: var(--jo-text-muted);
	border-radius: 50%;
}

.jb-modal__close:hover {
	background: var(--jo-bg-subtle);
	color: var(--jo-text);
}

.jb-modal__title {
	margin: 0 0 var(--jo-gap);
	font-size: 22px;
	font-weight: 600;
}

.jb-modal .jb-title-check,
.jb-modal .jb-title-request {
	display: none;
}

.jb-modal:not(.is-intent-request) .jb-title-check {
	display: inline;
}

.jb-modal.is-intent-request .jb-title-request {
	display: inline;
}

/* Steps indicator */
.jb-steps {
	list-style: none;
	padding: 0;
	margin: 0 0 var(--jo-gap-lg);
	display: flex;
	gap: var(--jo-gap-sm);
	font-size: 13px;
	color: var(--jo-text-subtle);
	counter-reset: step;
}

.jb-steps li {
	flex: 1;
	padding: 10px 12px;
	border-top: 3px solid var(--jo-border);
	counter-increment: step;
}

.jb-steps li::before {
	content: counter(step) ". ";
}

.jb-steps li.is-active {
	border-top-color: var(--jo-action);
	color: var(--jo-text);
	font-weight: 500;
}

.jb-steps li.is-complete {
	border-top-color: var(--jo-action);
	color: var(--jo-text-muted);
}

/* Step sections - only active one visible */
.jb-step {
	display: none;
}

.jb-step.is-active {
	display: block;
}

.jb-step-heading {
	margin: 0 0 var(--jo-gap-sm);
	font-size: 16px;
	font-weight: 600;
}

.jb-step-subheading {
	margin: var(--jo-gap) 0 4px;
	font-size: 14px;
	font-weight: 600;
}

.jb-step-actions {
	display: flex;
	justify-content: flex-end;
	gap: var(--jo-gap-sm);
	margin-top: var(--jo-gap-lg);
}

.jb-step-actions .jb-back {
	margin-right: auto;
}

/* Step 1: Calendar */
.jb-calendar-wrap {
	width: 100%;
	margin-bottom: var(--jo-gap);
}

.jb-calendar-summary-line {
	text-align: center;
	margin-top: var(--jo-gap-sm);
	font-size: 14px;
	line-height: 1.5;
}

/* Step 2: Extras as selectable cards */
.jb-extras {
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.jb-extra {
	position: relative;
	display: flex;
	align-items: center;
	gap: var(--jo-gap);
	padding: 14px 16px;
	border: 1.5px solid var(--jo-border);
	border-radius: var(--jo-radius);
	background: #fff;
	cursor: pointer;
	transition: border-color .12s ease, background-color .12s ease, box-shadow .12s ease;
}

.jb-extra:hover {
	border-color: var(--jo-text-muted);
}

/* Native checkbox is visually hidden but remains accessible and submits */
.jb-extra input[type="checkbox"] {
	position: absolute;
	opacity: 0;
	pointer-events: none;
	width: 0;
	height: 0;
	margin: 0;
}

.jb-extra__body {
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.jb-extra__label {
	font-weight: 500;
	color: var(--jo-text);
	font-size: 15px;
}

.jb-extra__price {
	font-size: 13px;
	color: var(--jo-text-muted);
}

.jb-extra__unit {
	color: var(--jo-text-subtle);
}

/* Check indicator in the top-right */
.jb-extra__check {
	flex-shrink: 0;
	width: 22px;
	height: 22px;
	border: 1.5px solid var(--jo-border);
	border-radius: 50%;
	background: #fff;
	position: relative;
	transition: background-color .12s ease, border-color .12s ease;
}

.jb-extra input:checked ~ .jb-extra__check {
	background: var(--jo-action);
	border-color: var(--jo-action);
}

.jb-extra input:checked ~ .jb-extra__check::after {
	content: '';
	position: absolute;
	left: 6px;
	top: 2px;
	width: 6px;
	height: 11px;
	border-right: 2px solid #fff;
	border-bottom: 2px solid #fff;
	transform: rotate(45deg);
}

/* Active state for the whole card when checked */
.jb-extra:has(input:checked) {
	border-color: var(--jo-action);
	background: var(--jo-bg-subtle);
}

/* Fallback for browsers without :has() — JS adds .is-checked via change event.
   (Safari <=15, Firefox <=120 don't support :has(). Modern browsers do.) */
.jb-extra.is-checked {
	border-color: var(--jo-action);
	background: var(--jo-bg-subtle);
}

/* Required options (pre-checked, disabled) look settled rather than interactive */
.jb-extra input:disabled ~ .jb-extra__check {
	opacity: .7;
}

.jb-extra:has(input:disabled) {
	cursor: default;
}

/* Step 3: grid layout - form left, price right */
.jb-grid {
	display: grid;
	grid-template-columns: 1fr 320px;
	gap: var(--jo-gap-lg);
}

@media (max-width: 768px) {
	.jb-grid {
		grid-template-columns: 1fr;
	}
}

.jb-price-box {
	background: var(--jo-bg-subtle);
	border: 1px solid var(--jo-border);
	border-radius: var(--jo-radius);
	padding: var(--jo-gap);
	position: sticky;
	top: 20px;
}

.jb-price-box__title {
	font-weight: 600;
	font-size: 15px;
	margin-bottom: var(--jo-gap-sm);
}

.jb-price-box__line {
	display: flex;
	justify-content: space-between;
	gap: 12px;
	padding: 6px 0;
	font-size: 14px;
}

.jb-price-box__line span:first-child {
	color: var(--jo-text-muted);
}

.jb-price-box__line span:last-child {
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.jb-price-box__line--nights {
	padding-bottom: 2px;
}

.jb-price-box__sub {
	font-size: 12px;
	color: var(--jo-text-subtle);
	margin: 0 0 6px;
	padding: 0;
}

/* On-site services (outside the price box — not billed) */
.jb-onsite {
	margin-top: var(--jo-gap);
	padding: 0;
}

.jb-onsite__title {
	font-size: 13px;
	font-weight: 600;
	color: var(--jo-text-muted);
	margin-bottom: 6px;
	text-transform: uppercase;
	letter-spacing: .04em;
}

.jb-onsite__lines .jb-price-box__line {
	color: var(--jo-text-muted);
}

.jb-onsite__lines .jb-price-box__line span:last-child {
	color: var(--jo-text);
}

.jb-price-box__total {
	display: flex;
	justify-content: space-between;
	padding-top: var(--jo-gap-sm);
	margin-top: var(--jo-gap-sm);
	border-top: 1px solid var(--jo-border);
	font-size: 16px;
	font-weight: 600;
}

.jb-price-box__total-value {
	font-variant-numeric: tabular-nums;
}

/* Step 4: thanks */
.jb-step--thanks {
	text-align: center;
	padding: var(--jo-gap-lg) 0;
}

.jb-thanks h3 {
	margin: 0 0 var(--jo-gap-sm);
	font-size: 20px;
}

.jb-thanks p {
	color: var(--jo-text-muted);
	margin: 0 0 var(--jo-gap-lg);
}

/* Body lock when modal is open */
body.jb-modal-open {
	overflow: hidden;
}


/* ============================================
   Read-only calendar (shortcode variant)
   ============================================
   Same look as the booking calendar, but no clicks, no hover, no nav.
   Used by [joerrens_booking_calendar cabin="..."] for static display
   on cabin landing pages.

   Visual language: red for booked, gray for pending request.
   Universal stop-light reading: a guest sees "red = can't have",
   "gray = maybe", "white = free" without needing the legend. */

.jb-calendar-readonly .jb-cal--readonly {
	grid-template-columns: 1fr;
}

/* Read-only calendar: no interactivity, period.
   The base .jb-cal__day rules include hover transitions and color
   changes for the booking modal. Here we kill all of that with a
   sweeping reset, then re-apply the status colors so booked days
   keep their red even on hover. */
.jb-calendar-readonly .jb-cal__day,
.jb-calendar-readonly .jb-cal__day:hover,
.jb-calendar-readonly .jb-cal__day:focus,
.jb-calendar-readonly .jb-cal__day:active {
	cursor: default !important;
	border-color: transparent !important;
	transition: none !important;
}

/* Free days: stay transparent on hover. */
.jb-calendar-readonly .jb-cal__day:not(.is-status-confirmed):not(.is-status-blocked):not(.is-status-request):not(.is-edge):not(.is-past):hover {
	background-color: transparent !important;
}

/* Past days: stay subtle on hover. */
.jb-calendar-readonly .jb-cal__day.is-past,
.jb-calendar-readonly .jb-cal__day.is-past:hover {
	background-color: transparent !important;
	color: var(--jo-text-subtle) !important;
	font-weight: 400;
}

/* Booked: confirmed + blocked share the same red. From the guest's
   point of view there is no difference; either way the day is gone. */
.jb-calendar-readonly .jb-cal__day.is-status-confirmed,
.jb-calendar-readonly .jb-cal__day.is-status-blocked,
.jb-calendar-readonly .jb-cal__day.is-status-confirmed:hover,
.jb-calendar-readonly .jb-cal__day.is-status-blocked:hover {
	background-color: var(--jo-warning) !important;
	color: #fff !important;
	font-weight: 700;
}

/* Pending request: muted gray. */
.jb-calendar-readonly .jb-cal__day.is-status-request,
.jb-calendar-readonly .jb-cal__day.is-status-request:hover {
	background-color: var(--jo-bg-muted) !important;
	color: var(--jo-text) !important;
	font-weight: 700;
}

/* Edge days: arrival or departure. Half the cell is colored, the
   other half stays free. The color halves are absolutely positioned
   so the day number floats centered over the split. */
.jb-calendar-readonly .jb-cal__day.is-edge {
	position: relative;
	overflow: hidden;
	background-color: transparent;
	color: var(--jo-text);
	font-weight: 700;
}

/* Back-to-back day: both halves are colored, so the day number sits
   on a fully red background. White text reads better there. */
.jb-calendar-readonly .jb-cal__day.is-edge.is-edge-full {
	color: #fff;
}

.jb-calendar-readonly .jb-cal__day.is-edge:hover {
	background-color: transparent;
}

.jb-calendar-readonly .jb-cal__day-half {
	position: absolute;
	inset: 0;
}

/*
   Diagonal triangle halves, matching the BCP visual idiom guests
   already know:
	 left  — top-left triangle, used for departure days
			 (morning booked, afternoon free)
	 right — bottom-right triangle, used for arrival days
			 (morning free, afternoon booked)
   The diagonal runs corner-to-corner so the day number stays readable
   in the center even when both halves are colored.
*/
.jb-calendar-readonly .jb-cal__day-half.is-half-left {
	clip-path: polygon(0 0, 100% 0, 0 100%);
}

.jb-calendar-readonly .jb-cal__day-half.is-half-right {
	clip-path: polygon(100% 0, 100% 100%, 0 100%);
}

/* Half cell colors mirror the full-day status colors. */
.jb-calendar-readonly .jb-cal__day-half.is-status-confirmed,
.jb-calendar-readonly .jb-cal__day-half.is-status-blocked {
	background-color: var(--jo-warning);
}

.jb-calendar-readonly .jb-cal__day-half.is-status-request {
	background-color: var(--jo-bg-muted);
}

/* The day number must sit above the colored halves. */
.jb-calendar-readonly .jb-cal__day-num {
	position: relative;
	z-index: 1;
}

/* Legend below the calendar grid. Two states only: booked + request.
   Free days have no legend entry on purpose, since whitespace already
   reads as "available" intuitively. */
.jb-calendar-readonly .jb-cal-legend {
	display: flex;
	gap: var(--jo-gap-lg);
	flex-wrap: wrap;
	margin-top: var(--jo-gap);
	font-size: 13px;
	color: var(--jo-text-muted);
}

.jb-calendar-readonly .jb-cal-legend__item {
	display: inline-flex;
	align-items: center;
	gap: 8px;
}

.jb-calendar-readonly .jb-cal-legend__dot {
	display: inline-block;
	width: 10px;
	height: 10px;
	border-radius: 2px;
}

.jb-calendar-readonly .jb-cal-legend__dot.is-booked  { background: var(--jo-warning); }
.jb-calendar-readonly .jb-cal-legend__dot.is-request { background: var(--jo-bg-muted); border: 1px solid var(--jo-border-strong); }
.jb-calendar-readonly .jb-cal-legend__dot.is-edge {
	background: var(--jo-warning);
	clip-path: polygon(100% 0, 100% 100%, 0 100%);
	border: 0;
}


/* --- Read-only Calendar Navigation ---
   Two button rows (top + bottom) with prev/next links that bump the
   12-month window forward or backward in 3-month steps. Server-side
   navigation via ?jb_cal_offset=, no JS. */

.jb-cal-nav {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 12px;
	margin: 16px 0;
}

.jb-cal-nav--top {
	margin-top: 0;
	margin-bottom: 24px;
}

.jb-cal-nav--bottom {
	margin-top: 24px;
	margin-bottom: 16px;
}

.jb-cal-nav__btn {
	display: inline-block;
	padding: 8px 16px;
	background: var(--jo-bg-subtle);
	color: var(--jo-text);
	border: 1px solid var(--jo-border);
	border-radius: 4px;
	text-decoration: none;
	font-size: 14px;
	line-height: 1.4;
	transition: background 0.15s ease;
}

.jb-cal-nav__btn:hover {
	background: var(--jo-bg-muted);
	color: var(--jo-text);
	text-decoration: none;
}

.jb-cal-nav__btn--prev {
	margin-right: auto;
}

.jb-cal-nav__btn--next {
	margin-left: auto;
}

/* Placeholder takes the prev-button's space when there's no prev link
   (we're on the default view), so the next button stays right-aligned. */
.jb-cal-nav__placeholder {
	margin-right: auto;
}

/* Loading state during AJAX swap. The grid dims and a rotating arrow
   sits centered on top, telling guests the calendar is updating. */
.jb-calendar-readonly .jb-cal-grid {
	position: relative;
	transition: opacity 0.15s ease;
}
.jb-calendar-readonly.is-loading .jb-cal-grid {
	opacity: 0.4;
	pointer-events: none;
}
.jb-cal-spinner {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 36px;
	height: 36px;
	margin: -18px 0 0 -18px;
	border-radius: 50%;
	border: 3px solid var(--jo-border);
	border-top-color: var(--jo-text);
	opacity: 1;
	pointer-events: none;
	animation: jb-cal-spin 0.8s linear infinite;
	/* Lift above the dimmed grid so it's clearly visible. */
	z-index: 5;
}
@keyframes jb-cal-spin {
	to { transform: rotate(360deg); }
}

/* Loading state on the booking form (after submit). Mirrors the read-only
   calendar's loading visual: dim the form, drop a centered spinner, lock
   pointer-events. The spinner element is the same .jb-cal-spinner from
   above — added by the JS into the form. */
.jb-form {
	position: relative;
}
.jb-form--loading > *:not(.jb-cal-spinner) {
	opacity: 0.4;
	pointer-events: none;
	transition: opacity 0.15s ease;
}