/* product-page-checkout.css
 *
 * The .ap-co (checkout/cart namespace) design system — the UNION of the
 * five checkout sandboxes' inline <style> blocks, extracted verbatim
 * (task 0017 checkout cutover, 2026-07-24) so the LIVE cart/checkout/
 * thank-you templates and all five sandboxes share ONE stylesheet —
 * same move as product-page-ago.css / product-page-list.css. Edit THIS
 * file; the sandboxes only link it.
 *
 * Dedupe notes: the summary/steps/method/form blocks were byte-identical
 * across delivery/payment/review and appear once. Two same-selector
 * variants existed as copy-paste drift (.ap-co__pay-options and
 * .ap-co__pay-option__logo img — review carried a stale copy of the
 * payment page's rules without rendering the markup); the PAYMENT page's
 * versions are canonical here (review's stale copies dropped). PHP-emitted
 * url() refs were rewritten to ../img/sandbox/… (resolve from assets/css/).
 *
 * Step scoping (2026-07-24): the per-page `.ap-co` base rules (page
 * insets) collided once merged — each surface's wrapper now carries a
 * step modifier (.ap-co--cart/--review/--delivery/--payment/
 * --confirmation) and the base rules are scoped to them. Every other
 * .ap-co__* rule stays step-agnostic.
 */


/* ══════════ from checkout-sandbox.php ══════════ */

/* Checkout body wrapper — horizontal page insets pin the content to the
   outer edge of grid column 2 / column 11 (`--grid-col2-inset`; its %
   resolves against the full-bleed `<main>`, i.e. the viewport — the
   Figma 245px inset is what this resolves to at the 1920 frame). 64px
   gap to the header's bottom edge, 192px gap to the footer's top edge.
   Vertical rhythm between internal sections is owned by each row's own
   top margin; sections are added in follow-up iterations against the
   Figma design. */
/* Scoped to the step modifiers (2026-07-24): the five sandboxes each
   carried their own `.ap-co` base rule; merged verbatim into one file
   they clobbered each other (confirmation's narrow col5 inset won
   everywhere — found with real data on the live cart). Cart + delivery
   share this shape (192px bottom); review + payment carry 88px (rule in
   the payment section); confirmation is its own centred layout. */
.ap-co--cart,
.ap-co--delivery {
	/* Summary panel width — four grid columns + the three gutters
	   between them, so the right-anchored panel spans from column 8's
	   outer edge to column 11's outer edge (2nd to 5th column counting
	   inwards from the right). Declared here so both the panel and the
	   items column's reservation below stay in lockstep. vw-based
	   `--grid-col-w` for the usual too-deep-in-the-flow reason. */
	--ap-co-summary-w: calc(4 * var(--grid-col-w, 109px) + 3 * var(--grid-gutter, 32px));
	padding: 64px var(--grid-col2-inset, 245px) 192px;
	position: relative; /* anchor for the absolutely-positioned summary panel */
}

/* Cart-items column — wraps every `.ap-co__item` + trailing `<hr>` and
   keeps the item content clear of the absolutely-positioned summary
   panel: 64px gap + the summary's grid-derived width. The title above
   stays full-width (not in this wrapper) so it reads as the page
   heading, not a column heading. */
.ap-co__items {
	margin-right: calc(64px + var(--ap-co-summary-w, 533px));
}

/* Item dividers span from column 2's outer edge (the content edge,
   where the items column starts) to column 6's far edge — five grid
   columns + the four gutters between them. vw-based `--grid-col-w`
   for the same too-deep-in-the-flow reason as the media tile above.
   The primitive's `margin: 32px 0 0` keeps the hairline left-aligned,
   so the explicit width simply stops it short on the right. */
.ap-co__items > .ap-pp__divider {
	width: calc(5 * var(--grid-col-w, 101px) + 4 * var(--grid-gutter, 32px));
}

/* Basket summary panel — pinned to the top-right of the inner padding
   area (64px from top, `--grid-col2-inset` from the right — i.e. the
   exact inner corner of `.ap-co`'s padding box; the % basis matches
   the padding's because `.ap-co` spans the full viewport width).
   Width is `--ap-co-summary-w` (columns 8→11; the Figma 533px is this
   shape near the design frame). 32px inner padding all round;
   `box-sizing: border-box` keeps the outer size grid-locked as inner
   content lands in follow-up iterations. */
.ap-co__summary-rail {
	right: var(--grid-col2-inset, 245px);
	width: var(--ap-co-summary-w, 533px);
}

/* ≤1512px (down to the mobile breakpoint) — the middle-ten-column
   footprint widens to all 12: both outer edges step out from columns
   2/11 to columns 1/12 while every inner edge stays put. The summary
   grows to five columns (left edge holds on column 8) exactly as the
   wrapper's padding sheds one column-step per side, so the items
   column's right boundary doesn't move either. (Synced from the four
   step sandboxes' inline tiers 2026-08-19 — the union, deduped like the
   original extraction; the `.ap-co` rule is scoped to the step
   modifiers so confirmation keeps its own centred inset. The missing
   tier was squeezing the live items column at ≤1512px: wrapped qty
   stepper + the remove button overlapping it.) */
@media (min-width: 769px) and (max-width: 1512px) {
	.ap-co--cart,
	.ap-co--delivery,
	.ap-co--payment,
	.ap-co--review {
		--ap-co-summary-w: calc(5 * var(--grid-col-w, 109px) + 4 * var(--grid-gutter, 32px));
		padding-inline: var(--grid-margin, 96px);
	}
	.ap-co__summary-rail {
		right: var(--grid-margin, 96px);
	}
	/* Dividers follow the items column's left edge out to column 1;
	   the sixth column keeps their right end on column 6's far edge. */
	.ap-co__items > .ap-pp__divider {
		width: calc(6 * var(--grid-col-w, 101px) + 5 * var(--grid-gutter, 32px));
	}
	/* Delivery/payment/review: the step strip + form column follow the
	   same six-column footprint. */
	.ap-co__steps,
	.ap-co__delivery {
		width: calc(6 * var(--grid-col-w, 101px) + 5 * var(--grid-gutter, 32px));
	}
}

/* WC appends its tax suffix ("(su PVM)") to every price it renders —
   item rows, subtotal, shipping, and AJAX-refreshed fragments alike.
   The design carries the suffix exactly once, hardcoded on the
   grand-total label (`.ap-co__summary__grand-total__label-suffix`),
   so the WC copy is suppressed wholesale within the checkout shell. */
.ap-co small.tax_label {
	display: none;
}

.ap-co__summary {
	min-height: 594px;
	padding: 32px;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	border-radius: var(--radius-15, 15px);
	background: var(--gray-50, #F7F7F7);
}

.ap-co__summary__title {
	color: var(--text-primary, #191919);
}

/* Free-delivery status panel — white card sitting 24px below the
   summary title. Width follows the summary's inner content area
   (469px = 533 - 64 padding) via column-flex `align-items: stretch`,
   not a hardcoded width. 12px internal gap stacks the future row(s)
   (progress bar, hint copy, etc.) when they land. */
.ap-co__summary__delivery {
	margin-top: 24px;
	padding: var(--space-8, 8px) var(--space-16, 16px) var(--space-16, 16px);
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	gap: var(--space-12, 12px);
	border-radius: var(--radius-15, 15px);
	background: var(--gray-0, #FFF);
}

/* Head row — 24×24 truck icon + 4px gap + status copy. */
.ap-co__summary__delivery-head {
	display: flex;
	align-items: center;
	gap: 4px;
}

.ap-co__summary__delivery-icon {
	display: inline-flex;
	width: 24px;
	height: 24px;
	flex: 0 0 24px;
}

.ap-co__summary__delivery-icon img {
	display: block;
	width: 100%;
	height: 100%;
}

.ap-co__summary__delivery-title {
	color: var(--text-primary, #191919);
}

/* Amount pinned to the right edge of the head row. `margin-left: auto`
   consumes the leftover flex space after the icon + title group on the
   left, so the icon-title pair keeps its 4px gap and the amount lands
   flush against the right edge. */
.ap-co__summary__delivery-amount {
	margin-left: auto;
	color: var(--text-primary, #191919);
}

/* Progress track + fill — sits 12px below the head row (delivered by
   the panel's own `gap: 12px`). Track spans the full inner width
   (column-flex `align-items: stretch` default), 5px tall, gray-200
   pill. Fill is a child div whose `width` (set inline via the
   `--ap-progress` custom property, default 50% for the sandbox preview)
   represents the basket amount as a fraction of the free-delivery
   threshold. `overflow: hidden` on the track clips the fill to the
   track's rounded corners so we don't need to maintain two radii.
   `role="progressbar"` + ARIA attrs on the track make the value
   announceable. */
.ap-co__summary__delivery-progress {
	height: 5px;
	border-radius: 6px;
	background: var(--gray-200, #E4E4E4);
	overflow: hidden;
}

.ap-co__summary__delivery-progress__fill {
	width: var(--ap-progress, 50%);
	height: 100%;
	border-radius: 6px;
	background: var(--gray-900, #262626);
}

/* Totals stack — "Tarpinė suma" + "Pristatymas" rows sitting 24px below
   the delivery panel. Column-flex with 12px row gap; each row is a
   horizontal flex with `justify-content: space-between` so the label
   stays left and the value lands right without an ad-hoc grid. Built
   on `<p>` rather than `<dl>/<dt>/<dd>` so the sandbox Astra
   neutraliser (which covers p, not dt/dd) strips Astra's body-copy
   line-height + margin overrides — otherwise the rows render visibly
   taller than the 24px line-box the type utility declares. */
.ap-co__summary__totals {
	margin-top: 24px;
	display: flex;
	flex-direction: column;
	gap: var(--space-12, 12px);
}

.ap-co__summary__total-row {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: var(--space-12, 12px);
}

.ap-co__summary__total-label,
.ap-co__summary__total-value {
	color: var(--text-primary, #191919);
}

.ap-co__summary__total-value {
	text-align: right;
}

/* Hairline above the grand-total — reuses the `.ap-pp__divider`
   primitive (1px, --divider-background-light) and only overrides its
   default 32px top inset down to the 24px the spec asks for here.
   `:first-of-type` scopes the override to the first divider in the
   summary so the second one (below the discount toggle) keeps the
   primitive's 32px default. Both stretch to the panel's 32px-padding
   inner edges because `.ap-co__summary` is a column flex. */
.ap-co__summary > .ap-pp__divider:first-of-type {
	margin-top: 24px;
}

/* Grand-total row — "Viso (su PVM)" label + "€xx.xx" value, sitting
   24px below the hairline. Same horizontal-flex-with-space-between
   shape as the totals rows above. The label intentionally mixes two
   type utilities on inline children: `.type-heading-sm-bold` on the
   "Viso" span (20/22/700, text-primary) and `.type-body-md-regular`
   on the parenthetical (16/24/400, text-tertiary). `align-items:
   baseline` aligns the label and value text baselines instead of
   their box centres, so the mixed-leading label sits visually flush
   with the heading-scale value. */
.ap-co__summary__grand-total {
	margin-top: 24px;
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: var(--space-12, 12px);
}

.ap-co__summary__grand-total__label {
	color: var(--text-primary, #191919);
}

.ap-co__summary__grand-total__label-suffix {
	color: var(--text-tertiary, #787878);
}

.ap-co__summary__grand-total__value {
	color: var(--text-primary, #191919);
	text-align: right;
}

/* Primary CTA — "Pradėti atsiskaitymą". Mirrors the product page's
   `.ap-pp__add-to-cart`: 60px tall, 18×20 padding, 15px radius,
   primary-background fill, white text, Outfit 16/24/500. Sits 24px
   below the grand-total row. `align-self: stretch` makes the button
   span the summary's inner content width (the panel is a column flex
   so stretching is the default — declared explicitly to match the
   Figma spec). Brand-wash lock at hover/focus/active per
   `feedback_lock_button_states_against_brand_wash`. */
.ap-co__summary__cta {
	margin-top: 24px;
	display: flex;
	height: 60px;
	padding: 18px 20px;
	box-sizing: border-box;
	justify-content: center;
	align-items: center;
	align-self: stretch;
	gap: var(--space-8, 8px);
	border-radius: var(--radius-15, 15px);
	background: var(--button-primary-background-enabled, #191919);
	color: var(--text-white, #FFF);
	cursor: pointer;
	font-family: var(--font-family-ui, 'Outfit', sans-serif);
	font-size: var(--font-size-16, 16px);
	font-weight: var(--font-weight-medium, 500);
	line-height: 1.5;
}

.ap-sandbox .ap-co__summary__cta:hover,
.ap-sandbox .ap-co__summary__cta:focus,
.ap-sandbox .ap-co__summary__cta:focus-visible,
.ap-sandbox .ap-co__summary__cta:active {
	background-color: var(--button-primary-background-enabled, #191919);
	color: var(--text-white, #FFF);
	border-color: transparent;
	outline: none;
	box-shadow: none;
}

/* Discount-code trigger — composes the `.ap-pp__section-head`
   primitive (button + chevron with aria-expanded toggling + 0.18s
   chevron rotation, all inherited from chrome-styles.php) so the
   discount form can drop in later as the controlled panel. The
   page-level rule only owns:
   - 32px top inset from the CTA above
   - the left-group layout (20×20 tag icon + 8px gap + label),
     wrapped in a sub-element because the primitive itself uses
     `justify-content: space-between` to pin the chevron to the
     right edge — the left group has to be a single flex item to
     keep the icon + label adjacent. */
.ap-co__summary__discount-toggle {
	margin-top: var(--space-32, 32px);
}

.ap-co__summary__discount-toggle__left {
	display: flex;
	align-items: center;
	gap: var(--space-8, 8px);
}

.ap-co__summary__discount-toggle__icon {
	display: inline-flex;
	width: 20px;
	height: 20px;
	flex: 0 0 20px;
}

.ap-co__summary__discount-toggle__icon img {
	display: block;
	width: 100%;
	height: 100%;
}

.ap-co__summary__discount-toggle__label {
	color: var(--text-primary, #191919);
}

/* Controlled panel — collapses when the toggle reads
   `aria-expanded="false"` via the same next-sibling pattern the product
   page uses for `.ap-pp__description`. When open it sits 12px below the
   toggle and holds the discount-code input, reusing the shared
   `.ap-pp__personalize__field` / `-field-input` primitive verbatim. */
.ap-co__summary__discount-toggle[aria-expanded="false"] + .ap-co__summary__discount-panel {
	display: none;
}

/* Cancel the `.ap-pp__section-head[aria-expanded="true"]` primitive's
   16px bottom margin so the gap above the panel is exactly the panel's
   own 12px (flex-item margins don't collapse, so the two would stack to
   28px otherwise). */
.ap-co__summary__discount-toggle[aria-expanded="true"] {
	margin-bottom: 0;
}

.ap-co__summary__discount-panel {
	margin-top: var(--space-12, 12px);
	display: flex;
	align-items: stretch;
	gap: var(--space-12, 12px);
}

/* 24px from the input row down to the divider below, only while open
   (the divider keeps the primitive's 32px default in the collapsed
   state, where the panel is `display: none`). */
.ap-co__summary__discount-toggle[aria-expanded="true"] + .ap-co__summary__discount-panel + .ap-pp__divider {
	margin-top: var(--space-24, 24px);
}

/* Apply button — reuses the `.ap-co__summary__cta` primary-button look
   but drops the CTA's vertical-stack assumptions (24px top inset +
   full-width stretch) so it sits inline to the right of the code input.
   `flex: 0 0 auto` keeps it sized to its label; the input wrapper
   (`flex: 1`) takes the remaining width. */
.ap-co__summary__discount-apply {
	margin-top: 0;
	flex: 0 0 auto;
	align-self: stretch;
}

/* Payment-methods block — uppercase label + row of 4 equal-width
   white tiles holding bank logos. Sits 24px below the bottom
   divider (the divider provides the gap above via its own 32px
   top inset + this 24px? — the divider's bottom edge to title
   top is owned here). 12px gap between title and tile row. Each
   tile is `flex: 1 0 0` so widths divide evenly regardless of
   logo intrinsic width; logos render at 20px tall with width:
   auto so each provider keeps its native aspect ratio. */
.ap-co__summary__payments {
	margin-top: 24px;
}

.ap-co__summary__payments__title {
	color: var(--text-tertiary, #787878);
}

.ap-co__summary__payments__row {
	margin-top: var(--space-12, 12px);
	display: flex;
	align-items: stretch;
	gap: var(--space-8, 8px);
}

.ap-co__summary__payments__tile {
	display: flex;
	flex: 1 0 0;
	padding: 10px var(--space-12, 12px);
	box-sizing: border-box;
	flex-direction: column;
	align-items: center;
	gap: 10px;
	border-radius: var(--radius-8, 8px);
	background: var(--gray-0, #FFF);
}

.ap-co__summary__payments__tile img {
	display: block;
	height: 20px;
	width: auto;
}

/* Page title — "Prekių krepšelis". Typography ships via the
   `.type-heading-md` utility (Special Gothic Expanded One 32/1.1,
   0.025em tracking, uppercase) so the brandbook scale stays the source
   of truth; this rule only owns the zeroed Astra heading margin and
   the primary colour. */
.ap-co__title {
	margin: 0;
	color: var(--text-primary, #191919);
}

/* Cart line item — 234×312 product image (3:4 ratio at 312 tall) with a
   32px horizontal gap to the info column on the right. `align-items:
   flex-start` keeps the info column anchored to the media's top edge
   regardless of how tall the info stack grows. 32px top margin owns
   the gap to the title above (and would compose between successive
   items once we add them). */
.ap-co__item {
	/* Media width — two grid columns + the gutter between them.
	   Declared on the row (not the media column) because the remove
	   button's media-bottom anchor below also derives from it. */
	--ap-co-media-w: calc(2 * var(--grid-col-w, 101px) + var(--grid-gutter, 32px));
	margin-top: 32px;
	display: flex;
	align-items: flex-start;
	gap: 32px;
	position: relative; /* anchor for the media-bottom-aligned remove button */
}

/* Left column — the product image alone (the quantity group lives in
   the info column, below the price). Two grid columns + the gutter
   between them wide, so the media spans from column 2's outer edge
   (the content edge) to column 3's far edge (`--ap-co-media-w`;
   vw-based `--grid-col-w` because this sits too deep in the flow for
   the %-based grid tokens — the Figma 234px is what this resolves to
   near the design frame). The media's height drives the row, so the
   info column (align-self: stretch) matches it and the bottom-pinned
   remove button lands on the media's bottom line. */
.ap-co__item__media-col {
	flex: 0 0 var(--ap-co-media-w);
	width: var(--ap-co-media-w);
	display: flex;
	flex-direction: column;
}

.ap-co__item__media {
	flex: 0 0 auto;
	width: var(--ap-co-media-w, 234px);
	aspect-ratio: 3 / 4; /* height tracks the fluid width — 312px at the 234px design frame */
	border-radius: 0; /* spec: non-rounded corners */
	background-color: #D9D9D9; /* fallback fill if the placeholder image is missing */
	background-position: center;
	background-size: cover;
	background-repeat: no-repeat;
}

.ap-co__item__info {
	flex: 1 1 auto;
	min-width: 0; /* let long titles wrap inside the flex item — see `feedback_flex_min_width_auto_trap` */
	align-self: stretch; /* fill the media column's height so `margin-top: auto` can push the remove button to the bottom edge */
	padding-top: var(--space-8, 8px); /* offset the info column 8px below the media's top edge */
	display: flex;
	flex-direction: column;
}

/* Per-row spacing inside the info column: title → 8px → first attr →
   2px → second attr → 2px → price → 24px → KIEKIS label → 12px → qty
   row. Each row owns its own top margin so reorders stay self-
   describing. Headings pin `text-transform: none` to defend against
   Astra's global uppercase on h2/h3 (see
   `feedback_sandbox_heading_text_transform_reset`). */
.ap-co__item__title {
	margin: 0;
	color: var(--text-primary, #191919);
	text-transform: none;
}

.ap-co__item__attr {
	margin: 2px 0 0;
	color: var(--text-secondary, #5C5C5C);
}

.ap-co__item__title + .ap-co__item__attr {
	margin-top: var(--space-8, 8px);
}

.ap-co__item__price {
	margin: 2px 0 0;
	color: var(--text-primary, #191919);
}

/* Quantity group — the KIEKIS label and the stepper it titles, one
   unit in the info column sitting 24px below the price (desktop; the
   mobile grid re-seats it beneath the product image with the spec's
   17px gap). The label sits flush at its top, the stepper 12px
   below. */
.ap-co__item__qty-group {
	margin-top: 24px;
}

.ap-co__item__qty-label {
	margin: 0;
	color: var(--text-tertiary, #787878);
}

/* Quantity stepper — minus/plus icon buttons flanking the shared
   `.ap-pp__personalize__field-input` primitive (defined in
   chrome-styles.php). 8px gap, `align-items: center` keeps the
   shorter buttons vertically centred against the taller (60px)
   input. `width: max-content` exempts the row from the media
   column's grid width — the stepper keeps its natural 184px
   (56+8+56+8+56) footprint at every viewport instead of being
   clamped to a single grid column narrower than its cells. */
.ap-co__item__qty {
	margin-top: var(--space-12, 12px);
	display: flex;
	align-items: center;
	gap: var(--space-8, 8px);
	width: max-content;
}

.ap-co__item__qty-btn {
	display: flex;
	width: 56px;
	flex-shrink: 0; /* hold the 56px width so the buttons stay as wide as the input when the row overflows the narrow mobile media column */
	height: 40px;
	padding: var(--space-8, 8px) var(--space-12, 12px);
	box-sizing: border-box;
	justify-content: center;
	align-items: center;
	gap: var(--space-8, 8px);
	border-radius: var(--radius-10, 10px);
	background: var(--button-secondary-background-enabled, #F0F0F0);
	cursor: pointer;
}

.ap-co__item__qty-btn img {
	display: block;
	width: 16px;
	height: 16px;
}

/* Five-property brand-wash lock at every state — same defence as the
   other sandbox icon buttons (see `feedback_lock_button_states_against_brand_wash`). */
.ap-sandbox .ap-co__item__qty-btn:hover,
.ap-sandbox .ap-co__item__qty-btn:focus,
.ap-sandbox .ap-co__item__qty-btn:focus-visible,
.ap-sandbox .ap-co__item__qty-btn:active {
	background-color: var(--button-secondary-background-hover, var(--button-secondary-background-enabled, #F0F0F0));
	color: inherit;
	border-color: transparent;
	outline: none;
	box-shadow: none;
}

/* Quantity input — matches the flanking ± button cells (56×40, 8px
   gap, 10px radius) but painted on the input semantic tokens (white
   fill + gray-200 border) rather than the secondary-button fill.
   Scoped under `.ap-sandbox` (0,2,0) to beat Astra's
   `.entry-content input[type="text"]` rule (0,1,1) which would
   otherwise force its own border + radius onto the input. */
.ap-sandbox .ap-co__item__qty-input {
	display: flex;
	width: 56px;
	flex-shrink: 0; /* stays at its 56px — with the buttons also pinned, neither cell yields when the row overflows */
	height: 40px;
	padding: 0 var(--space-12, 12px);
	box-sizing: border-box;
	justify-content: center;
	align-items: center;
	gap: var(--space-8, 8px);
	border-radius: var(--radius-10, 10px);
	border: 1px solid var(--input-border-enabled, #E4E4E4);
	background: var(--input-background-enabled, #FFF);
	color: var(--input-text-filled, #191919);
	text-align: center;
}

/* Interactive states per the brandbook Input catalog (hover token on
   hover, 2px focus border on focus), each branch re-pinning all five
   wash-sensitive props at (0,3,1) to beat the universal accent-wash
   kill (`.ap-sandbox input:hover` at (0,2,1)) — same tiers as the
   shared `.ap-pp__personalize__field-input` primitive. (Synced from
   the cart sandbox 2026-08-19.) */
.ap-sandbox .ap-co__item__qty-input:hover {
	background: var(--input-background-enabled, #FFF);
	color: var(--input-text-filled, #191919);
	border-color: var(--input-border-hover, #A3A3A3);
	outline: none;
	box-shadow: none;
}
.ap-sandbox .ap-co__item__qty-input:focus,
.ap-sandbox .ap-co__item__qty-input:focus-visible,
.ap-sandbox .ap-co__item__qty-input:active {
	background: var(--input-background-enabled, #FFF);
	color: var(--input-text-filled, #191919);
	border: 2px solid var(--input-border-focus, #191919);
	outline: none;
	box-shadow: none;
}

/* Remove-item button — tertiary (white) CTA at the bottom-LEFT of the
   info column (flush with the title/price/qty left edge), its bottom
   edge aligned with the media's bottom edge. Anchored absolutely
   against the item row and placed by the media's geometry (`left =
   media width + the row's 32px gap`, `top = media height − button
   height`, media height = width × 4/3 per its aspect-ratio) so the
   alignment holds regardless of whether the info column's content
   runs taller or shorter than the media. The mobile grid restores
   static flow (`margin-top: auto` + `align-self` bottom it inside its
   own row there). White background, 20×20 trash icon on the left,
   8px gap, "Pašalinti" label. */
.ap-co__item__remove {
	display: inline-flex;
	align-self: flex-end;
	margin-top: auto;
	position: absolute;
	/* Info-column left edge minus the button's own 16px left padding:
	   the button is white-on-white, so the padding is invisible and
	   would read as the icon being indented off the title/price/stepper
	   left edge — pulling the box back by it lands the trash icon's
	   VISIBLE edge on the column line (box-vs-ink, same idea as the
	   footer wordmark's sidebearing shift). Vertically the BOX aligns
	   with the media's bottom edge (media height = width × 4/3 per its
	   aspect-ratio, minus the 48px button height). */
	left: calc(var(--ap-co-media-w, 234px) + 32px - 16px);
	top: calc(var(--ap-co-media-w, 234px) * 4 / 3 - 48px);
	height: 48px;
	padding: 12px var(--space-16, 16px);
	box-sizing: border-box;
	justify-content: center;
	align-items: center;
	gap: var(--space-8, 8px);
	border-radius: 12px;
	background: var(--button-tertiary-background-enabled, #FFF);
	color: var(--text-primary, #191919);
	font-family: var(--font-family-ui, 'Outfit', sans-serif);
	font-size: var(--font-size-16, 16px);
	font-weight: 500;
	line-height: 1.5;
	cursor: pointer;
}

.ap-co__item__remove__icon {
	display: inline-flex;
	width: 20px;
	height: 20px;
}

.ap-co__item__remove__icon img {
	display: block;
	width: 100%;
	height: 100%;
}

/* Five-property brand-wash lock; tertiary nudges to `--button-tertiary-
   background-hover` (gray-50) on interaction. */
.ap-sandbox .ap-co__item__remove:hover,
.ap-sandbox .ap-co__item__remove:focus,
.ap-sandbox .ap-co__item__remove:focus-visible,
.ap-sandbox .ap-co__item__remove:active {
	background-color: var(--button-tertiary-background-hover, var(--button-tertiary-background-enabled, #FFF));
	color: var(--text-primary, #191919);
	border-color: transparent;
	outline: none;
	box-shadow: none;
}

/* Mobile (≤768px) — first iteration. Per `[Mobile typography via
   token remap]`, type utilities are left alone — no per-element
   font-size overrides here. The summary, absolutely positioned beside
   the items on desktop, drops to a stacked full-width card below them
   on mobile (see its rule below). */
@media (max-width: 768px) {
	/* Items column reclaims the full mobile width — the desktop
	   `margin-right` reservation for the summary
	   panel no longer applies because the panel stacks below. */
	.ap-co__items {
		margin-right: 0;
	}

	/* The full-bleed white rule cancels the panel's padding to reach
	   its edges — 24px on mobile (vs 32px desktop). The desktop -32px
	   overhang poked 8px past the viewport and opened a horizontal
	   scroll gutter on the payment/review steps. Chained to the panel
	   for (0,2,0): this block precedes the base rule in source order,
	   so at equal specificity the base's margin shorthand would win. */
	.ap-co__summary .ap-co__summary__rule {
		margin-inline: -24px;
	}

	/* Summary stacks below the items as a card on the mobile grid.
	   `order: 1` drops it past the items (it precedes them in the DOM);
	   static positioning + auto width/height shed the desktop absolute
	   533×594 panel so it sizes to its content. The card sits inside
	   `.ap-co`'s 24px insets — flush with the grid margins like every
	   other row — and its own 32px padding keeps the content inset. It keeps its gray-50 fill + 15px radius from the base
	   rule — the same background shape as
	   `.ap-pp__sizes-table-modal__visual`. 32px gap separates it from
	   the last cart item. */
	.ap-co__summary {
		order: 1;
		position: static;
		width: auto;
		height: auto;
		min-height: 0;
		margin-top: 32px;
		/* Full-bleed panel per the mobile frame (Figma 1159-3577): the
		   gray spans edge to edge — negative margins cancel the
		   wrapper's 24px insets, corners square off — and `flex: 1`
		   swallows the wrapper's min-height slack on short pages so
		   the panel runs straight into the footer instead of leaving
		   a white gap. Content stays on the 24px grid margin via the
		   panel's own padding; 64px below the payments row per frame. */
		margin-inline: -24px;
		flex: 1 0 auto;
		/* Top corners keep the 15px rounding (Figma 1166-3989) — only
		   the bottom squares off where the panel meets the footer. */
		border-radius: var(--radius-15, 15px) var(--radius-15, 15px) 0 0;
		padding: 24px 24px 64px;
	}

	/* Mobile cart item on the 2-column grid. The markup keeps the
	   qty-group in the info column (its desktop home, below the price),
	   so the mobile under-the-media layout is rebuilt as a grid:
	   `display: contents` on the info column promotes its children to
	   grid items, the media column spans the four text rows (title +
	   two attrs + price — a span tied to this static sandbox markup),
	   and auto-placement then drops the qty-group into column 1 row 5
	   (beneath the media) and the remove button into column 2 row 5
	   beside it. Column 1 is one mobile grid column wide (`--grid-col-w`
	   — 163px at a 390px viewport), the column gap is the grid gutter;
	   `row-gap: 0` so the text rows keep their own margin rhythm. Media
	   keeps the 3:4 ratio from the base rule. */
	.ap-co__item {
		display: grid;
		grid-template-columns: var(--grid-col-w, 163px) 1fr;
		/* Rows 1–3 (title + attrs) stay content-sized so the text keeps
		   its tight margin rhythm; row 4 (price) is the `1fr` that
		   absorbs the media's spanned height, parking the slack BELOW
		   the price instead of letting the grid distribute it between
		   the text rows. Row 5 is the qty + remove line. */
		grid-template-rows: auto auto auto 1fr auto;
		gap: 0 var(--grid-gutter, 16px);
	}
	.ap-co__item__media-col {
		width: 100%;
		grid-column: 1;
		grid-row: 1 / span 4;
	}
	.ap-co__item__media {
		width: 100%;
	}
	.ap-co__item__info {
		display: contents;
	}
	.ap-co__item__title,
	.ap-co__item__attr,
	.ap-co__item__price {
		grid-column: 2;
	}
	/* The info column's 8px top padding vanishes with `display:
	   contents` — restate the offset on the first text row. */
	.ap-co__item__title {
		margin-top: var(--space-8, 8px);
	}
	/* Beneath the media, with the spec's 17px image → KIEKIS gap
	   (desktop uses 24px below the price instead). */
	.ap-co__item__qty-group {
		grid-column: 1;
		margin-top: 17px;
	}
	/* Right of the stepper: back in static flow (the desktop rule
	   anchors it absolutely to the media's bottom edge); `margin-top:
	   auto` (base) bottoms it inside row 5, `justify-self` hugs the
	   right edge (the base `align-self: flex-end` was the flex
	   cross-axis right-hug; in grid that axis is vertical, so the
	   inline-axis hug is restated here), and the -4px drops its centre
	   onto the 40px stepper's y-axis (half the 48−40 height delta). */
	.ap-co__item__remove {
		position: static;
		grid-column: 2;
		justify-self: end;
		margin-bottom: -4px;
	}

	/* Item dividers reclaim the full mobile content width — the desktop
	   columns-2→6 width would resolve against the MOBILE column tokens
	   here (5 mobile columns ≈ 2.3 viewports) and blow the layout
	   sideways. */
	.ap-co__items > .ap-pp__divider {
		width: 100%;
	}

	/* No trailing hairline below the last cart item on mobile — the
	   items column ends flush, with no divider before the stacked
	   summary section. */
	.ap-co__items > .ap-pp__divider:last-child {
		display: none;
	}
}

/* ══════════ from checkout-delivery-sandbox.php ══════════ */

/* Basket summary panel — pinned to the top-right of the inner padding
   area (64px from top, `--grid-col2-inset` from the right — the exact
   inner corner of `.ap-co`'s padding box; the % basis matches the
   padding's because `.ap-co` spans the full viewport width). Width is
   `--ap-co-summary-w` (columns 8→11; the Figma 533px is this shape
   near the design frame). 32px inner padding all round; `box-sizing:
   border-box` keeps the outer size grid-locked as inner content lands
   in follow-up iterations. */
.ap-co__summary-rail {
	right: var(--grid-col2-inset, 245px);
	width: var(--ap-co-summary-w, 533px);
}

.ap-co__summary {
	min-height: 594px;
	padding: 32px;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	border-radius: var(--radius-15, 15px);
	background: var(--gray-50, #F7F7F7);
}

/* Totals stack — "Tarpinė suma" + "Pristatymas" rows sitting 24px below
   the summary title. Column-flex with 12px row gap; each row is a
   horizontal flex with `justify-content: space-between` so the label
   stays left and the value lands right without an ad-hoc grid. Built
   on `<p>` rather than `<dl>/<dt>/<dd>` so the sandbox Astra
   neutraliser (which covers p, not dt/dd) strips Astra's body-copy
   line-height + margin overrides — otherwise the rows render visibly
   taller than the 24px line-box the type utility declares. */
.ap-co__summary__totals {
	margin-top: 24px;
	display: flex;
	flex-direction: column;
	gap: var(--space-12, 12px);
}

/* Applied-discount confirmation — swapped in for the toggle + panel once a
   code is accepted (JS hides those and reveals this, see below). A white
   pill that reads against the panel's gray-50 fill, taking the toggle's
   32px slot below the divider. Row: 32px check icon · 6px gap · a text
   column that grows. Bespoke padding/gap/radius (10×15, 6, 13px) — none
   land on the AGO space/radius scale, so they stay literals. */
.ap-co__summary__discount-applied {
	margin-top: var(--space-32, 32px);
	display: flex;
	align-items: center;
	gap: 6px;
	align-self: stretch;
	padding: 10px 15px;
	box-sizing: border-box;
	border-radius: 13px;
	background: var(--gray-0, #FFF);
	/* Resting (just-revealed) state for the entrance: faded + nudged up.
	   The `.is-applied` class (added a frame after reveal) settles it into
	   place; removing the class on remove plays the same transition in
	   reverse. Gentle ease-out settle, ~320ms (see `feedback_animation_
	   style_apple_hig`). */
	opacity: 0;
	transform: translateY(-6px);
	transition: opacity 0.32s cubic-bezier(0.22, 1, 0.36, 1),
		transform 0.32s cubic-bezier(0.22, 1, 0.36, 1);
}

.ap-co__summary__discount-applied.is-applied {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	.ap-co__summary__discount-applied {
		transition: none;
		transform: none;
	}
	/* Skip the draw-on; show the check fully formed. */
	.ap-co__summary__discount-applied__check-ring,
	.ap-co__summary__discount-applied__check-tick {
		stroke-dashoffset: 0;
		animation: none;
	}
}

/* Hidden until a code is applied; the attribute beats the base display
   (0,2,0 > 0,1,0) so `hidden` actually collapses it. */
.ap-co__summary__discount-applied[hidden] {
	display: none;
}

/* Check icon shell — 32×32; the green check-contained glyph fills it. */
.ap-co__summary__discount-applied__icon {
	display: inline-flex;
	flex: 0 0 32px;
	width: 32px;
	height: 32px;
	aspect-ratio: 1 / 1;
}

.ap-co__summary__discount-applied__icon svg {
	display: block;
	width: 100%;
	height: 100%;
}

/* Draw-on entrance for the success check: the ring sweeps clockwise from
   the top (top → right → bottom → left) like a loading ring, while the tick
   draws left → right alongside it, both completing together. pathLength="1" normalises each path
   so |dashoffset| 1 = undrawn, 0 = full. The offset rests at -1 (not +1) so
   each stroke draws from its path END backward — that reversal is what
   yields the clockwise ring (its path runs counter-clockwise from the top)
   and the left→right tick (its path is defined right→left). Gated on
   `.is-applied` so they play on apply (not during the hidden page-load) and
   reset when the pill is removed. */
.ap-co__summary__discount-applied__check-ring,
.ap-co__summary__discount-applied__check-tick {
	stroke-dasharray: 1;
	stroke-dashoffset: -1;
}

.ap-co__summary__discount-applied.is-applied .ap-co__summary__discount-applied__check-ring {
	animation: ap-co-check-draw 0.7s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

.ap-co__summary__discount-applied.is-applied .ap-co__summary__discount-applied__check-tick {
	animation: ap-co-check-draw 0.7s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

@keyframes ap-co-check-draw {
	to { stroke-dashoffset: 0; }
}

/* Instant render — the pill in its final state with no entrance fade and
   the check fully drawn. Used when a previously applied code is restored
   from storage on page load. Placed after the entrance rules so it wins at
   equal specificity; the JS keeps the class on for the restored session so
   the draw-on never fires. */
.ap-co__summary__discount-applied.is-instant {
	transition: none;
}

.ap-co__summary__discount-applied.is-instant .ap-co__summary__discount-applied__check-ring,
.ap-co__summary__discount-applied.is-instant .ap-co__summary__discount-applied__check-tick {
	animation: none;
	stroke-dashoffset: 0;
}

/* Text column — grows to fill the remaining width (pushing the remove
   button to the pill's right edge). Code label on top; the note + amount
   sit on one line below it, the code→detail gap being line-height only. */
.ap-co__summary__discount-applied__text {
	flex: 1 1 auto;
	min-width: 0;
	display: flex;
	flex-direction: column;
}

.ap-co__summary__discount-applied__code {
	color: var(--text-primary, #191919);
}

/* Note + amount on one baseline-aligned row, 5px apart. */
.ap-co__summary__discount-applied__detail {
	display: flex;
	align-items: baseline;
	gap: 5px;
}

.ap-co__summary__discount-applied__note {
	color: var(--text-tertiary, #787878);
}

.ap-co__summary__discount-applied__amount {
	color: var(--text-primary, #191919);
}

/* Remove-discount button — pinned to the pill's right edge (the text
   column's flex-grow pushes it there). Bare 16×16 icon button; the sandbox
   neutraliser already strips its resting chrome, so this owns layout only.
   The five-property brand-wash lock keeps it transparent at every
   interactive state. */
.ap-co__summary__discount-applied__remove {
	display: inline-flex;
	flex: 0 0 16px;
	padding: 0;
	cursor: pointer;
	background: transparent;
}

.ap-co__summary__discount-applied__remove__icon {
	display: inline-flex;
	width: 16px;
	height: 16px;
	aspect-ratio: 1 / 1;
}

.ap-co__summary__discount-applied__remove__icon img {
	display: block;
	width: 100%;
	height: 100%;
}

.ap-sandbox .ap-co__summary__discount-applied__remove:hover,
.ap-sandbox .ap-co__summary__discount-applied__remove:focus,
.ap-sandbox .ap-co__summary__discount-applied__remove:focus-visible,
.ap-sandbox .ap-co__summary__discount-applied__remove:active {
	background-color: transparent;
	border-color: transparent;
	outline: none;
	box-shadow: none;
}

/* Full-bleed 2px white rule inside the summary card — negative 32px side
   margins cancel the panel's 32px horizontal padding so it reaches both
   edges of the gray-50 card (not just the inner content width); 24px clear
   above and below. Distinct from `.ap-pp__divider` (1px, light-gray): a
   2px white separator that reads against the panel's gray-50 fill. */
.ap-co__summary__rule {
	border: 0;
	height: 2px;
	margin: var(--space-24, 24px) -32px;
	background: var(--gray-0, #FFF);
}

/* Summary line item — the basket contents echoed read-only beneath the
   rule. Row is photo · 12px gap · params, centred on the y-axis. The
   basket page's remove button and quantity stepper are intentionally
   dropped; quantity reads here as a plain "Kiekis" attr line. No top
   margin on the first row: `.ap-co__summary` is a column flex (margins
   don't collapse), and the rule above already owns a 24px bottom margin,
   so that single 24px is the gap down to the photo's top. */
.ap-co__summary__item {
	display: flex;
	/* Top-aligned per Figma 1166-4040 — the text column may outgrow the
	   138px photo (long titles, extra attrs) and must extend BELOW it,
	   never above; centring floated it above the image top. The title's
	   8px offset from the photo's top edge is the frame's own inset. */
	align-items: flex-start;
	gap: var(--space-12, 12px);
}

/* Subsequent rows sit 12px apart. */
.ap-co__summary__item + .ap-co__summary__item {
	margin-top: var(--space-12, 12px);
}

/* Product photo — 104px wide, locked to a 3:4 portrait (≈139px tall),
   10px radius. cover-fills like the basket media; the gray-200 fill only
   shows if the placeholder image is missing. */
.ap-co__summary__item__photo {
	flex: 0 0 104px;
	width: 104px;
	aspect-ratio: 3 / 4;
	border-radius: var(--radius-10, 10px);
	background-color: var(--gray-200, #E4E4E4);
	background-position: center;
	background-size: cover;
	background-repeat: no-repeat;
}

/* Params column — mirrors the basket page's `.ap-co__item__info`
   typography + spacing: title → 8px → first attr → 2px → each following
   attr → 2px → price. `min-width: 0` lets a long title wrap inside the
   flex item (see `feedback_flex_min_width_auto_trap`). */
.ap-co__summary__item__info {
	flex: 1 1 auto;
	min-width: 0;
	display: flex;
	flex-direction: column;
	/* Title first line sits 8px below the photo's top edge (frame inset). */
	padding-top: var(--space-8, 8px);
}

.ap-co__summary__item__title {
	margin: 0;
	color: var(--text-primary, #191919);
	text-transform: none;
}

.ap-co__summary__item__attr {
	margin: 2px 0 0;
	color: var(--text-secondary, #5C5C5C);
}

.ap-co__summary__item__title + .ap-co__summary__item__attr {
	margin-top: var(--space-8, 8px);
}

.ap-co__summary__item__price {
	margin: 2px 0 0;
	color: var(--text-primary, #191919);
}

/* Checkout progress stepper — replaces the basket page's `.ap-co__title`
   in the same top-left flow slot. Horizontal flex of step groups joined
   by connector hairlines. `gap: 12px` delivers the uniform 12px rhythm
   between every adjacent element (indicator↔label inside a step, and
   step↔connector↔step across the row); `align-items: center` centres the
   connectors on the row's y-axis. The row spans grid columns 2→6 (same
   span as `.ap-co__delivery` below); the connectors flex to absorb the
   slack, so the first indicator sits on column 2's outer edge and the
   last label ends on column 6's far edge. */
.ap-co__steps {
	display: flex;
	align-items: center;
	gap: var(--space-12, 12px);
	width: calc(5 * var(--grid-col-w, 101px) + 4 * var(--grid-gutter, 32px));
}

/* One step group — 48px indicator + 12px gap + label, its own flex row so
   the pair stays adjacent and the 12px matches the outer rhythm. */
.ap-co__step {
	display: flex;
	align-items: center;
	gap: var(--space-12, 12px);
}

/* Completed steps on the live checkout are clickable back-nav targets
   (checkout-live.js adds --nav). Sandbox stepper pages never get --nav,
   so their static --complete step keeps the default cursor. */
.ap-co__step--nav {
	cursor: pointer;
}

/* Indicator bubble — 48×48 circle. Inactive steps are a white (gray-0)
   disc with a 1px gray-200 border and a gray-400 numeral; the active step
   overrides to a dark (gray-950) fill, no border, white content. Numerals
   come from the `.type-heading-sm-medium` utility (Outfit 20/22/500) on
   the element. */
.ap-co__step__indicator {
	display: flex;
	width: 48px;
	height: 48px;
	flex-shrink: 0;
	box-sizing: border-box;
	justify-content: center;
	align-items: center;
	border-radius: 999px;
	border: 1px solid var(--gray-200, #E4E4E4);
	background: var(--gray-0, #FFF);
	color: var(--gray-400, #A3A3A3);
}

.ap-co__step--active .ap-co__step__indicator {
	border-color: transparent;
	background: var(--gray-950, #191919);
	color: var(--text-white, #FFF);
}

/* Label (`.type-body-md-regular`, Outfit 16/24/400) — muted on inactive
   steps, primary on the active one. */
.ap-co__step__label {
	color: var(--gray-400, #A3A3A3);
}

.ap-co__step--active .ap-co__step__label {
	color: var(--text-primary, #191919);
}

/* Connector hairline between steps — 1px tall; `flex: 1 0 0` grows it
   to fill the row's slack, split evenly between the two connectors, so
   the stepper always fills its columns-2→6 width. No connector renders
   after the last step. */
.ap-co__step-connector {
	height: 1px;
	flex: 1 0 0;
	background: var(--gray-200, #E4E4E4);
}

/* Delivery-method section title — "Pasirinkite pristatymo būdą". Sits
   64px below the stepper; owns a 16px bottom gap to the delivery options
   that follow. Typography from `.type-heading-sm-medium` (Outfit
   20/22/500); the neutraliser already strips Astra's heading margin /
   uppercase (at (0,0,1)), so this class (0,1,0) only needs to reinstate
   the two intentional margins and the primary colour. */
.ap-co__delivery-title {
	margin: 64px 0 var(--space-16, 16px);
	color: var(--text-primary, #191919);
}

/* Delivery left column — spans grid columns 2→6 (five columns + the
   four gutters between them; left edge already sits on column 2's
   outer edge, the content edge). vw-based `--grid-col-w` for the
   usual too-deep-in-the-flow reason. The summary sits on columns
   8→11, so the column-7 step stays clear as the gap between the two
   by construction. */
.ap-co__delivery {
	width: calc(5 * var(--grid-col-w, 101px) + 4 * var(--grid-gutter, 32px));
}

/* Field row — `.ap-pp__personalize__field` pairs side by side, 16px
   apart. Each field is `flex: 1; min-width: 0` (from the shared
   primitive), so a pair splits the row evenly and a lone field fills it.
   16px top margin owns the gap to the preceding row; it collapses with
   that row's bottom margin so the rhythm stays a uniform 16px. */
.ap-co__form-row {
	display: flex;
	gap: var(--space-16, 16px);
	margin-top: var(--space-16, 16px);
}

/* Field label — sits 4px above its input via the field wrapper's column
   gap. `.type-body-sm-medium` carries the type; this only owns the
   primary colour. */
.ap-co__field-label {
	color: var(--text-primary, #191919);
}

/* Delivery-method cards — a two-up radiogroup of selectable cards under
   the "Pasirinkite pristatymo būdą" title; 32px gap to the contact fields
   below (16px gap between the two cards). Each card: icon shell · text
   block (grows) · radio marker pinned right, all centred on the y-axis.
   The 2px border tracks selection via the `--method-border` custom
   property — enabled → hover → selected map straight onto the
   SizeSelector outline tokens — so the brand-wash lock re-asserts it in a
   single line without per-state duplication. */
.ap-co__methods {
	display: flex;
	gap: var(--space-16, 16px);
	margin-bottom: var(--space-32, 32px);
}

.ap-co__method {
	--method-border: var(--size-selector-outline-enabled, #E4E4E4);
	display: flex;
	flex: 1 0 0;
	min-width: 0;
	box-sizing: border-box;
	align-items: center;
	gap: var(--space-16, 16px);
	padding: var(--space-12, 12px) var(--space-16, 16px);
	border: 2px solid var(--method-border);
	border-radius: var(--radius-15, 15px);
	cursor: pointer;
	text-align: left;
}

.ap-co__method[aria-pressed="true"] {
	--method-border: var(--size-selector-outline-selected, #191919);
}

.ap-sandbox .ap-co__method:not([aria-pressed="true"]):hover,
.ap-sandbox .ap-co__method:not([aria-pressed="true"]):focus,
.ap-sandbox .ap-co__method:not([aria-pressed="true"]):focus-visible {
	--method-border: var(--size-selector-outline-hover, #A3A3A3);
}

/* Brand-wash lock — keep the fill transparent and re-assert the
   state-driven border at every interactive state so Astra's button
   globals / the accent-wash can't repaint them. */
.ap-sandbox .ap-co__method:hover,
.ap-sandbox .ap-co__method:focus,
.ap-sandbox .ap-co__method:focus-visible,
.ap-sandbox .ap-co__method:active {
	background-color: transparent;
	border-color: var(--method-border);
	outline: none;
	box-shadow: none;
}

/* Icon shell — 24×24 square holding the method glyph. */
.ap-co__method__icon {
	display: inline-flex;
	flex: 0 0 24px;
	width: 24px;
	height: 24px;
	aspect-ratio: 1 / 1;
}

.ap-co__method__icon img {
	display: block;
	width: 100%;
	height: 100%;
}

/* Text block — grows to push the radio marker to the right edge; title
   over description, stacked tight by their own line-heights (no gap). */
.ap-co__method__text {
	display: flex;
	flex: 1 1 auto;
	min-width: 0;
	flex-direction: column;
}

.ap-co__method__title {
	color: var(--text-primary, #191919);
}

.ap-co__method__desc {
	color: var(--text-tertiary, #787878);
}

/* Radio marker — the shared 20×20 radio glyph, pinned right (centred on
   the y-axis by the card's `align-items: center`); swaps to the checked
   SVG when the card reads `aria-pressed="true"`. */
.ap-co__method__radio {
	flex: 0 0 20px;
	width: 20px;
	height: 20px;
	background: url('../img/sandbox/radio-unchecked.svg') center no-repeat;
}

.ap-co__method[aria-pressed="true"] .ap-co__method__radio {
	background-image: url('../img/sandbox/radio-checked.svg');
}

/* Buyer-type radiogroup — "Fizinis asmuo" / "Juridinis asmuo". 16px gap
   above the field row and 16px below before the next section; 16px
   between the two radios. Visuals reuse the custom-radio primitive shared
   with `.ap-pp__sizes-table-modal__sex-option`: a 20×20 SVG marker via
   `::before` keyed off `aria-pressed`, 8px to the label. The sandbox
   neutraliser already strips Astra's button padding/border/uppercase at
   rest, so the option rule only owns layout + colour; the five-property
   brand-wash lock at hover/focus/active is still required. */
.ap-co__radio-options {
	display: flex;
	gap: var(--space-16, 16px);
	margin: var(--space-16, 16px) 0;
}

.ap-co__radio-option {
	display: flex;
	align-items: center;
	gap: var(--space-8, 8px);
	color: var(--text-primary, #191919);
	cursor: pointer;
}

.ap-co__radio-option::before {
	content: '';
	flex-shrink: 0;
	width: 20px;
	height: 20px;
	background-image: url('../img/sandbox/radio-unchecked.svg');
	background-repeat: no-repeat;
	background-position: center;
}

.ap-co__radio-option[aria-pressed="true"]::before {
	background-image: url('../img/sandbox/radio-checked.svg');
}

.ap-sandbox .ap-co__radio-option:hover,
.ap-sandbox .ap-co__radio-option:focus,
.ap-sandbox .ap-co__radio-option:focus-visible,
.ap-sandbox .ap-co__radio-option:active {
	background-color: transparent;
	color: var(--text-primary, #191919);
	border-color: transparent;
	outline: none;
	box-shadow: none;
}

/* Delivery submit CTA — "Išsaugoti ir tęsti". Same primary-button shape as
   `.ap-co__summary__cta` (60px, 18×20 padding, 15px radius, Outfit
   16/24/500, full-width stretch); 32px above the last field row. Renders
   disabled until every required field is filled (toggled in JS) — the
   disabled state swaps to the primary-disabled fill + disabled-text token.
   Brand-wash lock pinned on the enabled interactive states only. */
.ap-co__delivery-submit {
	margin-top: var(--space-32, 32px);
	display: flex;
	width: 100%;
	height: 60px;
	padding: 18px 20px;
	box-sizing: border-box;
	justify-content: center;
	align-items: center;
	align-self: stretch;
	gap: var(--space-8, 8px);
	border-radius: var(--radius-15, 15px);
	background: var(--button-primary-background-enabled, #191919);
	color: var(--text-white, #FFF);
	cursor: pointer;
	font-family: var(--font-family-ui, 'Outfit', sans-serif);
	font-size: var(--font-size-16, 16px);
	font-weight: var(--font-weight-medium, 500);
	line-height: 1.5;
}

.ap-sandbox .ap-co__delivery-submit:not(:disabled):hover,
.ap-sandbox .ap-co__delivery-submit:not(:disabled):focus,
.ap-sandbox .ap-co__delivery-submit:not(:disabled):focus-visible,
.ap-sandbox .ap-co__delivery-submit:not(:disabled):active {
	background-color: var(--button-primary-background-enabled, #191919);
	color: var(--text-white, #FFF);
	border-color: transparent;
	outline: none;
	box-shadow: none;
}

/* Disabled — muted fill + disabled-text token, no pointer. Scoped under
   `.ap-sandbox` (0,2,0/0,2,1) so the resting + interactive states beat the
   accent-wash kill and Astra's button globals. */
.ap-sandbox .ap-co__delivery-submit:disabled {
	background: var(--button-primary-background-disabled, #F0F0F0);
	color: var(--button-text-disabled, #D4D4D4);
	cursor: not-allowed;
}

.ap-sandbox .ap-co__delivery-submit:disabled:hover,
.ap-sandbox .ap-co__delivery-submit:disabled:focus,
.ap-sandbox .ap-co__delivery-submit:disabled:focus-visible,
.ap-sandbox .ap-co__delivery-submit:disabled:active {
	background: var(--button-primary-background-disabled, #F0F0F0);
	color: var(--button-text-disabled, #D4D4D4);
	border-color: transparent;
	outline: none;
	box-shadow: none;
}

/* Mobile (≤768px) — first iteration. Per `[Mobile typography via
   token remap]`, type utilities are left alone — no per-element
   font-size overrides here. The summary, absolutely positioned beside
   the items on desktop, drops to a stacked full-width card below them
   on mobile (see its rule below). */
@media (max-width: 768px) {
	/* Stepper reclaims the full mobile width — the desktop columns-2→6
	   width no longer applies in the stacked layout. */
	.ap-co__steps {
		width: auto;
	}

	/* Stepper goes vertical per step: the label drops beneath the
	   indicator, centred (inherited `align-items: center`), 4px below it.
	   The three steps split the row into equal thirds (`flex: 1 1 0`),
	   spaced by the base 12px gap. */
	.ap-co__step {
		flex: 1 1 0;
		min-width: 0;
		flex-direction: column;
		gap: var(--space-4, 4px);
		position: relative; /* anchor the connector hairline drawn below */
	}
	/* Connector dividers are drawn as a hairline running between each step's
	   indicator and the next step's, instead of the flex-flow
	   `.ap-co__step-connector` elements (hidden below) which would steal
	   width and knock the steps off their equal thirds. Geometry, relative
	   to the step (width W): the line keeps 12px of clearance from each
	   indicator — it starts 12px past this indicator's right edge
	   (50% + 24px + 12px) and stops 12px short of the next indicator's left
	   edge, a span of `W - 60px` (the 12px inter-column gap, the two 24px
	   radii, and the two 12px clearances). It sits at the indicator's
	   vertical centre (24px) and freely overlaps the adjacent column. */
	.ap-co__step:not(:last-child)::after {
		content: '';
		position: absolute;
		top: 24px;
		left: calc(50% + 36px);
		width: calc(100% - 60px);
		height: 1px;
		background: var(--gray-200, #E4E4E4);
	}
	.ap-co__step-connector {
		display: none;
	}

	/* Section title sits 24px below the stepper on mobile (the desktop 64px
	   top margin is too large for the tighter mobile rhythm). */
	.ap-co__delivery-title {
		margin-top: var(--space-24, 24px);
	}

	/* Delivery-method cards stack one per row, 12px apart (the desktop
	   two-up row + 16px gap don't fit the narrow column). Each card fills
	   the width via the column's default stretch. */
	.ap-co__methods {
		flex-direction: column;
		gap: var(--space-12, 12px);
	}

	/* Form fields go one per row — the paired rows (Vardas/Pavardė,
	   Telefonas/El. paštas, Miestas/Pašto kodas) stack vertically. The
	   existing 16px row gap now applies down the column, matching the 16px
	   rhythm between rows. */
	.ap-co__form-row {
		flex-direction: column;
	}

	/* Delivery column reclaims the full mobile width — the desktop
	   columns-2→6 width no longer applies because the summary panel
	   stacks below. */
	.ap-co__delivery {
		width: auto;
	}

	/* Summary stacks below the items as a card on the mobile grid.
	   `order: 1` drops it past the items (it precedes them in the DOM);
	   static positioning + auto width/height shed the desktop absolute
	   533×594 panel so it sizes to its content. The card sits inside
	   `.ap-co`'s 24px insets — flush with the grid margins like every
	   other row — and its own 32px padding keeps the content inset. It keeps its gray-50 fill + 15px radius from the base
	   rule — the same background shape as
	   `.ap-pp__sizes-table-modal__visual`. 32px gap separates it from
	   the delivery form above. */
	.ap-co__summary {
		order: 1;
		position: static;
		width: auto;
		height: auto;
		min-height: 0;
		margin-top: 32px;
		/* Full-bleed panel per the mobile frame (Figma 1159-3577): the
		   gray spans edge to edge — negative margins cancel the
		   wrapper's 24px insets, corners square off — and `flex: 1`
		   swallows the wrapper's min-height slack on short pages so
		   the panel runs straight into the footer instead of leaving
		   a white gap. Content stays on the 24px grid margin via the
		   panel's own padding; 64px below the payments row per frame. */
		margin-inline: -24px;
		flex: 1 0 auto;
		/* Top corners keep the 15px rounding (Figma 1166-3989) — only
		   the bottom squares off where the panel meets the footer. */
		border-radius: var(--radius-15, 15px) var(--radius-15, 15px) 0 0;
		padding: 24px 24px 64px;
	}
}

/* ══════════ from checkout-payment-sandbox.php ══════════ */

/* Checkout body wrapper — horizontal page insets pin the content to
   the outer edge of grid column 2 / column 11 (`--grid-col2-inset`;
   ≈ the Figma 245px at the 1920 frame), 64px gap to the
   header's bottom edge, 88px gap to the footer's top edge. Vertical
   rhythm between internal sections is owned by each row's own top
   margin; sections are added in follow-up iterations against the Figma
   design. The summary is absolutely positioned, so a small script pins a
   min-height here when the summary is the taller column, keeping the
   footer from riding up over it (see the script at the foot of the page). */
.ap-co--payment,
.ap-co--review {
	/* Summary panel width — four grid columns + the three gutters
	   between them, so the right-anchored panel spans from column 8's
	   outer edge to column 11's outer edge (2nd to 5th column counting
	   inwards from the right). Declared here so both the panel and the
	   left column's reservation below stay in lockstep. vw-based
	   `--grid-col-w` for the usual too-deep-in-the-flow reason. */
	--ap-co-summary-w: calc(4 * var(--grid-col-w, 109px) + 3 * var(--grid-gutter, 32px));
	padding: 64px var(--grid-col2-inset, 245px) 88px;
	position: relative; /* anchor for the absolutely-positioned summary panel */
}

/* Active (current) and completed (past) steps share the same dark disc —
   gray-950 fill, no border, white content. Completed swaps the numeral for
   a 14×12 white check (staged at assets/img/sandbox/check-01.svg). */
.ap-co__step--active .ap-co__step__indicator,
.ap-co__step--complete .ap-co__step__indicator {
	border-color: transparent;
	background: var(--gray-950, #191919);
	color: var(--text-white, #FFF);
}

.ap-co__step--complete .ap-co__step__indicator img {
	display: block;
	width: 14px;
	height: 12px;
}

/* Label (`.type-body-md-regular`, Outfit 16/24/400) — muted on inactive
   (future) steps, primary on the active and completed ones. */
.ap-co__step__label {
	color: var(--gray-400, #A3A3A3);
}

.ap-co__step--active .ap-co__step__label,
.ap-co__step--complete .ap-co__step__label {
	color: var(--text-primary, #191919);
}

/* Payment-method options — a stack of collapsible rows under the
   "Pasirinkite mokėjimo būdą" title (16px below it, owned by the title's
   bottom margin). 12px between rows. */
.ap-co__pay-methods {
	display: flex;
	flex-direction: column;
	gap: var(--space-12, 12px);
}

/* Accordion group — the gray-50 rounded shape that owns the fill + 15px
   radius for the whole method (header + its revealed panel). The header
   button and the panel sit transparent inside it, so when the panel
   expands the two read as one continuous pill instead of two stacked
   ones. Collapsed, the group is just the 60px header → an unbroken pill;
   expanded, the panel extends the same shape downward with the radius
   wrapping its bottom corners. */
.ap-co__pay-group {
	border-radius: var(--radius-15, 15px);
	background: var(--gray-50, #F7F7F7);
}

/* Header row — the 60px trigger. Transparent (the group paints the
   gray-50); the `.ap-pp__section-head` primitive already pins transparent
   at every interactive state, so no brand-wash re-assert is needed here. */
.ap-co__pay-method {
	height: 60px;
	padding: var(--space-12, 12px) var(--space-16, 16px);
	box-sizing: border-box;
}

/* Left group — icon + label kept adjacent as a single flex item (the
   primitive's space-between pins the chevron to the right). 16px icon →
   label gap; centred on the y-axis by the row's `align-items: center`. */
.ap-co__pay-method__left {
	display: flex;
	align-items: center;
	gap: var(--space-16, 16px);
	min-width: 0;
}

.ap-co__pay-method__icon {
	display: inline-flex;
	flex: 0 0 24px;
	width: 24px;
	height: 24px;
	aspect-ratio: 1 / 1;
}

.ap-co__pay-method__icon img {
	display: block;
	width: 100%;
	height: 100%;
}

.ap-co__pay-method__title {
	color: var(--text-primary, #191919);
}

/* Provider panel — the controlled sibling revealed when its header reads
   `aria-expanded="true"` (collapsed via `display: none` while false, same
   next-sibling pattern as the discount panel). It sits flush against the
   header inside the group: the primitive's 16px expanded bottom-margin is
   cancelled (below) so the only space above the tiles is the header's own
   12px bottom padding. Padding is `0 16 16` — no top inset (the header
   supplies it), 16px sides + bottom framing the tiles in the group's
   gray-50. A two-up radiogroup: 8px between row neighbours AND between rows
   (single `gap` on the grid). On mobile it drops to one tile per row. */
.ap-co__pay-method[aria-expanded="false"] + .ap-co__pay-options {
	display: none;
}

.ap-co__pay-method[aria-expanded="true"] {
	margin-bottom: 0;
}

.ap-co__pay-options {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--space-8, 8px);
	padding: 0 var(--space-16, 16px) var(--space-16, 16px);
}

/* One provider tile — same selectable-card shape as `.ap-co__method`
   (2px border tracking selection via `--method-border`, the shared radio
   marker), but a fixed 60px row carrying only a left-aligned provider logo
   and the right-pinned radio. White fill so each tile reads against the
   group's gray-50 (mirrors `.ap-co__summary__payments__tile`).
   `justify-content: space-between` pushes the logo and radio to opposite
   edges. */
.ap-co__pay-option {
	--method-border: var(--size-selector-outline-enabled, #E4E4E4);
	display: flex;
	height: 60px;
	box-sizing: border-box;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-16, 16px);
	padding: var(--space-12, 12px) var(--space-16, 16px);
	border: 2px solid var(--method-border);
	border-radius: var(--radius-15, 15px);
	background: var(--gray-0, #FFF);
	cursor: pointer;
	text-align: left;
}

.ap-co__pay-option[aria-pressed="true"] {
	--method-border: var(--size-selector-outline-selected, #191919);
}

.ap-sandbox .ap-co__pay-option:not([aria-pressed="true"]):hover,
.ap-sandbox .ap-co__pay-option:not([aria-pressed="true"]):focus,
.ap-sandbox .ap-co__pay-option:not([aria-pressed="true"]):focus-visible {
	--method-border: var(--size-selector-outline-hover, #A3A3A3);
}

/* Brand-wash lock — keep the white fill and re-assert the state-driven
   border at every interactive state. */
.ap-sandbox .ap-co__pay-option:hover,
.ap-sandbox .ap-co__pay-option:focus,
.ap-sandbox .ap-co__pay-option:focus-visible,
.ap-sandbox .ap-co__pay-option:active {
	background-color: var(--gray-0, #FFF);
	border-color: var(--method-border);
	outline: none;
	box-shadow: none;
}

/* Provider logo — left-aligned; rendered at the 24px max height (forced,
   not capped — SVGs whose intrinsic height is under 24px wouldn't scale up
   under `max-height`), native aspect ratio kept via `width: auto`. */
.ap-co__pay-option__logo {
	display: inline-flex;
	align-items: center;
	min-width: 0;
}

.ap-co__pay-option__logo img {
	display: block;
	height: 24px;
	width: auto;
}

/* Radio marker — the shared 20×20 glyph pinned right; swaps to the checked
   SVG when the tile reads `aria-pressed="true"`. */
.ap-co__pay-option__radio {
	flex: 0 0 20px;
	width: 20px;
	height: 20px;
	background: url('../img/sandbox/radio-unchecked.svg') center no-repeat;
}

.ap-co__pay-option[aria-pressed="true"] .ap-co__pay-option__radio {
	background-image: url('../img/sandbox/radio-checked.svg');
}

/* Mobile (≤768px) — first iteration. Per `[Mobile typography via
   token remap]`, type utilities are left alone — no per-element
   font-size overrides here. The summary, absolutely positioned beside
   the items on desktop, drops to a stacked full-width card below them
   on mobile (see its rule below). */
@media (max-width: 768px) {
	/* Stepper reclaims the full mobile width — the desktop columns-2→6
	   width no longer applies in the stacked layout. */
	.ap-co__steps {
		width: auto;
	}

	/* Stepper goes vertical per step: the label drops beneath the
	   indicator, centred (inherited `align-items: center`), 4px below it.
	   The three steps split the row into equal thirds (`flex: 1 1 0`),
	   spaced by the base 12px gap. */
	.ap-co__step {
		flex: 1 1 0;
		min-width: 0;
		flex-direction: column;
		gap: var(--space-4, 4px);
		position: relative; /* anchor the connector hairline drawn below */
	}
	/* Connector dividers are drawn as a hairline running between each step's
	   indicator and the next step's, instead of the flex-flow
	   `.ap-co__step-connector` elements (hidden below) which would steal
	   width and knock the steps off their equal thirds. Geometry, relative
	   to the step (width W): the line keeps 12px of clearance from each
	   indicator — it starts 12px past this indicator's right edge
	   (50% + 24px + 12px) and stops 12px short of the next indicator's left
	   edge, a span of `W - 60px` (the 12px inter-column gap, the two 24px
	   radii, and the two 12px clearances). It sits at the indicator's
	   vertical centre (24px) and freely overlaps the adjacent column. */
	.ap-co__step:not(:last-child)::after {
		content: '';
		position: absolute;
		top: 24px;
		left: calc(50% + 36px);
		width: calc(100% - 60px);
		height: 1px;
		background: var(--gray-200, #E4E4E4);
	}
	.ap-co__step-connector {
		display: none;
	}

	/* Section title sits 24px below the stepper on mobile (the desktop 64px
	   top margin is too large for the tighter mobile rhythm). */
	.ap-co__delivery-title {
		margin-top: var(--space-24, 24px);
	}

	/* Provider tiles drop to one per row — the desktop two-up grid is too
	   tight for the narrow column. The 8px gap carries over down the column. */
	.ap-co__pay-options {
		grid-template-columns: 1fr;
	}

	/* Delivery-method cards stack one per row, 12px apart (the desktop
	   two-up row + 16px gap don't fit the narrow column). Each card fills
	   the width via the column's default stretch. */
	.ap-co__methods {
		flex-direction: column;
		gap: var(--space-12, 12px);
	}

	/* Form fields go one per row — the paired rows (Vardas/Pavardė,
	   Telefonas/El. paštas, Miestas/Pašto kodas) stack vertically. The
	   existing 16px row gap now applies down the column, matching the 16px
	   rhythm between rows. */
	.ap-co__form-row {
		flex-direction: column;
	}

	/* Delivery column reclaims the full mobile width — the desktop
	   columns-2→6 width no longer applies because the summary panel
	   stacks below. */
	.ap-co__delivery {
		width: auto;
	}

	/* Summary stacks below the items as a card on the mobile grid.
	   `order: 1` drops it past the items (it precedes them in the DOM);
	   static positioning + auto width/height shed the desktop absolute
	   533×594 panel so it sizes to its content. The card sits inside
	   `.ap-co`'s 24px insets — flush with the grid margins like every
	   other row — and its own 32px padding keeps the content inset. It keeps its gray-50 fill + 15px radius from the base
	   rule — the same background shape as
	   `.ap-pp__sizes-table-modal__visual`. 32px gap separates it from
	   the delivery form above. */
	.ap-co__summary {
		order: 1;
		position: static;
		width: auto;
		height: auto;
		min-height: 0;
		margin-top: 32px;
		/* Full-bleed panel per the mobile frame (Figma 1159-3577): the
		   gray spans edge to edge — negative margins cancel the
		   wrapper's 24px insets, corners square off — and `flex: 1`
		   swallows the wrapper's min-height slack on short pages so
		   the panel runs straight into the footer instead of leaving
		   a white gap. Content stays on the 24px grid margin via the
		   panel's own padding; 64px below the payments row per frame. */
		margin-inline: -24px;
		flex: 1 0 auto;
		/* Top corners keep the 15px rounding (Figma 1166-3989) — only
		   the bottom squares off where the panel meets the footer. */
		border-radius: var(--radius-15, 15px) var(--radius-15, 15px) 0 0;
		padding: 24px 24px 64px;
	}
}

/* ══════════ from checkout-review-sandbox.php ══════════ */

/* Review cards — one bordered panel per completed step (Pristatymas,
   Mokėjimo būdas, …) stacked under the stepper. The wrapper sits 54px below
   the stepper (16px on mobile, set in the media query); 16px between cards.
   As the first child of `.ap-co__delivery` (which sits flush under the
   stepper), the 54px reads as the stepper→cards gap whether or not the
   margin collapses through. */
.ap-co__review {
	margin-top: 54px;
	display: flex;
	flex-direction: column;
	gap: var(--space-16, 16px);
}

/* One card — full-width bordered container; 8px top, 16px sides + bottom
   padding, 8px between its rows (header + any detail added later). */
.ap-co__review-card {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-8, 8px);
	padding: var(--space-8, 8px) var(--space-16, 16px) var(--space-16, 16px);
	border: 1px solid var(--size-selector-outline-enabled, #E4E4E4);
	border-radius: var(--radius-15, 15px);
}

/* Header row — step title on the left, "Keisti" button on the right.
   `align-self: stretch` spans the card's inner width (the card is
   `align-items: flex-start`) so space-between pins the button to the
   right edge. */
.ap-co__review-card__head {
	display: flex;
	align-self: stretch;
	justify-content: space-between;
	align-items: center;
	gap: var(--space-12, 12px);
}

.ap-co__review-card__title {
	color: var(--text-primary, #191919);
}

/* Edit button — 40px tall tertiary (white) pill: 16px bag icon + 8px +
   "Keisti" label. The sandbox neutraliser strips its resting chrome, so
   this owns layout + the white fill; the brand-wash lock re-asserts that
   fill at every interactive state. */
.ap-co__review-card__edit {
	display: flex;
	height: 40px;
	padding: var(--space-8, 8px) var(--space-12, 12px);
	box-sizing: border-box;
	justify-content: center;
	align-items: center;
	gap: var(--space-8, 8px);
	border-radius: var(--radius-10, 10px);
	background: var(--button-tertiary-background-enabled, #FFF);
	cursor: pointer;
}

.ap-sandbox .ap-co__review-card__edit:hover,
.ap-sandbox .ap-co__review-card__edit:focus,
.ap-sandbox .ap-co__review-card__edit:focus-visible,
.ap-sandbox .ap-co__review-card__edit:active {
	background-color: var(--button-tertiary-background-enabled, #FFF);
	border-color: transparent;
	outline: none;
	box-shadow: none;
}

.ap-co__review-card__edit__icon {
	display: inline-flex;
	flex: 0 0 16px;
	width: 16px;
	height: 16px;
	aspect-ratio: 1 / 1;
}

.ap-co__review-card__edit__icon img {
	display: block;
	width: 100%;
	height: 100%;
}

.ap-co__review-card__edit__label {
	color: var(--text-primary, #191919);
}

/* Card body — the step's saved values. The card's 8px column gap puts the
   name 8px below the header and the details block 8px below the name. The
   detail lines sit tight (line-height only), so they live in their own
   wrapper to escape the card's 8px gap; the neutraliser zeroes their <p>
   margins. */
.ap-co__review-card__name {
	color: var(--text-primary, #191919);
}

.ap-co__review-card__detail {
	color: var(--text-secondary, #5C5C5C);
}

/* Mobile (≤768px) — first iteration. Per `[Mobile typography via
   token remap]`, type utilities are left alone — no per-element
   font-size overrides here. The summary, absolutely positioned beside
   the items on desktop, drops to a stacked full-width card below them
   on mobile (see its rule below). */
@media (max-width: 768px) {
	/* Stepper reclaims the full mobile width — the desktop columns-2→6
	   width no longer applies in the stacked layout. */
	.ap-co__steps {
		width: auto;
	}

	/* Stepper goes vertical per step: the label drops beneath the
	   indicator, centred (inherited `align-items: center`), 4px below it.
	   The three steps split the row into equal thirds (`flex: 1 1 0`),
	   spaced by the base 12px gap. */
	.ap-co__step {
		flex: 1 1 0;
		min-width: 0;
		flex-direction: column;
		gap: var(--space-4, 4px);
		position: relative; /* anchor the connector hairline drawn below */
	}
	/* Connector dividers are drawn as a hairline running between each step's
	   indicator and the next step's, instead of the flex-flow
	   `.ap-co__step-connector` elements (hidden below) which would steal
	   width and knock the steps off their equal thirds. Geometry, relative
	   to the step (width W): the line keeps 12px of clearance from each
	   indicator — it starts 12px past this indicator's right edge
	   (50% + 24px + 12px) and stops 12px short of the next indicator's left
	   edge, a span of `W - 60px` (the 12px inter-column gap, the two 24px
	   radii, and the two 12px clearances). It sits at the indicator's
	   vertical centre (24px) and freely overlaps the adjacent column. */
	.ap-co__step:not(:last-child)::after {
		content: '';
		position: absolute;
		top: 24px;
		left: calc(50% + 36px);
		width: calc(100% - 60px);
		height: 1px;
		background: var(--gray-200, #E4E4E4);
	}
	.ap-co__step-connector {
		display: none;
	}

	/* Section title sits 24px below the stepper on mobile (the desktop 64px
	   top margin is too large for the tighter mobile rhythm). */
	.ap-co__delivery-title {
		margin-top: var(--space-24, 24px);
	}

	/* Review cards sit 16px below the stepper on mobile (54px on desktop). */
	.ap-co__review {
		margin-top: var(--space-16, 16px);
	}

	/* Delivery-method cards stack one per row, 12px apart (the desktop
	   two-up row + 16px gap don't fit the narrow column). Each card fills
	   the width via the column's default stretch. */
	.ap-co__methods {
		flex-direction: column;
		gap: var(--space-12, 12px);
	}

	/* Form fields go one per row — the paired rows (Vardas/Pavardė,
	   Telefonas/El. paštas, Miestas/Pašto kodas) stack vertically. The
	   existing 16px row gap now applies down the column, matching the 16px
	   rhythm between rows. */
	.ap-co__form-row {
		flex-direction: column;
	}

	/* Delivery column reclaims the full mobile width — the desktop
	   columns-2→6 width no longer applies because the summary panel
	   stacks below. */
	.ap-co__delivery {
		width: auto;
	}

	/* Summary stacks below the items as a card on the mobile grid.
	   `order: 1` drops it past the items (it precedes them in the DOM);
	   static positioning + auto width/height shed the desktop absolute
	   533×594 panel so it sizes to its content. The card sits inside
	   `.ap-co`'s 24px insets — flush with the grid margins like every
	   other row — and its own 32px padding keeps the content inset. It keeps its gray-50 fill + 15px radius from the base
	   rule — the same background shape as
	   `.ap-pp__sizes-table-modal__visual`. 32px gap separates it from
	   the delivery form above. */
	.ap-co__summary {
		order: 1;
		position: static;
		width: auto;
		height: auto;
		min-height: 0;
		margin-top: 32px;
		/* Full-bleed panel per the mobile frame (Figma 1159-3577): the
		   gray spans edge to edge — negative margins cancel the
		   wrapper's 24px insets, corners square off — and `flex: 1`
		   swallows the wrapper's min-height slack on short pages so
		   the panel runs straight into the footer instead of leaving
		   a white gap. Content stays on the 24px grid margin via the
		   panel's own padding; 64px below the payments row per frame. */
		margin-inline: -24px;
		flex: 1 0 auto;
		/* Top corners keep the 15px rounding (Figma 1166-3989) — only
		   the bottom squares off where the panel meets the footer. */
		border-radius: var(--radius-15, 15px) var(--radius-15, 15px) 0 0;
		padding: 24px 24px 64px;
	}
}

/* ══════════ from checkout-confirmation-sandbox.php ══════════ */

/* Checkout body wrapper — horizontal page insets pin the content to
   the outer edge of grid column 5 / column 8 (`--grid-col5-inset`;
   ≈ 680px at the 1920 frame), so the content spans the middle four
   columns. 64px gap to the header's bottom edge, 88px gap to the
   footer's top edge. */
.ap-co--confirmation {
	padding: 64px var(--grid-col5-inset, 680px) 88px;
}

/* Confirmation hero — a centred column holding the success badge, the
   heading, and the note. The 64px gap below the header is owned by the
   wrapper's top padding (24px on mobile, per the family baseline); the
   gaps between the three rows live on each row's own top margin. */
.ap-co__confirmation {
	display: flex;
	flex-direction: column;
	align-items: center;
}

/* Success badge — a black round chip framing the green ring + white check.
   `inline-flex` hugs the chip to its content (a full-flex element would
   stretch into a bar); the column centres it. The chip itself is static —
   only the ring and tick inside it animate. */
.ap-co__success {
	display: inline-flex;
	padding: var(--space-8, 8px);
	justify-content: center;
	align-items: center;
	gap: 10px;
	border-radius: var(--radius-999, 999px);
	background: var(--basic-black, #000);
}

/* The 56px green ring + white check, drawn as one SVG so both strokes can
   sweep on (a CSS border can't be stroke-animated). The green has no token
   (the discount success check hardcodes the same #2ABA00). */
.ap-co__success__check {
	display: block;
	width: 56px;
	height: 56px;
}

/* Draw-on — mirrors `ap-co__summary__discount-applied__check`: the green ring
   sweeps clockwise from the top while the white tick strokes on left→right
   alongside it, both over 0.7s so they complete together. pathLength="1"
   normalises each path so |dashoffset| 1 = undrawn, 0 = full; resting at -1
   draws each from its path end backward — the ring path runs counter-clockwise
   from the top, so reversing yields the clockwise sweep, and the tick is
   defined right→left, so it yields left→right.

   `stroke-dashoffset` animates on the main thread (not the compositor), so the
   draw-on is gated behind `.is-confirmed`, added by JS once fonts/load have
   settled. Firing on initial parse instead would race the page's first
   layout/paint + webfont reflow and drop frames — the discount check looks
   smoother only because it fires on a click, when the main thread is idle. */
.ap-co__success__check-ring,
.ap-co__success__check-tick {
	stroke-dasharray: 1;
	stroke-dashoffset: -1;
}

.ap-co__success.is-confirmed .ap-co__success__check-ring,
.ap-co__success.is-confirmed .ap-co__success__check-tick {
	animation: ap-co-success-draw 0.7s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

@keyframes ap-co-success-draw {
	to { stroke-dashoffset: 0; }
}

/* Reduced motion — show the ring + tick fully formed, no draw-on (no gate
   needed; the resting offset is overridden straight to fully drawn). */
@media (prefers-reduced-motion: reduce) {
	.ap-co__success__check-ring,
	.ap-co__success__check-tick {
		animation: none;
		stroke-dashoffset: 0;
	}
}

/* Heading — "Ačiū už užsakymą!". Typography is the `.type-heading-md`
   utility (Special Gothic Expanded One 32/1.1, 0.025em ≈ 0.8px tracking,
   uppercase) so the brandbook scale stays the source of truth; this only
   owns the 32px gap below the badge, centring, and the primary colour. */
.ap-co__confirmation__title {
	margin-top: var(--space-32, 32px);
	color: var(--text-primary, #191919);
	text-align: center;
}

/* Note — "Užsakymo patvirtinimą išsiuntėme adresu …". `.type-body-md-regular`
   (Outfit 16/24/400); tertiary body text 8px below the heading, with the
   email span lifted to the primary colour. */
.ap-co__confirmation__note {
	margin-top: var(--space-8, 8px);
	color: var(--text-tertiary, #787878);
	text-align: center;
}

.ap-co__confirmation__note-email {
	color: var(--text-primary, #191919);
}

/* Order-summary card — gray-50 panel 32px below the note, holding the
   order's key facts as label/value rows. `align-self: stretch` spans the
   full content width inside the centred hero column; 32px padding all round,
   12px between rows. `align-items: flex-start` keeps the card hugging its
   own content vertically, so each row carries `align-self: stretch` to span
   the card width and let space-between push the value to the right edge. */
.ap-co__order {
	margin-top: var(--space-32, 32px);
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	align-self: stretch;
	gap: var(--space-12, 12px);
	padding: var(--space-32, 32px);
	box-sizing: border-box;
	border-radius: var(--radius-15, 15px);
	background: var(--gray-50, #F7F7F7);
}

.ap-co__order__row {
	display: flex;
	align-self: stretch;
	justify-content: space-between;
	align-items: baseline;
	gap: var(--space-12, 12px);
}

.ap-co__order__label {
	color: var(--text-tertiary, #787878);
}

.ap-co__order__value {
	color: var(--text-primary, #191919);
	text-align: right;
}

/* The live account-creation block is a <form.ap-co__account> (the sandbox
   had bare siblings). `display: contents` makes the form layout-transparent
   so its children (title / password / button) remain direct flex children
   of the centred `.ap-co__confirmation` column, exactly as in the sandbox. */
.ap-co__account {
	display: contents;
}

/* Account-creation prompt — invites the visitor to set a password and keep
   their pre-filled details as an AGO account. `.type-heading-sm-medium`
   (Outfit 20/22/500) carries the type; this owns the 32px gap below the
   order card, centring, and the primary colour. */
.ap-co__account-title {
	margin-top: var(--space-32, 32px);
	color: var(--text-primary, #191919);
	text-align: center;
}

/* Password field — the shared `.ap-pp__personalize__field-input` primitive
   8px below the prompt, full-width across the hero column, with a
   show/hide toggle pinned to the right. The wrapper positions the toggle;
   the input reserves 48px of right padding so the value never slides under
   it. */
.ap-co__password {
	margin-top: var(--space-8, 8px);
	position: relative;
	align-self: stretch;
}

.ap-co__password .ap-pp__personalize__field-input {
	width: 100%;
	padding-right: 48px;
	/* Typed value is always primary — only the placeholder stays gray. The
	   shared primitive sets this colour on focus but not at rest, so pin it
	   here so an entered password never reads as gray when the field blurs. */
	color: var(--text-primary, #191919);
}

/* Toggle — bare 24×24 icon shell sitting inside the input's padding box:
   12px from the right edge (matching the field's 12px side padding),
   vertically centred over the 60px field. The neutraliser strips its
   button chrome at rest; this only owns the shell box + placement. The
   icon renders at its own intrinsic size, centred within the shell. */
.ap-co__password__toggle {
	position: absolute;
	top: 50%;
	right: var(--space-12, 12px);
	transform: translateY(-50%);
	width: 24px;
	height: 24px;
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
}

.ap-co__password__toggle__icon {
	display: block;
}

/* Continue CTA — "Tęsti apsipirkimą". Same primary-button shape as
   `.ap-co__delivery-submit` (60px, 18×20 padding, 15px radius, Outfit
   16/24/500); 32px below the card and full-width across the hero column.
   Always enabled here, so only the enabled interactive states need the
   brand-wash lock per `feedback_lock_button_states_against_brand_wash`. */
.ap-co__continue {
	margin-top: var(--space-32, 32px);
	display: flex;
	width: 100%;
	height: 60px;
	padding: 18px 20px;
	box-sizing: border-box;
	justify-content: center;
	align-items: center;
	align-self: stretch;
	gap: var(--space-8, 8px);
	border-radius: var(--radius-15, 15px);
	background: var(--button-primary-background-enabled, #191919);
	color: var(--text-white, #FFF);
	cursor: pointer;
	font-family: var(--font-family-ui, 'Outfit', sans-serif);
	font-size: var(--font-size-16, 16px);
	font-weight: var(--font-weight-medium, 500);
	line-height: 1.5;
}

.ap-sandbox .ap-co__continue:hover,
.ap-sandbox .ap-co__continue:focus,
.ap-sandbox .ap-co__continue:focus-visible,
.ap-sandbox .ap-co__continue:active {
	background-color: var(--button-primary-background-enabled, #191919);
	color: var(--text-white, #FFF);
	border-color: transparent;
	outline: none;
	box-shadow: none;
}

/* Mobile (≤768px) — 24px top inset puts the content 24px below the header
   per spec; 24px horizontal inset matches the sibling sandboxes' mobile
   baseline (`tenant-products-list-sandbox.php`). Flex column so the content
   stacks naturally as it's added. */
@media (max-width: 768px) {
	.ap-co--confirmation {
		padding: 24px 24px 64px;
		display: flex;
		flex-direction: column;
	}
}

/* ══════════ step-scoped mobile base — MUST stay at the end of the
   file ══════════
   The flow steps' shared mobile wrapper rule. It lives here, after
   every section's DESKTOP `.ap-co--*` base rule, because they tie at
   (0,1,0) and only source order decides: when this block sat in the
   cart section it lost to the payment/review desktop rules declared
   later in the file, squeezing steps 2-3 into the desktop col2 insets
   at 390px (found with real data 2026-07-27). */
@media (max-width: 768px) {
	/* Page wrapper — 24px top inset puts the title 24px below the
	   header per spec; 24px horizontal inset matches the sibling
	   sandboxes' mobile baseline (`tenant-products-list-sandbox.php`).
	   Bottom inset zeroed so the footer butts straight onto the
	   summary card — the 64px gap below the payments row is owned by
	   the card's own bottom padding. Flex column so the children
	   stack and the summary can be re-ordered after the items via
	   `order`. */
	.ap-co--cart,
	.ap-co--review,
	.ap-co--delivery,
	.ap-co--payment {
		padding-top: 24px;
		padding-left: 24px;
		padding-right: 24px;
		padding-bottom: 0;
		display: flex;
		flex-direction: column;
	}
}

/* ── Empty cart (spec gap — no Figma design; confirmed 2026-08-03 the
   cart cluster has no empty frame). A minimal, honest centred state in
   place of the items/summary grid — no invented layout. The compound
   `.ap-co--cart.ap-co--empty` (0,2,0) beats the cart grid rule
   regardless of source order. ── */
.ap-co--cart.ap-co--empty {
	display: block;
}
.ap-co__empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-24, 24px);
	margin-top: var(--space-48, 48px);
	text-align: center;
}
.ap-co__empty__text {
	color: var(--text-secondary, #5C5C5C);
}
.ap-co__empty__cta {
	display: inline-flex;
	height: 60px;
	padding: 18px 32px;
	box-sizing: border-box;
	justify-content: center;
	align-items: center;
	border-radius: var(--radius-15, 15px);
	background: var(--button-primary-background-enabled, #191919);
	color: var(--text-white, #FFF);
	font-family: var(--font-family-ui, 'Outfit', sans-serif);
	font-size: var(--font-size-16, 16px);
	font-weight: var(--font-weight-medium, 500);
	line-height: 1.5;
	text-decoration: none;
}
.ap-sandbox .ap-co__empty__cta:hover,
.ap-sandbox .ap-co__empty__cta:focus,
.ap-sandbox .ap-co__empty__cta:focus-visible,
.ap-sandbox .ap-co__empty__cta:active {
	background-color: var(--button-primary-background-enabled, #191919);
	color: var(--text-white, #FFF);
	border-color: transparent;
	outline: none;
	box-shadow: none;
	text-decoration: none;
}

/* ══════════ ≤1512px (down to the mobile breakpoint) ══════════ */

/* The middle-ten-column footprint widens to all 12: both outer edges
   step out from columns 2/11 to columns 1/12 while every inner edge
   stays put. The left column (stepper + form / items) grows to six
   columns (right edge holds on column 6) and the summary to five
   (left edge holds on column 8) exactly as the wrapper's padding
   sheds one column-step per side. The confirmation step keeps its own
   centred `--grid-col5-inset` footprint — deliberately not included.
   Kept in lockstep with the checkout sandboxes' blocks of the same
   name. */
@media (min-width: 769px) and (max-width: 1512px) {
	.ap-co--cart,
	.ap-co--delivery,
	.ap-co--payment,
	.ap-co--review {
		--ap-co-summary-w: calc(5 * var(--grid-col-w, 109px) + 4 * var(--grid-gutter, 32px));
		padding-inline: var(--grid-margin, 96px);
	}
	.ap-co__summary-rail {
		right: var(--grid-margin, 96px);
	}
	.ap-co__steps,
	.ap-co__delivery {
		width: calc(6 * var(--grid-col-w, 101px) + 5 * var(--grid-gutter, 32px));
	}
	.ap-co__items > .ap-pp__divider {
		width: calc(6 * var(--grid-col-w, 101px) + 5 * var(--grid-gutter, 32px));
	}
}
