/**
 * 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;

	/* Metrics are OURS — see the typography note below. */
	line-height: 1.45;
}

/* --- Typography normalisation ------------------------------------------------
   READ THIS BEFORE ADDING ANY FONT DECLARATION IN THIS FILE.

   The widget inherits the site's TYPEFACE on purpose: it should look like it
   belongs to the theme. What it must never inherit is the theme's METRICS.

   Two things kept leaking in and re-sizing the whole widget per site:

   1. Themes (Voxel + Core Framework here) resolve their body `line-height` to a
      fixed pixel LENGTH, and a length inherits verbatim — so a 12px seat count
      and a 13px rail time were both handed the same ~32px line box. Measured on
      staging before this fix: a class header 87px tall against a designed 48px,
      and day chips at 99px. A UNITLESS ratio re-computes against each element's
      own size, which is what we want.
   2. The Elementor kit styles bare elements — `.elementor-kit-N button
      { font-size: 18px; line-height: 28px; }` — and essentially every control in
      this widget is a <button>.

   So this block pins family + metrics for every control, at a specificity that
   beats the kit's `.elementor-kit-N button` (0,1,1) while still losing to the
   per-component rules further down (which are also (0,2,0) but come later).
   The doubled root class is what buys that specificity; it is deliberate.

   RULES: never use `font: inherit` (the shorthand re-imports size AND
   line-height), and never size in `em` (that re-imports the theme's size through
   the back door). Give the component an explicit px size instead. */
.vxb-vendor-bookings.vxb-vendor-bookings :where( button, input, select, textarea, optgroup ) {
	font-family: inherit;
	font-size: 14px;
	line-height: 1.45;
	letter-spacing: normal;
	text-transform: none;
}

.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-family: 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-family: inherit;
	font-size: 13px;
	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: 15px;
	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: 13px;
	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: 13px;
	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: 13px;
	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: 13px;
	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-family: 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: 16px;
	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: 13px;
}

.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-family: 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);
	/* Abandoned checkout, place back on sale. Muted rather than red: nothing went wrong and
	   nothing needs the vendor's attention — it is a fact, not an alert. */
	--vxb-released: 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-released-bg: color-mix( in srgb, var(--vxb-released) 12%, var(--vxb-bg) );   --vxb-st-released-fg: var(--vxb-released);
	--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-family: 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-family: 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-family: 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-family: 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-family: 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) ); }
/* Level 2 of the ladder above: tinted, not filled. The status filter is one of five
   controls in the bar and shouldn't outrank the list it filters. */
.vxb-vendor-bookings .vxb-pill-on {
	background: color-mix( in srgb, var(--vxb-pill-active-bg, var(--vxb-accent)) 16%, var(--vxb-bg) );
	border-color: color-mix( in srgb, var(--vxb-pill-active-bg, var(--vxb-accent)) 45%, transparent );
	color: var(--vxb-pill-active-bg, var(--vxb-text));
	font-weight: 700;
}
.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
   ---------------------------------------------------------------------------
   The list is a CANVAS, not a card. It used to be one bounded box with rows
   divided by hairlines inside it; now every item carries its own surface (a
   class card, or a standalone booking), so keeping the outer box would frame
   each card a second time. `overflow` goes back to visible as well — hidden
   makes the list its own scroll container, which silently stops the sticky day
   headers from sticking to anything on small screens. */
.vxb-vendor-bookings .vxb-list {
	display: flex;
	flex-direction: column;
	gap: 4px;
	transition: opacity 0.15s ease;
}
.vxb-vendor-bookings .vxb-list.vxb-pending { opacity: 0.55; pointer-events: none; }
.vxb-vendor-bookings .vxb-group { display: flex; flex-direction: column; gap: 4px; }

/* Loading / empty keep a surface of their own — with no list card behind them
   they would otherwise be text floating on the page. */
.vxb-vendor-bookings .vxb-state {
	padding: 36px 20px; text-align: center; color: var(--vxb-muted); font-size: 14px;
	background: var(--vxb-bg);
	border: 1px solid var(--vxb-border);
	border-radius: var(--vxb-radius);
}

/* The day header is a heading now, not a filled band: it lines up with the cards
   it introduces (rail width + the slot's column gap) and separates with a rule. */
.vxb-vendor-bookings .vxb-group-head {
	display: flex; align-items: center; justify-content: space-between;
	padding: 16px 16px 8px calc( var(--vxb-rail-w, 62px) + 12px );
	font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em;
	line-height: 1.4;
	color: var(--vxb-muted);
	border-bottom: 1px solid var(--vxb-border);
	margin-bottom: 2px;
}
.vxb-vendor-bookings .vxb-group:first-child .vxb-group-head { padding-top: 4px; }
.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 calc( var(--vxb-rail-w, 62px) + 12px );
	font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.14em;
	line-height: 1.4;
	color: var(--vxb-muted);
}
.vxb-vendor-bookings .vxb-month-rule::after {
	content: "";
	flex: 1;
	height: 1px;
	background: var(--vxb-border);
}

/* --- The agenda: a time rail, and cards that contain what belongs to them ---
   A day used to read as one uniform stack of bars, where a class header and a
   booking under it were the same shape and only an indent said which held which.
   The rail gives the day an axis you can scan without reading, and the card gives
   a class an edge, so containment does the work the indent was doing. */
.vxb-vendor-bookings .vxb-slot {
	display: grid;
	grid-template-columns: var(--vxb-rail-w, 62px) minmax( 0, 1fr );
	gap: 12px;
	position: relative;
	padding: 4px 16px 4px 0;
	/* Pinned, and UNITLESS on purpose. The theme resolves its body line-height to a
	   fixed pixel length, and a length inherits verbatim — so 13px times in the rail
	   and 12.5px seat counts were all being given a ~32px line box, which inflated
	   every card (a class header measured 87px against a designed ~48px). A ratio
	   re-computes against each element's own size instead. */
	line-height: 1.4;
}

/* The rail's hairline is the day's timeline, running behind the times. */
/* Centred in the gutter between the rail and the card. The slot is
   `[rail-w] 12px-gap [card]`, so the card's edge is at rail-w + 12 and the
   midpoint is rail-w + 6 — anything larger runs INTO the card and reads as a
   line touching the booking. */
.vxb-vendor-bookings .vxb-slot::before {
	content: "";
	position: absolute;
	left: calc( var(--vxb-rail-w, 62px) + 6px );
	top: 0;
	bottom: 0;
	width: 1px;
	background: var(--vxb-border);
}

.vxb-vendor-bookings .vxb-slot:first-of-type::before { top: 8px; }
.vxb-vendor-bookings .vxb-slot:last-of-type::before { bottom: 8px; }

.vxb-vendor-bookings .vxb-rail {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	padding: 12px 0 0 16px;
	font-variant-numeric: tabular-nums;
	text-align: right;
	min-width: 0;
}

.vxb-vendor-bookings .vxb-rail-from {
	font-size: 13px;
	font-weight: 600;
	color: var(--vxb-text);
	white-space: nowrap;
	letter-spacing: -0.01em;
}

.vxb-vendor-bookings .vxb-rail-to {
	font-size: 11.5px;
	color: var(--vxb-muted);
	white-space: nowrap;
	margin-top: 1px;
}

/* "All day" has no second line and no room to be nowrap at 62px. */
.vxb-vendor-bookings .vxb-rail--wide .vxb-rail-from {
	font-size: 11.5px;
	font-weight: 500;
	color: var(--vxb-muted);
	white-space: normal;
	line-height: 1.25;
}

/* --- Class card ------------------------------------------------------------- */
.vxb-vendor-bookings .vxb-sess-card {
	position: relative;
	background: var(--vxb-bg);
	border: 1px solid var(--vxb-border);
	border-radius: var(--vxb-radius);
	overflow: hidden;
	transition: border-color 0.15s ease;
}

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

/* The class's own colour, as an edge rather than as coloured text: a tinted name is
   hard to read on half the palettes, an edge is legible on all of them. Falls back
   to the accent when the class has no colour set. */
.vxb-vendor-bookings .vxb-sess-card::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	width: 3px;
	background: var(--vxb-class-color, var(--vxb-accent));
}

.vxb-vendor-bookings .vxb-session {
	display: grid;
	grid-template-columns: minmax( 0, 1fr ) auto auto;
	align-items: center;
	gap: 14px;
	width: 100%;
	padding: 11px 13px 11px 16px;
	background: none;
	border: 0;
	text-align: left;
	color: inherit;
	cursor: pointer;
	user-select: none;
	/* NOT `font: inherit`. The Elementor kit sets a page-sized font on every
	   <button> (`.elementor-kit-N button`), and inheriting instead pulls the
	   theme's body size + its fixed line-height length. Both are pinned so the
	   header keeps its own metrics whatever the site's typography does. */
	font-family: inherit;
	font-size: 13px;
	line-height: 1.4;
	letter-spacing: normal;
	text-transform: none;
}

.vxb-vendor-bookings .vxb-session:hover { background: var(--vxb-bg-soft); }
.vxb-vendor-bookings .vxb-session:focus-visible { outline: 2px solid var(--vxb-accent); outline-offset: -3px; }

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

.vxb-vendor-bookings .vxb-session-name {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: 14px;
	font-weight: 600;
	color: var(--vxb-text);
	min-width: 0;
}

.vxb-vendor-bookings .vxb-session-dot {
	width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto;
	background: var(--vxb-class-color, var(--vxb-accent));
}

/* Only earns its place where the rail is gone (small screens) — see the media query. */
.vxb-vendor-bookings .vxb-session-time { display: none; }

.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-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); }

/* --- Occupancy -------------------------------------------------------------
   The one fact a class vendor scans a day for. Every meter lands on the same right
   edge, so the column reads as a bar chart of the day without anyone reading a
   single number. Colours reuse the tuned status hues rather than inventing new
   ones — those already work across every palette preset, light and dark. */
.vxb-vendor-bookings .vxb-occ {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	flex: 0 0 auto;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.vxb-vendor-bookings .vxb-occ-track {
	width: 56px; height: 6px; border-radius: 3px;
	background: color-mix( in srgb, var(--vxb-text) 12%, var(--vxb-bg) );
	overflow: hidden; flex: 0 0 auto;
}

.vxb-vendor-bookings .vxb-occ-fill {
	display: block; height: 100%; border-radius: 3px;
	background: var(--vxb-accent);
	transition: width 0.2s ease;
}

.vxb-vendor-bookings .vxb-occ-num { font-size: 12.5px; font-weight: 600; color: var(--vxb-text); }

/* Quiet: visibly empty, but nothing is wrong — so it stays grey, not alarming. */
.vxb-vendor-bookings .vxb-occ[data-state="quiet"] .vxb-occ-fill { background: var(--vxb-muted); }
.vxb-vendor-bookings .vxb-occ[data-state="quiet"] .vxb-occ-num { color: var(--vxb-muted); font-weight: 500; }

/* Nearly gone, and gone. */
.vxb-vendor-bookings .vxb-occ[data-state="tight"] .vxb-occ-fill,
.vxb-vendor-bookings .vxb-occ[data-state="full"] .vxb-occ-fill { background: var(--vxb-st-pending-fg); }
.vxb-vendor-bookings .vxb-occ[data-state="tight"] .vxb-occ-num,
.vxb-vendor-bookings .vxb-occ[data-state="full"] .vxb-occ-num { color: var(--vxb-st-pending-fg); }

/* No capacity to measure against: every booking on the card is still pointing at a
   deleted occurrence. The number says "N people" instead of a bare count. */
.vxb-vendor-bookings .vxb-occ[data-state="unknown"] .vxb-occ-num { color: var(--vxb-muted); font-weight: 500; }

.vxb-vendor-bookings .vxb-occ-flag {
	font-size: 10px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
	padding: 2px 6px; border-radius: 4px;
	color: var(--vxb-st-pending-fg);
	background: var(--vxb-st-pending-bg);
}

/* --- Face pile (summary density) -------------------------------------------- */
.vxb-vendor-bookings .vxb-facepile { display: inline-flex; align-items: center; flex: 0 0 auto; }

.vxb-vendor-bookings .vxb-facepile .vxb-ava,
.vxb-vendor-bookings .vxb-facepile .vxb-ava-img {
	width: 26px; height: 26px; font-size: 10px;
	margin-left: -8px;
	border: 2px solid var(--vxb-bg);
}

.vxb-vendor-bookings .vxb-facepile > :first-child { margin-left: 0; }

.vxb-vendor-bookings .vxb-facepile-more {
	font-size: 11.5px; font-weight: 600; color: var(--vxb-muted); margin-left: 7px;
}

/* --- Roster ----------------------------------------------------------------- */
.vxb-vendor-bookings .vxb-roster { border-top: 1px solid var(--vxb-border); }

/* Inside a card the row is already bounded, so it drops the outer padding it needs
   when it stands alone, and the separator hairlines come from the card. */
.vxb-vendor-bookings .vxb-row-in { padding: 7px 13px 7px 16px; border-top: 0; }
.vxb-vendor-bookings .vxb-row-in + .vxb-row-in { border-top: 1px solid color-mix( in srgb, var(--vxb-border) 55%, transparent ); }

/* A booking with no roster to sit in — every product type that isn't a class. */
.vxb-vendor-bookings .vxb-row-solo {
	background: var(--vxb-bg);
	border: 1px solid var(--vxb-border);
	border-radius: var(--vxb-radius);
	padding: 11px 13px 11px 16px;
	transition: border-color 0.15s ease;
}

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

/* Chips live in their own slot so a row can carry two without them colliding — and
   so the mobile grid has one thing to place instead of an unknown number. */
.vxb-vendor-bookings .vxb-row-chips {
	display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto;
	flex-wrap: wrap; justify-content: flex-end;
}

/* Chip kinds that aren't order statuses. Muted on purpose: they inform, they don't
   alarm — the loud colours stay reserved for a booking that needs a decision. */
.vxb-vendor-bookings .vxb-st-atvenue {
	background: var(--vxb-st-pending-bg); color: var(--vxb-st-pending-fg);
}

.vxb-vendor-bookings .vxb-st-seats,
.vxb-vendor-bookings .vxb-st-manual {
	background: var(--vxb-st-neutral-bg); color: var(--vxb-st-neutral-fg);
}

/* --- Day strip --------------------------------------------------------------
   A week of dates that is ALWAYS present in date view, with arrows to move it.
   It used to be assembled from whatever rows the current page held, so it came
   and went as you paged — worst of all on a busy day, which fills a page by
   itself and left the navigation missing exactly when it was most useful. */
.vxb-vendor-bookings .vxb-daynav {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
}

.vxb-vendor-bookings .vxb-day-nav {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	padding: 0;
	border: 1px solid var(--vxb-border);
	border-radius: var(--vxb-radius);
	background: var(--vxb-bg);
	color: var(--vxb-muted);
	cursor: pointer;
	transition: color 0.15s ease, border-color 0.15s ease;
}

.vxb-vendor-bookings .vxb-day-nav:hover { color: var(--vxb-text); border-color: var(--vxb-muted); }
.vxb-vendor-bookings .vxb-day-nav:focus-visible { outline: 2px solid var(--vxb-accent); outline-offset: 1px; }

/* Quiet text links under the strip. Deliberately NOT buttons in the strip's own row:
   there they appeared and disappeared between the arrows, shifting the chips sideways
   at the moment the vendor was aiming at one. */
.vxb-vendor-bookings .vxb-daynav-links {
	display: flex;
	gap: 16px;
	margin-top: -6px;
	padding-left: 40px;
}

.vxb-vendor-bookings .vxb-daylink {
	padding: 0;
	border: 0;
	background: none;
	color: var(--vxb-accent);
	font-size: 12px;
	font-weight: 600;
	cursor: pointer;
	text-decoration: underline;
	text-underline-offset: 3px;
	text-decoration-thickness: 1px;
	text-decoration-color: color-mix( in srgb, var(--vxb-accent) 45%, transparent );
}

.vxb-vendor-bookings .vxb-daylink:hover { text-decoration-color: currentColor; }
.vxb-vendor-bookings .vxb-daylink:focus-visible { outline: 2px solid var(--vxb-accent); outline-offset: 2px; }

.vxb-vendor-bookings .vxb-daystrip {
	/* basis 0, not auto: with `auto` the seven chips set the strip's minimum width, so on a
	   phone it wrapped onto its own row and pushed the arrows away from it. */
	flex: 1 1 0;
	min-width: 0;
	display: flex;
	gap: 6px;
	overflow-x: auto;
	padding-bottom: 2px;
	scrollbar-width: thin;
	line-height: 1.4; /* see .vxb-slot — the theme's inherited length otherwise applies */
}

.vxb-vendor-bookings .vxb-daystrip .vxb-day { flex: 1 1 0; }

.vxb-vendor-bookings .vxb-day {
	flex: 0 0 auto;
	min-width: 62px;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 1px;
	padding: 7px 9px 6px;
	background: var(--vxb-bg);
	border: 1px solid var(--vxb-border);
	border-radius: var(--vxb-radius);
	cursor: pointer;
	color: var(--vxb-text);
	transition: border-color 0.15s ease, background 0.15s ease;
	/* Same reason as .vxb-session: the kit styles bare <button>s. */
	font-family: inherit;
	font-size: 12px;
	line-height: 1.4;
	letter-spacing: normal;
	text-transform: none;
}

.vxb-vendor-bookings .vxb-day:hover:not(:disabled) { background: var(--vxb-bg-soft); border-color: var(--vxb-muted); }
.vxb-vendor-bookings .vxb-day:focus-visible { outline: 2px solid var(--vxb-accent); outline-offset: 1px; }

/* A day with nothing on it is still worth showing — but it isn't a target. */
.vxb-vendor-bookings .vxb-day:disabled { cursor: default; opacity: 0.55; }

.vxb-vendor-bookings .vxb-day-dow {
	font-size: 9.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
	color: var(--vxb-muted);
}

.vxb-vendor-bookings .vxb-day-num {
	display: inline-flex; align-items: baseline; gap: 4px;
	font-size: 16px; font-weight: 700; line-height: 1.15;
	font-variant-numeric: tabular-nums;
}

/* Only rendered on the first chip and wherever the month turns over, so a window
   spanning two months says so without repeating itself seven times. */
.vxb-vendor-bookings .vxb-day-mon {
	font-size: 9.5px;
	font-style: normal;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--vxb-muted);
}

.vxb-vendor-bookings .vxb-day--on .vxb-day-mon { color: var(--vxb-on-accent); opacity: 0.75; }

.vxb-vendor-bookings .vxb-day-count {
	font-size: 10.5px; font-weight: 600; color: var(--vxb-muted);
	min-height: 14px; font-variant-numeric: tabular-nums;
}

.vxb-vendor-bookings .vxb-day--empty .vxb-day-num { color: var(--vxb-muted); font-weight: 500; }

/* Today is a FACT about the calendar; the selected day is a CHOICE the vendor made.
   The choice gets the loud treatment — otherwise, on the day you are actually in,
   the two are indistinguishable and the strip stops telling you what it's filtering. */
.vxb-vendor-bookings .vxb-day--today {
	border-color: var(--vxb-accent);
}

.vxb-vendor-bookings .vxb-day--today .vxb-day-num { color: var(--vxb-accent); }

.vxb-vendor-bookings .vxb-day--on,
.vxb-vendor-bookings .vxb-day--on:hover:not(:disabled) {
	background: var(--vxb-accent);
	border-color: var(--vxb-accent);
	color: var(--vxb-on-accent);
}

.vxb-vendor-bookings .vxb-day--on .vxb-day-num { color: var(--vxb-on-accent); }

.vxb-vendor-bookings .vxb-day--on .vxb-day-dow,
.vxb-vendor-bookings .vxb-day--on .vxb-day-count { color: var(--vxb-on-accent); opacity: 0.75; }

/* Divider before the bookings on a day that belong to no class. */
.vxb-vendor-bookings .vxb-loose-label {
	margin: 0;
	/* Lines up with the cards: the rail's width plus the slot's column gap, so the
	   divider starts exactly where the things it divides start. */
	padding: 14px 16px 6px calc( var(--vxb-rail-w, 62px) + 12px );
	font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.12em;
	color: var(--vxb-muted);
}

/* --- 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-family: inherit;
	font-size: 13px;
	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); }

/* --- VISUAL HIERARCHY (read before making anything here louder) --------------
   The filter zone had FIVE accent-filled elements at once — the timeframe, the
   view, the density, the active status pill and the day chip — so nothing led
   the eye and the whole bar read as equally urgent. A selected filter is STATE,
   not a primary action, and only one thing on screen should be shouting.

   The ladder now:
     1. accent FILL   — the selected day, and real primary buttons. At most one.
     2. accent TINT   — the active status pill: present, not loud.
     3. raised NEUTRAL — the active segment of a segmented control (this rule).
     4. quiet         — everything unselected.

   A segmented control communicates perfectly well with a raised surface and
   full-strength text; it never needed the accent. */
.vxb-vendor-bookings .vxb-view-btn[aria-pressed="true"] {
	background: var(--vxb-bg-soft);
	color: var(--vxb-text);
	font-weight: 600;
	box-shadow: inset 0 -2px 0 0 var(--vxb-accent);
}
.vxb-vendor-bookings .vxb-view-btn svg { flex: 0 0 auto; }
/* The row itself is context-free: padding and separators come from wherever it sits
   — inside a class card's roster (.vxb-row-in) or standing on its own (.vxb-row-solo)
   — so the two can't fight over the same edge. */
.vxb-vendor-bookings .vxb-row {
	display: flex; align-items: center; gap: 12px;
	cursor: pointer;
	transition: background 0.12s ease, border-color 0.15s ease;
	/* Dense data, so the row sets its own base rather than inheriting the theme's
	   body size — anything inside it that doesn't size itself stays sane. */
	font-size: 14px;
	line-height: 1.45;
}
.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; }
/* Released: dimmed like a cancelled row, because it likewise no longer counts — but NOT struck
   through, because the order is still open and the vendor may still act on it. */
.vxb-vendor-bookings .vxb-row-released { opacity: 0.65; }
.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-released  { background: var(--vxb-st-released-bg);  color: var(--vxb-st-released-fg); cursor: help; }
.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-family: 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;
		/* Needs its own ground now that the list behind it is transparent —
		   otherwise the cards scroll visibly through the header. */
		background: var(--vxb-bg);
	}

	/* The rail is gone here, so the headings line up with the cards' own edge. */
	.vxb-vendor-bookings .vxb-group-head,
	.vxb-vendor-bookings .vxb-month-rule,
	.vxb-vendor-bookings .vxb-group-empty { padding-left: 4px; }

	/* A 62px time column is too much of a phone to spend on two numbers, so the rail
	   folds away and the time rides on the card it belongs to. The class colour keeps
	   doing the containment work, which is what the rail was only helping with. */
	.vxb-vendor-bookings .vxb-slot { grid-template-columns: minmax( 0, 1fr ); gap: 0; padding: 0; }
	.vxb-vendor-bookings .vxb-slot::before { display: none; }
	.vxb-vendor-bookings .vxb-rail { display: none; }
	.vxb-vendor-bookings .vxb-loose-label { padding-left: 4px; }

	.vxb-vendor-bookings .vxb-session-time {
		display: inline;
		font-size: 12px; font-weight: 600; color: var(--vxb-muted);
		font-variant-numeric: tabular-nums; white-space: nowrap;
	}

	/* Class name and time on one line, meta under it, occupancy holding the right edge. */
	.vxb-vendor-bookings .vxb-session { gap: 10px; padding: 10px 12px 10px 15px; }
	.vxb-vendor-bookings .vxb-session-name { flex-wrap: wrap; row-gap: 2px; }
	.vxb-vendor-bookings .vxb-session-meta { white-space: normal; }
	.vxb-vendor-bookings .vxb-occ-track { width: 40px; }

	.vxb-vendor-bookings .vxb-row-in { padding: 8px 12px 8px 15px; }
	.vxb-vendor-bookings .vxb-row-solo { padding: 10px 12px 10px 15px; }

	.vxb-vendor-bookings .vxb-day { min-width: 48px; padding: 6px 7px 5px; }
	.vxb-vendor-bookings .vxb-day-num { font-size: 15px; }

	.vxb-vendor-bookings .vxb-day-nav { width: 28px; height: 28px; }
}

/* 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-family: 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;
	}

	.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;
	}
	/* The chips share one cell, so a row carrying both a status and a "pay at venue"
	   can't stack two elements into the same grid area. */
	.vxb-vendor-bookings .vxb-row-chips { 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 "Jan 1 — Jan 4 · Listing" without merging the two elements. Hung off
	   the WHEN rather than the sub, because most rows no longer carry one — the rail
	   answers "when" now — and a leading dot on a bare email address is just litter. */
	.vxb-vendor-bookings .vxb-row-when::after {
		content: "·";
		margin-left: 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 16px 17px calc( var(--vxb-rail-w, 62px) + 12px );
	color: var(--vxb-muted);
	font-size: 0.875rem;
	line-height: 1.4;
}
