/*
 * Daylon — cart and checkout (DAY-19), against the Cart and checkout UX spec v8.
 *
 * Styles WooCommerce's own block cart and block checkout (§9: "no WooCommerce template
 * override, and no plugin"). Class names below are the Blocks package's own stable,
 * documented markup (`wc-block-cart`, `wc-block-checkout`, `wc-block-components-*`);
 * this file adds no markup of its own except the free-delivery line, the corridor
 * reduction, and the error-summary pattern, all built by cart-checkout.js into
 * containers this stylesheet already expects.
 *
 * The layout was checked against the real rendered DOM on staging, and at 320, 768,
 * 1024 and 1440, on 2026-09-18 (DAY-19 comment 11156).
 *
 * Tokens from theme.json (STANDARDS.md §7). The error colour is theme.json's `error`
 * (DAY-28 v6 §4.4), aliased below; its pale ground has no token, so it stays local.
 *
 * Breakpoints: 320, 768, 1024, 1440 — Daylon's declared set (ENVIRONMENTS.md), the
 * same ones the spec cites in §3.7 and §4.4.
 */

:root {
	--daylon-error: var(--wp--preset--color--error);
	--daylon-error-bg: #fbeaea;
}

/* ---------------------------------------------------------------- the corridor, §2 */

/* Everything the corridor removes is still in the shared header/footer template
   parts (STANDARDS.md §2 — one template, not a second copy); this hides it only on
   the class the three corridor pages carry.

   ⚠️ The account link is NOT in this list, and that is deliberate (DAY-170). Spec v14 §2
   removes it outright and §8 asks for it to be out of the reading order at every width,
   so it is dropped before it renders — `daylon_corridor_remove_account_link()` in
   inc/checkout.php. Hiding it here as well would give one rule two homes, and the CSS
   one is the half that a stylesheet that fails to load stops enforcing.

   The menu's toggle goes with the bar that holds it, not on its own: an empty bar is still an
   item in the header's row, and its gap pushed the wordmark off the page container's edge
   (DAY-362). */
body.daylon-corridor .daylon-header__bar,
body.daylon-corridor .daylon-flat-nav,
body.daylon-corridor .daylon-search,
body.daylon-corridor .daylon-cart-link {
	display: none;
}

body.daylon-corridor .daylon-footer {
	padding-block: var(--wp--preset--spacing--30);
}

/* "The footer shrinks to the legal links. Nothing else." (§2) — and the Legal group in
   particular stays, because withdrawing cookie consent has to remain reachable from the
   checkout (DAY-33 v13 §3.4). The keeping class is on the group itself in
   `parts/footer.html`: without it this rule hid the legal links too, which is the half
   of DAY-133 that was already live on the cart. */
body.daylon-corridor .daylon-footer__group:not(.daylon-footer__legal) {
	display: none;
}

/* ‹ Volver al carrito — checkout only, never rely on the browser's back button (§2). */
.daylon-back-to-cart {
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--10, 0.25rem);
	margin-block-end: var(--wp--preset--spacing--30);
	color: var(--wp--preset--color--main);
	text-decoration: none;
	font-size: var(--wp--preset--font-size--small);
}

.daylon-back-to-cart:hover,
.daylon-back-to-cart:focus-visible {
	text-decoration: underline;
}

/* ---------------------------------------------------------------- focus, everywhere */

.wc-block-cart a:focus-visible,
.wc-block-cart button:focus-visible,
.wc-block-cart input:focus-visible,
.wc-block-checkout a:focus-visible,
.wc-block-checkout button:focus-visible,
.wc-block-checkout input:focus-visible,
.wc-block-checkout select:focus-visible,
.daylon-order-confirmation-notes a:focus-visible {
	outline: 3px solid var(--wp--preset--color--primary);
	outline-offset: 2px;
}

/* Woo Blocks ships its own default focus/error styling in package CSS; this file only
   layers the theme's own focus ring and colour, never removes the package's own
   :focus handling (no outline: none anywhere in this file). */

/* ---------------------------------------------------------------- the two-column layout, §3.1, §4.1 */

.wc-block-cart__main {
	padding-block-start: var(--wp--preset--spacing--40);
}

/* Scoped to `.wc-block-components-sidebar-layout`, the one element in each block that
   holds the main column and the summary. The checkout block also puts
   `wc-block-checkout` on its outer wrapper, so a bare `.wc-block-checkout` selector
   made that wrapper a grid too, and pushed its notices into the summary column.
   No width, margin or side padding of its own: the template's group is the page container,
   and the two columns split inside it (style.css; "Page container" spec §3). */
@media (min-width: 1024px) {
	.wc-block-components-sidebar-layout.wc-block-cart,
	.wc-block-components-sidebar-layout.wc-block-checkout {
		display: grid;
		/* minmax(0, …): a long line or the error summary must not widen the track
		   past the viewport (DAY-19 comment 11156: 1081px of scroll at 1024). */
		grid-template-columns: minmax(0, 1fr) 360px;
		/* No gap: Ollie already draws the gutter, as padding on both columns and a
		   divider on the main one. A gap would double it. */
		gap: 0;
		align-items: start;
	}

	/* Woo sizes these as 65% / 35% of its flex row. Inside a grid track the
	   percentages resolve against the track, which is how the summary collapsed to
	   126px (DAY-19 comment 11156). The grid sizes the columns. */
	.wc-block-components-sidebar-layout .wc-block-components-main,
	.wc-block-components-sidebar-layout .wc-block-components-sidebar {
		width: auto;
		margin: 0;
	}

	/* Its gap, under the site header: the header is pinned too (style.css) and stands in
	   front, so at the gap alone the summary's first lines slid behind it (DAY-394). */
	.wc-block-cart__sidebar,
	.wc-block-checkout__sidebar {
		position: sticky;
		top: calc(var(--wp-admin--admin-bar--height, 0px) + var(--daylon-header-height, 102px) + var(--wp--preset--spacing--40));
	}
}

/* Below the rule above, Woo's 65% / 35% flex row left the checkout summary ~200px wide,
   and a line item's name ~50px: «RELLE / NO – / Umbra / l 49,00» at 768 (DAY-235). Same
   two columns, same order — only the summary's track is sized so a whole word fits: the
   name keeps ≥99px from 768 to 1023px (the least at ~830), enough for the longest real
   words («Sobrecamisa», ~96px). The track grows with the width because the gutter and
   the type do too; a flat 300px left 92px at 1023. It meets the 360px of the rule above.
   Keyed to `.is-large`, the class Woo sets when it draws two columns: below it
   (`.is-medium`, under ~768px) Woo stacks the summary on top and a grid here would pull it
   into a left column. The cart's summary carries no line items and keeps Woo's split. */
@media (max-width: 1023px) {
	.wc-block-components-sidebar-layout.wc-block-checkout.is-large {
		display: grid;
		grid-template-columns: minmax(0, 1fr) clamp(300px, 36vw, 360px);
		gap: 0;
		align-items: start;
	}

	.wc-block-components-sidebar-layout.is-large .wc-block-checkout__main,
	.wc-block-components-sidebar-layout.is-large .wc-block-checkout__sidebar {
		width: auto;
		margin: 0;
	}
}

/* ---------------------------------------------------------------- a cart line, §3.2 */

.wc-block-cart-item {
	border-block-end: 1px solid var(--wp--preset--color--border-light);
	padding-block: var(--wp--preset--spacing--30);
}

.wc-block-cart-item__image img {
	aspect-ratio: 4 / 5;
	object-fit: cover;
}

/* The chosen variant — talla, color — is the single most re-checked line (§3.2);
   it must never read as secondary metadata. */
.wc-block-cart-item__wrap .wc-block-components-product-metadata {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--main);
	font-weight: 500;
}

/* The unit price, once per line (DAY-323). WooCommerce prints it under the name and prints
   the line's total at the right; with one unit the two are the same figure, twice. It is
   hidden only then — from two units up they differ and both are information. React keeps the
   input's `value` attribute in step with the quantity (measured on staging, WC 11.1.2). */
.wc-block-cart .wc-block-cart-items__row:has(.wc-block-components-quantity-selector__input[value="1"]) .wc-block-cart-item__prices {
	display: none;
}

/* ---------------------------------------------------------------- quantity, §3.3 */

.wc-block-components-quantity-selector {
	min-height: 44px;
}

.wc-block-components-quantity-selector__button,
.wc-block-components-quantity-selector__input {
	min-height: 44px;
	min-width: 44px;
}

/* The two rules above never reached the cart (DAY-19 comment 11179: −/+ measured 34×35).
   Ollie's woocommerce.css shrinks the whole stepper with `transform: scale(0.8)`, so 44 px
   renders as 35, and Woo Blocks' `min-width: 30px` on the buttons outweighs a one-class
   rule. Both are matched here, scoped to the cart, where the stepper is a line's control. */
.wc-block-cart .wc-block-components-quantity-selector {
	transform: none;
	gap: 0;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 5px;
}

.wc-block-cart .wc-block-components-quantity-selector .wc-block-components-quantity-selector__button {
	min-width: 44px;
	border-radius: 0;
	font-size: var(--wp--preset--font-size--medium);
}

/* One control, not three (DAY-323): − and + were 13 px glyphs floating 5 px either side of a
   boxed number. The edge moves to the group, the number keeps only its two dividers, and at
   44 px wide the stepper leaves room for the remove button beside it at 390 px (it still
   wraps beneath at 320, as below). */
.wc-block-cart .wc-block-components-quantity-selector input.wc-block-components-quantity-selector__input {
	min-width: 44px;
	max-width: 44px;
	padding-inline: 0;
	border-block: 0;
	border-inline: 1px solid var(--wp--preset--color--border-light);
	border-radius: 0;
	text-align: center;
}

/* Remove, §3.2 and §8 — the trash icon was a 24×24 target with no focus indicator at all.
   Woo Blocks sizes it 24 px and sets `box-shadow: none` at (0,4,1); the site-wide ring is a
   box-shadow and sets `outline: none`, so the two cancelled out and nothing showed. Matched
   one class higher; `:not([hidden])` leaves Woo's own hiding of the link alone. */
.wc-block-cart table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__quantity .wc-block-cart-item__remove-link:not([hidden]) {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	vertical-align: middle;
}

/* The stepper and the remove button need ~186 px, and the line's details column is ~155 px
   at 320 — so the remove button wraps beneath the stepper there, instead of being squeezed
   back to 24 px or pushed past the row. */
.wc-block-cart .wc-block-cart-items .wc-block-cart-item__quantity {
	flex-wrap: wrap;
	row-gap: var(--wp--preset--spacing--20);
}

.wc-block-cart table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__quantity .wc-block-cart-item__remove-link:focus-visible {
	outline: none;
	box-shadow:
		0 0 0 2px var(--wp--preset--color--base),
		0 0 0 4px var(--wp--preset--color--main);
}

/* Forced colours drop the shadow: a real outline in a system colour, as in style.css. */
@media (forced-colors: active) {
	.wc-block-cart table.wc-block-cart-items .wc-block-cart-items__row .wc-block-cart-item__quantity .wc-block-cart-item__remove-link:focus-visible {
		outline: 2px solid CanvasText;
		outline-offset: 2px;
	}
}

/* No <select> ships for quantity in Woo Blocks by default; nothing here reintroduces
   one (§3.3 "No <select> for quantity"). */

/* Stock-clamp and total-change notices reuse Woo Blocks' own notice component —
   styled, not replaced, so the platform's own role="status"/aria-live wiring stays
   intact (§6 states 2–4, §8). */
.wc-block-components-notice-banner {
	border-radius: 2px;
}

.wc-block-components-notice-banner.is-error {
	border-color: var(--daylon-error);
	background: var(--daylon-error-bg);
	color: var(--daylon-error);
}

/* ---------------------------------------------------------------- removing, with undo, §3.4 */

.daylon-cart-undo {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--30);
	padding-block: var(--wp--preset--spacing--30);
	border-block-end: 1px solid var(--wp--preset--color--border-light);
	font-size: var(--wp--preset--font-size--small);
}

.daylon-cart-undo__action {
	background: none;
	border: none;
	padding: 0;
	color: var(--wp--preset--color--primary);
	text-decoration: underline;
	cursor: pointer;
	font: inherit;
	min-height: 44px;
}

/* ---------------------------------------------------------------- the coupon field, §3.5 */

.wc-block-components-totals-coupon {
	border-block-start: 1px solid var(--wp--preset--color--border-light);
	padding-block-start: var(--wp--preset--spacing--30);
}

/* «Introduce el código» is the field's label, not a message (DAY-323). The `position: static`
   rule under «validation» never reaches the checkout's own fields — Woo Blocks' selector
   there is one class heavier — so the coupon was the one field whose label dropped beneath
   its input, where an invalid code then painted it red: two red lines, one of them asking
   for a code already typed. It floats inside the field like every other label on these
   pages, and keeps its own colour; the field's edge and WooCommerce's message say the rest.
   Back in the field, it also stops stretching «Aplicar» past the input's height. */
.wc-block-components-totals-coupon .wc-block-components-text-input label {
	position: absolute;
	transform: translateY(-50%);
}

.wc-block-components-totals-coupon .wc-block-components-text-input.is-active label,
.wc-block-components-totals-coupon .wc-block-components-text-input input:-webkit-autofill + label {
	transform: scale(0.82);
}

.wc-block-components-totals-coupon .wc-block-components-text-input.has-error label {
	color: var(--wp--preset--color--secondary);
}

/* The applied coupon's «×» (DAY-323): a 16 px target. The button is 44 px and transparent,
   the disc is drawn on its icon, and the negative margin keeps the chip the size it was. */
.wc-block-components-totals-discount__coupon-list .wc-block-components-chip .wc-block-components-chip__remove {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	margin: -10px -10px -10px 0;
	border-radius: 50%;
	background: transparent;
}

.wc-block-components-totals-discount__coupon-list .wc-block-components-chip .wc-block-components-chip__remove-icon {
	box-sizing: border-box;
	width: 24px;
	height: 24px;
	padding: 4px;
	border-radius: 50%;
	background: var(--wp--preset--color--tertiary);
	fill: var(--wp--preset--color--main);
}

.wc-block-components-totals-discount__coupon-list .wc-block-components-chip .wc-block-components-chip__remove:is(:hover, :focus) .wc-block-components-chip__remove-icon {
	background: var(--wp--preset--color--main);
	fill: var(--wp--preset--color--base);
}

/* A tapped button stays `:hover` on a touch screen until the next tap elsewhere, and the
   shop's hover is ink — so after «Aplicar» the phone showed a dark block on a terracotta
   page (DAY-323). Where nothing can hover, hover changes nothing; with a mouse the buttons
   here keep the hover every other button in the shop has. */
@media (hover: none) {
	.wc-block-components-button.wp-element-button.contained:hover {
		background-color: var(--wp--preset--color--primary);
	}
}

/* ---------------------------------------------------------------- costs, §3.6 */

.wc-block-cart__totals-title,
.wc-block-components-totals-item__label {
	font-weight: 500;
}

.wc-block-components-totals-item.wc-block-cart__totals-row--full {
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 600;
}

/* State 8: the shipping row is present, marked, never 0,00 €. */
.wc-block-components-shipping-placeholder,
.wc-block-components-totals-shipping .wc-block-components-notice-banner {
	font-style: italic;
}

/* ---------------------------------------------------------------- the threshold line, §3.7, state 18 */

.daylon-delivery-status {
	margin-block: var(--wp--preset--spacing--30);
	padding: var(--wp--preset--spacing--20, 0.5rem) var(--wp--preset--spacing--30);
	background: var(--wp--preset--color--tertiary);
	border-radius: 2px;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--main);
	/* Not focusable, not a live region of its own (§8) — it rides the cart's
	   existing total-update announcement, built in cart-checkout.js. */
}

/* Never a badge, tooltip, sticky bar or promotional treatment (§3.7). */
.daylon-delivery-status--badge,
.daylon-delivery-status--sticky {
	all: unset;
}

@media (max-width: 767px) {
	.daylon-delivery-status {
		width: 100%;
	}
}

/* ---------------------------------------------------------------- the shop's notice, repeated in the order summary */

/* «Site notice banner» spec v2 §6 (DAY-335): the notice's text once more, above the shipping
   line, mounted by cart-checkout.js. A quiet paragraph in the summary's own type and colour —
   no band of its own, no icon: the band at the top is the notice, this is the reminder next to
   the delivery it is about. */
.daylon-notice-repeat {
	margin: 0;
	padding-block: var(--wp--preset--spacing--30);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.4;
	color: var(--wp--preset--color--main);
	overflow-wrap: anywhere;
}

/* The checkout's summary rows are `tertiary` tiles (`.wc-block-checkout__sidebar
   .wc-block-components-totals-wrapper`, below); a paragraph without one would be a white gap between two of them. Same tile, same
   inset — it reads as one more row of the summary (`main` on `tertiary`, measured 13.5:1). */
.wc-block-checkout__sidebar .daylon-notice-repeat {
	padding-inline: var(--wp--preset--spacing--30);
	background: var(--wp--preset--color--tertiary);
	border-radius: 2px;
}

/* ---------------------------------------------------------------- sticky action bar */

/* New here — no existing DAY-10 implementation to reuse from (see the PR description);
   built to the spec's own description and shared class names so a future product-page
   build can adopt this file's component instead of inventing a second one. */
.daylon-sticky-bar {
	position: fixed;
	inset-inline: 0;
	bottom: var(--daylon-consent-offset, 0px);
	z-index: 30;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--30);
	/* As wide as the page, its content on the page container's edges (style.css). */
	padding: var(--wp--preset--spacing--30) var(--daylon-edge);
	/* Clear of the device's bottom edge (the home indicator), where it reports one (§4.7). */
	padding-block-end: calc(var(--wp--preset--spacing--30) + env(safe-area-inset-bottom, 0px));
	background: var(--wp--preset--color--base);
	border-block-start: 1px solid var(--wp--preset--color--border-light);
	box-shadow: 0 -2px 8px rgb(0 0 0 / 6%);
	/* Off-screen is not enough: its button would stay in the tab order, and focus would land
	   on a control nobody can see (WCAG 2.4.7, DAY-21). `visibility: hidden` takes it out of
	   the tab order and the accessibility tree; the delay lets the slide-out finish first. */
	visibility: hidden;
	transform: translateY(100%);
	transition: transform 0.2s ease, visibility 0s linear 0.2s;
}

/* WooCommerce's own mobile "Finalizar compra" bar is fixed to the bottom too. While the
   cookie banner is open it would sit underneath it (z-index 9999 vs 100000), entirely hidden
   at 320px (DAY-21, WCAG 2.4.11), so every fixed bottom bar stands on top of the banner.
   `--daylon-consent-offset` is the banner's height, set by daylon-core's consent.js and
   absent — so 0 — once she has chosen. `body .wc-block-cart` because WooCommerce's own
   `bottom: 0` outranks the bare class (verified on staging, 320px). */
body .wc-block-cart .wc-block-cart__submit-container--sticky {
	bottom: var(--daylon-consent-offset, 0px);
}

.daylon-sticky-bar.is-visible {
	visibility: visible;
	transform: translateY(0);
	transition: transform 0.2s ease;
}

@media (prefers-reduced-motion: reduce) {
	/* WooCommerce's buttons fade their box-shadow in 0.1s — and the studio's focus ring is a
	   box-shadow (style.css), so under reduced motion the ring appears at once. And its field
	   labels carry `transition: all 0.2s`, the one other effect on the path not already gated
	   (swept on staging, product → cart → checkout, DAY-21). `html body` outranks WooCommerce's
	   own (0,2,1) whatever order the stylesheets load in. */
	.daylon-sticky-bar,
	.daylon-sticky-bar.is-visible,
	html body .wc-block-components-button:not(.is-link),
	html body .wc-block-components-form .wc-block-components-text-input label,
	html body .wc-block-components-text-input label {
		transition: none;
	}
}

.daylon-sticky-bar__total {
	font-weight: 600;
}

/* The checkout's bar (§4.7, DAY-225): the button alone, as wide as the real one and in its
   column — cart-checkout.js sets both from it. The page's pay button is 38px tall; in the
   bar it takes the cart button's own 48px (WooCommerce's `min-height` on
   `.wc-block-cart__submit-button`, measured on staging), so the bar is the cart's height and
   its top edge does not move between the two pages, and the target clears 44px (§8). */
.daylon-sticky-bar--button-only {
	justify-content: flex-start;
}

.daylon-sticky-bar--button-only .wc-block-components-button {
	min-block-size: 48px;
	max-inline-size: 100%;
}

/* §6 state 29: no payment method, no bar. `display: none` rather than the hidden state
   above, so neither the tab order nor the reserved bottom band keeps a trace of it. */
.daylon-sticky-bar.is-unavailable {
	display: none;
}

/* ---------------------------------------------------------------- the pay button, §10.3 */

/* «Pagar 89,00 €» (DAY-202). WooCommerce draws the word and the price as two flex items with
   a «·» between them, 16px either side; §10.3 has a word space and no mark. The price itself
   is WooCommerce's, from the cart total (inc/checkout.php, daylon_pay_button_with_price()).
   Only the text row changes: the button's own size, colour and weight are untouched.
   Covers the sticky bar's copy of the button too — it carries the same classes. */
.wc-block-components-checkout-place-order-button .wc-block-components-checkout-place-order-button__separator {
	display: none;
}

.wc-block-components-checkout-place-order-button .wc-block-components-checkout-place-order-button__text {
	column-gap: 0.3em;
}

/* State 14 (total zero): the button is «Confirmar pedido», with no «0,00 €» after it. The
   class is on <body> — set by assets/js/pay-button.js — because React owns the button. */
.daylon-order-total-zero .wc-block-components-checkout-place-order-button__price {
	display: none;
}

@media (min-width: 1024px) {
	/* The right column is already sticky and visible; the fixed bar would double it. */
	.daylon-sticky-bar {
		display: none;
	}
}

/* ---------------------------------------------------------------- checkout, one page, §4.1 */

/* The layout is the shared two-column rule above; the sections stack in one column. */

.wc-block-checkout__form .wc-block-components-checkout-step {
	border-block-end: 1px solid var(--wp--preset--color--border-light);
	padding-block: var(--wp--preset--spacing--40);
}

.wc-block-checkout__form .wc-block-components-checkout-step:first-child {
	padding-block-start: 0;
}

.wc-block-components-checkout-step__title {
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 600;
}

/* Mobile order summary: collapsed, expandable, repeated above the pay button (§4.1). */
.wc-block-checkout__sidebar .wc-block-components-totals-wrapper {
	background: var(--wp--preset--color--tertiary);
	border-radius: 2px;
	padding: var(--wp--preset--spacing--30);
}

/* ---------------------------------------------------------------- validation, §4.3 */

.wc-block-components-text-input label,
.wc-block-components-select-input label {
	position: static;
	transform: none;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 500;
	/* Labels are always visible — never a placeholder used as a label (§4.3). Woo
	   Blocks already floats a real <label>; this only stops it collapsing onto the
	   placeholder position at rest. */
}

/* A field's edge is the only thing that says "type here": its white fill is 1.11:1 against
   the page. Ollie's woocommerce.css draws that edge as tertiary + 40% main, measured on
   staging at 2.01:1 against the page and 2.22:1 against the fill; the terms checkbox, 48%
   currentColor, at 2.77:1 — all under the 3:1 WCAG 2.2 AA asks of a control's boundary
   (1.4.11, DAY-21). The palette's own `border` token is 3.42:1 / 3.79:1. `html body` and
   `.wc-block-components-form` lift these past Ollie's (0,3,1); an invalid field keeps its
   error colour. */
html body .wc-block-components-form .wc-block-components-text-input :is(input, textarea):not([aria-invalid="true"]),
html body .wc-block-components-form .wc-blocks-components-select__select:not([aria-invalid="true"]),
html body .wc-block-components-form .wc-block-components-textarea:not([aria-invalid="true"]),
html body .wc-block-components-checkbox .wc-block-components-checkbox__input[type="checkbox"]:not([aria-invalid="true"]),
html body .wc-block-components-totals-coupon .wc-block-components-text-input input:not([aria-invalid="true"]) {
	border-color: var(--wp--preset--color--border);
}

/* And an invalid one: WooCommerce sets `aria-invalid`, but its red border loses to the same
   Ollie rule, so on staging an invalid field kept the 2.01:1 edge. The message beneath it is
   the signal (text, role="alert"); this edge only makes the field findable (6.80:1). */
html body .wc-block-components-form .wc-block-components-text-input :is(input, textarea)[aria-invalid="true"],
html body .wc-block-components-form .wc-blocks-components-select__select[aria-invalid="true"],
html body .wc-block-components-form .wc-block-components-textarea[aria-invalid="true"],
html body .wc-block-components-checkbox .wc-block-components-checkbox__input[type="checkbox"][aria-invalid="true"] {
	border-color: var(--daylon-error);
}

.wc-block-components-validation-error {
	color: var(--daylon-error);
	font-size: var(--wp--preset--font-size--small);
	margin-block-start: var(--wp--preset--spacing--10, 0.25rem);
}

/* The error summary pattern — built by cart-checkout.js, listing every invalid field
   as a link (§4.3, §6 state 6, §8). New component; §9. */
.daylon-error-summary {
	border: 1px solid var(--daylon-error);
	background: var(--daylon-error-bg);
	border-radius: 2px;
	padding: var(--wp--preset--spacing--30);
	margin-block-end: var(--wp--preset--spacing--30);
}

.daylon-error-summary__title {
	font-weight: 600;
	color: var(--daylon-error);
	margin: 0 0 var(--wp--preset--spacing--10, 0.25rem);
}

.daylon-error-summary__list {
	margin: 0;
	padding-inline-start: 1.25em;
}

.daylon-error-summary__list a {
	color: var(--daylon-error);
}

/* ---------------------------------------------------------------- shipping area, §4.4 */

/* España, fixed and labelled — never an interactive selector with one option, never a
   disabled control, and never a focus stop (§4.4, §8).

   ⚠️ Until DAY-185 this section styled `.wc-block-components-country-input` small and
   secondary, on the belief — stated in daylon-core and repeated here — that restricting
   `woocommerce_countries` to ES made Woo Blocks draw the field as text. It does not:
   measured on staging (WC 11.1.0) it is a real <select> with a placeholder and one option,
   so that rule was quietly making a live control look like a caption. It is gone, and
   #billing's country select now looks like every other select in the form.

   The shipping country is replaced instead: cart-checkout.js adds the <p> below and marks
   the field it stands for, which this rule takes off the page — out of the tab order and
   out of the accessibility tree, with its value still travelling to the server.
   ⛔ Scoped to #shipping. A billing address may be outside the delivery area (§4.4), so
   billing keeps its own control. */
#shipping .wc-block-components-address-form__country.daylon-field-replaced {
	display: none;
}

/* DAY-186: the billing telephone, off the page. §4.1 puts the telephone in the shipping
   address and describes no billing one, but WooCommerce's telephone setting is not per-group,
   so unticking «Usar la misma dirección para facturación» drew a second required «Teléfono»
   and the buyer had to type her number twice to pay. Paula decided it is not drawn at all
   (2026-09-20).

   Hidden rather than removed, for the reason the rule above states: Woo Blocks owns these
   nodes and puts back what is taken out of the DOM. `display: none` is the buyer's side of
   «not drawn» — off the page, out of the tab order, out of the accessibility tree. The half
   this rule cannot do is in cart-checkout.js, which also takes `required` off the input, and
   in daylon-core's billing-phone.php, which stops the server asking for it.
   ⛔ Scoped to #billing, and the class is only added while a shipping telephone exists: on a
   virtual-only cart billing's is the only telephone and it stays. */
#billing .wc-block-components-address-form__phone.daylon-field-removed {
	display: none;
}

/* The fixed value in its place. `flex: 0 0 100%` is the address form's own full-width
   basis — Woo lays that form out with flex, and the country field it replaces measured
   exactly this — so it holds the row the field held instead of sharing one with «Nombre».
   `line-height` is stated for the same reason it is stated under `.daylon-field-error`
   below: this <p> lives inside Woo's own address form, where a `line-height: 0` set for
   a floated label is one inheritance away, and a box 0px high paints its text over
   whatever follows instead of pushing it down (DAY-153, DAY-173). Measured 1.4 here. */
.daylon-fixed-value {
	flex: 0 0 100%;
	margin: 0;
	line-height: 1.4;
}

.daylon-fixed-value__label {
	display: block;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--secondary);
}

.daylon-fixed-value__value {
	display: block;
	color: var(--wp--preset--color--main);
}

/* The restriction line. Two nodes carry the same sentence and only one is ever visible:
   the server-rendered <p> (daylon-core, above the section's heading — the copy a session
   without this theme's script still reads) and the shipping-address block's own
   `description`, which Woo Blocks renders between the <h2> and the first field, where
   §4.4 puts it. cart-checkout.js adds `is-superseded` to the first once it has seen the
   second carrying the same words; if that never happens, the first one stays. */
.daylon-shipping-area-note,
#shipping-fields .wc-block-components-checkout-step__description {
	margin-block-end: var(--wp--preset--spacing--30);
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--main);
}

.daylon-shipping-area-note.is-superseded {
	display: none;
}

/* The chosen province was cut along the bottom (DAY-323). Ollie's woocommerce.css gives the
   select `padding-top: 24px` for the label inside it and a 3.4em height, and the 25 px line
   it inherits does not fit in what is left: measured on staging, a 16 px box for a 25 px
   line. The line and the padding are stated so the value, descenders included, fits under
   the label; the field's height does not change. `html body` for the reason given under
   «validation». */
html body .wc-blocks-components-select .wc-blocks-components-select__select {
	padding-block: 22px 4px;
	line-height: 1.4;
}

/* State 17 — the province field's own inline error, not a page-level banner (§6, §8).
   Set directly by cart-checkout.js via `aria-invalid`/`daylon-field-error`, not Woo
   Blocks' own `has-error` class — DAY-19 comment 10721: dispatching into
   `wc/store/validation` with an assumed field id fed a checkout re-render loop, so
   the association is now plain DOM/ARIA instead. */
.wc-block-components-address-form select[aria-invalid="true"] {
	border-color: var(--daylon-error);
}

.daylon-field-error {
	color: var(--daylon-error);
	font-size: var(--wp--preset--font-size--small);
	margin-block-start: var(--wp--preset--spacing--10, 0.25rem);
}

/* ⚠️ `line-height` is load-bearing here, not taste, and it is stated once for every
   sentence cart-checkout.js inserts INSIDE one of Woo Blocks' field wrappers.
   WooCommerce Blocks' own packages-style.css sets `line-height: 0` on
   `.wc-block-components-text-input` (to close the inline gap around its floated label)
   and a <p> inserted in that wrapper inherits it: the text still paints, but its box is
   0px high, so it overlaps whatever follows instead of pushing it down. Measured on
   staging twice — the phone hint at 768 (DAY-153) and the province error at every width
   (DAY-173) — which is why this is one rule and not a patch per class.

   Our own markup is not affected: `.daylon-field-error` in account.css sits in the
   theme's own account templates, outside any Woo wrapper, and keeps its own rule. */
.daylon-field-error,
.daylon-field-hint {
	line-height: 1.4;
}

/* State 17 — «payment stays unavailable» (DAY-206). The pay button is marked
   `aria-disabled` by cart-checkout.js, not `disabled`: it stays focusable so a press can
   say why and move focus to the province (§6 state 17, «On submit»). The look is
   WooCommerce's own for a disabled button (`:disabled .wc-block-components-button__text`
   at half opacity, packages-style.css, WC 11.1) — the treatment §6 state 9 already calls
   «Pagar disabled», not a new one. Covers the sticky bar's copy, which carries the same
   classes. */
.wc-block-components-checkout-place-order-button[aria-disabled="true"] {
	cursor: not-allowed;
}

.wc-block-components-checkout-place-order-button[aria-disabled="true"] .wc-block-components-button__text {
	opacity: 0.5;
}

/* ------------------------------------------------- delivery options, each its own card */

/* DAY-323. WooCommerce draws the rates as one outlined box with a hairline between rows, and
   the selected row's own 2 px edge then sits flush against its neighbour. Each option carries
   its own edge instead, with air between them; the group's outline and the hairlines go.
   The margin is on an option that follows anything — another option, or the acceptance box
   cart-checkout.js puts under one (below) — so that box stays with the option it belongs to.
   ⛔ Scoped to #shipping-option: the payment methods use the accordion variant of this
   control and are not touched. */
#shipping-option .wc-block-components-radio-control--highlight-checked::after,
#shipping-option .wc-block-components-radio-control--highlight-checked .wc-block-components-radio-control__option::after {
	display: none;
}

#shipping-option .wc-block-components-radio-control__option {
	border-radius: 5px;
}

#shipping-option .wc-block-components-radio-control__option:not(.wc-block-components-radio-control__option--checked-option-highlighted) {
	box-shadow: inset 0 0 0 1px var(--wp--preset--color--border);
}

#shipping-option .wc-block-components-radio-control > * + .wc-block-components-radio-control__option {
	margin-block-start: var(--wp--preset--spacing--40);
}

/* ------------------------------------------------- a delivery option that asks for an acceptance */

/* DAY-354. A required box that cart-checkout.js draws directly under one delivery option
   while it is the selected one, for the buyer the server sends that option to. WooCommerce's
   own checkbox markup, so the control, its edge and its error are the Terms box's (above);
   what is added here is its place and its size.

   It is the one thing on this screen the shop asks of her that is not money, so it is not
   quiet: a `tertiary` tile at body size, `main` on it (13.5:1). No badge and no colour on the
   option's own row — that one stays a row like the others. */
.daylon-option-acceptance {
	margin-block-start: var(--wp--preset--spacing--20, 0.5rem);
	padding: var(--wp--preset--spacing--20, 0.5rem) var(--wp--preset--spacing--30);
	background: var(--wp--preset--color--tertiary);
	border-radius: 2px;
}

/* The label is part of the target, and the target is at least 44 px tall whatever the
   sentence's length (WCAG 2.5.8 asks 24; the spec asks 44). The Terms box's label is the
   height of its line, 20 px on staging; this one is not left to that. The sentence wraps
   inside the tile at 320 px and never scrolls sideways. */
.daylon-option-acceptance .wc-block-components-checkbox {
	margin: 0;
}

.daylon-option-acceptance .wc-block-components-checkbox label {
	display: flex;
	align-items: flex-start;
	min-height: 44px;
	padding-block: var(--wp--preset--spacing--20, 0.5rem);
	box-sizing: border-box;
	cursor: pointer;
}

.daylon-option-acceptance .wc-block-components-checkbox__label {
	min-width: 0;
	line-height: 1.4;
	overflow-wrap: anywhere;
}

/* A box reached by Tab while its message shows: the page's `scroll-padding-bottom`
   (style.css) clears everything fixed at the bottom for the control, and this adds the room
   the message under it takes — three lines of it at 320 px. The top is style.css's
   `scroll-padding-top` (DAY-361). Focus sent there by an unticked pay is another matter:
   WooCommerce centres it, and cart-checkout.js (`settleAcceptanceInView`) puts it right. */
.daylon-option-acceptance .wc-block-components-checkbox__input {
	scroll-margin-bottom: 5rem;
}

/* WooCommerce sets these wrappers to `line-height: 0` and its paragraph to 1; three wrapped
   lines of a message need air between them. */
.daylon-option-acceptance .wc-block-components-validation-error,
.daylon-option-acceptance .wc-block-components-validation-error p {
	line-height: 1.4;
}

/* The summary's sentence about that option, under the delivery row and above the total.
   Quiet, ordinary text — the same tile and inset as the rows around it in the checkout
   (see `.daylon-notice-repeat`), no icon, no link, no button.
   The checkout's coupon line (§4.5, DAY-560) sits in the same slot and reads the same way:
   no colour, icon or weight of its own. */
.daylon-summary-note,
.daylon-delivery-lost {
	margin: 0;
	padding-block: var(--wp--preset--spacing--30);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.4;
	color: var(--wp--preset--color--main);
	overflow-wrap: anywhere;
}

/* Below 768 px the summary above «Pagar» is not in the sidebar, and its rows carry
   WooCommerce's own 16px inset (`.wc-block-components-totals-item`): measured on staging at
   320 px, the line and the sentence started 16px left of «Envío» (DAY-560, DAY-561). Same
   inset, so they read as rows. Three lines at 320 px with it (§10.9). The sidebar rule below
   wins where it applies. Not the cart's summary: its rows have no inset, and the sentence
   already lines up with them there. */
.wp-block-woocommerce-checkout-order-summary-block .daylon-summary-note,
.wp-block-woocommerce-checkout-order-summary-block .daylon-delivery-lost {
	padding-inline: 16px;
}

.wc-block-checkout__sidebar .daylon-summary-note,
.wc-block-checkout__sidebar .daylon-delivery-lost {
	padding-inline: var(--wp--preset--spacing--30);
	background: var(--wp--preset--color--tertiary);
	border-radius: 2px;
}

/* ------------------------------------------------- the telephone's helper text, §4.1 / §10.3 */

/* Added under the field by cart-checkout.js and tied to it with `aria-describedby` (DAY-153).
   Quieter than the field's own error, which has to stay the loudest thing under it: this is
   `secondary`, 5.24:1 on the page's ground — above the 4.5:1 WCAG 2.2 AA asks of body text —
   and the same token the fixed country line above already uses. Never red, and never a
   substitute for an error message.

   Its `line-height` — load-bearing against Woo's `line-height: 0`, not taste — is stated in
   the shared rule above, beside `.daylon-field-error`. */
.daylon-field-hint {
	color: var(--wp--preset--color--secondary);
	font-size: var(--wp--preset--font-size--small);
	margin-block: var(--wp--preset--spacing--10, 0.25rem) 0;
}

@media (min-width: 1024px) {
	/* The restriction line spans the address section above the fields; it must never
	   share a row with a field or drift into the order summary column (§4.4).
	   The line a browser with JavaScript reads is now the block's own `description`,
	   which sits in the step's heading container — a block-level box outside the
	   field layout, so it spans by construction and needs no rule. This one still
	   covers the server-rendered <p> that a session without the script reads. */
	.daylon-shipping-area-note {
		grid-column: 1 / -1;
	}
}

/* ---------------------------------------------------------------- empty cart, §6 state 1 */

/* One line and the shop as the primary action, above the fold at 320. */
.daylon-cart-empty {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--wp--preset--spacing--30);
	padding-block: var(--wp--preset--spacing--40);
}

.daylon-cart-empty__line {
	margin: 0;
	font-size: var(--wp--preset--font-size--medium);
}

/* Seguir comprando — a text link under Finalizar compra (§3.1 item 7), and the last item of
   the order-received page (§5 item 6). */
.daylon-continue-shopping {
	margin-block: var(--wp--preset--spacing--30) 0;
	text-align: center;
}

.daylon-order-received .daylon-continue-shopping {
	text-align: start;
}

.daylon-continue-shopping a {
	display: inline-block;
	padding-block: 0.625rem;
	color: var(--wp--preset--color--main);
}

.daylon-continue-shopping a:focus-visible,
.daylon-cart-empty a:focus-visible {
	outline: 3px solid var(--wp--preset--color--primary);
	outline-offset: 2px;
}

/* ---------------------------------------------------------------- order received, §5 */

.daylon-order-confirmation-notes {
	margin-block-start: var(--wp--preset--spacing--40);
	padding-block-start: var(--wp--preset--spacing--40);
	border-block-start: 1px solid var(--wp--preset--color--border-light);
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--main);
}

.daylon-order-confirmation-notes p {
	margin: 0 0 var(--wp--preset--spacing--20, 0.5rem);
}

.daylon-order-confirmation-notes p:last-child {
	margin-block-end: 0;
}

/* ---------------------------------------------------------------- the account offer, DAY-380
   "Account creation after payment and its confirmation" spec v2 §2. The card is the cream
   card of My account → Registrarse — the same surface, radius and padding, which there come
   from Ollie's and WooCommerce's rules for `form.register` and here are stated, because
   neither stylesheet reaches this block. The form inside it is ours (inc/account-offer.php).

   WooCommerce's own rules for the block are undone only where they show: its grey ground,
   and the row it lays the sentence and the form out in. Its vertical margins are left alone.

   Breakpoints: 640 and 1024 — the page container's (§2.6), not this file's older set. */

.daylon-order-received .wc-block-order-confirmation-create-account {
	display: block;
	padding: var(--wp--preset--spacing--medium);
	border-radius: 5px;
	background: var(--wp--preset--color--tertiary);
	color: var(--wp--preset--color--main);
}

@media (min-width: 640px) {
	/* Never stretched to the container: a postscript under the order, on its left edge. */
	.daylon-order-received .wc-block-order-confirmation-create-account {
		max-width: 480px;
		margin-inline: 0 auto;
	}
}

.daylon-account-offer {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--40);
	margin-block-start: var(--wp--preset--spacing--40);
}

/* `hidden` loses to any `display` set below; these three are shown and hidden by it. */
.daylon-account-offer [hidden] {
	display: none;
}

.daylon-account-offer p {
	margin: 0;
}

/* A long address breaks anywhere rather than widening the card at 320 (§2.5 state 13). */
.daylon-account-offer__email {
	overflow-wrap: anywhere;
}

.daylon-account-offer__address {
	font-weight: 600;
}

.daylon-account-offer__alert {
	padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--40);
	border: 1px solid var(--daylon-error);
	border-radius: 2px;
	background: var(--daylon-error-bg);
	color: var(--daylon-error);
	line-height: 1.4;
}

.daylon-account-offer__alert a {
	display: inline-block;
	padding-block: 0.75rem;
	margin-block: -0.75rem;
	color: inherit;
}

.daylon-account-offer__field {
	display: flex;
	flex-direction: column;
}

.daylon-account-offer__field label {
	margin-block-end: var(--wp--preset--spacing--20);
	font-weight: 500;
}

.daylon-account-offer__input {
	position: relative;
	display: block;
}

/* 1rem, not the group's small size: under 16px iOS zooms the page when the field is focused.
   The form's class is repeated because Ollie sizes every text input with two classes. */
.daylon-account-offer .daylon-account-offer__input input {
	box-sizing: border-box;
	width: 100%;
	min-height: 48px;
	padding: 0.75rem 3rem 0.75rem 1rem;
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 4px;
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--main);
	font: inherit;
	font-size: 1rem;
	line-height: 1.4;
}

.daylon-account-offer .daylon-account-offer__field--invalid input {
	border-color: var(--daylon-error);
	box-shadow: inset 0 0 0 1px var(--daylon-error);
}

/* 44 × 44 inside the field's right edge, centred on its height. */
.daylon-account-offer__toggle {
	position: absolute;
	inset-block-start: 50%;
	inset-inline-end: 2px;
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 0;
	border-radius: 4px;
	background: none;
	color: var(--wp--preset--color--main);
	cursor: pointer;
	transform: translateY(-50%);
}

/* Struck through while the password is readable, as WooCommerce's own toggle is. */
.daylon-account-offer__toggle-slash {
	display: none;
}

.daylon-account-offer__toggle.is-shown .daylon-account-offer__toggle-slash {
	display: inline;
}

/* Three segments and a word: the word says the level, the colour only repeats it (D5). The
   word sits to the right of the bar and drops under it when the card is too narrow. */
.daylon-account-offer__strength {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--wp--preset--spacing--20) var(--wp--preset--spacing--30);
	margin-block-start: var(--wp--preset--spacing--20);
}

.daylon-account-offer__bar {
	display: grid;
	flex: 1 1 10rem;
	grid-template-columns: repeat(3, 1fr);
	gap: 4px;
}

.daylon-account-offer__bar span {
	height: 6px;
	border-radius: 3px;
	background: var(--wp--preset--color--border-light);
}

.daylon-account-offer__strength[data-level="1"] .daylon-account-offer__bar span:first-child {
	background: var(--wp--preset--color--error);
}

.daylon-account-offer__strength[data-level="2"] .daylon-account-offer__bar span:nth-child(-n+2) {
	background: var(--wp--preset--color--warning);
}

.daylon-account-offer__strength[data-level="3"] .daylon-account-offer__bar span {
	background: var(--wp--preset--color--success);
}

.daylon-account-offer__word {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	line-height: 1.4;
}

.daylon-account-offer__word:empty {
	display: none;
}

.daylon-account-offer__strength[data-level="1"] .daylon-account-offer__word {
	color: var(--wp--preset--color--error);
}

.daylon-account-offer__strength[data-level="2"] .daylon-account-offer__word {
	color: var(--wp--preset--color--warning);
}

.daylon-account-offer__strength[data-level="3"] .daylon-account-offer__word {
	color: var(--wp--preset--color--success);
}

.daylon-account-offer__hint {
	margin-block-start: var(--wp--preset--spacing--20);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.4;
}

.daylon-account-offer__hint--error {
	color: var(--daylon-error);
}

/* daylon-core's privacy checkbox, laid out for a thumb. Every line of the label is 44px
   high: the row is a 44px target, the box sits in its left padding so the sentence wraps as
   one paragraph, and the policy link is a 44px target that never reaches over the words
   beside or above it — tapping those ticks the box, and only the link opens the policy
   (§2.7; a link padded out to 44px with a negative margin covered the line above it, which is
   DAY-319 F-22 again). */
.daylon-account-offer .daylon-privacy-consent label {
	position: relative;
	display: block;
	padding-inline-start: 2.25rem;
	cursor: pointer;
	line-height: 2.75rem;
}

.daylon-account-offer .daylon-privacy-consent input[type="checkbox"] {
	position: absolute;
	inset-block-start: 0.625rem;
	inset-inline-start: 0;
	width: 1.5rem;
	height: 1.5rem;
	margin: 0;
	accent-color: var(--wp--preset--color--primary);
}

.daylon-account-offer .daylon-privacy-consent a {
	display: inline-block;
}

.daylon-account-offer .daylon-privacy-consent .daylon-field-error {
	display: block;
	margin-block-start: 0;
	padding-inline-start: 2.25rem;
}

/* Full card width on a phone; its own width, never under 200px, from 640 (§2.3). */
.daylon-account-offer__submit {
	width: 100%;
	min-height: 48px;
	border: 0;
	cursor: pointer;
}

.daylon-account-offer__submit[aria-disabled="true"] {
	opacity: 0.7;
	cursor: progress;
}

@media (min-width: 640px) {
	.daylon-account-offer__submit {
		align-self: flex-start;
		width: auto;
		min-width: 200px;
	}
}

/* ---------------------------------------------------------------- responsive sweep */

/* Ten items in the cart (state 16): the list scrolls normally, no cap, no internal
   scroll container — nothing here constrains .wc-block-cart-items height. */
