/*
 * Floating Book Now button.
 *
 * A small pill in the bottom left corner on phones and tablets. Inherited from
 * an earlier theme, where it was a round call button, and kept as a pill here
 * because "Book" has to be readable: a lash appointment is booked, not called
 * in, so an unlabelled icon would be a guess.
 *
 * Deliberately not a full-width bar. A bar costs around 88px of every mobile
 * screen, lands directly on top of whatever call to action the page already
 * has, and reads as an advertisement bolted to the page rather than a control
 * belonging to it.
 *
 * Two things are load-bearing here and are covered by tests/layout-contract:
 *
 *   --labco-booking-height   the button's measured height, published by
 *                            booking-button.js. The page's bottom padding is
 *                            derived from it, so the button can never cover
 *                            the last stripe of a page whatever the visitor's
 *                            text size.
 *   --labco-consent-height   the consent banner's measured height, published
 *                            by the banner's own script while it is visible.
 *                            The button rides above the banner instead of the
 *                            banner dodging the button, because the banner is
 *                            full width and transient while the button is
 *                            small and permanent.
 *
 * Each variable has exactly one writer. Two files setting the same figure is
 * how the 64px-versus-88px bug survived review in the theme this descends from.
 */

:root {
	/* Distance from the viewport edges, before any safe-area inset. */
	--labco-booking-gap: 16px;
	--labco-booking-size: 52px;
}

.labco-sticky-booking-button {
	display: none;
	position: fixed;
	left: calc(var(--labco-booking-gap) + env(safe-area-inset-left, 0px));

	/*
	 * env() keeps the button clear of the iPhone home indicator. The consent
	 * height is 0px unless the banner is actually on screen, so this resolves
	 * to the plain corner position in the usual case.
	 */
	bottom: calc(
		var(--labco-booking-gap)
		+ env(safe-area-inset-bottom, 0px)
		+ var(--labco-consent-height, 0px)
	);
	z-index: 1000;
	transition: bottom 220ms ease-out;
}

.labco-sticky-booking-button.is-mobile {
	display: block;
}

/*
 * Every rule below is scoped to the container, and that is not decoration.
 *
 * style.css styles every phone and mail link on the site, and on a phone it
 * does this:
 *
 *     a[href^="tel:"], a[href^="mailto:"] {
 *         display: inline-block;
 *         padding-block: 13px;
 *         margin-block: -13px;
 *     }
 *
 * An attribute selector plus an element is specificity (0,1,1), which beats a
 * bare class at (0,1,0). So `.labco-booking-link` would lose: display:flex
 * overridden, leaving the icon at the top left of the box instead of centred,
 * and 26px of vertical padding turning the pill into an oval. Scoping to
 * `.labco-sticky-booking-button .labco-booking-link` is (0,2,0), which wins
 * regardless of which stylesheet WordPress prints first -- and load order is
 * not something this file should have to bet on.
 *
 * padding and margin are set explicitly rather than trusted to be unset,
 * because the rule above sets both and something has to undo them by name.
 */
.labco-sticky-booking-button .labco-booking-link {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	box-sizing: border-box;
	min-height: var(--labco-booking-size);
	padding: 0 20px 0 16px;
	margin: 0;
	border-radius: 999px;
	background: #12100f;
	color: #f5edeb;
	text-decoration: none;
	line-height: 1;
	font-family: Inter, "Helvetica Neue", Arial, sans-serif;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;

	/*
	 * The blush ring is what lets the pill sit on a photograph. Without it the
	 * dark shape disappears into any dark hero image, and a booking button
	 * nobody can see is worse than no booking button at all.
	 */
	box-shadow:
		0 0 0 3px rgba(245, 237, 235, 0.7),
		0 6px 18px rgba(17, 16, 16, 0.32);
	animation: labcoBookingIn 320ms cubic-bezier(0.16, 1, 0.3, 1) both;
	transition: transform 160ms ease-out, box-shadow 160ms ease-out, background 160ms ease-out;
	touch-action: manipulation;
	-webkit-tap-highlight-color: transparent;
}

.labco-sticky-booking-button .labco-booking-link:hover,
.labco-sticky-booking-button .labco-booking-link:focus {
	background: #8a5d55;
	color: #fff;
	transform: translateY(-2px);
	box-shadow:
		0 0 0 3px rgba(245, 237, 235, 0.85),
		0 10px 24px rgba(17, 16, 16, 0.36);
}

.labco-sticky-booking-button .labco-booking-link:active {
	transform: scale(0.96);
}

.labco-sticky-booking-button .labco-booking-link:focus-visible {
	outline: 3px solid #f5edeb;
	outline-offset: 3px;
}

.labco-sticky-booking-button .labco-booking-icon {
	display: block;
	flex: none;
	width: 20px;
	height: 20px;
}

.labco-sticky-booking-button .labco-booking-text {
	display: block;
	white-space: nowrap;
}

/*
 * One ring, three times, then still.
 *
 * Enough to catch the eye of somebody scanning the page, and few enough that
 * it is not still twitching at a visitor trying to read the treatment menu.
 * pointer-events: none so the ring can never swallow the tap it advertises.
 */
.labco-sticky-booking-button .labco-booking-link::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 999px;
	border: 2px solid #8a5d55;
	animation: labcoBookingPulse 2s ease-out 1.2s 3 both;
	pointer-events: none;
}

@keyframes labcoBookingIn {
	from {
		opacity: 0;
		transform: translateY(16px) scale(0.9);
	}

	to {
		opacity: 1;
		transform: translateY(0) scale(1);
	}
}

@keyframes labcoBookingPulse {
	0% {
		opacity: 0.5;
		transform: scale(1);
	}

	70%,
	100% {
		opacity: 0;
		transform: scale(1.35);
	}
}

@media (max-width: 768px) {
	.labco-sticky-booking-button {
		display: block;
	}

	/*
	 * Reserve the button's corner so it cannot cover the end of a page.
	 *
	 * The height comes from the button's measured offsetHeight rather than a
	 * literal, because a visitor running larger text gets a larger button and
	 * a hardcoded figure would quietly go wrong for exactly the people least
	 * able to work around it. The fallback matches the shipped size.
	 */
	body.has-sticky-booking {
		padding-bottom: calc(
			var(--labco-booking-height, 52px)
			+ var(--labco-booking-gap) * 2
			+ env(safe-area-inset-bottom, 0px)
		);
	}
}

@media (min-width: 769px) {
	/*
	 * Desktop carries a Book Now button in the header, so the floating one is
	 * deliberately absent. !important because a style variation should not be
	 * able to bring it back by accident.
	 */
	.labco-sticky-booking-button {
		display: none !important;
	}

	body {
		padding-bottom: 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.labco-sticky-booking-button {
		transition: none;
	}

	.labco-sticky-booking-button .labco-booking-link {
		animation: none;
		transition: none;
	}

	.labco-sticky-booking-button .labco-booking-link:hover,
	.labco-sticky-booking-button .labco-booking-link:focus {
		transform: none;
	}

	.labco-sticky-booking-button .labco-booking-link::after {
		animation: none;
		display: none;
	}
}

@media print {
	.labco-sticky-booking-button {
		display: none !important;
	}
}
