/*!
 * OnePageCheckout for WooCommerce — base stylesheet (the "naked" look).
 * Fully driven by --opcw-* custom properties: a theme skins the checkout by
 * overriding variables (plus, rarely, a few component rules) in ONE file.
 * No site-specific values live in here.
 */

/*
 * WordPress' standard screen-reader-only class. The takeover page drops the
 * theme stylesheet (dequeue_theme_css), which is where this rule normally
 * lives — without it a theme's skip link and WooCommerce's own "Required"
 * labels become visible. Same values as wp-admin / core themes.
 */
.screen-reader-text {
	border: 0;
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute !important;
	width: 1px;
	word-wrap: normal !important;
}
.screen-reader-text:focus {
	background: var(--opcw-surface, #fff);
	clip-path: none;
	color: var(--opcw-ink, #17181a);
	display: block;
	font-size: 1em;
	height: auto;
	left: 5px;
	line-height: normal;
	padding: 15px 23px 14px;
	text-decoration: none;
	top: 5px;
	width: auto;
	z-index: 100000;
}

:root {
	/* palette */
	--opcw-bg: #ffffff;
	--opcw-bg-summary: #f5f5f6;
	--opcw-surface: #ffffff;
	--opcw-ink: #17181a;
	--opcw-text: #3d4045;
	--opcw-muted: #6b6f75; /* 5.0:1 on --opcw-bg, 4.6:1 on --opcw-bg-summary (#74787e was 4.4 / 4.1) */
	--opcw-faint: #6b7078; /* 5.0:1 on --opcw-bg, 4.6:1 on --opcw-bg-summary (#a3a7ad was 2.4 / 2.2) */
	--opcw-line: #dfe1e5;
	--opcw-line-strong: #17181a;
	--opcw-primary: #17181a;
	--opcw-primary-ink: #ffffff;
	--opcw-accent: #17181a;
	--opcw-success: #177a42; /* 5.4:1 on --opcw-bg, 4.9:1 on --opcw-bg-summary (#1f9d55 was 3.5 / 3.2) */
	--opcw-error: #c93b3b; /* 5.0:1 on --opcw-bg, 4.6:1 on --opcw-bg-summary (#d64545 was 4.4 / 4.0) */

	/* shape + type */
	--opcw-radius: 10px;
	--opcw-radius-sm: 8px;
	--opcw-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	--opcw-font-display: var(--opcw-font);
	--opcw-font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
	--opcw-fw-display: 700;
	--opcw-tt-btn: none;
	--opcw-ls-btn: .01em;

	/* rhythm */
	--opcw-field-h: 54px;
	--opcw-gap: 8px;
	--opcw-section-gap: 34px;
	--opcw-shadow: 0 1px 2px rgba(20, 22, 26, .05);
	--opcw-focus: 0 0 0 1.5px var(--opcw-accent);
}

/* ---------- base ---------- */
body.opcw { margin: 0; padding: 0; box-sizing: border-box;
	font-family: var(--opcw-font); color: var(--opcw-text); background: var(--opcw-bg);
	line-height: 1.5; font-size: 14px; -webkit-font-smoothing: antialiased; min-height: 100vh; }
.opcw *, .opcw *::before, .opcw *::after { box-sizing: border-box; }
.opcw [hidden] { display: none !important; }
.opcw a { color: var(--opcw-ink); text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
.opcw a:hover { text-decoration-thickness: 2px; }
.opcw button { font: inherit; cursor: pointer; }
.opcw img { max-width: 100%; height: auto; }
.opcw p { margin: 0; }
.opcw :where(a, button, input, select, textarea):focus-visible { outline: 2px solid var(--opcw-accent); outline-offset: 1px; }

/* ---------- shell header ---------- */
.opcw-header { border-bottom: 1px solid var(--opcw-line); background: var(--opcw-bg); position: relative; z-index: 5; }
.opcw-header__in { max-width: 1120px; margin: 0 auto; padding: 0 24px; height: 64px;
	display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.opcw-logo { font-family: var(--opcw-font-display); font-weight: var(--opcw-fw-display); font-size: 20px;
	letter-spacing: -.02em; color: var(--opcw-ink); text-decoration: none; display: inline-flex; align-items: center; gap: 10px; }
.opcw-logo .opcw-logo__img { max-height: 40px; width: auto; }
.opcw-header__secure { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--opcw-muted); white-space: nowrap; }
.opcw-header__usps { display: flex; gap: 18px; list-style: none; margin: 0; padding: 0; }
.opcw-header__usps li { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--opcw-muted); white-space: nowrap; }
/* Below 900px the USPs hide, except the first rows marked for phones
   (header_usps_mobile: li.is-m in ul.opcw-header__usps--m1 / --m2) — those and
   the rating form a compact strip under the 64px logo row. The logo row never
   wraps: the lead takes the free space (flex-basis 0) and shrinks first. */
@media (max-width: 899px) {
	.opcw-header__usps { display: none; }
	.opcw-header__in { flex-wrap: wrap; height: auto; min-height: 64px; row-gap: 0; }
	.opcw-header__lead { flex: 1 1 0%; min-height: 64px; }
	.opcw-header__usps.opcw-header__usps--m1,
	.opcw-header__usps.opcw-header__usps--m2 { display: flex; flex-basis: 100%; flex-wrap: wrap; gap: 4px 16px; margin: -8px 0 0; padding: 0 0 11px; }
	.opcw-header__usps--m1 > li:not(.is-m),
	.opcw-header__usps--m2 > li:not(.is-m) { display: none; }
	.opcw-header__usps--m1 > li,
	.opcw-header__usps--m2 > li { white-space: normal; min-width: 0; }
}
/* back-to-shop arrow (opt-in) — sits with the logo; content aligns to its left edge */
.opcw-header__lead { display: inline-flex; align-items: center; gap: 14px; min-width: 0; }
.opcw-back { display: inline-flex; align-items: center; gap: 7px; height: 36px; padding: 0 13px 0 10px;
	border: 1px solid var(--opcw-line); border-radius: var(--opcw-radius-sm); background: var(--opcw-surface);
	color: var(--opcw-muted); text-decoration: none; font-size: 13px; font-weight: 500; white-space: nowrap; flex: none;
	transition: color .15s, border-color .15s; }
.opcw-back:hover { color: var(--opcw-ink); border-color: var(--opcw-line-strong); text-decoration: none; }
/* Link-shaped controls stay plain: .opcw a (0,1,1) underlines links and outranked their
   own text-decoration: none (0,1,0): the boxed back link, the text logo, the secondary button. */
.opcw .opcw-back, .opcw .opcw-back:hover, .opcw .opcw-logo, .opcw .opcw-btn-secondary { text-decoration: none; }
.opcw-back svg { flex: none; }
@media (max-width: 599px) { .opcw-back__label { display: none; } .opcw-back { width: 36px; padding: 0; justify-content: center; } .opcw-header__lead { gap: 10px; } }

/* ---------- split layout ---------- */
.opcw-shell { background: var(--opcw-bg); overflow-x: clip; }
.opcw-layout { max-width: 1120px; margin: 0 auto; display: grid; grid-template-columns: minmax(0, 1fr) 460px; align-items: stretch; }
.opcw-layout--single { grid-template-columns: minmax(0, 1fr); }
.opcw-main { padding-block: 36px 64px; padding-inline: 24px 40px; max-width: 700px; width: 100%; justify-self: start; }
/* start edge aligns with the header logo (container + 24px); the 40px end
   padding mirrors the summary's 40px start inset so the divider sits centered
   in an even trough. Logical properties throughout: on a right-to-left site
   the whole split mirrors (the summary column on the left), and the pro
   "Order summary side: Left" (OPCW_Design::token_css()) mirrors it within
   the reading direction. */
.opcw-layout--single .opcw-main { justify-self: center; }
.opcw-summary { position: relative; background: var(--opcw-bg-summary); border-inline-start: 1px solid var(--opcw-line); padding-block: 36px 64px; padding-inline: 40px 24px; }
/* The summary background bleeds to the viewport edge beyond the column's end. */
.opcw-summary::after { content: ""; position: absolute; top: 0; bottom: 0; inset-inline-start: 100%; width: 50vw; background: var(--opcw-bg-summary); }
.opcw-summary__sticky { position: sticky; top: 24px; }
/* Without the height-aware summary (opcw_summary_fit false; body without
   opcw--summary-fit) a column taller than the viewport scrolls inside, as in
   4.4. The 4px padding, offset by the negative margin and the 4px smaller
   `top`, keeps focus rings unclipped and the content exactly where it was.
   With it (the default), summary-fit.js keeps the column inside the viewport
   instead and the column never scrolls (states: "height-aware summary"). */
@media (min-width: 1000px) {
	body:not(.opcw--summary-fit) .opcw-summary__sticky { top: 20px; max-height: calc(100vh - 40px); overflow-y: auto; padding: 4px; margin: -4px; }
}
/* "Sticky order summary" off: OPCW_Design::body_class() adds the class on
   every takeover page (classic, Block Mode, thank-you). */
body.opcw--summary-static .opcw-summary__sticky { position: static; max-height: none; overflow: visible; padding: 0; margin: 0; }

/* ---------- sections ---------- */
.opcw-section { margin-bottom: var(--opcw-section-gap); }
.opcw-section__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.opcw-kicker { display: block; font-family: var(--opcw-font-mono); font-size: 11px; letter-spacing: .12em;
	text-transform: uppercase; color: var(--opcw-faint); margin-bottom: 4px; }
/* Heading tokens (unset by default; the fallbacks are the designed values):
   --opcw-fs-h2, --opcw-fs-sum-title, --opcw-fs-perks-title, --opcw-fs-h1 and
   --opcw-fw-heading (falls back to --opcw-fw-display). Declared at the use
   site, not in :root, so a skin that sets --opcw-fw-display on body.opcw
   still reaches the headings. */
.opcw-h2 { font-family: var(--opcw-font-display); font-weight: var(--opcw-fw-heading, var(--opcw-fw-display)); font-size: var(--opcw-fs-h2, 19px);
	letter-spacing: -.01em; color: var(--opcw-ink); line-height: 1.2; margin: 0; }
.opcw-section__aside { font-size: 13px; white-space: nowrap; }
.opcw-secure-hint { display: inline-flex; align-items: center; gap: 6px; color: var(--opcw-muted); font-size: 12px; }
.opcw-muted { color: var(--opcw-muted); }

/* ---------- extension section slots (opcw_before_section / opcw_after_section) ---------- */
.opcw-slot { margin: 0 0 var(--opcw-section-gap); }
.opcw-slot--header-before, .opcw-slot--header-after { margin: 0; }
.opcw-summary__sticky > .opcw-slot--summary-before { margin-bottom: 18px; }
.opcw-summary__sticky > .opcw-slot--summary-after { margin: 18px 0 0; }
/* Inside a section, between its head and its content (opcw_section_after_head, 4.4). */
.opcw-slot--after-head { margin: 0 0 14px; }

/* ---------- express slot ---------- */
.opcw-express { margin-bottom: 28px; }
.opcw-express__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: var(--opcw-gap); }
.opcw-express__grid > * { height: 48px; }
.opcw-divider { display: flex; align-items: center; gap: 14px; margin: 22px 0 0; color: var(--opcw-faint);
	font-size: 12px; text-transform: uppercase; letter-spacing: .08em; }
.opcw-divider::before, .opcw-divider::after { content: ""; flex: 1; height: 1px; background: var(--opcw-line); }

/* ---------- rows + floating-label fields ---------- */
.opcw-row { display: grid; gap: var(--opcw-gap); margin-bottom: var(--opcw-gap); }
.opcw-row--2 { grid-template-columns: 1fr 1fr; }
.opcw-row--plz { grid-template-columns: minmax(110px, .8fr) 1.6fr; }
@media (max-width: 480px) { .opcw-row--2 { grid-template-columns: 1fr; } }

.opcw p.form-row { margin: 0 0 var(--opcw-gap); }
.opcw .opcw-row > p.form-row { margin: 0; }
.opcw-field { position: relative; }

/*
 * Field geometry (54px box, floating label):
 *   floated label   top 8px / 10.5px  → occupies 8–21px
 *   input value     pad-top 24px, 15px/22.5px line → 24–46.5px (center ≈ 35)
 *   select value    pad-top 18px, browser centers in the content box (≈ 36)
 * Selectors are DEPTH-AGNOSTIC (no child combinator): wc-country-select swaps
 * the state control in place and third parties may wrap controls.
 */
.opcw-field .opcw-input,
.opcw-field input.input-text,
.opcw-field select {
	width: 100%; height: var(--opcw-field-h); padding: 24px 14px 5px;
	border: 1px solid var(--opcw-line); border-radius: var(--opcw-radius-sm);
	background: var(--opcw-surface); color: var(--opcw-ink);
	font: inherit; font-size: 15px; line-height: 1.5; outline: none; appearance: none; -webkit-appearance: none;
	transition: border-color .12s, box-shadow .12s; box-shadow: var(--opcw-shadow); margin: 0;
}
.opcw-field select {
	padding: 18px 36px 0 14px;
	background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="%2374787e" stroke-width="2" stroke-linecap="round"><polyline points="6 9 12 15 18 9"/></svg>');
	background-repeat: no-repeat; background-position: right 14px center;
}
.opcw-field .opcw-textarea { height: auto; min-height: 96px; padding-top: 26px; resize: vertical; line-height: 1.5; }
.opcw-field__lbl {
	position: absolute; inset-inline-start: 15px; top: 50%; transform: translateY(-50%);
	font-size: 15px; color: var(--opcw-muted); pointer-events: none;
	transition: all .12s ease; max-width: calc(100% - 30px); white-space: nowrap; overflow: hidden; margin: 0;
}
/* An unfloated label is centred on the INPUT, not on the row: anything printed into the
   row under the control (our inline error and helper line, WooCommerce's inline error,
   a third-party notice such as Cart Abandonment Recovery's GDPR text) makes the row
   taller (placed before the floated rules so those still win). A textarea keeps the
   label centred on its own box; the 46px coupon field gets its own height. */
.opcw-field__lbl { top: calc(var(--opcw-field-h) / 2); }
.opcw-field:has(> .opcw-textarea) .opcw-field__lbl { top: 50%; }
.opcw-coupon .opcw-field { --opcw-field-h: 46px; }
.opcw .opcw-field__error { display: block; margin: 5px 2px 0; font-size: 12.5px; line-height: 1.4; color: var(--opcw-error); }
/* floated state — :has() (modern) + .is-float / JS fallback classes; selects
   and static fields float permanently */
.opcw-field:has(.opcw-input:focus) .opcw-field__lbl,
.opcw-field:has(.opcw-input:not(:placeholder-shown)) .opcw-field__lbl,
.opcw-field:has(.opcw-input:-webkit-autofill) .opcw-field__lbl,
.opcw-field:has(input.input-text:focus) .opcw-field__lbl,
.opcw-field:has(input.input-text:not(:placeholder-shown)) .opcw-field__lbl,
.opcw-field:has(select) .opcw-field__lbl,
.opcw-field:has(.opcw-field__static) .opcw-field__lbl,
.opcw-field .opcw-field__lbl.is-float,
.opcw-field.has-value .opcw-field__lbl,
.opcw-field.is-focused .opcw-field__lbl {
	top: 8px; transform: none; font-size: 10.5px; letter-spacing: .01em;
}
.opcw-field .opcw-input:focus,
.opcw-field input.input-text:focus,
.opcw-field select:focus { border-color: var(--opcw-line-strong); box-shadow: var(--opcw-focus); }
.opcw-field .opcw-input::placeholder,
.opcw-field input.input-text::placeholder { color: transparent; }
.opcw-field__chev { display: none; } /* superseded by the select background chevron */
/* …also against global SVG resets (`svg:not(:root) { display: inline }`, Royal Elementor Addons). */
.opcw .opcw-field svg.opcw-field__chev { display: none !important; }
.opcw-field__static { display: flex; align-items: flex-end; height: var(--opcw-field-h); padding: 24px 14px 7px;
	border: 1px solid var(--opcw-line); border-radius: var(--opcw-radius-sm); background: var(--opcw-surface);
	color: var(--opcw-ink); font-size: 15px; box-shadow: var(--opcw-shadow); }

/* wc-address-i18n rewrites labels client-side and injects required markers —
   the design doesn't use asterisks (required = everything not "(optional)"). */
.opcw abbr.required { display: none; }

/* validation states (WC toggles these) */
.opcw .form-row.woocommerce-invalid .opcw-input,
.opcw .form-row.woocommerce-invalid input.input-text,
.opcw .form-row.woocommerce-invalid select { border-color: var(--opcw-error); }
.opcw .form-row.woocommerce-validated .opcw-input { border-color: var(--opcw-line); }

/* WooCommerce's own "(optional)" span inside our labels (4.5): looks like the
   label text it replaces. */
.opcw .opcw-field__lbl .optional { color: inherit; font: inherit; visibility: visible; }

/* minimal select2 sanity (selectWoo is disabled on the takeover — its controls
   on our designed fields are hidden then, OPCW_Checkout::assets(), unless a
   site turns that off with opcw_disable_selectwoo; another plugin's adopted
   row keeps its select2) */
.opcw .select2-container .select2-selection--single { height: var(--opcw-field-h); border: 1px solid var(--opcw-line); border-radius: var(--opcw-radius-sm); }
.opcw .select2-container .select2-selection__rendered { line-height: var(--opcw-field-h); padding-left: 14px; }
.opcw .select2-container .select2-selection__arrow { height: var(--opcw-field-h); }

/* ---------- adopted native fields ----------
 * Custom / third-party checkout fields printed straight into the preserved
 * WooCommerce action hooks (woocommerce_before_order_notes, field-editor
 * plugins, bespoke snippets) render as bare `.form-row` + `input.input-text`
 * with NO `.opcw-field` wrapper, so the floating-label rules above can't reach
 * them and they read as foreign controls. Give those the OPC box + a clean top
 * label (native markup puts the <label> before the input, so a floating label
 * can't be forced — a top label is the honest match). Purely cosmetic: scoped
 * to the controls the WC field API emits and never touching the field model,
 * hooks, POST payload, or validation. `.input-text` is the safe signal — qty,
 * search and quantity inputs don't carry it, so they're left alone. */
.opcw .form-row:not(.opcw-field) input.input-text,
.opcw .form-row:not(.opcw-field) select,
.opcw .form-row:not(.opcw-field) textarea {
	width: 100%; height: var(--opcw-field-h); padding: 0 14px; margin: 0;
	border: 1px solid var(--opcw-line); border-radius: var(--opcw-radius-sm);
	background: var(--opcw-surface); color: var(--opcw-ink);
	font: inherit; font-size: 15px; line-height: 1.5; outline: none;
	appearance: none; -webkit-appearance: none;
	transition: border-color .12s, box-shadow .12s; box-shadow: var(--opcw-shadow);
}
.opcw .form-row:not(.opcw-field) select {
	padding: 0 36px 0 14px;
	background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="%2374787e" stroke-width="2" stroke-linecap="round"><polyline points="6 9 12 15 18 9"/></svg>');
	background-repeat: no-repeat; background-position: right 14px center;
}
.opcw .form-row:not(.opcw-field) textarea { height: auto; min-height: 96px; padding: 12px 14px; resize: vertical; }
.opcw .form-row:not(.opcw-field) input.input-text:focus,
.opcw .form-row:not(.opcw-field) select:focus,
.opcw .form-row:not(.opcw-field) textarea:focus { border-color: var(--opcw-line-strong); box-shadow: var(--opcw-focus); }
.opcw .form-row:not(.opcw-field) .woocommerce-input-wrapper { display: block; }
/* top label — only on rows that actually carry a text control, so checkbox /
   radio rows (whose <label> wraps the control) keep their native layout. */
.opcw .form-row:not(.opcw-field):has(input.input-text, select, textarea) > label {
	display: block; margin: 0 0 6px; padding: 0;
	font-size: 12px; font-weight: 500; letter-spacing: .01em; line-height: 1.4; color: var(--opcw-muted);
}
.opcw .form-row:not(.opcw-field) > label .optional { color: var(--opcw-faint); font-weight: 400; }
.opcw .form-row:not(.opcw-field).woocommerce-invalid input.input-text,
.opcw .form-row:not(.opcw-field).woocommerce-invalid select,
.opcw .form-row:not(.opcw-field).woocommerce-invalid textarea { border-color: var(--opcw-error); }
/* An adopted row paired with one of ours (a plugin's own city type next to our
   postcode: Persian WooCommerce): both sit on the row's bottom edge, so the two
   boxes line up and the adopted row's top label stays above its own box. */
.opcw .opcw-row:has(> .form-row:not(.opcw-field)) > .form-row { align-self: end; }
/* …and when that adopted row is a bare label + one native control (a select
   without select2, or a text input — Persian WooCommerce's city, whose script
   swaps the two and keeps the label first), it takes the floating label of
   its neighbours: the label sits inside the box (raised; centred while a
   text input is empty and unfocused), the control keeps the room for it.
   Label first in the DOM, so :has() reads the state. Rows with a wrapper,
   select2, a multiselect or a textarea keep the top label above. */
.opcw .opcw-row:has(> .form-row:not(.opcw-field) > label + :is(select:not(.select2-hidden-accessible, [multiple]), input.input-text)) > .form-row { align-self: auto; }
.opcw .opcw-row > .form-row:not(.opcw-field):has(> label + :is(select:not(.select2-hidden-accessible, [multiple]), input.input-text)) { position: relative; }
.opcw .opcw-row > .form-row:not(.opcw-field):has(> label + :is(select:not(.select2-hidden-accessible, [multiple]), input.input-text)) > label {
	position: absolute; inset-inline-start: 15px; top: 8px; z-index: 1; margin: 0; padding: 0;
	max-width: calc(100% - 30px); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none;
	font-size: 10.5px; font-weight: 400; letter-spacing: .01em; line-height: 1.4; color: var(--opcw-muted); transition: all .12s ease;
}
.opcw .opcw-row > .form-row:not(.opcw-field):has(> label + input.input-text:placeholder-shown:not(:focus)) > label {
	top: calc(var(--opcw-field-h) / 2); transform: translateY(-50%); font-size: 15px; letter-spacing: normal;
}
.opcw .opcw-row > .form-row:not(.opcw-field) > label + input.input-text { padding: 24px 14px 5px; }
.opcw .opcw-row > .form-row:not(.opcw-field) > label + input.input-text::placeholder { color: transparent; }
.opcw .opcw-row > .form-row:not(.opcw-field) > label + select:not(.select2-hidden-accessible, [multiple]) { padding: 18px 36px 0 14px; }
html[dir="rtl"] .opcw .opcw-row > .form-row:not(.opcw-field) > label + select:not(.select2-hidden-accessible, [multiple]) { padding: 18px 14px 0 36px; }

/* Third-party content in the address sections (4.5): what plugins print on
   WooCommerce's checkout actions (div.opcw-3p, OPCW_Checkout::hook_html()) or
   append to a field's markup (woocommerce_form_field filters: an opt-in under
   the email). Their checkboxes take the .opcw-check look; text stays text.
   The 12px spacing is for the address sections only: rows plugins print on
   woocommerce_review_order_* in the order summary (.opcw-summary,
   .opcw-msummary) sit flush, as in 4.4 (#99). :where() keeps the
   specificity of `.opcw .opcw-3p`. */
.opcw .opcw-3p { font-size: 14px; line-height: 1.5; color: var(--opcw-text); }
.opcw .opcw-3p:where(:not(.opcw-summary *, .opcw-msummary *)) { margin: 12px 0 0; }
.opcw .opcw-3p > p { margin: 0 0 8px; }
.opcw .opcw-3p > :last-child { margin-bottom: 0; }
/* nothing to show (hidden inputs, order attribution) or emptied by a script:
   no spacing */
.opcw .opcw-3p:is([hidden], :empty) { display: none; }
/* appended to a field row: the row's grid gap is the spacing */
.opcw .opcw-row > :not(.opcw-field) { margin: 0; }
.opcw :is(#opcw-contact, #opcw-shipping, #opcw-billing) .opcw-row > :not(.opcw-field) label:has(> input[type="checkbox"]) { margin-top: 4px; }
/* The box hangs in the label's start padding, so the label's own inline
   content (text, an "(optional)" span, a link) keeps flowing as one line. */
.opcw :is(#opcw-contact, #opcw-shipping, #opcw-billing) label:not(.opcw-check):has(> input[type="checkbox"]) {
	display: block; position: relative; margin: 12px 0 0; padding: 0; padding-inline-start: 28px;
	font-size: 14px; line-height: 1.5; color: var(--opcw-text); cursor: pointer;
}
.opcw :is(#opcw-contact, #opcw-shipping, #opcw-billing) label:not(.opcw-check) > input[type="checkbox"] {
	position: absolute !important; top: 2px !important; inset-inline-start: 0;
	width: 18px; height: 18px; margin: 0 !important; padding: 0; accent-color: var(--opcw-accent);
}

.opcw-field:has(.opcw-ac:not([hidden])) { z-index: 5; } /* raise the field so its dropdown sits above siblings */

/* address autocomplete dropdown — one combobox UI for hosted (OnePageCheckout Geo) and own-key Google */
.opcw-ac { position: absolute; z-index: 60; top: calc(100% + 4px); left: 0; right: 0;
	background: var(--opcw-surface); border: 1px solid var(--opcw-line-strong); border-radius: var(--opcw-radius-sm);
	box-shadow: 0 12px 32px rgba(20, 22, 26, .14); overflow: hidden; margin: 0; padding: 0; list-style: none; text-align: left; }
.opcw-ac[hidden] { display: none; }
.opcw-ac__list { margin: 0; padding: 0; }
.opcw-ac__item { display: block; width: 100%; text-align: left; padding: 10px 14px; margin: 0; background: none;
	border: 0; border-bottom: 1px solid var(--opcw-line); font: inherit; font-size: 13.5px; line-height: 1.4; cursor: pointer;
	-webkit-tap-highlight-color: transparent; user-select: none; }
.opcw-ac__item:last-child { border-bottom: 0; }
.opcw-ac__item b { display: block; font-weight: 600; color: var(--opcw-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.opcw-ac__item span { display: block; font-size: 12px; color: var(--opcw-muted); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.opcw-ac__item:hover, .opcw-ac__item.is-active { background: color-mix(in srgb, var(--opcw-accent) 4%, var(--opcw-surface)); }
/* OSM credit: by default in the bottom-right corner of the LAST suggestion row, on
   its secondary line (no extra height). When that row's text would reach it, JS
   adds .opcw-ac--attr-line and the credit takes its own small line instead.
   Plain --opcw-muted, no opacity: 5.1:1 on the dropdown, 4.7:1 on the active row
   (the former opacity .75 left 3.1:1 and 2.9:1, below AA for this small text). */
.opcw-ac__attr { position: absolute; right: 14px; bottom: 12px; z-index: 1; padding: 0; border: 0; font-size: 10px; line-height: 1.2;
	color: var(--opcw-muted); text-align: right; letter-spacing: .01em; white-space: nowrap; user-select: none; }
.opcw-ac--attr-line .opcw-ac__attr { position: static; padding: 0 10px 3px; }
.opcw .opcw-ac__attr a { color: inherit; text-decoration: none; }
.opcw .opcw-ac__attr a:hover { text-decoration: underline; }
.opcw-ac__attr[hidden], .opcw-ac__attr:empty { display: none; }
@media (max-width: 640px) {
	.opcw-ac__item { padding: 12px 14px; font-size: 14.5px; }
	.opcw-ac__item span { font-size: 13px; }
	.opcw-ac__attr { bottom: 14px; }
}


/* quiet toggles + checks */
.opcw-quiet { background: none; border: 0; padding: 0; margin: 2px 2px 12px; font-size: 13px; color: var(--opcw-muted);
	text-decoration: underline; text-underline-offset: 2px; }
.opcw-quiet:hover { color: var(--opcw-ink); }
.opcw-check { display: flex; align-items: flex-start; gap: 10px; font-size: 14px; line-height: 1.5; color: var(--opcw-text); cursor: pointer; margin: 12px 0 0; }
.opcw-check input { width: 18px; height: 18px; margin: 2px 0 0 !important; padding: 0; accent-color: var(--opcw-accent); flex: none;
	position: static !important; top: auto !important; /* WC/theme css nudges .input-checkbox via relative top */ }
.opcw-check span { margin-top: 0.5px; }

/* login collapse */
.opcw-login { border: 1px solid var(--opcw-line); border-radius: var(--opcw-radius); background: var(--opcw-surface);
	padding: 18px; margin-bottom: 14px; box-shadow: var(--opcw-shadow); }
.opcw-login form.login { border: 0; padding: 0; margin: 0; }
.opcw-login .form-row { margin: 0 0 var(--opcw-gap); position: relative; }
.opcw-login label:not(.woocommerce-form__label-for-checkbox) { display: block; font-size: 12px; color: var(--opcw-muted); margin: 0 0 4px; }
.opcw-login input.input-text { width: 100%; height: 46px; padding: 0 14px; border: 1px solid var(--opcw-line);
	border-radius: var(--opcw-radius-sm); font: inherit; font-size: 15px; }
.opcw-login .woocommerce-form-login__submit { height: 46px; padding: 0 22px; border: 0; border-radius: var(--opcw-radius-sm);
	background: var(--opcw-primary); color: var(--opcw-primary-ink); font-weight: 600; }
.opcw-login .lost_password { font-size: 12.5px; margin-top: 8px; }

/* account creation */
.opcw .create-account { margin-top: var(--opcw-gap); }
/* The sign-up password stays hidden from the first paint until "Create an account?" is
   checked (WooCommerce's JS shows it only after load): no flash, and password managers
   don't read the page as a registration form. Registration required (no checkbox) and a
   default-checked box keep it visible; WooCommerce's own toggle (inline styles) keeps working. */
.opcw .woocommerce-account-fields:has(#createaccount:not(:checked)) div.create-account { display: none; }

/* ---------- option cards (shipping + payment) ---------- */
.opcw-options { border: 1px solid var(--opcw-line); border-radius: var(--opcw-radius); overflow: hidden;
	background: var(--opcw-surface); box-shadow: var(--opcw-shadow); }
.opcw-option { display: block; border-bottom: 1px solid var(--opcw-line); position: relative; margin: 0; }
.opcw-option:last-child { border-bottom: 0; }
.opcw-option__row { display: flex; align-items: center; gap: 12px; padding: 15px 16px; cursor: pointer; }
.opcw-option input[type="radio"] { width: 18px; height: 18px; accent-color: var(--opcw-accent); flex: none; margin: 0; }
.opcw-option__label { flex: 1; min-width: 0; font-size: 14.5px; color: var(--opcw-ink); font-weight: 500; }
.opcw-option__sub { display: block; font-size: 12.5px; color: var(--opcw-muted); font-weight: 400; margin-top: 1px; }
.opcw-option__price { font-weight: 600; color: var(--opcw-ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.opcw-option__free { color: var(--opcw-success); font-weight: 600; }
.opcw-option.is-selected { background: color-mix(in srgb, var(--opcw-accent) 3%, var(--opcw-surface)); }
.opcw-option.is-selected .opcw-option__row { box-shadow: inset 3px 0 0 var(--opcw-accent); }
.opcw-ship-empty { border: 1px dashed var(--opcw-line); border-radius: var(--opcw-radius); padding: 16px; font-size: 13.5px; color: var(--opcw-muted); }
.opcw-ship-pkg { font-family: var(--opcw-font-mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--opcw-faint); margin: 0 0 8px; }

/* ---------- native payment block, restyled ---------- */
.opcw #payment { background: transparent; border-radius: 0; }
.opcw #payment ul.wc_payment_methods { list-style: none; margin: 0; padding: 0;
	border: 1px solid var(--opcw-line); border-radius: var(--opcw-radius); overflow: hidden;
	background: var(--opcw-surface); box-shadow: var(--opcw-shadow); }
.opcw #payment ul.wc_payment_methods li { border-bottom: 1px solid var(--opcw-line); margin: 0; padding: 0; position: relative; }
.opcw #payment ul.wc_payment_methods li:last-child { border-bottom: 0; }
.opcw #payment ul.wc_payment_methods li > label { display: flex; align-items: center; gap: 12px; padding: 15px 44px 15px 46px;
	cursor: pointer; font-size: 14.5px; font-weight: 500; color: var(--opcw-ink); margin: 0; }
.opcw #payment ul.wc_payment_methods li > input[type="radio"] { position: absolute; left: 16px; top: 17px;
	width: 18px; height: 18px; accent-color: var(--opcw-accent); margin: 0; }
.opcw #payment ul.wc_payment_methods li > label img { max-height: 24px; width: auto; margin-left: auto; }
/* single gateway: WC renders no radio — don't reserve space for one */
.opcw #payment ul.wc_payment_methods li:only-child > label { padding-left: 16px; }
.opcw #payment ul.wc_payment_methods li:only-child div.payment_box { padding-left: 16px; }
.opcw #payment ul.wc_payment_methods li.opcw-pm-selected { background: color-mix(in srgb, var(--opcw-accent) 3%, var(--opcw-surface)); }
.opcw #payment ul.wc_payment_methods li.opcw-pm-selected::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 3px; background: var(--opcw-accent); }
.opcw #payment div.payment_box { margin: 0; padding: 4px 16px 16px 46px; background: transparent; color: var(--opcw-muted); font-size: 13px; line-height: 1.55; }
.opcw #payment div.payment_box::before { display: none; }
.opcw #payment div.payment_box p { margin: 0 0 6px; }
/* Keep our payment-box inset when gateway CSS zeroes it with !important
   (e.g. `#payment .payment_methods li .payment_box { padding: 0 !important }`
   on phones): same values as above, more specific, both engines. */
.opcw #payment ul.wc_payment_methods > li > div.payment_box { padding: 4px 16px 16px 46px !important; }
.opcw #payment ul.wc_payment_methods > li:only-child > div.payment_box { padding-left: 16px !important; }
/* Phones: an inline payment form (card fields in a fieldset) gets the full width, not the 46px text inset. */
@media (max-width: 480px) {
	.opcw #payment ul.wc_payment_methods > li > div.payment_box:has(fieldset) { padding-left: 16px !important; }
}
/* 4.6 — a description inside the row (li.opcw-pm-inline, both engines): the
   shipping row's title + span.opcw-option__sub, no payment_box below, so a
   selection moves nothing. The radio centres on the row like a shipping radio. */
.opcw #payment ul.wc_payment_methods li.opcw-pm-inline > input[type="radio"] { top: 50%; margin-top: -9px; }
.opcw #payment ul.wc_payment_methods li.opcw-pm-inline .opcw-option__sub a { color: inherit; text-decoration: underline; }
.opcw #payment .form-row.place-order { padding: 0; margin: 0; }
/* Billing address subsection: two option cards (same as delivery / different);
   the "different" card expands the billing fields inside the card group.
   Its own section (kicker + h2) inside #payment, in Shopify order: payment
   methods → billing → terms + pay button (classic: OPCW_Checkout::
   print_payment(); Block Mode: PaymentSection afterMethods). Classic fallback
   (unsplittable payment markup): above #payment. */
.opcw .opcw-billing { min-width: 0; }
.opcw #payment > .opcw-billing { margin: var(--opcw-section-gap) 0 24px; }
.opcw .opcw-billing .opcw-section__head { margin-bottom: 14px; }
/* Split payment block: WooCommerce blocks the whole #payment on refresh; hide
   that overlay and dim only the refreshed live parts (billing stays usable).
   The place-order part keeps taking clicks (#101): a click during a refresh
   is held and submitted once it answered (checkout.js, aria-busy meanwhile). */
.opcw #payment:has(> .opcw-pm-live) > .blockUI { display: none !important; }
.opcw-pm-live, .opcw-po-live { transition: opacity .15s ease; }
#opcw-payment.is-updating .opcw-pm-live { opacity: .55; pointer-events: none; }
#opcw-payment.is-updating .opcw-po-live, #opcw-payment[aria-busy="true"] .opcw-po-live { opacity: .55; }
#opcw-payment.is-updating #place_order, #opcw-payment[aria-busy="true"] #place_order { cursor: progress; }
/* overflow stays visible so the address-autocomplete dropdown is never clipped;
   corners are rounded per edge instead. */
.opcw .opcw-billing__options { overflow: visible; }
.opcw-billing__options > .opcw-option:first-child,
.opcw-billing__options > .opcw-option:first-child .opcw-option__row { border-radius: calc(var(--opcw-radius) - 1px) calc(var(--opcw-radius) - 1px) 0 0; }
.opcw-billing__options > .opcw-option:nth-child(2) { border-bottom: 0; }
.opcw-billing:not(.is-different) .opcw-billing__options > .opcw-option:nth-child(2),
.opcw-billing:not(.is-different) .opcw-billing__options > .opcw-option:nth-child(2) .opcw-option__row { border-radius: 0 0 calc(var(--opcw-radius) - 1px) calc(var(--opcw-radius) - 1px); }
.opcw-billing__panel { display: grid; grid-template-rows: 0fr; visibility: hidden;
	transition: grid-template-rows .28s cubic-bezier(.2, .7, .2, 1), visibility 0s linear .28s; }
.opcw-billing__panel-in { min-height: 0; overflow: hidden; }
.opcw-billing.is-different .opcw-billing__panel { grid-template-rows: 1fr; visibility: visible;
	border-top: 1px solid var(--opcw-line);
	transition: grid-template-rows .28s cubic-bezier(.2, .7, .2, 1), visibility 0s linear 0s; }
.opcw-billing.is-settled .opcw-billing__panel-in { overflow: visible; }
/* Without JavaScript (or before it has run) the checked radio alone drives
   the panel and the selected card. Separate rules on purpose: a browser
   without :has() must drop only these, not the JS-driven rules above.
   .opcw-billing--js marks the enhanced state (animated, JS-unclipped). */
.opcw-billing:has(#opcw_bill_diff:checked) .opcw-billing__panel { grid-template-rows: 1fr; visibility: visible;
	border-top: 1px solid var(--opcw-line);
	transition: grid-template-rows .28s cubic-bezier(.2, .7, .2, 1), visibility 0s linear 0s; }
.opcw-billing:has(#opcw_bill_diff:checked) .opcw-billing__options > .opcw-option:nth-child(2),
.opcw-billing:has(#opcw_bill_diff:checked) .opcw-billing__options > .opcw-option:nth-child(2) .opcw-option__row { border-radius: 0; }
.opcw-billing:not(.opcw-billing--js):has(#opcw_bill_diff:checked) .opcw-billing__panel-in { overflow: visible; }
.opcw-billing:not(.opcw-billing--js) .opcw-billing__options > .opcw-option { background: transparent; }
.opcw-billing:not(.opcw-billing--js) .opcw-billing__options > .opcw-option .opcw-option__row { box-shadow: none; }
.opcw-billing:not(.opcw-billing--js) .opcw-billing__options > .opcw-option:has(input:checked) { background: color-mix(in srgb, var(--opcw-accent) 3%, var(--opcw-surface)); }
.opcw-billing:not(.opcw-billing--js) .opcw-billing__options > .opcw-option:has(input:checked) .opcw-option__row { box-shadow: inset 3px 0 0 var(--opcw-accent); }
/* The closing-animation copy (Block Mode) never shows validation state. */
.opcw-billing__ghost .woocommerce-invalid .opcw-input,
.opcw-billing__ghost .woocommerce-invalid select { border-color: var(--opcw-line) !important; box-shadow: none !important; }
.opcw .opcw-billing__fields { padding: 16px 16px 8px; border-radius: 0 0 calc(var(--opcw-radius) - 1px) calc(var(--opcw-radius) - 1px);
	background: color-mix(in srgb, var(--opcw-ink) 2.5%, var(--opcw-surface)); }
@media (max-width: 480px) { .opcw .opcw-billing__fields { padding: 14px 12px 6px; } }
@media (prefers-reduced-motion: reduce) { .opcw-billing__panel, .opcw-billing.is-different .opcw-billing__panel { transition: none; } }
/* Billing fields that are not part of the address (4.5): in view below the
   cards whatever card is chosen (OPCW_Fields::billing_panel_keys()). */
.opcw .opcw-billing__extra { margin-top: 16px; }
.opcw .opcw-billing__extra > .opcw-row:last-child { margin-bottom: 0; }

/* terms + privacy */
.opcw .woocommerce-terms-and-conditions-wrapper { margin: 18px 0 0; font-size: 13px; color: var(--opcw-muted); }
.opcw .woocommerce-terms-and-conditions-wrapper .woocommerce-privacy-policy-text p { margin: 0 0 10px; line-height: 1.6; }
.opcw .woocommerce-terms-and-conditions-checkbox-text { font-size: 13.5px; }
/* WooCommerce's inline terms box (the "terms and conditions" link toggles it
   above the checkbox): a framed scroll area, as the theme/WooCommerce CSS we drop
   gave it. Display stays WooCommerce's (slideToggle); the page's headings scale down. */
.opcw .woocommerce-terms-and-conditions { box-sizing: border-box; max-height: 200px; overflow: auto; margin: 0 0 12px;
	padding: 12px 16px; border: 1px solid var(--opcw-line); border-radius: var(--opcw-radius-sm);
	background: var(--opcw-bg-summary); color: var(--opcw-text); font-size: 13px; line-height: 1.6; }
.opcw .woocommerce-terms-and-conditions :is(h1, h2, h3, h4, h5, h6) { margin: 14px 0 6px; font-size: 14px; line-height: 1.4; font-weight: 600; color: var(--opcw-ink); }
.opcw .woocommerce-terms-and-conditions > :first-child { margin-top: 0; }
.opcw .woocommerce-terms-and-conditions p { margin: 0 0 10px; }
.opcw .woocommerce-terms-and-conditions > :last-child { margin-bottom: 0; }
.opcw .woocommerce-form__label-for-checkbox { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; }
.opcw .woocommerce-form__label-for-checkbox input[type="checkbox"] { width: 18px; height: 18px; margin: 2px 0 0; accent-color: var(--opcw-accent); flex: none; }

/* ---------- pay button + trust ---------- */
/* The pay CTA defends its colors with !important — themes and gateways love
   to restyle .button.alt/#place_order, and a broken pay button is the one
   thing a checkout plugin can never allow. */
.opcw .opcw-btn-primary {
	width: 100%; height: 58px; margin-top: 22px;
	background: var(--opcw-primary) !important; color: var(--opcw-primary-ink) !important;
	border: 0 !important; border-radius: var(--opcw-radius) !important;
	font-size: 15.5px; font-weight: 700; letter-spacing: var(--opcw-ls-btn); text-transform: var(--opcw-tt-btn);
	display: inline-flex; align-items: center; justify-content: center; gap: 10px; text-decoration: none;
	transition: filter .12s, transform .05s;
}
.opcw .opcw-btn-primary:not(#place_order)::before { display: none; }
.opcw .opcw-btn-primary::before {
	content: ""; width: 15px; height: 15px; flex: none; background: currentColor;
	-webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>') center / contain no-repeat;
	mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>') center / contain no-repeat;
}
.opcw .opcw-btn-primary:hover { filter: brightness(1.12); }
.opcw .opcw-btn-primary:active { transform: translateY(1px); }
.opcw .opcw-btn-primary:disabled { opacity: .6; cursor: wait; }
.opcw-trust { display: flex; justify-content: center; flex-wrap: wrap; gap: 6px 18px; margin-top: 18px;
	font-family: var(--opcw-font-mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--opcw-faint); }
.opcw-trust span { display: inline-flex; align-items: center; gap: 6px; }

.opcw-footnav { margin-top: 44px; padding-top: 18px; border-top: 1px solid var(--opcw-line);
	display: flex; flex-wrap: wrap; gap: 18px; font-size: 12px; }
.opcw-footnav a { color: var(--opcw-muted); text-decoration: none; }
.opcw-footnav a:hover { color: var(--opcw-ink); text-decoration: underline; }

/* ---------- notices ---------- */
.opcw-notices { margin-bottom: 18px; }
.opcw .woocommerce-error, .opcw .woocommerce-message, .opcw .woocommerce-info {
	list-style: none; margin: 0 0 12px; padding: 14px 16px;
	border: 1px solid var(--opcw-line); border-left: 3px solid var(--opcw-error); border-radius: var(--opcw-radius-sm);
	background: var(--opcw-surface); color: var(--opcw-ink); font-size: 13.5px; box-shadow: var(--opcw-shadow);
}
.opcw .woocommerce-error li { margin: 0 0 6px; }
.opcw .woocommerce-error li:last-child { margin: 0; }
.opcw .woocommerce-message { border-left-color: var(--opcw-success); }
.opcw .woocommerce-info { border-left-color: var(--opcw-accent); }
/* Block Mode: dismissible notices (text + close button per notice) */
.opcw-notices:focus { outline: none; }
/* Block Mode: a failed Pay focuses the payment notice (or the payment section) for screen
   readers — programmatic focus of a non-interactive container, no focus ring */
.opcw #payment .woocommerce-error:focus, .opcw #payment .wc-block-components-notice-banner:focus,
.opcw #opcw-payment:focus { outline: none; }
.opcw .opcw-notice { display: flex; align-items: flex-start; gap: 10px; }
.opcw .opcw-notice__text { flex: 1 1 auto; min-width: 0; }
.opcw .opcw-notice__close { flex: none; display: inline-flex; align-items: center; justify-content: center;
	width: 22px; height: 22px; min-height: 0; margin: -1px -6px -1px 0; padding: 0; border: 0; border-radius: var(--opcw-radius-sm);
	background: none; box-shadow: none; color: var(--opcw-muted); line-height: 1; cursor: pointer; transition: color .15s; }
.opcw .opcw-notice__close:hover { background: none; color: var(--opcw-ink); }
.opcw .opcw-notice__close svg { width: 14px; height: 14px; }
.opcw .woocommerce-NoticeGroup { margin-bottom: 18px; display: block; }
/* Notice lists stay vertical lists inside the notices region (it keeps the
   woocommerce-notices-wrapper class for third-party scroll code): global
   rules such as Royal Elementor Addons' `.woocommerce-notices-wrapper
   .woocommerce-error { display: flex; flex-direction: row-reverse }` turned
   the messages into reversed columns wider than a phone screen. A dismissible
   Block Mode notice (.opcw-notice) stays a row: text, then its close button. */
.opcw .woocommerce-notices-wrapper .woocommerce-error,
.opcw .woocommerce-notices-wrapper .woocommerce-message,
.opcw .woocommerce-notices-wrapper .woocommerce-info { display: block; flex-direction: row; min-width: 0; max-width: 100%; margin: 0 0 12px; }
.opcw .woocommerce-notices-wrapper .opcw-notice { display: flex; }
/* Block themes (and classic themes that opt in) get WooCommerce's block notice
   templates on the classic engine too (.wc-block-components-notice-banner,
   styled by wc-blocks-style): same card as the classic notices above, the
   type accent on the inline-start edge instead of the icon. A gateway's
   dismissible banner in Block Mode keeps its row (text, close button). */
.opcw .wc-block-components-notice-banner {
	display: flex; flex-direction: row; align-items: flex-start; gap: 10px; min-width: 0; max-width: 100%;
	margin: 0 0 12px; padding: 14px 16px !important;
	border: 1px solid var(--opcw-line); border-left: 3px solid var(--opcw-error); border-radius: var(--opcw-radius-sm);
	background: var(--opcw-surface); color: var(--opcw-ink); font-size: 13.5px; font-weight: 400; line-height: 1.5; box-shadow: var(--opcw-shadow);
}
.opcw .wc-block-components-notice-banner.is-error { background: var(--opcw-surface); border-color: var(--opcw-line); border-left-color: var(--opcw-error); }
.opcw .wc-block-components-notice-banner.is-success { background: var(--opcw-surface); border-color: var(--opcw-line); border-left-color: var(--opcw-success); }
.opcw .wc-block-components-notice-banner.is-info,
.opcw .wc-block-components-notice-banner.is-warning { background: var(--opcw-surface); border-color: var(--opcw-line); border-left-color: var(--opcw-accent); }
.opcw .wc-block-components-notice-banner > svg { display: none; }
.opcw .wc-block-components-notice-banner > .wc-block-components-notice-banner__content { align-self: auto; flex: 1 1 auto; min-width: 0; padding: 0; }
.opcw .wc-block-components-notice-banner > .wc-block-components-notice-banner__content .wc-block-components-notice-banner__summary { margin: 0 0 6px; font-weight: 600; }
.opcw .wc-block-components-notice-banner > .wc-block-components-notice-banner__content ul,
.opcw .wc-block-components-notice-banner > .wc-block-components-notice-banner__content ol { margin: 0; padding: 0; list-style: none; }
.opcw .wc-block-components-notice-banner > .wc-block-components-notice-banner__content li { margin: 0 0 6px; }
.opcw .wc-block-components-notice-banner > .wc-block-components-notice-banner__content li:last-child { margin: 0; }

/* blockUI overlay (WC uses it during AJAX) */
.opcw .blockUI.blockOverlay { background: rgba(255, 255, 255, .6) !important; background: color-mix(in srgb, var(--opcw-surface) 60%, transparent) !important; }

/* ---------- order summary ---------- */
.opcw-sum__title { font-family: var(--opcw-font-display); font-weight: var(--opcw-fw-heading, var(--opcw-fw-display)); font-size: var(--opcw-fs-sum-title, 16px);
	color: var(--opcw-ink); margin: 0 0 calc(var(--opcw-sum-gap, 14px) + 4px); }
.opcw-item { display: grid; grid-template-columns: 64px 1fr auto; gap: 14px; align-items: center; padding: var(--opcw-sum-item-pad, 10px) 0; }
.opcw-item__thumb { position: relative; width: 64px; height: 64px; border: 1px solid var(--opcw-line);
	border-radius: var(--opcw-radius-sm); background: var(--opcw-surface); }
.opcw-item__thumb img { width: 100%; height: 100%; object-fit: contain; border-radius: inherit; display: block; }
.opcw-item__qty { position: absolute; top: -7px; inset-inline-end: -7px; min-width: 20px; height: 20px; padding: 0 6px;
	border-radius: 10px; background: var(--opcw-muted); color: var(--opcw-surface); font-size: 11.5px; font-weight: 600;
	display: inline-flex; align-items: center; justify-content: center; }
.opcw-item__body { min-width: 0; }
.opcw-item__name { display: block; font-size: 13.5px; font-weight: 500; color: var(--opcw-ink); line-height: 1.35; }
/* woocommerce_checkout_cart_item_quantity prints into the name (as in the stock
   review-order.php): the quantity itself shows on the thumb badge or the stepper;
   what plugins add after it (Germanized: delivery time, unit, item description)
   reads like the item meta. */
.opcw-item__name .product-quantity { display: none; }
.opcw-item__name :where(p, div, dl, small) { display: block; margin: 2px 0 0; font-size: 12px; font-weight: 400; line-height: 1.4; color: var(--opcw-muted); }
.opcw-item__meta { display: block; font-size: 12px; color: var(--opcw-muted); margin-top: 2px; }
.opcw-item__meta p, .opcw-item__meta dl, .opcw-item__meta dt, .opcw-item__meta dd { display: inline; margin: 0; }
.opcw-item__price { font-size: 13.5px; font-weight: 600; color: var(--opcw-ink); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* editable cart (opt-in): qty stepper + remove per line */
.opcw-item--editable { align-items: start; }
.opcw-item--editable .opcw-item__price { padding-top: 1px; }
.opcw-item.is-busy { opacity: .5; pointer-events: none; }
/* The stepper never shrinks (a long price narrows the body on a phone: − / + stay 30px, the field
   keeps its width); Remove moves to the next line when both do not fit side by side. */
.opcw-item__edit { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin-top: 10px; }
.opcw-qty { display: inline-flex; flex: none; align-items: center; height: 32px; border: 1px solid var(--opcw-line);
	border-radius: var(--opcw-radius-sm); background: var(--opcw-surface); overflow: hidden; }
.opcw-qty__btn { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 30px; height: 30px;
	border: 0; background: none; color: var(--opcw-ink); padding: 0; transition: background .12s, color .12s; }
.opcw-qty__btn:hover:not([aria-disabled="true"]) { background: var(--opcw-bg-summary); }
.opcw-qty__btn[aria-disabled="true"] { color: var(--opcw-faint); cursor: default; }
/* keep the focus ring inside the overflow:hidden group so it isn't clipped */
.opcw-qty__btn:focus-visible { outline-offset: -2px; }
.opcw-qty__btn svg { width: 14px; height: 14px; }
.opcw-qty__n { min-width: 32px; padding: 0 2px; text-align: center; font-size: 13px; font-weight: 600;
	color: var(--opcw-ink); font-variant-numeric: tabular-nums; }
/* 4.5: the quantity is a typed field (input.opcw-qty__n, type text). The number's look (size, weight,
   colour, alignment) stays on the class rule above, so a skin that styled the span styles the field.
   Font, size, weight and colour are repeated for the field one step above theme input rules
   (Blocksy's input:is([type="text"], …) { font-size: 16px; font-weight: …; color: … } is 0-1-1,
   this is 0-2-0; its :focus colour is 0-2-1, the :focus rule here 0-3-0), so a skin's rule of two
   classes (.opcw .opcw-qty__n; three for the focused colour), loaded after this file, still wins.
   What makes it an input is reset below, outweighing theme input rules: no box of its own (the group
   is the box), as high as the group (it stretches, so a skin's shorter .opcw-qty shortens the field
   and its focus ring with it; no fixed height or line-height to clip), room for 4 digits. */
:where(input).opcw-qty__n { cursor: text; }
.opcw-qty :where(input).opcw-qty__n { font-family: inherit; font-size: 13px; font-weight: 600; color: var(--opcw-ink); }
.opcw-qty :where(input).opcw-qty__n:focus { color: var(--opcw-ink); }
.opcw .opcw-qty input.opcw-qty__n { -webkit-appearance: none; appearance: none; box-sizing: border-box; flex: none; width: 40px; max-width: none;
	align-self: stretch; height: auto; min-height: 0; margin: 0; padding: 0 2px; border: 0; border-radius: 0; background: transparent; box-shadow: none;
	line-height: normal; letter-spacing: normal; text-indent: 0; }
.opcw .opcw-qty input.opcw-qty__n:focus { border: 0; background: transparent; box-shadow: none; }
/* the focus ring stays inside the overflow:hidden group (as on the buttons) */
.opcw .opcw-qty input.opcw-qty__n:focus-visible { outline: 2px solid var(--opcw-accent); outline-offset: -2px; }
/* touch screens: 16px, or iOS Safari zooms the page in when the field takes the focus */
@media (pointer: coarse) { .opcw .opcw-qty input.opcw-qty__n { width: 44px; font-size: 16px; } }
.opcw-item__qtystatic { font-size: 12.5px; color: var(--opcw-muted); }
.opcw-item__remove { display: inline-flex; align-items: center; gap: 5px; border: 0; background: none;
	padding: 4px 2px; font-size: 12.5px; color: var(--opcw-muted); transition: color .15s; }
.opcw-item__remove:hover { color: var(--opcw-error); }
.opcw-item__remove svg { width: 14px; height: 14px; flex: none; }

/* summary progress (opcw_summary_progress, e.g. a free-shipping bar): between the items and the
   totals, same HTML in both engines and both summaries. Flush (no box): a message line + a 4px
   track; accent = progress, success = done. The check icon is in the markup, shown when done. */
.opcw-progress { padding: var(--opcw-fit-progress-pad, 8px 0 6px); }
.opcw-progress__msg { display: flex; align-items: center; gap: 7px; margin: 0; font-size: 13px; line-height: 1.4; color: var(--opcw-text); }
.opcw-progress__msg svg { display: none; flex: none; width: 15px; height: 15px; }
.opcw-progress__bar { position: relative; height: 4px; margin-top: 8px; border-radius: 999px; overflow: hidden;
	background: var(--opcw-line); background: color-mix(in srgb, var(--opcw-ink) 10%, transparent); }
.opcw-progress__fill { display: block; height: 100%; min-width: 4px; border-radius: inherit; background: var(--opcw-accent);
	transition: width .45s cubic-bezier(.2, .7, .2, 1), background-color .25s ease; }
/* 13px text: the darker mix keeps >= 4.5:1 on --opcw-bg-summary */
.opcw-progress.is-done .opcw-progress__msg { font-weight: 500; color: var(--opcw-success); color: color-mix(in srgb, var(--opcw-success) 75%, var(--opcw-ink)); }
.opcw-progress.is-done .opcw-progress__msg svg { display: block; color: var(--opcw-success); }
.opcw-progress.is-done .opcw-progress__fill { background: var(--opcw-success); }
@media (prefers-reduced-motion: reduce) { .opcw-progress__fill { transition: none; } }

.opcw-coupon { display: flex !important; gap: var(--opcw-gap); margin: 16px 0; } /* !important: wc-checkout.js hide()s form.checkout_coupon on init */
.opcw-coupon .form-row { flex: 1; margin: 0; }
.opcw-coupon .opcw-input { height: 46px; padding: 18px 14px 3px; box-shadow: none; }
.opcw-coupon .coupon-error-notice { display: block; margin-top: 6px; font-size: 12.5px; line-height: 1.4; color: var(--opcw-error); }
.opcw .opcw-coupon .opcw-input.has-error { border-color: var(--opcw-error); }
.opcw-coupon__btn { height: 46px; padding: 0 18px; border: 1px solid var(--opcw-line); border-radius: var(--opcw-radius-sm);
	background: var(--opcw-surface); font-weight: 600; font-size: 13px; color: var(--opcw-muted); }
.opcw-coupon__btn:hover { border-color: var(--opcw-line-strong); color: var(--opcw-ink); }

.opcw-totals { border-top: 1px solid var(--opcw-line); padding-top: var(--opcw-sum-gap, 14px); display: grid; gap: 8px; margin: var(--opcw-sum-gap, 14px) 0 0; }
.opcw-totals__row { display: flex; justify-content: space-between; gap: 12px; font-size: 13.5px; }
.opcw-totals__row dt { color: var(--opcw-muted); font-weight: 400; }
.opcw-totals__row dd { color: var(--opcw-ink); font-weight: 500; font-variant-numeric: tabular-nums; margin: 0; text-align: right; }
.opcw-totals__row--grand { margin-top: 6px; padding-top: var(--opcw-sum-gap, 14px); border-top: 1px solid var(--opcw-line); align-items: baseline; }
.opcw-totals__row--grand dt { font-size: 15px; color: var(--opcw-ink); font-weight: 600; }
.opcw-totals__row--grand dd { font-family: var(--opcw-font-display); font-weight: var(--opcw-fw-display); font-size: 22px; }
.opcw-totals__row--grand dd .includes_tax { display: block; font-family: var(--opcw-font); font-size: 11.5px; color: var(--opcw-faint); font-weight: 400; margin-top: 2px; }
.opcw-totals__row--coupon dd .woocommerce-remove-coupon { font-size: 11.5px; margin-left: 6px; color: var(--opcw-muted); }

.opcw-sum__perks { margin-top: var(--opcw-perks-gap, 22px); padding-top: 16px; border-top: 1px solid var(--opcw-line); display: grid; gap: 9px; }
.opcw-sum__perk { display: flex; gap: 9px; align-items: center; font-size: 12.5px; color: var(--opcw-muted); }
.opcw-sum__perk svg { color: var(--opcw-success); flex: none; }

/* Panel style (summary_perks_style = panel): a tinted trust box — heading +
   icon / title / description rows. Skinnable via --opcw-perks-panel-bg,
   --opcw-perks-panel-border and --opcw-perks-panel-radius (unset = derived
   from the accent / surface / line / radius tokens where the panel renders). */
.opcw-sum__perks--panel { display: block; margin-top: var(--opcw-perks-gap, 22px); padding: var(--opcw-fit-panel-pad, 18px 18px 20px);
	border: 1px solid var(--opcw-perks-panel-border, color-mix(in srgb, var(--opcw-accent) 16%, var(--opcw-line)));
	border-radius: var(--opcw-perks-panel-radius, var(--opcw-radius));
	background: var(--opcw-perks-panel-bg, color-mix(in srgb, var(--opcw-accent) 5%, var(--opcw-surface))); }
.opcw .opcw-sum__perks-title { margin: 0 0 var(--opcw-fit-perks-title-gap, 16px); font-family: var(--opcw-font-display); font-weight: var(--opcw-fw-heading, var(--opcw-fw-display));
	font-size: var(--opcw-fs-perks-title, 15px); line-height: 1.3; letter-spacing: -.01em; color: var(--opcw-ink); text-wrap: balance; }
.opcw-sum__perks-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--opcw-fit-perks-list-gap, 14px); }
.opcw-sum__perks--panel .opcw-sum__perk { display: flex; align-items: var(--opcw-fit-perk-align, flex-start); gap: var(--opcw-fit-perk-gap, 12px); margin: 0; padding: 0;
	font-size: 13px; line-height: 1.45; color: var(--opcw-text); }
.opcw-sum__perks--panel .opcw-sum__perk svg { color: var(--opcw-accent); flex: none; width: var(--opcw-fit-perk-icon, 22px); height: var(--opcw-fit-perk-icon, 22px); }
.opcw-sum__perk-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding-top: var(--opcw-fit-perk-body-pad, 1px); }
.opcw-sum__perk-title { font-weight: 600; font-size: 13.5px; line-height: 1.35; color: var(--opcw-ink); }
.opcw-sum__perk-desc { font-size: 12.5px; line-height: 1.45; color: var(--opcw-muted); }
/* Mobile copy (main column): only while the summary aside is hidden. */
.opcw-sum__perks--m { display: none; }
@media (max-width: 999px) { .opcw-sum__perks--panel.opcw-sum__perks--m { display: block; margin: 24px 0 28px; } }

/* ---------- height-aware summary (4.5.0) ----------
   assets/js/summary-fit.js measures the desktop column (checkout in both
   engines, thank-you aside) against the viewport and sets the first state
   that fits on .opcw-summary__sticky:
     is-compact      tighter rhythm, a tighter perks panel and progress bar
     is-tight        + perk titles only with 18px icons (descriptions stay
                     for screen readers)
     is-overflowing  + only the items list scrolls, capped (measured cap in
                     --opcw-sum-items-fit), with a fade while more follows;
                     coupon, totals and perk titles stay in view
                     (not for 8px or less: is-tight stays, the pixels come
                     off the gap below the stuck column; likewise
                     is-tight is-minimal)
     + is-minimal    a one-row list does not fit that way: the perks are
                     visually hidden too (still read by screen readers), with
                     is-tight (the full list fits then) or is-overflowing
     + is-unstuck    even that cannot fit: the column scrolls with the page,
                     perks back, a long list capped at one row
                     (is-overflowing is-unstuck, else is-tight is-unstuck)
   The column itself never scrolls; the total stays in view while the column
   is stuck. The states only set custom properties on the column (zero
   specificity), which the base rules above read with the designed values as
   fallbacks, so any skin rule on a component wins in every state. Exceptions
   (they must win over the component rules): is-minimal on the perks and
   is-unstuck on the column (override with the same selector if needed).
   Skin tokens, settable on any ancestor (unset = the designed values):
   --opcw-sum-gap (14px: title / coupon / totals rhythm), --opcw-sum-item-pad
   (10px), --opcw-perks-gap (22px) and, used while a state is set,
   --opcw-sum-gap-compact (10px), --opcw-sum-item-pad-compact (6px),
   --opcw-perks-gap-compact (14px); --opcw-sum-items-max (a cap of your own for
   the scrolling list; the measured cap wins when smaller). Tune one state
   with e.g. `.opcw-summary__sticky.is-tight { --opcw-sum-item-pad: 4px; }`.
   --opcw-fit-* are internal (the state values of the panel and progress bar). */
:where(.opcw-summary__sticky:is(.is-compact, .is-tight, .is-overflowing)) {
	--opcw-sum-gap: var(--opcw-sum-gap-compact, 10px);
	--opcw-sum-item-pad: var(--opcw-sum-item-pad-compact, 6px);
	--opcw-perks-gap: var(--opcw-perks-gap-compact, 14px);
	--opcw-fit-panel-pad: 14px 16px;
	--opcw-fit-perks-title-gap: 10px;
	--opcw-fit-perks-list-gap: 10px;
	--opcw-fit-progress-pad: 4px 0 2px;
}
:where(.opcw-summary__sticky:is(.is-tight, .is-overflowing)) {
	--opcw-fit-perks-list-gap: 8px;
	--opcw-fit-perk-align: center;
	--opcw-fit-perk-gap: 10px;
	--opcw-fit-perk-icon: 18px;
	--opcw-fit-perk-body-pad: 0px;
}
:where(.opcw-summary__sticky:is(.is-tight, .is-overflowing) .opcw-sum__perk-desc) { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
	overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
:where(.opcw-summary__sticky.is-overflowing .opcw-items) { max-height: min(var(--opcw-sum-items-max, 100vh), var(--opcw-sum-items-fit, 100vh));
	overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; padding: 2px 4px 0; margin-inline: -4px; /* room for the qty badge and focus rings */
	-webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent); mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent); }
:where(.opcw-summary__sticky.is-overflowing .opcw-items[data-opcw-at-end]) { -webkit-mask-image: none; mask-image: none; }
:where(.opcw-summary__sticky.is-overflowing .opcw-items):focus-visible { outline-offset: -2px; }
.opcw-summary__sticky.is-minimal .opcw-sum__perks { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
	overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.opcw-summary__sticky.is-unstuck { position: static; }
/* While summary-fit.js measures the column (a few synchronous reads, never
   painted): no transitions in it, so a skin transition on a property the
   states change can neither falsify a read nor resize the column afterwards
   (which would trigger the next measurement). A state change applies at once.
   The progress bar's fill is left out: its width never changes the column's
   size, and a measurement right after updated_checkout would cut its
   animation to the new width short. */
.opcw-summary__sticky.opcw-fit-measuring, .opcw-summary__sticky.opcw-fit-measuring *:not(.opcw-progress__fill),
.opcw-summary__sticky.opcw-fit-measuring::before, .opcw-summary__sticky.opcw-fit-measuring::after,
.opcw-summary__sticky.opcw-fit-measuring *::before, .opcw-summary__sticky.opcw-fit-measuring *::after { transition: none !important; }

/* ---------- mobile summary accordion ---------- */
.opcw-msummary { display: none; }
@media (max-width: 999px) {
	.opcw-layout, .opcw-shell .opcw-layout { grid-template-columns: 1fr; }
	.opcw-main { padding: 24px 20px 56px; max-width: 640px; margin: 0 auto; justify-self: stretch; }
	.opcw-summary { display: none; }
	.opcw-msummary { display: block; border-bottom: 1px solid var(--opcw-line); background: var(--opcw-bg-summary); }
	.opcw-msummary__bar { max-width: 640px; margin: 0 auto; width: 100%; display: flex; align-items: center;
		justify-content: space-between; padding: 14px 20px; background: none; border: 0; font-size: 14px; color: var(--opcw-ink); }
	.opcw-msummary__bar b { font-size: 16px; }
	.opcw-msummary__bar .lbl { display: inline-flex; align-items: center; gap: 8px; color: var(--opcw-muted); }
	.opcw-msummary__bar svg { transition: transform .15s; }
	.opcw-msummary.is-open .opcw-msummary__bar svg { transform: rotate(180deg); }
	.opcw-msummary__body { max-width: 640px; margin: 0 auto; padding: 4px 20px 20px; }
}

/* ============================================================
   THANK-YOU
   ============================================================ */
.opcw-ty__hero { display: flex; gap: 18px; align-items: flex-start; margin-bottom: 30px; }
.opcw-ty__check { width: 52px; height: 52px; border-radius: 50%; flex: none;
	background: color-mix(in srgb, var(--opcw-success) 12%, var(--opcw-surface)); color: var(--opcw-success);
	display: grid; place-items: center; }
.opcw-ty__check.is-fail { background: color-mix(in srgb, var(--opcw-error) 10%, var(--opcw-surface)); color: var(--opcw-error); }
.opcw-ty__order { font-family: var(--opcw-font-mono); font-size: 12px; letter-spacing: .08em; text-transform: uppercase;
	color: var(--opcw-muted); margin-bottom: 4px; }
.opcw-ty__h1 { font-family: var(--opcw-font-display); font-weight: var(--opcw-fw-heading, var(--opcw-fw-display)); font-size: var(--opcw-fs-h1, 26px);
	letter-spacing: -.015em; color: var(--opcw-ink); line-height: 1.15; margin: 0; }
/* a <div> since 4.5 (block markup from woocommerce_thankyou_order_received_text stays inside); margin 0 as the <p> had under `.opcw p` */
.opcw-ty__sub { margin: 0; font-size: 14px; color: var(--opcw-muted); }
.opcw-ty__sub b { color: var(--opcw-ink); font-weight: 600; }

.opcw-details { display: grid; grid-template-columns: 1fr 1fr; gap: var(--opcw-gap); }
@media (max-width: 560px) { .opcw-details { grid-template-columns: 1fr; } }
.opcw-detail { border: 1px solid var(--opcw-line); border-radius: var(--opcw-radius-sm); background: var(--opcw-surface);
	padding: 16px; box-shadow: var(--opcw-shadow); }
.opcw-detail__k { font-family: var(--opcw-font-mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
	color: var(--opcw-faint); margin-bottom: 8px; }
.opcw-detail__v { font-size: 13.5px; color: var(--opcw-text); line-height: 1.6; }
.opcw-detail__v b { color: var(--opcw-ink); font-weight: 600; }
.opcw-detail__v address { font-style: normal; }

/* extension region (gateway instructions, customizations) */
.opcw-ty__ext { margin: 30px 0 0; }
.opcw-ty__ext:empty { display: none; }
.opcw-ty__ext > * { margin-bottom: 18px; }
.opcw-ty__ext h2 { font-family: var(--opcw-font-display); font-weight: var(--opcw-fw-display); font-size: 17px; color: var(--opcw-ink); margin: 0 0 10px; }
.opcw-ty__ext table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.opcw-ty__ext table th, .opcw-ty__ext table td { text-align: left; padding: 8px 10px; border: 1px solid var(--opcw-line); }
.opcw-ty__ext .woocommerce-bacs-bank-details { border: 1px solid var(--opcw-line); border-radius: var(--opcw-radius-sm);
	background: var(--opcw-surface); padding: 16px; box-shadow: var(--opcw-shadow); }
.opcw-ty__ext .woocommerce-bacs-bank-details h2, .opcw-ty__ext .woocommerce-bacs-bank-details h3 { font-size: 14px; margin: 0 0 8px; }
/* gateway detail lists (BACS: ul.wc-bacs-bank-details.order_details.bacs_details): plain lines, no bullets, no floats */
.opcw-ty__ext ul.order_details, .opcw-ty__ext ul.wc-bacs-bank-details { list-style: none; margin: 0 0 12px; padding: 0;
	font-size: 13.5px; line-height: 1.6; color: var(--opcw-text); }
.opcw-ty__ext ul.order_details:last-child, .opcw-ty__ext ul.wc-bacs-bank-details:last-child { margin-bottom: 0; }
.opcw-ty__ext ul.order_details li, .opcw-ty__ext ul.wc-bacs-bank-details li { list-style: none; float: none; margin: 0; padding: 0;
	border: 0; font-size: inherit; line-height: inherit; text-transform: none; }
.opcw-ty__ext ul.order_details li strong, .opcw-ty__ext ul.wc-bacs-bank-details li strong { display: inline; font-size: inherit; color: var(--opcw-ink); font-weight: 600; }
.opcw-ty__ext ul.order_details::before, .opcw-ty__ext ul.order_details::after { content: none; }
/* WC core re-prints the order overview and the order/customer tables on the thank-you hooks: our layout already shows them.
   Only the overview list: other ul.order_details (the BACS bank details) stay visible. */
.opcw-ty__ext ul.woocommerce-order-overview,
.opcw-ty__ext .woocommerce-order-details,
.opcw-ty__ext .woocommerce-customer-details { display: none; }

.opcw-ty__help { border: 1px solid var(--opcw-line); border-radius: var(--opcw-radius); background: var(--opcw-bg-summary);
	padding: 18px 20px; font-size: 13.5px; color: var(--opcw-text); margin: 30px 0 0; }
.opcw-ty__help b { color: var(--opcw-ink); }
/* the order on narrow screens (the aside is hidden below 1000px): an open card after "Order details" */
.opcw-ty__msum { display: none; }
@media (max-width: 999px) {
	.opcw-ty__msum { display: block; margin: 30px 0 0; padding: 18px 20px; border: 1px solid var(--opcw-line);
		border-radius: var(--opcw-radius); background: var(--opcw-bg-summary); }
}
.opcw-ty__actions { display: flex; flex-wrap: wrap; gap: var(--opcw-gap); margin-top: 30px; }
.opcw-ty__actions .opcw-btn-primary { width: auto; padding: 0 30px; height: 52px; margin-top: 0; }
.opcw-btn-secondary, .opcw-cart-errors a.wc-backward { height: 52px; padding: 0 26px; display: inline-flex; align-items: center; justify-content: center;
	border: 1px solid var(--opcw-line-strong); border-radius: var(--opcw-radius); background: var(--opcw-surface);
	color: var(--opcw-ink); font-weight: 600; font-size: 14px; text-decoration: none;
	letter-spacing: var(--opcw-ls-btn); text-transform: var(--opcw-tt-btn); }
.opcw-btn-secondary:hover, .opcw-cart-errors a.wc-backward:hover { background: var(--opcw-bg-summary); }

/* empty cart */
.opcw-empty { padding: 40px 0; }
.opcw-empty p { margin: 10px 0 22px; color: var(--opcw-muted); }
/* cart errors: WooCommerce's checkout/cart-errors.php (text + "Return to cart") */
.opcw-cart-errors > p:first-child { margin-top: 0; color: var(--opcw-text); font-size: 15px; line-height: 1.6; }
/* guest checkout off: the message + the login form, no checkout form */
.opcw-must-login .opcw-login { max-width: 460px; margin: 18px 0 0; }

/* ============================================================
   v2 — configurable design (button shape, offer card)
   ============================================================ */
.opcw .opcw-btn-primary { border-radius: var(--opcw-btn-radius, var(--opcw-radius)) !important; }
.opcw-coupon .opcw-input, .opcw-field .opcw-input, .opcw-field select { border-radius: var(--opcw-radius-sm); }

/* offer card (opcw_order_bump) — the checked state (not only is-added) draws the solid border,
   so the look follows a click at once; classic then swaps in the card rendered from the cart */
.opcw-bump { display: flex; gap: 12px; align-items: flex-start; padding: 15px 16px; margin: 0 0 16px;
	border: 1.5px dashed var(--opcw-accent); border-radius: var(--opcw-radius); background: color-mix(in srgb, var(--opcw-accent) 4%, var(--opcw-surface)); cursor: pointer; transition: background .15s; }
.opcw-bump:hover { background: color-mix(in srgb, var(--opcw-accent) 7%, var(--opcw-surface)); }
.opcw-bump.is-added { border-style: solid; }
.opcw-bump.is-busy { opacity: .6; cursor: progress; }
.opcw-bump:has(input:checked) { border-style: solid; }
.opcw-bump input { width: 19px; height: 19px; margin: 1px 0 0; accent-color: var(--opcw-accent); flex: none; }
.opcw-bump__title { display: block; font-weight: 700; color: var(--opcw-ink); font-size: 14px; }
.opcw-bump__name { display: block; color: var(--opcw-text); font-size: 13px; margin-top: 2px; }

/* ============================================================
   THEME-BLEED HARDENING
   Scoped, moderate-specificity resets for theme patterns observed on
   live installs (Neve, GeneratePress, Hello Elementor, dark themes).
   Everything stays inside .opcw / body.opcw — nothing leaks outside
   the takeover page.
   ============================================================ */

/* Hidden mirror fields (e.g. the deduped shipping_phone) must not leave a gap. */
.opcw p.opcw-field--hidden { display: none; margin: 0; }

/* Form controls: full-width, overflow-safe, visually ours. Neve sizes inputs
   to content width inside grid columns; dark themes invert input background
   and text color. */
.opcw .opcw-field input.input-text,
.opcw .opcw-field .opcw-input,
.opcw .opcw-field select,
.opcw .opcw-field textarea {
	box-sizing: border-box; width: 100%; min-width: 0; max-width: none; float: none;
	background-color: var(--opcw-surface); color: var(--opcw-ink);
	appearance: none; -webkit-appearance: none;
}
/* Selects in the float pattern: re-assert the reserved label space (Neve's
   floating labels collide with the select value, e.g. "Country/Region" over
   "Switzerland") and keep the label raised. */
.opcw .opcw-field select { height: var(--opcw-field-h); padding: 18px 36px 0 14px; }
.opcw .opcw-field .opcw-field__lbl.is-float { top: 8px; transform: none; font-size: 10.5px; }
/* Native widgets (select dropdown, checkbox glyphs) stay light even when a
   dark theme sets color-scheme: dark on :root. */
body.opcw { color-scheme: light; }
/* Checkbox/radio: opinionated themes (e.g. a Blocksy child skin) strip the UA
   appearance (appearance:none + a themed/transparent fill) and shove the box
   down via position:relative;top — leaving WC's terms / remember-me / create-
   account checkboxes hollow, muted and a few px too low. Reassert the native
   control so color-scheme:light + accent-color paint a crisp, aligned box, the
   way our own .opcw-check / #opcw_bill_same boxes already render. Radios only
   need appearance restored — the plugin positions payment radios itself, so we
   leave their box offset alone. */
.opcw input[type="checkbox"],
.opcw input[type="radio"] { appearance: auto !important; -webkit-appearance: auto !important; }
.opcw input[type="checkbox"] { position: static !important; top: auto !important; }
/* Radios: some themes (Blocksy: `.wc_payment_method > input[type=radio]:checked::before`)
   paint their own marker through pseudo-elements — on our native radios that
   shows as a square inside the dot. Our radios never use pseudo-elements, so
   drop them for every radio we render (payment, shipping, billing cards, both
   engines). body.opcw + .opcw-shell outranks those (0,3,2) selectors without
   !important. */
body.opcw .opcw-shell input[type="radio"]::before,
body.opcw .opcw-shell input[type="radio"]::after { content: none; display: none; background: none; box-shadow: none; border: 0; }

/* Name / postcode rows: explicit grid columns, no content-width collapse. */
.opcw .opcw-row--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.opcw .opcw-row--plz { grid-template-columns: minmax(110px, .8fr) minmax(0, 1.6fr); }
.opcw .opcw-row > .form-row { min-width: 0; width: auto; max-width: none; float: none; }
@media (max-width: 480px) { .opcw .opcw-row--2 { grid-template-columns: 1fr; } }

/* Theme-injected required asterisks / label pseudo-icons — the design marks
   optional fields instead (abbr.required is already hidden above). */
.opcw .opcw-field__lbl::before,
.opcw .opcw-field__lbl::after,
.opcw .form-row .required::before,
.opcw .form-row .required::after { content: none; }

/* Buttons: themes hide svgs inside buttons and reset button ::before — which
   would erase the Pay-now lock (a CSS mask on #place_order::before). */
.opcw button svg { display: inline-block; vertical-align: middle; }
.opcw #place_order.opcw-btn-primary::before { content: ""; display: inline-block; }

/* Pay row: column flow — full-width button, trust badges centered BELOW it
   (theme flex/float form rules can pull the badges beside the button). */
.opcw #payment .form-row.place-order { display: block; width: 100%; float: none; }
.opcw #place_order { width: 100%; float: none; }
.opcw .opcw-pay-meta { display: block; width: 100%; clear: both; }
.opcw .opcw-trust { display: flex; width: 100%; }

/* Coupon: themes (GeneratePress) box coupon forms/fieldsets with borders. */
.opcw form.opcw-coupon { border: 0; background: none; padding: 0; box-shadow: none; }
.opcw .opcw-coupon fieldset { border: 0; margin: 0; padding: 0; background: none; }

/* Notices: themes prepend absolutely-positioned icons that overlap the text —
   the design signals the notice type via the left border color instead. */
.opcw .woocommerce-message::before,
.opcw .woocommerce-error::before,
.opcw .woocommerce-info::before { content: none; display: none; }
.opcw .woocommerce-message,
.opcw .woocommerce-error,
.opcw .woocommerce-info { position: static; padding: 14px 16px; }

/* wc-address-i18n.js injects <span class="required">*</span> when it rewrites
   locale labels client-side — same design rule as abbr.required above. */
.opcw span.required { display: none; }

/* WooCommerce's frontend CSS (woocommerce.css / twenty-*.css, -layout,
   -smallscreen, -blocktheme) is dropped on the takeover pages with the theme
   CSS (OPCW_Checkout::drop_handle_pattern()); the few WooCommerce widgets it
   styled that the rules above do not cover: */
/* the create-account password strength meter and its hint */
.opcw .woocommerce-password-strength { display: block; margin: 6px 0 0; padding: 4px 10px; border-radius: var(--opcw-radius-sm);
	font-size: 12.5px; font-weight: 600; line-height: 1.4; color: var(--opcw-ink); background: #fbc5a9; }
.opcw .woocommerce-password-strength.short { background: #f1adad; }
.opcw .woocommerce-password-strength.good { background: #ffe399; }
.opcw .woocommerce-password-strength.strong { background: #c1e1b9; }
.opcw .woocommerce-password-hint { display: block; margin: 5px 2px 0; font-size: 12px; line-height: 1.4; color: var(--opcw-muted); }
/* saved payment methods (tokenizing gateways) */
.opcw #payment .woocommerce-SavedPaymentMethods { list-style: none; margin: 0 0 8px; padding: 0; }
.opcw #payment ul.wc_payment_methods .woocommerce-SavedPaymentMethods li { margin: 0 0 6px; border: 0; }

/* Long labels in narrow columns (postcode at 390px) clip mid-letter — ellipsize. */
.opcw-field__lbl { text-overflow: ellipsis; }

/* Select float pattern, armored. Neve (and themes that print raw critical CSS
   with !important form rules AFTER our stylesheet) recenter the select value
   and keep its label un-floated. Selects always float their label by design,
   so pinning these with !important cannot fight legitimate customization. */
.opcw .opcw-field select {
	height: var(--opcw-field-h) !important;
	padding: 18px 36px 0 14px !important;
	line-height: 1.4 !important;
	background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="%2374787e" stroke-width="2" stroke-linecap="round"><polyline points="6 9 12 15 18 9"/></svg>') !important;
	background-repeat: no-repeat !important;
	background-position: right 14px center !important;
}
.opcw .opcw-field:has(select) .opcw-field__lbl,
.opcw .opcw-field select ~ .opcw-field__lbl,
.opcw .opcw-field.has-value .opcw-field__lbl {
	top: 8px !important;
	transform: none !important;
	font-size: 10.5px !important;
	letter-spacing: .01em !important;
}

/* WooCommerce notice buttons (View cart / wc-forward): themes style them via
   .wp-element-button global styles, which the takeover dequeues — pin ours so
   the button can never render invisible (black-on-black seen on a child theme). */
.opcw .woocommerce-message .button,
.opcw .woocommerce-info .button,
.opcw a.wc-forward {
	background: var(--opcw-ink) !important;
	color: var(--opcw-surface) !important;
	border: 0 !important;
	border-radius: var(--opcw-radius-sm);
	padding: 8px 14px;
	text-decoration: none;
	font-size: 13px;
	line-height: 1.4;
	display: inline-block;
}

/* Block Mode parity: classic WC renders NO radio for a single gateway (the
   only-child rule above removes the reserved indent for exactly that reason).
   The React payment host always renders one — hide it in the same situation. */
.opcw--blocks #payment ul.wc_payment_methods li:only-child .input-radio,
.opcw--blocks #payment ul.wc_payment_methods li:only-child input[type="radio"] { display: none; }

/* ============================================================
   4.2 — fields, login, inline errors
   ============================================================ */
:root {
	--opcw-focus-error: 0 0 0 1.5px var(--opcw-error); /* ring of an invalid + focused field; skins that thin --opcw-focus set this too */
}

/* Login box: a form of its own above section 01 (never inside form.checkout). */
.opcw-main > .opcw-login { margin: 0 0 var(--opcw-section-gap); }
/* The card keeps its compact rhythm: 46px fields beside the 46px Login button (the 4.1
   .opcw-login rule lost the cascade to the adopted-native field rule
   .opcw .form-row:not(.opcw-field) input.input-text, 0,3,1). */
.opcw .opcw-login .form-row input.input-text { height: 46px; padding: 0 14px; }
.opcw .opcw-login .woocommerce-form-login__rememberme { margin: 0 0 12px; }
/* WooCommerce's show-password button (its CSS is often dequeued by the theme): an eye at
   the end of the password field, in the muted ink. */
.opcw .opcw-login .password-input { position: relative; display: block; }
.opcw .opcw-login .password-input input.input-text { padding-inline-end: 44px; }
.opcw .opcw-login .show-password-input { position: absolute; inset-inline-end: 6px; top: 50%; transform: translateY(-50%);
	display: flex; align-items: center; justify-content: center; width: 34px; height: 34px; margin: 0; padding: 0;
	border: 0; border-radius: var(--opcw-radius-sm); background: transparent; color: var(--opcw-muted); cursor: pointer; box-shadow: none; }
.opcw .opcw-login .show-password-input:hover { color: var(--opcw-ink); }
.opcw .opcw-login .show-password-input:focus-visible { outline: 2px solid var(--opcw-accent); outline-offset: 0; }
.opcw .opcw-login .show-password-input::after { content: none; }
.opcw .opcw-login .show-password-input::before { content: ""; display: block; width: 20px; height: 20px; background: currentColor;
	-webkit-mask: url('data:image/svg+xml,<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M17.3 3.3C16.9 2.9 16.2 2.9 15.7 3.3L13.3 5.7C12.2437 5.3079 11.1267 5.1048 10 5.1C6.2 5.2 2.8 7.2 1 10.5C1.2 10.9 1.5 11.3 1.8 11.7C2.6 12.8 3.6 13.7 4.7 14.4L3 16.1C2.6 16.5 2.5 17.2 3 17.7C3.4 18.1 4.1 18.2 4.6 17.7L17.3 4.9C17.7 4.4 17.7 3.7 17.3 3.3ZM6.7 12.3L5.4 13.6C4.2 12.9 3.1 11.9 2.3 10.7C3.5 9 5.1 7.8 7 7.2C5.7 8.6 5.6 10.8 6.7 12.3ZM10.1 9C9.6 8.5 9.7 7.7 10.2 7.2C10.7 6.8 11.4 6.8 11.9 7.2L10.1 9ZM18.3 9.5C17.8 8.8 17.2 8.1 16.5 7.6L15.5 8.6C16.3 9.2 17 9.9 17.6 10.8C15.9 13.4 13 15 9.9 15H9.1L8.1 16C8.8 15.9 9.4 16 10 16C13.3 16 16.4 14.4 18.3 11.7C18.6 11.3 18.8 10.9 19.1 10.5C18.8 10.2 18.6 9.8 18.3 9.5ZM14 10L10 14C12.2 14 14 12.2 14 10Z" fill="%23111111"/></svg>') center / 20px 20px no-repeat; mask: url('data:image/svg+xml,<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M17.3 3.3C16.9 2.9 16.2 2.9 15.7 3.3L13.3 5.7C12.2437 5.3079 11.1267 5.1048 10 5.1C6.2 5.2 2.8 7.2 1 10.5C1.2 10.9 1.5 11.3 1.8 11.7C2.6 12.8 3.6 13.7 4.7 14.4L3 16.1C2.6 16.5 2.5 17.2 3 17.7C3.4 18.1 4.1 18.2 4.6 17.7L17.3 4.9C17.7 4.4 17.7 3.7 17.3 3.3ZM6.7 12.3L5.4 13.6C4.2 12.9 3.1 11.9 2.3 10.7C3.5 9 5.1 7.8 7 7.2C5.7 8.6 5.6 10.8 6.7 12.3ZM10.1 9C9.6 8.5 9.7 7.7 10.2 7.2C10.7 6.8 11.4 6.8 11.9 7.2L10.1 9ZM18.3 9.5C17.8 8.8 17.2 8.1 16.5 7.6L15.5 8.6C16.3 9.2 17 9.9 17.6 10.8C15.9 13.4 13 15 9.9 15H9.1L8.1 16C8.8 15.9 9.4 16 10 16C13.3 16 16.4 14.4 18.3 11.7C18.6 11.3 18.8 10.9 19.1 10.5C18.8 10.2 18.6 9.8 18.3 9.5ZM14 10L10 14C12.2 14 14 12.2 14 10Z" fill="%23111111"/></svg>') center / 20px 20px no-repeat; }
.opcw .opcw-login .show-password-input.display-password::before { -webkit-mask-image: url('data:image/svg+xml,<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18.3 9.49999C15 4.89999 8.50002 3.79999 3.90002 7.19999C2.70002 8.09999 1.70002 9.29999 0.900024 10.6C1.10002 11 1.40002 11.4 1.70002 11.8C5.00002 16.4 11.3 17.4 15.9 14.2C16.8 13.5 17.6 12.8 18.3 11.8C18.6 11.4 18.8 11 19.1 10.6C18.8 10.2 18.6 9.79999 18.3 9.49999ZM10.1 7.19999C10.6 6.69999 11.4 6.69999 11.9 7.19999C12.4 7.69999 12.4 8.49999 11.9 8.99999C11.4 9.49999 10.6 9.49999 10.1 8.99999C9.60003 8.49999 9.60003 7.69999 10.1 7.19999ZM10 14.9C6.90002 14.9 4.00002 13.3 2.30002 10.7C3.50002 8.99999 5.10002 7.79999 7.00002 7.19999C6.30002 7.99999 6.00002 8.89999 6.00002 9.89999C6.00002 12.1 7.70002 14 10 14C12.2 14 14.1 12.3 14.1 9.99999V9.89999C14.1 8.89999 13.7 7.89999 13 7.19999C14.9 7.79999 16.5 8.99999 17.7 10.7C16 13.3 13.1 14.9 10 14.9Z" fill="%23111111"/></svg>'); mask-image: url('data:image/svg+xml,<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18.3 9.49999C15 4.89999 8.50002 3.79999 3.90002 7.19999C2.70002 8.09999 1.70002 9.29999 0.900024 10.6C1.10002 11 1.40002 11.4 1.70002 11.8C5.00002 16.4 11.3 17.4 15.9 14.2C16.8 13.5 17.6 12.8 18.3 11.8C18.6 11.4 18.8 11 19.1 10.6C18.8 10.2 18.6 9.79999 18.3 9.49999ZM10.1 7.19999C10.6 6.69999 11.4 6.69999 11.9 7.19999C12.4 7.69999 12.4 8.49999 11.9 8.99999C11.4 9.49999 10.6 9.49999 10.1 8.99999C9.60003 8.49999 9.60003 7.69999 10.1 7.19999ZM10 14.9C6.90002 14.9 4.00002 13.3 2.30002 10.7C3.50002 8.99999 5.10002 7.79999 7.00002 7.19999C6.30002 7.99999 6.00002 8.89999 6.00002 9.89999C6.00002 12.1 7.70002 14 10 14C12.2 14 14.1 12.3 14.1 9.99999V9.89999C14.1 8.89999 13.7 7.89999 13 7.19999C14.9 7.79999 16.5 8.99999 17.7 10.7C16 13.3 13.1 14.9 10 14.9Z" fill="%23111111"/></svg>'); }

/* Field helper line (`description`): always visible, under the control (the label stays
   centred on the input: .opcw-field__lbl above). */
.opcw .opcw-field__desc { display: block; margin: 5px 2px 0; font-size: 12.5px; line-height: 1.4; color: var(--opcw-muted); }
.opcw .opcw-field__desc a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

/* Inline errors: WooCommerce's own line (9.6+) looks like ours in case it shows;
   an invalid + focused control takes the error ring. */
.opcw .checkout-inline-error-message { display: block; margin: 5px 2px 0; padding: 0; font-size: 12.5px; line-height: 1.4; color: var(--opcw-error); }
.opcw .form-row.woocommerce-invalid .opcw-input:focus,
.opcw .form-row.woocommerce-invalid input.input-text:focus,
.opcw .form-row.woocommerce-invalid select:focus { border-color: var(--opcw-error); box-shadow: var(--opcw-focus-error); }

/* Segmented radio (field type radio): a top label + one bordered group of real,
   visually hidden radios; the checked option takes the primary fill. */
.opcw .opcw-field--radio > .opcw-field__lbl { position: static; top: auto; transform: none; display: block; max-width: none;
	margin: 0 0 6px; padding: 0; font-size: 12px; font-weight: 500; letter-spacing: .01em; line-height: 1.4;
	color: var(--opcw-muted); white-space: normal; pointer-events: auto; }
.opcw .opcw-seg { margin: 0; padding: 0; position: relative; display: inline-flex; max-width: 100%; vertical-align: top;
	border: 1px solid var(--opcw-line); border-radius: var(--opcw-radius-sm);
	background: var(--opcw-surface); box-shadow: var(--opcw-shadow); overflow: hidden; }
.opcw-seg:focus { outline: none; }
.opcw .opcw-seg > .opcw-seg__input { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0;
	overflow: hidden; clip-path: inset(50%); border: 0; opacity: 0; appearance: none !important; -webkit-appearance: none !important; }
.opcw .opcw-seg > .opcw-seg__opt { float: none; width: auto; display: inline-flex; align-items: center; justify-content: center; min-width: 72px; height: 44px;
	padding: 0 18px; margin: 0; font-size: 14.5px; font-weight: 500; line-height: 1; color: var(--opcw-muted);
	white-space: nowrap; cursor: pointer; user-select: none; -webkit-tap-highlight-color: transparent;
	border-inline-start: 1px solid var(--opcw-line); transition: background .12s, color .12s; }
.opcw .opcw-seg > .opcw-seg__input:first-child + .opcw-seg__opt { border-inline-start: 0; }
.opcw .opcw-seg > .opcw-seg__opt:hover { color: var(--opcw-ink); background: color-mix(in srgb, var(--opcw-ink) 3%, var(--opcw-surface)); }
.opcw .opcw-seg > .opcw-seg__input:checked + .opcw-seg__opt { color: var(--opcw-primary-ink); background: var(--opcw-primary); border-color: var(--opcw-primary); }
.opcw .opcw-seg > .opcw-seg__input:checked + .opcw-seg__opt + .opcw-seg__input + .opcw-seg__opt { border-inline-start-color: var(--opcw-primary); }
.opcw .opcw-seg > .opcw-seg__input:focus-visible + .opcw-seg__opt { outline: 2px solid var(--opcw-accent); outline-offset: -2px; position: relative; z-index: 1; }
.opcw .opcw-seg > .opcw-seg__input:checked:focus-visible + .opcw-seg__opt { outline-color: var(--opcw-primary-ink); outline-offset: -4px; }
.opcw .opcw-seg > .opcw-seg__input:disabled + .opcw-seg__opt { color: var(--opcw-faint); background: var(--opcw-bg-summary); cursor: default; }
.opcw .form-row.woocommerce-invalid .opcw-seg { border-color: var(--opcw-error); }
@media (max-width: 480px) {
	.opcw .opcw-seg { display: flex; width: 100%; }
	.opcw .opcw-seg > .opcw-seg__opt { flex: 1 1 0; min-width: 0; padding: 0 10px; overflow: hidden; text-overflow: ellipsis; }
	.opcw-seg__opt > span { overflow: hidden; text-overflow: ellipsis; }
}

/* Third-party rows floated next to our grid rows (form-row-first / -last printed on
   the WooCommerce hooks): a grid row starts below them instead of squeezing between. */
.opcw .woocommerce-additional-fields > .opcw-row,
.opcw .woocommerce-additional-fields > .opcw-quiet,
.opcw #opcw-shipping-fields > .opcw-row,
.opcw #opcw-shipping-fields > .opcw-quiet,
.opcw .woocommerce-billing-fields__field-wrapper > .opcw-row,
.opcw .woocommerce-billing-fields__field-wrapper > .opcw-quiet { clear: both; }

@media (prefers-reduced-motion: reduce) {
	.opcw .opcw-seg > .opcw-seg__opt { transition: none; }
}

/* ============================================================
   4.2 — summary, coupon, pay total, mobile bar
   ============================================================ */

/* Unit price (summary_unit_price): "qty × unit" under the name, WooCommerce's
   own <del>/<ins> (or a pricing plugin's <s>/<strong>) as delivered. */
.opcw-item__unit { display: block; margin-top: 2px; font-size: 12px; line-height: 1.4; color: var(--opcw-muted); font-variant-numeric: tabular-nums; }
.opcw-item__unit-price { white-space: nowrap; }
.opcw-item__unit del, .opcw-item__unit s { color: var(--opcw-muted); text-decoration: line-through; margin-inline-end: 3px; }
.opcw-item__unit ins, .opcw-item__unit strong { text-decoration: none; font-weight: 500; color: var(--opcw-text); }
.opcw-item__price { text-align: end; }
.opcw-item__price del, .opcw-item__price s { display: block; font-weight: 400; color: var(--opcw-muted); text-decoration: line-through; margin-bottom: 1px; }
.opcw-item__price ins { text-decoration: none; }

/* Coupon block (OPCW_Checkout::coupon_html, Block Mode CouponArea): static,
   between the items and the totals of each summary copy. The toggle is the
   quiet-link idiom with the tag glyph; once open it steps aside. */
.opcw-coupon-wrap { margin: calc(var(--opcw-sum-gap, 14px) - 4px) 0 0; }
.opcw .opcw-coupon__toggle { display: inline-flex; align-items: center; gap: 7px; width: auto; height: auto; min-height: 0; margin: 2px 2px 4px; padding: 4px 0;
	border: 0; border-radius: 0; background: none; box-shadow: none; font-family: inherit; font-size: 13px; font-weight: 400; line-height: 1.4;
	letter-spacing: 0; text-transform: none; color: var(--opcw-muted); text-decoration: underline; text-underline-offset: 2px;
	text-decoration-thickness: 1px; cursor: pointer; transition: color .12s; }
.opcw .opcw-coupon__toggle:hover { background: none; color: var(--opcw-ink); text-decoration-thickness: 2px; }
.opcw-coupon__toggle svg { width: 14px; height: 14px; flex: none; }
.opcw .opcw-coupon__toggle[aria-expanded="true"] { display: none; }
.opcw-coupon__panel[hidden] { display: none; }
/* wc-checkout.js slideUp()s form.checkout_coupon after every apply / removal
   (and hide()s it at init): the form stays where it is, its panel decides. */
.opcw .opcw-coupon-wrap form.opcw-coupon { height: auto !important; overflow: visible !important; margin: 6px 0 4px !important; padding: 0 !important; }
/* The coupon field keeps its compact 46px box beside the 46px button: since 4.2 the input
   also carries .input-text, so .opcw-field input.input-text (0,2,1) outranked the 4.1
   .opcw-coupon .opcw-input (0,2,0) and the pair rendered 54 / 46. */
.opcw .opcw-coupon .opcw-field .opcw-input,
.opcw .opcw-coupon .opcw-field input.input-text { height: 46px; padding: 18px 14px 3px; box-shadow: none; }
/* …and keeps the focus ring of every other field: the reset above (0,4,x) outranked
   .opcw-field .opcw-input:focus (0,3,x), so a keyboard user saw no focus at all. */
.opcw .opcw-coupon .opcw-field .opcw-input:focus,
.opcw .opcw-coupon .opcw-field input.input-text:focus { border-color: var(--opcw-line-strong); box-shadow: var(--opcw-focus); }
/* invalid + focused: the error ring, as on the address fields (an ink ring over the red
   border read as a two-tone frame). */
.opcw .opcw-coupon .opcw-input.has-error:focus,
.opcw .opcw-coupon input.input-text.has-error:focus { border-color: var(--opcw-error); box-shadow: var(--opcw-focus-error); }
/* Secondary look that survives theme button rules (a leaked
   `.woocommerce button.button` painted it like the pay button). */
.opcw .opcw-coupon .opcw-coupon__btn,
.opcw .opcw-coupon button.opcw-coupon__btn { height: 46px; min-height: 0; padding: 0 18px; line-height: 1;
	background: var(--opcw-surface) !important; color: var(--opcw-muted) !important;
	border: 1px solid var(--opcw-line) !important; border-radius: var(--opcw-radius-sm) !important; box-shadow: none !important;
	font-size: 13px; font-weight: 600; letter-spacing: 0; text-transform: none !important; }
.opcw .opcw-coupon .opcw-coupon__btn:hover { color: var(--opcw-ink) !important; border-color: var(--opcw-line-strong) !important; background: var(--opcw-surface) !important; }
.opcw .opcw-coupon .opcw-coupon__btn:disabled { opacity: .6; cursor: wait; }

/* Applied coupons as chips (first child of the totals half); the totals
   row keeps WooCommerce's amount, its own remove link is now the chip. */
.opcw-chips { list-style: none; margin: 4px 0 2px; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.opcw-chip { display: inline-flex; align-items: center; gap: 6px; height: 28px; margin: 0; padding-block: 0; padding-inline: 10px 3px;
	border: 1px solid var(--opcw-line); border-radius: var(--opcw-radius-sm); background: var(--opcw-surface);
	font-size: 12.5px; font-weight: 600; line-height: 1; color: var(--opcw-ink); letter-spacing: .02em; }
.opcw-chip__icon { display: inline-flex; color: var(--opcw-muted); }
.opcw-chip__icon svg { width: 13px; height: 13px; flex: none; }
.opcw-chip__code { text-transform: uppercase; font-variant-numeric: tabular-nums; }
.opcw .opcw-chip__x { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; margin: 0;
	border-radius: calc(var(--opcw-radius-sm) - 2px); color: var(--opcw-muted); text-decoration: none; transition: color .12s, background-color .12s; }
.opcw-chip__x svg { width: 12px; height: 12px; }
.opcw .opcw-chip__x:hover { color: var(--opcw-error); background: color-mix(in srgb, var(--opcw-ink) 6%, var(--opcw-surface)); text-decoration: none; }
.opcw .opcw-chip__x:focus-visible { outline-offset: -2px; } /* inside the 22px button, as the qty stepper's ring */
.opcw-chip.is-busy { opacity: .5; pointer-events: none; }
.opcw-chips:empty { display: none; }
.opcw-chips ~ .opcw-totals .opcw-totals__row--coupon .woocommerce-remove-coupon { display: none; }

/* "Total" above the pay button (pay_total): the summary's grand row, in the
   native place-order block after the terms. The VAT note is WooCommerce's
   own small.includes_tax, in --opcw-muted (AA on the white main column).
   Classic wraps it in div.opcw-paytotal-live (its own fragment), which
   takes no box of its own. */
.opcw-paytotal-live { display: contents; }
.opcw .opcw-paytotal { display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
	margin: 18px 0 0; padding-top: 14px; border-top: 1px solid var(--opcw-line); }
.opcw-paytotal__label { font-size: 15px; font-weight: 600; color: var(--opcw-ink); }
.opcw-paytotal__amount { text-align: end; font-family: var(--opcw-font-display); font-weight: var(--opcw-fw-display); font-size: 22px; line-height: 1.2;
	color: var(--opcw-ink); font-variant-numeric: tabular-nums; }
.opcw-paytotal__amount strong { font-weight: inherit; }
.opcw-paytotal__amount .includes_tax { display: block; margin-top: 2px; font-family: var(--opcw-font); font-size: 11.5px; font-weight: 400; color: var(--opcw-muted); }
.opcw .opcw-paytotal ~ .opcw-btn-primary, .opcw .opcw-paytotal ~ #place_order,
.opcw .opcw-paytotal-live:has(> .opcw-paytotal) ~ .opcw-btn-primary, .opcw .opcw-paytotal-live:has(> .opcw-paytotal) ~ #place_order { margin-top: 16px; }

/* Mobile summary bar: first-item thumb with the count badge, "Show / Hide
   order summary" (switched by .is-open), the item count, the total. */
.opcw-msummary__hide { display: none; }
.opcw-msummary.is-open .opcw-msummary__show { display: none; }
.opcw-msummary.is-open .opcw-msummary__hide { display: inline; }
@media (max-width: 999px) {
	.opcw-msummary__bar { min-height: 64px; padding: 10px 20px; gap: 12px; text-align: start; }
	.opcw-msummary__bar .lbl { gap: 12px; min-width: 0; color: var(--opcw-ink); }
	.opcw-msummary__thumb { position: relative; width: 40px; height: 40px; flex: none; border: 1px solid var(--opcw-line);
		border-radius: var(--opcw-radius-sm); background: var(--opcw-surface); }
	.opcw-msummary__thumb:empty { display: none; }
	.opcw-msummary__thumb img { width: 100%; height: 100%; object-fit: contain; border-radius: inherit; display: block; }
	.opcw-msummary__thumb .opcw-item__qty { top: -6px; right: auto; inset-inline-end: -6px; }
	.opcw-msummary__txt { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; min-width: 0; max-width: 100%; text-align: start; }
	/* One line at any width ("Bestellübersicht ausblenden" beside a long total at 390px):
	   the label gives way with an ellipsis before it wraps, the chevron stays. */
	.opcw-msummary__title { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; min-width: 0; font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--opcw-ink); white-space: nowrap; }
	.opcw-msummary__show, .opcw-msummary.is-open .opcw-msummary__hide { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
	.opcw-msummary__count { font-size: 12px; line-height: 1.3; color: var(--opcw-muted); }
	.opcw-msummary__bar b { font-family: var(--opcw-font-display); font-weight: var(--opcw-fw-display); font-size: 17px; color: var(--opcw-ink);
		white-space: nowrap; font-variant-numeric: tabular-nums; }
	.opcw-msummary__bar svg { width: 16px; height: 16px; color: var(--opcw-muted); flex: none; }
	.opcw-msummary.is-open .opcw-msummary__bar { box-shadow: inset 0 -1px 0 var(--opcw-line); }
	.opcw-msummary__body { padding-top: 10px; }
}

@media (prefers-reduced-motion: reduce) {
	.opcw .opcw-coupon__toggle, .opcw .opcw-chip__x, .opcw-msummary__bar svg { transition: none; }
}

/* ============================================================
   4.2 — shipping options & footer
   ============================================================ */
/* "More shipping options" (opcw_shipping_rate_primary, both engines): the
   hidden rates stay in DOM order. Inside a collapsible group the row lines
   are drawn on top of every visible row that has a visible predecessor, so a
   hidden last row never leaves a doubled or missing edge. No animation: the
   list is a fragment and would replay it on every address change. */
.opcw-options--collapsible .opcw-option { border-bottom: 0; }
.opcw-options--collapsible .opcw-option:not([hidden]) ~ .opcw-option:not([hidden]) { border-top: 1px solid var(--opcw-line); }
.opcw .opcw-ship-more,
.opcw button.opcw-pm-more { display: inline-flex; align-items: center; gap: 6px; margin: 10px 2px 0; padding: 2px 0; min-height: 24px; }
.opcw .opcw-ship-more svg,
.opcw button.opcw-pm-more svg { width: 12px; height: 12px; flex: none; }
.opcw .opcw-ship-more[aria-expanded="true"] svg:first-of-type,
.opcw .opcw-ship-more[aria-expanded="false"] svg:last-of-type,
.opcw button.opcw-pm-more[aria-expanded="true"] svg:first-of-type,
.opcw button.opcw-pm-more[aria-expanded="false"] svg:last-of-type { display: none; }
/* "More payment options" (4.6, opcw_payment_gateway_primary, both engines):
   the same rules for the payment list. A hidden row stays hidden whatever a
   gateway's CSS sets on its li; the row lines follow the visible rows. */
.opcw #payment ul.wc_payment_methods > li.opcw-pm-more[hidden] { display: none !important; }
.opcw #payment ul.wc_payment_methods:has(> li.opcw-pm-more) > li { border-bottom: 0; }
.opcw #payment ul.wc_payment_methods:has(> li.opcw-pm-more) > li:not([hidden]) ~ li:not([hidden]) { border-top: 1px solid var(--opcw-line); }

/* Footer: the buffered opcw_footnav_links output of Block Mode sits in a
   wrapper that takes no box, so its links line up like the classic ones. */
.opcw-footnav__extra { display: contents; }

/* ============================================================
   4.2 — header, headings, autocomplete icon
   ============================================================ */

/* Header rating (opcw_header_rating; pro: the Content tab's rating) — five
   stars filled to --opcw-rating in --opcw-star (default: the accent), then
   "4.8/5 · text". On desktop it opens the right-hand group before the USPs
   (the secure badge keeps its middle place); on phones it is the first line
   of the strip under the logo row. */
.opcw-header__rating { display: inline-flex; align-items: center; gap: 6px; min-width: 0; margin-inline-start: auto;
	font-size: 12px; color: var(--opcw-muted); white-space: nowrap; }
.opcw-header__in:has(> .opcw-header__rating) > .opcw-header__secure { margin-inline-start: auto; }
.opcw-header__rating + .opcw-header__usps { margin-inline-start: 2px; }
.opcw-stars { display: inline-block; flex: none; width: 64px; height: 12px;
	background: linear-gradient(to right, var(--opcw-star, var(--opcw-accent)) var(--opcw-rating, 100%), var(--opcw-line) 0);
	-webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m12 2 3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2Z"/></svg>') left center / 12px 12px space no-repeat;
	mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m12 2 3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2Z"/></svg>') left center / 12px 12px space no-repeat; }
html[dir="rtl"] .opcw-stars { transform: scaleX(-1); } /* fill from the inline start */
.opcw-header__rating-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.opcw-header__rating-text::before { content: "·"; content: "·" / ""; margin-inline-end: 6px; }
@media (max-width: 899px) {
	.opcw-header__rating { flex-basis: 100%; margin: -8px 0 0; padding-bottom: 11px; white-space: normal; }
	.opcw-header__rating + .opcw-header__usps { margin-top: -7px; margin-inline-start: 0; } /* 4px between the two lines */
	.opcw-header__rating-text { overflow: visible; }
}

/* Section headings (section_heading): 'inline' puts a muted step number in
   the title ("2. Delivery address"), 'title' shows the title alone. */
.opcw-section__heading { min-width: 0; }
.opcw-h2__num { color: var(--opcw-muted); font-variant-numeric: tabular-nums; }

/* Address autocomplete: a magnifier in the street field while suggestions
   are live (.opcw-field--ac; opcw_autocomplete_icon). Centred on the input,
   not the row, so an inline error under the field never moves it. */
.opcw .opcw-field--ac .opcw-input,
.opcw .opcw-field--ac input.input-text { padding-inline-end: 44px; }
.opcw .opcw-field--ac .opcw-field__lbl { max-width: calc(100% - 60px); }
.opcw .opcw-field.opcw-field--ac::after { content: ""; display: block; position: absolute; inset-inline-end: 15px; top: calc(var(--opcw-field-h) / 2);
	width: 16px; height: 16px; margin: -8px 0 0; padding: 0; border: 0; clear: none; pointer-events: none;
	background: var(--opcw-muted); transition: background .12s;
	-webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>') center / contain no-repeat;
	mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>') center / contain no-repeat; }
.opcw .opcw-field.opcw-field--ac:has(.opcw-input:focus)::after,
.opcw .opcw-field.opcw-field--ac.is-focused::after { background: var(--opcw-ink); }
@media (prefers-reduced-motion: reduce) {
	.opcw .opcw-field.opcw-field--ac::after { transition: none; }
}

/* ============================================================
   4.5 — right-to-left (html[dir="rtl"]: Arabic, Hebrew, Persian …)
   Mirrors the physical left/right of the fields, option cards,
   payment methods and notices; the split layout and the order
   summary mirror in their own region. LTR is untouched.
   ============================================================ */
/* Select chevron at the inline end, the value clear of it (the !important armor above is LTR). */
html[dir="rtl"] .opcw .opcw-field select {
	padding: 18px 14px 0 36px !important;
	background-position: left 14px center !important;
}
html[dir="rtl"] .opcw .form-row:not(.opcw-field) select { padding: 0 14px 0 36px; background-position: left 14px center; }
html[dir="rtl"] .opcw .select2-container .select2-selection__rendered { padding-left: 0; padding-right: 14px; }
/* Address suggestions */
html[dir="rtl"] .opcw-ac, html[dir="rtl"] .opcw-ac__item { text-align: right; }
html[dir="rtl"] .opcw-ac__attr { right: auto; left: 14px; text-align: left; }
/* Selected option card: the accent bar on the inline-start edge */
html[dir="rtl"] .opcw-option.is-selected .opcw-option__row,
html[dir="rtl"] .opcw-billing:not(.opcw-billing--js) .opcw-billing__options > .opcw-option:has(input:checked) .opcw-option__row { box-shadow: inset -3px 0 0 var(--opcw-accent); }
/* Payment methods: the radio, the label and description insets, the logo and the accent bar */
html[dir="rtl"] .opcw #payment ul.wc_payment_methods li > input[type="radio"] { left: auto; right: 16px; }
html[dir="rtl"] .opcw #payment ul.wc_payment_methods li > label { padding: 15px 46px 15px 44px; }
html[dir="rtl"] .opcw #payment ul.wc_payment_methods li > label img { margin-left: 0; margin-right: auto; }
html[dir="rtl"] .opcw #payment ul.wc_payment_methods li:only-child > label { padding-left: 44px; padding-right: 16px; }
html[dir="rtl"] .opcw #payment ul.wc_payment_methods li.opcw-pm-selected::before { inset: 0 0 0 auto; }
html[dir="rtl"] .opcw #payment ul.wc_payment_methods > li > div.payment_box { padding: 4px 46px 16px 16px !important; }
html[dir="rtl"] .opcw #payment ul.wc_payment_methods > li:only-child > div.payment_box { padding-right: 16px !important; }
@media (max-width: 480px) {
	html[dir="rtl"] .opcw #payment ul.wc_payment_methods > li > div.payment_box:has(fieldset) { padding-right: 16px !important; }
}
/* Notices: the type accent on the inline-start edge */
html[dir="rtl"] .opcw .woocommerce-error,
html[dir="rtl"] .opcw .woocommerce-message,
html[dir="rtl"] .opcw .woocommerce-info { border-left-width: 1px; border-left-color: var(--opcw-line); border-right: 3px solid var(--opcw-error); }
html[dir="rtl"] .opcw .woocommerce-message { border-right-color: var(--opcw-success); }
html[dir="rtl"] .opcw .woocommerce-info { border-right-color: var(--opcw-accent); }
html[dir="rtl"] .opcw .opcw-notice__close { margin: -1px 0 -1px -6px; }
html[dir="rtl"] .opcw .wc-block-components-notice-banner { border-left-width: 1px; border-left-color: var(--opcw-line); border-right: 3px solid var(--opcw-error); }
html[dir="rtl"] .opcw .wc-block-components-notice-banner.is-error { border-left-color: var(--opcw-line); border-right-color: var(--opcw-error); }
html[dir="rtl"] .opcw .wc-block-components-notice-banner.is-success { border-left-color: var(--opcw-line); border-right-color: var(--opcw-success); }
html[dir="rtl"] .opcw .wc-block-components-notice-banner.is-info,
html[dir="rtl"] .opcw .wc-block-components-notice-banner.is-warning { border-left-color: var(--opcw-line); border-right-color: var(--opcw-accent); }
/* Phone numbers read left to right (the browser keeps the value LTR), but the
   value sits at the inline start like every other field, under its label. */
html[dir="rtl"] .opcw .opcw-field input[type="tel"] { direction: ltr; text-align: right; }
/* Back-to-shop link: the arrow points to the inline start */
html[dir="rtl"] .opcw-back { padding: 0 10px 0 13px; }
html[dir="rtl"] .opcw-back svg { transform: scaleX(-1); }

/* ============================================================
   Foldables (4.6.0, #106): three contexts, all scoped to the checkout
   page (body.opcw--checkout; the thank-you page keeps its layout).
   Desktop (>= 1000px, one segment) and phones (< 700px) are untouched:
   every rule below lives inside a media query that cannot match there.

   A. Mid split  700–999px wide, >= 480px tall, one segment: the unfolded
      inner screen held flat (and tablets in portrait, narrow windows).
      The order summary shows next to the form (as on desktop) in a
      narrower column instead of the collapsed accordion bar; from 900px
      the two columns are equal, so on a 933–951px inner screen the
      divider sits on the physical crease without any API (iPhone Duo).
   B. Book       (horizontal-viewport-segments: 2): the device half-open
      with a vertical hinge. Form in segment 0, order summary in
      segment 1, the crease is the column divider; nothing sits on it.
   C. Tabletop   (vertical-viewport-segments: 2): half-open with a
      horizontal hinge. The form scrolls in the top segment; the bottom
      segment is a fixed "deck" with the order summary and the total.

   Only --opcw-* tokens and logical properties; the split mirrors on RTL
   sites and with the pro "Order summary side: Left"
   (OPCW_Design::token_css() prints the option's border/padding swap for
   these contexts too, and for the asymmetric 700–899px tier the mirrored
   tracks `clamp(340px,40vw,400px) minmax(0,1fr)`). Specificity scheme
   for the column rules (grid-template-columns): the mid split's carry
   one extra class (.opcw-shell, 0,3,0) so that the option's desktop
   `460px minmax(0,1fr)` (0,2,0, printed after this file) cannot pull a
   column across the crease, and the option's mirrored tracks for the
   mid split are printed at the same 0,3,0 after this file, so they win
   by order; the book and tabletop tracks carry the class twice
   (.opcw-shell.opcw-shell, 0,4,0): a Pixel in book at 791x710 or in
   tabletop at 820x721 matches the width query too, and there the
   segments (or the single column) must stay. Everything else stays at
   0,3,0 (the column's own border/padding, no .opcw-shell) so the
   option's border/padding swap (0,3,0, after this file) and skins keep
   winning; only the deck's padding/border (tabletop, below) carries
   .opcw-shell too, as the deck has no side. The
   same three queries are OPCW_Design::SPLIT_MEDIA (summary-fit.js and
   the Block Mode extension host read it), keep them in step.
   ============================================================ */

/* ---------- A + B: the summary column next to the form ---------- */
@media (min-width: 700px) and (max-width: 999px) and (min-height: 480px), (horizontal-viewport-segments: 2) {
	/* The accordion bar and the in-form perks panel belong to the single
	   column: the column has the real summary and the perks. */
	:where(.opcw--checkout) .opcw-msummary { display: none; }
	:where(.opcw--checkout) .opcw-sum__perks--panel.opcw-sum__perks--m { display: none; }

	:where(.opcw--checkout) .opcw-layout:not(.opcw-layout--single) > .opcw-main {
		max-width: none; margin: 0; justify-self: stretch;
		padding-block: 28px 56px; padding-inline: 24px 28px;
		/* the two-up rows read their own column, not the viewport (below) */
		container-type: inline-size; container-name: opcw-main;
	}
	:where(.opcw--checkout) .opcw-layout:not(.opcw-layout--single) > .opcw-summary {
		display: block;
		padding-block: 28px 40px; padding-inline: 28px 24px;
		/* the item rows read the column's width (below) */
		container-type: inline-size; container-name: opcw-summary;
	}
	/* Stuck as on desktop, a 20px top for the shorter screens. "Sticky
	   order summary: off" (body.opcw--summary-static) still wins: its rule
	   has the higher specificity. */
	:where(.opcw--checkout) .opcw-summary__sticky { top: 20px; }

	/* Without the height-aware summary (opcw_summary_fit false; body
	   without opcw--summary-fit) the column is a flex column capped to the
	   viewport, so the totals never leave the screen: when the items do not
	   fit, only the items list scrolls (the 4.4 fallback, as the desktop
	   rule at min-width: 1000px). With summary-fit.js (the default) the
	   column must keep its natural height: the script measures it and sets
	   is-compact / is-tight / is-overflowing in these contexts too. */
	:where(body:not(.opcw--summary-fit).opcw--checkout) .opcw-summary__sticky {
		display: flex; flex-direction: column;
		max-height: calc(100vh - 40px); max-height: calc(100dvh - 40px);
	}
	/* The wrappers may shrink (min-height 0: a flex item's automatic minimum
	   is its whole content, the list included); inside them only the items
	   list gives way, down to one row. .opcw-summary__live clips, so should
	   even that not fit, the progress bar is cut rather than drawn over the
	   coupon and totals. */
	:where(body:not(.opcw--summary-fit).opcw--checkout) .opcw-summary__sticky > #order_review,
	:where(body:not(.opcw--summary-fit).opcw--checkout) .opcw-summary__sticky .opcw-summary__live {
		display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0;
	}
	:where(body:not(.opcw--summary-fit).opcw--checkout) .opcw-summary__sticky .opcw-summary__live { overflow: hidden; }
	:where(body:not(.opcw--summary-fit).opcw--checkout) .opcw-summary__sticky .opcw-items {
		flex: 1 1 auto; min-height: 76px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin;
		padding: 2px 4px 0; margin-inline: -4px; /* room for the qty badge and focus rings */
	}
	:where(body:not(.opcw--summary-fit).opcw--checkout) .opcw-summary__sticky > .opcw-sum__title,
	:where(body:not(.opcw--summary-fit).opcw--checkout) .opcw-summary__sticky > .opcw-sum__perks,
	:where(body:not(.opcw--summary-fit).opcw--checkout) .opcw-summary__sticky .opcw-progress,
	:where(body:not(.opcw--summary-fit).opcw--checkout) .opcw-summary__sticky .opcw-coupon-wrap,
	:where(body:not(.opcw--summary-fit).opcw--checkout) .opcw-summary__sticky .opcw-summary__totals { flex: none; }
}

/* ---------- A + B + C: the item row in a narrow column ---------- */
/* The editable row (stepper + Remove) needs 193px beside the 64px thumb
   and the price; a 340px column has 142px for it. The stepper never gives
   way (its + button was clipped); the row may wrap as the safety net for
   a long price in any column. In a column whose content box is 360px or
   less (the 340–412px columns of the mid split and the narrower book
   panes) the row is stacked for every item (stepper, Remove under it),
   so the rows read alike whatever their price's width; wider panes (the
   50/50 split, 425–480px book panes) and desktop keep today's one line.
   Container queries measure the content box. */
@media (min-width: 700px) and (max-width: 999px) and (min-height: 480px), (horizontal-viewport-segments: 2), (vertical-viewport-segments: 2) {
	:where(.opcw--checkout) .opcw-summary .opcw-item__edit { flex-wrap: wrap; gap: 6px 12px; }
	:where(.opcw--checkout) .opcw-summary .opcw-qty { flex: none; }
}
@container opcw-summary (max-width: 360px) {
	.opcw .opcw-summary .opcw-item__edit { flex-direction: column; align-items: flex-start; gap: 6px; }
}

/* ---------- A + B: the form column as a container ---------- */
/* Two-up rows (first/last name …) stack when their column is narrower
   than two honest fields; the postcode keeps room for its label
   ("Postcode / ZIP" ellipsized at 110px) in a column under 440px. Outside
   the contexts above .opcw-main is no container and neither ever matches;
   the name is what keeps a skin's container elsewhere from matching. */
@container opcw-main (max-width: 379px) {
	.opcw .opcw-main .opcw-row--2 { grid-template-columns: 1fr; }
}
@container opcw-main (max-width: 440px) {
	.opcw .opcw-main .opcw-row--plz { grid-template-columns: minmax(150px, .8fr) minmax(0, 1.6fr); }
}

/* ---------- A: mid split ---------- */
@media (min-width: 700px) and (max-width: 999px) and (min-height: 480px) {
	/* 340–400px summary column (desktop: 460px); the form takes the rest
	   (316px at 700px, ~500px at 899px). The divider trough is 56px
	   (desktop: 80px). "Order summary side: Left" prints the mirrored
	   tracks for this tier (OPCW_Design::token_css(), same 0,3,0, after
	   this file), so the form keeps the wide column there too. */
	:where(.opcw--checkout) .opcw-shell .opcw-layout:not(.opcw-layout--single) {
		grid-template-columns: minmax(0, 1fr) clamp(340px, 40vw, 400px);
	}
}
/* From 900px the columns are equal: hinge-vertical inner screens are
   symmetric, so on the 933px (Z Fold8) and 951px (iPhone Duo, no segment
   API in Safari) screens the divider lands on the physical crease with
   28px of padding on each side, and the form column is still >= 420px
   inside. The header takes its compact form (USPs hidden as below 900px)
   with the secure badge at the end, so no header text sits mid-screen. */
@media (min-width: 900px) and (max-width: 999px) and (min-height: 480px) {
	:where(.opcw--checkout) .opcw-shell .opcw-layout:not(.opcw-layout--single) { grid-template-columns: 1fr 1fr; }
	:where(.opcw--checkout) .opcw-header__usps { display: none; }
	:where(.opcw--checkout) .opcw-header__secure { margin-inline-start: auto; }
}

/* ---------- A + B + C: one header row ---------- */
/* The phone header (below 900px) stacks the rating and the marked USPs
   under the logo row: three rows on a 700–899px inner screen, which is
   half of a tabletop pane and reads unsettled next to the two columns
   (Gilles on a Magic V3, 2026-10-31). In these contexts the header keeps
   the desktop's single 64px row: back link and logo at the start, the
   rating at the end (ellipsized when short of room), the USPs hidden as
   from 900px. 700px fits back link, logo and rating with room to spare. */
@media (min-width: 700px) and (max-width: 999px) and (min-height: 480px), (horizontal-viewport-segments: 2), (vertical-viewport-segments: 2) {
	:where(.opcw--checkout) .opcw-header .opcw-header__in { flex-wrap: nowrap; height: 64px; min-height: 0; }
	:where(.opcw--checkout) .opcw-header .opcw-header__lead { flex: 0 1 auto; min-height: 0; }
	:where(.opcw--checkout) .opcw-header .opcw-header__usps { display: none; }
	:where(.opcw--checkout) .opcw-header .opcw-header__rating { flex: 0 1 auto; margin: 0; margin-inline-start: auto; padding: 0; white-space: nowrap; }
	:where(.opcw--checkout) .opcw-header .opcw-header__rating-text { overflow: hidden; }
}

/* ---------- B: book posture ---------- */
@media (horizontal-viewport-segments: 2) {
	/* The header spans both segments: its compact form (USPs hidden, as
	   below 900px), the secure badge at the end, so nothing sits on the
	   crease. */
	:where(.opcw--checkout) .opcw-header__in { max-width: none; }
	:where(.opcw--checkout) .opcw-header__usps { display: none; }
	:where(.opcw--checkout) .opcw-header__secure { margin-inline-start: auto; }

	/* Columns = the two segments; the gap = the hinge (0 on a flexible
	   panel, the mask on a dual-screen device). Padding on both sides of
	   the crease: 28px in each pane. Track 1 is always segment 0, whatever
	   sits in it ("Order summary side: Left" puts the summary there with
	   order: -1), so the tracks need no change for that option; the
	   doubled .opcw-shell (0,4,0) keeps the option's mid-split tracks
	   (0,3,0, printed after this file) out of a book-type device. */
	:where(.opcw--checkout) .opcw-shell.opcw-shell .opcw-layout:not(.opcw-layout--single) {
		max-width: none; margin: 0;
		grid-template-columns: env(viewport-segment-width 0 0, 50%) env(viewport-segment-width 1 0, 50%);
		column-gap: calc(env(viewport-segment-left 1 0, 50%) - env(viewport-segment-right 0 0, 50%));
	}
	/* RTL: the inline-start track is the physical right segment (1). The
	   paddings and borders are logical and mirror by themselves. */
	html[dir="rtl"] :where(.opcw--checkout) .opcw-shell.opcw-shell .opcw-layout:not(.opcw-layout--single) {
		grid-template-columns: env(viewport-segment-width 1 0, 50%) env(viewport-segment-width 0 0, 50%);
	}
}
/* Very short book panes (flips half-open, 338–341px): the receipt keeps
   only what the shopper needs beside the form (one or two item rows,
   coupon, totals) and fits under the 64px header at scroll 0 (the 88px:
   header + 24px), so the grand total is in the first screen. The summary
   title and the shipping progress go; the items list may shrink to what
   fits (it scrolls, with the fade below). */
@media (horizontal-viewport-segments: 2) and (max-height: 420px) {
	:where(.opcw--checkout) .opcw-layout:not(.opcw-layout--single) > .opcw-summary { padding-block: 10px 12px; }
	:where(.opcw--checkout) .opcw-summary__sticky { top: 8px; --opcw-sum-gap: 6px; }
	:where(body:not(.opcw--summary-fit).opcw--checkout) .opcw-summary__sticky { max-height: calc(100vh - 88px); max-height: calc(100dvh - 88px); }
	:where(body:not(.opcw--summary-fit).opcw--checkout) .opcw-summary__sticky .opcw-items { min-height: 0; }
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-sum__title,
	:where(.opcw--checkout) .opcw-summary__sticky .opcw-progress { display: none; }
	:where(.opcw--checkout) .opcw-summary__sticky .opcw-coupon-wrap { margin-block: 4px; }
}

/* ---------- A + B + C: the scrolling items list fades at its edges ---------- */
/* A list that scrolls (the fallback above, the deck, or summary-fit's
   is-overflowing) never cuts a row in half without a hint: a 32px fade at
   the edge where more follows, driven by the list's own scroll position
   (no JS, no at-end bookkeeping). The timeline is inactive when the list
   does not scroll, and then there is no mask at all. Browsers without
   scroll-driven animations (every one that matches the segment queries
   has them) get summary-fit's one-sided fade or no fade, as today. */
@property --opcw-items-fade-start { syntax: '<length>'; inherits: false; initial-value: 0px; }
@property --opcw-items-fade-end { syntax: '<length>'; inherits: false; initial-value: 0px; }
@supports (animation-timeline: scroll()) {
	@media (min-width: 700px) and (max-width: 999px) and (min-height: 480px), (horizontal-viewport-segments: 2), (vertical-viewport-segments: 2) {
		:where(.opcw--checkout) .opcw-summary__sticky .opcw-items {
			-webkit-mask-image: linear-gradient(transparent, #000 var(--opcw-items-fade-start), #000 calc(100% - var(--opcw-items-fade-end)), transparent);
			mask-image: linear-gradient(transparent, #000 var(--opcw-items-fade-start), #000 calc(100% - var(--opcw-items-fade-end)), transparent);
			animation: opcw-items-fade linear both; animation-timeline: scroll(self);
		}
		:where(.opcw--checkout) .opcw-summary__sticky .opcw-items[data-opcw-at-end] { -webkit-mask-image: linear-gradient(transparent, #000 var(--opcw-items-fade-start), #000); mask-image: linear-gradient(transparent, #000 var(--opcw-items-fade-start), #000); }
	}
	@keyframes opcw-items-fade {
		0% { --opcw-items-fade-start: 0px; --opcw-items-fade-end: 32px; }
		12%, 88% { --opcw-items-fade-start: 32px; --opcw-items-fade-end: 32px; }
		100% { --opcw-items-fade-start: 32px; --opcw-items-fade-end: 0px; }
	}
}

/* ---------- C: tabletop posture ---------- */
/* The document stays the scroller (WooCommerce's scroll-to-notice and
   focus scrolling keep working); the top segment shows the single phone
   column, the bottom segment is the deck: the order summary with the
   total, fixed to the lower pane. The on-screen keyboard opens over the
   deck while the shopper types, so the focused field stays in the upper
   pane (Gilles, 2026-10-30: the fields belong at the top, the flat part
   with the keyboard at the bottom). */
@media (vertical-viewport-segments: 2) {
	:where(.opcw--checkout) .opcw-msummary { display: none; }
	:where(.opcw--checkout) .opcw-sum__perks--panel.opcw-sum__perks--m { display: none; }

	/* Focus scrolling (Chrome scrolls a focused field into view) and the
	   notice scroll keep clear of the deck. */
	html:has(> body.opcw--checkout) { scroll-padding-bottom: calc(env(viewport-segment-height 0 1, 0px) + 16px); }

	/* Top segment: the single column of the phone layout; the document
	   scrolls behind the deck, so the form (and Pay at its end) can rise
	   fully into the top pane. The column and the deck have no "side": their
	   padding and border rules carry .opcw-shell (0,4,0) so that the pro
	   "Order summary side: Left" swap for the mid split (0,3,0, printed after
	   this file; a book-type device in tabletop is 700–960px wide) cannot
	   reach them, and the single track carries it twice (0,4,0) against the
	   option's mirrored mid-split tracks (0,3,0). */
	:where(.opcw--checkout) .opcw-shell.opcw-shell .opcw-layout:not(.opcw-layout--single) { grid-template-columns: minmax(0, 1fr); }
	:where(.opcw--checkout) .opcw-shell .opcw-layout:not(.opcw-layout--single) > .opcw-main {
		max-width: 640px; margin: 0 auto; justify-self: stretch;
		padding-block: 24px calc(env(viewport-segment-height 0 1, 0px) + 32px); padding-inline: 20px;
	}
	/* An open address-suggestion list sits above the deck (the field's
	   usual z-index 5 is below the deck's 6). */
	:where(.opcw--checkout) .opcw-field:has(.opcw-ac:not([hidden])) { z-index: 7; }

	/* Bottom segment: the deck. Fixed to segment (0,1) exactly (its top is
	   the crease; the env() indices are x then y), above the page; the
	   on-screen keyboard covers it while the shopper types and the form
	   keeps the top pane. */
	:where(.opcw--checkout) .opcw-shell .opcw-layout:not(.opcw-layout--single) > .opcw-summary {
		display: block; position: fixed; z-index: 6; inset-inline: 0; bottom: 0;
		top: env(viewport-segment-top 0 1, 50%);
		border-inline: 0; border-block-start: 1px solid var(--opcw-line);
		padding: 16px 24px 18px; overflow: hidden; box-sizing: border-box;
		/* the deck reads as one dense pane: the compact rhythm of summary-fit's is-compact */
		--opcw-sum-gap: var(--opcw-sum-gap-compact, 10px);
		--opcw-sum-item-pad: var(--opcw-sum-item-pad-compact, 6px);
		--opcw-perks-gap: var(--opcw-perks-gap-compact, 14px);
	}
	:where(.opcw--checkout) .opcw-layout:not(.opcw-layout--single) > .opcw-summary::after { display: none; }

	/* The deck is a pane of fixed height, so this structure applies with
	   and without summary-fit.js (the script stays out of tabletop). Narrow
	   deck (a flip in tabletop, ~410px wide): one column, the items scroll,
	   coupon and totals stay at the bottom; perks visually hidden. */
	:where(.opcw--checkout) .opcw-summary .opcw-summary__sticky {
		position: static; height: 100%; max-height: none; display: flex; flex-direction: column; padding: 0; margin: 0;
	}
	:where(.opcw--checkout) .opcw-summary__sticky > #order_review,
	:where(.opcw--checkout) .opcw-summary__sticky .opcw-summary__live {
		display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0;
	}
	:where(.opcw--checkout) .opcw-summary__sticky .opcw-summary__live { overflow: hidden; }
	:where(.opcw--checkout) .opcw-summary__sticky .opcw-items {
		flex: 1 1 auto; min-height: 76px; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin;
		padding: 2px 4px 0; margin-inline: -4px;
	}
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-sum__title { margin-block-end: 8px; }
	/* The summary's section slots (opcw_before_section / opcw_after_section
	   "summary": trust badges, a note) keep their place, first and last,
	   at their own height: only the items list gives way to them (down to
	   one row); a slot taller than the pane is the merchant's call. */
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-sum__title,
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-slot--summary-before,
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-slot--summary-after,
	:where(.opcw--checkout) .opcw-summary__sticky .opcw-progress,
	:where(.opcw--checkout) .opcw-summary__sticky .opcw-coupon-wrap,
	:where(.opcw--checkout) .opcw-summary__sticky .opcw-summary__totals { flex: none; }
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-slot--summary-before { margin: 0 0 10px; }
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-slot--summary-after { margin: 10px 0 0; }
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-sum__perks { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
		overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
}
/* Wide deck (a book-type device in tabletop, 700–960px wide): the receipt
   in two columns that read as one block each. Left: title, the items
   (they scroll, never grow) with the shipping progress right under them,
   the perks in one row at the foot. Right: the coupon directly above the
   totals, both anchored to the bottom: the grand total is the last thing
   bottom-end, where the thumb rests. The section slots span both columns
   in their own rows, the before-slot above the title and the after-slot
   under everything (an empty row is 0px), so nothing lands in an implicit
   row behind the totals. */
@media (vertical-viewport-segments: 2) and (min-width: 640px) {
	:where(.opcw--checkout) .opcw-summary .opcw-summary__sticky {
		display: grid; column-gap: 36px;
		grid-template-columns: minmax(0, 1fr) clamp(260px, 38%, 340px);
		grid-template-rows: auto auto minmax(0, 1fr) auto auto auto;
		grid-template-areas: "slotb slotb" "title title" "live coupon" "live totals" "perks totals" "slota slota";
	}
	:where(.opcw--checkout) .opcw-summary__sticky > #order_review { display: contents; }
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-slot--summary-before { grid-area: slotb; }
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-slot--summary-after { grid-area: slota; }
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-sum__title { grid-area: title; margin: 0 0 8px; }
	:where(.opcw--checkout) .opcw-summary__sticky .opcw-summary__live { grid-area: live; }
	:where(.opcw--checkout) .opcw-summary__sticky .opcw-items { flex: 0 1 auto; }
	:where(.opcw--checkout) .opcw-summary__sticky .opcw-coupon-wrap { grid-area: coupon; align-self: end; margin: 0 0 10px; }
	:where(.opcw--checkout) .opcw-summary__sticky .opcw-summary__totals { grid-area: totals; align-self: end; }
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-sum__perks {
		grid-area: perks; position: static; width: auto; height: auto; margin: 10px 0 0; padding: 10px 0 0; overflow: visible; clip-path: none; white-space: normal;
		display: flex; flex-wrap: wrap; gap: 6px 18px; border-top: 1px solid var(--opcw-line);
	}
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-sum__perks.opcw-sum__perks--panel { padding: 10px 0 0; border: 0; border-top: 1px solid var(--opcw-line); background: none; box-shadow: none; }
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-sum__perks.opcw-sum__perks--panel .opcw-sum__perks-title { display: none; }
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-sum__perks.opcw-sum__perks--panel .opcw-sum__perks-list { display: flex; flex-wrap: wrap; gap: 6px 18px; }
	:where(.opcw--checkout) .opcw-summary__sticky > .opcw-sum__perks.opcw-sum__perks--panel .opcw-sum__perk-desc { display: none; }
}
