/**
 * Checkout — /checkout/ only
 *
 * Loaded by f32_enqueue_checkout_styles() when f32_is_checkout() is true.
 * Generic input and submit styling lives in assets/css/forms.css; this file
 * covers only what is specific to the page where money changes hands.
 *
 * ---------------------------------------------------------------------------
 * THE LAYOUT: A SPLIT PAGE, NOT A PAGE MEASURE
 * ---------------------------------------------------------------------------
 *
 * The page had one defect that mattered more than every parity difference below
 * put together. In one column, with a single item in the cart, "Complete
 * Purchase" sat 1,636px down and the price was off screen when it was clicked.
 * Nobody should have to remember what they are about to pay. Two columns and a
 * sticky order rail fix that, and everything since has been about which two
 * columns and how they are dressed.
 *
 * THIS PAGE HAS NO MEASURE, WHICH IS THE ONE THING THAT MAKES IT UNUSUAL IN THIS
 * THEME. Every other template constrains its content to 696px or to the 1,180px
 * panel; this one constrains nothing. templates/page-checkout.html gives `main`
 * a `layout: default` and no class, because the design needs the ground to reach
 * both edges of the window and change colour at the seam between the form and
 * the order rail. The content inside each column is still capped - in pixels, by
 * this file - so nothing is actually as wide as the screen. What crosses the
 * whole window is the colour, and only the colour.
 *
 * IT USED TO SAY 1,180px, on the `f32-panel` class, and before that 1,100px
 * twice. Both are gone with the panel: a constrained `main` would have put white
 * space on the outside of the grey rail, which is the one arrangement the
 * reference design does not have. assets/css/panel.css is no longer enqueued
 * here at all - see f32_enqueue_panel_styles() in functions.php. theme.json's
 * contentSize is deliberately untouched; 696px is right for every other page on
 * the site.
 *
 * post-content stays `layout: default` for the reason it always was: there is
 * nothing left for a second constrained layout to do except reintroduce a
 * number.
 *
 * Below 900px the columns stack, and there is no second column to stick, so the
 * total reappears as a compact bar immediately above the button instead.
 * inc/checkout.php puts EDD's own `#edd_final_total_wrap` back for that; this
 * file dresses it and hides it again above 900px, where the rail has it covered.
 *
 * 782px is EDD's own breakpoint (`$break-medium` in its checkout stylesheet) and
 * 900px is this design's. Both numbers appear below, and the band between them
 * exists only to switch EDD's grid back off where the two disagree.
 *
 * ---------------------------------------------------------------------------
 * WHAT PRODUCTION ACTUALLY RENDERS — measured, not transcribed
 * ---------------------------------------------------------------------------
 *
 * Production ships roughly twenty hand-written EDD rules in post-309184.css.
 * Most of them are dead, and copying them across would have shipped dead CSS
 * into this theme. Both sites render the EDD **Blocks** checkout, whose cart
 * is a `<div class="edd-blocks-cart">` laid out with CSS grid — there is no
 * `<table>` on the page. Measured on both origins at a 1263px probe:
 *
 *   #edd_checkout_cart th          -> 0 elements   (production and staging)
 *   #edd_checkout_cart td          -> 0 elements
 *   #edd_checkout_cart tr:nth-of.. -> 0 elements
 *   #edd_final_total_wrap          -> element absent
 *
 * Four more are present but inert or already matched by EDD Blocks' own
 * stylesheet, so writing them would change nothing:
 *
 *   #edd_discount_code{text-align:right}  production computes `right`, but the
 *       element is shrink-wrapped around the discount button, so the button
 *       lands at x=301 on BOTH sites. No visual effect either way.
 *   #edd_discount_code{margin-bottom:4rem}  production computes 0px — the rule
 *       is overridden on production itself.
 *   #edd-payment-mode-wrap{display:flex;gap:1rem}  both sites already compute
 *       `flex` / `8px`; production's 1rem is overridden on production too.
 *   .edd_cart_item_price / .edd_cart_actions {text-align:right}  both sites
 *       already compute `right`.
 *   .edd_cart_item_image{float:left}  the parent .edd_checkout_cart_item_title
 *       is display:flex, so float is ignored on production as well.
 *
 * That leaves the handful of rules below, each of which was verified as a real
 * production-vs-staging difference before being written.
 *
 * Breakdance palette slots, resolved off production's live :root rather than
 * guessed, and mapped onto this theme's slugs:
 *
 *   --bde-palette-color-9  #e5e7eb  -> `border-subtle` #e0e0e0
 *   --bde-palette-color-1  #8080800d (grey at 5%), which over the #f9fafb page
 *                          composites to ~rgb(243,244,245)
 *                                   -> `subtle` #f5f5f5
 *
 * Neither is used here: slot 9 fed the dead `th` border and slot 1 fed the
 * dead `tr:nth-child(2n)` zebra stripe. They are recorded so the next person
 * does not have to re-derive them. Note that the cart's real border on both
 * sites is EDD Blocks' own `1px solid #eee`, not slot 9.
 *
 * @package F32
 */

/* === Purchase button — the one measured defect === */

/*
 * Staging rendered #edd-purchase-button at 198x46, hard against the left edge
 * of the 696px measure. Production centres it in a 380px column: its
 * #edd_purchase_submit computes max-width 380px with margin-left and
 * margin-right both 158px inside the same 696px measure.
 *
 * ID selectors, deliberately. Core prints its global stylesheet as
 * `:root :where(...)` AFTER the theme's, so a single-class selector ties and
 * loses (see BACKLOG.md). An ID also makes this independent of load order,
 * which matters here: forms.css is enqueued from a render_block filter and so
 * prints later in the document than this file, which is enqueued in wp_head.
 *
 * The button already carries theme.json's colour and pill radius via
 * forms.css's `form input[type="submit"]` rule — it is an
 * <input type="submit" class="edd-submit button">. Only its size and placement
 * were wrong, so only size and placement are set here.
 *
 * max-width, not width: at 390px the measure is 335px, and a fixed 380 would
 * have introduced the site's first horizontal overflow. Measured with these
 * declarations applied, cart populated, admin bar removed:
 *
 *   1263  wrap 696@276 -> 380@434   button 198x46@276 -> 380x46@434   overflow 0
 *    700  wrap 645@20  -> 380@153   button 198x46@20  -> 380x46@153   overflow 0
 *    390  wrap 335@20  -> 335@20    button 198x46@20  -> 335x46@20    overflow 0
 *
 * 380@434 is production's figure to the pixel: its #edd_purchase_submit computes
 * max-width 380px with margin-left and margin-right both 158px.
 *
 * THE CAP HAS MOVED OFF THE FIELDSET AND ONTO THE BUTTON, and that is a
 * correction rather than a preference. #edd_purchase_submit is not a wrapper
 * around the button; it also holds the error panel, the two consent checkboxes
 * and the phone total bar. Capping the fieldset at 380px was wrapping "I agree
 * to the terms and conditions" onto a second line and was a good part of the
 * reason three checkboxes cost 174px. The button keeps production's 380px to
 * the pixel; everything else in the fieldset now gets the full column.
 */
#edd_purchase_submit {
	max-width: none;
}

/*
 * UNVERIFIED, and the one declaration on this page that is: `padding: 2rem`.
 * Production never rendered #edd-purchase-button at all during the session that
 * produced these numbers — its checkout defers the button until the Stripe
 * payment element mounts, and it had not appeared after a 20s wait, so the
 * element could not be measured there. The value is taken from production's
 * stylesheet on trust. The 380px column around it IS measured, on both sites.
 * If the button ever looks too tall, this is the declaration to question; the
 * max-width above it is not in doubt.
 *
 * The heights in the table above are therefore the pre-padding 46px. With 2rem
 * the button becomes roughly 380x82 (32 + 32 + 16px x 1.125).
 *
 * `display: block` is what makes `margin-inline: auto` centre an <input>, which
 * is inline-block by default and would otherwise sit against the left edge of
 * the column now that the fieldset above no longer centres itself.
 */
/*
 * THE BUTTON'S SIZE, COLOUR AND PLACEMENT MOVED DOWN THE FILE. The note above is
 * kept because it records why the 380px cap and the 2rem padding were both
 * suspect; the rule that replaced them belongs to the layout and is written with
 * the rest of it, under "THE SPLIT CHECKOUT". Only `#edd_purchase_submit`'s cap
 * stays here, because that one is parity work and not design.
 */
/* === Cart item thumbnail === */

/*
 * Production puts 16px between the thumbnail and the item title; staging had
 * none, so the title sat flush against the image. `float: left` from
 * production's rule is deliberately omitted — the parent is a flex container
 * on both sites, which makes float a no-op.
 */
.edd_cart_item_image {
	margin-inline-end: 1rem;
}

/* === Discount code disclosure — the quietest control on the page === */

/*
 * THE FIELD IS SHUT AND EDD'S OWN LINK OPENS IT, and getting there was two
 * deletions rather than an addition. The rule that used to stand here forced the
 * field open with `!important` and hid the link, on the argument that "a
 * discount box a visitor has to go looking for is a discount box that does not
 * get used". That is true and it is the wrong thing to optimise for.
 *
 * An open, labelled discount field is read by the majority who do not have a
 * code as a discount they are missing. The finding is old and consistent -
 * Baymard's checkout usability work and Nielsen Norman's writing on coupons
 * agree on it - and the failure it describes is not a smaller order, it is an
 * abandoned one: the visitor leaves the checkout to go looking for a code, and
 * search results, extension pop-ups and a competitor's price are all on the
 * other side of that trip. The recommended shape in both places is the same, and
 * it is what EDD already ships: keep the affordance, spend as little attention
 * on it as possible, put the field behind a link.
 *
 * THE MECHANISM IS THE PLUGIN'S AND NEEDS NOTHING FROM US. `#edd_show_discount`
 * carries `edd-has-js` and `#edd-discount-code-wrap` carries `edd-no-js`; EDD
 * prints `.edd-js .edd-no-js { display: none }` inline in the head and puts
 * `edd-js` on the body, so with script running the field is shut and the link is
 * shown, and EDD's own handler opens the field. With script off the pair
 * reverses and the field renders open, which is the right failure - the one
 * arrangement where a link that reveals things cannot work.
 *
 * WHAT IS STYLED IS THE CONTROL'S WEIGHT, AND ONLY THAT. EDD draws the toggle as
 * `.edd-button-secondary`: grey fill, 1px border, 8px/16px padding. A filled
 * button is a call to action, and this is the one control on the page that most
 * visitors should read and skip. So it is drawn as text with an underline, at
 * the muted colour, the same treatment the account line's "log out" gets - the
 * two quietest links on the page look alike because they are the same kind of
 * thing.
 *
 * TWO IDS, AND THEY ARE NOT INSURANCE. EDD's own
 * `.wp-block-edd-checkout #edd_purchase_form .edd-button-secondary` is (1,2,0)
 * and paints the fill this rule has to remove; the cart moved inside
 * `#edd_purchase_form` with the inner-blocks change, so that selector matches
 * this button again. (0,3,0) - which is what this rule used to be, back when it
 * only set a font and had nothing to beat - now loses to it. (2,1,0) wins on the
 * first component and says why it is written that way.
 *
 * forms.css does not compete: its shape-based submit rule excludes
 * `.edd-button-secondary` by name, because EDD is the only party that knows this
 * button is secondary.
 */
#edd_checkout_form_wrap #edd_purchase_form .edd_discount_link {
	display: inline-flex;
	align-items: center;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: none;
	color: var(--wp--preset--color--muted, #6b7280);
	font: inherit;
	font-size: 0.8125rem;
	font-weight: 500;
	text-decoration: underline;
	text-underline-offset: 0.2em;
	cursor: pointer;

	/*
	 * 24px, THE SAME FIGURE THE ACCOUNT LINE TAKES AND FOR THE SAME REASON.
	 * Stripping the button's 8px of padding left the control 135x18, which is
	 * under WCAG 2.5.8's minimum - the cost of making it quiet, paid by the
	 * thumb. The height goes back without the fill coming with it. It is the
	 * minimum rather than the enhanced 44px because this is an optional
	 * detour, not the summary disclosure: missing it costs a second tap, not
	 * an answer the visitor needed.
	 */
	min-block-size: 1.5rem;

	/*
	 * `transform: none` is not tidying, and it is here rather than on the hover
	 * rule below on purpose. EDD's sheet lifts every `.edd-button-secondary` a
	 * pixel on hover - the affordance of a button pressing back, which is
	 * exactly what this control is being talked out of being. That rule is
	 * (1,3,0); this one is (2,1,0) and wins on the first component, so the
	 * unhovered declaration beats the hovered one and the hover rule stays free
	 * of motion. verify.ps1 gates that: `transform` on `:hover` belongs to
	 * surface.css and the f32-card class, and nowhere else in this theme.
	 */
	transform: none;
}

#edd_checkout_form_wrap #edd_purchase_form .edd_discount_link:hover,
#edd_checkout_form_wrap #edd_purchase_form .edd_discount_link:focus-visible {
	background: none;
	color: var(--wp--preset--color--primary, #000);
}

/* === The consent block =================================================== */

/*
 * 174px of the submit fieldset's 256 was three checkboxes, and almost none of
 * that height was checkbox. forms.css declares `label { display: block }` for
 * every form on the site, which is right for a field label sitting above its
 * input and wrong for a consent label sitting beside its box: each label dropped
 * onto its own line under a 13px checkbox and then wrapped inside the 380px cap,
 * at 58px a row.
 *
 * The row becomes a flex line instead, box first. Scoped to #edd_purchase_submit
 * because forms.css's `form:is(...) label` is (0,1,1) and prints later in the
 * document than this file, so a (0,1,1) selector here would tie and lose. The ID
 * scope earns its keep twice over: it is also what keeps these rules off the
 * marketing opt-in, which inc/checkout.php has moved out of this fieldset and
 * which is deliberately not styled to match.
 *
 * `align-items: flex-start` with a small offset on the box rather than
 * `baseline`: both labels carry a link and both wrap to two lines on a phone,
 * and baseline alignment would leave the box hanging against the second one.
 *
 * THE THIRD CLASS IS NOT EDD'S AND IS IN THIS LIST FOR THAT REASON.
 * inc/pass-consent.php prints the renewal consent on a subscription cart, and it
 * has to be indistinguishable from the box above it. Not for tidiness: a consent
 * that looks different from the consent beside it reads as an aside, and one set
 * SMALLER than its neighbour fails the conspicuousness test outright, since that
 * test is relative to the surrounding text. Same size, same shape, same rule.
 *
 * Nothing else about it is styled anywhere. The 12px above it comes from the
 * `#edd_purchase_submit fieldset` rule further down, which reaches it by
 * position, and the label size and colour come from the form.
 *
 * There was briefly a `.f32-renewal-terms` paragraph here instead, when this was
 * a disclosure line rather than a tickbox. Its rules are gone with it; the file
 * that prints the box explains why the shape changed twice.
 */
#edd_purchase_submit :is(.edd-terms-agreement, .edd-privacy-policy-agreement, .f32-consent-agreement) {
	display: flex;
	align-items: flex-start;
	gap: 0.5rem;
	line-height: 1.4;
}

#edd_purchase_submit :is(.edd-terms-agreement, .edd-privacy-policy-agreement, .f32-consent-agreement) label {
	display: inline;
	margin: 0;
	font-weight: 400;
}

/*
 * THE BOX SITS ON THE FIRST LINE, AND THE OFFSET THAT PUTS IT THERE IS
 * DERIVED RATHER THAN CHOSEN.
 *
 * `align-items: flex-start` above puts the box on the row's top edge, which
 * is a line-height's worth of leading ABOVE the text it belongs beside, so
 * the box has to come back down by half the difference between the line box
 * and itself. The old spelling was `margin: 0.2em 0 0` and it missed by
 * 1.84px - measured, not estimated - for two reasons, both of them units.
 *
 * `em` INSIDE A CHECKBOX IS NOT THE ROW'S `em`. A form control does not
 * inherit font-size; Chrome gives it 13.333px, so 0.2em resolved to 2.67px
 * against a row whose own em is 16px. `font: inherit` is what makes the two
 * agree, and it is the whole reason that declaration is here - a checkbox
 * with an explicit size draws nothing from its font.
 *
 * AND THE HEIGHT WAS THE UA'S. 13px is Chrome's; it is not Safari's and not
 * a zoomed Firefox's. Half of `line-height minus height` cannot be written
 * down in advance unless both terms are ours, so the size is set here and
 * the offset is computed from it. `1lh` is the row's line box, so the 1.4
 * on the rule above is stated once and read here rather than copied.
 *
 * The result is a box centred on the FIRST line and staying there when the
 * label wraps, which is what a consent row wants and what `align-items:
 * center` would give up the moment the sentence needed two lines.
 */
#edd_purchase_submit :is(.edd-terms-agreement, .edd-privacy-policy-agreement, .f32-consent-agreement) input[type="checkbox"] {
	flex: none;
	font: inherit;
	inline-size: var(--f32-co-tick, 0.875em);
	block-size: var(--f32-co-tick, 0.875em);
	margin: calc((1lh - var(--f32-co-tick, 0.875em)) / 2) 0 0;
}

/*
 * THE RULE THAT SPACED THESE TWO FIELDSETS USED TO STAND HERE AND NEVER WON
 * A DAY. It was `#edd_terms_agreement, #edd-privacy-policy-agreement` at
 * (1,0,0), and the exception list in the fieldset section below reaches the
 * same elements through `:is(..., #edd_purchase_submit fieldset)` - which
 * takes the specificity of its most specific argument, making that selector
 * (3,0,1). So the consent fieldsets computed `margin-block-end: 0`, the
 * comment beside the exception list said they were spaced at 12px, and on a
 * phone - the one width where EDD's total bar renders between the consent
 * and the button - the two boxes touched.
 *
 * The spacing now lives beside the exception it is an exception to, at the
 * same weight as everything else in that section. Nothing here.
 */

/* === The newsletter opt-in =============================================== */

/*
 * inc/checkout.php moves this off `edd_purchase_form_before_submit` and onto
 * `edd_blocks_checkout_address_fields`, which lands it at the end of the
 * personal-info and billing block. The styling finishes what the move started:
 * a hairline separates it from the fields it now follows, and it is set muted
 * and smaller so it reads as an offer. Nothing about it should look like the two
 * boxes that have to be ticked to buy.
 */
.f32-checkout__optin {
	margin-block-start: var(--wp--preset--spacing--40, 1rem);
	padding-block-start: var(--wp--preset--spacing--40, 1rem);
	border-top: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
	font-size: 0.875rem;
}

/*
 * The extension prints `<fieldset><p><input><label></p></fieldset>`, so the row
 * to lay out is the paragraph. Scoped to #edd_purchase_form for the same reason
 * the consents are scoped to #edd_purchase_submit: forms.css's label rule prints
 * later and has to be outweighed rather than tied.
 */
#edd_purchase_form .f32-checkout__optin p {
	display: flex;
	align-items: flex-start;
	gap: 0.5rem;
	margin: 0;
}

#edd_purchase_form .f32-checkout__optin label {
	display: inline;
	margin: 0;
	font-weight: 400;
	color: var(--wp--preset--color--muted, #6b7280);
}

#edd_purchase_form .f32-checkout__optin input[type="checkbox"] {
	flex: none;
	font: inherit;
	inline-size: var(--f32-co-tick, 0.875em);
	block-size: var(--f32-co-tick, 0.875em);
	margin: calc((1lh - var(--f32-co-tick, 0.875em)) / 2) 0 0;
}

/* === The total, on phones ================================================ */

/*
 * NOTHING, AND THAT IS A DELETION.
 *
 * inc/checkout.php used to restore EDD's own `#edd_final_total_wrap` immediately
 * above the purchase button, and this section dressed it: a bordered card with
 * the amount in the mint `price` badge, hidden again above 900px where the
 * sticky rail already carries the figure.
 *
 * It printed the total TWICE on the one width it existed for. The order summary
 * stacks above the form on a phone and its last row is the total, so the bar
 * repeated a number the visitor had already been shown - and repeated it in a
 * louder treatment than the original, which reads as two different totals until
 * you check that they agree. The badge was the loudest part of it: that mint
 * pill is the product card's price signal, and the rail's own total gave it up
 * for exactly this reason (see "NO MINT PILL" in the order rail).
 *
 * THE THING IT WAS FOR IS NOW DONE BY THE SUMMARY BEING OPEN. The bar was added
 * when the phone summary shipped collapsed, which put the total behind a
 * disclosure; it ships open now, so the figure is on screen in the place that
 * owns it, above the fields rather than below them.
 *
 * What this costs is real and worth writing down: on a long phone form the total
 * is scrolled off by the time "Complete Purchase" is reached, which is the
 * defect this whole file opens by describing. If it needs answering again, the
 * answer is a sticky mini-total, not a second copy of the row.
 */

/* === Errors ============================================================== */

/*
 * The one place a customer meets an error on this site is the one page where
 * being confused about it costs a sale, and it had no design at all. EDD's own
 * stylesheet is off site-wide (`disable_styles`), so
 * `.edd_errors.edd-alert-error` arrived as bare paragraphs in the middle of the
 * submit fieldset, which is where `edd_print_errors` renders them - directly
 * above the button, which at least is where the visitor is already looking.
 *
 * `danger` #b91c1c is the theme's alarm colour, and `danger-light` #fee2e2 is its
 * wash. IT USED TO BE CORAL AND IS NOT ANY MORE: coral #ee383a is the BRAND
 * colour, and a payment error drawn in brand red says "this is us" at the exact
 * moment it needs to say "this stopped". Coral is retired from destructive duty
 * site-wide; theme.json carries `danger` and `danger-light` for this, and those two
 * are now the palette's ONLY status colours.
 *
 * THERE WERE FOUR MORE AND THEY ARE GONE. `success` #15803d, `success-light`
 * #d1fae5, `warning` #b45309 and `warning-light` #fff4ca went in beside `danger` as
 * semantic aliases — the light pair deliberately the same hex as `price` and
 * `gold-light`, on the argument that a slug should say what a colour MEANS at the
 * point of use. The argument is a good one and it was never taken up: every rule in
 * this theme that actually paints a state reaches for `price` or `gold-light`
 * directly, and account-card.css and account-plan.css argue at length for exactly
 * those two. So the four slugs bought no meaning and sold a hazard — a second,
 * identical-looking way to spell a colour already spelled, which is a coin flip for
 * whoever writes the next badge and two different greens on one page when it lands
 * wrong. They were removed before anything used them, so nothing broke and no
 * author's colour choice was orphaned. `danger` survives because it is a colour this
 * palette does not otherwise contain — an alarm red is not an alias for anything.
 *
 * THE TINT IS NOW NEAT `danger-light` rather than a mix. The old rule mixed
 * coral-light 20% into white because #f58485 at full strength left black body
 * text short of comfortable. #fee2e2 is already a wash — BLACK ON IT IS 17.2:1 —
 * so the mix would be arithmetic performed on a value that has nothing left to
 * lighten. THE HAIRLINE HAD TO MOVE WITH IT: a #fee2e2 line on a #fee2e2 fill is
 * no line at all, so the box keeps a 25/75 mix of danger into danger-light -
 * rgb(237, 177, 177), which is visible against both the fill and the white page.
 * The heavier inline-start border is what makes it read as an alert at a glance
 * instead of as a pink paragraph.
 */
.edd_errors.edd-alert-error {
	margin-block-end: var(--wp--preset--spacing--40, 1rem);
	padding: 0.75rem 1rem;
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--danger, #b91c1c) 25%, var(--wp--preset--color--danger-light, #fee2e2));
	border-inline-start: 4px solid var(--wp--preset--color--danger, #b91c1c);
	border-radius: var(--wp--custom--border-radius--md, 8px);
	background: var(--wp--preset--color--danger-light, #fee2e2);
}

.edd_errors.edd-alert-error .edd_error {
	margin: 0;
}

.edd_errors.edd-alert-error .edd_error + .edd_error {
	margin-block-start: 0.5rem;
}

/*
 * The discount field's own error is a <span> that EDD ships carrying
 * `style="display:none"` and reveals from its own script, so nothing here may
 * set `display`. A stylesheet cannot beat that inline rule anyway, and one that
 * tried would start working the day EDD stopped shipping it - which is to say it
 * would break then. Colour and weight are all this one needs.
 *
 * `danger` and not coral, for the reason the alert above records, and this is the
 * case where the swap also fixes a measurement: coral text on white is 3.68:1 and
 * FAILS AA at this 0.875rem size, where #b91c1c on white is 6.47:1 and passes.
 */
#edd-discount-error-wrap {
	color: var(--wp--preset--color--danger, #b91c1c);
	font-size: 0.875rem;
	font-weight: 500;
}
/* ==========================================================================
 * THE SPLIT CHECKOUT — form left, order rail right, one black button
 * ==========================================================================
 *
 * Everything above this line is parity work: production rendered X, staging
 * rendered Y, here is the one declaration that closes the gap. Everything below
 * it is the layout, and a future parity question should not have to read past a
 * layout decision to find its answer.
 *
 * -------------------------------------------------------------------------
 * WHAT THE DESIGN IS
 * -------------------------------------------------------------------------
 *
 * The page is a Shopify checkout, measured off a live one rather than copied
 * from a picture of one. Two columns that do not sit inside a page measure: the
 * form fills the left part of the screen on white, the order summary fills the
 * right part on a soft grey that bleeds to the edge of the window. There is no
 * card around either one. Sections are separated by air and by a 20px heading,
 * never by a box. Every control is 48px tall with a label that floats up out of
 * the field when the field has something in it. The pay button is black, full
 * width, and the only filled control on the page.
 *
 * THIS REVERSES THE PREVIOUS ARRANGEMENT, and the reversal is the point. The
 * design before this one put the order on the LEFT and the payment on the RIGHT
 * and argued that this is what Stripe Checkout and Shopify both ship. Stripe
 * Checkout does. Shopify does not, and Shopify is what was asked for: the
 * reference checkout puts the form on the left at 500px and the summary on the
 * right at 400px, with the grey starting at the seam between them. Measured on
 * baskets-store.com at a 1899px viewport - main 500@460, aside 400@1040, the
 * ground changing colour at x=1000.
 *
 * -------------------------------------------------------------------------
 * THE FIVE NUMBERS, AND WHY THEY ARE CUSTOM PROPERTIES ON `body`
 * -------------------------------------------------------------------------
 *
 * `--f32-co-split` is consumed by TWO stylesheets. This file uses it to size the
 * form column; assets/css/checkout-chrome.css uses it to place the colour change
 * in the ground, and again to line the one-line footer up under the white half.
 * A second copy of that percentage in the other file would be a value that can
 * drift, and the symptom of the drift is the grey starting a few pixels away
 * from where the rail starts - which reads as a rendering fault rather than as a
 * number that needs changing.
 *
 * So the numbers are declared once, on the one element both files can reach.
 * `body:has(.f32-checkout)` and not `body:has(.f32-checkout-header)`: the chrome
 * is worn by the purchase-confirmation page as well, and that page is a single
 * receipt card with no columns and no rail. The class this hangs on is the one
 * templates/page-checkout.html puts on its own `main`.
 *
 * THE COLUMNS ARE A PERCENTAGE AND THE CONTENT INSIDE THEM IS A PIXEL CAP, which
 * is the arrangement that survives being resized. A fixed pair of pixel columns
 * centred on the page would put the seam at a position that moves as soon as
 * either column has to shrink, and the ground - which is painted by a gradient
 * on an element that knows nothing about flex shrinking - would no longer agree
 * with it. A percentage cannot disagree with itself.
 *
 * `--f32-co-form` 544px and `--f32-co-rail` 400px are the reference's 500/400
 * rounded to this theme's rem grid, with the form given the extra 44px because
 * SparkleStock sells downloads: there is no delivery address and no shipping
 * method, so the left column holds three fields where Shopify's holds nine, and
 * a slightly wider measure keeps the Stripe element comfortable.
 */
body:has(.f32-checkout) {
	--f32-co-split: 54%;
	--f32-co-form: 34rem;
	--f32-co-rail: 25rem;
	--f32-co-gutter: 2.5rem;
	--f32-co-block: 3rem;

	/*
	 * THE STEP BETWEEN SECTIONS, 32px, named because two rules several hundred
	 * lines apart have to agree on it: the base fieldset rhythm below and the
	 * submit block that reopens the gap the exception list closes. It stays a
	 * literal rather than becoming `--wp--preset--spacing--*`, and that is a
	 * decision and not an omission: this theme's scale steps 24px to 36px, the
	 * reference's step is 32, and a token that rounded to the nearest preset
	 * would be a design change wearing the clothes of a refactor.
	 */
	--f32-co-section: 2rem;

	/*
	 * THE STEP BETWEEN ROWS INSIDE A BLOCK, 12px, and the counterpart to the
	 * one above. The two consent lines are rows and not sections: they follow
	 * each other, and the button follows the last of them. The pair of names is
	 * the point - a rule that sets a margin in this file is choosing between two
	 * rhythms, and the token it reaches for says which.
	 */
	--f32-co-row: 0.75rem;

	/*
	 * THE SECTION HEADING'S TYPE, SPLIT IN TWO BECAUSE A SECOND RULE HAS TO DO
	 * ARITHMETIC WITH IT. Every heading on this form is a `<legend>`, and the
	 * account line is positioned to sit on the first legend's row - which means
	 * something other than the legend rule needs to know how tall that row is.
	 *
	 * A number copied into two rules is a number that will be changed in one of
	 * them. Written here, `font-size * line-height` is the legend's line box and
	 * both readers compute it from the same pair.
	 */
	--f32-co-legend: 1.25rem;
	--f32-co-legend-lh: 1.2;

	/*
	 * THE PAINTED SIZE OF A CONSENT CHECKBOX, written down because the offset
	 * that centres it on its first line is arithmetic done against it. A
	 * browser's default checkbox is 13px and that number belongs to the UA,
	 * not to us; an offset computed from a number we do not set is an offset
	 * that is right on one browser and wrong on the next.
	 */
	--f32-co-tick: 0.875em;

	/*
	 * THE ROOM A FOCUS RING NEEDS AT THE EDGE OF A SCROLL CONTAINER. The order
	 * rail is capped and scrolls inside itself above 900px, and a scroll
	 * container clips at its PADDING box - so a control flush with the rail's
	 * edge has its ring drawn outside the clip and cut off. Every control in the
	 * rail is flush, because the rail is exactly as wide as its content.
	 *
	 * 3px covers both rings on the page: this file draws its own as
	 * `box-shadow: 0 0 0 1px`, which sits 1px out, and the controls it does not
	 * style keep the browser's, which in Chrome is a 2px outline at 1px offset.
	 */
	--f32-co-ring: 3px;

	/*
	 * THE FIELD FONT IS 16px AT EVERY WIDTH, AND IT IS 16px FOR ONE REASON THAT
	 * IS NOT TASTE. iOS Safari zooms the whole page in when a text input smaller
	 * than 16px takes focus, and it does not zoom back out. On a checkout that
	 * means the visitor loses the layout at the moment they start typing their
	 * email address. The reference ships 14px and has the bug; we do not copy
	 * the bug.
	 *
	 * IT DOES NOT SHRINK ON A DESKTOP EITHER, and that is the interesting half.
	 * A media query here would have been free if this theme owned every field on
	 * the page, and it does not: the card fields belong to Stripe, and Stripe
	 * reads its appearance ONCE, when the element mounts, and never re-reads it
	 * on resize. So a responsive value could only be sent as one number, and a
	 * page with 14px card fields beside 16px email fields is the two-systems
	 * look this whole exercise exists to remove. One number, sent once, used
	 * everywhere. inc/checkout.php sends it.
	 *
	 * 16px at 1.4 with 13px of padding is a 50px control, which is the
	 * reference's 47px within three pixels and on the right side of every touch
	 * target guideline there is.
	 */
	--f32-co-field-font: 1rem;
}

/*
 * THE GROUND, painted on `main` rather than on `body`. checkout-chrome.css
 * already owns a `body` background - the flat `page` grey both chrome pages sit
 * on - and two files setting `background` on the same element at the same weight
 * is a fight decided by enqueue order, which is not a thing to decide a design
 * with. `main` is this file's element, it stretches to fill the space between
 * the header and the footer (checkout-chrome.css gives it `flex: 1 0 auto`), and
 * the header is opaque white, so nothing of the body ground shows through.
 *
 * The footer strip below `main` gets the same gradient from checkout-chrome.css,
 * off the same custom property, so the seam runs unbroken to the bottom of the
 * page exactly as it does on the reference.
 *
 * Two colour stops at one position rather than a soft blend: this is a change of
 * surface, not a gradient, and a `linear-gradient` with coincident stops is how
 * CSS spells a hard edge without a second element to draw it with.
 *
 * -------------------------------------------------------------------------
 * THE PREDICATE IS `:has(.edd-checkout__inner-blocks)` AND IT IS THE SAME ONE
 * EVERY RULE THAT DEPENDS ON THE TWO COLUMNS USES. That is the whole point of
 * spelling it this way. It used to name `.edd-blocks__purchase-form`, which was
 * the same fact under EDD's one-block markup; that element no longer exists,
 * and `.edd-checkout__inner-blocks` is the class EDD puts on the wrap when the
 * block renders inner blocks - which is now what "this page has two columns"
 * means.
 * -------------------------------------------------------------------------
 *
 * The seam only means something when there are two columns to divide. With an
 * empty cart EDD replaces the entire block body with `.f32-cart-empty`, which is
 * ONE centred column - and the ground went on painting a white half and a grey
 * half behind it, so an empty cart read as a two-column page whose right column
 * had lost its content. Which is exactly what it looked like.
 *
 * The fix is not a second condition. It is the SAME condition, written the same
 * way, in every rule that depends on the two columns existing: this ground, the
 * account line's positioned ancestor, and the footer strip in
 * assets/css/checkout-chrome.css. One fact about the page, one spelling of it.
 * The column widths no longer need to ask at all - they are inside the columns
 * block, which an empty cart never prints.
 *
 * `:has()` AND NOT A BODY CLASS FROM PHP, and the reason is that the fact can
 * change without a page load. Removing the last item from the cart is an
 * admin-ajax round trip; a class stamped on `<body>` at render time would still
 * say "two columns" while the page in front of the visitor had one. A selector
 * that asks the DOM is re-evaluated when the DOM changes. It also costs no new
 * predicate, no new class name and no new PHP - EDD's own class already IS the
 * question being asked.
 */
.f32-checkout {
	background: var(--wp--preset--color--contrast, #fff);
}

@media (min-width: 900px) {
	.f32-checkout:has(.edd-checkout__inner-blocks) {
		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 columns ========================================================= */

/*
 * TWO CORE `wp:columns`, AND THAT IS THE WHOLE LAYOUT NOW.
 *
 * What stood here was about two hundred lines that rebuilt a two-column
 * checkout out of EDD's one-column markup: a wrapping flex container behind a
 * `:has()` guard, a child reset that could not touch `order`, three separate
 * `order` declarations reversing EDD's own grid, a full-width rule for the
 * logged-in bar so that the two columns would share a top edge, and a band
 * between 782px and 900px that switched off a grid this page never wanted on.
 * Every one of those rules was correct, and every one of them existed for the
 * same reason: page 5 held ONE self-closing `edd/checkout` block, so the second
 * column had nowhere to come from except this file.
 *
 * EDD 3.7 registers `edd/checkout-cart`, `edd/checkout-personal-info` and
 * `edd/checkout-payment-info` as inner blocks of `edd/checkout`, and ships the
 * two-column arrangement as a block pattern. content/checkout-5.html now holds
 * that arrangement. So the columns are core blocks, the source order is already
 * form-then-cart, and the reversal, the guards and the band left with the markup
 * that made them necessary. What remains is a width, a padding and a cap.
 *
 * ---------------------------------------------------------------------------
 * `.wp-block-edd-checkout` AND NOT `#edd_checkout_form_wrap`, FOR THIS LAYER
 * ONLY
 * ---------------------------------------------------------------------------
 *
 * Everything else in this file is scoped to `#edd_checkout_form_wrap`, and it
 * has to be: those rules argue with EDD's own id-scoped stylesheets and would
 * lose the argument at one class. This layer argues with nobody. EDD does not
 * style `.wp-block-column`, so a class is enough here - and it buys the one
 * thing an id cannot, because the id is printed by the front-end render and the
 * class is on the block wrapper in BOTH contexts. Keyed this way the layout
 * reaches inside the block editor as well, which is the whole reason the page
 * was moved to inner blocks: the editor now draws the same two columns the
 * visitor sees, with the real sections in them.
 *
 * The tokens carry literal fallbacks for the same reason. `--f32-co-split` and
 * its neighbours are declared on `body:has(.f32-checkout)`, and the editor's
 * body is the editor's, not this template's. Without the fallback the split
 * would resolve to nothing inside the iframe and the columns would come out
 * even.
 *
 * WHAT THE EDITOR STILL WILL NOT SHOW is the ground. The white and grey halves
 * are a gradient on `main`, and `main` belongs to the template, not to the page.
 * The editor gets the structure and the content; it does not get the paint.
 *
 * ---------------------------------------------------------------------------
 * WHY THE COLUMNS ARE FLEX AND THE CONTENT IS CAPPED
 * ---------------------------------------------------------------------------
 *
 * `gap: 0` because the seam is a colour change, not a channel. Core gives a
 * columns block a block gap; a gap here would put a strip of neither colour
 * down the middle of the page.
 *
 * The split is a PERCENTAGE and the content inside it is a PIXEL CAP, which is
 * the arrangement that survives being resized - the note above the ground says
 * why at length, and the short version is that the gradient and the columns have
 * to agree about where the seam is, and only a percentage can be sure of
 * agreeing with itself.
 *
 * THE CAP IS DONE WITH `align-items` AND NOT WITH AN AUTO MARGIN, and that is
 * deliberate. `margin-inline-start: auto` is the flow idiom for this, and it
 * would have had to out-specify the section rhythm a few hundred lines below,
 * which sets `margin: 0 0 2rem` on every fieldset in the form. That is exactly
 * the specificity argument this file has already lost twice. A flex column
 * aligns its children without touching their margins, so there is nothing to
 * out-bid: the width and the cap say how wide, and the alignment says which
 * edge. `width: 100%` is needed with it because a flex child that is not
 * stretched shrinks to its content.
 *
 * The rail column aligns to `flex-start` for a second reason as well: the
 * sticky rail below needs the cart to be shorter than the column it sits in,
 * and a stretched flex child is exactly as tall as its column.
 */
@media (min-width: 900px) {
	.wp-block-edd-checkout .wp-block-columns {
		gap: 0;
	}

	.wp-block-edd-checkout .wp-block-column {
		display: flex;
		flex-direction: column;
		padding: var(--f32-co-block, 3rem) var(--f32-co-gutter, 2.5rem);
	}

	/* The form column: the white half, its content held against the seam. */
	.wp-block-edd-checkout .wp-block-columns > :first-child {
		flex: 0 0 var(--f32-co-split, 54%);
		max-width: var(--f32-co-split, 54%);
		align-items: flex-end;
	}

	.wp-block-edd-checkout .wp-block-columns > :first-child > * {
		width: 100%;
		max-width: var(--f32-co-form, 34rem);
	}

	/* The rail column: whatever is left, its content held against the seam. */
	/*
	 * The rail column, and the two inline values that look wrong and are not.
	 *
	 * The rail scrolls inside itself above 900px - see the sticky rail section
	 * - and a scroll container clips everything at its padding box. The rail is
	 * exactly as wide as its content, so every control in it is flush with that
	 * edge and every focus ring is drawn outside it and cut in half. Tabbing to
	 * the discount field showed it first, but the remove buttons, Apply and the
	 * summary disclosure all had it.
	 *
	 * There is no way to exempt a ring from the clip: `overflow-clip-margin`
	 * would do it, and it only applies to `overflow: clip`, which cannot scroll.
	 * So the scroller is given the room instead. The column hands one ring's
	 * width back on each side and the rail's cap takes it, which leaves the
	 * CONTENT exactly where it was - 400px starting at the same pixel - with
	 * three pixels of scrollport around it for the ring to live in.
	 */
	.wp-block-edd-checkout .wp-block-columns > :last-child {
		flex: 1 1 auto;
		align-items: flex-start;
		padding-inline: calc(var(--f32-co-gutter, 2.5rem) - var(--f32-co-ring, 3px));
	}

	.wp-block-edd-checkout .wp-block-columns > :last-child > * {
		width: 100%;
		max-width: calc(var(--f32-co-rail, 25rem) + 2 * var(--f32-co-ring, 3px));
	}
}

/*
 * THE 782-TO-900 BAND, which survives the rewrite because the disagreement it
 * settles survives it too: core stacks a columns block below 782px and this
 * design wants two columns only from 900px. So the 118px between them is told
 * to stack.
 *
 * It is two declarations now instead of a grid reset, and it needs no
 * `!important` even though core's own stacking rule below 782px uses one. That
 * is the payoff for leaving the widths out of the block markup: a `width`
 * attribute prints an inline `flex-basis`, and nothing but `!important` beats an
 * inline style. content/checkout-5.html carries no width for that reason and
 * for one other - the seam would then be written down in two places.
 *
 * 899.98px, not 899px: at a fractional device pixel ratio a viewport can report
 * 899.5px, and the two queries would then both fail and leave the page unstyled
 * at that width. The 0.02 gap is the standard hedge and is smaller than any
 * width a browser reports.
 */
@media (min-width: 782px) and (max-width: 899.98px) {
	.wp-block-edd-checkout .wp-block-columns {
		flex-wrap: wrap;
	}

	.wp-block-edd-checkout .wp-block-column {
		flex-basis: 100%;
	}
}

/*
 * THE STACK. One column, summary first, and the summary folded shut behind the
 * disclosure inc/checkout.php prints.
 *
 * `order: -1` on the rail column, and it is the ONE order declaration left on
 * this page. It used to take three, because EDD's markup put the cart first and
 * the desktop pair had to be reversed. The block pattern puts the form first,
 * which is right for a desktop and wrong for a phone: the reference opens a
 * narrow screen with the order summary, so that the visitor sees what they are
 * buying before they see what they have to type. One line, in the query that
 * wants it.
 *
 * The rail carries its own grey here. Above 900px the ground is a gradient on
 * `main` and neither column needs a background of its own; stacked, there is no
 * seam to put a gradient at, so the summary is the thing that has to be grey. It
 * is on the COLUMN rather than on the cart inside it, so the colour bleeds the
 * full width of the screen - which is what tells the visitor that the two halves
 * of the page are two different things.
 */
@media (max-width: 899.98px) {
	.wp-block-edd-checkout .wp-block-column {
		padding: var(--wp--preset--spacing--50, 1.5rem) var(--wp--preset--spacing--gutter, 1.25rem);
	}

	.wp-block-edd-checkout .wp-block-columns > :last-child {
		order: -1;
		background: var(--wp--preset--color--subtle, #f5f5f5);
		border-block-end: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
	}
}

/* === The account line =================================================== */

/*
 * "Account Information: You are currently logged in as x. (log out)" - a <p>
 * EDD prints out of one shared class (EDD\Blocks\Checkout\AccountLine). There is
 * no action around it, no filter on it and no attribute that moves it, so how
 * much of it shows is a decision this file has to make.
 *
 * WHERE IT GOES IS NO LONGER ONE OF THIS FILE'S DECISIONS, and that is the
 * correction this section carries. EDD echoes the line as the FIRST thing inside
 * `#edd_purchase_form`, above both columns; the heading it belongs beside - the
 * `<legend>` of `#edd_checkout_user_info` - is two levels further in, inside the
 * first column. They were never siblings, so they could never share a row in
 * flow, and this file used to fake the row with a page-level offset:
 * `inset-inline-end: calc(100% - var(--f32-co-split) + var(--f32-co-gutter))`
 * against the wrap. That arithmetic only has an answer while the columns are
 * side by side. Stacked, the legend's distance from the top of the wrap is the
 * height of the whole order summary, which is a number no stylesheet can write
 * down - so on a phone the link was left in flow at the top of the page, under
 * the site header, hundreds of pixels from the section it acts on.
 *
 * f32_checkout_move_account_line() in inc/checkout.php now moves the <p> INTO
 * that fieldset, immediately after the legend. Both media blocks that used to
 * live here are gone with it, and so is every page-level measurement: what is
 * left is one rule that pulls the line back over the heading it follows, written
 * in the same two values the heading is set in.
 *
 * WHAT SHOWS IS THE LINK AND NOTHING ELSE. The sentence names an address the
 * page is already showing - the Email Address field two rows below it is filled
 * with that exact string - so every word except "log out" is a second copy of
 * something the visitor can read anyway. The reference does the same thing: the
 * contact section carries the address, and the heading row beside it carries a
 * bare "Log out".
 *
 * `font-size: 0` on the paragraph with a size put back on the anchor, because
 * the words to drop are bare text nodes with no element around them and no
 * selector can reach them. It is a blunt instrument with one real virtue here:
 * the sentence stays in the accessibility tree whole, so a screen reader still
 * hears whose account is being bought from. Hiding the <strong> and shrinking
 * the rest would have been the same trick spelled longer and would have left
 * the sentence half said.
 */
.edd-blocks__logged-in {
	margin: 0;
	font-size: 0;
	line-height: 1.4;
}

/*
 * 24px OF TARGET AND DELIBERATELY NOT 44, and the height comes from the row
 * rather than from padding. The link is 42x16 as text, which is under WCAG
 * 2.5.8's minimum, so it needs to grow; it is also the one control on this page
 * whose accidental use throws the visitor out of a checkout they were halfway
 * through. The minimum is the right figure for a destructive escape hatch - big
 * enough to hit on purpose, small enough not to hit by accident - where the
 * summary disclosure in the rail takes the enhanced 44px for the opposite
 * reason.
 *
 * It stretches to the legend's line box, which is 20px x 1.2 = 24px, so the
 * target and the optical alignment are the same fact stated once. Padding would
 * have been a second number that had to agree with the first.
 */
.edd-blocks__logged-in a {
	display: inline-flex;
	align-items: center;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.8125rem;
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.edd-blocks__logged-in a:hover,
.edd-blocks__logged-in a:focus-visible {
	color: var(--wp--preset--color--primary, #000);
}

/*
 * ON THE LEGEND'S ROW AT EVERY WIDTH, AND IT IS A FLOAT, NOT A POSITION.
 *
 * `position: absolute` inside a `position: relative` fieldset was the obvious
 * spelling and it lands 40px too low. A fieldset does not lay its children out
 * in its own box: the rendered legend sits over the block-start border and
 * everything after it goes in an anonymous content box that BEGINS BELOW THE
 * LEGEND. Measured on staging - fieldset top 497, legend top 497, a child at
 * `inset-block-start: 0` painted at 537, which is 24px of legend plus the 16px
 * the legend rule puts under it. So the one box a stylesheet would reach for
 * here is the one box that cannot see the row it is aiming at, and how the three
 * engines resolve that containing block is not something to bet a checkout on.
 *
 * A float has no such question in it. The <p> follows the legend, so its flow
 * position IS the top of that content box in every engine, and one negative
 * block margin lifts it back over the legend: the legend's line box plus the
 * legend's own bottom margin, both read from the values those rules are written
 * with rather than measured off a screenshot. `float: inline-end` carries it to
 * the trailing edge with no offset to state at all.
 *
 * It is also the better failure. Out of flow, a long translated heading would
 * have run underneath the link; a float shortens the line boxes beside it, so
 * the heading wraps around "log out" instead of colliding with it.
 *
 * The height is the legend's line box for the second time in one rule, which is
 * what puts a 13px link on one optical line with a 20px heading - and it is why
 * the type is two tokens rather than two literals in the legend rule.
 *
 * THE CHILD COMBINATOR IS THE GUARD. The rule matches only where
 * f32_checkout_move_account_line() actually moved the line. If that ever misses
 * - EDD renames the class, the fieldset id changes - the <p> stays where EDD put
 * it, matches nothing here, and renders as a plain paragraph above the columns.
 * A checkout that degrades to plain is the right failure.
 */
#edd_checkout_form_wrap #edd_checkout_user_info > .edd-blocks__logged-in {
	float: inline-end;
	display: flex;
	block-size: calc(var(--f32-co-legend, 1.25rem) * var(--f32-co-legend-lh, 1.2));
	margin-block-start: calc(
		-1 * (
			var(--f32-co-legend, 1.25rem) * var(--f32-co-legend-lh, 1.2)
			+ var(--wp--preset--spacing--40, 1rem)
		)
	);
	padding: 0;
}

/*
 * ABOVE THE FOLD THERE IS NO FOLD. The collapsed-summary checkbox is a phone
 * affordance; at two columns the summary is always open and the label that names
 * the control is display:none - which would leave a focusable, invisible,
 * unlabelled checkbox in the desktop tab order. The control leaves the page with
 * its job.
 */
@media (min-width: 900px) {
	.f32-cart-head__toggle {
		display: none;
	}
}

/* === The sticky rail ===================================================== */

/*
 * THE RAIL HAS TO BE SHORTER THAN ITS COLUMN OR THE STICKY DOES NOTHING. A flex
 * child defaults to `stretch`, which would make the rail exactly as tall as the
 * form beside it, and a sticky box with no room left to travel inside its own
 * container never moves. This used to be said here as `align-self: flex-start`;
 * the rail column now says `align-items: flex-start` for both of its reasons at
 * once, so the declaration has gone rather than being kept as a second copy of
 * a decision made in the columns section.
 *
 * THE OFFSET IS A CONSTANT AND NOT `--f32-header-height`, AND THAT IS A
 * CORRECTION. The rule this replaces offset the rail by the site header's
 * measured height, on the reasoning that the header is sticky above 900px. The
 * checkout does not render the site header at all - templates/page-checkout.html
 * wears parts/checkout-header.html, which is deliberately NOT sticky, and
 * assets/css/checkout-chrome.css says so in as many words. So the property
 * resolved to its `0px` fallback on every checkout request and the offset was
 * really just the spacing token beside it. Naming a header that is not on the
 * page was the whole of the defect; it cost nothing and would have started
 * costing the moment the site header learned to publish that value globally.
 */
@media (min-width: 900px) {
	#edd_checkout_form_wrap .edd-blocks__cart {
		position: sticky;
		top: 0;

		/*
		 * The scrollport's own margin, and the other half of the arrangement the
		 * columns section describes. `box-sizing` is stated rather than assumed:
		 * the cap above is a `max-width` and this padding has to come out of it,
		 * not be added to it, or the rail grows by six pixels and the seam moves.
		 */
		box-sizing: border-box;
		padding-inline: var(--f32-co-ring, 3px);

		/*
		 * Defensive, and unlike the numbers above this one is not measured: a
		 * rail row runs about 72px, so a cart clears a 1080px screen at around
		 * twelve items. Sticky has no answer for a box taller than the viewport
		 * - it pins the top and the bottom simply never arrives - and the bottom
		 * is where the total is. Capping the rail and letting it scroll inside
		 * itself keeps the total reachable.
		 *
		 * `svh` rather than `vh` for the reason checkout-chrome.css gives at
		 * length: on iOS the large viewport unit measures the screen with the
		 * address bar retracted, so a `vh` cap is taller than what is visible.
		 */
		max-height: 100svh;

		/*
		 * BOTH AXES ARE NAMED, AND THE SECOND ONE IS NOT DECORATION. CSS does
		 * not allow one axis to scroll while the other stays `visible`: set
		 * `overflow-y` alone and the used value of `overflow-x` is promoted from
		 * `visible` to `auto`. So this box was offering a horizontal scrollbar
		 * nobody asked for, and the moment the rail became 400px wide rather
		 * than the width of the whole grey column, it started showing one -
		 * measured on staging at 412px of content in a 400px box.
		 *
		 * The 12px is the remove button, and it is not a defect to chase. That
		 * control is `box-sizing: content-box` with 0.75rem of padding and
		 * -0.75rem of margin, so a 13px icon sits flush with the end of the row
		 * inside a 37px target that hangs 12px past it on both sides. The left
		 * overhang lands on the price and the right one used to land in the grey
		 * column's padding, where nobody could see it. Clipped, the target keeps
		 * 25 of its 37 pixels, and only above 900px - the stack does not cap the
		 * rail at all, so a phone keeps the whole of it.
		 *
		 * `hidden` and not `clip`, because `clip` is coerced to `auto` by the
		 * same rule that promoted `visible`. The cap exists to keep a long cart's
		 * total reachable by scrolling DOWN; sideways was never part of it.
		 *
		 * NAMING THE AXIS DID NOT START THE CLIPPING. `auto` clips at the padding
		 * box exactly as `hidden` does - it only adds a scrollbar, and a ring
		 * drawn one pixel to the LEFT of the content is at a negative scroll
		 * position, so it was never reachable by scrolling either. This box has
		 * been cutting focus rings for as long as it has had a cap. The padding
		 * above is what actually fixes that, for both axes and every control.
		 */
		overflow-x: hidden;
		overflow-y: auto;
		overscroll-behavior: contain;
	}
}

/* === Section headings ==================================================== */

/*
 * EVERY SECTION HEADING ON THIS FORM IS A `<legend>`, which is worth knowing
 * before reaching for a class that does not exist. EDD prints four of them -
 * "Personal info" from the Checkout Fields Manager, then "Billing Details",
 * "Payment Method" and "Payment Info" from EDD itself - and each one is the
 * accessible name of the fieldset it opens. The reference's headings are 20px at
 * 600, measured, and that is what these become.
 *
 * The words are deliberately NOT changed to the reference's "Contact",
 * "Delivery" and "Payment". Three of the four are EDD's own translated strings
 * and the fourth is a label an administrator can edit in wp-admin; a theme that
 * rewrote them would be overruling both, and would do it in a way no translator
 * could reach.
 *
 * `float: none` and `padding: 0` are the user-agent defaults being undone.
 * Browsers still ship a legend with padding, and Chromium still lets a legend
 * shrink-wrap; both of those are visible the moment a legend is given a size.
 */
#edd_checkout_form_wrap #edd_purchase_form legend {
	display: block;
	float: none;
	width: 100%;
	margin: 0 0 var(--wp--preset--spacing--40, 1rem);
	padding: 0;
	color: var(--wp--preset--color--primary, #000);
	font-size: var(--f32-co-legend, 1.25rem);
	font-weight: 600;
	line-height: var(--f32-co-legend-lh, 1.2);
	letter-spacing: -0.01em;
}

/*
 * "Payment Info" is the one heading that goes. It opens the fieldset holding the
 * Stripe element, and it arrives immediately under "Payment Method" with only a
 * row of gateway tiles between them - two 20px headings 90px apart, both saying
 * payment. The reference has one heading there.
 *
 * VISUALLY HIDDEN AND NOT `display: none`, because the legend is the accessible
 * name of the fieldset around the card fields. Removing it from the page removes
 * the only thing that tells a screen reader what that group of fields is for.
 * This is the standard clip pattern, the same one .f32-cart-head__toggle uses.
 */
#edd_checkout_form_wrap #edd_cc_fields > legend {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	border: 0;
	clip-path: inset(50%);
	overflow: hidden;
	white-space: nowrap;
}

/*
 * The fieldsets themselves are the sections, and the design separates them with
 * air rather than with boxes. EDD borders and pads every `.edd-blocks-form`
 * fieldset - `border: 1px solid; padding: 2rem` - which is the nested-box look
 * this design exists to remove. forms.css zeroes fieldset margins site-wide, so
 * the 32px between sections has to be put back here.
 *
 * `:where(fieldset)` AND NOT `fieldset`, AND THIS FILE HAS NOW PAID FOR THAT
 * TWICE. A base rule is a default, and every later rule here that names one
 * fieldset is an exception to it and has to win. Spelled with a bare type
 * selector this rule is (2,0,1) - so a later rule naming a single fieldset by
 * id, which is (2,0,0), LOSES to the default it was written to override. That
 * is not a rule anyone reads as an override, so it failed quietly, twice:
 *
 *   #edd_cc_fields        kept `padding: 0`, and the payment panel showed its
 *                         grey fill with no frame around it - read on staging
 *                         as a stray background rather than as a surface.
 *   #edd_purchase_submit  kept `margin-top: 0`, and the consent checkbox sat
 *                         hard against the bottom of that panel with no air
 *                         between them at all.
 *
 * The first was repaired by adding a third id to the exception. That works and
 * it is the wrong repair: it leaves a default that every future exception has
 * to out-bid, and the next exception gets written with two ids exactly like the
 * last two were. The second defect is that repair's own bill arriving.
 *
 * `:where()` contributes ZERO specificity, so the type selector stops charging
 * for itself and this rule becomes (2,0,0). That is still far above what it has
 * to beat - forms.css zeroes fieldset margins site-wide at (0,1,2) - and it is
 * now exactly level with every id-scoped exception below, which win on source
 * order alone, with no arithmetic to get wrong. It is the same device core
 * wraps its own block-library defaults in, for the same reason: a default
 * should be the easiest thing on the page to override, not the hardest.
 */
#edd_checkout_form_wrap #edd_purchase_form :where(fieldset) {
	margin: 0 0 var(--f32-co-section, 2rem);
	padding: 0;
	border: 0;
}

/*
 * THE THREE FIELDSETS THAT ARE NOT SECTIONS, named rather than reached for with
 * `:last-of-type`. That was the first spelling and it was wrong twice over: EDD
 * nests fieldsets three deep, so `:last-of-type` matched the ONLY fieldset among
 * a set of siblings - "Personal info" and the billing block both qualified and
 * both lost their 32px - while the consent fieldset, which is genuinely last,
 * kept a 32px gap it has no use for.
 *
 *   #edd_payment_mode_select  opens the payment section and is joined to the
 *                             card fieldset below it; a gap would break the join.
 *   #edd_cc_fields            closes it, and what follows is the submit block,
 *                             which sets its own 32px from above.
 *
 * THE CONSENT FIELDSETS USED TO BE A THIRD ARGUMENT IN THIS `:is()` AND THAT
 * WAS THE BUG. `:is()` takes the specificity of its most specific argument,
 * so `:is(#edd_payment_mode_select, #edd_cc_fields, #edd_purchase_submit
 * fieldset)` was charged for `#edd_purchase_submit fieldset` - (1,0,1) - and
 * this selector came to (3,0,1). The rule meant to give those fieldsets 12px
 * was written at one id and lost by two, silently, and the comment here said
 * 12px for months while the browser computed 0.
 *
 * They are a rule of their own below, at (3,0,1), which is what they needed
 * all along: the exception list says WHICH fieldsets are not sections, and
 * the rule under it says what they are instead.
 */
#edd_checkout_form_wrap #edd_purchase_form :is(#edd_payment_mode_select, #edd_cc_fields) {
	margin-block-end: 0;
}

/*
 * A FIELDSET INSIDE THE SUBMIT FIELDSET IS A ROW. EDD wraps each consent in
 * one - terms and privacy policy are separate fieldsets and this site can
 * show either or both - and a row is spaced at `--f32-co-row`, not at the
 * section step.
 *
 * Reached by position rather than by id on purpose. The ids are EDD's
 * (`#edd_terms_agreement`, `#edd-privacy-policy-agreement`, and note that
 * one uses an underscore and the other a hyphen), the pair that renders
 * depends on two settings, and production shows a different combination from
 * staging. What makes these fieldsets rows is where they are, so that is
 * what the selector says.
 *
 * The 12px is what separates the two consents FROM EACH OTHER, and that is
 * now the whole of its work. It used to have a second job - holding the last
 * consent off the phone total bar - and that bar is gone; see "The total, on
 * phones". Below the last consent there is only the button, whose 16px top
 * margin is adjoining and collapses this 12 into itself at every width. So a
 * store showing one consent instead of two sees this rule change nothing,
 * which is correct: with one row there is no gap between rows to set.
 */
#edd_checkout_form_wrap #edd_purchase_form #edd_purchase_submit fieldset {
	margin-block-end: var(--f32-co-row, 0.75rem);
}

/*
 * EDD grids the billing row at a 20px gap; the reference uses 12px, which is the
 * same step this file gives two stacked fields. One number for both directions.
 */
#edd_checkout_form_wrap #edd_cc_address {
	gap: 0.75rem;
}

/* === Fields ============================================================== */

/*
 * THE BASE RULE HAS A WIDER REACH THAN IT LOOKS AND THAT IS DELIBERATE. It is
 * scoped to `#edd_purchase_form` and to element types, NOT to the field wrappers
 * below, because EDD Stripe measures this rule to style the inside of an iframe.
 *
 * WHAT EDD ACTUALLY DOES, read out of the plugin rather than guessed. Before it
 * mounts the Stripe Payment Element it builds
 * `<label id="edds-sample-label" class="edd-label"><input id="edds-sample-input"
 * class="edd-input" type="text"></label>`, inserts it immediately before
 * `#edd-stripe-payment-element`, reads `getComputedStyle()` off both, and passes
 * the result to Stripe's Appearance API as `.Input`, `.Input:focus`,
 * `.Input:hover`, `.Label`, `.CheckboxInput` and `.CodeInput` rules. Colour,
 * background, all four borders and the radius come off the input; font size,
 * weight, family and colour come off the label. See
 * easy-digital-downloads-pro/assets/src/js/frontend/gateways/stripe/
 * payment-elements/index.js::generateElementStyles.
 *
 * So the card fields inside Stripe's cross-origin iframe are styled by THIS
 * FILE, indirectly, and the only thing needed to keep them in step is that the
 * selector reaches a bare `input.edd-input` that is not inside one of our field
 * wrappers. An earlier note in this stylesheet said no selector here can reach
 * inside that iframe. That was true of direct styling and wrong about the
 * outcome, and it is why the theme and the card form used to disagree about what
 * a control looks like.
 *
 * inc/checkout.php closes the remaining half of the gap - label placement,
 * spacing and the accent - through EDD's `edds_stripe_payment_elements_*`
 * filters, which are the plugin's own documented seam for exactly this.
 */
/*
 * `:where()` AND NOT `:is()`, FOR THE REASON THE FIELDSET RESET A FEW HUNDRED
 * LINES BELOW GIVES AT LENGTH. This is the checkout's field DEFAULT - what a
 * text input looks like when nothing else has an opinion - and a default has to
 * be the easiest rule on the page to override. `:is()` takes the specificity of
 * its most specific argument, so spelled that way this rule is (2,1,1) and an
 * exception naming one field by its container's id, at (2,1,0), LOSES to it.
 *
 * That bill arrived the day the checkout moved to inner blocks. EDD's pattern
 * puts the cart INSIDE `#edd_purchase_form`, so this rule began reaching the
 * discount field, which had never been inside the purchase form before - and
 * `width: 100%` on a field that has to share its line with an Apply button put
 * the button on a line of its own.
 *
 * `:where()` contributes zero specificity, so the same list of types now costs
 * (2,0,0). That is still far above what it must beat - forms.css styles the same
 * inputs site-wide at (0,2,2) - and it is now below every id-scoped exception,
 * which is where a default belongs.
 */
#edd_checkout_form_wrap #edd_purchase_form :where(input[type="text"], input[type="email"], input[type="tel"], input[type="password"], input[type="number"], select) {
	box-sizing: border-box;
	width: 100%;
	margin: 0;
	padding: 0.8125rem 0.75rem;
	border: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
	border-radius: var(--wp--custom--border-radius--md, 8px);
	background: var(--wp--preset--color--contrast, #fff);
	color: var(--wp--preset--color--primary, #000);
	font-family: inherit;
	font-size: var(--f32-co-field-font, 1rem);
	line-height: 1.4;
}

/*
 * Focus is a ring and not a colour change, and the ring is the accent rather
 * than the black the button wears. `box-shadow` rather than `outline` so the
 * ring follows the 8px radius; the border darkens under it so the field still
 * reads as focused at a glance and for anyone who has forced-colours on.
 */
#edd_checkout_form_wrap #edd_purchase_form :is(input[type="text"], input[type="email"], input[type="tel"], input[type="password"], input[type="number"], select):focus {
	border-color: var(--wp--preset--color--primary, #000);
	box-shadow: 0 0 0 1px var(--wp--preset--color--primary, #000);
	outline: none;
}

/*
 * The label type, and it is set on `.edd-label` rather than on the wrapper's
 * child so that EDD's sample label - which is not inside a wrapper - gets the
 * same values and hands them to Stripe. 11px at 400 in the muted colour is what
 * the reference uses for a floated label, measured.
 */
#edd_checkout_form_wrap #edd_purchase_form .edd-label {
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.6875rem;
	font-weight: 400;
	line-height: 1;
	letter-spacing: 0.01em;
}

/*
 * The required asterisk goes. Every field on this form is required, so an
 * asterisk beside every label is a mark that distinguishes nothing - and at
 * 11px, floating over a field, it is noise. The reference marks none of its
 * fields. `aria-hidden` is not needed: the span is EDD's and carries no
 * accessible role, and the `required` attribute on the input is what actually
 * tells assistive technology the field is mandatory.
 */
#edd_checkout_form_wrap #edd_purchase_form .edd-required-indicator {
	display: none;
}

/*
 * THE NOTICE THE ASTERISK RULE ABOVE LEAVES BEHIND. Downloads > Settings >
 * Payments > Checkout has "Display a notice on forms explaining that fields
 * marked with an asterisk (*) are required". With it on, EDD prints
 * `<p class="edd-required-fields-notice">` at the top of the first column,
 * above the "Personal info" heading, and prefixes it with an asterisk of its
 * own - which the rule above hides along with the other five.
 *
 * inc/checkout.php rewrites the sentence to "All fields are required." through
 * `edd_required_fields_notice_text`, so the paragraph no longer names a mark
 * nobody can see. The header of that filter carries the whole argument,
 * including why un-hiding the asterisks would not have worked on a form with
 * floating labels. What is left here is the type.
 *
 * 13px in the muted colour is the size every other supporting line on this page
 * takes - the account link, the discount link, the trust line. EDD's own 16px
 * black would make an aside the loudest sentence in the column and out-shout
 * the heading two rows under it.
 *
 * NO RULE HIDES THIS PARAGRAPH, deliberately. The admin setting is what decides
 * whether it prints, and a theme that hid it would make that switch do nothing
 * and send the next person looking here for a bug that is not one.
 */
#edd_checkout_form_wrap #edd_purchase_form .edd-required-fields-notice {
	margin: 0 0 var(--wp--preset--spacing--40, 1rem);
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.8125rem;
	line-height: 1.4;
}

/* --- The floating label --------------------------------------------------- */

/*
 * WHAT A FLOATING LABEL ACTUALLY IS, since the name suggests animation and the
 * mechanism is nothing of the kind. Empty field: the label is not drawn, and the
 * input's own `placeholder` carries the field name at full size in the middle of
 * the box. Field with something in it, or field with focus: the placeholder is
 * gone by definition, the label appears in 11px at the top of the box, and the
 * input's padding moves the value down to sit under it. The box is the same
 * height in both states, so nothing on the page moves as the visitor types.
 *
 * THIS NEEDS A PLACEHOLDER ON EVERY FIELD, because `:placeholder-shown` is the
 * only thing in CSS that can tell a text input is empty. Two of the five fields
 * had one already - EDD gives the postal code "Postal / ZIP Code" and the
 * discount field "Enter discount code". The three Checkout Fields Manager fields
 * shipped `placeholder=""`, which is an attribute that is present and never
 * shown, so it matches nothing. inc/checkout.php fills them from each field's
 * own label through the plugin's `cfm_pull_field_characteristics` filter; see
 * the note there for why that is the seam and not the admin screen.
 *
 * `:has()` IS LOAD-BEARING AND THE WHOLE BLOCK IS GUARDED ON IT. The label has
 * to react to the state of a sibling that comes AFTER it in the DOM - EDD prints
 * label, then description, then input - and no sibling combinator looks
 * backwards. A browser without `:has()` gets the block skipped entirely and
 * reads a perfectly ordinary form with its labels above its fields, which is the
 * right thing to fall back to.
 */
@supports selector(:has(*)) {
	#edd_checkout_form_wrap #edd_purchase_form :is(.cfm-el, .edd-blocks-form__group) {
		position: relative;
		display: flex;
		flex-direction: column;
	}

	/*
	 * The label leaves the flow entirely, which is what lets the input own the
	 * full 48px of the box and the label sit on top of the first 18px of it.
	 * `pointer-events: none` so a click on the label's own pixels still lands on
	 * the input underneath; the `for` attribute would handle a click, but not a
	 * drag that starts on the label and ends in the value.
	 */
	#edd_checkout_form_wrap #edd_purchase_form :is(.cfm-el, .edd-blocks-form__group) > label {
		position: absolute;
		inset-block-start: 0.4375rem;
		inset-inline-start: 0.75rem;
		z-index: 1;
		max-width: calc(100% - 1.5rem);
		margin: 0;
		overflow: hidden;
		opacity: 0;
		pointer-events: none;
		text-overflow: ellipsis;
		white-space: nowrap;
		transition: opacity 120ms ease;
	}

	/*
	 * The two states that float it. A select is always one of the two: it has a
	 * value from the moment it renders, and `:placeholder-shown` never matches a
	 * select at all, so it is named separately rather than being left to a rule
	 * that cannot fire for it.
	 */
	#edd_checkout_form_wrap #edd_purchase_form :is(.cfm-el, .edd-blocks-form__group):has(:is(input, select):focus) > label,
	#edd_checkout_form_wrap #edd_purchase_form :is(.cfm-el, .edd-blocks-form__group):has(input:not(:placeholder-shown)) > label,
	#edd_checkout_form_wrap #edd_purchase_form :is(.cfm-el, .edd-blocks-form__group):has(select) > label {
		opacity: 1;
	}

	/*
	 * The value moves down by exactly what the label takes: 22px of top padding
	 * against 4px at the bottom, where the resting field has 13px at both ends.
	 * 22 + 4 is 26 and 13 + 13 is 26, so the box does not change height and the
	 * page does not reflow on the first keystroke.
	 */
	#edd_checkout_form_wrap #edd_purchase_form :is(.cfm-el, .edd-blocks-form__group):has(:is(input, select):focus) :is(input, select),
	#edd_checkout_form_wrap #edd_purchase_form :is(.cfm-el, .edd-blocks-form__group):has(input:not(:placeholder-shown)) input,
	#edd_checkout_form_wrap #edd_purchase_form :is(.cfm-el, .edd-blocks-form__group) select {
		padding-block: 1.375rem 0.25rem;
	}

	/*
	 * The placeholder is the label until the label appears, so it is drawn at
	 * full strength rather than at the browser's default grey-on-grey - and it
	 * goes the moment the field takes focus, because at that point the real
	 * label has floated up and two copies of the same word would be on screen.
	 */
	#edd_checkout_form_wrap #edd_purchase_form input::placeholder {
		color: var(--wp--preset--color--muted, #6b7280);
		opacity: 1;
	}

	#edd_checkout_form_wrap #edd_purchase_form input:focus::placeholder {
		color: transparent;
	}
}

/*
 * The email field's description - "We will send the purchase receipt to this
 * address" - is printed BETWEEN the label and the input. With the label floating
 * over the input, that sentence would sit where the field goes. `order` puts it
 * back underneath, which is where a hint belongs and where the reference puts
 * its own.
 */
#edd_checkout_form_wrap #edd_purchase_form .cfm-el > .edd-description {
	order: 1;
	margin: 0.375rem 0 0;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.75rem;
	line-height: 1.4;
}

/*
 * The space between fields. EDD's own `.edd-blocks-form` grid gap is 1.25rem,
 * which is close enough to leave alone where EDD owns the layout; the Checkout
 * Fields Manager fieldset has no gap of its own and needs one.
 *
 * THE FIELDS ARE NOT JOINED INTO SHARED-BORDER GROUPS, and that is a deliberate
 * omission rather than an oversight. The reference draws City / Province /
 * Postal as one rounded box with two hairlines inside it, which is handsome and
 * is also three negative margins, six corner overrides and a z-index that has to
 * win on focus. It buys that at the price of breaking the first time EDD adds a
 * state field to the row - which it does, for any country that has states. This
 * store's billing block is two fields wide. Separate rounded controls with a gap
 * read as the same design and cannot come apart.
 */
#edd_checkout_form_wrap #edd_purchase_form .cfm-el + .cfm-el {
	margin-block-start: 0.75rem;
}

/* === The payment block =================================================== */

/*
 * The gateway chooser becomes the reference's payment card: one bordered box
 * with a row per method, a real radio at the head of each row, the brand icons
 * pushed to the far end, and the chosen row filled rather than outlined.
 *
 * EDD draws it as a flex ROW of outlined tiles. A row works while there are two
 * gateways and stops working at three; a stacked list is what both Shopify and
 * Stripe ship, and it is what the Stripe Payment Element itself renders below
 * when its layout is `accordion` - which is the setting this store runs. So the
 * chooser and the thing under it finally use one idiom.
 */
#edd_checkout_form_wrap #edd-payment-mode-wrap {
	display: flex;
	flex-direction: column;
	gap: 0;
	margin: 0;
	border: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
	border-radius: var(--wp--custom--border-radius--md, 8px);
	overflow: hidden;
}

#edd_checkout_form_wrap #edd-payment-mode-wrap label.edd-gateway-option {
	display: flex;
	align-items: center;

	/*
	 * EDD centres the tile's contents, which is right for a tile and wrong for a
	 * row: it put the radio and the method's name in the middle of a 470px line
	 * with white space at both ends. A list is read down its leading edge.
	 */
	justify-content: flex-start;
	gap: 0.75rem;
	margin: 0;
	padding: 0.875rem 1rem;
	border: 0;
	border-radius: 0;
	background: var(--wp--preset--color--contrast, #fff);
	font-size: 0.875rem;
	font-weight: 500;
	cursor: pointer;
}

#edd_checkout_form_wrap #edd-payment-mode-wrap label.edd-gateway-option + label.edd-gateway-option {
	border-top: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
}

#edd_checkout_form_wrap #edd-payment-mode-wrap label.edd-gateway-option-selected {
	background: var(--wp--preset--color--subtle, #f5f5f5);
	box-shadow: none;
}

/*
 * THE RADIO COMES BACK. EDD hides it with `position: absolute; opacity: 0` and
 * marks the chosen tile with a border instead, which leaves a row of methods
 * with no visible control on it - the visitor is told what is selected and not
 * what kind of thing they are looking at. Every checkout the reference is drawn
 * from shows the dot.
 *
 * All four of EDD's hiding declarations are undone rather than the one that
 * happens to be doing the work today, so this keeps working if EDD swaps
 * `opacity` for a clip or a zero size.
 *
 * `accent-color` is what paints the dot black without replacing the control with
 * a hand-built one. A hand-built radio is a `appearance: none` box plus a
 * `:checked::after`, and it loses the platform's own focus and forced-colours
 * behaviour on the one form where that matters most.
 */
#edd_checkout_form_wrap #edd-payment-mode-wrap input.edd-gateway {
	position: static;
	flex: none;
	width: 1rem;
	height: 1rem;
	margin: 0;
	opacity: 1;
	clip-path: none;
	accent-color: var(--wp--preset--color--primary, #000);
}

/*
 * The brand icons go to the far end of the row, which is where the reference
 * puts them and where they stop competing with the method's name. This replaces
 * the `justify-content: center` further up this file, which centred them inside
 * a tile that no longer exists.
 *
 * TWO IDs, AND THE SECOND ONE IS NOT DECORATION. EDD prints
 * `.wp-block-edd-checkout #edd-payment-mode-wrap .edd-payment-icons` — (1,2,0),
 * and printed INLINE in the document, so it wins on weight and on order both.
 * A one-ID selector here was measured losing to it: the auto margin computed to
 * 0px and the icons sat against the method's name instead of at the end of the
 * row. Naming the wrap by its ID costs no new assumption — this rule only ever
 * meant the icons inside the gateway chooser — and takes the row out of that
 * argument for good.
 */
#edd_checkout_form_wrap #edd-payment-mode-wrap .edd-payment-icons {
	margin-inline-start: auto;
	justify-content: flex-end;
	gap: 0.25rem;
}

/*
 * The card fields, joined to the bottom of the chooser so the two read as one
 * object - the reference's "Credit card" header with the card form under it.
 * The fill is the same `subtle` the chosen row takes, which is what carries the
 * selection down into the fields it applies to.
 *
 * BOTH HALVES OF THE JOIN ARE GUARDED, because either one can be absent. EDD
 * drops the chooser when only one gateway is enabled, and it replaces the card
 * fieldset wholesale when the chosen gateway is PayPal. `:has()` asks the parent
 * whether the other half is on the page, which is the only question that can be
 * asked in the right direction for a preceding sibling.
 *
 * TWO IDS, AND THE THIRD ONE IS GONE ON PURPOSE. This rule briefly carried a
 * third id, added to out-bid the fieldset reset several hundred lines above it,
 * which was (2,0,1) and was eating the `padding` here. That reset is now
 * `:where(fieldset)` and costs (2,0,0), so an exception no longer has to buy
 * its way past a default - it only has to come later in the file, which this
 * does. The id is removed rather than left in as harmless ballast: an escalated
 * selector is a standing instruction to the next reader to escalate too, and
 * that instruction is what produced the second bug it was patching.
 */
#edd_checkout_form_wrap #edd_cc_fields {
	margin: 0;
	padding: 1rem;
	border: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
	border-radius: var(--wp--custom--border-radius--md, 8px);
	background: var(--wp--preset--color--subtle, #f5f5f5);
}

#edd_checkout_form_wrap .edd-blocks__payment-details:has(#edd_cc_fields) #edd-payment-mode-wrap {
	border-end-start-radius: 0;
	border-end-end-radius: 0;
	border-bottom: 0;
}

#edd_checkout_form_wrap .edd-blocks__payment-details:has(#edd-payment-mode-wrap) #edd_cc_fields {
	border-start-start-radius: 0;
	border-start-end-radius: 0;
}

/*
 * EDD's own security line - a padlock and "This is a secure SSL encrypted
 * payment", printed inside the card fieldset by `edds_credit_card_form()` behind
 * an `is_ssl()` check and behind no filter at all.
 *
 * IT IS OFF BECAUSE IT IS SAID TWICE. `f32_checkout_trust_line()` in
 * inc/checkout.php already prints a padlock and "Secured by Stripe" under the
 * pay button, which is where the reference puts its one trust line and which
 * names the processor rather than the transport. Two padlocks eight rows apart
 * making the same claim is weaker than one, and this was the copy that had to go
 * because it is the copy that cannot move: EDD hard-codes it inside the panel,
 * so it was also the thing putting text on the grey above the card tile.
 *
 * `display: none` and not a PHP removal, because there is nothing in PHP to
 * remove - no action, no filter, no template part. The sentence is not lost to
 * anyone: it is EDD's own string and the claim survives in the line under the
 * button.
 */
#edd_checkout_form_wrap #edd_secure_site_wrapper {
	display: none;
}

/* === The pay button ====================================================== */

/*
 * BLACK, AND THAT IS THE ONE COLOUR DECISION ON THIS PAGE. The design before
 * this one gave the button the theme's `action` blue and made a rule of it -
 * "exactly one accent colour and it belongs to the pay button". The rule is
 * kept; the colour changes, because the reference's pay button is black and
 * because black is what makes the rest of the page read as a Shopify checkout
 * rather than as a blue form. `primary` #000000 is already this theme's ink, so
 * this introduces no new value.
 *
 * Full width of the form measure at 15px of vertical padding, which lands the
 * control at the reference's measured 50px.
 *
 * The colour has to be stated here at all because forms.css paints every
 * `input[type="submit"]` on the site with the accent and a pill radius, and this
 * one is an `<input type="submit" class="edd-submit button">`. The ID beats
 * forms.css's `(0,1,1)` on weight rather than on print order, which matters:
 * forms.css is enqueued from a render_block filter and prints after this file.
 */
#edd_checkout_form_wrap #edd-purchase-button {
	display: block;
	width: 100%;
	max-width: none;

	/*
	 * 16px of air above it, because the thing directly above is a consent
	 * checkbox and the two were touching. The reference leaves the same step
	 * between its last line of fine print and "Pay now". The inline margin is
	 * zeroed in the same declaration: forms.css centres submit inputs, and a
	 * full-width control has nothing to centre.
	 */
	margin: var(--wp--preset--spacing--40, 1rem) 0 0;
	padding: 0.9375rem 1rem;
	border: 0;
	border-radius: var(--wp--custom--border-radius--md, 8px);
	background: var(--wp--preset--color--primary, #000);
	color: var(--wp--preset--color--contrast, #fff);
	font-size: 0.9375rem;
	font-weight: 600;
	line-height: 1.25;
}

#edd_checkout_form_wrap #edd-purchase-button:hover,
#edd_checkout_form_wrap #edd-purchase-button:focus-visible {
	background: color-mix(in srgb, var(--wp--preset--color--primary, #000) 85%, #fff);
	color: var(--wp--preset--color--contrast, #fff);
}

/*
 * The consent boxes and the button are the bottom of the form. The hairline that
 * used to separate them is gone with the card it belonged to: this design
 * separates with air, and 32px above the consent is the same step every other
 * section on the page takes - the same token, so that it stays the same step.
 *
 * This gap was measured at ZERO on staging before the reset above lost its type
 * selector: the checkbox touched the bottom edge of the card panel. Nothing was
 * wrong with the declaration; it simply never applied. See the note on that
 * reset for why, and do not answer a future instance of this by adding an id.
 */
#edd_checkout_form_wrap #edd_purchase_submit {
	margin-block-start: var(--f32-co-section, 2rem);
	padding-block-start: 0;
	border-top: 0;
}

/* === The order rail ====================================================== */

/*
 * NO CARD. The rail is content on a coloured ground, exactly as the reference
 * draws it - the grey IS the container, and a white box inside it would be a
 * second container saying the same thing. This undoes the panel treatment
 * further up this file, which was right for a summary standing on a white page
 * and is wrong for one standing on its own ground.
 */
#edd_checkout_form_wrap .edd-blocks-form__cart #edd_checkout_cart {
	margin: 0;
	border: 0;
	border-radius: 0;
	background: none;
}

#edd_checkout_form_wrap .edd-blocks-form__cart .edd-blocks-cart__row,
#edd_checkout_form_wrap .edd-blocks-form__cart .edd_cart_footer_row {
	padding-inline: 0;
	padding-block: 0.75rem;
	border: 0;
}

/*
 * THE TITLE HAS TO BE THE THING THAT SHRINKS. EDD lays a cart row out as a
 * wrapping flex line and gives only the price a basis - `flex: 1 1 110px` on the
 * last child. The name keeps `flex: 0 1 auto`, so its base size is its own
 * max-content: thumbnail, gap and the whole product title on one line, measured
 * at 347px. That fits a cart page and it does not fit a 400px rail - name plus
 * gap plus price came to 473px, the line wrapped, and the price dropped under
 * the thumbnail at full width with nothing beside it.
 *
 * `min-width: 0` alone was not enough and the order of operations is why: a
 * flex line is broken up on the items' BASE sizes, and only then is what is left
 * on the line shrunk. At 347 + 16 + 110 the line still broke before any shrinking
 * could happen. So the row is told not to wrap, and then `min-width: 0` lets the
 * name go below its min-content width - a grid item will not, on its own - and
 * the title wraps to a second line inside the row while the price holds the
 * first. That is the reference's line item exactly.
 *
 * Scoped to `.edd-blocks-cart__items` and not to every row: the discount row and
 * the total row are the same class, they fit at 400px already, and a discount
 * field that cannot wrap away from its Apply button is a phone defect waiting.
 */
#edd_checkout_form_wrap .edd-blocks-form__cart .edd-blocks-cart__items .edd-blocks-cart__row {
	flex-wrap: nowrap;
}

#edd_checkout_form_wrap .edd-blocks-form__cart .edd-blocks-cart__items .edd_cart_item_name {
	flex: 1 1 auto;
	min-width: 0;
}

#edd_checkout_form_wrap .edd-blocks-form__cart .edd-blocks-cart__items .edd_cart_item_price {
	flex: 0 0 auto;
}

/*
 * EDD opens the cart with a table-header row reading "Item Name" / "Item Price".
 * That is an honest label for a full-width cart page and the wrong object for a
 * rail; inc/checkout.php prints a real "Order summary" heading in its place and
 * this hides the row. Hidden rather than emptied, because the text is EDD's and
 * translated, and a theme that blanked it with `::before` would be lying to a
 * screen reader about what is there.
 */
#edd_checkout_form_wrap .edd-blocks-cart__row-header {
	display: none;
}

/*
 * "Your pass covers everything in the store", under the cart's rows.
 *
 * inc/cart-all-access.php takes the rows a pass in the cart already covers out of
 * the EDD cart, and prints them again here on `edd_cart_items_after`. The drawer
 * draws the same list against the same shelf - see section 9 of
 * assets/css/cart-preview.css - and the two have to look like the same object,
 * because they are the same list on two screens of one purchase.
 *
 * NO ARTWORK AND NO STRUCK PRICES, which is where it departs from the drawer. The
 * panel is a shopping surface and its rows are money; this sits under a cart that
 * has already totalled itself, and a second column of figures below a total
 * invites the reader to add them up. Names, and nothing beside them.
 *
 * THE HEADING IS A SENTENCE AND NOT A SECTION LABEL, which is a change from the
 * first cut and the reason the whole block was redrawn. It used to be set the way
 * every other label in this rail is - 10.5px, uppercase, tracked out - and that
 * treatment says "here is a category, and these are its members". Over two
 * product names, on the page where $84 is about to move, it meant "your pass
 * includes these two things". So the heading is now the size of the text it
 * governs and reads as prose, the names moved behind a lede that makes them an
 * example rather than a definition, and the per-row "Included" chip is gone: it
 * was the same claim a third time, in bold, at the end of every line.
 */
/*
 * THE BOTTOM MARGIN IS NOT COSMETIC AND IT IS THE SAME 16px THE ITEMS LIST USES.
 * `.edd-blocks-cart` is a GRID, so margins here add rather than collapse - which
 * makes the rail's spacing arithmetic rather than guesswork, and made this
 * visible. The items list ends with `margin-block-end: 1rem`; this panel had
 * `0.75rem` above and NOTHING below, so it sat 28px under the cart and flush
 * against the footer row, and the discount link directly beneath it inherited
 * the asymmetry: 12px of clearance above, 28 below. Matching the list's 16 puts
 * the same 28 on both sides of the discount row whether this panel is on the
 * page or not, which is the point - the rail must not re-space itself depending
 * on whether the cart happens to hold a pass.
 */
.f32-included {
	margin: 0.75rem 0 1rem;
	padding: 0.75rem 0.875rem;
	border-radius: 8px;
	background: var(--wp--preset--color--subtle, #f5f5f5);
}

.f32-included__label {
	margin: 0;
	color: var(--wp--preset--color--primary, #000);
	font-size: 0.8125rem;
	font-weight: 600;
	line-height: 1.4;
}

.f32-included__lede {
	margin: 0.125rem 0 0.375rem;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.75rem;
	line-height: 1.4;
}

.f32-included__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.f32-included__item {
	padding: 0.125rem 0;
	font-size: 0.8125rem;
	line-height: 1.4;
}

.f32-included__name {
	color: var(--wp--preset--color--muted, #6b7280);
}

/*
 * The rail's own heading. The reference has none - its summary starts with the
 * first line item - but ours carries the phone disclosure, and a control with no
 * name is not a control. It is set at the size of a section label rather than at
 * the 20px the form's headings take, because it names a column and not a step.
 */
.f32-cart-head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;

	/*
	 * Two values, and the row gap is the smaller one. Wrapping only happens on a
	 * phone too narrow to hold the heading, the offer pill and the disclosure on
	 * one line; 16px of air between two halves of a single head would read as two
	 * headings, and 8px reads as one that ran out of room.
	 */
	gap: 0.5rem var(--wp--preset--spacing--40, 1rem);
	margin: 0 0 0.5rem;
	padding: 0;
	border: 0;
}

.f32-cart-head__title {
	margin: 0;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	text-transform: uppercase;
}

/*
 * The offer, as a pill beside the heading. inc/cart-offer.php decides whether
 * there is one and inc/checkout.php prints it; this is the paint.
 *
 * NEUTRAL, NOT GREEN, and that is the one decision worth defending here. The
 * checkout has exactly one green - `.f32-cart-saved` a few hundred lines down,
 * the note under the total - and it means a saving that has already happened.
 * This pill is an offer the shopper has not met yet. Tinting it the same colour
 * would make the page congratulate a cart of one, and would spend the only
 * signal the rail has for real money on a maybe.
 *
 * `margin-right: auto` IS THE WHOLE LAYOUT. The head is a flex row of three
 * things - the heading, this, and the phone disclosure whose own `margin-left:
 * auto` holds it against the far edge. Two auto margins facing each other across
 * the same gap absorb the same free space, so the pill stays with the heading it
 * qualifies and the control stays where it has always been, at both widths and
 * with no media query. Above 900px the label is `display: none` and the pill
 * simply sits next to the title with nothing to push.
 *
 * `flex-wrap: wrap` on the head above is the safety net, not the plan: on a
 * phone narrow enough that a title, a pill and a disclosure will not share a
 * line, the disclosure drops to a second row rather than the three of them
 * crushing together. `white-space: nowrap` keeps the pill itself from breaking
 * across "10% off" and "2+ items", which is the one break that would read as two
 * separate claims.
 *
 * 12px sits under the 13px heading on purpose. It is a qualifier on that
 * heading, and a qualifier set at the size of the thing it qualifies stops being
 * one.
 *
 * A HAIRLINE AND NO FILL, because the fill was measured and there is none to be
 * had. `subtle` is #f5f5f5 and the checkout's ground is `page`, #f9fafb - four
 * units apart, which paints a pill nobody can see and leaves 12px of muted grey
 * sitting beside 13px of muted grey, reading as a second half of the heading
 * rather than as a tag. #e0e0e0 is the hairline this store already draws its
 * cart rows and its drawer rules with, so the pill gets an edge without the page
 * gaining a colour.
 */
.f32-cart-head__offer {
	margin-right: auto;
	padding: 0.125rem 0.5rem;
	border: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
	border-radius: 999px;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.75rem;
	font-weight: 500;
	line-height: 1.35;
	white-space: nowrap;
}

/*
 * THE CHECKBOX IS FUNCTIONAL AND MUST NOT BE `display: none`. A hidden-with-
 * display input is removed from the accessibility tree and from the tab order,
 * which would make the disclosure keyboard-unreachable - the control would still
 * work for a mouse and vanish for everybody else. Clipped to a 1px box instead,
 * the standard visually-hidden treatment, so it keeps focus and the label keeps
 * toggling it.
 *
 * Above 900px it is `display: none` and that IS correct there, because the label
 * that names it is gone too and an invisible unlabelled control in the tab order
 * is worse than no control. That rule is with the columns further up.
 *
 * `:focus-visible` on the checkbox draws its ring on the LABEL, which is the
 * thing the visitor can actually see. Without it, tabbing to the control would
 * move focus to a 1px clipped box and show nothing at all.
 */
.f32-cart-head__toggle {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	border: 0;
	clip-path: inset(50%);
	overflow: hidden;
	white-space: nowrap;
}

/*
 * The disclosure's label, and it ships hidden. The summary is only ever folded
 * on a phone; the rule that shows this is in the phone block at the bottom of
 * this section, beside the one that does the folding, so the two cannot get
 * separated.
 *
 * SCOPED TO THE WRAP, AND IT HAS TO BE, FOR THE REASON THE CONSENT ROWS ARE
 * SCOPED TO `#edd_purchase_submit`. forms.css says
 * `form:is(.edd_form, .edd-blocks-form, .wp-block-search) label {display:block}`
 * for every form on the site - (0,2,2) - and a bare `.f32-cart-head__label` is
 * (0,1,0). Written that way this rule lost both of its jobs: above 900px the
 * label rendered instead of hiding, putting a live "2 items" disclosure with a
 * chevron on the desktop rail next to a checkbox that is `display: none`, and
 * below 900px the phone rule's `inline-flex` lost too, so the label's own
 * `gap` and `align-items` did nothing and the chevron sat against the text.
 *
 * The cart moved inside `#edd_purchase_form` with the inner-blocks change, so
 * forms.css began reaching a label it had never reached before - the same
 * event, and the same kind of surprise, as the discount field's `width: 100%`
 * a few hundred lines below.
 */
#edd_checkout_form_wrap .f32-cart-head__label {
	display: none;
	align-items: center;
	gap: 0.5rem;
	margin: 0 0 0 auto;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.875rem;
	font-weight: 500;
	cursor: pointer;
}

.f32-cart-head__toggle:focus-visible + .f32-cart-head__label {
	outline: 2px solid var(--wp--preset--color--primary, #000);
	outline-offset: 2px;
	border-radius: var(--wp--custom--border-radius--sm, 4px);
}

/* The chevron, which flips when the summary is open. */
.f32-cart-head__more {
	display: inline-block;
	width: 0.5rem;
	height: 0.5rem;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: translateY(-2px) rotate(45deg);
	transition: transform 0.15s ease;
}

.f32-cart-head__toggle:checked + .f32-cart-head__label .f32-cart-head__more {
	transform: translateY(2px) rotate(-135deg);
}

/*
 * The item row. EDD lays it out as a wrapping flex line with the title block
 * first and the price block last; the design keeps that and fixes only the
 * proportions - the thumbnail at 48px with 8px rounding, the title at 13px, the
 * price tabular so two prices stacked line up on the decimal.
 *
 * The thumbnail's WIDTH is not set here. inc/checkout.php raises EDD's
 * `thumbnail_width` attribute from 25 to 48 so WordPress picks the right
 * intermediate size and builds the srcset from it; a CSS width would have scaled
 * a 25px file up and shipped a blurred image. All this does is round the corners
 * and stop a non-square source from distorting.
 */
#edd_checkout_form_wrap .edd_cart_item_image img {
	width: 48px;
	height: 48px;
	border-radius: var(--wp--custom--border-radius--md, 8px);
	object-fit: cover;
}

#edd_checkout_form_wrap .edd_checkout_cart_item_title {
	font-size: 0.8125rem;
	font-weight: 600;
	line-height: 1.35;
}

#edd_checkout_form_wrap .edd_cart_item_price {
	color: var(--wp--preset--color--primary, #000);
	font-size: 0.8125rem;
	font-variant-numeric: tabular-nums;
}

/*
 * The remove control is EDD's trash glyph, and it stays a glyph. The reference
 * draws a "Remove" text link, and swapping the glyph for text would mean either
 * replacing EDD's anchor - which carries the nonce that makes removal work - or
 * hiding it and printing our own, which is two removal controls in one DOM.
 * Neither is worth a word. What it gets instead is a hit area: EDD sizes it at
 * 1em square, which is a 16px target and below every touch guideline there is.
 */
#edd_checkout_form_wrap .edd-blocks-cart__action-remove {
	box-sizing: content-box;
	padding: 0.75rem;
	margin: -0.75rem;
	color: var(--wp--preset--color--muted, #6b7280);
}

/*
 * A hairline above the arithmetic, which is what turns "more rows" into "this is
 * what it costs". It is the only rule in the rail, and it is drawn in the ground
 * rather than in a border colour meant for white.
 *
 * IT IS DRAWN UNDER THE ITEMS AND NOT OVER THE NEXT ROW, and the `+` this
 * replaces is the reason the section below this one exists.
 * `.edd-blocks-cart__items + .edd_cart_footer_row` assumed the arithmetic starts
 * immediately after the items. It does not, in either direction: EDD prints a fee
 * row for every automatic per-item discount BETWEEN the two, and the row that
 * does follow the items on a plain cart - the discount-code row - ships an inline
 * `display: none` until a code is applied. So the line was landing either on a
 * row that is not the arithmetic or on a hidden one, and on this store it never
 * drew at all.
 *
 * What was visible in its place was EDD's own `1px solid #eee` on the items
 * CONTAINER, which survived this file's `border: 0` because that reset targets
 * rows and this is their parent. The declaration below overwrites that one, so
 * the number of lines in the rail is unchanged; only the colour and the spacing
 * move, and they move to the values the rule above always intended.
 *
 * On a folded phone summary the items are `display: none` and the line goes with
 * them. That is what the `+` rule did too, and it is right: with nothing above
 * the total there is nothing to separate it from.
 */
#edd_checkout_form_wrap .edd-blocks-form__cart .edd-blocks-cart__items {
	margin-block-end: 1rem;
	border-bottom: 1px solid var(--wp--preset--color--border-strong, #d1d5db);
}

#edd_checkout_form_wrap .edd_cart_footer_row {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	align-items: center;
	gap: 0.75rem;
}

/* --- Automatic per-item savings ------------------------------------------- */

/*
 * THE FEE ROW, FOR EVERY FEE THIS THEME DOES NOT FOLD AWAY. A store fee, a
 * handling charge, an add-on's own line - and, in a browser without `:has()`, the
 * automatic per-item discounts as well.
 *
 * It needs its own rule because it carries `.edd_cart_fee` and NOT
 * `.edd_cart_footer_row`, and that one missing class is the whole reason the
 * automatic discounts arrived on this page unstyled: every rule above was keyed
 * to the class EDD does not put on a fee row. Measured before this rule, on a cart
 * of two discounted products: 107.2px per fee row against 145px for both product
 * rows together, 16px type against the 13px of the titles it repeated, and the
 * amount on a line of its own because the label's max-content width beat the
 * 400px rail and EDD's `flex-wrap: wrap` broke the line rather than shrinking the
 * label. The three declarations that fix it are the same three
 * `.edd-blocks-cart__items .edd-blocks-cart__row` gets further up, for the same
 * reason.
 */
#edd_checkout_form_wrap .edd_cart_fee {
	display: flex;
	flex-wrap: nowrap;
	justify-content: space-between;
	align-items: baseline;
	gap: 0.75rem;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.8125rem;
	text-align: left;
}

#edd_checkout_form_wrap .edd_cart_fee .edd_cart_fee_label {
	min-width: 0;
}

#edd_checkout_form_wrap .edd_cart_fee .edd_cart_fee_amount {
	flex: 0 0 auto;
	font-variant-numeric: tabular-nums;
}

/*
 * ONE MARKER, THREE CONSEQUENCES. inc/checkout.php prints
 * `.f32-cart-fee-folded` inside the fee row of every per-item automatic saving,
 * and the rules below read it three times: fold that row, strike the item's list
 * price, show the note under the total.
 *
 * Written this way round on purpose. A browser without `:has()` matches none of
 * the three and gets today's checkout - the fee rows printed as EDD wrote them,
 * plain list prices beside the items, no note - which is the only safe way for
 * this to fail. Folding the rows while the strike-through did not apply would
 * hide a discount the visitor then cannot find; applying the strike while the
 * rows stayed would show the same saving twice. Neither half is allowed to ship
 * without the other, so both hang off the same condition.
 *
 * It is the same construction the phone disclosure at the bottom of this file
 * uses, and it is here for the same reason: EDD builds the fee row's class list
 * in cart-fees.php and offers no filter on it, so a theme that cannot reach the
 * parent asks about the child instead.
 *
 * IT CARRIES THE ID, and the first cut of this rule did not. `#edd_checkout_form_wrap`
 * on the fee-row rule above makes that declaration (1,1,0); a bare
 * `.edd_cart_fee:has(> .f32-cart-fee-folded)` is (0,2,0), so `display: flex` beat
 * `display: none` and the rows stayed on screen with the struck prices already
 * printed beside them - the saving shown twice, which is the one outcome the
 * marker exists to prevent. Measured on staging before the id was added.
 */
#edd_checkout_form_wrap .edd_cart_fee:has(> .f32-cart-fee-folded) {
	display: none;
}

/*
 * The item's two prices, STACKED. Side by side they measure about 95px and the
 * rail has 400: the title was seen wrapping to a third line to pay for them.
 * Stacked they cost 45px and no height at all, because the row is already 48px
 * tall for the thumbnail.
 */
.f32-cart-price {
	display: inline-flex;
	flex-direction: column;
	align-items: flex-end;
	line-height: 1.25;
}

/*
 * These two are the no-`:has()` state, and they are today's rendering exactly:
 * the charged price is not shown and the list price is not struck, so the item
 * reads as it does now and the fee row below it is still doing the work.
 */
.f32-cart-price__now {
	display: none;
}

.f32-cart-price__was {
	text-decoration: none;
}

#edd_checkout_cart:has(.f32-cart-fee-folded) .f32-cart-price__now {
	display: block;
	color: var(--wp--preset--color--primary, #000);
}

#edd_checkout_cart:has(.f32-cart-fee-folded) .f32-cart-price__was {
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.6875rem;
	font-weight: 400;
	text-decoration: line-through;
	text-decoration-thickness: 1px;
}

/*
 * The note under the total, and it is the only green on the checkout.
 *
 * theme.json's palette carries none - the block comment at the top of
 * assets/css/order-receipt.css sets out why a green that exists solely to say
 * "this went well" was not made a preset - so the value is declared here the way
 * that file declares it, and it is the same number: #15803d, green-700, which
 * clears 4.5:1 on the rail's `page` ground. Two files, one value. If a third ever
 * needs it, that is the moment it becomes a preset, and not before.
 *
 * It ships hidden for the reason given above: it describes strikes that a browser
 * without `:has()` never drew.
 */
.f32-cart-saved {
	--f32-checkout-saved: #15803d;

	display: none;
	align-items: flex-start;
	justify-content: flex-end;
	gap: 0.375rem;
	width: 100%;
	margin: 0;
	color: var(--f32-checkout-saved);
	font-size: 0.75rem;
	text-align: start;
}

/*
 * THE BLOCK IS RIGHT-ALIGNED AND THE SENTENCE IS NOT, which sounds like a
 * contradiction and is the only arrangement that works at both widths.
 *
 * `justify-content: flex-end` is what holds the note against the total it
 * describes. `text-align` used to be `right` as well, which is invisible on a
 * rail wide enough for one line and wrong the moment there are two: the
 * second line hugged the far edge, leaving a ragged left margin under the
 * first and the tick orphaned at the other side of the row. At a 345px column
 * this is the ordinary case, not the edge one.
 *
 * `start` sets the wrap under the sentence's own first character, and
 * `align-items: flex-start` keeps the tick on the first line for the same
 * reason the consent checkbox stays on its own - the mark belongs to the
 * sentence's opening, not to the middle of a paragraph.
 */

#edd_checkout_cart:has(.f32-cart-fee-folded) .f32-cart-saved {
	display: flex;
}

/*
 * The note arrives inside EDD's footer-buttons row, which is the only hook below
 * the total that is still inside the cart. That row is built for buttons and
 * opens with the rail's 12px of air; under a total the note reads as a caption on
 * it, so the air above is removed and the total's own bottom padding sets the
 * distance. Scoped with `:has()` so a row that really is holding EDD's "Save
 * cart" button keeps its spacing.
 */
#edd_checkout_form_wrap .edd_cart_footer_row:has(> .f32-cart-saved) {
	padding-block-start: 0;
}

.f32-cart-saved__icon {
	flex: none;
}

/* --- The discount field --------------------------------------------------- */

/*
 * IT IS SHUT, AND SHUTTING IT WAS THE REMOVAL OF TWO `!important`s. This pair of
 * rules used to force `#edd-discount-code-wrap` open and hide
 * `#edd_show_discount`, which meant the stylesheet and EDD's script were setting
 * `display` on the same two elements in opposite directions and the stylesheet
 * had to shout to win. Both are gone; the reasoning is in "Discount code
 * disclosure" near the top of this file.
 *
 * `width: 100%` stays and is the only thing left here. The wrap is a flex item
 * of the footer row - see `#edd_discount_code` below, which is the CELL - and
 * without it the field and Apply size to their content instead of to the rail.
 * It is not part of the disclosure and never was.
 *
 * `#edd-discount-error-wrap` is still not touched, for the reason the note
 * further up this file gives: that one is toggled at runtime by state the
 * visitor changes, and a stylesheet that overruled it would hide the discount
 * error forever. That is now true of the wrap and the link as well.
 */
#edd_checkout_form_wrap #edd-discount-code-wrap {
	width: 100%;
}

/*
 * `#edd_discount_code` IS A DIV. It is not the input, and the name is the whole
 * trap: EDD hangs that id on the cart footer's discount CELL, and the field
 * inside it is `input.edd-input` with no id of its own. This rule was read as
 * the input's once and its `flex` deleted as a duplicate; the cell then shrank
 * to 323px inside a 400px rail and took the field and the button with it.
 *
 * `flex: 1 1 100%` is the cell's own job and belongs here. The footer row is a
 * wrapping flex row that puts a label at one end of a line and a figure at the
 * other; the discount cell is not one of those pairs and needs a line to itself.
 *
 * `text-align: start` is the second half of the same job. Those footer rows are
 * right-aligned, which is what carries a price to the end of its line, and a
 * discount code drifting to the right inside a left-to-right field is the one
 * thing in the rail that must not inherit it.
 */
#edd_checkout_form_wrap #edd_discount_code {
	flex: 1 1 100%;
	text-align: start;

	/*
	 * THE ROW WAS SITTING OFF-CENTRE BETWEEN THE RULE AND THE TOTAL, and the
	 * asymmetry was built out of two numbers that never met. Above it: whatever
	 * precedes the footer row, plus the footer row's own 12px top padding. Below
	 * it: the footer row's 12px flex gap, and nothing else. Measured on staging -
	 * 28 above, 12 below - which reads as a row that belongs to the total rather
	 * than one standing between two things.
	 *
	 * "Whatever precedes" is two different things and both had to be made to
	 * agree. On a plain cart it is the items list, at `margin-block-end: 1rem`.
	 * On a cart holding a pass, inc/cart-all-access.php puts `.f32-included`
	 * between them, and that panel had no bottom margin at all - so the same
	 * discount row measured 28px of clearance on one kind of cart and 12 on the
	 * other. The panel now carries the same 1rem; see its rule above.
	 *
	 * 16px here makes the space below 12 + 16 = 28, the same sum spelled the same
	 * way. Not a 28px value written down once: the two gaps are built from the
	 * same two figures in the same order, so a change to either the list's margin
	 * or the row's gap moves both sides together instead of silently breaking the
	 * symmetry this rule exists to state.
	 *
	 * It applies open as well as shut, which is right. Once the field and Apply
	 * are on screen they need MORE clearance from the total, not less - that is
	 * the moment two controls are stacked directly above the number they change.
	 */
	margin-block-end: 1rem;
}

/*
 * Input and Apply as two controls with a gap, not one joined box. That is what
 * the reference does - measured, the field ends at x=777 and the button starts
 * at x=782 - and it is also the shape that survives the button's label being
 * translated into a longer word.
 */
#edd_checkout_form_wrap .edd-discount-code-field-wrap {
	display: flex;
	flex-wrap: nowrap;
	gap: 0.5rem;
	align-items: stretch;
}

/*
 * `flex-wrap: nowrap` IS LEFT-HAND-SIDE INSURANCE AND IT PAYS OUT ON A PHONE.
 * EDD's own sheet sets `wrap` on this span. At the rail's 400px the pair fits
 * and the wrap never fires; below about 380px of column it does, and Apply
 * drops onto a line of its own, left-aligned under a full-width field - 106px
 * of height doing the work of 50, and a stranded button that reads as broken.
 *
 * Told not to wrap, the field absorbs the difference instead: it already
 * carries `flex: 1 1 auto` and `min-width: 0` below, which is what lets a
 * flex item shrink past its content width. Measured at a 345px column, field
 * 241px and Apply 74px on one 50px line.
 */

/*
 * TWO IDS, AND THE SECOND ONE IS THE PRICE OF MOVING THE CART INSIDE THE FORM.
 *
 * The one declaration this rule cannot do without is `width: auto`. Without it
 * the field takes the whole 400px rail as its flex base and Apply - which cannot
 * shrink - drops onto a line of its own. Measured on staging: field 400px,
 * button on the next row, the pair 106px tall to do the work of 50.
 *
 * That is exactly what happened the day the checkout moved to inner blocks, and
 * nothing in this section changed to cause it. The cart used to be a sibling of
 * `#edd_purchase_form`; EDD's block pattern puts it INSIDE that form, so the
 * checkout's field default several hundred lines above began reaching a field it
 * had never reached before, and that default says `width: 100%`. It is written
 * with `:where()` now and costs nothing, so this rule wins by naming its own
 * scope rather than by out-bidding anything.
 *
 * `#edd_discount_code` is that scope: the cart cell the field lives in, named by
 * EDD, and naming it says what the exception is about. Note that the id is on
 * the CELL and not on the input - see the rule above, which was misread that way
 * once.
 */
#edd_checkout_form_wrap #edd_discount_code .edd-input {
	flex: 1 1 auto;
	width: auto;
	min-width: 0;
	padding: 0.8125rem 0.75rem;
	border: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
	border-radius: var(--wp--custom--border-radius--md, 8px);
	background: var(--wp--preset--color--contrast, #fff);
	font-size: var(--f32-co-field-font, 1rem);
	line-height: 1.4;
}

/*
 * Apply is a SECONDARY control and is drawn as one. It sits a few hundred pixels
 * from the pay button, and giving it the same fill would put two equally loud
 * calls to action on a page whose whole job is to funnel to one. It is drawn
 * heavier than the link that revealed it, and that is the right order: by the
 * time Apply is on screen the visitor has said they have a code.
 */
#edd_checkout_form_wrap .edd-apply-discount {
	flex: none;
	margin: 0;
	padding: 0.8125rem 1rem;
	border: 1px solid var(--wp--preset--color--border-subtle, #e0e0e0);
	border-radius: var(--wp--custom--border-radius--md, 8px);
	background: var(--wp--preset--color--contrast, #fff);
	color: var(--wp--preset--color--primary, #000);
	font-size: 0.875rem;
	font-weight: 600;
	line-height: 1.4;
}

#edd_checkout_form_wrap .edd-apply-discount:hover,
#edd_checkout_form_wrap .edd-apply-discount:focus-visible {
	background: var(--wp--preset--color--subtle, #f5f5f5);
	border-color: var(--wp--preset--color--border-strong, #d1d5db);
}

/* --- The total ------------------------------------------------------------ */

/*
 * NO MINT PILL. The total used to take the `price` badge every product card
 * wears, on the argument that it is the one number the visitor is deciding
 * about. On a white card among white rows that was true. On a grey rail whose
 * last row is already the loudest thing in the column it is a second signal for
 * something that is not ambiguous, and the reference simply sets it larger and
 * bolder than everything above it.
 */
#edd_checkout_form_wrap .edd_cart_total {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	width: 100%;
	gap: 0.75rem;
	color: var(--wp--preset--color--primary, #000);
	font-size: 1rem;
	font-weight: 600;
}

#edd_checkout_form_wrap .edd_cart_total .edd_cart_amount {
	display: inline;
	padding: 0;
	border-radius: 0;
	background: none;
	font-size: 1.25rem;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	letter-spacing: -0.01em;
}

/*
 * THE FOLD, and it only exists below 900px. Above that the summary sits in its
 * own column with nothing to gain from being shut.
 *
 * `:has()` is what lets a checkbox fold a box it does not contain. The items are
 * EDD's `.edd-blocks-cart__items`, which EDD replaces wholesale over admin-ajax
 * on every discount and quantity change; a wrapper of ours around it would not
 * survive that, and a sibling selector does. The fold is written as "hide when
 * the box is CLEAR" rather than "show when it is checked", and inc/checkout.php
 * now ships the box CHECKED - so the summary opens open, and a browser without
 * `:has()` lands on the same arrangement by never applying the rule at all. The
 * two agree, which they did not when the default was collapsed.
 *
 * The footer rows are deliberately OUTSIDE the fold: the total and the discount
 * field stay on screen whether the summary is open or shut, which is what makes
 * the collapsed row a summary rather than a lid.
 */
@media (max-width: 899.98px) {
	/*
	 * AND IT IS A TAP TARGET, because on a phone this label is the only control
	 * over what the cart shows. It shipped at 60x20: a thumb is about 44px, so
	 * the control that folds the order summary was less than half the size of
	 * the finger aiming at it, which is the likeliest reading of "I don't see
	 * the items".
	 *
	 * 44px is WCAG 2.5.5, the enhanced target size, and this control earns the
	 * enhanced figure rather than the 24px minimum: it is the summary's primary
	 * affordance and a miss costs the visitor the answer to "what am I buying".
	 * The head grows with it and the title re-centres, so the row reads as a
	 * header rather than as a caption with a link stuck to it.
	 *
	 * `min-block-size` and not a negative-margin overhang. The overhang trick
	 * is what the remove buttons use and it is what gets them clipped by the
	 * rail's scrollport above 900px; there is no scrollport here, but there is
	 * also no reason to spend a pixel budget when the row can simply be taller.
	 */
	#edd_checkout_form_wrap .f32-cart-head__label {
		display: inline-flex;
		min-block-size: 2.75rem;
		padding-inline-start: 0.75rem;
	}

	#edd_checkout_cart:has(.f32-cart-head__toggle:not(:checked)) .edd-blocks-cart__items {
		display: none;
	}
}

/* === The trust line ====================================================== */

/*
 * inc/checkout.php prints these two lines on `edd_purchase_form_after_submit`,
 * which is the only hook that fires BELOW the button. Centred under it, muted,
 * and small enough that neither line competes with the price or the button -
 * they are read at the moment of doubt, not scanned on the way down.
 */
.f32-checkout__trust {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	margin: var(--wp--preset--spacing--40, 1rem) 0 0;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.8125rem;
}

.f32-checkout__trust:empty {
	display: none;
}

.f32-checkout__trust-icon {
	flex: none;
}

.f32-checkout__fine {
	margin: 0.5rem 0 0;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.75rem;
	text-align: center;
}

.f32-checkout__fine a {
	color: inherit;
}


/* ==========================================================================
 * THE EMPTY CART
 * ==========================================================================
 *
 * inc/checkout.php replaces EDD's one-sentence empty cart with `.f32-cart-empty`.
 * The markup is ours end to end, so this is the one part of the checkout where the
 * CSS gets to describe the design rather than negotiate with somebody else's DOM.
 *
 * IT IS ONE SECTION NOW. There was a bordered pass band under the hero - its own
 * surface, its own heading, its own link - and roughly ninety lines here drawing it.
 * All of it is gone, and the pass is the second button in the hero's action row
 * instead. The argument is in inc/checkout.php; the consequence here is that this
 * whole block is a centred column and nothing else, which is why there is no
 * surface token in it any more.
 *
 * IT HAS TO CAP AND PAD ITSELF. When the checkout wore the 1,180px panel this block
 * inherited a measure and a gutter from the template; the split layout took both
 * away, because a page whose ground has to reach the edge of the window cannot also
 * constrain its content. So the two declarations that used to come from `f32-panel`
 * are written here. The block padding matches the form column's on the populated
 * checkout, so the two states of this page start at the same distance below the
 * header.
 */

.f32-cart-empty {
	max-width: 900px;
	margin-inline: auto;
	padding: var(--f32-co-block, 3rem) var(--wp--preset--spacing--gutter, 1.25rem);
}

/*
 * 28rem, not the 26 it was. Two buttons side by side need about 24rem before they
 * wrap, and a measure that wraps them at the desktop width would make the stacked
 * phone layout the default everywhere.
 */
.f32-cart-empty__hero {
	max-width: 28rem;
	margin-inline: auto;
	padding-block: 2rem;
	text-align: center;
}

/*
 * The cart mark. A MARK AND NOT AN ILLUSTRATION, and the difference is the whole
 * argument: it used to be 42px of `action` blue inside an 88px disc tinted with
 * the same accent, sitting directly above the sentence "Your cart is empty" - a
 * picture and a heading saying one thing twice, and 112 vertical pixels to say it.
 *
 * At 40px in `muted` with no disc it does the job an icon is actually good at:
 * giving the section something to start on. It is the same glyph, drawn quieter -
 * and the stroke drops to 1.6 in the markup because a weight tuned for 42px reads
 * heavy at 40 with no fill behind it.
 */
.f32-cart-empty__icon {
	display: block;
	margin: 0 auto var(--wp--preset--spacing--30, 1rem);
	color: var(--wp--preset--color--muted, #6b7280);
	line-height: 0;
}

.f32-cart-empty__icon svg {
	width: 40px;
	height: 40px;
}

.f32-cart-empty__title {
	margin: 0 0 0.5rem;
	font-size: 1.375rem;
	letter-spacing: -0.01em;
}

.f32-cart-empty__lede {
	margin: 0 0 var(--wp--preset--spacing--50, 1.5rem);
	color: var(--wp--preset--color--muted, #6b7280);
}

/*
 * The action row. `flex-wrap` and a `gap` are the whole responsive story: below
 * about 26rem the second button drops under the first, full width, with no media
 * query and no number written down twice. `justify-content: center` rather than a
 * grid, because the row holds one button for a pass holder and two for everybody
 * else, and a centred flex row is the only arrangement that looks deliberate at
 * both counts.
 */
.f32-cart-empty__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	justify-content: center;
}

/*
 * The primary action. Same accent, same shape as the pay button on the populated
 * checkout, because it is the same promise in a different state of the page.
 *
 * The border is transparent and not absent so that this button and the outlined one
 * below are exactly the same height. Two buttons of different heights in one row is
 * the classic version of this bug and it is invisible until they sit side by side.
 */
.f32-cart-empty__cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0.75rem 1.5rem;
	border: 1.5px solid transparent;
	border-radius: var(--wp--custom--border-radius--md, 8px);
	background: var(--wp--preset--color--action, #1d4ed8);
	color: var(--wp--preset--color--contrast, #fff);
	font-weight: 600;
	text-decoration: none;
}

.f32-cart-empty__cta:hover,
.f32-cart-empty__cta:focus {
	background: color-mix(in srgb, var(--wp--preset--color--action, #1d4ed8) 85%, #000);
	color: var(--wp--preset--color--contrast, #fff);
}

/*
 * The pass. OUTLINED, NOT FILLED, and not a text link either.
 *
 * Filled would make the store choose for the shopper - two solid blue buttons and
 * no answer to which one you meant. A text link would put the pass back where it
 * has been all along, visibly secondary and easy to miss. An outline in the same
 * accent is the honest middle: equal size, equal position, less ink.
 *
 * It relies on source order to beat `.f32-cart-empty__cta` above - both are one
 * class, 0,1,0 - so these rules must stay after it in the file.
 */
.f32-cart-empty__cta--pass {
	border-color: var(--wp--preset--color--action, #1d4ed8);
	background: transparent;
	color: var(--wp--preset--color--action, #1d4ed8);
}

.f32-cart-empty__cta--pass:hover,
.f32-cart-empty__cta--pass:focus {
	background: color-mix(in srgb, var(--wp--preset--color--action, #1d4ed8) 8%, transparent);
	color: var(--wp--preset--color--action, #1d4ed8);
}

/*
 * The renewal terms. Small and grey because it CONFIRMS the offer rather than
 * making it - but it is still the store's whole price disclosure on this page, so
 * it sits directly under the buttons in the reading order, never below a link or
 * off in a corner. inc/checkout.php prints it only when a price actually resolved.
 */
.f32-cart-empty__terms {
	margin: 1rem 0 0;
	color: var(--wp--preset--color--muted, #6b7280);
	font-size: 0.8125rem;
}

/*
 * The free-presets link, and it is a LINK and not a third button. It prints only
 * when f32_checkout_free_url() resolves a category, which on this store it does not
 * yet - so this rule is written for a page nobody has seen. It goes last, under the
 * terms, because it is an alternative to the whole section rather than to either
 * button in it.
 */
.f32-cart-empty__alt {
	display: block;
	margin-block-start: 1rem;
	color: var(--wp--preset--color--action, #1d4ed8);
	font-size: 0.875rem;
	text-decoration: none;
}

.f32-cart-empty__alt:hover,
.f32-cart-empty__alt:focus {
	text-decoration: underline;
}

/* --- Cancelling out of the discount field --------------------------------- */

/*
 * assets/js/checkout-discount.js appends this button to
 * `#edd-discount-code-wrap` when the field is opened, and it exists only there:
 * with JavaScript off the field is permanently open and there is nothing to
 * cancel. That file carries the argument for why it is built by script rather
 * than printed and hidden.
 *
 * IT IS THE OPENING LINK, FACING THE OTHER WAY, so it is drawn as the opening
 * link - text, underlined, muted, 13px. The two controls are one control in two
 * states and a shopper should not have to work out that the way out is a
 * different kind of thing from the way in. The declarations are the same set the
 * disclosure rule near the top of this file lists, and they are repeated rather
 * than shared: that rule has to out-specify EDD's `.edd-button-secondary` fill
 * at (1,2,0) and carries two ids to do it, and this button is ours, inherits
 * nothing of EDD's, and needs none of that weight. Joining them would drag a
 * (2,1,0) selector onto an element that has no competition.
 *
 * ON ITS OWN LINE, ALIGNED LEFT UNDER THE FIELD. `#edd-discount-code-wrap` is
 * `width: 100%` and holds the field-and-Apply span; a block-level button after
 * it lands under the field rather than beside Apply, which is the only place it
 * can go without reading as a third thing to press in a row of two.
 *
 * The 24px minimum is the same target size, and for the same reason, as the link
 * that opened the field: quiet is paid for by the thumb unless the height is put
 * back without the fill.
 */
.f32-discount-cancel {
	display: inline-flex;
	align-items: center;
	min-block-size: 1.5rem;
	margin-block-start: 0.5rem;
	padding: 0;
	border: 0;
	background: none;
	color: var(--wp--preset--color--muted, #6b7280);
	font: inherit;
	font-size: 0.8125rem;
	font-weight: 500;
	text-decoration: underline;
	text-underline-offset: 0.2em;
	cursor: pointer;
}

.f32-discount-cancel:hover,
.f32-discount-cancel:focus-visible {
	color: var(--wp--preset--color--primary, #000);
}
