/**
 * Checkout chrome — the slim header and the one-line footer that the checkout and
 * the purchase confirmation wear INSTEAD of the site header and the site footer.
 *
 * This stylesheet styles two template parts, parts/checkout-header.html and
 * parts/checkout-footer.html, and nothing else. What it is FOR is subtraction: a
 * visitor with a card in their hand has exactly one thing left to do, and every
 * other route off the page — the product search, the category strip, the account
 * and cart links, the four-column footer, the fixed mobile tab bar — is a route
 * away from finishing. So those pages do not render the parts that carry them.
 * The tab bar in particular is gone BY CONSTRUCTION rather than by a `display:
 * none` here: parts/checkout-footer.html simply does not include the mobile-bar
 * part the way parts/footer.html does, so there is no element to hide.
 *
 * Two enqueues, both predicated, and they are deliberately not one:
 *
 *   inc/checkout.php  f32_enqueue_checkout_styles()      — edd_is_checkout()
 *   functions.php     f32_enqueue_order_receipt_styles() — has_shortcode(edd_receipt)
 *
 * The two pages are found by two different questions. The checkout form is a
 * gateway-select round trip that EDD answers for; the confirmation page is found
 * by the shortcode it carries, because EDD lets that page move. Both questions
 * were already being asked for the two page stylesheets, so this file rides along
 * on the answers rather than inventing a third predicate that could disagree with
 * either.
 *
 * The header borrows the site header's idiom on purpose — same 18px rows, same
 * gutter padding, same white band over a hairline bottom border — so the change
 * of chrome reads as the same site in a quieter room, not as a different site
 * asking for a card number.
 *
 * @package F32
 */

/* === Header ============================================================== */

/*
 * THE LOGO IS CENTRED, WHICH IS THE ONE THING THIS BAR SAYS. The reference
 * checkout the store is drawn from puts the shop's name in the middle of an
 * otherwise empty white strip and one control at the end of it, and that is the
 * whole of its chrome. Ours is the same shape: logo in the middle track, "Back
 * to store" at the end.
 *
 * THE "SECURE CHECKOUT" LABEL IS GONE FROM THIS BAR. It used to hold the centre
 * track, which is why the logo could not. It has not been deleted so much as
 * found in its proper place: EDD already prints the same claim, translated, as
 * `#edd_secure_site_wrapper` immediately above the card fields — which is where
 * a visitor reads it, next to the number they are about to type, rather than
 * fifty pixels under the browser's own padlock. assets/css/checkout.css styles
 * it there.
 *
 * Three tracks and not two, and the reasoning is lifted wholesale from
 * .site-header-main in assets/css/site-header.css: a centre track can only be
 * centred on the PAGE if the two beside it are equal, so the empty leading track
 * has to exist. `1fr` on both sides rather than a floor, because the leading
 * track now has no content at all — its min-content is zero by construction, not
 * by accident, so there is nothing for a floor to protect.
 *
 * The group is declared `layout: default` in the part so core sets no `display`
 * on it at all, and this file owns the row outright instead of racing a
 * serialised `.wp-container-…-is-layout-flex` rule for it. That race is not
 * theoretical; site-header.css lost it once already, and the note there about
 * `.is-layout-flex > :is(*, div) { margin: 0 }` being 0,1,1 is why neither file
 * positions anything in this row with a margin.
 */
.f32-checkout-header {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: center;
	gap: var(--f32-header-gap, 24px);
	background: var(--wp--preset--color--contrast, #fff);
	border-bottom: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
}

/*
 * NOT sticky, unlike the site header. The site header sticks because the search
 * is the point of it and a 1,082-product archive scrolls it away in one flick;
 * this bar carries a logo and two words, so pinning it would spend viewport on
 * nothing. On a phone the checkout form is long and the visitor needs all of it.
 */

.f32-checkout-header__logo {
	grid-column: 2;
	justify-self: center;
}

.f32-checkout-header__back {
	grid-column: 3;
	justify-self: end;
	margin: 0;
	font-size: 0.8125rem;
	white-space: nowrap;
}

.f32-checkout-header__back a {
	color: var(--wp--preset--color--muted, #6b7280);
	text-decoration: none;
}

.f32-checkout-header__back a:hover,
.f32-checkout-header__back a:focus-visible {
	color: var(--wp--preset--color--primary, #000);
	text-decoration: underline;
}

/*
 * Below the mobile breakpoint the row loses its gap rather than one of its
 * items. Logo 120px plus "Back to store" at about 90px plus two 24px gaps plus
 * the gutter is 298px on the narrowest phone in use, which fits — but only just,
 * and with nothing left over the trailing track starts taking width off the
 * leading one and the logo drifts off centre. Halving the gap buys back 24px and
 * the logo stays where it belongs.
 */
@media (max-width: 600px) {
	.f32-checkout-header {
		--f32-header-gap: 12px;
	}
}

/* === Footer ============================================================== */

/*
 * One line, centred, and quiet enough to be furniture. The links are the three a
 * card form is obliged to put within reach — terms, privacy, refunds — and they
 * are the same URLs parts/footer.html carries in its Legal column, because a
 * second copy of a policy URL is a second thing to forget to change.
 */
.f32-checkout-footer {
	border-top: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
}

/*
 * THE HORIZONTAL PADDING MOVED OFF THE GROUP AND ONTO THE LINE, and that is what
 * makes the checkout's version of this footer possible at all. The part used to
 * carry `padding-left/right: gutter` as a serialised inline style, and an inline
 * style cannot be overruled by a stylesheet without `!important`. The checkout
 * needs the footer element itself to run edge to edge — it paints the same
 * two-colour ground the page above it does — so the padding is now a rule here,
 * which the checkout block below can simply restate.
 *
 * The confirmation page, which wears this same footer, is unaffected: it gets
 * the gutter it always had, from one line lower down.
 */
.f32-checkout-footer__line {
	margin: 0;
	padding-inline: var(--wp--preset--spacing--gutter, 1.25rem);
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.75rem;
	text-align: center;
}

.f32-checkout-footer__line a {
	color: inherit;
	text-decoration: none;
}

.f32-checkout-footer__line a:hover,
.f32-checkout-footer__line a:focus-visible {
	color: var(--wp--preset--color--primary, #000);
	text-decoration: underline;
}

/* === The footer, on the split checkout =================================== */

/*
 * ON THE CHECKOUT THIS STRIP IS PART OF THE PAGE'S GROUND AND NOT A BAR ACROSS
 * IT. assets/css/checkout.css paints `main` with a hard two-colour gradient —
 * white under the form, `subtle` under the order rail, changing at
 * `--f32-co-split`. `main` stops where the footer begins, so a footer that did
 * not carry the same gradient would leave the grey ending in a straight line
 * sixty pixels above the bottom of the window, which reads as a rendering fault.
 * The reference runs its grey to the very bottom.
 *
 * The tokens are declared once, in checkout.css, on `body:has(.f32-checkout)`.
 * The note there says why they live on `body` rather than on either element: two
 * files need the same percentage, and a second copy of it is a value that can
 * drift by exactly the amount that makes the seam visible.
 *
 * `body:has(.f32-checkout .edd-checkout__inner-blocks)` is the two-column
 * predicate, and it is written the same way here as it is in checkout.css. It
 * named `.edd-blocks__purchase-form` until 2026-09-03, which was the same fact
 * while EDD rendered the checkout as one block; the page now holds EDD's inner
 * blocks, that element is gone, and the class EDD adds to the wrap when inner
 * blocks render says the same thing. Two things are being excluded and both
 * matter:
 *
 *   the purchase-confirmation page, which wears this same chrome and is a single
 *   receipt card with no columns and no rail;
 *
 *   the EMPTY checkout, where EDD replaces the block body with one centred
 *   column. That one was shipped wrong for a day: the ground and this footer
 *   both went on painting a seam behind a page that had nothing to divide, and
 *   an empty cart read as a two-column layout that had lost its right-hand
 *   column.
 *
 * One fact about the page, one spelling of it, in both stylesheets. The long
 * note above the ground rule in checkout.css says why the fact is asked of the
 * DOM rather than stamped on `<body>` from PHP.
 */
@media (min-width: 900px) {
	body:has(.f32-checkout .edd-checkout__inner-blocks) .f32-checkout-footer {
		border-top: 0;
		background: linear-gradient(
			to right,
			var(--wp--preset--color--contrast, #fff) 0 var(--f32-co-split),
			var(--wp--preset--color--subtle, #f5f5f5) var(--f32-co-split) 100%
		);
	}

	/*
	 * The line takes the white half and sets itself against the same inner edge
	 * the form above it uses, so the policy links start exactly where the first
	 * field starts. That inset is the width of the white column less the form
	 * measure and its gutter — the same three tokens the column itself is built
	 * from, so the two cannot fall out of step.
	 *
	 * `max()` is the floor for the widths where the column is narrower than the
	 * form measure and the subtraction would go negative: below that point the
	 * line simply keeps the ordinary gutter.
	 *
	 * The hairline moves here from the footer element for the same reason the
	 * background moved onto it: a rule across the whole page would cross the
	 * seam, and the reference draws it over the white half only.
	 */
	body:has(.f32-checkout .edd-checkout__inner-blocks) .f32-checkout-footer__line {
		box-sizing: border-box;
		max-width: var(--f32-co-split);
		padding-block-start: var(--wp--preset--spacing--40, 1rem);
		padding-inline: max(
				var(--f32-co-gutter),
				calc(var(--f32-co-split) - var(--f32-co-form) - var(--f32-co-gutter))
			)
			var(--f32-co-gutter);
		border-top: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
		text-align: start;
	}
}

/* === Hold the footer at the bottom ======================================= */

/*
 * The site footer is four columns tall, so on any normal page it reaches the
 * bottom of a laptop viewport by itself. This one is a single 12px line, and a
 * completed order with three items ends about 400px short — which left the
 * hairline rule and the copyright stranded halfway down the screen with white
 * below them, reading as a rendering fault rather than as the end of the page.
 * Measured on the confirmation page at 1102x1115.
 *
 * A flex column, scoped to the pages that wear this chrome. It goes on
 * `.wp-site-blocks` and NOT on `<body>`, and that is the whole of what took two
 * attempts. The template parts are not body children: core wraps the entire
 * block-theme render in one `div.wp-site-blocks`, and body's actual children are
 * that div plus twenty-odd scripts and two plugin overlay divs — one of which
 * measures the full viewport height and would have absorbed every pixel `flex:
 * 1` was meant to give the content. Measured: body had 30 children, the footer
 * still sat at y=1253 in a 1940px viewport.
 *
 * `min-height: 100svh`, not `100vh`. On iOS the large viewport unit measures the
 * screen with the address bar retracted, so a `100vh` floor is taller than what
 * is actually visible and reintroduces the scroll it was added to remove.
 *
 * THE ADMIN BAR IS SUBTRACTED, and leaving it in was the same class of mistake
 * that `svh` guards against: a floor taller than the screen. Core pushes the whole
 * document down with `html { margin-top: 32px !important }` - 46px at 782px and
 * below - and a viewport unit does not know about it, so `100svh` plus that margin
 * is a page 32px taller than the glass. On the checkout, whose only content is one
 * short empty-cart hero, that arithmetic WAS the whole scrollbar.
 *
 * Two numbers rather than one, because core changes it at 782px - the same width
 * this theme's phone rules use, and for the same reason: it is core's own mobile
 * boundary. Nobody who is logged out ever sees either number; the property
 * resolves to 0px for them and this reads as a plain `100svh`.
 *
 * Not `position: fixed` on the footer: the confirmation's receipt card is taller
 * than the viewport on a phone, and a footer pinned to the glass would sit on
 * top of the download buttons.
 */
/*
 * THE GROUND IS GREY SO THE CARD CAN BE WHITE. The confirmation page is one
 * receipt card on an otherwise empty page, and without a ground under it the
 * page was white-on-white and the card dissolved into its own hairline. The
 * theme's `page` preset goes on the body so the header, the footer and the card
 * all sit on one continuous surface.
 *
 * THE CHECKOUT NO LONGER USES THIS, and nothing here needs to know that. Its
 * `main` and its footer both paint a two-colour ground of their own, opaquely,
 * from `--f32-co-split`; the header is opaque white; so this rule is simply
 * never visible on that page. It is left applying to both because the selector
 * that describes it — "a page wearing the chrome" — is still true of both, and
 * narrowing it would buy nothing except a second predicate to keep in step.
 */
body:has(.f32-checkout-header) {
	background: var(--wp--preset--color--page, #f9fafb);
}

body.admin-bar:has(.f32-checkout-header) {
	--f32-admin-bar-height: 32px;
}

@media (max-width: 782px) {
	body.admin-bar:has(.f32-checkout-header) {
		--f32-admin-bar-height: 46px;
	}
}

body:has(.f32-checkout-header) .wp-site-blocks {
	display: flex;
	flex-direction: column;
	min-height: calc(100svh - var(--f32-admin-bar-height, 0px));
}

/*
 * The one child that takes the slack. `flex: 1 0 auto` rather than `1 1 auto`:
 * the receipt and the checkout form both overflow a short viewport, and a
 * shrinkable middle would let the footer eat into them.
 */
body:has(.f32-checkout-header) .wp-site-blocks > main {
	flex: 1 0 auto;
}

/* === Undo the tab bar's reserved strip ==================================== */

/*
 * assets/css/mobile-bar.css sets `body { padding-bottom: <bar height> + safe
 * area }` under 782px, unconditionally, because the bar is `position: fixed` and
 * would otherwise cover the last thing on every page. On THESE two pages the bar
 * is not rendered at all, so that padding is 63px of dead space under the footer
 * with nothing sitting in it.
 *
 * The selector is `body:has(…)`, not a page-id or a template class, and that is
 * the whole point: the padding exists because the bar exists, so the reset is
 * keyed to the absence of the bar as expressed by the presence of this chrome.
 * A page that adopts parts/checkout-header.html later gets the correct bottom
 * edge without anyone remembering this file. It also wins on weight — 0,1,1
 * (`:has()` carries its most specific argument's class weight on top of the
 * `body` type) against mobile-bar.css's bare `body` at 0,0,1 — so load order
 * between the two stylesheets does not decide it.
 *
 * The media query mirrors mobile-bar.css's own breakpoint, and it has to be the
 * SAME NUMBER, not one below it. It read 781px, which left exactly one viewport
 * width - 782px itself - where mobile-bar.css had already added the padding and
 * this rule had not yet fired to take it away, so the checkout carried 63px of
 * dead space and a scrollbar at that one width. Above the bound there is no
 * padding to undo and the rule is inert either way.
 */
@media (max-width: 782px) {
	body:has(.f32-checkout-header) {
		padding-bottom: 0;
	}
}
