/* ShootCal Web Calendar - frontend month grid + paginated toolbar.
 *
 * ============================================================================
 *  Theming / override paths for site owners (read me first if you're a theme dev):
 * ============================================================================
 *
 *  1. CSS CUSTOM PROPERTIES (recommended)
 *     The whole calendar is themed via the variables below. Override them
 *     anywhere outside the plugin layer to recolor without touching selectors:
 *
 *        .shootcal-web-calendar__wrap {
 *            --shootcal-booked-bg: #ffe4e6;
 *            --shootcal-wrap-radius: 4px;
 *            --shootcal-label-fg: #333;
 *        }
 *
 *     Available variables (defaults shown):
 *        --shootcal-wrap-bg          card background
 *        --shootcal-wrap-border      card border color
 *        --shootcal-wrap-radius      card corner radius
 *        --shootcal-wrap-shadow      card box-shadow
 *        --shootcal-grid-line        between-cell hairline color
 *        --shootcal-toolbar-border   toolbar bottom divider
 *        --shootcal-label-fg         month label color
 *        --shootcal-muted            weekday header + muted text
 *        --shootcal-btn-bg/fg/border/hover-bg/focus    nav button look
 *        --shootcal-available-bg/fg                    open day cell
 *        --shootcal-limited-bg/fg                      timed-only day cell
 *        --shootcal-booked-bg/fg                       all-day-blocked day cell
 *        --shootcal-past-bg/fg                         past day wash
 *        --shootcal-today-ring                         today's date highlight
 *        --shootcal-credit-fg                          attribution color
 *
 *  2. SELECTOR OVERRIDES
 *     All plugin styles are wrapped in @layer shootcal-web-calendar. Any
 *     unlayered CSS in the theme will WIN over these without any !important
 *     gymnastics. Just write a normal rule in your theme stylesheet and it
 *     takes precedence.
 *
 *  3. JS OVERRIDES
 *     Not needed - the plugin is a server-rendered structure with vanilla CSS.
 *     No build step, no shadow DOM, no JS-injected styles.
 * ============================================================================
 */

/* Variables live OUTSIDE the layer so they're easy to override globally without
 * having to think about layer cascade. */
.shootcal-web-calendar__wrap {
	--shootcal-wrap-bg: #ffffff;
	--shootcal-wrap-border: #e5e7eb;
	--shootcal-wrap-radius: 10px;
	/* Soft, layered elevation so the card lifts off the page like a macOS window. */
	--shootcal-wrap-shadow: 0 10px 28px -8px rgba(0, 0, 0, 0.16), 0 2px 6px -2px rgba(0, 0, 0, 0.08);

	--shootcal-grid-line: #e5e7eb;
	--shootcal-toolbar-border: #e5e7eb;

	--shootcal-label-fg: #111827;
	/* #6b7280 (gray-500) clears WCAG AA 4.5:1 on the white card; the old #9ca3af
	 * was ~2.5:1 and failed for the small weekday headers + muted text. */
	--shootcal-muted: #6b7280;

	--shootcal-btn-bg: transparent;
	--shootcal-btn-fg: #374151;
	--shootcal-btn-border: #d1d5db;
	--shootcal-btn-hover-bg: #f3f4f6;
	--shootcal-btn-focus: #2271b1;
	--shootcal-btn-active-bg: #e5e7eb;

	/* === ShootCal brand colors ============================================
	 * Sourced directly from the macOS app's color assets so the web grid
	 * stays in family with the desktop experience.
	 *
	 *   sunset        primary identity orange  (rgb 0.78, 0.42, 0.18)
	 *   sunset-vivid  brighter accent          (rgb 0.95, 0.45, 0.20)
	 *   sunrise       softer amber             (rgb 0.85, 0.62, 0.30)
	 *
	 * Stored TWO ways for maximum flexibility:
	 *   --shootcal-{name}-rgb   raw "R, G, B" triplet for use with rgba()
	 *                           when you want a transparent tint
	 *                              background: rgba(var(--shootcal-sunset-rgb), 0.1)
	 *   --shootcal-{name}       solid-color alias, drop-in for `color:`,
	 *                           `background:`, `border-color:`, etc.
	 *
	 * Limited cells derive their tint from sunrise; Booked cells from sunset;
	 * the whole grid stays visually anchored to the brand palette.
	 */
	--shootcal-sunset-rgb:        199, 107,  46;
	--shootcal-sunset-vivid-rgb:  242, 115,  51;
	--shootcal-sunrise-rgb:       217, 158,  76;
	--shootcal-sunset:       rgb( var(--shootcal-sunset-rgb) );
	--shootcal-sunset-vivid: rgb( var(--shootcal-sunset-vivid-rgb) );
	--shootcal-sunrise:      rgb( var(--shootcal-sunrise-rgb) );

	--shootcal-available-bg: #ffffff;
	--shootcal-available-fg: #1f2937;

	/* Limited + Booked cell colors are stored as RGB triplets so they can be
	 * rendered at 0.8 opacity at rest and 1.0 on hover via rgba(). Each embed
	 * (shortcode generator / block, availability mode only) can override these:
	 * the plugin emits a per-instance inline <style> scoped to that calendar's
	 * wrap when non-default colors are picked. */
	--shootcal-limited-bg-rgb: 252, 227, 168; /* #fce3a8 default */
	--shootcal-limited-fg: #7a4f1a;
	--shootcal-booked-bg-rgb:  246, 185, 163; /* #f6b9a3 default */
	--shootcal-booked-fg: #7c3d18;

	--shootcal-past-bg: #f9fafb;
	--shootcal-past-fg: #b6bac0;
	--shootcal-out-bg: #fafbfc;
	--shootcal-credit-fg: #6b7280;
}

@layer shootcal-web-calendar {

	/* === Defense against inadvertent wrapping ===
	 *
	 * If a user pastes the shortcode into a paragraph block AND toggles
	 * inline-code formatting (Cmd+E in Gutenberg), the resulting markup is
	 * `<p><code>[shortcode]</code></p>` and WordPress runs the shortcode but
	 * leaves the `<code>` wrapping. That `<code>` then becomes the grid item
	 * inside our cell and collapses the entire layout.
	 *
	 * Same problem can happen with `<pre>`, `<kbd>`, `<samp>`, or with WP's
	 * `wpautop` filter wrapping fragments in `<p>` tags. Defang all of them by
	 * making them `display: contents` (their children become direct children
	 * of the grid container) and stripping the code-like font + background.
	 *
	 * The user-visible fix is to use the "ShootCal Web Calendar" block instead
	 * of a shortcode in a code-formatted paragraph, but defending in CSS means
	 * the calendar still renders correctly even when the editor mistake happens.
	 */
	.shootcal-web-calendar__wrap code,
	.shootcal-web-calendar__wrap pre,
	.shootcal-web-calendar__wrap kbd,
	.shootcal-web-calendar__wrap samp,
	.shootcal-web-calendar__day code,
	.shootcal-web-calendar__day pre {
		display: contents !important;
		font-family: inherit !important;
		background: transparent !important;
		color: inherit !important;
		padding: 0 !important;
		border: 0 !important;
		white-space: normal !important;
	}

	/* --- Card wrap --- */

	.shootcal-web-calendar__wrap {
		display: flex;
		flex-direction: column;
		margin: 1.5rem 0;
		background: var(--shootcal-wrap-bg);
		border: 1px solid var(--shootcal-wrap-border);
		border-radius: var(--shootcal-wrap-radius);
		box-shadow: var(--shootcal-wrap-shadow);
		overflow: hidden;
		/* Self-contained sans-serif so the calendar reads consistently and does
		 * not inherit a theme's serif heading/body font. !important because
		 * themes set fonts with high-specificity selectors. */
		font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif !important;
		animation: shootcal-fade-in 0.35s ease both;
	}

	@keyframes shootcal-fade-in {
		from { opacity: 0; transform: translateY(4px); }
		to   { opacity: 1; transform: none; }
	}
	@media ( prefers-reduced-motion: reduce ) {
		.shootcal-web-calendar__wrap { animation: none; }
	}

	/* AJAX "Page caching" mode: placeholder shown until JS swaps in the calendar.
	 * Reuses the card chrome via the __wrap class. */
	.shootcal-web-calendar__lazy {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		gap: 0.9rem;
		/* Roughly a month-grid's height so the box "expands" to fill the
		 * calendar's footprint and the swap-in doesn't jump the layout. */
		min-height: 22rem;
		/* Gentle scale/fade so it eases open rather than snapping in. */
		animation: shootcal-lazy-expand 0.4s cubic-bezier( 0.22, 0.61, 0.36, 1 ) both;
	}
	/* Plain "Loading calendar…" text - no spinner. The swap-in is near-instant,
	 * and a spinner could be restyled into a strange shape by some themes /
	 * CSS optimizers, so the placeholder stays as simple centered text. */
	.shootcal-web-calendar__lazy-msg {
		margin: 0;
		color: var(--shootcal-muted);
		font-size: 0.95rem;
	}
	@keyframes shootcal-lazy-expand {
		from { opacity: 0; transform: scale( 0.96 ); }
		to   { opacity: 1; transform: scale( 1 ); }
	}
	@media ( prefers-reduced-motion: reduce ) {
		.shootcal-web-calendar__lazy { animation: none; }
	}

	/* --- Toolbar (Month Year | < Today >) --- */

	.shootcal-web-calendar__toolbar {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 1rem;
		padding: 0.85rem 1rem;
		border-bottom: 1px solid var(--shootcal-toolbar-border);
		background: var(--shootcal-wrap-bg);
	}

	.shootcal-web-calendar__nav-label {
		margin: 0;
		/* Set directly (not just inherited) and !important: this is an <h2>, and a
		 * theme's `h2 { font-family: <serif> }` is a direct match that would beat
		 * an inherited font from the wrap. */
		font-family: inherit !important;
		font-size: 1.4rem;
		font-weight: 800; /* heavier weight on the month name */
		color: var(--shootcal-label-fg);
		line-height: 1.1;
		letter-spacing: -0.02em;
	}

	/* Year accent in the toolbar label - matches the desktop app: signature
	 * sunset color, slightly smaller + lighter weight than the month name so
	 * the eye reads month first, year as supporting context. */
	.shootcal-web-calendar__nav-year {
		color: var(--shootcal-sunset);
		font-size: 0.82em;     /* ~82% of parent = ~1.15rem when label is 1.4rem */
		font-weight: 600;      /* lighter than the 800 month name */
		letter-spacing: -0.01em;
		margin-left: 0.1em;
	}

	/* Three discrete buttons grouped by a small gap. No shared pill container,
	 * no negative-offset outline tricks - keeps focus rings + active states
	 * from intersecting with sibling borders. */
	.shootcal-web-calendar__nav {
		display: inline-flex;
		align-items: stretch;
		gap: 0.3rem;
		flex-shrink: 0;
	}

	/* Themes style raw <button> elements (dark fills, shadows, uppercase), which
	 * would otherwise win over these. Force the light pill look with !important. */
	.shootcal-web-calendar__btn {
		font-family: inherit !important;
		font-size: 0.85rem;
		font-weight: 500;
		text-transform: none !important;
		letter-spacing: normal !important;
		background: #ffffff !important;
		color: var(--shootcal-btn-fg) !important;
		border: 1px solid var(--shootcal-btn-border) !important;
		border-radius: 6px !important;
		padding: 0.4rem 0.9rem;
		cursor: pointer;
		line-height: 1;
		transition: background 0.1s ease, color 0.1s ease;
		appearance: none;
		-webkit-appearance: none;
		box-shadow: none !important;
		text-shadow: none !important;
	}
	.shootcal-web-calendar__btn:hover:not(:disabled) {
		background: var(--shootcal-btn-hover-bg) !important;
		color: var(--shootcal-label-fg) !important;
	}
	.shootcal-web-calendar__btn:active:not(:disabled) {
		background: var(--shootcal-btn-active-bg) !important;
		color: var(--shootcal-label-fg) !important;
	}
	.shootcal-web-calendar__btn:focus-visible {
		outline: 2px solid var(--shootcal-btn-focus);
		outline-offset: 2px;
	}
	.shootcal-web-calendar__btn:disabled {
		opacity: 0.4;
		cursor: default;
	}

	.shootcal-web-calendar__btn--prev,
	.shootcal-web-calendar__btn--next {
		font-size: 1.1rem;
		padding: 9px 10px 10px 10px;
		min-width: 3rem;
		color: var(--shootcal-label-fg) !important;
	}

	/* Today button gets a brand-tinted hover/active state - subtle sunset wash
	 * so the user feels the connection between the button and "today" highlight
	 * in the grid. Uses rgba over the existing white bg. */
	.shootcal-web-calendar__btn--today:hover:not(:disabled) {
		background: rgba( var(--shootcal-sunset-rgb), 0.08 ) !important;
		border-color: rgba( var(--shootcal-sunset-rgb), 0.4 ) !important;
		color: var(--shootcal-sunset) !important;
	}
	.shootcal-web-calendar__btn--today:active:not(:disabled) {
		background: rgba( var(--shootcal-sunset-rgb), 0.16 ) !important;
		border-color: rgba( var(--shootcal-sunset-rgb), 0.55 ) !important;
	}

	/* --- Viewport / month grid --- */

	.shootcal-web-calendar__viewport { position: relative; }
	.shootcal-web-calendar__month-panel { display: block; }
	.shootcal-web-calendar__month-panel[hidden] { display: none; }

	.shootcal-web-calendar__wrap--paginated .shootcal-web-calendar__caption {
		display: none;
	}

	.shootcal-web-calendar--month {
		display: grid !important;
		grid-template-columns: 1fr !important;
	}

	.shootcal-web-calendar__caption {
		font-size: 1.15rem;
		font-weight: 600;
		color: var(--shootcal-label-fg);
		padding: 0.75rem 1rem;
		margin: 0;
		/* !important on all the grid divider lines: a theme reset like
		 * `* { border: 0 }` (Tailwind preflight, some normalize variants) would
		 * otherwise strip these non-important layered borders and the grid would
		 * lose its internal + closing lines. */
		border-bottom: 1px solid var(--shootcal-grid-line) !important;
	}

	/* Weekday header row */
	.shootcal-web-calendar__week--header {
		display: grid !important;
		grid-template-columns: repeat(7, minmax(0, 1fr)) !important;
		background: var(--shootcal-out-bg);
		border-bottom: 1px solid var(--shootcal-grid-line) !important;
	}
	.shootcal-web-calendar__weekday {
		font-size: 0.7rem;
		text-transform: uppercase;
		letter-spacing: 0.05em;
		font-weight: 600;
		color: var(--shootcal-muted);
		text-align: center;
		padding: 0.45rem 0;
	}
	.shootcal-web-calendar__weekday abbr,
	.shootcal-web-calendar__weekday abbr[title] {
		/* Browsers + themes give abbr[title] a dotted underline and a help
		 * (question-mark) cursor. Strip both; keep the title for accessibility. */
		text-decoration: none !important;
		border: none !important;
		cursor: default !important;
		font-weight: inherit;
	}

	/* Day rows */
	.shootcal-web-calendar__week {
		display: grid !important;
		grid-template-columns: repeat(7, minmax(0, 1fr)) !important;
	}
	.shootcal-web-calendar__week + .shootcal-web-calendar__week {
		border-top: 1px solid var(--shootcal-grid-line) !important;
	}

	/* --- Day cell (flat, no rounded pills, joined by 1px lines) ---
	 *
	 * Uses CSS Grid with three rows: date (auto) / status (auto) / a 1fr filler
	 * row that holds the bookings list. The bookings element is align-self:end
	 * inside that 1fr row, which RELIABLY pins it to the bottom of the cell
	 * regardless of whether sibling cells in the row force the cell to grow.
	 * This is more deterministic than the flex auto-margin trick (which can
	 * lose to theme CSS that flips the cell to display:block). */
	.shootcal-web-calendar__day {
		display: grid !important;
		grid-template-rows: auto auto 1fr !important;
		row-gap: 0;
		min-height: 5.5rem;
		min-width: 0;
		padding: 0.4rem 0.55rem 0.5rem;
		background: var(--shootcal-available-bg);
		color: var(--shootcal-available-fg);
		border-left: 1px solid var(--shootcal-grid-line) !important;
		box-sizing: border-box;
		position: relative !important;
		/* Themes can right-align text inside post content; keep cell text left. */
		text-align: left !important;
	}
	.shootcal-web-calendar__day:first-child { border-left: none !important; }

	/* Three busy states - the "peak" color comes from the per-embed pickers (or
	 * the built-in defaults); the cell renders at 0.8 opacity at rest and rises to
	 * 1.0 (full) on hover or when a popover is open. Computed via rgba() against
	 * the RGB triplet variables so override is a single style override. */
	.shootcal-web-calendar__day.is-booked {
		background: rgba( var(--shootcal-booked-bg-rgb), 0.8 );
		color: var(--shootcal-booked-fg);
		transition: background-color 0.12s ease;
	}
	.shootcal-web-calendar__day.is-limited {
		background: rgba( var(--shootcal-limited-bg-rgb), 0.8 );
		color: var(--shootcal-limited-fg);
		transition: background-color 0.12s ease;
	}
	/* On hover and when opened, the cells lift to 100% of their picked color. */
	.shootcal-web-calendar__day.is-booked:hover {
		background: rgba( var(--shootcal-booked-bg-rgb), 1 );
	}
	.shootcal-web-calendar__day.is-limited:hover,
	.shootcal-web-calendar__day.is-limited.is-open,
	.shootcal-web-calendar__day.is-limited.is-open-above {
		background: rgba( var(--shootcal-limited-bg-rgb), 1 );
	}

	/* Out-of-month cells render their events with the same state coloring as
	 * in-month cells (matches the macOS app's month view). The only visual
	 * cue that a cell belongs to a different month is the muted date number. */
	.shootcal-web-calendar__day.is-out-of-month .shootcal-web-calendar__date {
		color: var(--shootcal-muted);
		font-weight: 500;
	}
	.shootcal-web-calendar__day.is-past {
		background: var(--shootcal-past-bg);
		color: var(--shootcal-past-fg);
	}
	.shootcal-web-calendar__day.is-past .shootcal-web-calendar__date {
		font-weight: 500;
	}

	/* Today: just color the date number in the brighter sunset-vivid so it
	 * pops at small sizes. No background bubble (was distorting cell layout). */
	.shootcal-web-calendar__day.is-today .shootcal-web-calendar__date {
		color: var(--shootcal-sunset-vivid);
		font-weight: 700;
	}

	/* Date number - explicit BLOCK so date + status always stack regardless of
	 * any inherited inline rules from the theme. Mandatory bottom margin
	 * gives the chip room to breathe. */
	.shootcal-web-calendar__date {
		display: block;
		font-weight: 600;
		font-size: 0.95rem;
		line-height: 1.2;
		margin: 0 0 0.3rem; /* the "bit of padding below the date number" */
	}

	/* Status chip - small uppercase label below the date */
	.shootcal-web-calendar__status {
		display: block;
		font-size: 0.6rem;
		text-transform: uppercase;
		letter-spacing: 0.06em;
		font-weight: 700;
		opacity: 0.85; /* was 0.7 - lifted so the status label keeps AA contrast */
		line-height: 1;
	}

	/* Hide the visible status word on Available and Limited days: emptiness is
	 * the cue for Available, and on Limited days the booked times + amber tint +
	 * legend already say "Limited". Booked days keep their label (they have no
	 * times, so the word is their only on-cell cue). The cell's aria-label still
	 * announces the status for screen readers in every case. */
	.shootcal-web-calendar__day.is-available .shootcal-web-calendar__status,
	.shootcal-web-calendar__day.is-limited .shootcal-web-calendar__status {
		display: none;
	}

	/* Bookings list sits in the cell's 1fr grid row and aligns to its end -
	 * this is the deterministic "pin to bottom" mechanism. The `padding-top`
	 * gives the list a touch of breathing room visually inside its track.
	 * The `li` rules explicitly reset font-family / background / list-style
	 * so theme CSS that targets generic `ul`/`li` in post content can't make
	 * the booked times look like a code block or get a default bullet. */
	.shootcal-web-calendar__bookings {
		grid-row: 3 !important;
		align-self: end !important;
		list-style: none !important;
		list-style-type: none !important;
		margin: 0 !important;
		padding: 0.3rem 0 0 !important;
		font-size: 0.7rem;
		line-height: 1.4;
		font-weight: 500;
		font-family: inherit;
		background: transparent;
		text-align: left !important;
	}
	.shootcal-web-calendar__bookings li {
		margin: 0 0 3px;
		padding: 0;
		background: transparent;
		color: inherit;
		font-family: inherit;
		opacity: 0.85;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
		min-width: 0;
		list-style: none;
	}
	.shootcal-web-calendar__bookings li:last-child { margin-bottom: 0; }
	.shootcal-web-calendar__bookings li::before {
		content: none !important; /* defeat any theme rule that injects bullet glyphs */
	}

	/* "+N more" overflow: a cell shows up to 2 booking times inline plus a
	 * "+N more" hint; the open popover reveals the rest and hides the hint, so
	 * busy days keep a uniform cell height. */
	.shootcal-web-calendar__booking--overflow { display: none; }
	.shootcal-web-calendar__booking--more {
		opacity: 0.8;
		font-weight: 600;
	}
	.shootcal-web-calendar__day.is-open .shootcal-web-calendar__booking--overflow { display: list-item; }
	.shootcal-web-calendar__day.is-open .shootcal-web-calendar__booking--more { display: none; }

	/* --- Click-to-expand popover (all viewports) ---
	 *
	 * When a Limited cell is tapped, the cell visually "lifts" - rounded
	 * corners on top, a slight shadow above - and the bookings list pops
	 * out below as a matching rounded tail with the same background color.
	 * Together they look like one tall rounded card holding the day's
	 * full booking detail. The cell stays in its grid position so the rest
	 * of the layout doesn't shift; only the bookings overlap downward.
	 */

	/* Tappable affordance on cells with bookings. Hover/active states are
	 * handled by the 0.8 -> 1.0 alpha shift above; cursor change is all the
	 * extra hint that's needed. */
	.shootcal-web-calendar__day.is-limited {
		cursor: pointer;
	}

	/* Let the popover tail extend past the card's rounded clip. */
	.shootcal-web-calendar__wrap { overflow: visible; }

	/* Because the wrap is overflow:visible (so the popover can escape), it can't
	 * clip its children to the rounded corners the way overflow:hidden would.
	 * Without help, the first child (toolbar) and last child (legend/credit) are
	 * plain rectangles whose square corners poke past the card's rounded border,
	 * making the corners look "cut off." Round their outer corners to match the
	 * card so the corners stay clean. Inner radius = card radius minus the 1px
	 * border so the child nests exactly inside the border's curve. */
	.shootcal-web-calendar__wrap > :first-child {
		border-top-left-radius: calc(var(--shootcal-wrap-radius) - 1px);
		border-top-right-radius: calc(var(--shootcal-wrap-radius) - 1px);
	}
	.shootcal-web-calendar__wrap > :last-child {
		border-bottom-left-radius: calc(var(--shootcal-wrap-radius) - 1px);
		border-bottom-right-radius: calc(var(--shootcal-wrap-radius) - 1px);
	}

	/* Cell in open state: lifted via z-index. No border-radius trick anymore -
	 * the popover is now a standalone floating card (wider than the cell, can
	 * be horizontally nudged at the calendar edges) so trying to "join" it to
	 * the cell with matching radii doesn't align. The popover's own shadow +
	 * the cell's color shift carry the visual association. */
	.shootcal-web-calendar__day.is-open {
		z-index: 25 !important;
	}

	/* Bookings becomes the "tail" - extends BELOW the cell.
	 * Explicit background-color per cell state so the popover is fully opaque
	 * and visually covers the row below it (no see-through onto neighbors).
	 * !important on the structural pieces so theme CSS can't break positioning.
	 *
	 * Sizing: the popover is allowed to grow WIDER than its cell so booking
	 * times like "Booked 7:30 pm - 8:30 pm" stay on a single line. It's centered
	 * under the cell; JS measures after opening and nudges the transform
	 * horizontally if it would overflow the calendar card's edges. min-width:
	 * 100% guarantees it never gets narrower than the cell on wide layouts. */
	.shootcal-web-calendar__day.is-open .shootcal-web-calendar__bookings {
		display: block !important;
		position: absolute !important;
		top: calc(100% + 4px) !important;  /* small gap so it reads as a floating card */
		bottom: auto !important;
		left: 50% !important;
		right: auto !important;
		transform: translateX(-50%);
		min-width: 100%;
		width: max-content;
		max-width: 16rem;
		margin: 0 !important;
		/* !important required: the base .__bookings rule sets padding with
		 * !important (for theme defense), so the popover's padding must also be
		 * !important to win, otherwise the bubble loses its left/right padding. */
		padding: 1rem 1.5rem !important;
		text-align: center !important;
		background-color: rgba( var(--shootcal-limited-bg-rgb), 1 );
		color: var(--shootcal-limited-fg);
		border-radius: 10px;
		box-shadow: 0 12px 24px -6px rgba(0, 0, 0, 0.28),
		            0 0 0 1px var(--shootcal-grid-line);
		font-size: 0.78rem;
		font-weight: 500;
		line-height: 1.4;
		z-index: 25 !important;
	}
	/* Booked state - keep the popover in the cell's color family even though
	 * Booked cells aren't currently interactive. Future-proof. */
	.shootcal-web-calendar__day.is-booked.is-open .shootcal-web-calendar__bookings {
		background-color: rgba( var(--shootcal-booked-bg-rgb), 1 );
		color: var(--shootcal-booked-fg);
	}

	/* Flip the popover ABOVE the cell when JS detects last-row position.
	 * Same standalone-card chrome, just inverted vertical direction. */
	.shootcal-web-calendar__day.is-open-above .shootcal-web-calendar__bookings {
		top: auto !important;
		bottom: calc(100% + 4px) !important;
		border-radius: 10px;
		box-shadow: 0 -12px 24px -6px rgba(0, 0, 0, 0.28),
		            0 0 0 1px var(--shootcal-grid-line);
	}

	/* Each booking line breaks naturally - no truncation when popped open. */
	.shootcal-web-calendar__day.is-open .shootcal-web-calendar__bookings li {
		white-space: normal;
		overflow: visible;
		text-overflow: clip;
		opacity: 1;
		margin: 0 0 0.3rem;
	}
	.shootcal-web-calendar__day.is-open .shootcal-web-calendar__bookings li:last-child {
		margin-bottom: 0;
	}

	/* --- Mobile sizing --- */
	@media (max-width: 600px) {
		.shootcal-web-calendar__toolbar {
			padding: 0.65rem;
		}
		.shootcal-web-calendar__nav-label {
			font-size: 1.1rem;
		}
		.shootcal-web-calendar__day {
			min-height: 3.5rem;
			padding: 0.3rem;
		}
		.shootcal-web-calendar__date { font-size: 0.85rem; margin-bottom: 0.2rem; }
		.shootcal-web-calendar__weekday { font-size: 0.6rem; padding: 0.3rem 0; }
		.shootcal-web-calendar__status { font-size: 0.55rem; }
		.shootcal-web-calendar__btn { padding: 0.35rem 0.6rem; font-size: 0.8rem; }
		.shootcal-web-calendar__btn--prev,
		.shootcal-web-calendar__btn--next { padding: 0.3rem 0.55rem; font-size: 1rem; }

		/* On phones the inline bookings list would just be a single ellipsed
		 * line - hide it. Users tap to see the full popover instead. */
		.shootcal-web-calendar__bookings { display: none; }

		/* Since the times are hidden on phones, show a small dot on Limited days
		 * so visitors know the cell is tappable for the booked times. (Booked days
		 * keep their "BOOKED" label; Available days have nothing to show.) */
		.shootcal-web-calendar__day.is-limited::after {
			content: '';
			position: absolute;
			left: 50%;
			bottom: 6px;
			transform: translateX(-50%);
			width: 6px;
			height: 6px;
			border-radius: 50%;
			background: var(--shootcal-sunset);
		}
		.shootcal-web-calendar__day.is-limited.is-open::after { display: none; }

		/* Tighter popover padding on phones. !important to beat the base
		 * .__bookings padding rule (itself !important for theme defense). */
		.shootcal-web-calendar__day.is-open .shootcal-web-calendar__bookings {
			font-size: 0.72rem;
			padding: 0.7rem 0.85rem !important;
		}
	}

	/* --- No-JS fallback --- */
	.no-js .shootcal-web-calendar__month-panel,
	.no-js .shootcal-web-calendar__month-panel[hidden] {
		display: block !important;
	}
	.no-js .shootcal-web-calendar__toolbar { display: none; }
	.no-js .shootcal-web-calendar__wrap--paginated .shootcal-web-calendar__caption {
		display: block;
	}

	/* --- Legend (color key) ---
	 *
	 * This is a <ul> of <li>s, so it is exposed to any theme rule on `ul`/`li`
	 * in the post-content area (list margins, left padding, bullets, display
	 * flips). Because the whole plugin sits in @layer, those UNLAYERED theme
	 * rules win over normal layered declarations - so the box-model + list
	 * properties here are pinned with !important, matching how the toolbar and
	 * day cells defend themselves. Colors/typography stay overridable. */
	.shootcal-web-calendar__legend {
		display: flex !important;
		flex-wrap: wrap !important;
		align-items: center;
		gap: 0.4rem 1.4rem;
		margin: 0 !important;
		padding: 0.75rem 1rem !important;
		list-style: none !important;
		/* The line ABOVE the legend - closes the bottom of the grid. !important so
		 * a theme `ul { border: 0 }` reset can't strip it. */
		border-top: 1px solid var(--shootcal-grid-line) !important;
		font-size: 0.85rem;
		color: var(--shootcal-muted);
	}
	.shootcal-web-calendar__legend-item {
		display: inline-flex !important;
		align-items: center;
		gap: 0.4rem;
		margin: 0 !important;
		padding: 0 !important;
		list-style: none !important;
	}
	/* Defeat any theme rule that injects list bullets via ::before/::marker. */
	.shootcal-web-calendar__legend-item::before { content: none !important; }
	.shootcal-web-calendar__legend-item::marker { content: "" !important; }
	.shootcal-web-calendar__legend-swatch {
		display: inline-block !important;
		width: 1rem !important;
		height: 1rem !important;
		border-radius: 3px;
		flex-shrink: 0;
		box-sizing: border-box;
	}
	.shootcal-web-calendar__legend-swatch--available {
		background: var(--shootcal-available-bg);
		box-shadow: inset 0 0 0 1px var(--shootcal-grid-line);
	}
	.shootcal-web-calendar__legend-swatch--limited {
		background: rgba( var(--shootcal-limited-bg-rgb), 1 );
	}
	.shootcal-web-calendar__legend-swatch--booked {
		background: rgba( var(--shootcal-booked-bg-rgb), 1 );
	}

	/* --- Attribution ---
	 * This is a <p>, so a theme rule like `.entry-content p { padding: 0 }`
	 * (unlayered) would otherwise win over the layered padding and the text
	 * would run to the card's right edge. Pin the box-model + alignment with
	 * !important; leave color/size overridable. */
	.shootcal-web-calendar__credit {
		margin: 0 !important;
		padding: 0.5rem 1rem 0.55rem !important;
		font-size: 0.7rem;
		line-height: 1.4;
		color: var(--shootcal-credit-fg);
		text-align: right !important;
		/* The line BELOW the legend (separating it from the credit). !important so
		 * a theme `p { border: 0 }` reset can't strip it. */
		border-top: 1px solid var(--shootcal-grid-line) !important;
		background: var(--shootcal-out-bg);
		box-sizing: border-box;
	}
	.shootcal-web-calendar__credit a {
		color: inherit;
		text-decoration: underline;
		text-decoration-style: dotted;
		text-underline-offset: 2px;
	}
	.shootcal-web-calendar__credit a:hover,
	.shootcal-web-calendar__credit a:focus-visible {
		color: var(--shootcal-sunset);
	}

	/* Screen-reader only */
	.shootcal-web-calendar__sr-only {
		position: absolute;
		width: 1px;
		height: 1px;
		padding: 0;
		margin: -1px;
		overflow: hidden;
		clip: rect(0,0,0,0);
		white-space: nowrap;
		border: 0;
	}

} /* end @layer shootcal-web-calendar */

/* ----------------------------------------------------------------------------
 * Full-calendar mode (mode="full") — list each event's time + title per day
 * instead of free/busy shading. Activated by the --full container modifier.
 * Cells carry no is-booked/is-limited/is-available class, so they keep the
 * neutral "available" background; the event chips are a neutral gray.
 * ------------------------------------------------------------------------- */
.shootcal-web-calendar--full .shootcal-web-calendar__events {
	grid-row: 2 / span 2 !important;
	list-style: none !important;
	margin: 0.1rem 0 0 !important;
	padding: 0 !important;
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
	min-width: 0;
	align-self: start;
}
.shootcal-web-calendar--full .shootcal-web-calendar__event {
	list-style: none !important;
	margin: 0 !important;
	padding: 0.1rem 0.32rem !important;
	background: rgba( 0, 0, 0, 0.05 );
	border-radius: 5px;
	font-size: 0.66rem;
	line-height: 1.25;
	color: var(--shootcal-label-fg);
	overflow-wrap: anywhere;
	text-indent: 0 !important;
}
.shootcal-web-calendar--full .shootcal-web-calendar__event::before { content: none !important; }
.shootcal-web-calendar--full .shootcal-web-calendar__event-time {
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	margin-right: 0.25rem;
	white-space: nowrap;
}
.shootcal-web-calendar--full .shootcal-web-calendar__event-title {
	color: var(--shootcal-muted);
}
.shootcal-web-calendar--full .shootcal-web-calendar__day.is-past .shootcal-web-calendar__events {
	opacity: 0.55;
}
@media (max-width: 600px) {
	.shootcal-web-calendar--full .shootcal-web-calendar__event { font-size: 0.58rem; padding: 0.06rem 0.22rem !important; }
}
