/**
 * Availability (VX) widget styles.
 *
 * Scoped to .vxb-availability so it never collides with the Vendor Bookings
 * widget (which uses .vxb-* / .vxb-panel) when both are on the same page.
 * Status colours and accents are driven by CSS custom properties so the Style
 * tab controls can override them per widget instance.
 *
 * @package VxBookings
 */

.vxb-availability [v-cloak],
.vxb-availability[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-availability 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-availability .ts-btn-2 {
	background: var(--vxb-accent);
	border: 1px solid var(--vxb-accent);
	color: var(--vxb-on-accent);
}

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

.vxb-availability {
	/* DESIGN-FIRST palette (deliberate, since 1.6.0): this widget is a working tool,
	   so it ships a self-contained neutral light UI — like the big booking dashboards —
	   instead of inheriting the theme's shade tokens (which made it look arbitrary on
	   many themes). Typography is still inherited, the ACCENT still follows the theme,
	   and every colour below remains overridable via the Style tab. */
	--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 PALETTE (1.14.0) ────────────────────────────────────────────
	   The whole widget is themed from these few variables. The Style tab's
	   "Palette" + "Status colours" controls set them; the "Style preset" control
	   sets a baseline bundle via a wrapper class (.vxb-preset-*) below; every
	   per-element colour throughout this file DERIVES from them (so month + week
	   share one source of truth). color-mix tints always mix against --vxb-bg, so
	   they stay correct in light AND dark presets. */
	--vxb-radius: 12px;
	/* Shared status palette (month + week). Booked deliberately follows accent. */
	--vxb-available: #1d9e75;
	--vxb-booked: var(--vxb-accent);
	--vxb-pending: #b45309;
	--vxb-blocked: #a32d2d;
	--vxb-today: var(--vxb-accent);
	/* Density (overridden by .vxb-density-compact). */
	--vxb-cell-h: 112px;
	--vxb-cell-pad: 6px;
	--vxb-cell-fz: 13px;
	/* iCal-imported events — distinct accent, shared by month + week. */
	--vxb-imported: #534ab7;
	/* Past days + weekday header (customisable in Style → Advanced). */
	--vxb-past-bg: color-mix( in srgb, var(--vxb-muted) 16%, var(--vxb-bg) );
	--vxb-wd-bg: var(--vxb-bg-soft);
	--vxb-wd-text: var(--vxb-muted);

	/* Week view derives from the SAME master palette (previously a separate set of
	   --vxb-wk-* variables that had to be coloured twice). Now month + week match. */
	--vxb-wk-booking: var(--vxb-accent);
	--vxb-wk-pending: var(--vxb-pending);
	--vxb-wk-block: var(--vxb-blocked);
	--vxb-wk-imported: var(--vxb-imported);
	--vxb-wk-excluded: var(--vxb-muted);
	--vxb-wk-today: var(--vxb-today);
	--vxb-wk-today-text: var(--vxb-on-accent);
	--vxb-wk-today-col: color-mix( in srgb, var(--vxb-accent) 7%, var(--vxb-bg) );
	--vxb-wk-tab-active-bg: var(--vxb-accent);
	--vxb-wk-tab-active-text: var(--vxb-on-accent);
	--vxb-wk-tab-text: var(--vxb-muted);
	--vxb-wk-tabs-bg: var(--vxb-bg-soft);
	--vxb-wk-line: var(--vxb-border);
	--vxb-wk-head-text: var(--vxb-muted);
	--vxb-wk-muted: var(--vxb-muted);

	/* Per-element colours (month grid, panel, popups, action bar, note field) — all DERIVE
	   from the master palette above, and are defined here on the ROOT so EVERY part of the
	   widget can read them (not just the calendar card). This is what stops the day editor /
	   action bar from falling back to hardcoded blue/grey. Tints mix against --vxb-bg so
	   they track light/dark presets. */
	--vxb-av-available-bg: var(--vxb-bg);
	--vxb-av-available-text: var(--vxb-text);
	--vxb-av-booked-bg: color-mix( in srgb, var(--vxb-booked) 14%, var(--vxb-bg) );
	--vxb-av-booked-text: var(--vxb-booked);
	--vxb-av-blocked-bg: color-mix( in srgb, var(--vxb-blocked) 14%, var(--vxb-bg) );
	--vxb-av-blocked-text: var(--vxb-blocked);
	--vxb-av-unavailable-bg: var(--vxb-bg-soft);
	--vxb-av-imported: var(--vxb-imported);
	--vxb-av-accent: var(--vxb-accent);
	--vxb-av-today: var(--vxb-today);
	--vxb-av-selected: var(--vxb-accent);
	--vxb-av-partial: var(--vxb-pending);
	--vxb-av-badge-bg: var(--vxb-accent);
	--vxb-av-badge-text: var(--vxb-on-accent);
	--vxb-av-border: var(--vxb-border);

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

/* ── STYLE PRESETS (1.14.0) ──────────────────────────────────────────────────
   Each preset sets the master palette baseline via a wrapper class written by the
   "Style preset" control (prefix_class => vxb-preset-). Any Palette/Status colour
   the user sets is emitted by Elementor as per-widget CSS that loads afterwards, so
   it overrides the preset. Minimal = the base defaults above (no overrides needed). */
.vxb-preset-soft .vxb-availability {
	--vxb-accent: #1d9e75;
	--vxb-bg: #fbfaf7;
	--vxb-bg-soft: #f3efe8;
	--vxb-text: #33302a;
	--vxb-muted: #8c8579;
	--vxb-border: #ece6db;
	--vxb-available: #639922;
	--vxb-pending: #ba7517;
	--vxb-blocked: #d85a30;
	--vxb-radius: 16px;
}
.vxb-preset-bold .vxb-availability {
	--vxb-accent: #534ab7;
	--vxb-bg: #ffffff;
	--vxb-bg-soft: #f1f0fb;
	--vxb-text: #1c1830;
	--vxb-muted: #6f6a86;
	--vxb-border: #e2e0f0;
	--vxb-available: #3b6d11;
	--vxb-pending: #ba7517;
	--vxb-blocked: #a32d2d;
	--vxb-radius: 18px;
}
.vxb-preset-midnight .vxb-availability {
	--vxb-accent: #8f86e6;
	--vxb-on-accent: #14121f;
	--vxb-bg: #1b1d24;
	--vxb-bg-soft: #23262f;
	--vxb-text: #eef0f5;
	--vxb-muted: #9aa1b1;
	--vxb-border: #313542;
	--vxb-available: #5dcaa5;
	--vxb-pending: #efaf52;
	--vxb-blocked: #e86a6a;
	--vxb-imported: #b69cff; /* lightened so it stays legible on the dark surface */
	--vxb-radius: 12px;
}
/* "Activity rush" — dark, high-energy, lime accent (matches the Sportelo design). */
.vxb-preset-activity-rush .vxb-availability {
	--vxb-accent: #c0fa1e;
	--vxb-on-accent: #121416; /* dark text on the bright lime */
	--vxb-bg: #1c1e22;
	--vxb-bg-soft: #25272d;
	--vxb-text: #fafafa;
	--vxb-muted: #a1a4aa;
	--vxb-border: #30333a;
	--vxb-available: #5dcaa5;
	--vxb-pending: #efaf52;
	--vxb-blocked: #f0616a;
	--vxb-imported: #b794f6;
	--vxb-radius: 12px;
}

/* ── DENSITY (compact shrinks the day cells; comfortable = base defaults) ── */
.vxb-density-compact .vxb-availability {
	--vxb-cell-h: 78px;
	--vxb-cell-pad: 5px;
	--vxb-cell-fz: 12px;
}

/* --- Header --- */
.vxb-av-head h2 {
	margin: 0 0 4px;
}

.vxb-av-head p {
	margin: 0;
	opacity: 0.75;
}

.vxb-av-empty {
	padding: 40px 20px;
	text-align: center;
	opacity: 0.7;
	border: 1px dashed var(--vxb-border);
	border-radius: 12px;
}

/* --- Toolbar / listing selector --- */
.vxb-av-toolbar {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	align-items: flex-end;
}

.vxb-av-listing {
	display: flex;
	flex-direction: column;
	gap: 6px;
	min-width: 220px;
	flex: 1 1 220px;
	max-width: 360px;
}

.vxb-av-listing-text {
	font-size: 12px;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--vxb-muted);
}

.vxb-av-listing-select {
	height: 44px;
	padding: 0 12px;
	border: 1px solid var(--vxb-border);
	border-radius: 8px;
	background: var(--vxb-bg);
	color: var(--vxb-text); /* explicit — avoids white-on-white on dark themes */
	width: 100%;
}

/* --- Polished dropdowns: themed field + a chevron with breathing room from the edge
   (so native OS arrows aren't crammed against the border). Applies to every <select>
   in the widget; Style-tab controls still win where they target a specific field. --- */
.vxb-availability select {
	-webkit-appearance: none;
	-moz-appearance: none;
	appearance: none;
	width: 100%;
	height: 44px;
	padding: 0 40px 0 14px;
	border: 1px solid var(--vxb-border);
	border-radius: 8px;
	background-color: var(--vxb-bg);
	color: var(--vxb-text);
	font: inherit;
	line-height: normal;
	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;
	transition: border-color 0.15s ease;
}

.vxb-availability select:hover {
	border-color: var(--ts-shade-3, #bfc3c8);
}

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

/* --- Calendar card --- */
.vxb-av-calendar {
	border: 1px solid var(--vxb-av-border);
	border-radius: var(--vxb-radius);
	padding: 18px;
	background: var(--vxb-bg);
	color: var(--vxb-text); /* paired with the card surface — theme-independent */
	box-shadow: 0 1px 2px rgba( 16, 24, 40, 0.04 ), 0 8px 24px rgba( 16, 24, 40, 0.05 );
	transition: opacity 0.15s ease;
}

.vxb-av-calendar.vxb-pending {
	opacity: 0.55;
	pointer-events: none;
}

.vxb-av-cal-head {
	display: flex;
	align-items: center;
	/* Wrap instead of squeezing: the action pills have min-widths, so without
	   wrapping all the shrink lands on the view toggle and clips it. */
	flex-wrap: wrap;
	gap: 10px;
	row-gap: 10px;
	margin-bottom: 16px;
}

/* Paging arrows + Today grouped left; the period label centres between the
   clusters (the layout every major booking dashboard uses). */
.vxb-av-nav-cluster {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-shrink: 0;
}

.vxb-av-month-label {
	flex: 1;
	text-align: center;
	font-weight: 700;
	font-size: 18px;
	min-width: 150px;
}

.vxb-availability .vxb-av-nav-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border: 1px solid var(--vxb-av-border);
	border-radius: 50%;
	background: var(--vxb-bg);
	cursor: pointer;
	color: inherit;
	transition: background 0.15s ease, border-color 0.15s ease;
}

.vxb-availability .vxb-av-nav-btn:hover {
	background: var(--vxb-bg-soft);
	border-color: var(--vxb-border);
}

.vxb-av-head-actions {
	margin-left: auto;
	display: flex;
	align-items: center;
	gap: 8px;
}

.vxb-availability .vxb-av-select-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	height: 38px;
	min-width: 120px;
	padding: 0 20px;
	border: 1px solid var(--vxb-av-border);
	border-radius: 8px;
	background: var(--vxb-bg);
	color: inherit;
	font-size: 13px;
	white-space: nowrap;
	cursor: pointer;
	transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.vxb-availability .vxb-av-select-toggle:hover {
	border-color: var(--vxb-av-accent);
}

.vxb-availability .vxb-av-select-toggle.is-active {
	background: var(--vxb-av-accent);
	border-color: var(--vxb-av-accent);
	color: var(--vxb-on-accent);
}

/* "Today" is a navigation control, NOT an action button — so it has its OWN styling
   here and deliberately does not carry .ts-btn (it is not governed by the Buttons
   style section). It's a pill that sits beside the prev/next nav circles, fully
   palette-driven so every preset themes it. */
.vxb-availability .vxb-av-today-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	height: 36px;
	min-height: 36px;
	padding: 0 16px;
	border: 1px solid var(--vxb-av-border);
	border-radius: var(--vxb-radius);
	background: var(--vxb-bg);
	color: var(--vxb-text);
	font: inherit;
	font-size: 13px;
	line-height: 1;
	cursor: pointer;
	transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.vxb-availability .vxb-av-today-btn:hover {
	background: var(--vxb-bg-soft);
	border-color: var(--vxb-av-accent);
	color: var(--vxb-av-accent);
}

/* --- Bulk selection hint --- */
.vxb-av-hintbar {
	margin: 0 0 12px;
	padding: 9px 14px;
	border-radius: 8px;
	background: color-mix( in srgb, var(--vxb-av-accent) 10%, var(--vxb-bg) );
	border: 1px solid color-mix( in srgb, var(--vxb-av-accent) 30%, var(--vxb-bg) );
	font-size: 13px;
}

/* --- Weekday header (a bordered band atop the table grid) --- */
.vxb-av-weekdays {
	display: grid;
	/* minmax(0,1fr) — NOT 1fr: a 1fr track refuses to shrink below its content,
	   so one long no-wrap chip would widen its column and crush the others. */
	grid-template-columns: repeat( 7, minmax( 0, 1fr ) );
	gap: 0;
	margin: 0;
	border: 1px solid var(--vxb-av-border);
	border-bottom: 0;
	border-radius: 10px 10px 0 0;
	background: var(--vxb-wd-bg);
	overflow: hidden;
}

.vxb-av-weekday {
	text-align: center;
	font-size: 12px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--vxb-wd-text);
	padding: 10px 6px;
}

.vxb-av-weekday + .vxb-av-weekday {
	border-left: 1px solid var(--vxb-av-border);
}

/* --- Day grid: a real bordered table (FullCalendar-style), not floating tiles.
   Cells are tall, day numbers sit top-right, bookings render as chips below. --- */
.vxb-av-grid {
	display: grid;
	grid-template-columns: repeat( 7, minmax( 0, 1fr ) ); /* equal columns, always */
	gap: 0;
	border: 1px solid var(--vxb-av-border);
	border-radius: 0 0 10px 10px;
	background: var(--vxb-av-available-bg);
	overflow: hidden;
}

.vxb-availability .vxb-av-day {
	position: relative;
	min-height: var(--vxb-cell-h);
	display: flex;
	flex-direction: column;
	align-items: stretch;
	justify-content: flex-start;
	gap: 3px;
	padding: var(--vxb-cell-pad);
	border: 0;
	border-left: 1px solid var(--vxb-av-border);
	border-top: 1px solid var(--vxb-av-border);
	border-radius: 0;
	background: var(--vxb-av-available-bg);
	color: var(--vxb-av-available-text);
	font: inherit;
	font-size: var(--vxb-cell-fz);
	text-align: left;
	cursor: pointer;
	transition: background 0.12s ease;
	-webkit-appearance: none;
	appearance: none;
}

/* First column / first row: the outer frame already draws those edges. */
.vxb-av-day:nth-child( 7n + 1 ) {
	border-left: 0;
}

.vxb-av-day:nth-child( -n + 7 ) {
	border-top: 0;
}

.vxb-av-day:hover:not( :disabled ) {
	background: var(--vxb-bg-soft);
}

/* Day number: small, muted, top-right (content reads below it). */
.vxb-av-daynum {
	align-self: flex-end;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 24px;
	height: 24px;
	padding: 0 4px;
	border-radius: 50%;
	font-size: 12px;
	font-weight: 500;
	line-height: 1;
	color: var(--vxb-muted);
}

/* Status cell tints: subtle — the CHIPS carry the strong colour now. */
.vxb-availability .vxb-av-day--excluded {
	background: var(--vxb-av-unavailable-bg);
}

.vxb-av-day--excluded .vxb-av-daynum {
	text-decoration: line-through;
}

/* Past days: a muted fill (plus the dimmed number) so they clearly recede from the
   actionable future days — best practice is to de-emphasise, not hide, past dates. */
.vxb-availability .vxb-av-day--past {
	background: var(--vxb-past-bg);
}

.vxb-av-day--past .vxb-av-daynum {
	color: color-mix( in srgb, var(--vxb-muted) 55%, var(--vxb-bg) );
}

/* A past day's CONTENT (bookings / blocks / dots) is dimmed too, so a past date that
   has a reservation still clearly reads as "past", not active. */
.vxb-availability .vxb-av-day--past .vxb-av-chips,
.vxb-availability .vxb-av-day--past .vxb-av-blockbar,
.vxb-availability .vxb-av-day--past .vxb-av-partial-dot {
	opacity: 0.4;
}

/* Out of current month: quiet, clearly secondary. */
.vxb-av-day.vxb-av-out {
	background: var(--vxb-bg-soft);
	cursor: default;
}

.vxb-av-day.vxb-av-out .vxb-av-daynum {
	opacity: 0.45;
}

.vxb-av-day.vxb-av-out .vxb-av-chips,
.vxb-av-day.vxb-av-out .vxb-av-blockbar,
.vxb-av-day.vxb-av-out .vxb-av-partial-dot {
	opacity: 0.4;
}

/* Today: the date NUMBER itself is accent-coloured + bold — no filled circle, so it's
   never mistaken for a "booked" marker (which also uses the accent). */
.vxb-av-day.vxb-av-today .vxb-av-daynum {
	color: var(--vxb-av-today);
	font-weight: 700;
}

/* Selected (single day, editor open): ring + tint */
.vxb-av-day.vxb-av-selected {
	box-shadow: 0 0 0 2px var(--vxb-av-selected) inset;
	background: color-mix( in srgb, var(--vxb-av-selected) 8%, var(--vxb-bg) );
}

/* Bulk range selection */
.vxb-av-day.vxb-av-inrange {
	background: color-mix( in srgb, var(--vxb-av-accent) 12%, var(--vxb-bg) );
}

.vxb-av-day.vxb-av-sel-start,
.vxb-av-day.vxb-av-sel-end {
	background: color-mix( in srgb, var(--vxb-av-accent) 22%, var(--vxb-bg) );
	box-shadow: 0 0 0 2px var(--vxb-av-accent) inset;
}

/* --- Booking chips (time + customer), the heart of the redesign --- */
.vxb-av-chips {
	display: flex;
	flex-direction: column;
	gap: 3px;
	width: 100%;
	min-width: 0;
	overflow: hidden;
}

.vxb-av-chip {
	display: flex;
	align-items: center;
	gap: 5px;
	min-width: 0;
	padding: 3px 7px;
	border-radius: 6px;
	background: var(--vxb-av-booked-bg);
	color: var(--vxb-av-booked-text);
	font-size: 11px;
	line-height: 1.35;
}

/* Leading status dot in the chip's own (strong) colour — no markup needed. */
.vxb-av-chip::before {
	content: "";
	flex: 0 0 auto;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: currentColor;
}

.vxb-av-chip b {
	font-weight: 600;
	white-space: nowrap;
}

.vxb-av-chip-name {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Pending: soft amber tint derived from the (strong) partial colour. */
.vxb-av-chip.is-pending {
	background: color-mix( in srgb, var(--vxb-av-partial) 16%, var(--vxb-bg) );
	color: var(--vxb-av-partial);
}

.vxb-av-more {
	font-size: 11px;
	font-weight: 500;
	color: var(--vxb-muted);
	padding-left: 2px;
}

/* Mobile-only compact day summary (the rich chips above don't fit narrow phone cells).
   Hidden on desktop; the mobile media query below shows it and hides the desktop chips. */
.vxb-av-mob {
	display: none;
	flex-direction: column;
	gap: 3px;
	width: 100%;
	min-width: 0;
}

.vxb-av-mob-lead {
	display: flex;
	align-items: baseline;
	gap: 4px;
	max-width: 100%;
	padding: 1px 5px;
	border-radius: 5px;
	font-size: 10px;
	line-height: 1.3;
	background: var(--vxb-av-booked-bg);
	color: var(--vxb-av-booked-text);
	overflow: hidden;
}

.vxb-av-mob-lead.is-pending {
	background: color-mix( in srgb, var(--vxb-av-partial) 16%, var(--vxb-bg) );
	color: var(--vxb-av-partial);
}

.vxb-av-mob-lead b {
	font-weight: 600;
	white-space: nowrap;
}

.vxb-av-mob-name {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.vxb-av-mob-dots {
	display: flex;
	align-items: center;
	gap: 3px;
	padding-left: 1px;
}

.vxb-av-mob-dot {
	width: 5px;
	height: 5px;
	border-radius: 50%;
	background: var(--vxb-av-booked-text);
}

.vxb-av-mob-dot.is-pending {
	background: var(--vxb-av-partial);
}

.vxb-av-mob-more {
	font-size: 9px;
	color: var(--vxb-muted);
}

/* Phones: swap the rich month chips for the compact next-upcoming + dots summary and
   shorten the cells (Google / Apple month pattern). Full details are one tap away. */
@media ( max-width: 600px ) {
	.vxb-availability .vxb-av-chips,
	.vxb-availability .vxb-av-more { display: none; }
	.vxb-availability .vxb-av-mob { display: flex; }
	.vxb-availability .vxb-av-day { min-height: 66px; }
	.vxb-availability .vxb-av-daynum { min-width: 20px; height: 20px; font-size: 11px; }
	/* Lanes stay (the only place multi-day bookings appear on mobile) but collapse to
	   thin colour strips without labels so the compact cell isn't overloaded. */
	.vxb-availability .vxb-av-lane { height: 5px; }
	.vxb-availability .vxb-av-lanes { gap: 3px; }
	.vxb-availability .vxb-av-lane .vxb-av-blockbar { height: 5px; padding: 0; border-radius: 3px; }
	.vxb-availability .vxb-av-lane .vxb-av-blockbar-label { display: none; }
	/* Reclaim width on phones: trim the calendar card's own padding (keep a little so the
	   grid doesn't touch the rounded border). Other paddings are left as-is. */
	.vxb-availability .vxb-av-calendar { padding: 8px; }
}

.vxb-av-lock {
	position: absolute;
	right: 6px;
	bottom: 6px;
	display: inline-flex;
	opacity: 0.7;
	color: var(--vxb-av-blocked-text);
}

/* Blocked / imported ranges: a labelled event bar (chip height) that bleeds across
   cell borders on connecting sides, so consecutive days read as ONE spanning event
   with the label riding its first segment — the pattern of the big dashboards. */
.vxb-av-blockbar {
	position: relative;
	display: flex;
	align-items: center;
	left: -7px;
	width: calc( 100% + 14px );
	height: 20px;
	margin-top: 1px;
	padding: 0 7px;
	background: var(--vxb-av-block-bar, var(--vxb-av-blocked-bg) );
	color: var(--vxb-av-blocked-text, #fff);
	box-sizing: border-box;
	overflow: hidden;
	z-index: 1;
}

.vxb-av-blockbar.is-imported {
	background: color-mix( in srgb, var(--vxb-av-imported) 16%, var(--vxb-bg) );
	color: var(--vxb-av-imported);
}

/* Multi-day booking bar: SOLID accent (matches the booking chips) so a date-range
   reservation reads as one booking, distinct from the tinted block / imported bars. */
.vxb-av-blockbar.is-booking {
	background: var(--vxb-booked);
	color: var(--vxb-on-accent);
}

.vxb-av-blockbar.is-booking .vxb-av-blockbar-label {
	color: var(--vxb-on-accent);
}

/* Lane stack: one row per overlapping booking / block / iCal event, so they never
   cut each other. Empty lanes are spacers that keep bars aligned across the week. */
.vxb-av-lanes {
	display: flex;
	flex-direction: column;
	gap: 2px;
	margin-top: 1px;
}

.vxb-av-lane {
	position: relative;
	height: 20px;
}

.vxb-av-lane .vxb-av-blockbar {
	margin-top: 0;
}

.vxb-av-blockbar-label {
	font-size: 10px;
	font-weight: 600;
	line-height: 1;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.vxb-av-blockbar.is-start {
	left: 0;
	width: calc( 100% + 7px );
	border-top-left-radius: 6px;
	border-bottom-left-radius: 6px;
}

.vxb-av-blockbar.is-end {
	width: calc( 100% + 7px );
	border-top-right-radius: 6px;
	border-bottom-right-radius: 6px;
}

.vxb-av-blockbar.is-start.is-end {
	left: 0;
	width: 100%;
}

/* Partly-blocked (some time slots blocked) marker */
.vxb-av-partial-dot {
	position: absolute;
	top: 9px;
	left: 8px;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--vxb-av-partial);
}

/* --- Legend: coloured dots, like the reference dashboards --- */
.vxb-av-legend {
	display: flex;
	flex-wrap: wrap;
	gap: 14px;
	margin-top: 14px;
	font-size: 12px;
	color: var(--vxb-muted);
}

.vxb-av-legend-item {
	display: inline-flex;
	align-items: center;
	gap: 6px;
}

/* Legend markers mirror the ACTUAL marks on the calendar so the key reads at a
   glance: an outline cell (available = open, nothing on it), a chip with a leading
   dot (booked / pending bookings), a small dot (partly-blocked day), a tinted bar
   (blocked), and a greyed, struck-through cell (unavailable / closed). */
.vxb-av-lg {
	display: inline-block;
	flex-shrink: 0;
}

/* Available — an empty open day */
.vxb-lg-available {
	width: 14px;
	height: 14px;
	border-radius: 3px;
	border: 1px solid var(--vxb-border);
	background: var(--vxb-bg);
}

/* Booked / Pending — a booking chip with a leading status dot */
.vxb-lg-booked,
.vxb-lg-pending {
	position: relative;
	width: 24px;
	height: 13px;
	border-radius: 4px;
}
.vxb-lg-booked { background: color-mix( in srgb, var(--vxb-accent) 16%, var(--vxb-bg) ); }
.vxb-lg-pending { background: color-mix( in srgb, var(--vxb-pending) 18%, var(--vxb-bg) ); }
.vxb-lg-booked::before,
.vxb-lg-pending::before {
	content: "";
	position: absolute;
	left: 4px;
	top: 50%;
	transform: translateY( -50% );
	width: 5px;
	height: 5px;
	border-radius: 50%;
}
.vxb-lg-booked::before { background: var(--vxb-accent); }
.vxb-lg-pending::before { background: var(--vxb-pending); }

/* Partly blocked — the small corner dot shown when only some time-slots are blocked */
.vxb-lg-partial {
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: var(--vxb-pending);
}

/* Blocked — the labelled block bar */
.vxb-lg-blocked {
	width: 24px;
	height: 13px;
	border-radius: 4px;
	background: color-mix( in srgb, var(--vxb-blocked) 16%, var(--vxb-bg) );
	border-left: 3px solid var(--vxb-blocked);
}

/* Unavailable — a closed (greyed, struck-through) day */
.vxb-lg-unavailable {
	width: 14px;
	height: 14px;
	border-radius: 3px;
	background: var(--vxb-bg-soft);
	border: 1px solid var(--vxb-border);
	background-image: linear-gradient( 45deg, transparent 43%, var(--vxb-muted) 43%, var(--vxb-muted) 57%, transparent 57% );
}

/* --- Floating bulk action bar --- */
.vxb-av-actionbar {
	position: fixed;
	left: 50%;
	bottom: 24px;
	transform: translateX( -50% );
	z-index: 100000;
	display: flex;
	flex-direction: column;
	gap: 8px;
	/* Adaptive: grows to fit its content (long button labels in any language) up to a
	   sensible cap, instead of a fixed width that clipped longer text. */
	width: max-content;
	min-width: 320px;
	max-width: min( 92vw, 640px );
	padding: 16px;
	border-radius: var(--vxb-radius);
	background: var(--vxb-bg);
	color: var(--vxb-text);
	box-shadow: 0 12px 34px rgba( 0, 0, 0, 0.22 );
}

.vxb-av-ab-summary {
	font-weight: 600;
}

/* Shared "Note" title above the comment field (day editor + action bar). */
.vxb-av-note-title {
	display: block;
	font-size: 11px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: color-mix( in srgb, var(--vxb-muted) 80%, var(--vxb-bg) );
}

/* Tighten the title→field gap inside the day editor (panel uses a 10px gap). */
.vxb-av-panel-body .vxb-av-note-title {
	margin-bottom: -4px;
}

.vxb-av-ab-label {
	margin-top: 2px;
}

.vxb-av-ab-note {
	width: 100%;
}

.vxb-av-ab-actions {
	display: flex;
	gap: 8px;
	margin-top: 4px;
	flex-wrap: wrap;
}

.vxb-availability .vxb-av-ab-btn {
	flex: 1 1 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	height: 40px;
	padding: 0 16px;
	border: 1px solid var(--vxb-border);
	border-radius: var(--vxb-radius);
	background: var(--vxb-bg);
	color: inherit;
	font-size: 13px;
	white-space: nowrap;
	cursor: pointer;
	transition: background 0.12s ease, border-color 0.12s ease, opacity 0.12s ease;
}

.vxb-availability .vxb-av-ab-btn:disabled {
	opacity: 0.5;
	cursor: not-allowed;
}

.vxb-availability .vxb-av-ab-clear {
	color: var(--vxb-muted);
}

.vxb-availability .vxb-av-ab-unblock {
	color: var(--vxb-blocked);
	border-color: color-mix( in srgb, var(--vxb-blocked) 45%, var(--vxb-bg) );
}

.vxb-availability .vxb-av-ab-block {
	background: var(--vxb-accent);
	border-color: var(--vxb-accent);
	color: var(--vxb-on-accent);
}

/* Text input shared by the day editor + action bar (note / reason). */
.vxb-av-input {
	height: 40px;
	padding: 0 12px;
	border: 1px solid var(--vxb-av-border, #e8eaed );
	border-radius: 8px;
	background: var(--vxb-bg-soft);
	color: var(--vxb-text);
	width: 100%;
	font-size: 14px;
}

.vxb-av-input:focus {
	outline: none;
	border-color: var(--vxb-av-accent, #2563eb );
}

/* Voxel's theme styles bare `input[type=...]` (specificity 0,1,1) and commonly sets
   `-webkit-text-fill-color` on inputs — both outrank our single-class `.vxb-av-input`
   (0,1,0), so on dark presets the typed text kept Voxel's dark colour and became
   invisible (a <select>/<textarea> weren't matched by `input[type=…]`, which is why
   only the text/number/date inputs vanished). Re-assert the palette colours with
   element+class weight, plus `-webkit-text-fill-color` (which overrides `color` on
   WebKit regardless of specificity), so every field is legible on every preset. */
.vxb-availability input.vxb-av-input,
.vxb-availability select.vxb-av-input,
.vxb-availability textarea.vxb-av-input {
	color: var(--vxb-text);
	-webkit-text-fill-color: var(--vxb-text);
	background-color: var(--vxb-bg-soft);
	/* Full `border` shorthand (not just border-color): Voxel's `.ts-form input { border: none }`
	   (0,1,1) zeroes the width/style, so declaring only the colour left the border invisible.
	   This selector is (0,2,1) so it wins outright. The palette `--vxb-border` is intentionally
	   faint (≈1.1:1 vs the field), so the visible border is derived from the muted colour
	   (measured ≈2.0:1 on light presets, ≈3.3:1 on dark). */
	border: 1px solid color-mix( in srgb, var(--vxb-muted) 65%, var(--vxb-bg-soft) );
	border-radius: 8px;
	opacity: 1;
}

/* Box metrics for the single-line fields — also (0,2,1) so Voxel's `.ts-form input`
   (height/padding/line-height) can't override them. Excludes <textarea>, which keeps
   its own auto height. */
.vxb-availability input.vxb-av-input,
.vxb-availability select.vxb-av-input {
	height: 40px;
	padding: 0 12px;
	line-height: normal;
}

.vxb-availability .vxb-av-input::placeholder {
	color: var(--vxb-muted);
	-webkit-text-fill-color: var(--vxb-muted);
	opacity: 1;
}

.vxb-availability .vxb-av-input:disabled {
	opacity: 0.55;
	cursor: not-allowed;
}

/* The date fields use the browser's native <input type="date"> picker. On dark presets,
   ask the browser to render its native calendar in dark mode (Chrome/Edge/Safari), and tint
   the picker glyph so it stays visible. color-scheme also darkens the popup itself. */
.vxb-preset-midnight .vxb-availability input.vxb-av-input[type="date"],
.vxb-preset-activity-rush .vxb-availability input.vxb-av-input[type="date"] {
	color-scheme: dark;
}

.vxb-availability input.vxb-av-input[type="date"]::-webkit-calendar-picker-indicator {
	filter: invert( 0.5 ) opacity( 0.85 );
}

/* --- Toast --- */
.vxb-av-toast {
	position: fixed;
	left: 50%;
	bottom: 28px;
	transform: translateX( -50% );
	z-index: 100001;
	padding: 12px 20px;
	border-radius: 10px;
	background: var(--vxb-text);
	color: var(--vxb-on-accent);
	box-shadow: 0 8px 28px rgba( 0, 0, 0, 0.25 );
	font-size: 14px;
	max-width: calc( 100vw - 32px );
}

.vxb-av-toast-error {
	background: #9b1c1c;
}

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

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

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

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

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

/* --- Booking popup (opens above the day editor) --- */
.vxb-av-bp-overlay {
	position: fixed;
	inset: 0;
	background: rgba( 0, 0, 0, 0.4 );
	z-index: 100002;
}

.vxb-av-bp {
	position: fixed;
	top: 0;
	right: 0;
	width: 420px;
	max-width: 100vw;
	height: 100%;
	background: var(--vxb-bg);
	box-shadow: -8px 0 28px rgba( 0, 0, 0, 0.18 );
	z-index: 100003;
	display: flex;
	flex-direction: column;
	transform: translateX( 100% );
	transition: transform 0.25s ease;
}

.vxb-av-bp.vxb-av-bp-open {
	transform: translateX( 0 );
}

.vxb-av-bp-body {
	padding: 18px 20px;
	overflow-y: auto;
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.vxb-av-bp-row {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.vxb-av-bp-total {
	font-weight: 600;
}

.vxb-av-bp-comments span:last-child {
	white-space: pre-wrap;
	word-break: break-word;
}

.vxb-av-bp-foot {
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 16px 20px;
	border-top: 1px solid var(--vxb-border);
}

.vxb-av-bp-error {
	margin: 0;
	color: var(--vxb-blocked);
	font-size: 13px;
}

@media ( max-width: 600px ) {
	.vxb-av-bp {
		width: 100%;
		top: auto;
		bottom: 0;
		height: auto;
		max-height: 90vh;
		transform: translateY( 100% );
		border-radius: 16px 16px 0 0;
	}
	.vxb-av-bp.vxb-av-bp-open {
		transform: translateY( 0 );
	}
}

/* --- Add-booking panel (direct booking) --- */
.vxb-av-ab {
	position: fixed;
	top: 0;
	right: 0;
	width: 460px;
	max-width: 100vw;
	height: 100%;
	background: var(--vxb-bg);
	box-shadow: -8px 0 28px rgba( 0, 0, 0, 0.18 );
	z-index: 100003;
	display: flex;
	flex-direction: column;
	transform: translateX( 100% );
	transition: transform 0.25s ease;
}

.vxb-av-ab.vxb-av-bp-open {
	transform: translateX( 0 );
}

.vxb-av-ab-body {
	padding: 18px 20px;
	overflow-y: auto;
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: 14px;
}

.vxb-av-ab-row {
	display: flex;
	gap: 12px;
}

.vxb-av-ab-field {
	flex: 1 1 0;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 5px;
}

/* `flex: 1 1 0` above means "share the width evenly", which is right for the fields
   INSIDE a .vxb-av-ab-row. A field placed directly in the body is in a COLUMN flex
   instead, where the same rule reads as "grow vertically" — so a lone field (the class
   picker, the single-day date) stretched to eat every spare pixel and pushed the rest of
   the form to the bottom of the panel. Direct children size to their content; only the
   fields inside a row share space. */
.vxb-av-ab-body > .vxb-av-ab-field {
	flex: 0 0 auto;
}

.vxb-av-ab-field label {
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: color-mix( in srgb, var(--vxb-muted) 80%, var(--vxb-bg) );
	font-weight: 600;
}

.vxb-av-ab-field-narrow {
	flex: 0 0 110px;
}

.vxb-av-ab-total {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 12px 14px;
	border-radius: var(--vxb-radius, 8px);
	background: color-mix( in srgb, var(--vxb-accent) 8%, var(--vxb-bg) );
	border: 1px solid var(--vxb-border);
}

.vxb-av-ab-total strong {
	font-size: 17px;
	font-weight: 700;
}

.vxb-av-ab-textarea {
	resize: vertical;
	min-height: 54px;
}

.vxb-av-ab-warn {
	margin: 0;
	padding: 10px 12px;
	border-radius: var(--vxb-radius, 8px);
	background: color-mix( in srgb, var(--vxb-blocked) 12%, var(--vxb-bg) );
	border: 1px solid color-mix( in srgb, var(--vxb-blocked) 35%, var(--vxb-bg) );
	color: color-mix( in srgb, var(--vxb-blocked) 85%, var(--vxb-text) );
	font-size: 13px;
	line-height: 1.4;
}

.vxb-av-ab-foot {
	display: flex;
	gap: 10px;
	padding: 16px 20px;
	border-top: 1px solid var(--vxb-border);
}

.vxb-av-ab-foot .ts-btn {
	flex: 1 1 0;
}

/* Native Voxel .ts-btn resets cursor to default; restore the pointer inside the
   add-booking panel (it is not covered by the .vxb-av-bp / .vxb-av-panel rules). */
.vxb-av-ab .ts-btn {
	cursor: pointer;
}

.vxb-av-ab .ts-btn:disabled {
	cursor: not-allowed;
	opacity: 0.6;
}

@media ( max-width: 600px ) {
	.vxb-av-ab {
		width: 100%;
		top: auto;
		bottom: 0;
		height: auto;
		max-height: 92vh;
		transform: translateY( 100% );
		border-radius: 16px 16px 0 0;
	}
	.vxb-av-ab.vxb-av-bp-open {
		transform: translateY( 0 );
	}
	.vxb-av-ab-row {
		flex-wrap: wrap;
	}
}

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

.vxb-av-panel-head strong {
	font-size: 18px;
	font-weight: 600;
	color: var(--vxb-text);
}

/* The booking popup's head carries the customer name + status pill instead of the
   word "Booking" — you already know it's a booking, you tapped one. Not inside a
   media query: the head is like this at every width, and it is what lets the body
   drop its CUSTOMER and STATUS rows. */
.vxb-av-bp-head {
	align-items: flex-start;
}

.vxb-av-bp-head-text {
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 6px;
}

.vxb-av-bp-head-text strong {
	font-size: 17px;
	font-weight: 600;
	color: var(--vxb-text);
	overflow-wrap: anywhere;
}

.vxb-availability .vxb-av-panel-close {
	border: 0;
	background: transparent;
	font-size: 24px;
	line-height: 1;
	cursor: pointer;
	color: var(--vxb-muted);
}

.vxb-av-panel-body {
	padding: 18px 20px;
	overflow-y: auto;
	display: flex;
	flex-direction: column;
	gap: 10px;
}

/* Section labels are the LEAST prominent tier: small, uppercase, wide-tracked and
   strongly muted, so the eye lands on the customer name / day title first. */
.vxb-av-panel-label {
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: color-mix( in srgb, var(--vxb-muted) 80%, var(--vxb-bg) );
	font-weight: 600;
}

.vxb-av-avail-label,
.vxb-av-slots-label {
	margin-top: 8px;
	padding-top: 14px;
	border-top: 1px solid var(--vxb-border);
}

/* Reservation items */
.vxb-av-res-list {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

/* Two lines, four columns — the same shape as the Vendor Bookings / My Bookings rows,
   so every list of bookings in the plugin reads the same way:

       [ava] Manos Admin ....................... 15 €
             18:02 – 19:02 · Yoga Flow   [pill]   ›

   It was a flex row wrapping a column of name / meta / total, with nothing truncating.
   The price took a line of its own, and the meta (which used to be the full summary,
   date and all) wrapped across three — so a card said little and said it in five lines. */
.vxb-availability .vxb-av-res {
	display: grid;
	grid-template-columns: auto minmax( 0, 1fr ) auto auto;
	grid-template-areas:
		"ava name total open"
		"ava meta status open";
	column-gap: 10px;
	row-gap: 2px;
	align-items: center;
	padding: 10px 12px;
	border-radius: 10px;
	background: var(--vxb-bg-soft);
}

.vxb-av-res-avatar {
	grid-area: ava;
	width: 34px;
	height: 34px;
	border-radius: 50%;
	object-fit: cover;
	flex-shrink: 0;
}

/* Dissolve the wrapper so its children are placed directly on the card's grid. */
.vxb-av-res-text {
	display: contents;
}

/* Primary (focal) line: the customer name. */
.vxb-av-res-name {
	grid-area: name;
	min-width: 0;
	font-size: 15px;
	font-weight: 600;
	color: var(--vxb-text);
	line-height: 1.25;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Secondary line: time · class — clearly muted so it doesn't compete with the name.
   One line, always: a translated status pill sits beside it and takes what it needs,
   so this is the element that has to give way. */
.vxb-av-res-meta {
	grid-area: meta;
	min-width: 0;
	font-size: 12.5px;
	color: var(--vxb-muted);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.vxb-av-res-total {
	grid-area: total;
	justify-self: end;
	font-size: 12.5px;
	font-weight: 500;
	color: var(--vxb-muted);
	white-space: nowrap;
}

.vxb-availability .vxb-av-res .order-status {
	grid-area: status;
	justify-self: end;
}

/* A reservation row that opens the booking popup (rendered as a <button>). */
.vxb-availability .vxb-av-res-link {
	width: 100%;
	text-align: left;
	font: inherit;
	border: 0;
	text-decoration: none;
	color: var(--vxb-text);
	cursor: pointer;
	transition: background-color 0.15s ease, transform 0.05s ease;
}

.vxb-availability .vxb-av-res-link:hover {
	background: var(--vxb-bg-soft);
}

.vxb-availability .vxb-av-res-link:active {
	transform: translateY(1px);
}

.vxb-av-res-open {
	grid-area: open;
	align-self: center;
	display: inline-flex;
	align-items: center;
	flex-shrink: 0;
	opacity: 0.4;
}

.vxb-availability .vxb-av-res-link:hover .vxb-av-res-open {
	opacity: 0.8;
}

.vxb-av-res-empty {
	margin: 0;
	opacity: 0.6;
	font-size: 14px;
}

.vxb-av-view-res {
	align-self: flex-start;
	margin-top: 2px;
}

.vxb-av-note {
	margin: 0;
	font-size: 13px;
	opacity: 0.7;
}

.vxb-av-blocked-state {
	margin: 0;
	font-weight: 600;
	color: var(--vxb-blocked);
}

/* Imported (synced) days are blocked, but the note is informational, not an error. */
.vxb-av-imported-state {
	color: var(--vxb-text);
}

.vxb-av-reason {
	margin: 0;
	font-size: 13px;
	opacity: 0.85;
}

.vxb-av-reason-label {
	font-size: 11px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	opacity: 0.7;
	margin-right: 4px;
}

.vxb-av-panel .ts-btn {
	cursor: pointer;
	align-self: flex-start;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	height: 40px;
	min-height: 40px;
	padding: 0 20px;
}

.vxb-av-panel .ts-btn:disabled {
	opacity: 0.5;
	cursor: not-allowed;
}

/* Booking-popup action buttons live in .vxb-av-bp (not .vxb-av-panel), and a native
   <button> defaults to an arrow cursor — restore the pointer + not-allowed states. */
.vxb-av-bp .ts-btn {
	cursor: pointer;
}

.vxb-av-bp .ts-btn:disabled {
	cursor: not-allowed;
}

/* Past-date actions: visually identical to :disabled, but the button stays interactive
   so its explanatory title tooltip shows on hover (native tooltips on truly disabled
   buttons are unreliable across browsers). Click handlers no-op on past dates. */
.vxb-av-panel .vxb-av-locked {
	opacity: 0.5;
	cursor: not-allowed;
}

/* When two unblock buttons share the row, let them sit comfortably. */
.vxb-av-panel .vxb-av-actions .ts-btn {
	align-self: auto;
}

.vxb-availability .vxb-av-danger {
	color: var(--vxb-blocked);
}

/* Time-slot chips */
.vxb-av-slots {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.vxb-availability .vxb-av-slot {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	padding: 7px 12px;
	border: 1px solid var(--vxb-av-border, #e8eaed );
	border-radius: 8px;
	background: var(--vxb-bg);
	color: var(--vxb-text);
	font-size: 13px;
	cursor: pointer;
	transition: border-color 0.12s ease, background 0.12s ease;
}

.vxb-av-slot:hover:not( :disabled ) {
	border-color: var(--vxb-accent);
}

.vxb-av-slot.is-blocked {
	background: color-mix( in srgb, var(--vxb-blocked) 16%, var(--vxb-bg) );
	color: var(--vxb-blocked);
	border-color: transparent;
}

.vxb-av-slot.is-booked {
	background: color-mix( in srgb, var(--vxb-accent) 16%, var(--vxb-bg) );
	color: var(--vxb-accent);
	border-color: transparent;
	cursor: not-allowed;
	opacity: 0.9;
}

.vxb-av-slot.is-imported {
	background: var(--vxb-bg-soft);
	color: var(--vxb-muted);
	border-color: transparent;
	cursor: not-allowed;
}

.vxb-av-slot:disabled {
	cursor: not-allowed;
}

.vxb-av-slot-tag {
	font-size: 10px;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	opacity: 0.7;
}

/* --- Open-hours "open clock" time-range blocker --- */
.vxb-av-oh-blocks {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin-bottom: 10px;
}

/* Palette-derived so it stays readable on every preset (the old hardcoded
   #fdecec/#9b1c1c pale-red left the text unreadable on the dark presets). Neutral
   surface + a red accent bar keeps the "blocked" meaning without a low-contrast tint. */
.vxb-av-oh-block {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	padding: 7px 12px;
	border-radius: 8px;
	background: var(--vxb-bg-soft);
	border-left: 3px solid var(--vxb-blocked);
	color: var(--vxb-text);
	font-size: 13px;
}

.vxb-av-oh-block-time {
	font-weight: 600;
}

.vxb-availability .vxb-av-oh-unblock {
	background: transparent;
	border: 0;
	padding: 0;
	font-size: 12px;
	font-weight: 600;
	cursor: pointer;
	color: var(--vxb-blocked);
	text-decoration: underline;
}

.vxb-availability .vxb-av-oh-unblock:disabled {
	cursor: not-allowed;
	opacity: 0.5;
}

.vxb-av-oh-range {
	display: flex;
	gap: 10px;
	margin-bottom: 10px;
}

.vxb-av-oh-field {
	display: flex;
	flex-direction: column;
	gap: 4px;
	flex: 1;
	min-width: 0;
}

.vxb-av-oh-field-label {
	font-size: 12px;
	opacity: 0.7;
}

.vxb-av-oh-select {
	width: 100%;
}

/* --- Responsive: panel + action bar adapt to small screens --- */
@media ( max-width: 600px ) {
	.vxb-av-panel {
		top: auto;
		bottom: 0;
		right: 0;
		left: 0;
		width: 100%;
		height: auto;
		max-height: 85vh;
		border-radius: 18px 18px 0 0;
		transform: translateY( 100% );
		box-shadow: 0 -8px 28px rgba( 0, 0, 0, 0.18 );
	}

	.vxb-av-panel.vxb-av-panel-open {
		transform: translateY( 0 );
	}

	.vxb-av-actionbar {
		left: 12px;
		right: 12px;
		transform: none;
		flex-direction: column;
		align-items: stretch;
		gap: 10px;
	}

	.vxb-av-ab-actions {
		justify-content: space-between;
	}

	.vxb-av-cal-head {
		flex-wrap: wrap;
	}

	.vxb-av-head-actions {
		width: 100%;
		margin-left: 0;
		gap: 8px;
	}

	/* Select-dates stretches on mobile; the nav cluster (arrows + Today) stays compact. */
	.vxb-av-head-actions .vxb-av-select-toggle {
		flex: 1 1 0;
		justify-content: center;
		text-align: center;
		height: 42px;
	}

	.vxb-av-month-label {
		font-size: 16px;
	}

	/* Tighter table cells; chips shrink with them (names ellipsize). */
	.vxb-av-day {
		min-height: 76px;
		font-size: 12px;
		padding: 4px;
	}

	.vxb-av-chip {
		padding: 2px 5px;
		font-size: 10px;
	}

	.vxb-av-daynum {
		min-width: 20px;
		height: 20px;
		font-size: 11px;
	}
}

/* --- Week view (hour-by-hour timeline) ---
   Rendered inside .vxb-av-calendar, so the --vxb-av-* theme bridge is in scope.
   Every colour/size sits on a --vxb-wk-* custom property (with a safe fallback)
   so the "Week view" Elementor section can restyle each part. Span positions are
   calc( --vxb-wk-hour-h × hours ) set inline by the JS. */
.vxb-av-week {
	border: 1px solid var(--vxb-av-border, #e8eaed);
	border-radius: 12px;
	overflow: hidden;
}

.vxb-av-wk-head,
.vxb-av-wk-allday,
.vxb-av-wk-body {
	display: grid;
	grid-template-columns: var(--vxb-wk-gutter-w, 56px) repeat(7, minmax(0, 1fr));
}

.vxb-av-wk-head {
	border-bottom: 1px solid var(--vxb-av-border, #e8eaed);
}

.vxb-availability .vxb-av-wk-dayhead {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 3px;
	padding: 8px 4px;
	background: transparent;
	border: 0;
	border-left: 1px solid var(--vxb-av-border, #e8eaed);
	cursor: pointer;
	/* `inherit` (not a shade token): the calendar card's own text colour cascades
	   here, so the date number can never go dark-on-dark on themes that map the
	   shade tokens unexpectedly (the month label works the same way). */
	color: var(--vxb-wk-head-text, inherit);
	font: inherit;
}

.vxb-availability .vxb-av-wk-dayhead:hover {
	background: color-mix( in srgb, currentColor 5%, transparent );
}

.vxb-av-wk-wd {
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--vxb-wk-muted, var(--vxb-muted, #6b7280));
}

.vxb-av-wk-num {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 28px;
	height: 28px;
	padding: 0 4px;
	border-radius: 50%;
	font-weight: 600;
	font-size: 15px;
}

/* Today: a filled accent circle around the date (the big-platform pattern). */
.vxb-av-wk-dayhead.is-today .vxb-av-wk-num {
	background: var(--vxb-wk-today, var(--vxb-av-accent, #2271b1));
	color: var(--vxb-wk-today-text, #fff);
}

.vxb-av-wk-dayhead.is-past {
	opacity: 0.55;
}

/* All-day row: a 7-column lane grid. Date-range blocks span multiple columns as ONE
   bar (placed via inline grid-column/grid-row); overlapping all-day items stack in lanes. */
.vxb-av-wk-allday {
	border-bottom: 1px solid var(--vxb-av-border, #e8eaed);
	row-gap: 3px;
	padding: 4px 0;
	align-items: stretch;
}

.vxb-av-wk-alldaylabel {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	padding: 4px 6px;
	font-size: 11px;
	color: var(--vxb-wk-muted, var(--vxb-muted, #6b7280));
}

.vxb-av-wk-alldaycol {
	display: flex;
	flex-direction: column;
	gap: 3px;
	padding: 4px;
	border-left: 1px solid var(--vxb-av-border, #e8eaed);
	min-width: 0;
}

.vxb-availability .vxb-av-wk-chip {
	border: 0;
	cursor: pointer;
	border-radius: var(--vxb-wk-span-radius, 6px);
	margin: 0 4px;
	padding: 3px 8px;
	font-size: 11px;
	font-weight: 500;
	line-height: 1.3;
	text-align: left;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	font-family: inherit;
	box-sizing: border-box;
}

.vxb-av-wk-chip.is-booking { background: color-mix( in srgb, var(--vxb-wk-booking, #185fa5) 15%, var(--vxb-bg) ); color: var(--vxb-wk-booking, #185fa5); }
.vxb-av-wk-chip.is-block { background: color-mix( in srgb, var(--vxb-wk-block, #a32d2d) 15%, var(--vxb-bg) ); color: var(--vxb-wk-block, #a32d2d); }
.vxb-av-wk-chip.is-imported { background: color-mix( in srgb, var(--vxb-wk-imported, #534ab7) 15%, var(--vxb-bg) ); color: var(--vxb-wk-imported, #534ab7); }
.vxb-av-wk-chip.is-excluded { background: color-mix( in srgb, var(--vxb-wk-excluded, #6b7280) 15%, var(--vxb-bg) ); color: var(--vxb-wk-excluded, #6b7280); }

/* A range bar that continues beyond the visible week: flatten + reach the edge on the
   open side(s) so it reads as "continues". */
.vxb-av-wk-chip.is-open-start { margin-left: 0; border-top-left-radius: 0; border-bottom-left-radius: 0; }
.vxb-av-wk-chip.is-open-end { margin-right: 0; border-top-right-radius: 0; border-bottom-right-radius: 0; }

/* Timeline body: hour gutter + 7 columns. Hour lines come from a repeating
   gradient sized by the hour height, so they track the Elementor control. */
.vxb-av-wk-gutter {
	display: flex;
	flex-direction: column;
}

.vxb-av-wk-hour {
	height: var(--vxb-wk-hour-h, 48px);
	padding: 2px 6px 0 0;
	box-sizing: border-box;
	text-align: right;
	font-size: 11px;
	color: var(--vxb-wk-muted, var(--vxb-muted, #6b7280));
}

.vxb-av-wk-col {
	position: relative;
	height: calc( var(--vxb-wk-hour-h, 48px) * var(--vxb-wk-rows, 12) );
	border-left: 1px solid var(--vxb-av-border, #e8eaed);
	cursor: pointer;
	background-image: repeating-linear-gradient(
		to bottom,
		var(--vxb-wk-line, rgba(0, 0, 0, 0.06)) 0,
		var(--vxb-wk-line, rgba(0, 0, 0, 0.06)) 1px,
		transparent 1px,
		transparent var(--vxb-wk-hour-h, 48px)
	);
}

/* No column highlight for today in the week view — today is already marked by the
   accent circle on the date number in the header. */

.vxb-av-wk-col.is-past {
	background-color: color-mix( in srgb, var(--vxb-muted) 10%, transparent );
}

.vxb-av-wk-closed {
	position: absolute;
	left: 0;
	right: 0;
	background: var(--vxb-wk-closed, color-mix( in srgb, var(--vxb-muted) 12%, transparent ));
	pointer-events: none;
}

/* Whole-day unavailable (manual block / imported all-day event / excluded day): a tint
   across EVERY hour of the column, so the day clearly reads as blocked — not just the
   chip in the all-day row. Sits behind the timed spans + lets clicks through to the col. */
.vxb-av-wk-fullblock {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
}

.vxb-av-wk-fullblock.is-block { background: color-mix( in srgb, var(--vxb-wk-block) 18%, transparent ); }
.vxb-av-wk-fullblock.is-imported { background: color-mix( in srgb, var(--vxb-wk-imported) 18%, transparent ); }
.vxb-av-wk-fullblock.is-excluded { background: color-mix( in srgb, var(--vxb-wk-excluded) 16%, transparent ); }

.vxb-availability .vxb-av-wk-span {
	position: absolute;
	left: 4px;
	right: 4px;
	min-height: 16px;
	display: flex;
	flex-direction: column;
	gap: 1px;
	padding: 3px 6px;
	border: 0;
	border-radius: var(--vxb-wk-span-radius, 6px);
	border-left: 3px solid currentColor;
	font-size: 11px;
	font-family: inherit;
	line-height: 1.25;
	text-align: left;
	cursor: pointer;
	overflow: hidden;
	box-sizing: border-box;
	z-index: 1;
}

.vxb-av-wk-span.is-booking { background: color-mix( in srgb, var(--vxb-wk-booking, #185fa5) 15%, var(--vxb-bg) ); color: var(--vxb-wk-booking, #185fa5); }
.vxb-av-wk-span.is-booking.is-pending { background: color-mix( in srgb, var(--vxb-wk-pending, #b45309) 16%, var(--vxb-bg) ); color: var(--vxb-wk-pending, #b45309); }
.vxb-av-wk-span.is-block { background: color-mix( in srgb, var(--vxb-wk-block, #a32d2d) 15%, var(--vxb-bg) ); color: var(--vxb-wk-block, #a32d2d); }
.vxb-av-wk-span.is-imported { background: color-mix( in srgb, var(--vxb-wk-imported, #534ab7) 15%, var(--vxb-bg) ); color: var(--vxb-wk-imported, #534ab7); }

/* Overlapping spans step right so both stay visible and clickable. */
.vxb-av-wk-span.is-indent {
	left: 30%;
	z-index: 2;
}

.vxb-av-wk-span-label {
	font-weight: 600;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.vxb-av-wk-span-sub {
	opacity: 0.85;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* Month / Week view toggle — a segmented control: a soft track with rounded
   pill tabs, the active one lifted with the accent. The track tint derives from
   currentColor so it reads correctly on light AND dark themes. flex-shrink:0 is
   load-bearing: the sibling pills have min-widths, so in a tight header all the
   flex shrink would otherwise land here and clip the Week tab. */
.vxb-availability .vxb-av-viewtabs {
	display: inline-flex;
	flex-shrink: 0;
	gap: 2px;
	padding: 3px;
	border-radius: 10px;
	background: var(--vxb-wk-tabs-bg, color-mix( in srgb, currentColor 8%, transparent ));
}

.vxb-availability .vxb-av-viewtab {
	display: inline-flex;
	align-items: center;
	height: 32px;
	border: 0;
	border-radius: 8px;
	background: transparent;
	padding: 0 14px;
	font-size: 13px;
	font-weight: 500;
	font-family: inherit;
	white-space: nowrap;
	cursor: pointer;
	color: var(--vxb-wk-tab-text, inherit);
	opacity: 0.7;
	transition: background 0.15s ease, color 0.15s ease, opacity 0.15s ease;
}

.vxb-availability .vxb-av-viewtab:hover {
	opacity: 1;
}

.vxb-availability .vxb-av-viewtab.is-active {
	background: var(--vxb-wk-tab-active-bg, var(--vxb-av-accent, #2271b1));
	color: var(--vxb-wk-tab-active-text, #fff);
	opacity: 1;
	font-weight: 600;
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
}

/* Narrow screens: keep the timeline usable with a horizontal scroll. */
@media (max-width: 720px) {
	/* The 7-day hour timeline can't fit a phone width, so it scrolls horizontally with
	   readable day columns (~100px each) — swipe to reach later days. */
	.vxb-av-week {
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
	}

	.vxb-av-wk-head,
	.vxb-av-wk-allday,
	.vxb-av-wk-body {
		min-width: 780px;
	}
}

/* ── Class sessions (day panel) ─────────────────────────────────────────────
   Class listings replace the native availability controls with the day's
   sessions. Every colour derives from the master palette above, so the Style
   tab's presets re-theme this for free. */
.vxb-av-cls-list {
	display: flex;
	flex-direction: column;
	border-top: 1px solid var(--vxb-border);
}

.vxb-av-cls {
	display: flex;
	align-items: center;
	gap: 10px;
	width: 100%;
	padding: 10px 2px;
	background: none;
	border: 0;
	border-bottom: 1px solid var(--vxb-border);
	text-align: left;
	cursor: pointer;
	font: inherit;
	color: var(--vxb-text);
}

.vxb-av-cls:hover {
	background: var(--vxb-bg-soft);
}

.vxb-av-cls-time {
	flex: 0 0 auto;
	width: 44px;
	font-size: 13px;
	color: var(--vxb-muted);
}

/* The class's own colour — the same value the schedule editor, its weekly
   preview and the public timetable use, so a class reads as one object. */
.vxb-av-cls-bar {
	flex: 0 0 auto;
	width: 3px;
	height: 30px;
	border-radius: 0;
}

.vxb-av-cls-main {
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 1px;
}

.vxb-av-cls-name {
	font-size: 14px;
	font-weight: 500;
	color: var(--vxb-text);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.vxb-av-cls-meta {
	font-size: 12px;
	color: var(--vxb-muted);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Without this an overridden session just looks wrong ("why does Tuesday say
   8?"), so the chip is what stops it reading as a bug. */
.vxb-av-cls-chip {
	display: inline-block;
	margin-left: 6px;
	padding: 1px 7px;
	border-radius: 999px;
	font-size: 11px;
	font-weight: 400;
	color: var(--vxb-accent);
	background: color-mix( in srgb, var(--vxb-accent) 12%, var(--vxb-bg) );
}

.vxb-av-cls-seats {
	flex: 0 0 auto;
	font-size: 13px;
	color: var(--vxb-muted);
}

.vxb-av-cls-off {
	flex: 0 0 auto;
	padding: 2px 8px;
	border-radius: 999px;
	font-size: 12px;
	color: var(--vxb-blocked);
	background: color-mix( in srgb, var(--vxb-blocked) 12%, var(--vxb-bg) );
}

.vxb-av-cls-chev {
	flex: 0 0 auto;
	display: flex;
	color: var(--vxb-muted);
}

/* A closed class stays listed and still shows its booking count — it must never
   silently disappear while people are still booked into it. */
.vxb-av-cls.is-off .vxb-av-cls-name {
	color: var(--vxb-muted);
	text-decoration: line-through;
}

.vxb-av-cls.is-off .vxb-av-cls-bar {
	background: var(--vxb-border) !important;
}

.vxb-av-cls-warn {
	color: var(--vxb-blocked);
}

/* ── Session editor modal ───────────────────────────────────────────────── */
.vxb-av-sm-overlay {
	position: fixed;
	inset: 0;
	background: rgba( 0, 0, 0, 0.45 );
	z-index: 100004;
}

.vxb-av-sm {
	position: fixed;
	top: 50%;
	left: 50%;
	width: 420px;
	max-width: calc( 100vw - 32px );
	transform: translate( -50%, -50% ) scale( 0.98 );
	background: var(--vxb-bg);
	border-radius: var(--vxb-radius);
	box-shadow: 0 12px 40px rgba( 0, 0, 0, 0.22 );
	z-index: 100005;
	display: flex;
	flex-direction: column;
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.18s ease, transform 0.18s ease;
}

.vxb-av-sm.vxb-av-sm-open {
	opacity: 1;
	pointer-events: auto;
	transform: translate( -50%, -50% ) scale( 1 );
}

.vxb-av-sm-head {
	display: flex;
	align-items: flex-start;
	gap: 10px;
}

.vxb-av-sm-bar {
	flex: 0 0 auto;
	width: 3px;
	height: 34px;
}

.vxb-av-sm-head-text {
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.vxb-av-sm-sub {
	font-size: 12px;
	color: var(--vxb-muted);
}

.vxb-av-sm-body {
	padding: 16px 20px;
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.vxb-av-sm-zero {
	margin: 2px 0 0;
	padding: 9px 11px;
	border-radius: 8px;
	font-size: 12px;
	line-height: 1.5;
	color: var(--vxb-blocked);
	background: color-mix( in srgb, var(--vxb-blocked) 10%, var(--vxb-bg) );
}

.vxb-av-sm-toggle {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin-top: 10px;
	padding-top: 14px;
	border-top: 1px solid var(--vxb-border);
}

.vxb-av-sm-toggle-text {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.vxb-av-sm-toggle-label {
	font-size: 13px;
	color: var(--vxb-text);
}

.vxb-av-switch {
	flex: 0 0 auto;
	width: 38px;
	height: 22px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background: color-mix( in srgb, var(--vxb-muted) 40%, var(--vxb-bg) );
	cursor: pointer;
	position: relative;
	transition: background 0.15s ease;
}

.vxb-av-switch.is-on {
	background: var(--vxb-accent);
}

.vxb-av-switch-knob {
	position: absolute;
	top: 3px;
	left: 3px;
	width: 16px;
	height: 16px;
	border-radius: 50%;
	background: #000;
	transition: transform 0.15s ease;
}

.vxb-av-switch.is-on .vxb-av-switch-knob {
	transform: translateX( 16px );
}

.vxb-av-sm-foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	padding: 14px 20px;
	border-top: 1px solid var(--vxb-border);
}

.vxb-av-sm-reset {
	font-size: 13px;
	color: var(--vxb-muted);
	text-decoration: none;
}

.vxb-av-sm-reset:hover {
	color: var(--vxb-text);
}

.vxb-av-sm-actions {
	display: flex;
	gap: 8px;
	margin-left: auto;
}

@media ( max-width: 600px ) {
	.vxb-av-sm {
		top: auto;
		bottom: 0;
		left: 0;
		width: 100%;
		max-width: 100%;
		transform: translateY( 100% );
		border-radius: 16px 16px 0 0;
	}
	.vxb-av-sm.vxb-av-sm-open {
		transform: translateY( 0 );
	}
}

/* Elementor's Kit styles bare `button` elements globally (`.elementor-kit-N button`
   = 0-1-1), which outguns our single-class rules (0-1-0) — it was flattening the
   modal's padding and killing the pointer cursor. Scoping to the modal keeps the
   specificity fight contained, and !important is what actually settles it: TWO
   systems target bare elements here (Elementor's Kit and Voxel's `.ts-form`), so a
   plain declaration loses to whichever loads last. */
.vxb-av-sm button,
.vxb-av-sm .ts-btn,
.vxb-av-sm .vxb-av-sm-reset,
.vxb-av-cls {
	cursor: pointer !important;
}

.vxb-av-sm .ts-btn {
	padding: 0 18px !important;
	height: 40px !important;
	min-height: 0 !important;
	width: auto !important;
	flex: 0 0 auto !important;
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	line-height: 1 !important;
	border-radius: 8px !important;
}

.vxb-av-sm .vxb-av-panel-close {
	padding: 0 !important;
	width: 30px !important;
	height: 30px !important;
	min-height: 0 !important;
	flex: 0 0 auto !important;
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	background: none !important;
	border: 0 !important;
	color: var(--vxb-muted) !important;
	font-size: 20px !important;
	line-height: 1 !important;
}

/* Both sheets that carry the switch — the theme's Kit repaints a bare <button> with its own
   padding/height, which would stretch the track out of shape wherever it appears. */
.vxb-av-sm .vxb-av-switch,
.vxb-cv-sheet .vxb-av-switch {
	padding: 0 !important;
	height: 22px !important;
	min-height: 0 !important;
	width: 38px !important;
	flex: 0 0 auto !important;
	background-image: none !important;
	box-shadow: none !important;
}

/* The toggle sits between the fields and the apply-to row in the Classes View sheet, so it
   needs its own spacing rather than the day panel's modal rhythm. */
.vxb-cv-toggle {
	margin-top: 14px;
	padding-top: 14px;
}
/* When the block note is above it, that note already provides the separation. */
.vxb-cv-blocked + .vxb-cv-toggle {
	margin-top: 6px;
	padding-top: 10px;
}
.vxb-cv-blocked {
	margin: 14px 0 0 !important;
}
.vxb-cv-toggle .vxb-av-sm-toggle-label {
	font-size: 13px !important;
	color: var(--vxb-text) !important;
}
.vxb-cv-toggle .vxb-av-note {
	font-size: 12px !important;
	color: var(--vxb-muted) !important;
}

/* The session row is a <button>: stop the Kit giving it a background, a border or
   centred text. */
.vxb-av-cls {
	background: none !important;
	border: 0 !important;
	border-bottom: 1px solid var(--vxb-border) !important;
	border-radius: 0 !important;
	padding: 10px 2px !important;
	height: auto !important;
	min-height: 0 !important;
	text-align: left !important;
	justify-content: flex-start !important;
	color: var(--vxb-text) !important;
}

.vxb-av-cls:hover {
	background: var(--vxb-bg-soft) !important;
}

/* ═══════════════════════════════════════════════════════════════════════════
   MOBILE (≤600px) — booking popup, day panel, session modal
   ═══════════════════════════════════════════════════════════════════════════
   Appended last and scoped to .vxb-availability / the panel roots, so it beats
   both the base rules above and Elementor's Kit (bare `button`/`a`/`p` at
   0-1-1). The sheets themselves already become bottom sheets earlier in this
   file; what follows is about the CONTENT being too tall to read.
   ═══════════════════════════════════════════════════════════════════════════ */
@media ( max-width: 600px ) {

	/* ── Booking popup: two-column body ──────────────────────────────────────
	   Every detail was label-above-value at full width — six of them ≈ 350px
	   before the actions even start, so the booking you tapped was off-screen.
	   Pairing the short ones halves that; only genuinely long values (email,
	   listing title, the date+time range) keep a full row. */
	.vxb-av-bp .vxb-av-bp-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 a line and strands an empty half — dense
		   pulls the next half-width field up into it. Which fields exist varies
		   per booking, so the markup can't pre-pair them. */
		grid-auto-flow: dense;
		/* The body is `flex: 1` in a full-height sheet — without this the grid
		   stretches its rows to fill it and every field becomes a tall cell. */
		align-content: start;
		gap: 8px;
		padding: 12px 16px;
	}


	/* Bounded field blocks, matching Vendor Bookings and My Bookings so all three
	   booking panels read the same way. */
	.vxb-av-bp .vxb-av-bp-row {
		align-items: stretch;
		justify-content: flex-start;
		min-width: 0;
		padding: 7px 9px;
		background: var(--vxb-bg-soft);
		border: 1px solid var(--vxb-border);
		border-radius: 8px;
	}

	.vxb-av-bp .vxb-av-bp-row > * {
		text-align: left !important;
		min-width: 0;
		overflow-wrap: anywhere;
	}

	.vxb-av-bp .vxb-av-bp-row--wide,
	.vxb-av-bp .vxb-av-bp-comments { grid-column: 1 / -1; }

	/* ── Booking popup: two-column actions ───────────────────────────────────
	   Wrapping is required, not tolerated: these labels come from Voxel and are
	   localized, so "Άνοιγμα παραγγελίας στο backend" has to be free to take two
	   lines inside its cell. Two two-line buttons side by side are still shorter
	   than two full-width rows. */
	.vxb-av-bp .vxb-av-bp-foot {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: 8px;
		padding: 12px 16px calc( 12px + env( safe-area-inset-bottom, 0px ) );
	}

	.vxb-av-bp .vxb-av-bp-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;
	}

	.vxb-av-bp .vxb-av-bp-foot > .vxb-av-panel-label,
	.vxb-av-bp .vxb-av-bp-foot > .vxb-av-bp-error,
	.vxb-av-bp .vxb-av-bp-foot > .vxb-av-note { grid-column: 1 / -1; }

	/* Cancelling a booking is irreversible — own row, last, never a half-width
	   neighbour of "Open order page" where a thumb can miss. */
	.vxb-av-bp .vxb-av-bp-foot .vxb-av-danger {
		grid-column: 1 / -1;
		order: 99;
	}

	/* ── Day panel: unblock actions pair up ─────────────────────────────────── */
	.vxb-av-panel .vxb-av-actions {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: 8px;
	}

	.vxb-av-panel .vxb-av-actions .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;
	}

	/* ── Day panel: reservation rows ─────────────────────────────────────────
	   The card is a two-line grid that already truncates at every width, so all a
	   phone needs is tighter gutters and the chevron gone — the card is a button,
	   and the arrow only spends width the name and class need. */
	.vxb-av-panel .vxb-av-res {
		column-gap: 8px;
		padding: 9px 10px;
	}
	.vxb-av-panel .vxb-av-res-open { display: none; }

	/* ── Session modal: actions ──────────────────────────────────────────────
	   Only Cancel/Save, so they simply share a row rather than needing a grid. */
	.vxb-av-sm .vxb-av-sm-actions { flex: 1; }
	.vxb-av-sm .vxb-av-sm-actions .ts-btn { flex: 1; }

	/* ── Add-booking panel: its footer is already two across, but the labels are
	   translated too ("Καταχώρηση ούτως ή άλλως"), so they must be free to wrap
	   rather than overflow their button. */
	.vxb-av-ab .vxb-av-ab-foot .ts-btn {
		height: auto !important;
		min-height: 42px !important;
		padding: 8px 10px !important;
		white-space: normal !important;
		line-height: 1.25 !important;
		text-align: center !important;
	}
}

/* ═══════════════════════════════════════════════════════════════════════════
 * Classes view (schedule management on class listings)
 *
 * The widget root carries `ts-form`, and the Elementor Kit repaints bare
 * button/input/select globally, so every legibility-critical property here is
 * pulled from the shared palette (--vxb-text/--vxb-muted/--vxb-bg) and forced
 * with !important — otherwise the theme wins and text vanishes on a dark preset.
 * ═══════════════════════════════════════════════════════════════════════════ */

.vxb-availability .vxb-av-modetabs {
	display: inline-flex;
	gap: 2px;
	padding: 3px;
	border-radius: 10px;
	background: color-mix( in srgb, var( --vxb-text, currentColor ) 8%, transparent );
}
.vxb-availability .vxb-av-modetab {
	height: 32px;
	border: 0 !important;
	border-radius: 8px !important;
	background: transparent !important;
	padding: 0 14px !important;
	font: inherit;
	font-size: 13px !important;
	font-weight: 500;
	white-space: nowrap;
	cursor: pointer;
	color: var( --vxb-text ) !important;
	opacity: 0.65;
	transition: background 0.15s ease, opacity 0.15s ease;
	width: auto !important;
	min-height: 0 !important;
}
.vxb-availability .vxb-av-modetab:hover { opacity: 1; }
.vxb-availability .vxb-av-modetab.is-active {
	background: var( --vxb-accent, #2271b1 ) !important;
	color: var( --vxb-on-accent, #fff ) !important;
	opacity: 1;
	font-weight: 600;
}

.vxb-cv { margin-top: 6px; }

.vxb-cv-bar { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; }
.vxb-availability .vxb-cv-weeklabel { font-size: 14px; font-weight: 600; min-width: 120px; color: var( --vxb-text ) !important; }

.vxb-cv-empty { padding: 28px 4px; color: var( --vxb-muted ); font-size: 14px; }

/* The grid: a time gutter + 7 day columns; scrolls sideways on narrow screens. */
.vxb-cv-grid {
	display: grid;
	grid-template-columns: 52px repeat( 7, minmax( 104px, 1fr ) );
	gap: 6px;
	overflow-x: auto;
	padding-bottom: 6px;
}
.vxb-cv-dayhead {
	text-align: center;
	padding: 4px 2px 8px;
	line-height: 1.2;
	border-bottom: 1px solid var( --vxb-border, currentColor );
}
.vxb-cv-dayhead.is-past { opacity: 0.55; }
.vxb-cv-wd { display: block; font-size: 11px; color: var( --vxb-muted ); }
.vxb-cv-dn { display: block; font-size: 15px; font-weight: 600; color: var( --vxb-text ); }
.vxb-cv-dayhead.is-today .vxb-cv-dn { color: var( --vxb-accent ); }

.vxb-cv-time { font-size: 11px; color: var( --vxb-muted ); text-align: right; padding: 8px 4px 0 0; }
.vxb-cv-cell { display: flex; flex-direction: column; gap: 5px; min-width: 0; padding-top: 4px; }

/* Class block: a solid card (palette bg + a wash of the class colour) so the
   text is always readable, with the colour as a left bar. Forced past the Kit. */
.vxb-availability .vxb-cv-block {
	display: block !important;
	width: 100% !important;
	text-align: left;
	box-sizing: border-box;
	border: 1px solid var( --vxb-border, currentColor ) !important;
	border-left: 3px solid var( --vxb-cv-cc, var( --vxb-muted ) ) !important;
	border-radius: 0 8px 8px 0 !important;
	background: linear-gradient( 90deg, color-mix( in srgb, var( --vxb-cv-cc, transparent ) 13%, var( --vxb-bg ) ), var( --vxb-bg ) 68% ) !important;
	padding: 7px 9px !important;
	line-height: 1.25;
	cursor: pointer;
	font: inherit;
	color: var( --vxb-text ) !important;
	min-height: 0 !important;
	height: auto !important;
	transition: border-color 0.15s ease;
}
.vxb-availability .vxb-cv-block:hover { border-color: var( --vxb-cv-cc, var( --vxb-accent ) ) !important; }
/* A closed class keeps FULL brightness (no fade — a dimmed card wrongly read as "future/
   inactive"); it's marked instead by a grey left bar and a red "Closed" label. */
.vxb-availability .vxb-cv-block.is-off { border-left-color: var( --vxb-muted ) !important; background: var( --vxb-bg ) !important; }
/* .vxb-cv-bs.vxb-cv-off-lbl (0-3-0) beats the base .vxb-cv-bs colour (0-2-0) whatever the
   source order — both carry !important, so specificity, not order, has to decide. */
.vxb-availability .vxb-cv-bs.vxb-cv-off-lbl { color: var( --vxb-blocked, #f0616a ) !important; font-weight: 600; }
.vxb-availability .vxb-cv-bn { display: block; font-size: 12px !important; font-weight: 600; color: var( --vxb-text ) !important; }
/* Brighter than --vxb-muted so the meta + seats read easily over the colour wash. */
.vxb-availability .vxb-cv-bm { display: block; font-size: 11px !important; color: color-mix( in srgb, var( --vxb-text ) 72%, transparent ) !important; margin-top: 1px; }
.vxb-availability .vxb-cv-bs { display: flex; align-items: center; gap: 4px; font-size: 11px !important; color: color-mix( in srgb, var( --vxb-text ) 78%, transparent ) !important; margin-top: 2px; }
.vxb-cv-ico { flex: 0 0 auto; opacity: 0.75; }
.vxb-availability .vxb-cv-block.is-edited .vxb-cv-bn::after { content: "•"; color: var( --vxb-accent ); margin-left: 5px; }

/* Overlays: edit sheet + cancel dialog. */
.vxb-cv-overlay { position: fixed; inset: 0; background: rgba( 0, 0, 0, 0.5 ); z-index: 100000; }
.vxb-cv-sheet,
.vxb-cv-confirm {
	position: fixed;
	z-index: 100001;
	left: 50%;
	top: 50%;
	transform: translate( -50%, -50% );
	width: min( 460px, calc( 100vw - 32px ) );
	max-width: calc( 100vw - 32px );
	max-height: calc( 100vh - 48px );
	box-sizing: border-box;
	overflow-x: hidden;
	overflow-y: auto;
	background: var( --vxb-bg, #fff ) !important;
	color: var( --vxb-text, inherit ) !important;
	border: 1px solid var( --vxb-border, currentColor );
	border-radius: 14px;
	padding: 18px;
	box-shadow: 0 12px 40px rgba( 0, 0, 0, 0.35 );
}

.vxb-cv-sheet-head { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.vxb-cv-dot { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; }
.vxb-availability .vxb-cv-sheet-head strong { font-size: 15px; color: var( --vxb-text ) !important; }
.vxb-cv-sub { font-size: 12px; color: var( --vxb-muted ); }
.vxb-cv-badge { font-size: 11px; padding: 2px 8px; border-radius: 999px; background: color-mix( in srgb, var( --vxb-text ) 12%, transparent ); color: var( --vxb-text ); }
.vxb-availability .vxb-cv-x {
	margin-left: auto;
	border: 0 !important;
	background: transparent !important;
	color: var( --vxb-text ) !important;
	font-size: 22px !important;
	line-height: 1 !important;
	cursor: pointer;
	opacity: 0.6;
	width: auto !important;
	min-height: 0 !important;
	padding: 0 4px !important;
}
.vxb-availability .vxb-cv-x:hover { opacity: 1; }

.vxb-cv-booked { margin: 0 0 12px; font-size: 12px; color: var( --vxb-accent ); }

.vxb-cv-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.vxb-cv-f { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.vxb-cv-f-full { grid-column: 1 / -1; }
.vxb-availability .vxb-cv-f > span { font-size: 11px !important; color: var( --vxb-muted ) !important; }

/* Controls: solid palette bg + forced text, so neither ts-form nor the Kit can
   leave white-on-white. Option colours are set too (the native dropdown list). */
.vxb-availability .vxb-cv-f select,
.vxb-availability .vxb-cv-f input,
.vxb-availability .vxb-cv-f textarea {
	width: 100% !important;
	box-sizing: border-box;
	border: 1px solid var( --vxb-border, currentColor ) !important;
	border-radius: 8px !important;
	background: var( --vxb-bg-soft, transparent ) !important;
	color: var( --vxb-text ) !important;
	font: inherit;
	font-size: 13px !important;
	padding: 8px 9px !important;
	height: auto !important;
	min-height: 0 !important;
}
/* Keep the native dropdown caret (its colour follows `color`, so it stays visible on a dark
   preset); force the option list's colours too, since the native popup ignores the select's bg. */
.vxb-availability .vxb-cv-f option { background: var( --vxb-bg ) !important; color: var( --vxb-text ) !important; }
.vxb-availability .vxb-cv-f textarea { resize: vertical; min-height: 54px !important; font-family: inherit; }
.vxb-availability .vxb-cv-f input::placeholder,
.vxb-availability .vxb-cv-f textarea::placeholder { color: var( --vxb-muted ) !important; opacity: 1; }
.vxb-availability .vxb-cv-f select:focus,
.vxb-availability .vxb-cv-f input:focus,
.vxb-availability .vxb-cv-f textarea:focus { outline: none; border-color: var( --vxb-accent ) !important; }

.vxb-cv-warn {
	margin: 10px 0 0;
	font-size: 12px;
	line-height: 1.4;
	color: var( --vxb-pending, #d98a00 );
	background: color-mix( in srgb, var( --vxb-pending, #d98a00 ) 15%, transparent );
	border-radius: 8px;
	padding: 8px 10px;
}

/* Actions: two buttons that SHARE the width and never overflow the sheet. */
.vxb-cv-actions { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
.vxb-availability .vxb-cv-actions .ts-btn {
	flex: 1 1 0 !important;
	width: auto !important;
	min-width: 0 !important;
	height: auto !important;
	min-height: 0 !important;
	padding: 10px 14px !important;
	white-space: nowrap;
	font-size: 13px !important;
}
/* Cancel dialog: Keep it is the strong accent CTA; Cancel class is a quiet red outline. */
.vxb-availability .vxb-cv-keep {
	background: var( --vxb-accent, #2271b1 ) !important;
	border: 1px solid var( --vxb-accent, #2271b1 ) !important;
	color: var( --vxb-on-accent, #fff ) !important;
	font-weight: 600;
}
.vxb-availability .vxb-cv-danger-outline {
	background: transparent !important;
	border: 1px solid var( --vxb-blocked, #c0392b ) !important;
	color: var( --vxb-blocked, #c0392b ) !important;
}
.vxb-availability .vxb-cv-danger-outline:hover { background: color-mix( in srgb, var( --vxb-blocked, #c0392b ) 12%, transparent ) !important; }

/* Legend under the week grid — explains the marks (like the bookings calendar's legend). */
.vxb-cv-legend { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 14px; font-size: 12px; color: var( --vxb-muted ); }
.vxb-cv-lg { display: inline-flex; align-items: center; gap: 6px; }
.vxb-cv-lg-dot { width: 7px; height: 7px; border-radius: 50%; background: var( --vxb-accent ); flex: 0 0 auto; }
.vxb-cv-lg-closed { width: 12px; height: 4px; border-radius: 2px; background: var( --vxb-muted ); flex: 0 0 auto; }

.vxb-availability .vxb-cv-confirm strong { font-size: 15px; display: block; margin-bottom: 12px; color: var( --vxb-text ) !important; }
/* Cancel-scope choice as segmented pills (the theme hides native radios). */
.vxb-cv-scope { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.vxb-availability .vxb-cv-scopebtn {
	flex: 0 1 auto;
	border: 1px solid var( --vxb-border, currentColor ) !important;
	border-radius: 999px !important;
	background: transparent !important;
	color: var( --vxb-text ) !important;
	padding: 1px 15px !important;
	font: inherit;
	font-size: 13px !important;
	cursor: pointer;
	width: auto !important;
	height: auto !important;
	min-height: 0 !important;
	white-space: nowrap;
}
.vxb-availability .vxb-cv-scopebtn.is-active {
	background: var( --vxb-accent, #2271b1 ) !important;
	border-color: var( --vxb-accent, #2271b1 ) !important;
	color: var( --vxb-on-accent, #fff ) !important;
	font-weight: 600;
}

@media (max-width: 600px) {
	.vxb-cv-fields { grid-template-columns: 1fr; }
	.vxb-cv-grid { grid-template-columns: 46px repeat( 7, minmax( 116px, 1fr ) ); }
}

/* Cursor: the theme/Kit drops the hand on some controls — force it on every CV clickable. */
.vxb-availability .vxb-av-modetab,
.vxb-availability .vxb-cv-block,
.vxb-availability .vxb-cv-scopebtn,
.vxb-availability .vxb-cv-x,
.vxb-availability .vxb-cv-reset,
.vxb-availability .vxb-cv-actions .ts-btn { cursor: pointer !important; }

/* Closed class: strike the name through (on top of the grey bar + "Closed" label). */
.vxb-availability .vxb-cv-block.is-off .vxb-cv-bn {
	text-decoration: line-through;
	text-decoration-color: var( --vxb-blocked, #f0616a );
}

/* Fully-booked class: amber "Full" where the seats count goes. */
.vxb-availability .vxb-cv-bs.vxb-cv-full-lbl { color: var( --vxb-pending, #efaf52 ) !important; font-weight: 600; }

/* Edit scope ("apply to this / every Monday"). */
.vxb-cv-applyto { margin-top: 14px; }
.vxb-cv-applyto-lbl { display: block; font-size: 11px; color: var( --vxb-muted ); margin-bottom: 6px; }

/* Reset-to-schedule link under the actions. */
.vxb-cv-resetrow { margin-top: 12px; display: flex; flex-direction: column; gap: 2px; }
.vxb-availability .vxb-cv-reset {
	color: var( --vxb-muted ) !important;
	text-decoration: underline;
	cursor: pointer;
	font-size: 12px;
	align-self: flex-start;
}
.vxb-availability .vxb-cv-reset:hover { color: var( --vxb-text ) !important; }
.vxb-cv-reset-hint { font-size: 11px; color: var( --vxb-muted ); }

/* Full swatch for the legend. */
.vxb-cv-lg-full { width: 12px; height: 4px; border-radius: 2px; background: var( --vxb-pending, #efaf52 ); flex: 0 0 auto; }

/* Add-class button in the week bar + the add sheet's existing/new toggle spacing. */
.vxb-cv-bar-sp { flex: 1; }
.vxb-availability .vxb-cv-addbtn {
	flex: 0 0 auto !important;
	width: auto !important;
	height: auto !important;
	min-height: 0 !important;
	padding: 8px 14px !important;
	font-size: 13px !important;
	background: var( --vxb-accent, #2271b1 ) !important;
	border: 1px solid var( --vxb-accent, #2271b1 ) !important;
	color: var( --vxb-on-accent, #fff ) !important;
	font-weight: 600;
	white-space: nowrap;
	cursor: pointer !important;
}
.vxb-cv-scope-top { margin-bottom: 14px; }

/* Attendee roster in the edit sheet. */
.vxb-cv-roster { margin: 0 0 12px; border: 1px solid var( --vxb-border, currentColor ); border-radius: 10px; padding: 10px 12px; }
.vxb-cv-roster-h { display: block; font-size: 11px; color: var( --vxb-muted ); margin-bottom: 6px; }
.vxb-cv-roster-list { list-style: none; margin: 0; padding: 0; }
.vxb-cv-roster-row { display: flex; justify-content: space-between; gap: 10px; font-size: 12.5px; padding: 3px 0; }
.vxb-cv-roster-name { color: var( --vxb-text ); }
.vxb-cv-roster-order { color: var( --vxb-muted ); white-space: nowrap; }

/* Two-dropdown 24h time picker (native <input type=time> gets stripped by the theme). */
.vxb-cv-time2 { display: flex; align-items: center; gap: 6px; }
.vxb-availability .vxb-cv-time2 select { width: auto !important; flex: 1 1 0; }
.vxb-cv-time2-sep { color: var( --vxb-muted ); font-weight: 600; }

/* Remove-from-calendar is a destructive link (red), unlike the neutral reset link. */
.vxb-availability .vxb-cv-remove { color: var( --vxb-blocked, #f0616a ) !important; }
.vxb-availability .vxb-cv-remove:hover { color: var( --vxb-blocked, #f0616a ) !important; opacity: 0.85; }

/* Attendee name / order links — the vendor jumps straight to the person or the order. */
.vxb-availability .vxb-cv-roster-name.is-link,
.vxb-availability .vxb-cv-roster-order.is-link {
	color: var( --vxb-accent ) !important;
	text-decoration: underline;
	cursor: pointer !important;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * 1.45.2 mobile fixes. One late block ON PURPOSE: each of these has to beat
 * earlier same-specificity !important rules, and source order is the tiebreak.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* The Classes View week bar is a nowrap flex row: arrows + week label + "This
   week" + "+ Add class". With Greek labels ("Προσθήκη μαθήματος" ≈ 180px) that
   cannot fit a phone, and a flex row refuses to shrink below min-content — the
   Add button ran past the viewport edge and handed the whole PAGE a horizontal
   scrollbar. Wrap instead, and give Add its own full-width row (a thumb is not
   a mouse; same idiom as the timetable's Book button). */
@media ( max-width: 600px ) {
	.vxb-cv-bar { flex-wrap: wrap; }

	.vxb-availability .vxb-cv-addbtn {
		flex: 1 1 100% !important;
		width: 100% !important;
	}
}

/* Sheet close (X) buttons, ALL of them — day panel, booking popup, session
   sheet, Classes View sheets. Reported on mobile as "the X doesn't work":
   every X was its bare glyph, a ~14×24px tap target at worst, so thumb taps
   landed on the head beside it and the button read as stuck. 40px target
   (glyph stays centred, so nothing moves visually), lifted above any
   overlapping head text, double-tap zoom opted out so the first tap counts. */
.vxb-availability .vxb-av-panel-close,
.vxb-av-sm .vxb-av-panel-close,
.vxb-availability .vxb-cv-x {
	width: 40px !important;
	height: 40px !important;
	min-width: 40px !important;
	min-height: 40px !important;
	padding: 0 !important;
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	flex: 0 0 auto !important;
	position: relative;
	z-index: 2;
	touch-action: manipulation;
}

/* The day panel is a flex column capped at 85vh on phones, but its body had no
   min-height:0 — a flex item never shrinks below its content, so on a busy day
   the body overflowed the sheet instead of scrolling inside it. Base-level fix:
   the desktop panel is the same flex column at height:100%, where this makes
   the body fill and scroll correctly too. */
.vxb-av-panel-body {
	flex: 1 1 auto;
	min-height: 0;
}

/* The availability switch's hint, at the ONE moment it matters: a recurrence is
   selected AND the switch was flipped, so the save is about to split — fields to
   every <weekday>, the switch to this class only. Amber (the palette's warning
   tier, themeable via the Pending status colour) + semibold + full opacity, so
   the eye is pulled to it exactly as the flip happens. Deliberately NOT shown
   for merely selecting a recurrence: a warning that is always on trains the eye
   to ignore it. */
.vxb-availability .vxb-cv-toggle .vxb-av-note.is-once-warn {
	color: var( --vxb-pending, #b45309 ) !important;
	font-weight: 600;
	opacity: 1;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * Cancel/Restore flow redesign: choice cards with consequences, the paused-
 * series banner, the apply-diff block, the series-edit undo bar, and the day
 * panel's cancel/restore row. All palette-driven. Appended last so it wins on
 * source order.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* The confirm dialogs open from BOTH Classes View (sheet z 100001) and the day
   panel (sheet z 100005) — their overlay + box must clear either surface. */
.vxb-availability ~ .vxb-cv-overlay--top,
.vxb-cv-overlay--top { z-index: 100006; }
.vxb-cv-confirm { z-index: 100007; }

/* Choice cards: label + plain-language consequence. The active one takes the accent. */
.vxb-cv-choices { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; }
.vxb-cv-choice {
	display: block; width: 100%; text-align: left; cursor: pointer;
	background: var( --vxb-bg ); border: 1px solid var( --vxb-border );
	border-radius: 10px; padding: 10px 12px!important;
}
.vxb-cv-choice.is-active {
	border-color: var( --vxb-accent );
	background: color-mix( in srgb, var( --vxb-accent ) 10%, var( --vxb-bg ) );
}
.vxb-cv-choice-t { display: block; font-size: 14px; font-weight: 600; color: var( --vxb-text ); }
.vxb-cv-choice.is-active .vxb-cv-choice-t { color: var( --vxb-accent ); }
.vxb-cv-choice-s { display: block; font-size: 12px; line-height: 1.45; color: var( --vxb-muted ); margin-top: 2px; }

/* The apply dialog's diff — what is about to change, one line per field. */
.vxb-cv-diff {
	display: flex; flex-direction: column; gap: 3px;
	background: var( --vxb-bg-soft ); border-radius: 8px; padding: 9px 11px; margin: 4px 0 0;
}
.vxb-cv-diff-line { font-size: 12.5px; color: var( --vxb-text ); font-variant-numeric: tabular-nums; }

/* Paused-series banner: a state, not an error — amber-ish via the pending status var. */
.vxb-cv-paused {
	border: 1px solid color-mix( in srgb, var( --vxb-pending ) 45%, transparent );
	background: color-mix( in srgb, var( --vxb-pending ) 12%, var( --vxb-bg ) );
	border-radius: 10px; padding: 10px 12px; margin: 10px 0;
}
.vxb-cv-paused-t { margin: 0 0 8px; font-size: 13px; line-height: 1.45; color: var( --vxb-text ); }
.vxb-cv-paused-a { display: flex; gap: 8px; flex-wrap: wrap; }

/* Series-edit undo bar: the toast idiom, plus one button. */
.vxb-cv-undobar { display: flex; align-items: center; gap: 14px; }
.vxb-cv-undobtn {
	background: none; border: 0; cursor: pointer; padding: 2px 4px;
	font: inherit; font-weight: 700; text-decoration: underline; color: inherit;
}

/* Day panel: the cancel/restore row sits under the capacity block. */
.vxb-av-sm-cancelrow { margin-top: 14px; }
.vxb-av-sm-paused { margin-top: 14px; }

/* ═══════════════════════════════════════════════════════════════════════════
 * OFFERS vs COMMITS.
 *
 * Opening a day panel should feel like looking, not like being asked to act.
 * The actions it presents — add a booking, block the day, block a range — are
 * OFFERS: available, not urgent. They read as outlined buttons with a leading
 * glyph. The filled accent stays reserved for the COMMIT inside whatever panel
 * or dialog an offer opens (Save, Apply, Add booking), so a full-strength
 * button always means "this is the thing that will happen".
 *
 * Appended last so it beats the generic .ts-btn-1 defaults near the top, while
 * still losing to the Elementor "Buttons" Style section — a vendor who styles
 * buttons deliberately should still win.
 * ═══════════════════════════════════════════════════════════════════════════ */
.vxb-availability .vxb-av-offer {
	display: inline-flex; align-items: center; justify-content: center; gap: 8px;
	background: var( --vxb-bg );
	border: 1px solid var( --vxb-border );
	color: var( --vxb-text );
	font-weight: 500;
	transition: background-color .13s ease, border-color .13s ease, color .13s ease;
}
.vxb-availability .vxb-av-offer-ico { flex: 0 0 auto; opacity: .8; }
.vxb-availability .vxb-av-offer:hover:not( :disabled ) { background: var( --vxb-bg-soft ); }

/* The constructive offer keeps a hint of accent — enough to lead the eye, far
   short of a filled call to action. */
.vxb-availability .vxb-av-offer-go {
	border-color: color-mix( in srgb, var( --vxb-accent ) 42%, var( --vxb-border ) );
	color: var( --vxb-accent );
}
.vxb-availability .vxb-av-offer-go .vxb-av-offer-ico { opacity: 1; }
.vxb-availability .vxb-av-offer-go:hover:not( :disabled ) {
	background: color-mix( in srgb, var( --vxb-accent ) 8%, var( --vxb-bg ) );
	border-color: var( --vxb-accent );
}

/* Blocking closes something off, so it stays neutral until you reach for it —
   the warning colour belongs to the moment of intent, not to the resting state. */
.vxb-availability .vxb-av-offer-block { color: var( --vxb-muted ); }
.vxb-availability .vxb-av-offer-block:hover:not( :disabled ) {
	background: color-mix( in srgb, var( --vxb-blocked ) 7%, var( --vxb-bg ) );
	border-color: color-mix( in srgb, var( --vxb-blocked ) 38%, var( --vxb-border ) );
	color: var( --vxb-blocked );
}

/* Inline SVG icons are stroke-only (all 11 of them carry fill="none"), but a
   presentation ATTRIBUTE loses to any stylesheet rule — and themes/Elementor
   commonly ship `.ts-btn svg { fill: currentColor }`. That repaints our glyphs
   and, worse, turns an outlined circle into a solid disc: the "block" icon read
   as a filled ball rather than a no-entry sign. State both properties as rules
   so they outrank the theme instead of relying on the attribute. */
.vxb-availability svg {
	fill: none !important;
	stroke: currentColor !important;
	/* …and `currentColor` has to mean the BUTTON's colour. Voxel's commons.css sets
	   `:where(svg) { color: var(--ts-icon-color) }`, which lands on the svg itself —
	   so currentColor resolved to the theme's grey icon colour and the stroke dutifully
	   painted grey, ignoring the accent on the parent. Inheriting colour is what makes
	   a currentColor icon actually follow the control it sits in. */
	color: inherit !important;
}

/* ── The paused-series banner: ONE way back, plus an exception ──────────────
 * A paused series offers two genuinely different things — bring the whole
 * series back, or revive just this date and leave the rest paused. They were
 * rendered at equal weight, which turned a decision into a puzzle (made worse
 * by a third button elsewhere that duplicated the second).
 *
 * "Resume series" is the answer almost every time, so it keeps the filled
 * accent. The single-class exception drops to a quiet text button: present for
 * the vendor who wants it, silent for the one who doesn't. */
.vxb-availability .vxb-cv-paused-a { align-items: center; }
.vxb-availability .vxb-cv-resume-one {
	background: none !important;
	border: 0 !important;
	padding: 4px 6px !important;
	font-weight: 500;
	text-decoration: underline;
	text-underline-offset: 2px;
	color: var( --vxb-muted ) !important;
}
.vxb-availability .vxb-cv-resume-one:hover:not( :disabled ) {
	color: var( --vxb-text ) !important;
	background: none !important;
}
