/**
 * woocommerce.css
 * Visual overrides for WooCommerce native elements — buttons, forms, notices,
 * and cart — scoped to WooCommerce pages only via conditional enqueue.
 *
 * Also contains styles for the /nos-vins filter tabs and catalog grid,
 * since those are commerce-context-only components.
 *
 * Targeting strategy: always use WooCommerce's own classes. Never override
 * by element type globally — always scope to .woocommerce or a WC class.
 *
 * @package astra-child
 */

/* ── WooCommerce buttons ─────────────────────────────────────────────────── */

/*
 * WC uses .button on anchor tags and button[type="submit"] on form submits.
 * Both need to match our .porta-btn--primary appearance.
 * #respond input#submit covers the review form submit button.
 */
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit {
  background-color: var(--color-accent);
  color: var(--color-white);
  border: var(--btn-border-width) solid var(--color-accent);
  border-radius: var(--border-radius);
  font-family: var(--font-body);
  font-size: var(--btn-font-size);
  font-weight: var(--btn-font-weight);
  letter-spacing: var(--btn-tracking);
  text-transform: uppercase;
  padding: var(--btn-padding);
  /* Same timing as .porta-btn: the two must look identical (audit 02-019). */
  transition: background-color var(--duration) ease, border-color var(--duration) ease;
}

.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce #respond input#submit:hover {
  background-color: var(--color-accent-dark);
  border-color: var(--color-accent-dark);
  color: var(--color-white);
}

/* ── WooCommerce notices ─────────────────────────────────────────────────── */

/*
 * Unified notice design: warm background + 3px left accent bar.
 * No full border — the left bar is enough to signal the notice type.
 * !important only where a vendor rule competes — border/background (Astra's
 * notice rules) and margin/padding (WooCommerce's); the rest was dropped in
 * audit 02-021 after measuring the rendered notices.
 *
 * Three types:
 *   .woocommerce-message → confirmation (accent burgundy bar)
 *   .woocommerce-info    → neutral info (gold bar)
 *   .woocommerce-error   → error (muted red bar)
 */
.woocommerce-message,
.woocommerce-error,
.woocommerce-info {
  list-style: none;
  /* margin/padding keep !important: WooCommerce's woocommerce.css sets both
     on its notices (48px left padding for its icon) at higher specificity. */
  margin: 0 0 1rem !important;
  padding: 0.85rem 1.25rem !important;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text);
  background-color: var(--color-bg-alt) !important;
  border: none !important;
  border-left: 3px solid var(--color-accent) !important;
  border-radius: 0 var(--border-radius) var(--border-radius) 0;
  box-shadow: none;
  /* Notices are focused programmatically (tabindex="-1") so screen readers
     announce them — they are not tabbable, a visible ring is just noise. */
  outline: none;
}

/*
 * .woocommerce-error and .woocommerce-message are <ul> containing <li> items —
 * flex column stacks multiple validation errors vertically.
 * .woocommerce-info is a <div> with inline text + link, NOT a list.
 * Setting flex-direction:column on it makes the text node and <a> separate
 * flex items that stack, breaking "Déjà client ? Cliquez ici" onto two lines.
 * Fix: info uses display:block so inline content flows naturally on one line.
 */
.woocommerce-message,
.woocommerce-error {
  display: flex !important;
  flex-direction: column !important;
  align-items: stretch !important;
}

.woocommerce-info {
  display: block !important;
  border-left-color: var(--color-gold) !important;
}

.woocommerce-error {
  border-left-color: var(--color-accent) !important;
}

/* Hide WooCommerce's ::before icon glyphs — render as broken characters
   when icon font isn't loaded, and conflict with our left-bar design. */
.woocommerce-message::before,
.woocommerce-info::before,
.woocommerce-error::before {
  display: none !important;
}

.woocommerce-notices-wrapper:not(:empty) {
  margin-bottom: 1rem;
}

/*
 * Notice inner <li>.
 * display: block keeps text left-aligned for both single-line info notices
 * (e.g. "Déjà client ? Cliquez ici") and multi-item validation error lists.
 * Padding adds breathing room between stacked error items.
 */
.woocommerce-message li,
.woocommerce-info li,
.woocommerce-error li {
  display: block !important;
  padding: 0.1rem 0 !important;
}

/* Action links/buttons inside notices — plain inline underlined text, no button styling */
.woocommerce-message a,
.woocommerce-info a,
.woocommerce-error a,
.woocommerce-info button.showcoupon {
  display: inline !important;
  background: none !important;
  border: none !important;
  padding: 0 !important;
  margin: 0 0 0 0.5rem !important;
  box-shadow: none !important;
  font-size: var(--text-sm) !important;
  font-weight: 400 !important;
  color: var(--color-accent) !important;
  text-decoration: underline !important;
  text-underline-offset: 2px !important;
  text-transform: none !important;
  letter-spacing: 0 !important;
}

.woocommerce-message a:hover,
.woocommerce-info a:hover,
.woocommerce-error a:hover,
.woocommerce-info button.showcoupon:hover {
  color: var(--color-gold-text) !important;
  background: none !important;
}

/* button.showcoupon also needs cursor:pointer — not covered by the combined rule above */
.woocommerce-info button.showcoupon {
  cursor: pointer !important;
}

/* ── WooCommerce form inputs ─────────────────────────────────────────────── */

/*
 * Checkout and account forms — consistent input styling aligned with brand.
 */
.woocommerce .input-text,
.woocommerce input[type="text"],
.woocommerce input[type="email"],
.woocommerce input[type="tel"],
.woocommerce input[type="password"],
.woocommerce textarea,
.woocommerce select {
  border: 1px solid var(--color-bg-alt);
  border-radius: var(--border-radius);
  font-family: var(--font-body);
  font-size: var(--text-field);   /* never below 16px — see style.css */
  color: var(--color-text);
  background-color: var(--color-white);
  padding: 0.625rem 0.875rem;
  transition: border-color 0.15s ease;
}

.woocommerce .input-text:focus,
.woocommerce input[type="text"]:focus,
.woocommerce input[type="email"]:focus,
.woocommerce input[type="tel"]:focus,
.woocommerce input[type="password"]:focus,
.woocommerce textarea:focus,
.woocommerce select:focus {
  border-color: var(--color-accent);
  /* The accent border, thickened by a 1px ring (no layout shift), IS the
     focus indicator on form fields — an outline on top would double up.
     The ring matters on the wine page's size/closure selects, whose border
     alone went from beige to burgundy at 1px (audit 09-002). */
  box-shadow: 0 0 0 1px var(--color-accent);
  outline: none;
}

/* ── Empty cart ──────────────────────────────────────────────────────────── */

/*
 * Stack the two buttons vertically on mobile with a proper gap.
 * On desktop they sit inline (flex-row with wrap).
 */
.return-to-shop {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: center;
  margin-top: 1.5rem;
}

@media (max-width: 767px) {
  .return-to-shop {
    flex-direction: column;
    align-items: center;
  }
  .return-to-shop .porta-btn {
    width: 100%;
    max-width: 320px;
    text-align: center;
  }
}

/* ── Cart page ───────────────────────────────────────────────────────────── */

/*
 * Redesigned 2026-10-04 to read as step 1 of the checkout: bottle list on the
 * left, the same beige summary panel on the right (stacked on phones).
 *
 * NO cart.php override — WooCommerce updates that template often (10.1.0 at
 * the time). Layout is CSS on WooCommerce's own markup:
 *   - two columns: a grid on the .woocommerce wrapper that holds the progress
 *     bar, notices, form.woocommerce-cart-form and .cart-collaterals;
 *   - each cart line: a grid on WooCommerce's <tr>.
 * Only the panel's content is overridden (woocommerce/cart/cart-totals.php).
 *
 * WooCommerce's cart.js swaps form.woocommerce-cart-form and .cart_totals
 * after each quantity change — styles target those classes, never wrappers
 * added around them.
 */

/*
 * The "Mettre à jour le panier" button stays in the DOM — cart.js clicks it
 * whenever a quantity changes — but is never shown.
 * !important: Astra's button rules are more specific.
 */
button[name="update_cart"] {
  display: none !important;
}

/* Two columns from 992px — same proportions as the checkout. */
@media (min-width: 992px) {
  .woocommerce:has(> .woocommerce-cart-form) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 25rem);
    column-gap: 4rem;
    align-items: start;
  }
  .woocommerce:has(> .woocommerce-cart-form) > * {
    grid-column: 1 / -1;     /* progress bar, notices: full width */
  }
  .woocommerce:has(> .woocommerce-cart-form) > .woocommerce-cart-form {
    grid-column: 1;
  }
  .woocommerce:has(> .woocommerce-cart-form) > .cart-collaterals {
    grid-column: 2;
  }
}

/* Astra floats the totals box to the right at 48% — the grid places it now. */
.woocommerce-cart .cart-collaterals,
.woocommerce-cart .cart-collaterals .cart_totals {
  float: none;
  width: 100%;
}

/* ── Cart lines ──────────────────────────────────────────────────────────── */

.woocommerce-cart .woocommerce table.shop_table.cart {
  width: 100%;
  margin: 0;
  border: 0;
  border-radius: 0;
  border-collapse: collapse;
  background: transparent;
}

/* Column headers: kept for screen readers, hidden visually. */
.woocommerce-cart .woocommerce table.shop_table.cart thead {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.woocommerce-cart .woocommerce table.shop_table.cart tbody {
  display: block;
  border-top: 1px solid rgba(26, 26, 26, 0.12);
}

/*
 * One line = a grid on WooCommerce's <tr>:
 *
 *   [bottle]  Villette – Les Echelettes – 70cl         [×]
 *             CHF 16.00
 *             [ − 6 + ]                           CHF 96.00
 */
.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item {
  position: relative;      /* the remove button is pinned to the top-right corner */
  display: grid;
  grid-template-columns: 80px minmax(0, 1fr) auto;
  grid-template-areas:
    "thumb name  name"
    "thumb price price"
    "thumb qty   subtotal";
  grid-template-rows: auto auto 1fr;   /* name and price hug the top; the stepper row takes the rest */
  align-content: start;
  align-items: center;
  gap: 0.25rem 1rem;
  padding: 1.25rem 0;
  border-bottom: 1px solid rgba(26, 26, 26, 0.12);
}

.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td {
  display: block;
  height: auto;
  min-height: 0;
  line-height: 1.4;
  padding: 0;
  border: 0;
  background: transparent;
  /* !important: WooCommerce's small-screen sheet right-aligns every responsive
     table cell with !important (and pads its data-title labels). */
  text-align: left !important;
  font-size: var(--text-sm);
  color: var(--color-text);
}

/* Astra gives every cart cell min-height: 3.25em through an id selector
   (`.woocommerce-page #content table.cart td`, 1,2,1), which spread the name
   and the price ~50px apart. An id is needed to undo it. */
.woocommerce-cart #content table.shop_table.cart tr.cart_item td {
  min-height: 0;
}

/* WooCommerce's responsive table prints "Produit :", "Prix :"… before cells. */
.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td::before {
  display: none;
}

.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-thumbnail {
  grid-area: thumb;
  align-self: start;
  width: 80px;
}

/* Two classes + type: .woocommerce-page img { height: auto } (0,1,1) is in play here. */
.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-thumbnail img {
  display: block;
  width: 80px;
  height: 80px;
  padding: 6px;
  box-sizing: border-box;
  object-fit: contain;
  background: var(--color-white);
  border: 1px solid rgba(26, 26, 26, 0.08);
  border-radius: var(--border-radius);
}

.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-name {
  grid-area: name;
  padding-right: 2.75rem;  /* room for the pinned remove button */
  font-size: var(--text-base);
  font-weight: 500;
  line-height: 1.35;
}

.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-name a {
  color: var(--color-text);
  text-decoration: none;
}

.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-name a:hover {
  color: var(--color-accent);
}

.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-name .variation {
  margin: 0.125rem 0 0;
  font-size: var(--text-xs);
  font-weight: 400;
  color: var(--color-text-light);
}

.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-price {
  grid-area: price;
  color: var(--color-text-light);
}

.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-quantity {
  grid-area: qty;
  margin-top: 0.5rem;
}

.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-subtotal {
  grid-area: subtotal;
  margin-top: 0.5rem;
  font-weight: 600;
  text-align: right !important;   /* beats the general cell rule's left !important */
  white-space: nowrap;
}

/* Pinned top-right, out of the grid, so its 44px tap area does not push the
   price away from the name. */
.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-remove {
  position: absolute;
  top: 0.75rem;
  right: -0.625rem;
}

/* Remove: Astra swaps the "×" for its close icon (an SVG) and rings it with a
   ::before circle — keep the icon, drop the ring, size it to the 44px target. */
.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-remove a.remove {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--color-text-light) !important;   /* WooCommerce colours a.remove red with !important */
  font-size: 1.375rem;
  font-weight: 400;
  line-height: 1;
  text-decoration: none;
  transition: background-color var(--duration) ease, color var(--duration) ease;
}

.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-remove a.remove::before {
  display: none;
}

.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-remove a.remove svg {
  width: 18px;
  height: 18px;
}

.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-remove a.remove:hover {
  background: var(--color-bg-alt) !important;
  color: var(--color-accent) !important;
}

/* Stepper: − / qty / + (quantity-stepper.js). 16px so iOS does not zoom on focus. */
.woocommerce-cart-form .quantity {
  display: flex;
  align-items: center;
}

.woocommerce-cart-form .qty {
  width: 3.5rem;
  height: 40px;
  padding: 0;
  text-align: center;
  border: 1px solid var(--color-bg-alt);
  border-radius: 0;
  font-family: var(--font-body);
  font-size: var(--text-field);   /* never below 16px — see style.css */
  color: var(--color-text);
  background: var(--color-white);
}

/* ── Promo code (bottom of the list) ─────────────────────────────────────── */

.woocommerce-cart .woocommerce table.shop_table.cart tr:not(.cart_item) {
  display: block;
}

.woocommerce-cart .woocommerce table.shop_table.cart td.actions {
  display: block;
  padding: 1.25rem 0 0;
  border: 0;
  background: transparent;
}

/* Wraps the button under the field when "Appliquer le code promo" does not
   fit beside it (phones). */
.woocommerce-cart table.shop_table.cart td.actions .coupon {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  float: none;
  width: 100%;
  max-width: 26rem;
  margin: 0;
  padding: 0;
}

.woocommerce-cart table.shop_table.cart td.actions .coupon .input-text {
  flex: 1 1 10rem;
  width: auto;
  min-width: 0;
  height: 44px;
  margin: 0;
  padding: 0 0.875rem;
  font-size: var(--text-field);   /* never below 16px — see style.css */
  border: 1px solid rgba(26, 26, 26, 0.22);
  border-radius: var(--border-radius);
  background: var(--color-white);
}

/* Astra caps the field at 35px with `.woocommerce-page #content table.cart
   [name="coupon_code"]` (1,3,1), and WooCommerce's small-screen sheet sets it
   to width 48% — an id is needed to undo both. Astra's grid sheet also sets
   `height: auto` there (1,2,1): with our zero vertical padding the field
   collapsed to ~22px on phones (audit 09-014), so the height is restated. */
.woocommerce-cart #content table.shop_table.cart [name="coupon_code"] {
  max-height: none;
  width: auto;
  height: var(--tap-size);
  min-height: var(--tap-size);
}

/* A secondary action — hairline, not the solid burgundy of "Passer la commande". */
.woocommerce-cart table.shop_table.cart td.actions .coupon button.button {
  flex: 0 0 auto;
  width: auto;
  height: 44px;
  margin: 0;
  padding: 0 1.125rem;
  background: transparent;
  border: 1px solid var(--color-accent);
  color: var(--color-accent);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  white-space: nowrap;
}

/* Astra's small-screen sheet stretches this button (flex: 1) and shrinks its
   text to ~11px through an id selector, so the label overflowed on phones.
   Same id strength here; with flex-wrap above, the button drops under the
   field when it no longer fits beside it. */
.woocommerce-cart #content table.shop_table.cart td.actions .coupon button.button {
  flex: 0 0 auto;
  width: auto;             /* WooCommerce's small-screen sheet: width 48% */
  padding: 0 1.125rem;
  font-size: var(--text-xs);
}

.woocommerce-cart table.shop_table.cart td.actions .coupon button.button:hover {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-white);
}

/* ── Summary panel (cart-totals.php) ─────────────────────────────────────── */

.woocommerce-cart .cart-collaterals .porta-cart-summary {
  margin: 2rem 0 0;
  padding: 1.5rem 1.25rem;
  background: var(--color-bg-alt);
  border: 0;
  border-radius: var(--border-radius);
}

@media (min-width: 992px) {
  .woocommerce-cart .cart-collaterals .porta-cart-summary {
    margin-top: 0;
    padding: 1.75rem;
  }
}

/* Astra styles `.cart-collaterals .cart_totals > h2` (0,3,1) as a grey strip with a rule. */
.woocommerce-cart .cart-collaterals .porta-cart-summary > .porta-cart-summary__title {
  margin: 0 0 1rem;
  padding: 0;
  border: 0;
  background: transparent;
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  font-weight: 400;
  text-transform: none;
  color: var(--color-text);
}

/* The panel's table rows are styled with the checkout summary (.porta-review).
   The first total row has no item list above it, so no top rule. */
.woocommerce .porta-cart-summary table.shop_table.porta-review tr:first-child th,
.woocommerce .porta-cart-summary table.shop_table.porta-review tr:first-child td {
  padding-top: 0;
  border-top: 0;
}

/* Delivery terms before checkout (audit 00-005) — porta_delivery_info(),
   inc/shipping.php: product page under the add-to-cart button, cart under
   the totals. Quiet secondary text; S5 may add lines inside the block. */
.porta-delivery-info {
  margin: 0.75rem 0 0;
  font-size: var(--text-xs);
  line-height: 1.5;
  color: var(--color-text-light);
}

.porta-delivery-info__line {
  margin: 0;
}

/* « Conditions de vente » read as plain text (audit 09-021): a link, so
   burgundy and underlined like body links (DS § 6.4). */
.porta-delivery-info__line a {
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Free-delivery cue in the cart panel (audit 04-015). */
.porta-cart-summary__free {
  margin: 0.75rem 0 0;
  font-size: var(--text-sm);
  color: var(--color-accent);
}

/* Checkout: the country row when only one country is sold to (04-015,
   porta_checkout_hide_single_country()). Its hidden input still submits.
   !important against WooCommerce's address-i18n.js, which calls .show() on
   every address row (inline display: block) after each country update. */
.woocommerce form .form-row.porta-field-hidden {
  display: none !important;
}

.porta-delivery-info--product {
  margin-top: 1rem;
  font-size: var(--text-sm);
}

/* Age notice under the delivery block (audit 05-003, G2 follow-up,
   inc/legal.php): main line, then the legal threshold smaller. */
.porta-age-notice--product {
  margin: 0.75rem 0 0;
  line-height: 1.5;
}

.porta-age-notice--product p {
  margin: 0;
}

.porta-age-notice--product .porta-age-notice__main {
  font-size: var(--text-sm);
  color: var(--color-text);
}

.porta-age-notice--product .porta-age-notice__law {
  font-size: var(--text-xs);
  color: var(--color-text-light);
}

/* The panel is too narrow for the reassurance on one line: two deliberate
   lines (lock + "Paiement sécurisé", then the phone) instead of a break
   after the "·". */
.porta-cart-summary .porta-checkout__reassurance > span[aria-hidden="true"] {
  display: none;
}

.porta-cart-summary .porta-checkout__reassurance > span:last-child {
  flex-basis: 100%;
}

.woocommerce-cart .porta-cart-summary .wc-proceed-to-checkout {
  margin: 1.25rem 0 0;
  padding: 0;
}

/* Same size and type as the checkout's Commander button (colour: button block, top of file). */
.woocommerce-cart .porta-cart-summary a.checkout-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 56px;
  margin: 0;
  padding: 1rem 1.5rem;
  box-sizing: border-box;
  border-radius: var(--border-radius);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  letter-spacing: var(--tracking);
  text-transform: uppercase;
  text-align: center;
}

/* "Voir mon compte" — a quiet text link under the reassurance line. */
.woocommerce p.porta-cart__account {
  margin: 1rem 0 0;
  text-align: center;
}

.porta-cart__account a {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  min-height: 44px;
  font-size: var(--text-sm);
  color: var(--color-text-light);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

.porta-cart__account a:hover {
  color: var(--color-accent);
}

/* ── Filter tabs — /nos-vins ─────────────────────────────────────────────── */

/* The top-row tabs (.porta-filter, .porta-filter__btn, hover, active) live in
   components.css — /actualites uses them too, and this sheet does not load
   there. Only the /nos-vins sub-row stays here; this sheet loads after
   components.css, so the gold sub-row overrides below still win. */

/* ── Delivery and gift line under the filters (audit 06-004) ─────────────── */
.porta-catalog__note {
  margin: 0 0 2rem;
  font-size: var(--text-sm);
  color: var(--color-text-light);
  text-align: center;
}

.porta-catalog__note-sep {
  margin: 0 0.5em;
}

/* Underlined at rest (audit 09-021): colour alone did not mark it as a link. */
.porta-catalog__note a {
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  white-space: nowrap;
}

.porta-catalog__note a:hover,
.porta-catalog__note a:focus-visible {
  text-decoration-thickness: 2px;
}

/* ── Sub-filter row (varietals under the active colour) ──────────────────── */
/*
 * Appears only when the active top-level filter has child terms. State is
 * driven by the `.is-closed` class (toggled by wine-filter.js), not the
 * `[hidden]` attribute — so we can animate max-height, opacity, and a small
 * translateY together for a smooth drop-down. `aria-hidden` is kept in sync
 * in the JS so screen readers skip the collapsed row.
 *
 * Shape, size, and interaction pattern match the top row 1:1 — the only
 * differentiator is colour (gold instead of burgundy), so the user reads
 * the sub-row as a second filter of the same kind, just one level deeper.
 */
.porta-filter--sub {
  /*
   * Drop-down animation pattern: CSS grid with grid-template-rows 1fr ↔ 0fr
   * animates the row's height from 0 to the natural content height (and back)
   * without needing JavaScript to measure scrollHeight or a fixed max-height
   * cap. This is the only CSS-only way to animate "height: auto".
   *
   * Structure:
   *   <nav .porta-filter--sub>          ← grid container (one column, one row)
   *     <div .porta-filter__inner>      ← single grid item; flex-wraps the buttons
   *       <div .porta-filter__group> …  ← per-parent groups (display: contents)
   *   </nav>
   *
   * The inner wrapper carries overflow:hidden and min-height:0 so the clipped
   * content shrinks with the row during the animation. The outer nav still
   * handles opacity/transform/margin for the fade + slide effect.
   */
  display: grid;
  grid-template-rows: 1fr;
  margin-top: -1.75rem;        /* pull closer to parent row (parent has 2.5rem mb) */
  margin-bottom: 2.5rem;
  opacity: 1;
  transform: translateY(0);
  /*
   * cubic-bezier(0.16, 1, 0.3, 1) — ease-out-expo. Strong initial motion
   * tapering to a soft settle, which reads as a deliberate drop-down rather
   * than a linear slide. Opacity fades in slightly behind the slide so the
   * text becomes readable just as the row reaches its final height.
   */
  transition:
    grid-template-rows 0.5s cubic-bezier(0.16, 1, 0.3, 1),
    opacity 0.35s ease 0.1s,
    transform 0.5s cubic-bezier(0.16, 1, 0.3, 1),
    margin 0.5s cubic-bezier(0.16, 1, 0.3, 1),
    visibility 0s linear 0s;
}

.porta-filter--sub .porta-filter__inner {
  /* Single grid item — gets 1fr (full row height) when open, 0fr when closed.
     overflow:hidden + min-height:0 let the clipping collapse cleanly. */
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  overflow: hidden;
  min-height: 0;
}

.porta-filter--sub.is-closed {
  grid-template-rows: 0fr;
  margin-top: 0;
  margin-bottom: 0;
  opacity: 0;
  transform: translateY(-14px);
  visibility: hidden;
  /* Delay `visibility:hidden` until the close animation finishes so the row
     remains paintable for its duration. Other properties animate normally. */
  transition:
    grid-template-rows 0.4s cubic-bezier(0.4, 0, 1, 1),
    opacity 0.25s ease,
    transform 0.4s cubic-bezier(0.4, 0, 1, 1),
    margin 0.4s cubic-bezier(0.4, 0, 1, 1),
    visibility 0s linear 0.4s;
}

@media (prefers-reduced-motion: reduce) {
  .porta-filter--sub,
  .porta-filter--sub.is-closed {
    transition: none;
  }
}

.porta-filter__group {
  display: contents;          /* group's children participate in parent flex */
}

/*
 * [hidden] trap — any author `display` rule (we set `flex` on .porta-filter and
 * `contents` on .porta-filter__group) beats the UA stylesheet's
 * `[hidden] { display: none }`. Restore it explicitly on both targets so
 * wine-filter.js's `.hidden = true/false` actually toggles visibility.
 */
.porta-filter[hidden],
.porta-filter__group[hidden] {
  display: none;
}

/* Sub buttons inherit size/shape/font from .porta-filter__btn — only the
   colour treatment differs from the main row. */
.porta-filter--sub .porta-filter__btn:hover {
  background-color: transparent;
  border-color: var(--color-gold-text);
  color: var(--color-gold-text);
}

.porta-filter--sub .porta-filter__btn--active,
.porta-filter--sub .porta-filter__btn--active:hover {
  background-color: var(--color-gold-text);
  border-color: var(--color-gold-text);
  color: var(--color-white);
}

/* ── Catalog page layout — /nos-vins ─────────────────────────────────────── */

.porta-catalog__header {
  text-align: center;
  background-color: var(--color-bg-alt);
  /* Full-bleed: escape .ast-container max-width (same technique as components.css) */
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

/*
 * Same size as .porta-section-header__title on /actualites and /contact —
 * all three are the same construct (a compact tint band above the content),
 * so they carry the same H1. 56px is reserved for the full-viewport
 * photographic heroes on the homepage and /domaine.
 */
.porta-catalog__title {
  font-size: var(--text-3xl);
  margin-bottom: 1rem;
}

.porta-catalog__intro {
  color: var(--color-text-light);
  font-size: var(--text-lg);
  line-height: 1.7;
  max-width: var(--max-width-text);
  margin-inline: auto;
}

/*
 * Phones: TWO compact columns (owner S9-Q8, audit 09-009 / 09-DR-5): bottle,
 * category, name, vintage, price, button — the short description is dropped
 * below 768px (it stays on the wine page and in search results). 16 wines
 * went from ~9 200px of scrolling to ~3 800px; about four wines per screen.
 * Tablets and desktop keep three columns with the description.
 */
.porta-catalog__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.5rem 0.75rem;
  /*
   * Left-align cards when fewer than 3 fill the row — prevents odd centering
   * with gaps when only 1–2 products are visible after filtering.
   * design.md §5.2: "if only 1–2 products, cards should left-align"
   */
  justify-items: start;
}

/* Cards must stretch to fill their column or they shrink to content width */
.porta-catalog__grid .porta-wine-card {
  width: 100%;
}

/* Hidden state for JS filter — class-based so CSS resets can't override it */
.porta-wine-card--hidden {
  display: none;
}

/*
 * « − 1 + » on single-size cards (design review B1, audit 09-DR-6): beside the
 * button from 768px, above it on phones. The same stepper as the wine page
 * (quantity-stepper.js), at the button's 46px height. Cards are anchors
 * (#porta-wine-ID): after an add the page returns to the card, clear of the
 * sticky header.
 */
.porta-catalog__grid .porta-wine-card {
  scroll-margin-top: 110px;
}

.porta-wine-card__cart {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.porta-wine-card__qty {
  display: flex;
  justify-content: center;
}

.porta-wine-card__qty .porta-qty-btn {
  width: 40px;
  height: 46px;
  padding: 0;   /* Astra's button padding (15px 30px) made them 61px wide */
}

/* (0,3,0): Astra's `.woocommerce-js .quantity .qty { width: 3.631em }` */
.porta-wine-card__cart .porta-wine-card__qty .qty {
  width: 2.75rem;
  height: 46px;
  padding: 0;
  text-align: center;
  border: 1px solid var(--color-bg-alt);
  border-radius: 0;
  font-family: var(--font-body);
  font-size: var(--text-field);   /* never below 16px — see style.css */
  color: var(--color-text);
  background: var(--color-white);
}

@media (min-width: 768px) {
  .porta-wine-card__cart {
    flex-direction: row;
  }

  .porta-wine-card__qty {
    flex: 0 0 auto;
  }

  .porta-wine-card__footer .porta-wine-card__cart .porta-btn {
    flex: 1 1 auto;
    width: auto;
    padding-inline: 0.75rem;
  }
}

@media (max-width: 767px) {
  .porta-wine-card__qty {
    justify-content: stretch;
  }

  .porta-wine-card__cart .porta-wine-card__qty .qty {
    flex: 1 1 auto;
    min-width: 0;
  }

  /* One side margin, not two (design review A2): handled sitewide since
     audit 09-DR-O4 — base.css drops Astra's 20px on theme pages, so the
     catalogue keeps its own .porta-container padding. */

  .porta-catalog__grid .porta-wine-card__image {
    height: 200px;
  }

  .porta-catalog__grid .porta-wine-card__image img {
    padding: 0.5rem;
  }

  .porta-catalog__grid .porta-wine-card__body {
    padding: 0.75rem 0.5rem 0.25rem;
  }

  .porta-catalog__grid .porta-wine-card__title {
    font-size: var(--text-lg);
  }

  .porta-catalog__grid .porta-wine-card__desc {
    display: none;
  }

  .porta-catalog__grid .porta-wine-card__footer {
    gap: 0.5rem;
  }

  .porta-catalog__grid .porta-wine-card__price {
    font-size: var(--text-base);
  }

  .porta-catalog__grid .porta-wine-card__footer .porta-btn {
    padding: 0.5rem;
    font-size: var(--text-xs);
  }

  .porta-catalog__grid .porta-medal--card {
    width: 40px;
  }
}

@media (min-width: 768px) {
  .porta-catalog__title {
    font-size: var(--text-4xl);
  }

  .porta-catalog__grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 2rem;
  }
}

/* ── Single product page — .porta-product ────────────────────────────────── */

/*
 * Remove Astra's default content-area top padding on single product pages.
 * Astra applies padding/margin at multiple levels of the wrapper stack depending
 * on which container layout is active in the Customizer (plain, separate, etc.).
 * We zero all candidates so the full-bleed burgundy band sits flush under the nav.
 * .woocommerce-notices-wrapper is also zeroed: WC always outputs this div even
 * when empty and it can carry margin from WC's own stylesheet.
 * .single-product body class is added by WooCommerce.
 */
.single-product #content,
.single-product #primary,
.single-product #main,
.single-product .site-main,
.single-product article.product,
.single-product .ast-article-single,
.single-product .entry-content,
.single-product .woocommerce-notices-wrapper {
  padding-top: 0 !important;
  margin-top: 0 !important;
}

/*
 * The wrapper carries WooCommerce's product classes, Astra's `ast-article-single`
 * among them (content-single-product.php). Astra's inline customizer CSS gives
 * `.ast-article-single img:not(figure img)` a 30px drop shadow (0,1,2) — the
 * bottle photo is shown flat on white everywhere else, so cancel it here.
 */
.porta-product.ast-article-single img {
  box-shadow: none;
}

/*
 * Full-bleed header band: beige like every shop and information page
 * (colour roles, design.md § 1.2 — burgundy is kept for closing bands only;
 * audit 09-005 / 09-DR-2, owner S9-Q3). It stays COMPACT, not the 270px page
 * band: on phones the price must stay on the first screen.
 * Same negative-margin full-bleed technique as .porta-hero and .porta-catalog__header.
 */
.porta-product__header {
  background-color: var(--color-bg-alt);
  color: var(--color-text);
  padding: 1.5rem 0;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  text-align: center;
}

@media (min-width: 768px) {
  .porta-product__header {
    padding: 2rem 0;
  }
}

/* Category badge — sits above the product name */
.porta-product__badge {
  display: inline-block;
  font-family: var(--font-body);
  font-size: var(--eyebrow-size);
  font-weight: var(--eyebrow-weight);
  letter-spacing: var(--eyebrow-tracking);
  text-transform: uppercase;
  color: var(--color-accent);
  border: 1px solid var(--color-accent);
  border-radius: var(--border-radius);
  padding: 0.25rem 0.875rem;
  margin-bottom: 1.25rem;
}

.porta-product__title {
  font-family: var(--font-heading);
  font-size: var(--text-3xl);
  color: var(--color-text);
  margin: 0;
  line-height: 1.15;
}

@media (min-width: 768px) {
  .porta-product__title {
    font-size: var(--text-4xl);
  }
}

/* Translated descriptor under the wine's name — German and English pages only
   (« im Eichenfass ausgebaut » under « … Pinot Noir fût de chêne »): the name
   stays the label's, the subtitle gives its meaning (audit 07-003, step-0 O2). */
.porta-product__descriptor {
  margin: 0.5rem 0 0;
  font-family: var(--font-body);
  font-size: var(--text-lg);
  font-style: italic;
  color: var(--color-text-light);
}

/* Body section — two-column: image | details */
.porta-product__body {
  padding: 1rem 0 2rem;
}

@media (min-width: 768px) {
  .porta-product__body {
    padding: 1.5rem 0 3rem;
  }
}

.porta-product__cols {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
}

@media (min-width: 768px) {
  .porta-product__cols {
    grid-template-columns: 1fr 1fr;
    gap: 4rem;
    align-items: start;
  }
}

/* Product image — WC gallery wrapper. margin:0 removes WC's default margin-bottom. */
.porta-product__image-wrap .woocommerce-product-gallery {
  margin: 0;
  min-height: 360px; /* prevent blank column before variation is selected */
}

/*
 * WooCommerce hides the gallery figure via JS before a variation is chosen
 * on variable products (display:none injected inline). Force the first image
 * visible so the left column is never a blank white void at desktop.
 * WC overrides this once a variation is selected — no conflict.
 */
.porta-product__image-wrap .woocommerce-product-gallery__image:first-child {
  display: block !important;
}

/* WC also adds margin via .woocommerce-product-gallery--columns-* and the figure wrapper */
.porta-product__image-wrap .woocommerce-product-gallery figure {
  margin: 0;
}

.porta-product__image-wrap .woocommerce-product-gallery__image > a,
.porta-product__image-wrap .woocommerce-product-gallery__image img {
  border-radius: var(--border-radius);
  display: block;
  width: 100%;
  height: auto;
}

/*
 * Gallery magnifier (opens the full-screen lightbox).
 *
 * WooCommerce pins this top-right with its own stylesheet, which this theme
 * does not load — so until 2026-10-03 it rendered as a bare 🔍 emoji in normal
 * flow, floating above the photo's top-left corner and pushing the image down
 * by its own height. This restores the intended placement as a small round
 * button, and frees the top-left corner for the distinction medal below.
 *
 * Focus is shown with the border, not outline: Astra owns outline and
 * box-shadow on links (see CLAUDE.md), and this trigger is an <a role=button>.
 */
.porta-product__image-wrap .woocommerce-product-gallery {
  position: relative;
}

.porta-product__image-wrap .woocommerce-product-gallery__trigger {
  position: absolute;
  top: 1rem;
  right: 1rem;
  z-index: var(--z-raised-3); /* above WC's hover-zoom layer and the medal */
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid rgba(26, 26, 26, 0.12);
  border-radius: 50%;
  background-color: var(--color-white);
  text-decoration: none;
  transition: border-color var(--duration) ease;
}

.porta-product__image-wrap .woocommerce-product-gallery__trigger:hover,
.porta-product__image-wrap .woocommerce-product-gallery__trigger:focus-visible {
  border-color: var(--color-accent);
}

/* The 🔍 character (or the colour Twemoji <img> WordPress swaps it for —
   blue lens, pink handle, the only emoji on the site) is hidden; a line
   magnifier in --color-text is drawn instead, a mask so it takes the colour
   (audit 09-028). The link keeps its aria-label. */
.porta-product__image-wrap .woocommerce-product-gallery__trigger img.emoji,
.porta-product__image-wrap .woocommerce-product-gallery__trigger span {
  display: none !important;
}

.porta-product__image-wrap .woocommerce-product-gallery__trigger::before {
  content: '';
  width: 18px;
  height: 18px;
  background-color: var(--color-text);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='M15.5 15.5 21 21'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='M15.5 15.5 21 21'/%3E%3C/svg%3E") center / contain no-repeat;
}

.porta-product__image-wrap .woocommerce-product-gallery__trigger:hover::before,
.porta-product__image-wrap .woocommerce-product-gallery__trigger:focus-visible::before {
  background-color: var(--color-accent);
}

/*
 * Distinction medal on the product photo. Base rules (.porta-medal) live in
 * components.css with the /nos-vins card variant.
 *
 * The medal is a sibling of the WC gallery inside this wrapper, never inside
 * the gallery: WooCommerce's gallery JS rebuilds its own markup for the slider
 * and zoom and would discard anything injected there. Top-left because the
 * lightbox magnifier (.woocommerce-product-gallery__trigger) is top-right.
 * z-index 2 keeps it above the hover-zoom layer WC adds over the image.
 */
.porta-product__image-wrap {
  position: relative;
}

.porta-medal--single {
  top: 1rem;
  left: 1rem;
  width: 72px;
}

@media (min-width: 768px) {
  .porta-medal--single {
    width: 88px;
  }
}

/*
 * The distinction as text, above the price. Kicker treatment in burgundy, not
 * gold: gold fails contrast at this size (design.md §9.1).
 */
.porta-product__distinction {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--color-accent);
  margin: 0;
}

/* Details column: flex stack with consistent spacing between child elements */
.porta-product__details {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* Price — body sans (Inter) bold in accent colour, matching the /nos-vins
   card price rule. Previously Playfair serif — it didn't tie into the rest
   of the product page typography and read as an orphan. Size bumped from
   the card's --text-lg to --text-2xl so it still reads as the headline
   price on the page without visually competing with the product title. */
.porta-product__price .price,
.porta-product__price .woocommerce-Price-amount {
  font-family: var(--font-body);
  font-size: var(--text-2xl);
  color: var(--color-accent);
  font-weight: 700;
}

/* Variation price — same typography as static price; hide tax suffix (repeats same amount) */
.woocommerce-variation-price .price,
.woocommerce-variation-price .woocommerce-Price-amount {
  font-family: var(--font-body);
  font-size: var(--text-2xl);
  color: var(--color-accent);
  font-weight: 700;
}

.woocommerce-variation-price .woocommerce-price-suffix {
  display: none;
}

/* Price per litre under the bottle's price — product page only, discreet
   (audit 05-001, G2 follow-up; inc/legal.php). */
.porta-unit-price {
  display: block;
  margin-top: 0.125rem;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 400;
  color: var(--color-text-light);
}

/* A little air before the quantity stepper. */
.woocommerce-variation-price .porta-unit-price {
  margin-bottom: 0.75rem;
}

/* Sale price: strike-through on original, clean on discounted */
.porta-product__price ins {
  text-decoration: none;
}

.porta-product__price del {
  color: var(--color-text-light);
  font-size: var(--text-xl);
  margin-right: 0.5rem;
}

/* Short description */
.porta-product__excerpt {
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--color-text-light);
  line-height: 1.7;
}

.porta-product__excerpt p:last-child {
  margin-bottom: 0;
}

/* Thin separator between the description and the purchase area */
.porta-product__excerpt {
  padding-bottom: 1.25rem;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}

/*
 * Phones: price, format and « Ajouter au panier » first (audit 00-017). The
 * button used to start 1 159 px down a 844 px screen, under a full-height
 * photo and the accroche. Below 768px the photo is capped and the accroche
 * moves after the purchase block (CSS order — the markup, and so the reading
 * order for screen readers on wide screens, is unchanged); the meta line
 * follows it. From 768px the two-column layout keeps the original order.
 */
@media (max-width: 767px) {
  .porta-product__cols {
    gap: 1.5rem;
  }

  .porta-product__image-wrap .woocommerce-product-gallery {
    min-height: 0;
  }

  .porta-product__image-wrap .woocommerce-product-gallery__image img {
    max-height: 240px;
    object-fit: contain;
  }

  .porta-product__excerpt {
    order: 1;
    padding: 1.25rem 0 0;
    border-bottom: 0;
    border-top: 1px solid rgba(0, 0, 0, 0.08);
  }

  .porta-product__meta {
    order: 2;
  }
}

/*
 * Add-to-cart area: WC outputs a .cart form containing .quantity + .single_add_to_cart_button.
 * We flex-row them and style to match brand.
 */
.porta-product__cart .cart {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.75rem;
}

.porta-product__cart .single_add_to_cart_button {
  margin-top: 1.25rem !important;
}

/* .qty input styling lives with the stepper block below (square field
   bracketed by the − / + pill buttons injected by quantity-stepper.js). */

/*
 * Add-to-cart button — matches .porta-btn--primary.
 * !important on background/color/border: WooCommerce's own woocommerce.css
 * overrides the button colour for variable products (no variation selected)
 * with a blue .disabled state that wins without !important.
 */
.porta-product__cart .single_add_to_cart_button {
  background-color: var(--color-accent) !important;
  color: var(--color-white) !important;
  border: var(--btn-border-width) solid var(--color-accent) !important;
  border-radius: var(--border-radius);
  font-family: var(--font-body);
  font-size: var(--btn-font-size);
  font-weight: var(--btn-font-weight);
  letter-spacing: var(--btn-tracking);
  text-transform: uppercase;
  padding: var(--btn-padding);
  cursor: pointer;
  transition: background-color var(--duration) ease, border-color var(--duration) ease, opacity var(--duration) ease;
}

/* Disabled (no variation chosen yet, out of stock), hover, pressed, focus and
   loading: the primary button state set in components.css (audit 09-DR-3). */

/* ── Quantity stepper ────────────────────────────────────────────────────── */

/*
 * Custom − / + stepper replacing the native browser number spinner.
 * quantity-stepper.js injects .porta-qty-btn buttons; CSS hides the native
 * arrows and connects the three elements (−, input, +) into a single pill.
 */

/* Hide native browser spinner arrows (quantity-stepper.js adds custom buttons) */
.quantity input[type="number"].qty::-webkit-outer-spin-button,
.quantity input[type="number"].qty::-webkit-inner-spin-button {
  -webkit-appearance: none;
}

.quantity input[type="number"].qty {
  -moz-appearance: textfield;
  appearance: textfield;
}

/* Flex wrapper so − input + align in a row */
.porta-product__cart .quantity {
  display: flex;
  align-items: center;
}

/* Shared button style */
.porta-qty-btn {
  width: 40px;
  height: 40px;
  background: transparent;
  border: 1px solid var(--color-bg-alt);
  color: var(--color-text);
  font-size: var(--text-xl);
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: border-color var(--duration-fast) ease, color var(--duration-fast) ease;
}

.porta-qty-btn--minus {
  border-radius: var(--border-radius) 0 0 var(--border-radius);
  border-right: none;
}

.porta-qty-btn--plus {
  border-radius: 0 var(--border-radius) var(--border-radius) 0;
  border-left: none;
}

.porta-qty-btn:hover,
.porta-qty-btn:focus,
.porta-qty-btn:active {
  border-color: var(--color-accent);
  color: var(--color-accent);
  background: transparent;
  outline: none;
  box-shadow: none;
}

/* Product-page qty input — square middle piece of the −/qty/+ stepper pill */
.porta-product__cart .qty {
  width: 3.5rem;
  height: 40px;
  text-align: center;
  border: 1px solid var(--color-bg-alt);
  border-radius: 0;
  font-family: var(--font-body);
  font-size: var(--text-field);   /* never below 16px — see style.css */
  color: var(--color-text);
  background: var(--color-white);
  padding: 0;
}

/* Hide "Effacer" / reset variations link — customer can reselect from the dropdown */
.porta-product__cart .reset_variations {
  display: none !important;
}

/*
 * Option availability cue — set by product-variations.js on <option> elements
 * whose attribute value has no matching variation when combined with the
 * currently-selected values of the OTHER attribute dropdowns. Rendering them
 * in the muted text colour signals "picking this will change the other
 * attribute" without removing the option (which is what WC's default
 * behaviour does, and what confused customers on two-attribute products).
 * Browsers vary on <option> styling support — Chrome/Firefox/Safari respect
 * `color` on <option>; this degrades gracefully to black text elsewhere.
 */
.porta-product__cart .variations select option.porta-variation-unavailable {
  color: var(--color-text-muted);
}

/*
 * Product meta: SKU + category links (WC output via woocommerce_template_single_meta).
 * Hidden for two reasons:
 *   1. UGS (SKU) shows "ND" (non défini) until real SKUs are assigned — noise for customers.
 *   2. Category links point to /boutique archive pages which are intentionally hidden
 *      from navigation (engine-room pages per CLAUDE.md two-layer commerce architecture).
 * Re-enable by changing display:none to display:block when SKUs are populated.
 */
.porta-product__meta {
  display: none;
}

/*
 * Key-fact chips under the short description — grape · appellation ·
 * vintage · alcohol (wine sheet, inc/wine-sheet.php). Quiet outlined pills;
 * the vintage is the one in burgundy, it is what changes each year.
 */
.porta-wine-facts {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 1.5rem;
  padding: 0;
}

.porta-wine-facts__item {
  margin: 0;
  padding: 0.3rem 0.75rem;
  border: 1px solid rgba(26, 26, 26, 0.15);
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  line-height: 1.4;
  color: var(--color-text);
  background: var(--color-white);
}

.porta-wine-facts__item--vintage {
  border-color: var(--color-accent);
  color: var(--color-accent);
  font-weight: 600;
}

/*
 * "Le vin" — full-bleed beige band replacing the old "Notes de dégustation".
 * Story (centred prose) → Dégustation | Fiche technique (two columns from
 * 768px) → Service & accords strip. Every block is optional (the template
 * only prints what is filled in), so the layout must look finished with any
 * subset — hence no fixed heights and a grid that collapses to one column.
 */
.porta-product__wine {
  background-color: var(--color-bg-alt);
  padding: var(--space-section-sm) 0;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

@media (min-width: 768px) {
  .porta-product__wine {
    padding: var(--space-section) 0;
  }
}

/* Narrative heading tier (CLAUDE.md "Section heading tiers"): centred, gold dash. */
.porta-product .porta-product__wine-title {
  margin: 0 0 2rem;
  font-family: var(--font-heading);
  font-size: var(--text-3xl);
  font-weight: 400;
  line-height: 1.2;
  text-align: center;
  color: var(--color-text);
}

.porta-product .porta-product__wine-title::after {
  content: '';
  display: block;
  width: 40px;
  height: 2px;
  margin: 0.75rem auto 0;
  background: var(--color-gold);
}

@media (min-width: 768px) {
  .porta-product .porta-product__wine-title {
    font-size: var(--text-4xl);
    margin-bottom: 2.5rem;
  }
}

.porta-product__story {
  max-width: var(--max-width-text);
  margin: 0 auto;
  font-size: var(--text-lg);
  line-height: 1.7;
  text-align: center;
  color: var(--color-text);
}

.porta-product__story p {
  margin: 0 0 1rem;
}

.porta-product__story p:last-child {
  margin-bottom: 0;
}

/* Dégustation | Fiche technique — white cards on the beige band. */
.porta-product__sheet {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem;
  max-width: 960px;
  margin: 2.5rem auto 0;
}

@media (min-width: 768px) {
  .porta-product__sheet {
    grid-auto-flow: column;            /* one equal column per block present (1, 2 or 3) */
    grid-auto-columns: minmax(0, 1fr);
    gap: 2rem;
  }
}

/* A card on its own (no tasting notes) takes the story's reading width —
   at 960px its label/value rows had a gulf between them. */
.porta-product__sheet:has(> .porta-product__sheet-block:only-child) {
  max-width: var(--max-width-text);
}

.porta-product__sheet-block {
  padding: 1.5rem;
  background: var(--color-white);
  border-radius: var(--border-radius);
}

@media (min-width: 768px) {
  .porta-product__sheet-block {
    padding: 2rem;
  }
}

/* Two classes: Astra's `.entry-content h3`. */
.porta-product .porta-product__sheet-title {
  margin: 0 0 1.25rem;
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  font-weight: 400;
  color: var(--color-text);
}

.porta-product__dl {
  margin: 0;
}

.porta-product__dl > div + div {
  margin-top: 0.875rem;
}

/* Small tracked-caps labels, the same as the confirmation page's details. */
.porta-product__dl dt {
  margin: 0 0 0.125rem;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-light);
}

.porta-product__dl dd {
  margin: 0;
  font-size: var(--text-base);
  line-height: 1.7;
  color: var(--color-text);
}

/* Fiche technique: label left, value right on one line from 480px — a sheet, not prose.
   480px is a content breakpoint: the 8.5rem label column plus a value fit from
   there, well before the 768px layout change (CLAUDE.md § CSS, audit 02-020). */
@media (min-width: 480px) {
  .porta-product__dl--facts > div {
    display: grid;
    grid-template-columns: 8.5rem minmax(0, 1fr);
    gap: 1rem;
    align-items: baseline;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid rgba(26, 26, 26, 0.08);
  }
  .porta-product__dl--facts > div:last-child {
    padding-bottom: 0;
    border-bottom: 0;
  }
  .porta-product__dl--facts dt {
    margin: 0;
  }
}

/* Service & accords — three icon items under the cards. */
/* « Informations légales » — mandatory food information, closing the band
   (audit 05-002, inc/legal.php). Small print, but full contrast for the text. */
.porta-product__legal {
  max-width: 960px;
  margin: 2.5rem auto 0;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(26, 26, 26, 0.12);
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--color-text);
  text-align: center;
}

.porta-product__legal-title {
  display: block;
  margin-bottom: 0.25rem;
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-light);
}

.porta-product__service {
  list-style: none;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.25rem;
  max-width: 960px;
  margin: 2.5rem auto 0;
  padding: 0;
}

@media (min-width: 768px) {
  .porta-product__service {
    grid-auto-flow: column;            /* one equal column per block present (1, 2 or 3) */
    grid-auto-columns: minmax(0, 1fr);
    gap: 2rem;
    text-align: center;
  }
}

.porta-product__service-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "icon label"
    "icon value";
  column-gap: 0.875rem;
  margin: 0;
}

@media (min-width: 768px) {
  .porta-product__service-item {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "icon"
      "label"
      "value";
    justify-items: center;
    align-content: start;   /* labels line up across items whatever the value's length */
  }
}

.porta-product__service-icon {
  grid-area: icon;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--color-white);
  color: var(--color-accent);
}

@media (min-width: 768px) {
  .porta-product__service-icon {
    margin-bottom: 0.75rem;
  }
}

.porta-product__service-label {
  grid-area: label;
  align-self: end;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-light);
}

@media (min-width: 768px) {
  .porta-product__service-label {
    align-self: auto;   /* "end" is for the phone layout, beside the icon */
  }
}

/* Pairings: one dish per line. The column is too narrow for an inline list —
   tried with "·" separators, which kept landing at the start of lines. */
.porta-product__pairings {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}

.porta-product__service-value {
  grid-area: value;
  font-size: var(--text-base);
  line-height: 1.5;
  color: var(--color-text);
}

/* Back to /nos-vins — sits just below the header band, above the two-column body */
.porta-product__nav {
  /* padding-block only: the container's side padding is the page margin
     (audit 09-DR-O4 — Astra's own 20px is gone on phones). */
  padding-block: 0.5rem;
}

.porta-product__back {
  display: inline-block;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: var(--tracking-tight);
  text-transform: uppercase;
  color: var(--color-accent);
  text-decoration: none;
  transition: color var(--duration-fast) ease;
}

.porta-product__back:hover {
  color: var(--color-gold-text);
}

/* ── Add-to-cart toast ───────────────────────────────────────────────────── */

/*
 * Top-right floating card that replaces WooCommerce's static success banner
 * on /nos-vins and single product pages. JS (add-to-cart-toast.js) builds the
 * DOM, these rules handle the look, motion, and responsive sizing.
 *
 * Layer order: below admin bar (WP's is 99999) but above the sticky header,
 * mini-cart panel, and any sticky sub-navs. 10000 is safely in that band.
 */
.woocommerce-message.porta-toast-consumed {
  display: none !important;
}

.porta-toast {
  /* Read by add-to-cart-toast.js (audit 02-020), so the script never repeats a
     breakpoint or a timing: the gap below the sticky header, and how long the
     toast stays (the progress bar below runs for the same time). */
  --toast-gap: 16px;
  --toast-duration: 3.5s;
  position: fixed;
  top: 1.25rem;             /* JS overrides this to sit below the sticky header */
  right: 1.25rem;
  z-index: var(--z-toast);
  width: calc(100% - 2.5rem);
  max-width: 380px;
  background: var(--color-white);
  border-radius: 8px;
  box-shadow:
    0 16px 40px -12px rgba(26, 26, 26, 0.18),
    0 4px 12px -4px rgba(26, 26, 26, 0.08);
  overflow: hidden;
  opacity: 0;
  transform: translate3d(0, -24px, 0) scale(0.98);
  transform-origin: top right;
  pointer-events: none;
  transition:
    opacity 0.35s ease,
    transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}

.porta-toast.is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0) scale(1);
  pointer-events: auto;
}

.porta-toast.is-leaving {
  opacity: 0;
  transform: translate3d(0, -12px, 0) scale(0.98);
  transition:
    opacity 0.3s ease,
    transform 0.45s cubic-bezier(0.4, 0, 1, 1);
}

.porta-toast__body {
  display: flex;
  align-items: flex-start;
  gap: 0.875rem;
  padding: 1rem 1.125rem;
}

.porta-toast__icon {
  flex: 0 0 32px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-white);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: 0.125rem;
}

.porta-toast__icon svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  stroke-width: 2.5;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.porta-toast__content {
  flex: 1 1 auto;
  min-width: 0;              /* allow text-overflow to work in flex child */
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}

.porta-toast__title {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text);
  line-height: 1.3;
  letter-spacing: 0.01em;
}

.porta-toast__message {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-text-light);
  line-height: 1.4;
  /* Clamp long product names to two lines with ellipsis — keeps toast height
     predictable and prevents the card from pushing off-screen. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere; /* = the deprecated word-break: break-word */
}

.porta-toast__link {
  margin-top: 0.5rem;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  align-self: flex-start;
  transition: color var(--duration-fast) ease;
}

.porta-toast__link:hover,
.porta-toast__link:focus-visible {
  color: var(--color-gold-text);
}

.porta-toast__close {
  flex: 0 0 auto;
  background: transparent;
  border: none;
  padding: 0.375rem;
  margin: -0.375rem -0.375rem 0 0;
  cursor: pointer;
  color: var(--color-text-light);
  line-height: 0;
  border-radius: 50%;
  transition: color var(--duration-fast) ease, background-color var(--duration-fast) ease;
}

/* Keyboard focus keeps the global burgundy ring (base.css) — the subtle
   background change alone is not a sufficient focus indicator. */
.porta-toast__close:hover,
.porta-toast__close:focus-visible {
  color: var(--color-text);
  background-color: var(--color-bg-alt);
}

.porta-toast__close svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  stroke-width: 2;
  fill: none;
  stroke-linecap: round;
}

/* Progress bar shrinks left-to-right over the dismiss delay. Driven by a CSS
   transform on an inner <span> so we can pause it with animation-play-state
   without interrupting the countdown position. */
.porta-toast__progress {
  position: relative;
  height: 2px;
  background: var(--color-bg-alt);
  overflow: hidden;
}

.porta-toast__progress span {
  position: absolute;
  inset: 0;
  background: var(--color-accent);
  transform-origin: left center;
  animation: porta-toast-progress var(--toast-duration) linear forwards;
}

.porta-toast.is-paused .porta-toast__progress span {
  animation-play-state: paused;
}

@keyframes porta-toast-progress {
  from { transform: scaleX(1); }
  to   { transform: scaleX(0); }
}

/* Mobile: span (almost) the full width with symmetric margins, and use a tighter
   top offset since mobile viewports are height-constrained. WP's admin bar is
   46px tall at ≤782px viewports — bumped accordingly via the body.admin-bar rule. */
/* 640px, not the 767px grid line: a content breakpoint — the toast is 360px
   wide plus margins, so it only needs to go full-width on true phone widths. */
@media (max-width: 640px) {
  .porta-toast {
    --toast-gap: 12px;
    right: 0.75rem;
    left: 0.75rem;
    width: auto;
    max-width: none;
    border-radius: 6px;
  }
  .porta-toast__body {
    padding: 0.875rem 1rem;
    gap: 0.75rem;
  }
}

/* Honour user OS-level motion preference — swap slide+scale for a plain fade
   and freeze the progress bar so it's still informative but not animated. */
@media (prefers-reduced-motion: reduce) {
  .porta-toast,
  .porta-toast.is-leaving {
    transform: none;
    transition: opacity var(--duration-fast) ease;
  }
  .porta-toast__progress span {
    animation: none;
    transform: scaleX(0.5);
  }
}

/* ── Checkout page ───────────────────────────────────────────────────────── */

/*
 * Redesigned 2026-10-04 — numbered steps on the left, sticky summary on the
 * right, modelled on Shopify-style checkouts. Markup: woocommerce/checkout/
 * (start with form-checkout.php). The previous burgundy band, card-style
 * toggles and mobile mini-summary are recoverable from git history.
 *
 * Specificity note: Astra and WooCommerce style checkout fields, tables and
 * #payment with long selectors (and some !important). Rules below are scoped
 * under .porta-checkout so they win by specificity; !important appears only
 * where a vendor rule carries it too, and says so.
 */

/*
 * Astra's page title is replaced by the progress bar, which carries the H1.
 * Cart: only when the bar is there — the empty cart has no bar and keeps
 * Astra's "Panier" title.
 */
body.woocommerce-checkout .ast-article-post .entry-header,
body.woocommerce-checkout .entry-header .entry-title,
body.woocommerce-checkout .ast-single-post-order > header.entry-header,
body.woocommerce-cart:has(.porta-steps) .ast-article-post .entry-header,
body.woocommerce-cart:has(.porta-steps) .entry-header .entry-title {
  display: none !important;
}

/* The checkout's scroll-to-top arrow overlaps the Commander button on phones. */
body.woocommerce-checkout #ast-scroll-top {
  display: none !important;
}

/* ── Progress bar: Panier → Commande → Confirmation ─────────────────────── */

.porta-steps {
  margin: 0 0 2rem;
  padding: 0 0 1rem;
  border-bottom: 1px solid rgba(26, 26, 26, 0.1);
}

.porta-steps__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
  align-items: flex-start;
}

.porta-steps__item {
  display: flex;
  align-items: flex-start;
  margin: 0;
}

/* The connector line between two steps — burgundy once the step before is done. */
.porta-steps__item + .porta-steps__item::before {
  content: '';
  flex: 0 0 auto;
  width: 1.75rem;
  height: 1px;
  margin: 13px 0.5rem 0;  /* 13px = half the 26px dot, so the line meets its centre */
  background: rgba(26, 26, 26, 0.2);
}

.porta-steps__item--done + .porta-steps__item::before {
  background: var(--color-accent);
}

/* Phones: label under the dot, so three steps fit in 335px. */
.porta-steps__link {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.375rem;
  min-width: 44px;
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--color-text-light);
}

a.porta-steps__link:hover {
  color: var(--color-accent);
}

.porta-steps__dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-size: var(--text-xs);
  letter-spacing: 0;
  line-height: 1;
}

.porta-steps__item--done .porta-steps__link {
  color: var(--color-text);
}

.porta-steps__item--done .porta-steps__dot {
  color: var(--color-accent);
}

.porta-steps__item--current .porta-steps__link {
  color: var(--color-accent);
}

.porta-steps__item--current .porta-steps__dot {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-white);
}

@media (min-width: 768px) {
  .porta-steps {
    margin-bottom: 2.5rem;
    padding-bottom: 1.25rem;
  }
  .porta-steps__item,
  .porta-steps__list {
    align-items: center;
  }
  .porta-steps__item + .porta-steps__item::before {
    width: 4rem;
    margin: 0 1rem;
  }
  .porta-steps__link {
    flex-direction: row;
    gap: 0.625rem;
  }
}

/* ── Layout ─────────────────────────────────────────────────────────────── */

.porta-checkout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  margin-bottom: var(--space-section-sm);
}

@media (min-width: 992px) {
  .porta-checkout {
    grid-template-columns: minmax(0, 1fr) minmax(0, 25rem);
    grid-template-areas: "main summary";
    column-gap: 4rem;
    align-items: start;
    margin-bottom: var(--space-section);
  }
  .porta-checkout__main    { grid-area: main; }
  .porta-checkout__summary { grid-area: summary; }
}

/* ── Order summary panel ────────────────────────────────────────────────── */

/*
 * Phones/tablets: a full-bleed beige bar above the form, collapsed by
 * checkout.js to "Afficher le récapitulatif · CHF 111.00".
 * Desktop: a beige card that stays in view while the form scrolls.
 */
.porta-checkout__summary {
  margin: 0 calc(50% - 50vw) 1.5rem;
  background: var(--color-bg-alt);
  border-block: 1px solid rgba(26, 26, 26, 0.08);
}

/* `hidden` must win over the display:flex below (it is set until JS runs). */
.porta-checkout__summary-toggle[hidden] {
  display: none;
}

.porta-checkout .porta-checkout__summary-toggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  min-height: 56px;
  margin: 0;
  padding: 0.75rem 1.25rem;
  background: transparent;
  border: 0;
  border-radius: 0;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--color-accent);
  cursor: pointer;
}

.porta-checkout .porta-checkout__summary-toggle:hover,
.porta-checkout .porta-checkout__summary-toggle:focus {
  background: transparent;
  color: var(--color-accent);
}

.porta-checkout__summary-toggle-chevron {
  transition: transform var(--duration) ease;
}

.porta-checkout__summary-toggle[aria-expanded="true"] .porta-checkout__summary-toggle-chevron {
  transform: rotate(180deg);
}

.porta-checkout__summary-toggle-total {
  margin-left: auto;
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--color-text);
  white-space: nowrap;
}

.porta-checkout__summary-body {
  padding: 0 1.25rem 1.25rem;
}

.porta-checkout__summary.is-collapsed .porta-checkout__summary-body {
  display: none;
}

/* On phones the toggle already says what this is. */
.porta-checkout .porta-checkout__summary-title {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

@media (min-width: 992px) {
  .porta-checkout__summary {
    position: sticky;
    top: calc(80px + 1.5rem);              /* below the 80px sticky header */
    max-height: calc(100vh - 80px - 3rem);
    overflow-y: auto;                       /* a long cart scrolls inside the panel */
    margin: 0;
    border: 0;
    border-radius: var(--border-radius);
  }
  body.admin-bar .porta-checkout__summary {
    top: calc(80px + 32px + 1.5rem);
    max-height: calc(100vh - 80px - 32px - 3rem);
  }
  .porta-checkout .porta-checkout__summary-toggle {
    display: none;
  }
  .porta-checkout__summary.is-collapsed .porta-checkout__summary-body {
    display: block;
  }
  .porta-checkout__summary-body {
    padding: 1.75rem 1.75rem 1.5rem;
  }
  .porta-checkout .porta-checkout__summary-title {
    position: static;
    width: auto;
    height: auto;
    overflow: visible;
    clip: auto;
    white-space: normal;
    margin: 0 0 1.25rem;
    padding: 0;
    border: 0;
    font-family: var(--font-heading);
    font-size: var(--text-xl);
    font-weight: 400;
    color: var(--color-text);
  }
}

/* Summary table (.porta-review) — shared by the checkout summary, the cart panel
   and the confirmation page. A summary, not a data table: no borders, no headers. */
.porta-checkout #order_review {
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
}

.woocommerce table.shop_table.porta-review {
  width: 100%;
  margin: 0;
  border: 0;
  border-radius: 0;
  border-collapse: collapse;
  background: transparent;
}

.woocommerce table.shop_table.porta-review th,
.woocommerce table.shop_table.porta-review td {
  padding: 0.375rem 0;
  border: 0;
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 400;
  color: var(--color-text);
  vertical-align: middle;
}

.woocommerce table.shop_table.porta-review th {
  text-align: left;
  color: var(--color-text-light);
}

.woocommerce table.shop_table.porta-review td {
  text-align: right;
  white-space: nowrap;
}

.woocommerce table.shop_table.porta-review tbody td {
  padding: 0.625rem 0;
}

.woocommerce table.shop_table.porta-review tbody td.product-name {
  min-width: 9rem; /* a wine name never shrinks to one word per line (04-001) */
  text-align: left;
  white-space: normal;
}

/* The bottle on a white tile, quantity badge on its corner. */
.porta-review__item {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.porta-review__thumb {
  position: relative;
  flex: 0 0 64px;
  width: 64px;
  height: 64px;
  background: var(--color-white);
  border: 1px solid rgba(26, 26, 26, 0.08);
  border-radius: var(--border-radius);
}

/* Two classes: .woocommerce-page img { height: auto } (0,1,1) would otherwise win. */
.porta-review .porta-review__thumb img {
  display: block;
  width: 100%;
  height: 100%;
  padding: 4px;
  box-sizing: border-box;
  object-fit: contain;
}

.porta-review__qty {
  position: absolute;
  top: -8px;
  right: -8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  box-sizing: border-box;
  border-radius: var(--radius-pill);
  background: var(--color-accent);
  color: var(--color-white);
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1;
}

.porta-review__name {
  font-weight: 500;
  line-height: 1.35;
}

/* Variation details (dl.variation) under the name. */
.porta-review__name .variation {
  margin: 0.125rem 0 0;
  font-size: var(--text-xs);
  font-weight: 400;
  color: var(--color-text-light);
}

/* One « label : value » pair per line (audit 09-001). WooCommerce and Astra
   float every dt left, so the earlier display: inline sent all the values
   onto the first line and left the labels standing empty (« Contenu : 70 cl
   Bouchon 2025 / Fermeture : / Millésime : »). A two-column grid pairs each
   dt with its dd whatever the floats say. Same rule for the cart lines. */
.porta-review__name dl.variation,
.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-name dl.variation {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 0.25em;
  align-items: baseline;
}

.porta-review__name .variation dt,
.porta-review__name .variation dd,
.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-name .variation dt,
.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-name .variation dd {
  float: none;
  clear: none;
  display: block;
  margin: 0;
  padding: 0;
  font-weight: 400;
}

.porta-review__name .variation p,
.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-name .variation p {
  display: inline;
  margin: 0;
}

/* Totals: a hairline above the first row and above the grand total. */
.woocommerce table.shop_table.porta-review tfoot tr:first-child th,
.woocommerce table.shop_table.porta-review tfoot tr:first-child td {
  padding-top: 1rem;
  border-top: 1px solid rgba(26, 26, 26, 0.12);
}

.woocommerce table.shop_table.porta-review tr.order-total th,
.woocommerce table.shop_table.porta-review tr.order-total td {
  padding-top: 1rem;
  border-top: 1px solid rgba(26, 26, 26, 0.12);
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--color-text);
  vertical-align: baseline;
}

/* The grand total only — never the VAT amount inside .includes_tax, which
   used to come out at the total's size (« dont CHF 2.32 TVA », audit 04-001).
   Cart and checkout wrap the total in <strong>; the confirmation page prints
   the amount directly in the cell. */
.woocommerce table.shop_table.porta-review tr.order-total td > strong,
.woocommerce table.shop_table.porta-review tr.order-total td > .woocommerce-Price-amount {
  font-size: var(--text-xl);
  font-weight: 600;
}

/* "(dont CHF 8.39 TVA)" on its own line under the total. It must be allowed
   to wrap: the cells are nowrap (amounts stay on one line), and this longer
   line forced the table wider than the 344px summary column, clipping every
   price and squeezing the names to one word per line (audit 04-001). */
/* WooCommerce greys this line #777 (3.8:1 on the beige panel) at (0,3,2);
   the token passes (audit 00-043, contrast pass). */
.woocommerce-cart .cart-collaterals .cart_totals table small.includes_tax {
  color: var(--color-text-light);
}

.porta-review .order-total .includes_tax {
  display: block;
  margin-top: 0.25rem;
  font-size: var(--text-xs);
  font-weight: 400;
  color: var(--color-text-light);
  white-space: normal;
}

.porta-review__pending {
  color: var(--color-text-light);
}

/* Promo code — one quiet link under the totals. */
.porta-coupon-toggle {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid rgba(26, 26, 26, 0.12);
}

.porta-coupon-toggle a.showcoupon {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: var(--text-sm);
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

.porta-coupon-toggle a.showcoupon:hover {
  color: var(--color-text);
}

.porta-checkout form.porta-coupon {
  display: flex;
  gap: 0.5rem;
  margin: 0.25rem 0 0;
  padding: 0;
  border: 0;
}

.porta-checkout form.porta-coupon .form-row {
  margin: 0;
  padding: 0;
  float: none;
  width: auto;
}

.porta-coupon__field {
  flex: 1 1 auto;
}

.porta-checkout form.porta-coupon .input-text {
  width: 100%;
  height: 44px;
  padding: 0 0.875rem;
  font-size: var(--text-field);   /* never below 16px — see style.css */
  border: 1px solid rgba(26, 26, 26, 0.22);
  background: var(--color-white);
}

.woocommerce .porta-checkout form.porta-coupon button.porta-coupon__button {
  height: 44px;
  padding: 0 1.125rem;
  background: transparent;
  border: 1px solid var(--color-accent);
  color: var(--color-accent);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
}

.woocommerce .porta-checkout form.porta-coupon button.porta-coupon__button:hover {
  background: var(--color-accent);
  color: var(--color-white);
}

/* Coupon success/error notices land inside the panel. */
.porta-checkout__coupon .woocommerce-message,
.porta-checkout__coupon .woocommerce-error,
.porta-checkout__coupon .woocommerce-info {
  margin: 0.75rem 0 0 !important;   /* the global notice rule carries !important */
  background-color: var(--color-white) !important;
}

/* ── Main column ────────────────────────────────────────────────────────── */

/* "Déjà client ? Se connecter" — a line of text, not a beige notice bar.
   The global notice rules carry !important, hence here too. */
.porta-checkout__main .woocommerce-form-login-toggle .woocommerce-info {
  margin: 0 0 0.5rem !important;
  padding: 0 !important;
  background: transparent !important;
  border: 0 !important;
  color: var(--color-text-light) !important;
}

.porta-checkout__main form.woocommerce-form-login {
  margin: 0.5rem 0 1.5rem;
  padding: 1.25rem;
  border: 1px solid rgba(26, 26, 26, 0.12);
  border-radius: var(--border-radius);
  background: var(--color-white);
}

/* Submit-error notices WooCommerce prepends to the form. */
.porta-checkout form.checkout > .woocommerce-NoticeGroup {
  margin-bottom: 1rem;
}

/* ── Numbered steps ─────────────────────────────────────────────────────── */

/*
 * The numbers come from a CSS counter, not the markup: when an order needs no
 * delivery (step 3 not rendered), Paiement becomes 3 by itself.
 */
.porta-checkout form.checkout {
  counter-reset: porta-step;
}

.porta-checkout__step {
  margin: 1.5rem 0 0;
  padding: 1.75rem 0 0;
  border-top: 1px solid rgba(26, 26, 26, 0.1);
}

.porta-checkout__step--contact {
  margin-top: 0;
  padding-top: 0.75rem;
  border-top: 0;
}

/* Two classes: Astra's `.entry-content h2` (0,1,1) sets size and margins. */
.porta-checkout .porta-checkout__step-title {
  counter-increment: porta-step;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0 0 1.25rem;
  padding: 0;
  border: 0;
  font-family: var(--font-heading);
  font-size: var(--text-2xl);
  font-weight: 400;
  line-height: 1.2;
  color: var(--color-text);
}

.porta-checkout .porta-checkout__step-title::before {
  content: counter(porta-step);
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-white);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1;
}

/* ── Fields ─────────────────────────────────────────────────────────────── */

/*
 * Two-column grid at every width — first/last name and postcode/town pair up
 * even on a 375px phone, as on Swiss shop checkouts; every other row spans both.
 */
.porta-checkout__fields {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1rem 0.75rem;
}

.porta-checkout .porta-checkout__fields .form-row {
  grid-column: 1 / -1;
  float: none;
  width: auto;
  margin: 0;
  padding: 0;
}

.porta-checkout .porta-checkout__fields .form-row-first { grid-column: 1; }
.porta-checkout .porta-checkout__fields .form-row-last  { grid-column: 2; }

.porta-checkout form.checkout .form-row label {
  display: block;
  margin: 0 0 0.375rem;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: 1.3;
  color: var(--color-text);
}

.porta-checkout form.checkout .form-row label .optional {
  font-weight: 400;
  color: var(--color-text-light);
}

.porta-checkout form.checkout .form-row .required {
  color: var(--color-accent);
  text-decoration: none;
  border: 0;
}

/*
 * 48px tall, 16px text. Under 16px, iOS Safari zooms the whole page in when a
 * field is focused — the old 14.6px fields did exactly that.
 */
.porta-checkout form.checkout .form-row .input-text,
.porta-checkout form.checkout .form-row select,
.porta-checkout form.checkout .form-row textarea {
  width: 100%;
  min-height: 48px;
  margin: 0;
  padding: 0.75rem 0.875rem;
  box-sizing: border-box;
  font-family: var(--font-body);
  font-size: var(--text-field);   /* never below 16px — see style.css */
  line-height: 1.4;
  color: var(--color-text);
  background: var(--color-white);
  border: 1px solid rgba(26, 26, 26, 0.22);
  border-radius: var(--border-radius);
  box-shadow: none;
  transition: border-color var(--duration) ease, box-shadow var(--duration) ease;
}

.porta-checkout form.checkout .form-row textarea {
  min-height: 96px;
  resize: vertical;
}

.porta-checkout form.checkout .form-row .input-text::placeholder,
.porta-checkout form.checkout .form-row textarea::placeholder {
  color: var(--color-text-light);
  opacity: 0.75;
}

/* Focus: accent border thickened by a 1px ring — no layout shift.
   The border change is the focus indicator, so the outline is dropped. */
.porta-checkout form.checkout .form-row .input-text:focus,
.porta-checkout form.checkout .form-row select:focus,
.porta-checkout form.checkout .form-row textarea:focus {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 1px var(--color-accent);
  outline: none;
}

/* Inline validation (WooCommerce adds these classes on blur and on submit). */
.porta-checkout form.checkout .form-row.woocommerce-invalid .input-text,
.porta-checkout form.checkout .form-row.woocommerce-invalid select,
.porta-checkout form.checkout .form-row.woocommerce-invalid .select2-selection {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 1px var(--color-accent);
}

.porta-checkout form.checkout .form-row.woocommerce-invalid label {
  color: var(--color-accent);
}

.porta-checkout .checkout-inline-error-message {
  margin: 0.375rem 0 0;
  font-size: var(--text-xs);
  color: var(--color-accent);
}

/* Country select — WooCommerce replaces it with selectWoo (select2). */
.porta-checkout .select2-container--default .select2-selection--single {
  height: 48px;
  display: flex;
  align-items: center;
  background: var(--color-white);
  border: 1px solid rgba(26, 26, 26, 0.22);
  border-radius: var(--border-radius);
  transition: border-color var(--duration) ease, box-shadow var(--duration) ease;
}

.porta-checkout .select2-container--default .select2-selection--single .select2-selection__rendered {
  padding: 0 2.25rem 0 0.875rem;
  font-family: var(--font-body);
  font-size: var(--text-field);   /* never below 16px — see style.css */
  line-height: 46px;
  color: var(--color-text);
}

.porta-checkout .select2-container--default .select2-selection--single .select2-selection__arrow {
  top: 0;
  right: 0.5rem;
  height: 46px;
}

.porta-checkout .select2-container--open .select2-selection--single,
.porta-checkout .select2-container--focus .select2-selection--single {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 1px var(--color-accent);
}

/* ── Quiet options: create account · other address · order note ─────────── */

.porta-checkout p.create-account,
.porta-checkout #ship-to-different-address {
  margin: 0.75rem 0 0;
  padding: 0;
  background: none;
  border: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--color-text);
}

.porta-checkout #ship-to-different-address {
  margin-top: 1rem;
}

/* Astra's inline CSS underlines every h3 in #customer_details with an
   id-strength selector, (1,2,2) — two ids are needed to remove it here. */
.porta-checkout #customer_details h3#ship-to-different-address {
  padding: 0;
  border: 0;
}

.porta-checkout #ship-to-different-address::after {
  display: none;
}

.porta-checkout p.create-account label,
.porta-checkout #ship-to-different-address label {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  min-height: 44px;
  margin: 0;
  font-size: var(--text-sm);
  font-weight: 400;
  color: var(--color-text);
  cursor: pointer;
}

.porta-checkout p.create-account input[type="checkbox"],
.porta-checkout #ship-to-different-address input[type="checkbox"] {
  width: 18px;
  height: 18px;
  margin: 0;
  flex-shrink: 0;
  accent-color: var(--color-accent);
  cursor: pointer;
}

/* The other-address fields, when opened. */
.porta-checkout .shipping_address {
  margin-top: 0.75rem;
}

/* "Ajouter une remarque" — native disclosure, styled as a + link. */
.porta-checkout__note {
  margin-top: 0.25rem;
}

.porta-checkout__note-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  font-size: var(--text-sm);
  color: var(--color-accent);
  cursor: pointer;
  list-style: none;
}

.porta-checkout__note-toggle::-webkit-details-marker {
  display: none;
}

.porta-checkout__note-toggle::before {
  content: '+';
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-size: var(--text-sm);
  line-height: 1;
}

.porta-checkout__note[open] .porta-checkout__note-toggle::before {
  content: '\2212';  /* minus sign */
}

.porta-checkout__note-toggle:hover {
  color: var(--color-text);
}

/* The summary line already names the field — keep its label for screen readers only. */
.porta-checkout .porta-checkout__note .form-row label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.porta-checkout .porta-checkout__note .form-row {
  margin: 0.25rem 0 0;
  padding: 0;
}

/* ── Option cards: delivery (step 3) and payment (step 4) ───────────────── */

/*
 * One bordered group, rows separated by hairlines; the chosen row gets a tint
 * and an accent outline. The radio is drawn in CSS so it matches the brand.
 * Payment rows use WooCommerce's own markup (ul.payment_methods > li > input +
 * label + .payment_box), hence the paired selectors.
 */
.porta-checkout .porta-options,
.porta-checkout #payment ul.payment_methods {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid rgba(26, 26, 26, 0.15);
  border-radius: var(--border-radius);
  background: var(--color-white);
  overflow: hidden;
}

/* Astra zeroes the list's bottom border with
   .woocommerce-page.woocommerce-checkout #payment ul.payment_methods (1,3,1). */
body.woocommerce-checkout .porta-checkout #payment ul.payment_methods {
  border-bottom: 1px solid rgba(26, 26, 26, 0.15);
}

.porta-checkout .porta-options__item,
.porta-checkout #payment ul.payment_methods li.wc_payment_method {
  position: relative;
  margin: 0;
  padding: 0;
  border-top: 1px solid rgba(26, 26, 26, 0.1);
  list-style: none;
  transition: background-color var(--duration) ease, box-shadow var(--duration) ease;
}

.porta-checkout .porta-options__item:first-child,
.porta-checkout #payment ul.payment_methods li.wc_payment_method:first-child {
  border-top: 0;
}

.porta-checkout .porta-options__item:has(input:checked),
.porta-checkout .porta-options__item:has(input[type="hidden"]),
.porta-checkout #payment ul.payment_methods li.wc_payment_method:has(> input:checked) {
  background: color-mix(in srgb, var(--color-accent) 4%, var(--color-white));
  box-shadow: inset 0 0 0 1px var(--color-accent);
}

.porta-checkout .porta-options__radio[type="radio"],
.porta-checkout #payment ul.payment_methods li.wc_payment_method > input[type="radio"] {
  -webkit-appearance: none;
  appearance: none;
  position: absolute;
  top: 1.125rem;
  left: 1rem;
  width: 18px;
  height: 18px;
  margin: 0;
  border: 1.5px solid rgba(26, 26, 26, 0.35);
  border-radius: 50%;
  background: var(--color-white);
  pointer-events: none;  /* the label is the tap target */
  transition: border-color var(--duration) ease, box-shadow var(--duration) ease;
}

.porta-checkout .porta-options__radio[type="radio"]:checked,
.porta-checkout #payment ul.payment_methods li.wc_payment_method > input[type="radio"]:checked {
  border-color: var(--color-accent);
  background: var(--color-accent);
  box-shadow: inset 0 0 0 4px var(--color-white);
}

/* Keyboard focus on the visually-redrawn radio. */
.porta-checkout .porta-options__radio[type="radio"]:focus-visible,
.porta-checkout #payment ul.payment_methods li.wc_payment_method > input[type="radio"]:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.porta-checkout .porta-options__label,
.porta-checkout #payment ul.payment_methods li.wc_payment_method > label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 56px;
  margin: 0;
  padding: 0.875rem 1rem 0.875rem 3rem;
  box-sizing: border-box;
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 500;
  line-height: 1.35;
  color: var(--color-text);
  cursor: pointer;
}

/* A lone delivery option has no radio — no space reserved for one. */
.porta-checkout .porta-options__item:has(input[type="hidden"]) .porta-options__label {
  padding-left: 1rem;
  cursor: default;
}

.porta-options__text {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}

.porta-options__desc {
  font-size: var(--text-sm);
  font-weight: 400;
  color: var(--color-text-light);
}

.porta-options__price {
  flex: 0 0 auto;
  font-weight: 600;
  white-space: nowrap;
}

.porta-checkout-shipping__empty {
  margin: 0;
  padding: 1rem;
  border-radius: var(--border-radius);
  background: var(--color-bg-alt);
  font-size: var(--text-sm);
  color: var(--color-text-light);
}

/* Payment: logos at the right of the row, all the same height. */
.porta-checkout #payment ul.payment_methods li.wc_payment_method > label img {
  max-height: 24px;
  width: auto;
  margin: 0 0 0 0.25rem;
  float: none;
  vertical-align: middle;
}

.porta-gateway-icon {
  display: inline-flex;
  margin-left: auto;
  color: var(--color-text-light);
}

/* Payrexx gateways (audit 00-003): the plugin wraps its logos in span.icon-wrapper.
   Its own stylesheet is dequeued (inc/payrexx.php) — it capped each logo at 32px
   wide; here they follow the row's 24px height, with a little air between them. */
.porta-checkout #payment ul.payment_methods li.wc_payment_method > label .icon-wrapper {
  display: inline-flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: 0.375rem;
  margin-left: auto;
}

.porta-checkout #payment ul.payment_methods li.wc_payment_method > label .icon-wrapper img {
  margin: 0;
}

/* The selected method's description / card fields, under its row.
   body.woocommerce-checkout answers Astra's grey `.woocommerce-page.woocommerce-checkout #payment div.payment_box` (1,2,1, woocommerce-grid.min.css). */
body.woocommerce-checkout .porta-checkout #payment div.payment_box {
  margin: 0;
  padding: 0 1rem 1rem 3rem;
  background: transparent;
  border: 0;
  border-radius: 0;
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--color-text-light);
}

.porta-checkout #payment div.payment_box::before {
  display: none;  /* WooCommerce's speech-bubble arrow */
}

.porta-checkout #payment div.payment_box p:last-child {
  margin-bottom: 0;
}

/* #payment wrapper: Astra paints it as a grey box. */
.porta-checkout #payment {
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0;
}

/* ── Place order ────────────────────────────────────────────────────────── */

.porta-checkout #payment .place-order {
  margin: 1.5rem 0 0;
  padding: 0;
}

/* Privacy / terms text WooCommerce prints above the button. */
.porta-checkout .woocommerce-terms-and-conditions-wrapper {
  font-size: var(--text-xs);
  line-height: 1.5;
  color: var(--color-text-light);
}

/* Privacy line above the boxes (audit 05-006, text from the replay script). */
.porta-checkout .woocommerce-privacy-policy-text p {
  margin: 0 0 1rem;
}

.porta-checkout .woocommerce-privacy-policy-text a {
  color: var(--color-text-light);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* The CGV acceptance box (audit 00-004): a quiet row above the 18+ card, its
   checkbox aligned with the card's (1rem inset) and the CGV link underlined. */
.porta-checkout .woocommerce-terms-and-conditions-wrapper .form-row.validate-required {
  margin: 0 0 0.75rem !important; /* WooCommerce .form-row margin carries !important */
  padding: 0 1rem !important;
}

/* (0,4,1): Astra/WooCommerce set `.woocommerce form .form-row label` to block. */
.porta-checkout .woocommerce-terms-and-conditions-wrapper .form-row label.woocommerce-form__label-for-checkbox {
  display: flex;
  align-items: flex-start;
  font-size: var(--text-sm);
  color: var(--color-text);
}

/* Spacing on the box, not a flex gap: the « * » after the text is its own flex
   item and a gap would push it away from the sentence. */
.porta-checkout .woocommerce-terms-and-conditions-wrapper .form-row label input[type="checkbox"] {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin: 0.1rem 0.875rem 0 0;
  accent-color: var(--color-accent);
}

/* Its refusal message (checkout.js, 00-004), under the sentence, not the box. */
.porta-checkout .woocommerce-terms-and-conditions-wrapper .checkout-inline-error-message {
  padding-left: calc(18px + 0.875rem);
  font-size: var(--text-sm);
}

.porta-checkout .woocommerce-terms-and-conditions-wrapper a.woocommerce-terms-and-conditions-link {
  color: var(--color-text);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Colour and hover live in the button block at the top of this file (#place_order).
   Two ids + two classes: Astra floats it right with
   .woocommerce-page #payment #place_order (2,1,0), which squeezed the
   reassurance line beside it to zero width. */
.woocommerce-page .porta-checkout #payment #place_order {
  display: block;
  float: none;
  width: 100%;
  min-height: 56px;
  margin: 0;
  padding: 1rem 1.5rem;
  border-radius: var(--border-radius);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  letter-spacing: var(--tracking);
  text-transform: uppercase;
  transition: background-color var(--duration) ease, border-color var(--duration) ease;
}

/* Two classes + type: Astra's `.entry-content p` (0,1,1) adds a 1.6em bottom margin. */
.woocommerce p.porta-checkout__reassurance {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.25rem 0.5rem;
  margin: 1rem 0 0;
  font-size: var(--text-sm);
  color: var(--color-text-light);
  text-align: center;
}

.porta-checkout__reassurance a {
  color: var(--color-text);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  white-space: nowrap;
}

.porta-checkout__reassurance a:hover {
  color: var(--color-accent);
}

/* ── Age verification (18+, 05-003) ──────────────────────────────────────────────────── */

/*
 * Legal requirement, so it keeps its card and 18+ badge rather than becoming
 * a quiet line like the other checkboxes. :has(input:checked) tints it once
 * confirmed.
 */
.porta-age-verification {
  margin: 0 0 1.25rem !important;   /* WooCommerce .form-row margin carries !important */
  padding: 0 !important;
}

.porta-age-verification__label {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  margin: 0;
  padding: 0.875rem 1rem;
  border: 1px solid rgba(26, 26, 26, 0.15);
  border-radius: var(--border-radius);
  background: var(--color-white);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: 1.45;
  color: var(--color-text);
  cursor: pointer;
  transition: border-color var(--duration) ease, background-color var(--duration) ease;
}

.porta-age-verification__label:hover {
  border-color: var(--color-text-light);
}

.porta-age-verification:has(input:checked) .porta-age-verification__label {
  border-color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 4%, var(--color-white));
}

/* Its refusal message (checkout.js, 00-004), under the card. */
.porta-age-verification .checkout-inline-error-message {
  margin-top: 0.5rem;
  font-size: var(--text-sm);
}

.porta-age-verification.woocommerce-invalid .porta-age-verification__label {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 1px var(--color-accent);
}

.porta-age-verification__input {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--color-accent);
  cursor: pointer;
}

.porta-age-verification__badge {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 42px;
  height: 28px;
  padding: 0 0.5rem;
  border-radius: var(--radius-pill);
  background: var(--color-accent);
  color: var(--color-white);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
}

.porta-age-verification__text {
  flex: 1 1 auto;
}

.porta-age-verification__text .required {
  margin-left: 0.125rem;
  color: var(--color-accent);
  text-decoration: none;
  border: none;
}

@media (prefers-reduced-motion: reduce) {
  .porta-checkout__summary-toggle-chevron,
  .porta-checkout .porta-options__item,
  .porta-checkout #payment ul.payment_methods li.wc_payment_method {
    transition: none;
  }
}

/* ── Order confirmation (thankyou.php) ──────────────────────────────────── */

/*
 * Step 3 of the ordering path, in the checkout's language: "Merci" header,
 * next steps + details on the left, the same beige summary panel on the
 * right (above the details on phones, like the checkout's summary bar).
 * Summary rows use the shared .porta-review table styles above.
 */

.porta-thankyou__header {
  margin: 0 0 2rem;
  text-align: center;
}

.porta-thankyou__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  margin-bottom: 1rem;
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-white);
}

/* Two classes: Astra's `.entry-content h1` (0,1,1). */
.porta-thankyou .porta-thankyou__title {
  margin: 0 0 0.5rem;
  font-family: var(--font-heading);
  font-size: var(--text-3xl);
  font-weight: 400;
  line-height: 1.2;
  color: var(--color-text);
}

.porta-thankyou__meta,
.porta-thankyou__email {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--color-text-light);
}

.porta-thankyou__meta {
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  color: var(--color-text);
}

.porta-thankyou__email {
  margin-top: 0.25rem;
}

.porta-thankyou__email strong {
  font-weight: 500;
  color: var(--color-text);
}

@media (min-width: 768px) {
  .porta-thankyou .porta-thankyou__title {
    font-size: var(--text-4xl);
  }
  .porta-thankyou__header {
    margin-bottom: 3rem;
  }
}

.porta-thankyou__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2rem;
  margin-bottom: var(--space-section-sm);
}

@media (min-width: 992px) {
  .porta-thankyou__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 25rem);
    grid-template-areas: "main summary";
    column-gap: 4rem;
    align-items: start;
    margin-bottom: var(--space-section);
  }
  .porta-thankyou__main    { grid-area: main; }
  .porta-thankyou__summary { grid-area: summary; }
}

.porta-thankyou__summary {
  padding: 1.5rem 1.25rem;
  background: var(--color-bg-alt);
  border-radius: var(--border-radius);
}

@media (min-width: 992px) {
  .porta-thankyou__summary {
    padding: 1.75rem;
  }
}

.porta-thankyou .porta-thankyou__summary-title,
.porta-thankyou .porta-thankyou__heading {
  margin: 0 0 1rem;
  padding: 0;
  border: 0;
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  font-weight: 400;
  color: var(--color-text);
}

/* "La suite" and "Récapitulatif" — hairline-separated blocks, like the checkout steps. */
.porta-thankyou__next,
.porta-thankyou__details {
  padding: 0 0 1.75rem;
  margin: 0 0 1.75rem;
  border-bottom: 1px solid rgba(26, 26, 26, 0.1);
}

.porta-thankyou__next p {
  margin: 0 0 0.75rem;
  font-size: var(--text-base);
  line-height: 1.7;
  color: var(--color-text);
}

/*
 * Bank details printed by WooCommerce's bank-transfer gateway
 * (woocommerce_thankyou_bacs): its own <h2> + a <ul> per account. Set in a
 * white card so the IBAN — the one thing to copy — stands out.
 */
.porta-thankyou__next .wc-bacs-bank-details-heading,
.porta-thankyou__next .wc-bacs-bank-details-account-name {
  margin: 1.25rem 0 0.5rem;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  text-transform: uppercase;
  color: var(--color-text);
}

.porta-thankyou__next ul.wc-bacs-bank-details {
  list-style: none;
  margin: 0;
  padding: 1rem 1.25rem;
  background: var(--color-white);
  border: 1px solid rgba(26, 26, 26, 0.12);
  border-radius: var(--border-radius);
}

/* The list also carries WooCommerce's .order_details class, which Astra lays
   out as a floated, dashed-separated uppercase strip — reset all of it. */
.porta-thankyou__next ul.wc-bacs-bank-details li {
  float: none;
  margin: 0.25rem 0;
  padding: 0;
  border: 0;
  font-size: var(--text-sm);
  line-height: 1.5;
  text-transform: none;
  color: var(--color-text-light);
}

.porta-thankyou__next ul.wc-bacs-bank-details::after,
.porta-thankyou__next ul.wc-bacs-bank-details::before {
  display: none;
}

.porta-thankyou__next ul.wc-bacs-bank-details li strong {
  display: block;
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--color-text);
  overflow-wrap: anywhere; /* = the deprecated word-break: break-word */   /* long IBANs on narrow phones */
}

/* WooCommerce writes the delivery total as "CHF 15.00 via Forfait". Kept on
   one line it widened the price column until the wine names wrapped word by
   word — let it wrap, with the method name on its own line. */
.woocommerce .porta-thankyou__summary table.shop_table.porta-review tr.shipping td {
  white-space: normal;
}

.porta-thankyou__summary .shipped_via {
  display: block;
  font-size: var(--text-xs);
  color: var(--color-text-light);
}

/* Details grid: Contact · Livraison · Adresse de facturation · Paiement. */
.porta-thankyou__dl {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.25rem 2rem;
  margin: 0;
}

/* 600px: content breakpoint — two address blocks fit side by side from here
   (CLAUDE.md § CSS, audit 02-020). */
@media (min-width: 600px) {
  .porta-thankyou__dl {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

.porta-thankyou__dl dt {
  margin: 0 0 0.25rem;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-light);
}

.porta-thankyou__dl dd {
  margin: 0;
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--color-text);
  overflow-wrap: anywhere; /* = the deprecated word-break: break-word */
}

.porta-thankyou__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.5rem;
  margin: 0;
}

.porta-thankyou__link {
  font-size: var(--text-sm);
  color: var(--color-text-light);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

.porta-thankyou__link:hover {
  color: var(--color-accent);
}

/* ── Related wines (audit 04-011) ─────────────────────────────────────────
   « À découvrir aussi » after the « Le vin » band — the homepage's bottle
   cards (.porta-bottle-card, components.css) on the page background. The
   white plinth would vanish on white, so it gets the hairline of the
   checkout's bottle tiles. */
.porta-related .porta-bottle-card__image {
  border: 1px solid rgba(26, 26, 26, 0.08);
}

@media (min-width: 768px) {
  .porta-related .porta-featured__grid {
    justify-content: start;
  }
}

/* ── Touch targets (owner S9-Q11, audit 09-011 / 09-DR-8) ────────────────────
 * The WooCommerce controls at 44px (--tap-size): quantity − / + and field on
 * the wine page and the cart (were 40px), the size and closure selects, the
 * add-to-cart button, the photo magnifier (was 40px); « ← Retour à nos vins »
 * at least 24px (was 20px). The theme-wide rule is in components.css.
 */
.porta-qty-btn {
  height: var(--tap-size);
  min-width: var(--tap-size);
}

.porta-product__cart .qty,
.woocommerce-cart-form .qty {
  height: var(--tap-size);
}

.porta-product__cart .variations select {
  min-height: var(--tap-size);
}

.porta-product__cart .single_add_to_cart_button {
  min-height: var(--tap-size);
}

.porta-product__image-wrap .woocommerce-product-gallery__trigger {
  width: var(--tap-size);
  height: var(--tap-size);
}

.porta-product__back,
.porta-toast__link,
.woocommerce-cart .woocommerce table.shop_table.cart tr.cart_item td.product-name a {
  /* inline-block, not inline-flex: a flex box drops the space before an
     arrow (« Nos distinctions→ »). The padding centres one line in 24px. */
  display: inline-block;
  min-height: var(--tap-size-link);
  padding-block: max(0px, calc((var(--tap-size-link) - 1lh) / 2));
}

/* Toast close: 27px drawn, 44px to tap */
.porta-toast__close {
  position: relative;
}

.porta-toast__close::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--tap-size);
  height: var(--tap-size);
  transform: translate(-50%, -50%);
}


/* ── Account and empty cart: the beige page band (audit 09-013, 04-014) ──────
 * These WooCommerce screens use Astra's page template: their H1 is Astra's
 * .entry-title, which sat against the header in Astra's default look. It
 * becomes the same beige band as every information page (colour roles,
 * design.md § 1.2; height rule in base.css: 140 / 270px), 32 / 44px H1.
 * The cart with bottles has the steps bar instead, so only the EMPTY cart
 * (no .porta-steps) gets the band.
 */
/* Two ids: Astra's `.ast-plain-container.ast-no-sidebar #primary` (1,2,0)
   gives it a 60px top margin on desktop. */
.woocommerce-account #content #primary,
.woocommerce-cart:not(:has(.porta-steps)) #content #primary {
  margin-top: 0;
  padding-top: 0;
}

.woocommerce-account .entry-header,
.woocommerce-cart:not(:has(.porta-steps)) .entry-header {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 140px;
  margin: 0 calc(50% - 50vw) 2.5rem;
  padding: 2rem 1.5rem;
  background-color: var(--color-bg-alt);
  text-align: center;
}

.woocommerce-account .entry-header .entry-title,
.woocommerce-cart:not(:has(.porta-steps)) .entry-header .entry-title {
  margin: 0;
  font-size: var(--text-3xl);
  color: var(--color-text);
}

@media (min-width: 768px) {
  .woocommerce-account .entry-header,
  .woocommerce-cart:not(:has(.porta-steps)) .entry-header {
    min-height: 270px;
    padding-block: 3.5rem;
    margin-bottom: 3.5rem;
  }

  .woocommerce-account .entry-header .entry-title,
  .woocommerce-cart:not(:has(.porta-steps)) .entry-header .entry-title {
    font-size: var(--text-4xl);
  }
}

/* Login and register forms: the site's radius, labels in the text colour,
   required marks in burgundy (were Astra's 5px card and #ff0000). */
.woocommerce-account .woocommerce form.login,
.woocommerce-account .woocommerce form.register {
  border: 1px solid var(--color-bg-alt);
  border-radius: var(--border-radius);
  background: var(--color-bg);
}

.woocommerce-account .woocommerce form .form-row label {
  color: var(--color-text);
}

.woocommerce-account .woocommerce form .required,
.woocommerce-account .woocommerce form abbr.required {
  color: var(--color-accent);
  text-decoration: none;
}

/* Show-password eye: 16 x 17px drawn, 44px to tap (axe target-size). */
.woocommerce-account .show-password-input {
  min-width: var(--tap-size);
  min-height: var(--tap-size);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Account menu: aligned with the content, the current item in burgundy text
   on beige (it was gold, ~2:1). */
.woocommerce-account .woocommerce-MyAccount-navigation ul {
  margin: 0 0 2rem;
  padding: 0;
  list-style: none;
}

.woocommerce-account .woocommerce-MyAccount-navigation li a {
  display: flex;
  align-items: center;
  min-height: var(--tap-size);
  padding: 0 0.75rem;
  color: var(--color-text);
  text-decoration: none;
  border-radius: var(--border-radius);
}

.woocommerce-account .woocommerce-MyAccount-navigation li.is-active a,
.woocommerce-account .woocommerce-MyAccount-navigation li a:hover {
  color: var(--color-accent);
  background-color: var(--color-bg-alt);
}

/* Order-received screen that asks a guest for their e-mail (audit 09-013):
   the thank-you line as a heading, the form in a readable column. */
.woocommerce-order-received .woocommerce > .woocommerce-thankyou-order-received {
  margin: 1.5rem 0 1rem;
  font-family: var(--font-heading);
  font-size: var(--text-2xl);
  color: var(--color-text);
}

.woocommerce-verify-email {
  max-width: var(--max-width-text);
  margin-bottom: var(--space-section-sm);
}

.woocommerce-verify-email .required {
  color: var(--color-accent);
  text-decoration: none;
}
