/* ===========================================================================
   Mobile bottom navigation, its category sheet, and the product page's
   sticky add-to-cart bar.  <= 768px ONLY.

   EVERY RULE IN THIS FILE LIVES INSIDE `@media (max-width: 768px)`, and that
   is the desktop guarantee rather than a tidiness preference: there is no
   selector here that a viewport above 768px can ever match, so "desktop is
   unchanged" is true by construction and the geometry proof only has to
   confirm it rather than discover it.

   The two custom properties are declared on `body`, not on `:root`, for the
   same reason - a `:root` declaration would exist at every width.
   =========================================================================== */

/*
 * THE ONE RULE ABOVE 768px, AND IT HAS TO EXIST.
 *
 * The markup is rendered by PHP, which cannot know the viewport width, so the
 * bar, its sheet and the sticky cart are in the document at every width. Left
 * unstyled on a desktop they fall into normal flow at the end of the body as
 * five stacked links - measured before this rule, the homepage gained
 * horizontal overflow at 1024 and 1440.
 *
 * "Desktop is unchanged" survives intact, because all three selectors name
 * elements that did not exist before this feature: nothing pre-existing is
 * matched, moved or hidden by it.
 */
@media (min-width: 769px) {
	.ml-bnav,
	.ml-bnav-sheet,
	.ml-stickycart {
		display: none;
	}
}

@media (max-width: 768px) {

	body.medlife-has-bnav {
		--ml-bnav-h: 60px;
		--ml-bnav-safe: env(safe-area-inset-bottom, 0px);

		/*
		 * The bar is `position: fixed`, so it is out of flow and would sit on
		 * top of the last thing on the page - the footer's bottom bar. This
		 * reserves exactly its height, and it is keyed on the body class
		 * rather than applied unconditionally because checkout and the pharma
		 * pages render no bar and must not reserve space for one.
		 */
		padding-bottom: calc(var(--ml-bnav-h) + var(--ml-bnav-safe));
	}

	/* -------------------------------------------------------------- the bar */

	.ml-bnav {
		position: fixed;
		right: 0;
		bottom: 0;
		left: 0;

		/*
		 * 40 IS DELIBERATELY BELOW EVERYTHING THE HEADER OWNS.
		 * `.medlife-header` is 60 at this width (header.css), the open burger
		 * menu 59 (nav.css:511) and `.medlife-nav__panel` 60 - so the bar
		 * lands underneath an open menu or search panel with no edit to any
		 * of those files. Raising this number is what would break requirement
		 * D4; do not "fix" a stacking question here.
		 */
		z-index: 40;

		display: flex;
		align-items: stretch;
		height: calc(var(--ml-bnav-h) + var(--ml-bnav-safe));
		padding-bottom: var(--ml-bnav-safe);
		background: var(--ml-white);
		border-top: 1px solid var(--ml-line);
		box-shadow: 0 -2px 10px rgba(var(--ml-shadow-tint), 0.07);
	}

	/*
	 * Hidden while a field has focus (the on-screen keyboard is up) and while
	 * the sticky cart bar has taken its place. `visibility` rather than
	 * `display` so the slide has something to animate; `pointer-events: none`
	 * so a hidden bar cannot swallow a tap aimed at the form underneath it.
	 */
	.ml-bnav.is-hidden,
	.ml-bnav.is-swapped {
		visibility: hidden;
		pointer-events: none;
		transform: translateY(100%);
	}

	.ml-bnav {
		transition:
			transform var(--ml-t-base) var(--ml-e-standard),
			visibility var(--ml-t-base) var(--ml-e-standard);
	}

	/* ------------------------------------------------------------- the items */

	/*
	 * THE REST RULE IS (0,2,0) ON PURPOSE, not (0,1,0).
	 *
	 * Three of the five items are bare `<button>` elements, and Astra's inline
	 * Customizer CSS repaints `button:hover`, `button:focus` and
	 * `input:focus` at (0,1,1). A rest rule keeps matching in every state, so
	 * (0,2,0) is immune to all three at once and no separate pin is needed for
	 * the fill. `.ml-bnav .ml-bnav__item` gets there with no extra markup.
	 *
	 * `padding: 0` and `box-shadow: none` are the other half of the same trap:
	 * Astra gives every bare button `padding: 10px 20px`, `border-radius: 30px`
	 * and `box-shadow: 0 1px 2px rgba(0,0,0,.05)`, and A RULE WINS ONLY THE
	 * PROPERTIES IT NAMES - staying silent about the shadow is exactly what put
	 * a white box behind each banner dot.
	 */
	.ml-bnav .ml-bnav__item {
		position: relative;
		flex: 1 1 0;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		gap: 3px;

		min-width: 0;
		min-height: 44px;
		margin: 0;
		padding: 0;

		border: 0;
		border-radius: 0;
		background: none;
		box-shadow: none;

		font-family: inherit;
		font-size: 11px;
		font-weight: 500;
		line-height: 1.2;
		letter-spacing: 0;
		text-align: center;
		text-decoration: none;
		text-transform: none;
		color: var(--ml-muted);
		cursor: pointer;
		-webkit-tap-highlight-color: transparent;
	}

	.ml-bnav .ml-bnav__item.is-active {
		color: var(--ml-cyan);
	}

	/* the 2px cyan mark above the icon - only the current item carries it */
	.ml-bnav .ml-bnav__rule {
		position: absolute;
		top: 0;
		left: 50%;
		width: 26px;
		height: 2px;
		border-radius: 0 0 2px 2px;
		background: transparent;
		transform: translateX(-50%);
	}

	.ml-bnav .ml-bnav__item.is-active .ml-bnav__rule {
		background: var(--ml-cyan);
	}

	.ml-bnav .ml-bnav__icon {
		position: relative;
		display: flex;
		align-items: center;
		justify-content: center;
		width: 22px;
		height: 22px;
		color: inherit;
	}

	.ml-bnav .ml-bnav__icon svg {
		display: block;
		width: 22px;
		height: 22px;
	}

	.ml-bnav .ml-bnav__label {
		display: block;
		max-width: 100%;
		overflow: hidden;
		white-space: nowrap;      /* "label 11px, ek line" */
		text-overflow: ellipsis;
	}

	/*
	 * NAME THE TRANSITION, BECAUSE ASTRA'S `all` REACHES THE FOCUS RING.
	 *
	 * Every item is an `<a>`, so Astra's inline `a { transition: all .2s
	 * linear }` applies to any item that names no transition of its own - and
	 * "all" includes `outline`. Measured under emulated reduced motion after a
	 * REAL tap: `color` and `outline-width` both running on the item. The ink
	 * change is wanted (2.3.3 is about motion, not a tint, and this file's own
	 * reduced-motion note says so); the ring growing is not.
	 *
	 * Naming `color` alone removes `outline` from the list, which is the fix
	 * this theme's ring-fade pass already prescribes for 32 other families.
	 * Nothing is ADDED here, so there is no reduced-motion twin to write: the
	 * one property left is a tint, which that block deliberately keeps.
	 *
	 * A SETTLED READ CANNOT SEE THIS, and neither can `forcePseudoState`: both
	 * reported "no fade" on this very control while a real tap showed the
	 * transition running.
	 */
	.ml-bnav .ml-bnav__item {
		transition: color var(--ml-t-base) var(--ml-e-standard);
	}

	/* press feedback - the icon only, so the row's geometry never moves */
	.ml-bnav .ml-bnav__item .ml-bnav__icon {
		transition:
			transform var(--ml-t-base) var(--ml-e-standard),
			opacity var(--ml-t-base) var(--ml-e-standard);
	}

	.ml-bnav .ml-bnav__item:active .ml-bnav__icon {
		transform: scale(0.88);
		opacity: 0.7;
	}

	/*
	 * THE POINTER PIN, and it is the whole reason a tap leaves no ring.
	 * `:not(:focus-visible)` matches pointer focus only, so the keyboard ring
	 * below is untouched. Placed before it, per the house order
	 * rest -> pin -> states -> ring.
	 */
	.ml-bnav .ml-bnav__item:focus:not(:focus-visible) {
		outline: none;
		color: var(--ml-muted);
	}

	.ml-bnav .ml-bnav__item.is-active:focus:not(:focus-visible) {
		color: var(--ml-cyan);
	}

	/*
	 * THE RING IS INSET (`-3px`), not the usual `+3px`.
	 * The items are flush to each other and to the bar's own top border, so an
	 * outward ring would be clipped by the bar's edge on one side and would
	 * paint over its neighbour on the other - less visible, which is the
	 * opposite of the intent. The six controls that already draw inside their
	 * box in this theme use the same negative offset.
	 */
	.ml-bnav .ml-bnav__item:focus-visible {
		outline: 3px solid var(--ml-cyan);
		outline-offset: -3px;
	}

	/* the TI Wishlist counter, on the icon rather than beside the label */
	.ml-bnav .ml-bnav__icon .medlife-badge {
		position: absolute;
		top: -5px;
		right: -9px;
		min-width: 16px;
		height: 16px;
		padding: 0 4px;
		border-radius: 999px;
		background: var(--ml-cyan);
		color: var(--ml-white);
		font-size: 10px;
		font-weight: 600;
		line-height: 16px;
		text-align: center;
	}

	/* ------------------------------------------------------ the category sheet */

	/*
	 * A native <dialog>. `showModal()` supplies Escape, the focus trap, the
	 * inert background and focus restoration; what is written here is only the
	 * geometry and the scrim, which the element does not give you.
	 *
	 * `dialog:not([open])` is `display: none` in every UA stylesheet, so no
	 * rule is needed for the closed state.
	 */
	.ml-bnav-sheet {
		position: fixed;
		inset: auto 0 0 0;
		width: 100%;
		max-width: 100%;
		max-height: 86vh;
		margin: 0;
		padding: 0;
		border: 0;
		background: transparent;
		overflow: visible;
	}

	.ml-bnav-sheet::backdrop {
		background: rgba(var(--ml-navy-rgb, 10, 37, 64), 0.55);
	}

	.ml-bnav-sheet__panel {
		max-height: 86vh;
		overflow-y: auto;
		padding: 10px 16px calc(18px + env(safe-area-inset-bottom, 0px));
		background: var(--ml-white);
		border-radius: 18px 18px 0 0;
		box-shadow: 0 -10px 30px rgba(var(--ml-shadow-tint), 0.18);
	}

	.ml-bnav-sheet[open] .ml-bnav-sheet__panel {
		animation: ml-bnav-sheet-in var(--ml-t-panel) var(--ml-e-enter);
	}

	@keyframes ml-bnav-sheet-in {
		from { transform: translateY(100%); }
		to   { transform: translateY(0); }
	}

	.ml-bnav-sheet__handle {
		display: block;
		width: 40px;
		height: 4px;
		margin: 0 auto 12px;
		border-radius: 999px;
		background: var(--ml-line);
	}

	.ml-bnav-sheet__head {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 12px;
		margin-bottom: 16px;
	}

	.ml-bnav-sheet .ml-bnav-sheet__title {
		margin: 0;
		font-size: 17px;
		font-weight: 600;
		line-height: 1.3;
		color: var(--ml-navy);
	}

	/* same Astra reset as the bar's buttons, at the same (0,2,0) tier */
	.ml-bnav-sheet .ml-bnav-sheet__close {
		display: flex;
		align-items: center;
		justify-content: center;
		flex: 0 0 auto;
		width: 40px;
		height: 40px;
		margin: 0;
		padding: 0;
		border: 0;
		border-radius: 999px;
		background: var(--ml-stage-soft);
		box-shadow: none;
		color: var(--ml-navy);
		cursor: pointer;
		-webkit-tap-highlight-color: transparent;
	}

	.ml-bnav-sheet .ml-bnav-sheet__close:focus:not(:focus-visible) {
		outline: none;
		background: var(--ml-stage-soft);
		color: var(--ml-navy);
	}

	.ml-bnav-sheet .ml-bnav-sheet__close:focus-visible {
		outline: 3px solid var(--ml-cyan);
		outline-offset: 3px;
	}

	.ml-bnav-sheet__grid {
		display: grid;
		grid-template-columns: repeat(3, minmax(0, 1fr));   /* "3-column grid" */
		gap: 14px 10px;
		margin: 0;
		padding: 0;
		list-style: none;
	}

	.ml-bnav-sheet__item {
		margin: 0;
		padding: 0;
	}

	.ml-bnav-sheet__item::before {
		content: none;     /* the policy shell's cyan bullet must not reach here */
	}

	.ml-bnav-sheet .ml-bnav-sheet__link {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 8px;
		min-height: 44px;
		padding: 10px 4px;
		border-radius: 12px;
		text-align: center;
		text-decoration: none;
		color: var(--ml-navy);
	}

	.ml-bnav-sheet .ml-bnav-sheet__link:focus:not(:focus-visible) {
		outline: none;
		color: var(--ml-navy);
		text-decoration: none;
	}

	.ml-bnav-sheet .ml-bnav-sheet__link:focus-visible {
		outline: 3px solid var(--ml-cyan);
		outline-offset: 3px;
	}

	.ml-bnav-sheet__icon {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 64px;
		height: 64px;
	}

	.ml-bnav-sheet__icon .ml-bnav-sheet__img,
	.ml-bnav-sheet__icon .ml-cats__fallback {
		display: block;
		width: 100%;
		height: 100%;
		object-fit: contain;
	}

	.ml-bnav-sheet__label {
		display: block;
		font-size: 12.5px;
		font-weight: 500;
		line-height: 1.3;
		color: var(--ml-navy);
	}

	/* ------------------------------------------- the product sticky cart bar */

	/*
	 * It takes the bar's own place rather than stacking on top of it - both are
	 * `--ml-bnav-h` tall and both sit at z-index 40, and bottom-nav.js adds
	 * `is-swapped` to the nav whenever this is shown. Equal heights are what
	 * make the swap invisible: nothing in the page reflows.
	 */
	.ml-stickycart {
		position: fixed;
		right: 0;
		bottom: 0;
		left: 0;
		z-index: 40;

		display: flex;
		align-items: center;
		gap: 10px;
		height: calc(var(--ml-bnav-h) + var(--ml-bnav-safe));
		padding: 0 12px var(--ml-bnav-safe);
		background: var(--ml-white);
		border-top: 1px solid var(--ml-line);
		box-shadow: 0 -2px 10px rgba(var(--ml-shadow-tint), 0.07);
	}

	.ml-stickycart[hidden] {
		display: none;     /* an author `display: flex` would beat the UA rule */
	}

	.ml-stickycart__media {
		flex: 0 0 auto;
		width: 40px;
		height: 40px;
		border-radius: 8px;
		background: var(--ml-stage-soft);
		overflow: hidden;
	}

	.ml-stickycart__media .ml-stickycart__img {
		display: block;
		width: 100%;
		height: 100%;
		object-fit: contain;
		mix-blend-mode: multiply;   /* the packshots' white ground, as elsewhere */
	}

	.ml-stickycart__meta {
		display: flex;
		flex-direction: column;
		justify-content: center;
		gap: 1px;
		min-width: 0;
		flex: 1 1 auto;
	}

	.ml-stickycart__name {
		overflow: hidden;
		white-space: nowrap;
		text-overflow: ellipsis;
		font-size: 12px;
		font-weight: 500;
		line-height: 1.25;
		color: var(--ml-muted);
	}

	.ml-stickycart__price {
		overflow: hidden;
		white-space: nowrap;
		text-overflow: ellipsis;
		font-size: 15px;
		font-weight: 700;
		line-height: 1.25;
		color: var(--ml-navy);
	}

	.ml-stickycart__price del {
		margin-right: 4px;
		font-size: 12px;
		font-weight: 500;
		color: var(--ml-muted);
	}

	.ml-stickycart__price ins {
		text-decoration: none;
	}

	/* the same (0,2,0) Astra-proof rest rule as the bar's buttons */
	.ml-stickycart .ml-stickycart__btn {
		flex: 0 0 auto;
		min-height: 44px;
		margin: 0;
		padding: 0 20px;
		border: 0;
		border-radius: 8px;
		background: var(--ml-cyan);
		box-shadow: none;
		font-family: inherit;
		font-size: 14px;
		font-weight: 600;
		line-height: 1.2;
		letter-spacing: 0;
		text-transform: none;
		color: var(--ml-white);
		cursor: pointer;
		-webkit-tap-highlight-color: transparent;
		transition: background-color var(--ml-t-base) var(--ml-e-standard);
	}

	.ml-stickycart .ml-stickycart__btn:focus:not(:focus-visible) {
		outline: none;
		background: var(--ml-cyan);
		color: var(--ml-white);
	}

	.ml-stickycart .ml-stickycart__btn:hover {
		background: var(--ml-cyan-dark);
	}

	.ml-stickycart .ml-stickycart__btn:focus-visible {
		outline: 3px solid var(--ml-cyan);
		outline-offset: 3px;
	}

	.ml-stickycart .ml-stickycart__btn.is-busy {
		opacity: 0.7;
		pointer-events: none;
	}

	/* ------------------------------------------------------- the WhatsApp float */

	/*
	 * `.wa-float` lives in Code Snippet #17 - the DATABASE, not this theme - and
	 * both of its rules (the base and its own `@media (max-width: 600px)`) are
	 * (0,1,0). A single extra class therefore wins outright, with no
	 * `!important` and no dependence on load order.
	 *
	 * 20px of clearance above the bar. The same lift covers the sticky cart
	 * bar, because the two are the same height and never render together.
	 *
	 * IT WAS 14px AND IT NEVER ACTUALLY COVERED ANYTHING - measured at 375 and
	 * 414 before this change: the float cleared the bar's top edge, overlapped
	 * zero nav items, and a hit test at the centre of all five returned the
	 * item itself. Horizontally it sits over ACCOUNT, not Wishlist. So this is
	 * a legibility change, not a bug fix: at 14px the button's shadow crowded
	 * the bar's top border and read as touching it. 20px separates the two
	 * without pushing a 58px target any further from the thumb.
	 */
	body.medlife-has-bnav .wa-float {
		bottom: calc(var(--ml-bnav-h) + var(--ml-bnav-safe) + 20px);
	}

	/* ------------------------------------------------------------ reduced motion */

	/*
	 * The twins name every pseudo-class the animating rules name - a grouped
	 * or state selector left out here is how motion suppression silently stops
	 * working, which this theme has already been bitten by twice.
	 *
	 * Colour is deliberately NOT suppressed: 2.3.3 is about motion, not a tint,
	 * and the sheet still opens (it just arrives rather than slides).
	 */
	@media (prefers-reduced-motion: reduce) {

		.ml-bnav,
		.ml-bnav.is-hidden,
		.ml-bnav.is-swapped {
			transition: none;
		}

		.ml-bnav .ml-bnav__item .ml-bnav__icon,
		.ml-bnav .ml-bnav__item:active .ml-bnav__icon {
			transition: none;
			transform: none;
		}

		.ml-bnav-sheet[open] .ml-bnav-sheet__panel {
			animation: none;
		}

		.ml-stickycart .ml-stickycart__btn,
		.ml-stickycart .ml-stickycart__btn:hover,
		.ml-stickycart .ml-stickycart__btn:focus-visible {
			transition: none;
		}
	}

	/* ------------------------------------------------------------- narrow phones */

	@media (max-width: 360px) {
		.ml-bnav .ml-bnav__item {
			font-size: 10px;
		}

		.ml-bnav-sheet__icon {
			width: 56px;
			height: 56px;
		}

		.ml-stickycart {
			gap: 8px;
		}

		.ml-stickycart .ml-stickycart__btn {
			padding: 0 14px;
		}
	}
}
