/**
 * Vendor Bookings (VX) widget styles.
 * Layout + states only; colours/typography are driven by the Elementor Style tab
 * and inherited Voxel classes where possible.
 */

.vxb-vendor-bookings[v-cloak] {
	display: none;
}

/* Flatten the browser's default 3D button bevel. A native <button> gets a UA
   `border: 2px outset`; Voxel never resets it because it styles <a class="ts-btn">,
   while we use <button> for real actions (correct keyboard/screen-reader semantics).
   Wrapped in :where() so this carries ZERO specificity — any button that sets its own
   border (our nav/action buttons, or an Elementor "Buttons" border control) wins. */
:where( .vxb-vendor-bookings button ) {
	border: 0;
}

/* Palette-correct button defaults (scoped → beat Elementor's global Kit `button` rule and
   follow the active preset). The unified "Buttons" Style section overrides these. */
.vxb-vendor-bookings .ts-btn-2 {
	background: var(--vxb-accent);
	border: 1px solid var(--vxb-accent);
	color: var(--vxb-on-accent);
}

.vxb-vendor-bookings .ts-btn-1 {
	background: var(--vxb-bg);
	border: 1px solid var(--vxb-border);
	color: var(--vxb-text);
}

.vxb-vendor-bookings {
	/* Theme bridge — Voxel tokens with safe fallbacks (see open-hours-booking.css). */
	--vxb-text: var(--ts-shade-1, #1f2933);
	--vxb-muted: var(--ts-shade-2, #6b7280);
	--vxb-border: var(--ts-shade-4, #e8eaed);
	--vxb-bg-soft: var(--ts-shade-6, #f5f6f8);
	--vxb-bg: var(--ts-shade-7, #fff);
	--vxb-accent: var(--ts-accent-1, #2563eb);
	--vxb-on-accent: #fff;

	display: flex;
	flex-direction: column;
	gap: 20px;
	position: relative;
	color: inherit;
}

.vxb-vendor-bookings .vxb-head h2 {
	margin: 0 0 4px;
}

.vxb-vendor-bookings .vxb-head p {
	margin: 0;
	opacity: 0.8;
}

/* Filters. Desktop: the wrapper + body dissolve (display:contents) so the
   secondary selects flow inline as toolbar flex items ("inline but grouped" —
   bounded by .vxb-filterbar). Mobile: they re-form into a bottom sheet (782px). */
.vxb-vendor-bookings .vxb-filters,
.vxb-vendor-bookings .vxb-filters-body {
	display: contents;
}

/* Modal chrome — only shown on mobile. */
.vxb-vendor-bookings .vxb-filters-head,
.vxb-vendor-bookings .vxb-filters-apply,
.vxb-vendor-bookings .vxb-filters-backdrop {
	display: none;
}

.vxb-vendor-bookings .vxb-filter {
	height: 44px;
	padding: 0 14px;
	border: 1px solid var(--vxb-border);
	border-radius: var(--vxb-radius);
	background: var(--vxb-bg);
	font: inherit;
	color: inherit;
	flex: 1 1 150px;
	min-width: 0; /* allow filters to shrink instead of overflowing */
	max-width: 100%;
	box-sizing: border-box;
}

/* Polished dropdowns: drop the native OS arrow for a themed chevron with breathing
   room from the edge. Surgical (chevron + right padding only) so the filter-bar flex
   sizing on .vxb-filter is untouched. */
.vxb-vendor-bookings select {
	-webkit-appearance: none;
	-moz-appearance: none;
	appearance: none;
	padding-right: 38px;
	cursor: pointer;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23797a88' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 15px center;
	background-size: 13px;
}

.vxb-vendor-bookings select:focus {
	border-color: var(--vxb-accent);
	outline: none;
}

.vxb-vendor-bookings .vxb-search {
	flex: 2 1 220px;
}

.vxb-vendor-bookings .vxb-daterange {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	flex: 1 1 180px;
	min-width: 0;
}

.vxb-vendor-bookings .vxb-daterange .vxb-filter {
	flex: 1 1 auto;
}

/* Date field + inline calendar popover (we control open/close). */
.vxb-vendor-bookings .vxb-datefield {
	position: relative;
	flex: 1 1 auto;
	min-width: 0;
}

.vxb-vendor-bookings .vxb-datefield .vxb-filter {
	width: 100%;
}

.vxb-vendor-bookings .vxb-date {
	cursor: pointer;
	/* Counter theme styling that mutes read-only inputs. */
	opacity: 1;
	-webkit-text-fill-color: currentColor;
}

.vxb-vendor-bookings .vxb-cal-host {
	position: absolute;
	top: calc( 100% + 6px );
	left: 0;
	z-index: 100050;
}

.vxb-vendor-bookings .vxb-cal-host--up {
	top: auto;
	bottom: calc( 100% + 6px );
}

/* Toolbar row (separate from filters): holds the mobile Filters trigger + sort. */
.vxb-vendor-bookings .vxb-toolbar {
	display: flex;
	align-items: center;
	justify-content: flex-end; /* sort sits top-right on desktop */
	gap: 12px;
	min-height: 0;
}

/* Sort = subtle text link with an icon (not a field/button). */
.vxb-vendor-bookings .vxb-sort {
	position: relative;
}

.vxb-vendor-bookings .vxb-sort-btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 4px 2px;
	border: 0;
	background: none;
	color: inherit;
	font: inherit;
	font-size: 0.9em;
	line-height: 1.2;
	opacity: 0.7;
	cursor: pointer;
	transition: opacity 0.15s ease;
}

.vxb-vendor-bookings .vxb-sort-btn:hover {
	opacity: 1;
}

.vxb-vendor-bookings .vxb-sort-icon {
	flex: 0 0 auto;
}

.vxb-vendor-bookings .vxb-sort-caret {
	width: 7px;
	height: 7px;
	margin-top: -3px;
	border: solid currentColor;
	border-width: 0 2px 2px 0;
	transform: rotate( 45deg );
	opacity: 0.6;
}

.vxb-vendor-bookings .vxb-sort-menu {
	position: absolute;
	top: calc( 100% + 6px );
	right: 0;
	z-index: 100050;
	min-width: 210px;
	max-width: calc( 100vw - 32px );
	margin: 0;
	padding: 6px;
	list-style: none;
	background: var(--vxb-bg);
	border: 1px solid var(--vxb-border);
	border-radius: 10px;
	box-shadow: 0 12px 32px rgba( 0, 0, 0, 0.16 );
}

.vxb-vendor-bookings .vxb-sort-option {
	padding: 9px 12px;
	border-radius: 6px;
	cursor: pointer;
	white-space: nowrap;
}

.vxb-vendor-bookings .vxb-sort-option:hover {
	background: color-mix( in srgb, var(--vxb-text) 8%, transparent );
}

.vxb-vendor-bookings .vxb-sort-option-active {
	font-weight: 600;
	color: var( --vxb-sort-accent, #2271b1 );
}

/* List */
.vxb-vendor-bookings .vxb-list {
	display: flex;
	flex-direction: column;
	gap: 10px;
	transition: opacity 0.2s ease;
}

.vxb-vendor-bookings .vxb-list.vxb-pending {
	opacity: 0.55;
	pointer-events: none;
}

.vxb-vendor-bookings .vxb-state {
	padding: 40px 16px;
	text-align: center;
	opacity: 0.7;
}

.vxb-vendor-bookings .vxb-card {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 14px 16px;
	border: 1px solid var(--vxb-border);
	border-radius: var(--vxb-radius);
	background: var(--vxb-bg);
	cursor: pointer;
	transition: background-color 0.15s ease, border-color 0.15s ease;
}

.vxb-vendor-bookings .vxb-card:hover {
	border-color: color-mix( in srgb, var(--vxb-text) 22%, var(--vxb-border) );
}

.vxb-vendor-bookings .vxb-card.vxb-canceled {
	opacity: 0.6;
}

.vxb-vendor-bookings .vxb-card-main {
	display: flex;
	align-items: center;
	gap: 12px;
	min-width: 0;
}

.vxb-vendor-bookings .vxb-avatar {
	width: 42px;
	height: 42px;
	border-radius: 50%;
	object-fit: cover;
	flex-shrink: 0;
}

.vxb-vendor-bookings .vxb-card-text {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.vxb-vendor-bookings .vxb-customer-name {
	font-weight: 600;
}

.vxb-vendor-bookings .vxb-card-meta {
	font-size: 0.85em;
	opacity: 0.75;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.vxb-vendor-bookings .vxb-card-side {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-shrink: 0;
}

.vxb-vendor-bookings .vxb-type-badge {
	font-size: 0.75em;
	padding: 3px 8px;
	border-radius: 6px;
	background: color-mix( in srgb, var(--vxb-text) 8%, transparent );
}

/* Status badge — uses Voxel's --s-color convention with a safe default. */
.vxb-vendor-bookings .order-status {
	--s-color: var(--vxb-muted);
	display: inline-block;
	padding: 3px 10px;
	border-radius: 6px;
	font-size: 0.78em;
	color: var( --s-color );
	background: color-mix( in srgb, var( --s-color ) 14%, transparent );
}

/* Pagination */
.vxb-vendor-bookings .vxb-pagination {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 14px;
}

.vxb-vendor-bookings .vxb-page-info {
	opacity: 0.8;
}

/* Detail panel */
.vxb-vendor-bookings .vxb-panel-overlay {
	position: fixed;
	inset: 0;
	background: rgba( 0, 0, 0, 0.4 );
	z-index: 100000;
}

.vxb-vendor-bookings .vxb-panel {
	position: fixed;
	top: 0;
	right: 0;
	height: 100%;
	width: min( 440px, 100vw );
	background: var(--vxb-bg);
	box-shadow: -8px 0 30px rgba( 0, 0, 0, 0.18 );
	z-index: 100001;
	transform: translateX( 100% );
	transition: transform 0.25s ease;
	display: flex;
	flex-direction: column;
}

.vxb-vendor-bookings .vxb-panel.vxb-panel-open {
	transform: translateX( 0 );
}

.vxb-vendor-bookings .vxb-panel-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 16px 20px;
	border-bottom: 1px solid var(--vxb-border);
}

.vxb-vendor-bookings .vxb-panel-body {
	flex: 1 1 auto;
	padding: 16px 20px;
	display: flex;
	flex-direction: column;
	gap: 14px;
	overflow-y: auto;
}

/* NOTE: .vxb-panel-row itself is defined once, further down with the rest of the
   1.15.0 panel — it used to be declared here too, and the two merged silently
   (this block supplied `flex-direction`, that one everything else), which is how
   the row ended up column-flex AND `justify-content: space-between`. */

.vxb-vendor-bookings .vxb-panel-label {
	font-size: 0.75em;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	opacity: 0.6;
}

.vxb-vendor-bookings .vxb-panel-total {
	font-weight: 600;
}

/* Actions footer */
.vxb-vendor-bookings .vxb-panel-foot {
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 16px 20px;
	border-top: 1px solid var(--vxb-border);
}

.vxb-vendor-bookings .vxb-panel-foot .ts-btn {
	width: 100%;
	justify-content: center;
}

/* Action buttons are native <button>s (default arrow cursor) — make them feel clickable. */
.vxb-vendor-bookings .ts-btn {
	cursor: pointer;
}

.vxb-vendor-bookings .ts-btn:disabled {
	cursor: not-allowed;
}

.vxb-vendor-bookings .vxb-actions-loading {
	opacity: 0.7;
}

.vxb-vendor-bookings .vxb-actions-error {
	margin: 0;
	font-size: 0.9em;
	color: var(--vxb-canceled);
}

.vxb-vendor-bookings .vxb-action-danger {
	color: var(--vxb-canceled);
}

/* Reschedule form */
.vxb-vendor-bookings .vxb-reschedule {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.vxb-vendor-bookings .vxb-cal-inline {
	position: static;
	top: auto;
	left: auto;
	margin-top: 4px;
}

.vxb-vendor-bookings .vxb-rs-slots {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.vxb-vendor-bookings .vxb-rs-slot {
	flex: 0 0 auto;
	padding: 8px 14px;
	border: 1px solid var(--vxb-border);
	border-radius: 8px;
	background: var(--vxb-bg);
	color: inherit;
	font: inherit;
	line-height: 1.2;
	cursor: pointer;
	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.vxb-vendor-bookings .vxb-rs-slot:hover:not( .vxb-rs-slot-full ) {
	border-color: var( --vxb-cal-accent, #2271b1 );
}

.vxb-vendor-bookings .vxb-rs-slot.vxb-rs-slot-selected {
	background: var( --vxb-cal-accent, #2271b1 );
	border-color: var( --vxb-cal-accent, #2271b1 );
	color: var(--vxb-on-accent);
}

.vxb-vendor-bookings .vxb-rs-slot-full,
.vxb-vendor-bookings .vxb-rs-slot[disabled] {
	opacity: 0.4;
	cursor: not-allowed;
}

/* Confirmation toast */
.vxb-vendor-bookings .vxb-toast {
	position: fixed;
	left: 50%;
	bottom: 24px;
	transform: translateX( -50% );
	z-index: 100100;
	max-width: 92vw;
	padding: 12px 18px;
	border-radius: 10px;
	background: var(--vxb-text);
	color: var(--vxb-on-accent);
	font-size: 0.95em;
	box-shadow: 0 8px 24px rgba( 0, 0, 0, 0.25 );
}

.vxb-vendor-bookings .vxb-toast-error {
	background: var(--vxb-canceled);
}

.vxb-vendor-bookings .vxb-toast-enter-active,
.vxb-vendor-bookings .vxb-toast-leave-active {
	transition: opacity 0.25s ease, transform 0.25s ease;
}

.vxb-vendor-bookings .vxb-toast-enter-from,
.vxb-vendor-bookings .vxb-toast-leave-to {
	opacity: 0;
	transform: translateX( -50% ) translateY( 12px );
}

.vxb-vendor-bookings .vxb-rs-noslots {
	opacity: 0.7;
	font-size: 0.9em;
}

.vxb-vendor-bookings .vxb-rs-actions {
	display: flex;
	gap: 10px;
}

.vxb-vendor-bookings .vxb-panel-foot .vxb-rs-actions .ts-btn {
	width: auto;
	flex: 1 1 0;
}

/* Phones: cards stack and the detail panel goes full-screen. */
@media ( max-width: 600px ) {
	.vxb-vendor-bookings .vxb-card {
		flex-direction: column;
		align-items: flex-start;
		gap: 10px;
	}

	.vxb-vendor-bookings .vxb-card-side {
		flex-wrap: wrap;
		width: 100%;
	}
}

@media ( max-width: 480px ) {
	.vxb-vendor-bookings .vxb-panel {
		width: 100vw;
	}
}

/* ---------------------------------------------------------------------------
 * Date-range calendar popup (Pikaday), scoped to our own theme class so it
 * never affects Voxel's calendars. Provides full popup chrome since Voxel's
 * base pikaday CSS intentionally has no background/border/shadow.
 * Colours are driven by CSS variables the Elementor "Calendar popup" controls set.
 * ------------------------------------------------------------------------- */
.vxb-vendor-bookings .pika-single.vxb-pikaday {
	background: var( --vxb-cal-bg, #fff );
	color: var( --vxb-cal-text, #1f2430 );
	border: 1px solid var( --vxb-cal-border, rgba( 0, 0, 0, 0.1 ) );
	border-radius: var( --vxb-cal-radius, 12px );
	box-shadow: 0 12px 32px rgba( 0, 0, 0, 0.16 );
	padding: 10px;
	z-index: 100050;
	font: inherit;
}

.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-lendar {
	margin: 2px;
	width: auto;
}

.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-title {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	height: 40px;
}

/* The month and the year are REAL dropdowns — Pikaday overlays an invisible native
   <select> on each label. Style them as small select-buttons so that's actually
   discoverable; as plain text nobody realised they were clickable. */
.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-label {
	font-weight: 600;
	font-size: 13px;
	color: var( --vxb-cal-text, #1f2430 );
	background: var( --vxb-cal-label-bg, rgba( 0, 0, 0, 0.05 ) );
	border: 1px solid var( --vxb-cal-border, rgba( 0, 0, 0, 0.1 ) );
	border-radius: 8px;
	padding: 5px 10px;
	margin: 0 2px;
	cursor: pointer;
	transition: border-color 0.15s ease;
}

.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-label:hover {
	border-color: var( --vxb-cal-accent, #2271b1 );
}

.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-label:after {
	border-color: var( --vxb-cal-text, #1f2430 );
	opacity: 0.7;
}

.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-prev,
.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-next {
	position: absolute;
	top: 0;
	width: 30px;
	height: 40px;
	padding: 0;
	font-size: 0;
	background: none;
	border: 0;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	opacity: 0.7;
}

.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-prev:hover,
.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-next:hover {
	opacity: 1;
}

.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-prev { left: 2px; }
.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-next { right: 2px; }

.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-prev:before,
.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-next:before {
	content: "";
	width: 8px;
	height: 8px;
	border: solid var( --vxb-cal-text, #1f2430 );
	border-width: 0 2px 2px 0;
}

.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-prev:before { transform: rotate( 135deg ); }
.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-next:before { transform: rotate( -45deg ); }

/* Hide Voxel's built-in arrow icon/text so only our single chevron shows. */
.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-prev > *,
.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-next > * {
	display: none;
}

.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-prev:before,
.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-next:before {
	pointer-events: none;
}

.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-table th {
	color: var( --vxb-cal-muted, #8a8f9c );
	font-size: 12px;
	font-weight: 500;
	padding-bottom: 4px;
}

.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-button {
	width: 36px;
	height: 36px;
	margin: auto;
	padding: 0;
	border: 2px solid transparent;
	border-radius: 8px;
	background: transparent;
	color: var( --vxb-cal-text, #1f2430 );
	font-size: 14px;
	text-align: center;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background-color 0.15s ease, color 0.15s ease;
}

.vxb-vendor-bookings .pika-single.vxb-pikaday .pika-button:hover {
	background: var( --vxb-cal-accent, #2271b1 );
	color: var(--vxb-on-accent);
	border-color: transparent;
	border-radius: 8px;
	box-shadow: none;
}

.vxb-vendor-bookings .pika-single.vxb-pikaday .is-today .pika-button {
	color: var( --vxb-cal-accent, #2271b1 );
	font-weight: 700;
}

.vxb-vendor-bookings .pika-single.vxb-pikaday .is-selected .pika-button {
	background: var( --vxb-cal-accent, #2271b1 );
	color: var(--vxb-on-accent);
	border-radius: 8px;
	box-shadow: none;
}

.vxb-vendor-bookings .pika-single.vxb-pikaday .is-disabled .pika-button,
.vxb-vendor-bookings .pika-single.vxb-pikaday .is-outside-current-month .pika-button {
	opacity: 0.35;
}

/* ============================================================================
   Bookings (VX) redesign (1.11.0) — modern dashboard: stats, status pills,
   date-grouped rows, soft status pills, refined slide-over panel. Appended so it
   overrides the earlier layout while the Pikaday theme + reschedule-slot styles
   above are preserved. Ships a self-contained neutral light palette (typography
   inherits, accent follows the theme); every colour is overridable in the Style tab.
   ============================================================================ */
.vxb-vendor-bookings {
	/* Design-first neutral base = the "Minimal" preset; the Style presets below override
	   these master variables and everything in this file DERIVES from them. */
	--vxb-text: #1f2937;
	--vxb-muted: #6b7280;
	--vxb-border: #e5e7eb;
	--vxb-bg-soft: #f9fafb;
	--vxb-bg: #ffffff;
	--vxb-accent: var(--ts-accent-1, #2563eb);
	--vxb-on-accent: #fff;

	/* Master extras (1.15.0): radius, density, semantic ORDER-status colours. The pill
	   bg/fg pairs DERIVE from these (tints mix against --vxb-bg so they track light/dark
	   presets); dark presets lighten the status hues. */
	--vxb-radius: 12px;
	--vxb-row-gap: 8px;
	--vxb-completed: #1e7e45;
	--vxb-pending: #b45309;
	--vxb-canceled: #b42318;
	--vxb-refunded: var(--vxb-muted);

	--vxb-ava-bg: color-mix( in srgb, var(--vxb-accent) 12%, var(--vxb-bg) );
	--vxb-ava-fg: var(--vxb-accent);
	--vxb-st-completed-bg: color-mix( in srgb, var(--vxb-completed) 14%, var(--vxb-bg) ); --vxb-st-completed-fg: var(--vxb-completed);
	--vxb-st-pending-bg: color-mix( in srgb, var(--vxb-pending) 14%, var(--vxb-bg) );     --vxb-st-pending-fg: var(--vxb-pending);
	--vxb-st-canceled-bg: color-mix( in srgb, var(--vxb-canceled) 14%, var(--vxb-bg) );   --vxb-st-canceled-fg: var(--vxb-canceled);
	--vxb-st-refunded-bg: color-mix( in srgb, var(--vxb-muted) 12%, var(--vxb-bg) );      --vxb-st-refunded-fg: var(--vxb-muted);
	--vxb-st-neutral-bg: color-mix( in srgb, var(--vxb-muted) 12%, var(--vxb-bg) );       --vxb-st-neutral-fg: var(--vxb-muted);

	/* Sub-component vars (calendar view, status pills, sort menu) all derive from the
	   master palette, so the whole widget — including the calendar tab — follows the
	   preset. (These previously fell back to hardcoded blue/black on dark presets.) */
	--vxb-sort-accent: var(--vxb-accent);
	--vxb-pill-active-bg: var(--vxb-accent);
	--vxb-pill-active-fg: var(--vxb-on-accent);
	--vxb-cal-accent: var(--vxb-accent);
	--vxb-cal-bg: var(--vxb-bg);
	--vxb-cal-text: var(--vxb-text);
	--vxb-cal-muted: var(--vxb-muted);
	--vxb-cal-border: var(--vxb-border);
	--vxb-cal-label-bg: color-mix( in srgb, var(--vxb-text) 5%, transparent );
	--vxb-cal-radius: var(--vxb-radius);
	color: var(--vxb-text);
}

/* ── STYLE PRESETS (1.15.0) — same set as the other VX widgets. Minimal = base above. ── */
.vxb-preset-soft .vxb-vendor-bookings {
	--vxb-accent: #1d9e75;
	--vxb-bg: #fbfaf7;
	--vxb-bg-soft: #f3efe8;
	--vxb-text: #33302a;
	--vxb-muted: #8c8579;
	--vxb-border: #ece6db;
	--vxb-radius: 16px;
}
.vxb-preset-bold .vxb-vendor-bookings {
	--vxb-accent: #534ab7;
	--vxb-bg: #ffffff;
	--vxb-bg-soft: #f1f0fb;
	--vxb-text: #1c1830;
	--vxb-muted: #6f6a86;
	--vxb-border: #e2e0f0;
	--vxb-radius: 18px;
}
.vxb-preset-midnight .vxb-vendor-bookings {
	--vxb-accent: #8f86e6;
	--vxb-on-accent: #14121f;
	--vxb-bg: #1b1d24;
	--vxb-bg-soft: #23262f;
	--vxb-text: #eef0f5;
	--vxb-muted: #9aa1b1;
	--vxb-border: #313542;
	--vxb-completed: #5dcaa5;
	--vxb-pending: #efaf52;
	--vxb-canceled: #e86a6a;
	--vxb-radius: 12px;
}
.vxb-preset-activity-rush .vxb-vendor-bookings {
	--vxb-accent: #c0fa1e;
	--vxb-on-accent: #121416;
	--vxb-bg: #1c1e22;
	--vxb-bg-soft: #25272d;
	--vxb-text: #fafafa;
	--vxb-muted: #a1a4aa;
	--vxb-border: #30333a;
	--vxb-completed: #5dcaa5;
	--vxb-pending: #efaf52;
	--vxb-canceled: #f0616a;
	--vxb-radius: 12px;
}

/* ── DENSITY ── */
.vxb-density-compact .vxb-vendor-bookings {
	--vxb-row-gap: 5px;
}

/* Summary stats */
.vxb-vendor-bookings .vxb-stats {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 10px;
}
.vxb-vendor-bookings .vxb-stat {
	background: var(--vxb-bg-soft);
	border-radius: 10px;
	padding: 12px 14px;
}
.vxb-vendor-bookings .vxb-stat-label { display: block; font-size: 12px; color: var(--vxb-muted); }
.vxb-vendor-bookings .vxb-stat-value { display: block; font-size: 20px; font-weight: 600; margin-top: 3px; color: var(--vxb-text); }

/* Toolbar (search + selects + sort) — overrides the old mobile-drawer layout.
   justify-content:flex-start is explicit so the custom date-range row (which
   wraps onto its own line) aligns left instead of being pushed right by the
   old base rule's flex-end (which left an empty gap on the left). */
.vxb-vendor-bookings .vxb-toolbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: flex-start;
	gap: 8px;
}
.vxb-vendor-bookings .vxb-search-box {
	flex: 1 1 200px;
	min-width: 0;
	display: flex;
	align-items: center;
	gap: 8px;
	height: 40px;
	padding: 0 12px;
	background: var(--vxb-bg);
	border: 1px solid var(--vxb-border);
	border-radius: 8px;
}
.vxb-vendor-bookings .vxb-search-icon { color: var(--vxb-muted); flex: 0 0 auto; }
.vxb-vendor-bookings .vxb-search-input {
	flex: 1; min-width: 0; height: 100%;
	border: 0; background: transparent; outline: none;
	font: inherit; font-size: 14px; color: var(--vxb-text);
}
.vxb-vendor-bookings select.vxb-filter {
	appearance: none; -webkit-appearance: none; -moz-appearance: none;
	height: 40px;
	padding: 0 34px 0 12px;
	border: 1px solid var(--vxb-border);
	border-radius: 8px;
	background-color: var(--vxb-bg);
	color: var(--vxb-text);
	font: inherit; font-size: 14px; cursor: pointer;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 12px center;
	background-size: 12px;
}
.vxb-vendor-bookings select.vxb-filter:focus { outline: none; border-color: var(--vxb-accent); }
/* Custom date range. On desktop it's a toolbar flex item: order:1 + basis:100%
   drop it onto its own full-width line AFTER the sort control (so From/To sit on
   a clean second row, left-aligned, not squeezed between the selects and sort). */
.vxb-vendor-bookings .vxb-daterow { display: flex; flex-wrap: wrap; gap: 8px; order: 1; flex-basis: 100%; }
.vxb-vendor-bookings .vxb-daterow .vxb-datefield { flex: 0 1 220px; min-width: 0; }
.vxb-vendor-bookings .vxb-date { width: 100%; height: 40px; padding: 0 12px; border: 1px solid var(--vxb-border); border-radius: 8px; background: var(--vxb-bg); color: var(--vxb-text); font: inherit; font-size: 14px; }

/* Filter zone: one bounded card that groups the toolbar (search + secondary
   filters + sort) and the status pills, so the eye reads them as a unit with a
   clear boundary — instead of loose fields floating on the page. */
.vxb-vendor-bookings .vxb-filterbar {
	display: flex;
	flex-direction: column;
	gap: 12px;
	padding: 12px;
	border: 1px solid var(--vxb-border);
	border-radius: var(--vxb-radius);
	background: var(--vxb-bg-soft);
}

/* Hairline between the secondary filters and the status pills inside the card. */
.vxb-vendor-bookings .vxb-filterbar .vxb-pills {
	padding-top: 12px;
	border-top: 1px solid var(--vxb-border);
}

/* Mobile-only "Filters" trigger (hidden on desktop; shown in the 782px block). */
.vxb-vendor-bookings .vxb-filters-toggle {
	display: none;
	align-items: center;
	gap: 7px;
	height: 40px;
	padding: 0 14px;
	border: 1px solid var(--vxb-border);
	border-radius: 8px;
	background: var(--vxb-bg);
	color: var(--vxb-text);
	font: inherit; font-size: 14px;
	cursor: pointer;
	flex: 0 0 auto;
}
.vxb-vendor-bookings .vxb-filters-badge {
	display: inline-flex; align-items: center; justify-content: center;
	min-width: 18px; height: 18px; padding: 0 5px;
	border-radius: 999px;
	background: var(--vxb-accent); color: var(--vxb-on-accent);
	font-size: 11px; font-weight: 600; line-height: 1;
}

/* "More" statuses menu — mirrors the sort dropdown, palette-derived. */
.vxb-vendor-bookings .vxb-more { position: relative; flex: 0 0 auto; }
.vxb-vendor-bookings .vxb-more-btn { gap: 5px; }
.vxb-vendor-bookings .vxb-more-caret {
	width: 6px; height: 6px; margin-top: -2px;
	border: solid currentColor; border-width: 0 2px 2px 0;
	transform: rotate( 45deg ); opacity: 0.6;
}
.vxb-vendor-bookings .vxb-more-menu {
	position: absolute;
	top: calc( 100% + 6px );
	left: 0;
	z-index: 100050;
	min-width: 180px;
	max-width: calc( 100vw - 32px );
	max-height: 320px;
	overflow-y: auto;
	margin: 0;
	padding: 6px;
	list-style: none;
	background: var(--vxb-bg);
	border: 1px solid var(--vxb-border);
	border-radius: 10px;
	box-shadow: 0 12px 32px rgba( 0, 0, 0, 0.16 );
}
.vxb-vendor-bookings .vxb-more-option {
	display: flex; align-items: center; justify-content: space-between; gap: 12px;
	padding: 9px 12px;
	border-radius: 6px;
	color: var(--vxb-text);
	cursor: pointer;
	white-space: nowrap;
}
.vxb-vendor-bookings .vxb-more-option:hover { background: color-mix( in srgb, var(--vxb-text) 8%, transparent ); }
.vxb-vendor-bookings .vxb-more-option-active { font-weight: 600; color: var(--vxb-accent); }
.vxb-vendor-bookings .vxb-more-count { font-size: 12px; color: var(--vxb-muted); }

/* Status filter pills */
.vxb-vendor-bookings .vxb-pills { display: flex; flex-wrap: wrap; gap: 6px; }
.vxb-vendor-bookings .vxb-pill {
	display: inline-flex; align-items: center; gap: 6px;
	border: 1px solid var(--vxb-border);
	background: var(--vxb-bg);
	border-radius: 999px;
	padding: 6px 12px;
	font: inherit; font-size: 13px;
	color: var(--vxb-muted);
	cursor: pointer;
	transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.vxb-vendor-bookings .vxb-pill:hover { border-color: color-mix( in srgb, var(--vxb-text) 22%, var(--vxb-border) ); }
.vxb-vendor-bookings .vxb-pill-on {
	background: var(--vxb-pill-active-bg, var(--vxb-text));
	border-color: var(--vxb-pill-active-bg, var(--vxb-text));
	color: var(--vxb-pill-active-fg, #fff);
}
.vxb-vendor-bookings .vxb-pill-count { font-size: 12px; opacity: 0.65; }
.vxb-vendor-bookings .vxb-pill-on .vxb-pill-count { opacity: 0.85; }

/* List + date groups + rows */
.vxb-vendor-bookings .vxb-list {
	border: 1px solid var(--vxb-border);
	border-radius: 12px;
	overflow: hidden;
	background: var(--vxb-bg);
	transition: opacity 0.15s ease;
}
.vxb-vendor-bookings .vxb-list.vxb-pending { opacity: 0.55; pointer-events: none; }
.vxb-vendor-bookings .vxb-state { padding: 36px 20px; text-align: center; color: var(--vxb-muted); font-size: 14px; }
.vxb-vendor-bookings .vxb-group-head {
	display: flex; align-items: center; justify-content: space-between;
	background: var(--vxb-bg-soft);
	padding: 9px 16px;
	font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em;
	color: var(--vxb-muted);
	border-top: 1px solid var(--vxb-border);
}
.vxb-vendor-bookings .vxb-group:first-child .vxb-group-head { border-top: 0; }
.vxb-vendor-bookings .vxb-group-count { font-weight: 500; }

/* --- Date view -------------------------------------------------------------
   The date header carries more than the period one (weekday, date, sometimes a
   Today/Tomorrow chip), so it needs an explicit gap and a `margin-left: auto`
   count instead of the plain space-between used above. */
.vxb-vendor-bookings .vxb-group-head--date { gap: 8px; justify-content: flex-start; }
.vxb-vendor-bookings .vxb-group-head--date .vxb-group-count { margin-left: auto; }
.vxb-vendor-bookings .vxb-group-date {
	color: var(--vxb-text);
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}
.vxb-vendor-bookings .vxb-group-rel {
	/* Chip, so it reads as a note on the date rather than part of it. */
	text-transform: none;
	letter-spacing: 0.01em;
	font-size: 11px;
	font-weight: 600;
	line-height: 1.4;
	color: var(--vxb-accent);
	border: 1px solid color-mix( in srgb, var(--vxb-accent) 40%, transparent );
	border-radius: 20px;
	padding: 0 8px;
}

/* Month rule: only rendered where the list crosses into a new month. */
.vxb-vendor-bookings .vxb-month-rule {
	display: flex; align-items: center; gap: 12px;
	margin: 0;
	padding: 18px 16px 8px;
	font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.14em;
	color: var(--vxb-muted);
	border-top: 1px solid var(--vxb-border);
}
.vxb-vendor-bookings .vxb-month-rule::after {
	content: "";
	flex: 1;
	height: 1px;
	background: var(--vxb-border);
}
.vxb-vendor-bookings .vxb-group:first-child .vxb-month-rule { border-top: 0; }
/* The rule already separates the months; a second line under it reads as a gap. */
.vxb-vendor-bookings .vxb-month-rule + .vxb-group-head { border-top: 0; }

/* --- Class session sub-groups ----------------------------------------------
   A day can hold the same class five times over. The session header carries what
   every row underneath would otherwise repeat — time, class, room, instructor. */
.vxb-vendor-bookings .vxb-session {
	display: flex; align-items: center; gap: 10px;
	padding: 9px 16px;
	border-top: 1px solid var(--vxb-border);
	/* Sits between the day header and the rows in weight: tinted, not filled. */
	background: color-mix( in srgb, var(--vxb-text) 3%, var(--vxb-bg) );
	border-left: 2px solid var(--vxb-accent);
	cursor: pointer;
	user-select: none;
}
.vxb-vendor-bookings .vxb-session:hover { background: color-mix( in srgb, var(--vxb-text) 6%, var(--vxb-bg) ); }
.vxb-vendor-bookings .vxb-session-chev { display: flex; flex: 0 0 auto; color: var(--vxb-muted); transition: transform 0.15s ease; }
.vxb-vendor-bookings .vxb-session-closed .vxb-session-chev { transform: rotate(-90deg); }
.vxb-vendor-bookings .vxb-session-time {
	font-size: 12.5px; font-weight: 600; color: var(--vxb-text);
	font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* Colour comes from the class itself (inline style), so this must not set one. */
.vxb-vendor-bookings .vxb-session-name { font-size: 13.5px; font-weight: 600; white-space: nowrap; }
.vxb-vendor-bookings .vxb-session-meta {
	font-size: 12.5px; color: var(--vxb-muted);
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.vxb-vendor-bookings .vxb-session-seats {
	margin-left: auto;
	display: inline-flex; align-items: center; gap: 5px;
	font-size: 12.5px; color: var(--vxb-muted);
	font-variant-numeric: tabular-nums; white-space: nowrap; flex: 0 0 auto;
}
.vxb-vendor-bookings .vxb-session-seats svg { flex: 0 0 auto; }
/* Full is the one fact worth pushing at someone scanning a day. Reuses the pending
   status colour rather than inventing an amber — that one is already tuned for every
   palette preset, light and dark. */
.vxb-vendor-bookings .vxb-session-seats.full { color: var(--vxb-st-pending-fg); font-weight: 600; }
.vxb-vendor-bookings .vxb-session-full::before { content: "· "; }

/* Roster rows: indented and rail-linked to the session that owns them. */
.vxb-vendor-bookings .vxb-row-in { padding-left: 34px; border-left: 2px solid var(--vxb-border); }
.vxb-vendor-bookings .vxb-row-seats {
	font-size: 11.5px; padding: 2px 8px; border-radius: 20px; white-space: nowrap;
	color: var(--vxb-accent);
	border: 1px solid color-mix( in srgb, var(--vxb-accent) 40%, transparent );
}

/* Divider before the bookings on a day that belong to no session. */
.vxb-vendor-bookings .vxb-loose-label {
	margin: 0;
	padding: 12px 16px 6px;
	border-top: 1px solid var(--vxb-border);
	font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.12em;
	color: var(--vxb-muted);
}
.vxb-vendor-bookings .vxb-loose-label + .vxb-row { border-top: 0; }

/* --- View switch ----------------------------------------------------------- */
.vxb-vendor-bookings .vxb-view {
	display: inline-flex;
	border: 1px solid var(--vxb-border);
	border-radius: var(--vxb-radius);
	overflow: hidden;
	flex: 0 0 auto;
}
.vxb-vendor-bookings .vxb-view-btn {
	display: inline-flex; align-items: center; gap: 6px;
	padding: 6px 11px;
	border: 0;
	background: var(--vxb-bg);
	color: var(--vxb-muted);
	font: inherit;
	font-size: 0.86em;
	line-height: 1.2;
	cursor: pointer;
	white-space: nowrap;
	transition: background 0.12s ease, color 0.12s ease;
}
.vxb-vendor-bookings .vxb-view-btn + .vxb-view-btn { border-left: 1px solid var(--vxb-border); }
.vxb-vendor-bookings .vxb-view-btn:hover { color: var(--vxb-text); }
.vxb-vendor-bookings .vxb-view-btn[aria-pressed="true"] {
	background: var(--vxb-accent);
	color: var(--vxb-on-accent);
	font-weight: 600;
}
.vxb-vendor-bookings .vxb-view-btn svg { flex: 0 0 auto; }
.vxb-vendor-bookings .vxb-row {
	display: flex; align-items: center; gap: 12px;
	padding: 11px 16px;
	border-top: 1px solid var(--vxb-border);
	cursor: pointer;
	transition: background 0.12s ease;
}
.vxb-vendor-bookings .vxb-row:hover { background: var(--vxb-bg-soft); }
.vxb-vendor-bookings .vxb-row-canceled { opacity: 0.6; }
.vxb-vendor-bookings .vxb-row-canceled .vxb-row-name { text-decoration: line-through; }
.vxb-vendor-bookings .vxb-ava, .vxb-vendor-bookings .vxb-ava-img { width: 38px; height: 38px; border-radius: 50%; flex: 0 0 auto; }
.vxb-vendor-bookings .vxb-ava {
	display: flex; align-items: center; justify-content: center;
	font-size: 13px; font-weight: 600;
	background: var(--vxb-ava-bg); color: var(--vxb-ava-fg);
}
.vxb-vendor-bookings .vxb-ava-img { object-fit: cover; }
.vxb-vendor-bookings .vxb-row-main { flex: 1; min-width: 0; }
.vxb-vendor-bookings .vxb-row-name { display: block; font-size: 14px; font-weight: 500; color: var(--vxb-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vxb-vendor-bookings .vxb-row-sub { display: block; font-size: 13px; color: var(--vxb-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 1px; }
.vxb-vendor-bookings .vxb-row-when { font-size: 13px; color: var(--vxb-muted); white-space: nowrap; flex: 0 0 auto; }
.vxb-vendor-bookings .vxb-row-total { font-size: 14px; font-weight: 500; color: var(--vxb-text); white-space: nowrap; flex: 0 0 auto; min-width: 52px; text-align: right; }
.vxb-vendor-bookings .vxb-row-chev { color: color-mix( in srgb, var(--vxb-muted) 55%, var(--vxb-bg) ); display: flex; flex: 0 0 auto; }

/* Soft status pills (rows + panel) */
.vxb-vendor-bookings .vxb-status { font-size: 12px; line-height: 1.3; padding: 3px 9px; border-radius: 999px; white-space: nowrap; flex: 0 0 auto; }
.vxb-vendor-bookings .vxb-st-completed { background: var(--vxb-st-completed-bg); color: var(--vxb-st-completed-fg); }
.vxb-vendor-bookings .vxb-st-pending   { background: var(--vxb-st-pending-bg);   color: var(--vxb-st-pending-fg); }
.vxb-vendor-bookings .vxb-st-canceled  { background: var(--vxb-st-canceled-bg);  color: var(--vxb-st-canceled-fg); }
.vxb-vendor-bookings .vxb-st-refunded  { background: var(--vxb-st-refunded-bg);  color: var(--vxb-st-refunded-fg); }
.vxb-vendor-bookings .vxb-st-neutral   { background: var(--vxb-st-neutral-bg);   color: var(--vxb-st-neutral-fg); }

/* Pagination */
.vxb-vendor-bookings .vxb-pagination { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 2px; }
.vxb-vendor-bookings .vxb-page-btn { height: 36px; padding: 0 14px; border: 1px solid var(--vxb-border); border-radius: 8px; background: var(--vxb-bg); color: var(--vxb-text); font: inherit; font-size: 13px; cursor: pointer; }
.vxb-vendor-bookings .vxb-page-btn:disabled { opacity: 0.5; cursor: default; }
.vxb-vendor-bookings .vxb-page-info { font-size: 13px; color: var(--vxb-muted); }

/* Detail panel head/body (the slide-in container + animation stay above) */
.vxb-vendor-bookings .vxb-panel-head { display: flex; align-items: flex-start; gap: 12px; padding: 16px; border-bottom: 1px solid var(--vxb-border); }
.vxb-vendor-bookings .vxb-ava-lg { width: 46px; height: 46px; font-size: 15px; }
.vxb-vendor-bookings .vxb-panel-head-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.vxb-vendor-bookings .vxb-panel-head-text strong { font-size: 15px; font-weight: 500; color: var(--vxb-text); }
.vxb-vendor-bookings .vxb-panel-head-text .vxb-status { align-self: flex-start; }
.vxb-vendor-bookings .vxb-panel-close { margin-left: auto; border: 0; background: transparent; color: var(--vxb-muted); cursor: pointer; display: flex; padding: 2px; }
.vxb-vendor-bookings .vxb-panel-body { padding: 4px 16px; }
/* Consolidated from two definitions that used to merge (see the note further up).
   `flex-direction: column` came from the older block, everything else from here —
   so despite the name, this has always been a stacked label-above-value field, not
   a `label | value` row. The effective values are unchanged.
   `justify-content: space-between` is deliberately NOT carried over: it was inert
   here (a column-flex row is content-height, so there is no free space to spread),
   but the moment the mobile grid stretched these cells it pushed each label and its
   value ~50px apart — the 1.35.1 bug. Nothing wants it. */
.vxb-vendor-bookings .vxb-panel-row { display: flex; flex-direction: column; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--vxb-border); font-size: 14px; }
.vxb-vendor-bookings .vxb-panel-row:last-child { border-bottom: 0; }
.vxb-vendor-bookings .vxb-panel-label { color: var(--vxb-muted); }
.vxb-vendor-bookings .vxb-panel-total { font-weight: 600; }
.vxb-vendor-bookings .vxb-panel-comments { flex-direction: column; align-items: flex-start; }
.vxb-vendor-bookings .vxb-panel-comments span:last-child { white-space: pre-wrap; word-break: break-word; }
.vxb-vendor-bookings .vxb-panel-foot { padding: 14px 16px; border-top: 1px solid var(--vxb-border); display: flex; flex-direction: column; gap: 8px; }
.vxb-vendor-bookings .vxb-panel-foot .ts-btn { width: 100%; }

/* Responsive.
   600px, not 560 — every other widget (and every other block in this file) switches at 600,
   so a stray 560 left a 40px band where the row had already lost its layout but not yet its
   mobile rules. The time is no longer hidden here: the two-line row below has a place for it. */
@media ( max-width: 600px ) {
	.vxb-vendor-bookings .vxb-stat-value { font-size: 18px; }
	.vxb-vendor-bookings .vxb-search-box { flex-basis: 100%; }

	/* Full width and split evenly — the switch is a primary control on a phone, and
	   both halves need to be a comfortable thumb target. */
	.vxb-vendor-bookings .vxb-view { display: flex; width: 100%; order: 10; }
	.vxb-vendor-bookings .vxb-view-btn { flex: 1 1 0; justify-content: center; padding: 9px 11px; }

	/* Sticky date headers: on a long single-column list it's easy to scroll past a
	   boundary and lose track of which day you're reading. Only in date view — the
	   period buckets are few and far apart enough not to need it. */
	.vxb-vendor-bookings .vxb-group-head--date {
		position: sticky;
		top: 0;
		z-index: 2;
	}

	/* Session header wraps to two lines: time + class + count stay together, room and
	   instructor drop underneath rather than being truncated to nothing. */
	.vxb-vendor-bookings .vxb-session { flex-wrap: wrap; row-gap: 3px; padding: 9px 12px; }
	.vxb-vendor-bookings .vxb-session-meta { flex-basis: 100%; order: 5; white-space: normal; }

	/* Indentation costs width a phone doesn't have; the rail alone carries the nesting. */
	.vxb-vendor-bookings .vxb-row-in { padding-left: 22px; }
}

/* Tablets / phones: filters become a bottom-sheet modal with an apply button. */
@media ( max-width: 782px ) {
	.vxb-vendor-bookings .vxb-toolbar {
		justify-content: space-between;
	}

	/* Scoped to out-specify the base .vxb-vendor-bookings .vxb-filters-toggle rule. */
	.vxb-vendor-bookings .vxb-filters-toggle {
		display: inline-flex;
		justify-content: center;
	}

	.vxb-vendor-bookings .vxb-filters-backdrop {
		display: block;
		position: fixed;
		inset: 0;
		background: rgba( 0, 0, 0, 0.45 );
		z-index: 100040;
	}

	.vxb-vendor-bookings .vxb-filters {
		position: fixed;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: 100041;
		display: flex;
		flex-direction: column;
		max-height: 85vh;
		background: var(--vxb-bg);
		border-radius: 16px 16px 0 0;
		box-shadow: 0 -8px 30px rgba( 0, 0, 0, 0.2 );
		transform: translateY( 100% );
		transition: transform 0.25s ease;
	}

	.vxb-vendor-bookings .vxb-filters.vxb-filters-open {
		transform: translateY( 0 );
	}

	.vxb-vendor-bookings .vxb-filters-head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 14px 18px;
		border-bottom: 1px solid var(--vxb-border);
	}

	.vxb-vendor-bookings .vxb-filters-close {
		font-size: 22px;
		line-height: 1;
		background: none;
		border: 0;
		color: var(--vxb-muted);
		cursor: pointer;
		padding: 4px 8px;
	}

	.vxb-vendor-bookings .vxb-filters-body {
		display: flex;
		flex-direction: column;
		align-items: stretch;
		gap: 12px;
		padding: 16px 18px;
		overflow-y: auto;
	}

	/* In the sheet, every secondary field spans the full width. */
	.vxb-vendor-bookings .vxb-filters-body .vxb-filter,
	.vxb-vendor-bookings .vxb-filters-body .vxb-daterow,
	.vxb-vendor-bookings .vxb-filters-body .vxb-daterow .vxb-datefield {
		flex: 1 1 auto;
		width: 100%;
	}

	.vxb-vendor-bookings .vxb-filters-apply {
		display: flex;
		align-items: center;
		justify-content: center;
		box-sizing: border-box;
		width: calc( 100% - 36px );
		height: 46px;
		margin: 12px 18px 18px;
		border: 1px solid var(--vxb-accent);
		border-radius: 10px;
		background: var(--vxb-accent);
		color: var(--vxb-on-accent);
		font: inherit; font-size: 15px; font-weight: 600;
		cursor: pointer;
	}

	/* In the bottom-sheet, let the calendar flow inline (it can scroll). */
	.vxb-vendor-bookings .vxb-cal-host,
	.vxb-vendor-bookings .vxb-cal-host--up {
		position: static;
		top: auto;
		bottom: auto;
		margin-top: 8px;
	}

	/* Status pills become a single horizontally-scrollable strip so the list
	   stays visible immediately (no tall wrapped block pushing it down). */
	.vxb-vendor-bookings .vxb-pills {
		flex-wrap: nowrap;
		overflow-x: auto;
		scrollbar-width: none;
		-webkit-overflow-scrolling: touch;
	}
	.vxb-vendor-bookings .vxb-pills::-webkit-scrollbar { display: none; }
	.vxb-vendor-bookings .vxb-pill { flex: 0 0 auto; }

	/* The pill strip clips overflow-y, and the sort control can sit near a screen
	   edge — so dock BOTH dropdowns to the viewport bottom (fixed escapes the clip
	   and can't run off-screen) instead of anchoring them to the button. */
	.vxb-vendor-bookings .vxb-sort-menu,
	.vxb-vendor-bookings .vxb-more-menu {
		position: fixed;
		left: 12px; right: 12px; bottom: 12px; top: auto;
		min-width: 0; max-width: none;
		max-height: 55vh;
		z-index: 100060;
	}
}

/* ═══════════════════════════════════════════════════════════════════════════
   MOBILE (≤600px) — rows and panel
   ═══════════════════════════════════════════════════════════════════════════
   Appended last, and every rule is scoped to .vxb-vendor-bookings, so it beats
   both the base rules above and Elementor's Kit (which styles bare `button`,
   `a` and `p` globally at 0-1-1 and otherwise out-guns a single class).
   ═══════════════════════════════════════════════════════════════════════════ */
@media ( max-width: 600px ) {

	/* ── List row: two lines instead of one ──────────────────────────────────
	   The one-line row put six items in a single flex context, and the status
	   pill takes what it needs — with a localized label ("Εγκρίθηκε",
	   "Εκκρεμεί πληρωμή") that is most of the width, so the customer name
	   collapsed to "M…". Four columns over two rows costs the same height and
	   gives the name a line of its own.

	       [ava] Name ......................... 15 €
	             18:02–19:02 · Listing    [pill]

	   `display: contents` promotes .vxb-row-main's children into this grid so
	   name and sub can be placed independently, without touching the markup. */
	.vxb-vendor-bookings .vxb-row {
		display: grid;
		grid-template-columns: auto auto minmax( 0, 1fr ) auto;
		grid-template-areas:
			"ava name name   total"
			"ava when sub    status";
		column-gap: 8px;
		row-gap: 2px;
		align-items: center;
		padding: 10px 14px;
	}

	.vxb-vendor-bookings .vxb-row > .vxb-ava,
	.vxb-vendor-bookings .vxb-row > .vxb-ava-img { grid-area: ava; align-self: center; }
	.vxb-vendor-bookings .vxb-row-main { display: contents; }
	.vxb-vendor-bookings .vxb-row-name { grid-area: name; }
	.vxb-vendor-bookings .vxb-row-sub  { grid-area: sub; margin-top: 0; }
	/* This cell is the TIME for a timeslot booking, but rowWhen() falls back to the
	   whole summary for a date range ("Jan 1 — Jan 4"). It sits in an `auto` column,
	   so an unusually long value would take its full width and starve the listing
	   name beside it. The cap never fires for real values; it just bounds the damage. */
	.vxb-vendor-bookings .vxb-row-when {
		grid-area: when;
		display: block;
		max-width: 45vw;
		overflow: hidden;
		text-overflow: ellipsis;
	}
	.vxb-vendor-bookings .vxb-row .vxb-status { grid-area: status; justify-self: end; }
	.vxb-vendor-bookings .vxb-row-total { grid-area: total; justify-self: end; min-width: 0; }

	/* The whole row is already tappable; the chevron only spends ~26px of the
	   width the name needs. */
	.vxb-vendor-bookings .vxb-row-chev { display: none; }

	/* Reads as "18:02–19:02 · Listing" without merging the two elements. */
	.vxb-vendor-bookings .vxb-row-sub::before {
		content: "·";
		margin-right: 5px;
		color: var( --vxb-muted );
	}

	/* ── Detail panel: two-column body ───────────────────────────────────────
	   Label above value in a 2-col grid: ~10 single-line rows become ~5, and no
	   value has to share a line with its own label.

	   `align-content: start` is REQUIRED, not cosmetic: .vxb-panel-body is
	   `flex: 1` inside a full-height sheet, so without it the grid stretches its
	   rows to fill the sheet and every field becomes a ~90px tall cell. */
	.vxb-vendor-bookings .vxb-panel-body {
		display: grid;
		grid-template-columns: 1fr 1fr;
		/* `dense` backfills the holes. A full-width field can't start beside a
		   half-width one, so it drops to the next line and strands an empty half
		   — with `dense` the next half-width field is pulled up into that hole
		   instead. Which fields are present varies per booking (email, phone,
		   class, room, instructor and comments are all conditional), so the
		   pairing can't be hand-tuned in the markup; the grid has to solve it. */
		grid-auto-flow: dense;
		align-content: start;
		gap: 8px;
		padding: 12px 14px;
	}

	/* Each field is its own bounded block. Label and value sit on the same left
	   edge, tight together, with the separation BETWEEN fields — that pairing is
	   what stops the panel reading as one run-on block of text. */
	.vxb-vendor-bookings .vxb-panel-row {
		display: flex;
		flex-direction: column;
		align-items: stretch;
		gap: 2px;
		padding: 7px 9px;
		min-width: 0;
		background: var(--vxb-bg-soft);
		border: 1px solid var(--vxb-border);
		border-radius: 8px;
	}

	.vxb-vendor-bookings .vxb-panel-label {
		font-size: 11px;
		line-height: 1.3;
		letter-spacing: 0.04em;
		text-transform: uppercase;
	}

	/* No text-align here any more. It used to force `left !important` because
	   my-bookings-user.css declared an UNSCOPED `.vxb-panel-row > :last-child {
	   text-align: right }` and both widgets share these class names, so its
	   stylesheet right-aligned THIS widget's values whenever both were on a page.
	   Both files are scoped now, this widget never sets text-align, and inheriting
	   is also the only thing that stays correct on an RTL site. */
	.vxb-vendor-bookings .vxb-panel-row > * {
		min-width: 0;
		overflow-wrap: anywhere;
	}

	/* Anything that can't live in half a phone width. */
	.vxb-vendor-bookings .vxb-panel-row--wide,
	.vxb-vendor-bookings .vxb-panel-comments { grid-column: 1 / -1; }

	/* ── Detail panel: two-column actions ────────────────────────────────────
	   Buttons must be allowed to WRAP: Voxel's action labels are localized, and
	   a long one ("Άνοιγμα παραγγελίας στο backend") in a half-width cell wraps
	   to two lines — two of those side by side still beat two full-width rows. */
	.vxb-vendor-bookings .vxb-panel-foot {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: 8px;
		padding: 12px 16px calc( 12px + env( safe-area-inset-bottom, 0px ) );
	}

	.vxb-vendor-bookings .vxb-panel-foot .ts-btn {
		width: 100% !important;
		height: auto !important;
		min-height: 42px !important;
		padding: 8px 10px !important;
		white-space: normal !important;
		line-height: 1.25 !important;
		display: inline-flex !important;
		align-items: center !important;
		justify-content: center !important;
		text-align: center !important;
	}

	/* Everything that isn't a button spans the grid. */
	.vxb-vendor-bookings .vxb-panel-foot > .vxb-panel-label,
	.vxb-vendor-bookings .vxb-panel-foot > .vxb-actions-error,
	.vxb-vendor-bookings .vxb-panel-foot > .vxb-actions-loading,
	.vxb-vendor-bookings .vxb-panel-foot > .vxb-reschedule { grid-column: 1 / -1; }

	/* Cancel is destructive and irreversible: it gets its own full-width row at
	   the end, never a half-width cell beside a benign action where a thumb can
	   miss and cancel a customer's booking. */
	.vxb-vendor-bookings .vxb-panel-foot .vxb-action-danger {
		grid-column: 1 / -1;
		order: 99;
	}
}

/* The injected empty-Today note (see groupsByDate): quiet, not an error — the date
   header above it is the information, this only explains the silence. */
.vxb-vendor-bookings .vxb-group-empty {
	margin: 0;
	padding: 13px 4px 17px;
	color: var(--vxb-muted);
	font-size: 0.875rem;
}
