/**
 * RivoFrame - WooCommerce Styles
 *
 * The theme drops WooCommerce's three classic stylesheets
 * (woocommerce-layout, woocommerce-smallscreen, woocommerce-general) and styles
 * every Woo surface here instead, from the same design tokens as the rest of
 * the theme. See context/architecture.md for the rationale.
 *
 * Still supplied by WooCommerce, and deliberately not duplicated here:
 *   - woocommerce-blocktheme.css .... --wc-* variables, star/WooCommerce icon fonts
 *   - assets/client/blocks/*.css .... Cart, Checkout and other Woo block styles
 *
 * Blockified shop/product pages are styled through theme.json (styles.blocks);
 * this file covers the classic markup that theme.json cannot reach.
 */

/* -------------------------------------------------------------------------
 * 1. Token bridge
 *
 * WooCommerce hardcodes its palette on :root. Remapping those onto theme
 * presets means the style variations (Default / Forest / Midnight) re-colour
 * every Woo surface with no further work.
 * ---------------------------------------------------------------------- */

:root {
    --wc-primary: var(--wp--preset--color--primary);
    --wc-primary-text: var(--wp--preset--color--background);
    --wc-secondary: var(--wp--preset--color--surface);
    --wc-secondary-text: var(--wp--preset--color--foreground-light);
    --wc-highlight: var(--wp--preset--color--accent);
    --wc-highligh-text: var(--wp--preset--color--foreground);
    --wc-content-bg: var(--wp--preset--color--background);
    --wc-subtext: var(--wp--preset--color--foreground-light);
    --wc-form-border-color: var(--wp--preset--color--border);
    --wc-form-border-radius: var(--wp--custom--border--radius);
    --wc-form-border-width: 1px;

    /* Status colours stay semantic rather than following the palette. */
    --wc-green: #007518;
    --wc-red: #cc1818;
    --wc-orange: #b45309;
    --wc-blue: #1e6a9c;
    --wc-destructive: #cc1818;

    /* RivoFrame-local Woo tokens. */
    --rivoframe-wc-gap: var(--wp--preset--spacing--40);
    --rivoframe-wc-radius: var(--wp--custom--border--radius);
    --rivoframe-wc-border: 1px solid var(--wp--preset--color--border);

    /* Used height of .woocommerce form .form-row input.input-text (section 4):
       7px padding top and bottom, 1px border top and bottom, medium/1.5 text
       — 40px in total. Derived rather than hardcoded so it tracks the
       font-size preset, and so section 13's select2 re-skin stays the same
       height as a native field without repeating the arithmetic. */
    --rivoframe-wc-field-height: calc(
        (7px * 2) + 2px + (var(--wp--preset--font-size--medium) * 1.5)
    );
}

/* -------------------------------------------------------------------------
 * 2. Star rating
 *
 * Uses the `WooCommerce` icon font, which woocommerce-blocktheme.css still
 * loads. "s" renders an empty star, "S" a filled one.
 * ---------------------------------------------------------------------- */

.woocommerce .star-rating,
.wc-block-components-product-rating .star-rating {
    overflow: hidden;
    position: relative;
    height: 1em;
    line-height: 1;
    font-size: 1em;
    width: 5.4em;
    font-family: WooCommerce, sans-serif;
    letter-spacing: 0;
}

.woocommerce .star-rating::before {
    content: "sssss";
    color: var(--wp--preset--color--border);
    float: left;
    top: 0;
    left: 0;
    position: absolute;
}

.woocommerce .star-rating span {
    overflow: hidden;
    float: left;
    top: 0;
    left: 0;
    position: absolute;
    padding-top: 1.5em;
}

.woocommerce .star-rating span::before {
    content: "SSSSS";
    top: 0;
    position: absolute;
    left: 0;
    color: var(--wp--preset--color--accent);
}

.woocommerce .woocommerce-product-rating {
    display: flex;
    align-items: center;
    gap: var(--wp--preset--spacing--20);
    margin-bottom: var(--wp--preset--spacing--30);
}

.woocommerce .woocommerce-product-rating .woocommerce-review-link {
    color: var(--wp--preset--color--foreground-light);
    font-size: var(--wp--preset--font-size--small);
}

/* Star selector in the review form.
 *
 * review-rating.js swaps the rating <select> for a row of links whose text
 * ("1 of 5 stars") is the accessible name; the visible star is drawn from the
 * WooCommerce icon font on ::before, so the text itself is indented away.
 * "s" is an empty star, "S" a filled one — the hover/selected combinations
 * below fill every star up to the one being pointed at. */
.woocommerce #review_form #respond .comment-form-rating {
    display: flex;
    align-items: center;
    gap: var(--wp--preset--spacing--20);
    margin-bottom: var(--wp--preset--spacing--30);
}

.woocommerce #review_form #respond .comment-form-rating label {
    margin: 0;
}

.woocommerce #review_form #respond p.stars {
    display: inline-flex;
    gap: 4px;
    margin: 0;
    line-height: 1;
}

.woocommerce #review_form #respond p.stars a {
    position: relative;
    /* text-indent has no effect on an inline box. */
    display: inline-block;
    width: 1em;
    height: 1em;
    font-size: 16px;
    text-indent: -999em;
    text-decoration: none;
    color: var(--wp--preset--color--accent);
}

.woocommerce #review_form #respond p.stars a::before {
    content: "s";
    position: absolute;
    top: 0;
    left: 0;
    width: 1em;
    height: 1em;
    font-family: WooCommerce, sans-serif;
    font-weight: 400;
    line-height: 1;
    text-indent: 0;
}

.woocommerce #review_form #respond p.stars:hover a::before,
.woocommerce #review_form #respond p.stars.selected a.active::before,
.woocommerce #review_form #respond p.stars.selected a:not(.active)::before {
    content: "S";
}

.woocommerce #review_form #respond p.stars a:hover ~ a::before,
.woocommerce #review_form #respond p.stars.selected a.active ~ a::before {
    content: "s";
}

/* -------------------------------------------------------------------------
 * 3. Notices - message / info / error
 * ---------------------------------------------------------------------- */

.woocommerce-message,
.woocommerce-info,
.woocommerce-error,
.woocommerce-noreviews,
p.no-comments {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--wp--preset--spacing--30);
    margin: 0 0 var(--wp--preset--spacing--40);
    padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--40);
    list-style: none;
    background-color: var(--wp--preset--color--background-alt);
    border-left: 3px solid var(--wp--preset--color--primary);
    border-radius: var(--rivoframe-wc-radius);
    font-size: var(--wp--preset--font-size--small);
    color: var(--wp--preset--color--foreground);
}

.woocommerce-message {
    border-left-color: var(--wc-green);
}

.woocommerce-info {
    border-left-color: var(--wp--preset--color--primary);
}

.woocommerce-error {
    border-left-color: var(--wc-red);
    flex-direction: column;
    align-items: flex-start;
}

.woocommerce-error li {
    margin: 0;
}

/* Push the inline action button to the far end of the notice. */
.woocommerce-message .button,
.woocommerce-info .button,
.woocommerce-error .button {
    margin-left: auto;
}

.woocommerce-store-notice,
p.demo_store {
    background-color: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--background);
    padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--40);
    font-size: var(--wp--preset--font-size--small);
    text-align: center;
    margin: 0;
}

.woocommerce-store-notice a,
p.demo_store a {
    color: inherit;
    text-decoration: underline;
}

/* Block notice banners.
 *
 * The account, cart and checkout screens do NOT emit the classic
 * `.woocommerce-info` markup styled above. They render through Woo's React
 * notice component as `.wc-block-components-notice-banner`, which brings its
 * own inline <svg> icon and is styled by `wc-blocks-style` — a stylesheet the
 * theme does not dequeue, so none of the classic rules reach it. Left alone it
 * draws a tinted, outlined callout; the reference design is a flat grey bar
 * with the action rendered as a real button on the right. */
.wc-block-components-notice-banner.wc-block-components-notice-banner,
.wc-block-components-notice-banner.wc-block-components-notice-banner.is-info,
.wc-block-components-notice-banner.wc-block-components-notice-banner.is-success,
.wc-block-components-notice-banner.wc-block-components-notice-banner.is-warning,
.wc-block-components-notice-banner.wc-block-components-notice-banner.is-error {
    display: flex;
    align-items: center;
    gap: 16px;
    min-height: 60px;
    margin: 0 0 var(--wp--preset--spacing--40);
    /* wc-blocks.css pads the banner with `16px !important`. */
    padding: 15px 20px !important;
    background-color: var(--wp--preset--color--surface);
    border: 0;
    border-radius: var(--rivoframe-wc-radius);
    color: var(--wp--preset--color--foreground);
    font-size: var(--wp--preset--font-size--small);
}

/* The per-status classes must be listed above, and the base class is doubled
   on every one of them: wc-blocks.css colours the bar through
   `.wc-block-components-notice-banner.is-info` (0-2-0) and outlines it through
   the bare class (0-1-0), both of which would otherwise win on source order —
   `rivoframe-woocommerce` declares no dependency on the Woo block sheets, so
   their relative order is not guaranteed. */

/* Woo's own icon is a filled disc — a white glyph knocked out of a status
   colour. The reference uses a single flat outline bell for every status, so
   Woo's <svg> is dropped and the icon redrawn as a mask, the same technique as
   the account navigation in section 6. */
.wc-block-components-notice-banner > svg {
    display: none;
}

.wc-block-components-notice-banner::before {
    content: "";
    flex: 0 0 24px;
    width: 24px;
    height: 24px;
    background-color: currentColor;
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9'/%3E%3Cpath d='M10.3 21a1.94 1.94 0 0 0 3.4 0'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9'/%3E%3Cpath d='M10.3 21a1.94 1.94 0 0 0 3.4 0'/%3E%3C/svg%3E");
    -webkit-mask-position: center;
    -webkit-mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-position: center;
    mask-size: contain;
    mask-repeat: no-repeat;
}

/* Only the real status types earn a colour; info stays as quiet as the bar. */
.wc-block-components-notice-banner.wc-block-components-notice-banner.is-error::before {
    background-color: var(--wc-red);
}

.wc-block-components-notice-banner.wc-block-components-notice-banner.is-success::before {
    background-color: var(--wc-green);
}

.wc-block-components-notice-banner > .wc-block-components-notice-banner__content {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    width: 100%;
    padding: 0;
}

/* The action sits inside __content but reads as the banner's button.
 *
 * Two separate fights here, and they need different tools:
 *
 *  - Position and size. wc-blocks.css targets it as
 *    `.…notice-banner > .…__content .wc-forward` (0-3-0), which outranks the
 *    obvious `.…__content > .button` (0-2-0) and pins a 20px left margin. The
 *    class name is doubled below to reach 0-4-0 and win outright, rather than
 *    relying on stylesheet order — `rivoframe-woocommerce` declares no
 *    dependency on the Woo block sheets, so their relative order is not
 *    actually guaranteed.
 *  - Colour and padding. That same rule sets `background: transparent` and
 *    `padding: 0`, both `!important`, and no amount of specificity beats an
 *    important declaration, so those two have to answer in kind. Everything
 *    else comes from section 18 unforced. */
.wc-block-components-notice-banner
    .wc-block-components-notice-banner__content.wc-block-components-notice-banner__content
    > .button {
    order: 1;
    margin-left: auto;
    /* wc-blocks.css also dims the link to `opacity: .7`, which reads as a
       disabled button once it has a solid fill. */
    opacity: 1;
    /* This one is an <a> carrying `wp-element-button`, so it takes
       theme.json's button skin but *not* the flex centring — that lives on
       `.wp-block-button__link` in theme.css (wrong class) and on section 18's
       rule (explicitly `:not(.wp-element-button)`). Without it the label sits
       on its line box at the top of the 40px min-height instead of in the
       middle of it. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 40px;
    padding: 5px 15px !important;
    font-size: var(--wp--preset--font-size--small);
    line-height: 1.5;
    background-color: var(--wp--preset--color--primary) !important;
    color: var(--wp--preset--color--background) !important;
    text-decoration: none;
}

.wc-block-components-notice-banner
    .wc-block-components-notice-banner__content.wc-block-components-notice-banner__content
    > .button:hover {
    background-color: var(--wp--preset--color--primary-dark) !important;
}

/* -------------------------------------------------------------------------
 * 4. Forms
 * ---------------------------------------------------------------------- */

.woocommerce form .form-row {
    display: flex;
    flex-direction: column;
    gap: var(--wp--preset--spacing--20);
    margin: 0 0 var(--wp--preset--spacing--40);
}

.woocommerce form .form-row label {
    color: var(--wp--preset--color--foreground);
    font-size: 15px;
    font-weight: 400;
    line-height: 1.4;
}

.woocommerce form .form-row .required {
    color: var(--wc-red);
    text-decoration: none;
    border: 0;
}

.woocommerce form .form-row .optional {
    color: var(--wp--preset--color--foreground-light);
}

.woocommerce form .form-row input.input-text,
.woocommerce form .form-row textarea,
.woocommerce form .form-row select,
.woocommerce table.cart td.actions .coupon .input-text,
.woocommerce .woocommerce-form-login input.input-text,
.woocommerce #review_form input[type="text"],
.woocommerce #review_form input[type="email"],
.woocommerce #review_form textarea {
    width: 100%;
    box-sizing: border-box;
    padding: 7px 16px;
    color: var(--wp--preset--color--foreground);
    background-color: var(--wp--preset--color--background-alt);
    border: var(--rivoframe-wc-border);
    border-radius: var(--rivoframe-wc-radius);
    font-family: inherit;
    font-size: var(--wp--preset--font-size--medium);
    line-height: 1.5;
}

.woocommerce form .form-row textarea {
    min-height: 8rem;
    resize: vertical;
}

.woocommerce form .form-row input.input-text:focus,
.woocommerce form .form-row textarea:focus,
.woocommerce form .form-row select:focus {
    outline: 2px solid var(--wp--preset--color--primary);
    outline-offset: 1px;
    border-color: var(--wp--preset--color--primary);
}

.woocommerce form .form-row.woocommerce-invalid input.input-text,
.woocommerce form .form-row.woocommerce-invalid select {
    border-color: var(--wc-red);
}

.woocommerce form .form-row.woocommerce-validated input.input-text {
    border-color: var(--wc-green);
}

/* Two-up rows on wider viewports.
 *
 * Float, not inline-flex. Inline-level boxes are separated by the whitespace
 * text node WooCommerce leaves between the two <p>s, so 50% + 50% + that
 * whitespace overflows the line and the pair wraps — which is exactly how
 * First/Last name ended up stacked. Floats ignore it. Woo emits a
 * <div class="clear"> after each pair, which ends the float context. */
@media (min-width: 600px) {
    .woocommerce form .form-row-first,
    .woocommerce form .form-row-last {
        width: calc(50% - 20px);
    }

    .woocommerce form .form-row-first {
        float: left;
    }

    .woocommerce form .form-row-last {
        float: right;
    }

    .woocommerce form .clear {
        clear: both;
    }

    /* `.clear` only shows up on the checkout form. `form-edit-address`
       renders the same first/last pair with nothing after it, so the next
       full-width row — Country / Region — flowed into the 40px gutter left
       between the two floats and its label landed on top of "Last name".
       Clearing on the rows themselves covers both forms: `-first` starts each
       new pair on a fresh line, `-wide` starts each full-width field. */
    .woocommerce form .form-row-first,
    .woocommerce form .form-row-wide {
        clear: both;
    }
}

/* Password change is a real <fieldset>; without this it renders in the
   browser's default chrome, which is a solid inset border unrelated to the
   rest of the form. */
.woocommerce form fieldset {
    margin: 0 0 var(--wp--preset--spacing--40);
    padding: 24px 30px 30px;
    border: 1px dashed var(--wp--preset--color--border);
    border-radius: var(--rivoframe-wc-radius);
}

.woocommerce form fieldset legend {
    padding: 0 8px;
    font-size: 15px;
    font-weight: 500;
    color: var(--wp--preset--color--foreground);
}

.woocommerce form.login,
.woocommerce form.register,
.woocommerce form.checkout_coupon,
.woocommerce form.lost_reset_password {
    margin: 0 0 var(--wp--preset--spacing--50);
}

/* Woo's password fields wrap the input in .password-input and append an empty
   .show-password-input span as the toggle. woocommerce-general.css used to
   place and draw it; the theme drops that sheet, so without these rules the
   toggle renders as a stray grey pill above the checkbox row. */
.woocommerce .password-input {
    position: relative;
    display: block;
    width: 100%;
}

.woocommerce .password-input input.input-text {
    padding-right: 2.75rem;
}

.woocommerce .show-password-input {
    position: absolute;
    top: 50%;
    right: 0.75rem;
    transform: translateY(-50%);
    width: 1.25rem;
    height: 1.25rem;
    padding: 0;
    background: none;
    border: 0;
    cursor: pointer;
    opacity: 0.55;
    /* Eye glyph, so no icon font or image request is needed. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234a5568' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7z'/%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
}

.woocommerce .show-password-input:hover,
.woocommerce .show-password-input.display-password {
    opacity: 1;
}

.woocommerce form .form-row .woocommerce-form__label-for-checkbox {
    flex-direction: row;
    align-items: center;
    gap: var(--wp--preset--spacing--20);
    display: flex;
    font-weight: 400;
}

.woocommerce-password-strength {
    padding: var(--wp--preset--spacing--20) var(--wp--preset--spacing--30);
    border-radius: var(--rivoframe-wc-radius);
    font-size: var(--wp--preset--font-size--small);
    font-weight: 600;
    text-align: center;
    background-color: var(--wp--preset--color--surface);
}

.woocommerce-password-strength.short,
.woocommerce-password-strength.bad {
    color: var(--wc-red);
}

.woocommerce-password-strength.good {
    color: var(--wc-orange);
}

.woocommerce-password-strength.strong {
    color: var(--wc-green);
}

.woocommerce-password-hint {
    display: block;
    margin-top: var(--wp--preset--spacing--20);
    font-size: var(--wp--preset--font-size--small);
    color: var(--wp--preset--color--foreground-light);
}

/* -------------------------------------------------------------------------
 * 5. Tables - cart, order details, addresses
 * ---------------------------------------------------------------------- */

.woocommerce table.shop_table,
.woocommerce table.shop_attributes {
    width: 100%;
    border-collapse: collapse;
    margin: 0 0 var(--wp--preset--spacing--50);
    border: var(--rivoframe-wc-border);
    border-radius: var(--rivoframe-wc-radius);
    overflow: hidden;
    font-size: var(--wp--preset--font-size--small);
}

.woocommerce table.shop_table th,
.woocommerce table.shop_attributes th {
    text-align: left;
    font-weight: 600;
    padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--40);
    background-color: var(--wp--preset--color--background-alt);
    border-bottom: var(--rivoframe-wc-border);
}

.woocommerce table.shop_table td,
.woocommerce table.shop_attributes td {
    padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--40);
    border-bottom: var(--rivoframe-wc-border);
    vertical-align: middle;
}

.woocommerce table.shop_table tr:last-child td {
    border-bottom: 0;
}

.woocommerce table.shop_table td.product-remove a.remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5em;
    height: 1.5em;
    border-radius: 50%;
    color: var(--wc-red);
    text-decoration: none;
    font-weight: 700;
    line-height: 1;
}

.woocommerce table.shop_table td.product-remove a.remove:hover {
    background-color: var(--wc-red);
    color: var(--wp--preset--color--background);
}

/* The single-product attributes table is a two-column key/value grid with
   banded rows — a different shape from the cart/order tables above, which are
   borderless rows on the page ground. */
.woocommerce table.shop_attributes {
    border-collapse: separate;
    border-spacing: 0;
}

.woocommerce table.shop_attributes th,
.woocommerce table.shop_attributes td {
    padding: 10px 16px;
    border-bottom: var(--rivoframe-wc-border);
    background-color: transparent;
    font-weight: 400;
    vertical-align: middle;
}

/* The label column is divided from its value, not just from the row below —
   the reference draws the attributes as a full grid, not as banded rows. */
.woocommerce table.shop_attributes th {
    width: 30%;
    border-right: var(--rivoframe-wc-border);
    font-weight: 400;
}

.woocommerce table.shop_attributes tr:nth-child(even) th,
.woocommerce table.shop_attributes tr:nth-child(even) td {
    background-color: var(--wp--preset--color--background-alt);
}

.woocommerce table.shop_attributes tr:last-child th,
.woocommerce table.shop_attributes tr:last-child td {
    border-bottom: 0;
}

.woocommerce table.shop_attributes p {
    margin: 0;
}

.woocommerce table.shop_table img {
    width: 3.5rem;
    height: auto;
    border-radius: var(--rivoframe-wc-radius);
}

.woocommerce .cart-collaterals .cart_totals,
.woocommerce-checkout #order_review {
    padding: var(--wp--preset--spacing--40);
    border: var(--rivoframe-wc-border);
    border-radius: var(--rivoframe-wc-radius);
    background-color: var(--wp--preset--color--background-alt);
}

.woocommerce .cart-collaterals .cart_totals h2,
.woocommerce-checkout #order_review_heading {
    font-size: var(--wp--preset--font-size--x-large);
    margin-top: 0;
}

.woocommerce .cart-collaterals .cart_totals table.shop_table {
    border: 0;
    margin-bottom: 0;
}

.woocommerce .wc-proceed-to-checkout {
    padding-top: var(--wp--preset--spacing--30);
}

.woocommerce .wc-proceed-to-checkout .checkout-button {
    display: block;
    text-align: center;
}

.woocommerce table.cart td.actions {
    text-align: right;
}

.woocommerce table.cart td.actions .coupon {
    display: flex;
    gap: var(--wp--preset--spacing--20);
    float: left;
    max-width: 60%;
}

/* -------------------------------------------------------------------------
 * 6. My Account
 * ---------------------------------------------------------------------- */

/* woocommerce-blocktheme.css caps .wp-block-post-title at 1000px on the
   account, cart, checkout and order-received pages. Inside the page-header
   band that cap centres the title on a narrower axis than the breadcrumb
   beside it, so the two visibly disagree.

   The replacement must be the band's own width, not `none`: this selector
   outranks the constrained-layout rule that supplies the 1200px cap, so
   `none` would release the title to the full viewport instead of realigning
   it. */
.rivoframe-page-header .wp-block-post-title,
.rivoframe-page-header .wp-block-query-title,
.rivoframe-page-header .wp-block-heading {
    max-width: var(--wp--style--global--wide-size);
}

/* The same stylesheet caps `div.woocommerce` itself at 1000px, which is what
   held the whole account layout to 1000 inside a 1290 content column. Here
   `none` IS correct — unlike the title above, this element's width is supplied
   by its 1290px parent, not by a constrained-layout rule, so releasing the cap
   fills the column rather than escaping to the viewport. */
.woocommerce-account .wp-block-post-content > .woocommerce {
    max-width: none;
}

/* Logged-out account screen.
 *
 * Woo's form-login.php adds its own <h2>Login</h2> directly above the form,
 * which reads as a second title under the page H1. The H2 is kept (it labels
 * the form, and the register form gets a matching one on two-column setups)
 * but demoted to a quiet legend that sits with the form.
 *
 * The form itself is constrained: at full width it stretched to 1290px, which
 * left two short fields spanning the whole column. */
.woocommerce-account .woocommerce > h2,
.woocommerce-account .u-column1 > h2,
.woocommerce-account .u-column2 > h2 {
    max-width: 28rem;
    margin: 0 auto var(--wp--preset--spacing--30);
    font-size: var(--wp--preset--font-size--large);
    font-weight: 600;
    letter-spacing: 0;
}

.woocommerce-account form.login,
.woocommerce-account form.register,
.woocommerce-account form.lost_reset_password {
    max-width: 28rem;
    margin-inline: auto;
}

/* The submit on each of those forms is the screen's only action, and reads as
   a full-width bar rather than an inline button — same treatment as Place
   Order and Proceed to Checkout in section 14. */
.woocommerce-account form.login button[type="submit"],
.woocommerce-account form.register button[type="submit"],
.woocommerce-account form.lost_reset_password button[type="submit"] {
    width: 100%;
    min-height: 48px;
    font-size: var(--wp--preset--font-size--medium);
    font-weight: 400;
}

/* Two-column account layout: fixed 259px sidebar, fluid content, 28px gutter.
 *
 * Woo's markup is `div.woocommerce > nav.…-navigation + div.…-content`. The
 * `:has()` guard keeps the flex context off the logged-out screen, whose
 * `.woocommerce` holds only the centred login form and must keep its auto
 * margins. Flex replaces the old float pair, which needed a clearfix. */
.woocommerce-account .woocommerce:has(> .woocommerce-MyAccount-navigation) {
    display: flex;
    align-items: flex-start;
    gap: 28px;
}

.woocommerce-account .woocommerce-MyAccount-navigation {
    flex: 0 0 259px;
}

.woocommerce-account .woocommerce-MyAccount-content {
    flex: 1 1 auto;
    min-width: 0;
}

/* The nav is a white card: one border around the list, hairlines between rows,
   and a full-bleed blue active row. */
.woocommerce-account .woocommerce-MyAccount-navigation ul {
    list-style: none;
    margin: 0;
    padding: 0;
    background-color: var(--wp--preset--color--background);
    border: var(--rivoframe-wc-border);
    border-radius: var(--rivoframe-wc-radius);
    overflow: hidden;
}

/* Both blockGap and the paragraph rhythm reach these list items, and
   woocommerce-blocktheme.css pads them 16px top and bottom on top of that —
   which is what pushed an 53px row to 86px and left a dead band above and
   below each link, outside the hover and active fills. Zero both, and the
   row's height is the anchor's own. */
.woocommerce-account .woocommerce-MyAccount-navigation li {
    margin: 0;
    padding: 0;
}

.woocommerce-account .woocommerce-MyAccount-navigation li + li {
    border-top: var(--rivoframe-wc-border);
}

/* `display: flex` on the anchor (not the li) is what makes the whole row
   clickable and lets the active background run the full card width. */
.woocommerce-account .woocommerce-MyAccount-navigation.woocommerce-MyAccount-navigation li a {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 53px;
    padding: 0 20px;
    color: var(--wp--preset--color--foreground);
    font-size: 15px;
    font-weight: 400;
    line-height: 1.4;
    /* These read as navigation rows, not as links in a sentence — the row
       fill and the icon carry the affordance. The underline in
       `.woocommerce-MyAccount-content a` below is for body copy and stays.

       woocommerce-blocktheme.css underlines the active row (0-4-1) and every
       row on hover (0-3-2), which is why the nav class is doubled on this
       rule and on the two state rules below. */
    text-decoration: none;
    transition: var(--wp--custom--transition);
}

/* Icons are drawn as masks, not background images, so `currentColor` carries
   them: they turn white on the active row and follow the dark style variations
   for free. A background-image would need a second copy per state. */
.woocommerce-account .woocommerce-MyAccount-navigation li a::before {
    content: "";
    flex: 0 0 20px;
    width: 20px;
    height: 20px;
    background-color: currentColor;
    /* Longhands, deliberately not the `mask` shorthand. The shorthand resets
       mask-image to `none`, and this rule outranks the per-item rules below
       (same two classes, one more element in the selector), so using it here
       blanks every icon into a solid square. */
    -webkit-mask-position: center;
    -webkit-mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-position: center;
    mask-size: contain;
    mask-repeat: no-repeat;
}

.woocommerce-account .woocommerce-MyAccount-navigation-link--dashboard a::before {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='3' width='7' height='7' rx='1'/%3E%3Crect x='14' y='3' width='7' height='7' rx='1'/%3E%3Crect x='14' y='14' width='7' height='7' rx='1'/%3E%3Crect x='3' y='14' width='7' height='7' rx='1'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='3' width='7' height='7' rx='1'/%3E%3Crect x='14' y='3' width='7' height='7' rx='1'/%3E%3Crect x='14' y='14' width='7' height='7' rx='1'/%3E%3Crect x='3' y='14' width='7' height='7' rx='1'/%3E%3C/svg%3E");
}

.woocommerce-account .woocommerce-MyAccount-navigation-link--orders a::before {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z'/%3E%3Cpath d='M3 6h18'/%3E%3Cpath d='M16 10a4 4 0 0 1-8 0'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z'/%3E%3Cpath d='M3 6h18'/%3E%3Cpath d='M16 10a4 4 0 0 1-8 0'/%3E%3C/svg%3E");
}

.woocommerce-account .woocommerce-MyAccount-navigation-link--downloads a::before {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/%3E%3Cpolyline points='7 10 12 15 17 10'/%3E%3Cline x1='12' y1='15' x2='12' y2='3'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/%3E%3Cpolyline points='7 10 12 15 17 10'/%3E%3Cline x1='12' y1='15' x2='12' y2='3'/%3E%3C/svg%3E");
}

.woocommerce-account .woocommerce-MyAccount-navigation-link--edit-address a::before {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'/%3E%3Cpolyline points='9 22 9 12 15 12 15 22'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'/%3E%3Cpolyline points='9 22 9 12 15 12 15 22'/%3E%3C/svg%3E");
}

.woocommerce-account .woocommerce-MyAccount-navigation-link--edit-account a::before {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='12' cy='7' r='4'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='12' cy='7' r='4'/%3E%3C/svg%3E");
}

.woocommerce-account .woocommerce-MyAccount-navigation-link--customer-logout a::before {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4'/%3E%3Cpolyline points='16 17 21 12 16 7'/%3E%3Cline x1='21' y1='12' x2='9' y2='12'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4'/%3E%3Cpolyline points='16 17 21 12 16 7'/%3E%3Cline x1='21' y1='12' x2='9' y2='12'/%3E%3C/svg%3E");
}

.woocommerce-account .woocommerce-MyAccount-navigation.woocommerce-MyAccount-navigation li a:hover {
    background-color: var(--wp--preset--color--surface);
    text-decoration: none;
}

.woocommerce-account .woocommerce-MyAccount-navigation.woocommerce-MyAccount-navigation li.is-active a,
.woocommerce-account .woocommerce-MyAccount-navigation.woocommerce-MyAccount-navigation li.is-active a:hover {
    background-color: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--background);
    text-decoration: none;
}

/* Body copy inside the account panels underlines its links; buttons opt out. */
.woocommerce-account .woocommerce-MyAccount-content a {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.woocommerce-account .woocommerce-MyAccount-content a.button,
.woocommerce-account .woocommerce-MyAccount-content .button {
    text-decoration: none;
}

/* Addresses: two dashed cards side by side, each wrapping its own title row. */
.woocommerce-account .addresses {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 30px;
}

.woocommerce-account .addresses .title {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--wp--preset--spacing--30);
}

.woocommerce-account .addresses .title h2,
.woocommerce-account .addresses .title h3 {
    margin: 0;
    font-size: var(--wp--preset--font-size--medium);
    font-weight: 700;
}

.woocommerce-account .woocommerce-Address {
    margin-bottom: 0;
    padding: 24px 30px 30px;
    border: 1px dashed var(--wp--preset--color--border);
    border-radius: var(--rivoframe-wc-radius);
}

.woocommerce-account .woocommerce-Address address {
    font-style: normal;
    margin: 0;
    line-height: 1.7;
}

@media (max-width: 781px) {
    .woocommerce-account .woocommerce:has(> .woocommerce-MyAccount-navigation) {
        display: block;
    }

    .woocommerce-account .woocommerce-MyAccount-navigation {
        margin-bottom: 30px;
    }

    .woocommerce-account .addresses {
        grid-template-columns: minmax(0, 1fr);
    }
}


/* -------------------------------------------------------------------------
 * 7. Classic archive controls
 *
 * Blockified templates use Woo blocks for these, but classic templates,
 * shortcodes and widgets still emit this markup.
 * ---------------------------------------------------------------------- */

.woocommerce .woocommerce-breadcrumb {
    margin: 0 0 var(--wp--preset--spacing--40);
    color: var(--wp--preset--color--foreground-light);
}

/* The trail is quieter than the eyebrow it borrows its type from: 11px / 500
   rather than 12px / 600.
   
   Only the weight is settled here. The *size* has to come from the block's
   own `fontSize` attribute in `templates/single-product.html`: the block
   declares `"fontSize": {"default": "small"}`, so it always renders
   `has-small-font-size` — a preset class, and core emits those with
   `!important`, which no selector can outrank. Setting the attribute to
   `xx-small` makes Breadcrumbs::render() drop the small class instead.
   `.woocommerce-breadcrumb` is the classic markup, which carries no preset
   class and so takes its size from here.

   `is-style-eyebrow` reaches the block wrapper at 0-2-0, so the leading
   `body` (0-2-1) is what wins for the weight — the theme's stylesheet and
   the global-styles block that carries the variation are both in the head,
   and their order is not something to rely on. */
body .wp-block-woocommerce-breadcrumbs.is-style-eyebrow,
.woocommerce .woocommerce-breadcrumb {
    font-weight: 500;
}

.woocommerce .woocommerce-breadcrumb {
    font-size: var(--wp--preset--font-size--xx-small);
}

.woocommerce .woocommerce-breadcrumb a {
    color: var(--wp--preset--color--foreground-light);
}

.woocommerce .woocommerce-breadcrumb a:hover {
    color: var(--wp--preset--color--primary);
}

/* Breadcrumb links carry the link colour; the current page stays quiet.
   `is-style-eyebrow` supplies the type, and its own `elements.link` block
   paints every link muted grey — which is right for post terms but wrong
   here, so this reclaims the trail. One more element in the selector beats
   the block style variation's 0-2-0. */
.wp-block-woocommerce-breadcrumbs.is-style-eyebrow a,
.woocommerce .woocommerce-breadcrumb a {
    color: var(--wp--preset--color--primary);
}

.wp-block-woocommerce-breadcrumbs.is-style-eyebrow a:hover,
.woocommerce .woocommerce-breadcrumb a:hover {
    color: var(--wp--preset--color--primary-dark);
    text-decoration: underline;
}

.rivoframe-breadcrumb-sep {
    margin: 0 2px;
    color: var(--wp--preset--color--foreground-light);
}

.woocommerce .woocommerce-result-count {
    float: left;
    margin: 0 0 var(--wp--preset--spacing--40);
    color: var(--wp--preset--color--foreground-light);
    font-size: var(--wp--preset--font-size--small);
}

.woocommerce .woocommerce-ordering {
    float: right;
    margin: 0 0 var(--wp--preset--spacing--40);
}

.woocommerce .woocommerce-ordering select {
    padding: 0.4rem 0.6rem;
    border: var(--rivoframe-wc-border);
    border-radius: var(--rivoframe-wc-radius);
    background-color: var(--wp--preset--color--background);
    color: var(--wp--preset--color--foreground);
    font-size: var(--wp--preset--font-size--small);
    font-family: inherit;
}

.woocommerce nav.woocommerce-pagination {
    clear: both;
    text-align: center;
    padding: var(--wp--preset--spacing--50) 0;
}

.woocommerce nav.woocommerce-pagination ul {
    display: inline-flex;
    flex-wrap: wrap;
    gap: var(--wp--preset--spacing--20);
    list-style: none;
    margin: 0;
    padding: 0;
    border: 0;
}

.woocommerce nav.woocommerce-pagination ul li {
    border: 0;
    margin: 0;
}

.woocommerce nav.woocommerce-pagination ul li a,
.woocommerce nav.woocommerce-pagination ul li span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.25rem;
    height: 2.25rem;
    padding: 0 0.5rem;
    border: var(--rivoframe-wc-border);
    border-radius: var(--rivoframe-wc-radius);
    color: var(--wp--preset--color--foreground);
    text-decoration: none;
    font-size: var(--wp--preset--font-size--small);
}

.woocommerce nav.woocommerce-pagination ul li a:hover {
    border-color: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--primary);
}

.woocommerce nav.woocommerce-pagination ul li span.current {
    background-color: var(--wp--preset--color--primary);
    border-color: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--background);
    font-weight: 600;
}

/* -------------------------------------------------------------------------
 * 8. Classic product loop
 *
 * Emitted by [products] shortcodes, widgets and related/upsell sections.
 * ---------------------------------------------------------------------- */

.woocommerce ul.products {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--rivoframe-wc-gap);
    list-style: none;
    margin: 0 0 var(--wp--preset--spacing--50);
    padding: 0;
    clear: both;
}

.woocommerce ul.products li.product {
    display: flex;
    flex-direction: column;
    gap: var(--wp--preset--spacing--20);
    margin: 0;
    padding: var(--wp--preset--spacing--40);
    border: var(--rivoframe-wc-border);
    border-radius: var(--rivoframe-wc-radius);
    position: relative;
    text-align: left;
}

.woocommerce ul.products li.product img {
    display: block;
    width: 100%;
    height: auto;
    margin-bottom: var(--wp--preset--spacing--20);
    border-radius: var(--rivoframe-wc-radius);
}

.woocommerce ul.products li.product .woocommerce-loop-product__title {
    font-size: var(--wp--preset--font-size--large);
    font-weight: 600;
    line-height: 1.3;
    margin: 0;
    padding: 0;
}

.woocommerce ul.products li.product a {
    text-decoration: none;
}

.woocommerce ul.products li.product .star-rating {
    font-size: 0.857em;
    margin: 0;
}

.woocommerce ul.products li.product .button {
    margin-top: auto;
    align-self: flex-start;
}

/* Sale and stock badges. */
.woocommerce span.onsale {
    position: absolute;
    top: var(--wp--preset--spacing--30);
    left: var(--wp--preset--spacing--30);
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 1.8em;
    padding: 0.25em 0.7em;
    background-color: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--background);
    border-radius: 3px;
    font-size: var(--wp--preset--font-size--small);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    line-height: 1;
    margin: 0;
}

.woocommerce .stock {
    font-size: var(--wp--preset--font-size--small);
    color: var(--wc-green);
    margin: 0;
}

.woocommerce .stock.out-of-stock {
    color: var(--wc-red);
}

/* Prices. */
.woocommerce .price,
.woocommerce ul.products li.product .price {
    color: var(--wp--preset--color--foreground);
    font-weight: 600;
    display: block;
}

.woocommerce .price del,
.woocommerce ul.products li.product .price del {
    color: var(--wp--preset--color--foreground-light);
    font-weight: 400;
    opacity: 1;
    margin-right: 0.35em;
}

.woocommerce .price ins,
.woocommerce ul.products li.product .price ins {
    text-decoration: none;
    font-weight: 700;
}

.woocommerce .price .woocommerce-Price-currencySymbol {
    font-weight: inherit;
}

/* -------------------------------------------------------------------------
 * 9. Single product - classic sections
 * ---------------------------------------------------------------------- */

.woocommerce div.product .woocommerce-tabs ul.tabs {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--wp--preset--spacing--50);
    list-style: none;
    margin: 0 0 var(--wp--preset--spacing--50);
    padding: 0 0 var(--wp--preset--spacing--20);
    border-bottom: var(--rivoframe-wc-border);
}

.woocommerce div.product .woocommerce-tabs ul.tabs li {
    margin: 0;
    padding: 0;
    background: none;
    border: 0;
}

.woocommerce div.product .woocommerce-tabs ul.tabs li a {
    display: block;
    padding: var(--wp--preset--spacing--20) 0;
    color: var(--wp--preset--color--foreground-light);
    text-decoration: none;
    font-weight: 600;
    font-size: var(--wp--preset--font-size--small);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    border-bottom: 2px solid transparent;
}

.woocommerce div.product .woocommerce-tabs ul.tabs li.active a,
.woocommerce div.product .woocommerce-tabs ul.tabs li a:hover {
    color: var(--wp--preset--color--primary);
    border-bottom-color: var(--wp--preset--color--primary);
}

/* The tabs render through the `woocommerce/product-details` block, whose
   `is-style-minimal` stylesheet (product-details.css) reaches them as
   `html body .wp-block-woocommerce-product-details.is-style-minimal
   ul.tabs.wc-tabs …` — up to 0-5-5. That outranks every rule above, and it
   zeroes the rail under the tab row (`border-bottom-width: 0`), dims each tab
   to `opacity: .65` and forces `color: inherit` on the active one. The block
   below answers at the same shape with one class doubled, so the rail, the
   muted/active colours and the underline survive. */
html body .wp-block-woocommerce-product-details.is-style-minimal
    ul.tabs.wc-tabs.wc-tabs {
    padding-bottom: 0;
    border-bottom: var(--rivoframe-wc-border);
}

/* The underline moves from the <a> to the <li> so it lands on the rail rather
   than floating above it; the -1px pulls the two together. */
html body .wp-block-woocommerce-product-details.is-style-minimal
    ul.tabs.wc-tabs.wc-tabs li {
    margin-bottom: -1px;
    border-bottom: 2px solid transparent;
    opacity: 1;
}

html body .wp-block-woocommerce-product-details.is-style-minimal
    ul.tabs.wc-tabs.wc-tabs li a {
    padding: var(--wp--preset--spacing--20) 0;
    border-bottom: 0;
    color: var(--wp--preset--color--foreground-light);
}

html body .wp-block-woocommerce-product-details.is-style-minimal
    ul.tabs.wc-tabs.wc-tabs li.active {
    border-bottom-color: var(--wp--preset--color--primary);
}

html body .wp-block-woocommerce-product-details.is-style-minimal
    ul.tabs.wc-tabs.wc-tabs li.active a,
html body .wp-block-woocommerce-product-details.is-style-minimal
    ul.tabs.wc-tabs.wc-tabs li a:hover {
    color: var(--wp--preset--color--primary);
}

/* The active tab already labels the panel, so Woo's duplicate <h2> is hidden
   visually but left in the accessibility tree. */
.woocommerce div.product .woocommerce-tabs .panel > h2:first-child {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Reviews.
 *
 * Two columns: the review list on the left, the review form on the right —
 * the same split as the reference. Both children of #reviews are plain
 * wrappers, so the grid needs nothing from the markup. */
.woocommerce #reviews.woocommerce-Reviews {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    column-gap: 5%;
    row-gap: var(--wp--preset--spacing--50);
}

@media (max-width: 781px) {
    .woocommerce #reviews.woocommerce-Reviews {
        grid-template-columns: 1fr;
    }
}

.woocommerce #reviews #comments,
.woocommerce #reviews #review_form_wrapper {
    min-width: 0;
}

/* "Reviews" and "Be the first to review …" are the two column headings and
   read at the same size; left alone the first is an <h2> carrying the
   document's heading scale. */
.woocommerce #reviews .woocommerce-Reviews-title,
.woocommerce #reviews #respond .comment-reply-title {
    display: block;
    margin: 0 0 var(--wp--preset--spacing--30);
    font-size: var(--wp--preset--font-size--medium);
    font-weight: 600;
    line-height: 1.4;
}

/* Inside the reviews column this is body copy, not one of section 3's
   banners. */
.woocommerce #reviews .woocommerce-noreviews {
    display: block;
    margin: 0;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 0;
    color: var(--wp--preset--color--foreground-light);
    font-size: var(--wp--preset--font-size--small);
}

.woocommerce #reviews #comments ol.commentlist {
    list-style: none;
    margin: 0 0 var(--wp--preset--spacing--50);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--wp--preset--spacing--40);
}

.woocommerce #reviews #comments ol.commentlist li .comment_container {
    display: flex;
    gap: var(--wp--preset--spacing--30);
    padding: var(--wp--preset--spacing--40);
    border: var(--rivoframe-wc-border);
    border-radius: var(--rivoframe-wc-radius);
}

.woocommerce #reviews #comments ol.commentlist li img.avatar {
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    flex-shrink: 0;
}

.woocommerce #reviews #comments ol.commentlist li .comment-text {
    flex: 1;
    min-width: 0;
}

.woocommerce #reviews #comments ol.commentlist li .meta {
    font-size: var(--wp--preset--font-size--small);
    color: var(--wp--preset--color--foreground-light);
    margin-bottom: var(--wp--preset--spacing--20);
}

/* Quantity control — a single bordered box holding minus/number/plus.
   assets/js/quantity-stepper.js injects the two buttons (the theme's first
   script); without JS the field still works as a plain number input, so the
   box degrades to something usable rather than broken. */
.woocommerce .quantity {
    display: inline-flex;
    align-items: stretch;
    height: 48px;
    border: var(--rivoframe-wc-border);
    border-radius: var(--rivoframe-wc-radius);
    overflow: hidden;
    background-color: var(--wp--preset--color--background-alt);
}

.woocommerce .quantity .qty {
    box-sizing: border-box;
    width: 56px;
    flex: 1 1 auto;
    height: 100%;
    padding: 0 8px;
    text-align: center;
    color: var(--wp--preset--color--foreground);
    background-color: transparent;
    border: 0;
    font-size: var(--wp--preset--font-size--medium);
    -moz-appearance: textfield;
}

.woocommerce .quantity .qty::-webkit-inner-spin-button,
.woocommerce .quantity .qty::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.woocommerce .quantity .qty:focus {
    outline: 2px solid var(--wp--preset--color--primary);
    outline-offset: -2px;
}

.woocommerce .quantity .qty-button {
    flex: 0 0 40px;
    width: 40px;
    height: 100%;
    border: 0;
    background-color: var(--wp--preset--color--background-alt);
    color: var(--wp--preset--color--foreground);
    font-size: var(--wp--preset--font-size--medium);
    line-height: 1;
    cursor: pointer;
}

.woocommerce .quantity .qty-button--minus {
    border-right: var(--rivoframe-wc-border);
}

.woocommerce .quantity .qty-button--plus {
    border-left: var(--rivoframe-wc-border);
}

.woocommerce .quantity .qty-button:hover:not(:disabled) {
    background-color: var(--wp--preset--color--background);
}

.woocommerce .quantity .qty-button:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.woocommerce div.product form.cart {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-bottom: var(--wp--preset--spacing--40);
}

/* Add to cart shares the rest of the row with the quantity box — and, once
   assets/js/single-add-to-cart.js reveals it, with the "View cart" link
   below. `flex: 1 1 0` (rather than `1 1 auto`) is what lets that link claim
   an even half instead of shrinking to its own content width. */
.woocommerce div.product form.cart button.single_add_to_cart_button {
    flex: 1 1 0;
    min-height: 48px;
}

/* Loading state while assets/js/single-add-to-cart.js's fetch is in flight. */
.woocommerce div.product form.cart button.single_add_to_cart_button.is-adding {
    position: relative;
    color: transparent;
}

.woocommerce div.product form.cart button.single_add_to_cart_button.is-adding::after {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    width: 18px;
    height: 18px;
    border: 2px solid var(--wp--preset--color--background);
    border-top-color: transparent;
    border-radius: 50%;
    animation: rivoframe-spin 0.6s linear infinite;
}

/* The "View cart" link assets/js/single-add-to-cart.js inserts right after
   the button on a successful add — a secondary pill sharing the row evenly
   with the (now half-width) "Add to cart" button. */
/* WooCommerce's own woocommerce-blocktheme.css ships `a.added_to_cart {
   display: block; margin-top: 1em; }`, written for the archive grid where the
   link stacks *under* the button. Reused here as a horizontal sibling, that
   margin does nothing useful and just pushes the link down out of alignment
   with the button beside it — margin has to be zeroed explicitly since our
   rule otherwise never touches it and the cascade lets Woo's stand. */
.woocommerce div.product form.cart a.added_to_cart.wc-forward {
    flex: 1 1 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    margin: 0;
    padding: 0 16px;
    box-sizing: border-box;
    border: var(--rivoframe-wc-border);
    border-radius: var(--rivoframe-wc-radius);
    background-color: var(--wp--preset--color--background-alt);
    color: var(--wp--preset--color--foreground);
    font-size: var(--wp--preset--font-size--medium);
    font-weight: 500;
    text-align: center;
    text-decoration: none;
}

.woocommerce div.product form.cart a.added_to_cart.wc-forward:hover {
    background-color: var(--wp--preset--color--background);
}

/* Variations stack: label over a full-width select, "Clear" beneath.
   The markup is a <table>, so each cell has to be un-tabled first. */
.woocommerce div.product form.cart .variations {
    width: 100%;
    margin-bottom: var(--wp--preset--spacing--40);
    border: 0;
}

/* One attribute per row, with air between them — without this the next
   attribute's label sits directly against the select above it. */
.woocommerce div.product form.cart .variations tr:not(:last-child) {
    margin-bottom: var(--wp--preset--spacing--40);
}

.woocommerce div.product form.cart .variations tbody,
.woocommerce div.product form.cart .variations tr,
.woocommerce div.product form.cart .variations td,
.woocommerce div.product form.cart .variations th {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    text-align: left;
}

.woocommerce div.product form.cart .variations th.label label {
    display: block;
    margin-bottom: var(--wp--preset--spacing--20);
    color: var(--wp--preset--color--foreground);
    font-size: 15px;
    font-weight: 400;
}

.woocommerce div.product form.cart .variations td.value select {
    width: 100%;
    box-sizing: border-box;
    height: 44px;
    padding: 0 16px;
    color: var(--wp--preset--color--foreground);
    background-color: var(--wp--preset--color--background-alt);
    border: var(--rivoframe-wc-border);
    border-radius: var(--rivoframe-wc-radius);
    font-size: var(--wp--preset--font-size--medium);
}

.woocommerce div.product form.cart .variations .reset_variations {
    display: inline-block;
    margin-top: var(--wp--preset--spacing--20);
    font-size: var(--wp--preset--font-size--small);
}

/* On a variable product the quantity and button are wrapped two levels
   deeper: form.cart > .single_variation_wrap > .woocommerce-variation-add-to-cart.
   The outer wrapper is the flex item of form.cart, and as a plain block it
   shrinks to the width of the quantity box plus the button — which is what
   leaves the button short of the column edge, with the empty
   .woocommerce-variation (price / availability) sitting in the gap. Both
   wrappers have to claim the full row for the button to fill it. */
.woocommerce div.product form.cart .single_variation_wrap {
    flex: 1 1 100%;
    width: 100%;
}

/* Woo prints this wrapper whether or not a variation is selected; only give
   it room once it has something in it. */
.woocommerce div.product .single_variation_wrap .single_variation:not(:empty) {
    margin-bottom: var(--wp--preset--spacing--30);
}

.woocommerce div.product .woocommerce-variation-add-to-cart {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    flex: 1 1 100%;
}

.woocommerce div.product .product_meta {
    font-size: var(--wp--preset--font-size--small);
    color: var(--wp--preset--color--foreground-light);
    padding-top: var(--wp--preset--spacing--30);
    border-top: var(--rivoframe-wc-border);
}

/* -------------------------------------------------------------------------
 * 10. Widgets
 * ---------------------------------------------------------------------- */

.woocommerce ul.cart_list,
.woocommerce ul.product_list_widget {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--wp--preset--spacing--30);
}

.woocommerce ul.cart_list li,
.woocommerce ul.product_list_widget li {
    display: flex;
    gap: var(--wp--preset--spacing--30);
    align-items: flex-start;
    padding: 0;
}

.woocommerce ul.cart_list li img,
.woocommerce ul.product_list_widget li img {
    width: 3rem;
    height: auto;
    border-radius: var(--rivoframe-wc-radius);
    flex-shrink: 0;
}

/* -------------------------------------------------------------------------
 * 11. Notices wrapper
 *
 * WooCommerce prints the wrapper unconditionally, so it has to collapse when
 * empty - otherwise it contributes a full blockGap of dead space to every
 * shop and product page.
 * ---------------------------------------------------------------------- */

.woocommerce-notices-wrapper {
    margin-bottom: var(--wp--preset--spacing--50);
}

.woocommerce-notices-wrapper:empty {
    display: none;
    margin: 0;
}

/* The store-notices block emits the same wrapper with a block classname and
   may contain whitespace, which defeats :empty. */
.wp-block-woocommerce-store-notices:not(:has(> *)) {
    display: none;
    margin: 0;
}

/* Section 3 already gives every notice a bottom margin; don't double it up
   on the last one inside the wrapper. */
.woocommerce-notices-wrapper > :last-child {
    margin-bottom: 0;
}

/* -------------------------------------------------------------------------
 * 12. Product gallery - classic flexslider
 *
 * templates/single-product.html uses the classic wp:woocommerce/product-image-gallery
 * block, and functions.php opts into wc-product-gallery-zoom/-lightbox/-slider,
 * so flexslider and photoswipe markup is rendered. WooCommerce's own rules for
 * it sit behind a `.woocommerce div.product div.images` prefix that the block
 * output never produces (ProductImageGallery.php wraps the gallery in
 * .wp-block-woocommerce-product-image-gallery only), so all of it is
 * reauthored here against the gallery classes directly.
 *
 * The zoom trigger is an <a> holding a visible U+1F50D emoji span, built in
 * assets/js/frontend/single-product.js. The emoji is clipped and the magnifier
 * redrawn from two pseudo-element shapes - there is no icon font involved.
 * ---------------------------------------------------------------------- */

.woocommerce-product-gallery {
    position: relative;
    width: 100%;
    margin: 0;
}

/* flexslider sizes the slide list from the image's intrinsic width, which
   leaves the gallery narrower than the column it sits in. */
.woocommerce-product-gallery .woocommerce-product-gallery__wrapper,
.woocommerce-product-gallery .woocommerce-product-gallery__image {
    width: 100%;
}

.woocommerce-product-gallery__wrapper {
    margin: 0;
    padding: 0;
    list-style: none;
}

.woocommerce-product-gallery__image,
.woocommerce-product-gallery__image a {
    display: block;
}

.woocommerce-product-gallery__image a {
    outline-offset: -2px;
}

.woocommerce-product-gallery__image img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--rivoframe-wc-radius);
}

.woocommerce-product-gallery__image--placeholder img {
    border: var(--rivoframe-wc-border);
}

/* flexslider viewport. `.flex-viewport` is added by the slider script; until
   it initialises the wrapper is a plain stack, which is an acceptable no-JS
   fallback. The inline opacity:0 on the wrapper is left alone on purpose -
   the script clears it, and forcing it visible causes a flash of
   unpositioned slides. */
.woocommerce-product-gallery .flex-viewport {
    margin-bottom: var(--rivoframe-wc-gap);
    border-radius: var(--rivoframe-wc-radius);
    overflow: hidden;
}

/* Thumbnail strip. Rendered as a bare <ol>, so the list affordances have to
   be reset before it can become a grid. Column count follows the
   data-columns attribute Woo writes in single-product/product-image.php. */
.woocommerce-product-gallery .flex-control-thumbs {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--wp--preset--spacing--20);
    margin: 0;
    padding: 0;
    list-style: none;
}

.woocommerce-product-gallery[data-columns="3"] .flex-control-thumbs {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.woocommerce-product-gallery[data-columns="5"] .flex-control-thumbs {
    grid-template-columns: repeat(5, minmax(0, 1fr));
}

.woocommerce-product-gallery .flex-control-thumbs li {
    margin: 0;
    padding: 0;
    list-style: none;
}

.woocommerce-product-gallery .flex-control-thumbs img {
    display: block;
    width: 100%;
    height: auto;
    margin: 0;
    border: 1px solid transparent;
    border-radius: var(--rivoframe-wc-radius);
    opacity: 0.55;
    cursor: pointer;
    transition: opacity 0.15s ease, border-color 0.15s ease;
}

.woocommerce-product-gallery .flex-control-thumbs img.flex-active,
.woocommerce-product-gallery .flex-control-thumbs img:hover,
.woocommerce-product-gallery .flex-control-thumbs img:focus-visible {
    border-color: var(--wp--preset--color--primary);
    opacity: 1;
}

/* Zoom / lightbox trigger. */
.woocommerce-product-gallery__trigger {
    position: absolute;
    top: var(--wp--preset--spacing--30);
    right: var(--wp--preset--spacing--30);
    z-index: 99;
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
    background-color: var(--wp--preset--color--background);
    border: var(--rivoframe-wc-border);
    border-radius: 50%;
    box-shadow: 0 1px 3px rgb(0 0 0 / 0.12);
    color: var(--wp--preset--color--foreground);
    text-decoration: none;
    cursor: pointer;
    /* Kill inherited text metrics so the clipped emoji cannot reflow the box. */
    font-size: 0;
    line-height: 0;
}

.woocommerce-product-gallery__trigger:hover,
.woocommerce-product-gallery__trigger:focus-visible {
    border-color: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--primary);
}

/* Clip the emoji; the accessible name comes from the anchor's aria-label. */
.woocommerce-product-gallery__trigger span[aria-hidden="true"] {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Magnifier lens. */
.woocommerce-product-gallery__trigger::before {
    content: "";
    display: block;
    box-sizing: content-box;
    width: 9px;
    height: 9px;
    margin: -3px 0 0 -3px;
    border: 2px solid currentColor;
    border-radius: 50%;
}

/* Magnifier handle. */
.woocommerce-product-gallery__trigger::after {
    content: "";
    position: absolute;
    top: 56%;
    left: 58%;
    display: block;
    box-sizing: content-box;
    width: 2px;
    height: 8px;
    background-color: currentColor;
    border-radius: 2px;
    transform: rotate(-45deg);
}

/* photoswipe overlay. Its own skin CSS is still enqueued, so only the
   stacking guard is needed here. */
.pswp {
    z-index: 100000;
}

/* -------------------------------------------------------------------------
 * 13. Select2 / selectWoo
 *
 * WooCommerce still enqueues its own select2.css - a separate handle, not one
 * of the three this theme drops - so the structural rules are already present
 * and this section is a re-skin, not a rebuild. Do not redeclare
 * position/display/left on the dropdown: select2.css owns the off-screen
 * `left: -100000px` trick that hides it while closed.
 *
 * The visible bug is select2's `.select2-selection--single{height:28px;
 * margin:0 0 -4px}` sitting against this theme's taller inputs inside a
 * flex-column form-row - the negative margin pulls the next label over the
 * control. Zeroing that margin is the fix; matching the height makes it look
 * right.
 *
 * Dropdown rules are unscoped on purpose: selectWoo appends the open dropdown
 * to <body>, outside any .woocommerce ancestor.
 * ---------------------------------------------------------------------- */

.woocommerce .select2-container,
.select2-container {
    box-sizing: border-box;
    max-width: 100%;
}

/* selectWoo writes an inline width from a measurement taken before this
   stylesheet lands, so !important is unavoidable. Scoped as tightly as
   possible so it cannot reach the shipping calculator or wp-admin. */
.woocommerce form .form-row .select2-container {
    width: 100% !important;
}

.select2-container--default .select2-selection--single {
    display: flex;
    align-items: center;
    box-sizing: border-box;
    height: var(--rivoframe-wc-field-height);
    margin: 0;
    padding: 0 2.25rem 0 0.75rem;
    color: var(--wp--preset--color--foreground);
    background-color: var(--wp--preset--color--background);
    border: var(--rivoframe-wc-border);
    border-radius: var(--rivoframe-wc-radius);
    font-family: inherit;
    font-size: var(--wp--preset--font-size--medium);
    line-height: 1.5;
}

.select2-container--default .select2-selection--single .select2-selection__rendered {
    /* Padding now lives on the control so the flex centring is honest. */
    padding: 0;
    color: inherit;
    line-height: inherit;
}

.select2-container--default .select2-selection--single .select2-selection__placeholder {
    color: var(--wp--preset--color--foreground-light);
}

.select2-container--default .select2-selection--single .select2-selection__clear {
    margin-right: var(--wp--preset--spacing--20);
    color: var(--wp--preset--color--foreground-light);
    font-weight: 700;
}

/* select2.css pins the arrow at top/right 1px with a fixed 26px height, which
   no longer matches the taller control. */
.select2-container--default .select2-selection--single .select2-selection__arrow {
    top: 0;
    right: 0;
    width: 2.25rem;
    height: 100%;
}

.select2-container--default .select2-selection--single .select2-selection__arrow b {
    border-color: var(--wp--preset--color--foreground-light) transparent transparent transparent;
    border-width: 5px 4px 0 4px;
}

.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
    border-color: transparent transparent var(--wp--preset--color--foreground-light) transparent;
    border-width: 0 4px 5px 4px;
}

/* Same focus ring as section 4's inputs. */
.select2-container--default.select2-container--focus .select2-selection--single,
.select2-container--default.select2-container--open .select2-selection--single {
    outline: 2px solid var(--wp--preset--color--primary);
    outline-offset: 1px;
    border-color: var(--wp--preset--color--primary);
}

/* Square off the corners where the open dropdown meets the control. */
.select2-container--default.select2-container--open.select2-container--below .select2-selection--single {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}

.select2-container--default.select2-container--open.select2-container--above .select2-selection--single {
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}

.select2-container--default.select2-container--disabled .select2-selection--single {
    background-color: var(--wp--preset--color--surface);
    color: var(--wp--preset--color--foreground-light);
    cursor: not-allowed;
}

/* Validation states, matching section 4. */
.woocommerce form .form-row.woocommerce-invalid .select2-container--default .select2-selection--single {
    border-color: var(--wc-red);
}

.woocommerce form .form-row.woocommerce-validated .select2-container--default .select2-selection--single {
    border-color: var(--wc-green);
}

.select2-dropdown {
    background-color: var(--wp--preset--color--background);
    color: var(--wp--preset--color--foreground);
    border: 1px solid var(--wp--preset--color--primary);
    border-radius: var(--rivoframe-wc-radius);
    box-shadow: 0 4px 12px rgb(0 0 0 / 0.08);
    font-size: var(--wp--preset--font-size--medium);
}

.select2-container--open .select2-dropdown--below {
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}

.select2-container--open .select2-dropdown--above {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}

.select2-search--dropdown {
    padding: var(--wp--preset--spacing--20);
}

.select2-container--default .select2-search--dropdown .select2-search__field {
    box-sizing: border-box;
    width: 100%;
    padding: 0.4rem 0.6rem;
    color: var(--wp--preset--color--foreground);
    background-color: var(--wp--preset--color--background);
    border: var(--rivoframe-wc-border);
    border-radius: var(--rivoframe-wc-radius);
    font-family: inherit;
    font-size: var(--wp--preset--font-size--small);
}

.select2-container--default .select2-results > .select2-results__options {
    max-height: 16rem;
    padding: 0;
}

.select2-container--default .select2-results__option {
    padding: 0.45rem 0.75rem;
    color: var(--wp--preset--color--foreground);
    line-height: 1.5;
}

/* selectWoo 1.0.x emits data-selected, select2 4.x emits aria-selected, and
   WooCommerce ships both scripts - match either or the highlight silently
   disappears on some pages. */
.select2-container--default .select2-results__option--highlighted[aria-selected],
.select2-container--default .select2-results__option--highlighted[data-selected] {
    background-color: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--background);
}

.select2-container--default .select2-results__option[aria-selected="true"],
.select2-container--default .select2-results__option[data-selected="true"] {
    background-color: var(--wp--preset--color--surface);
    color: var(--wp--preset--color--foreground);
}

.select2-container--default .select2-results__option[aria-disabled="true"] {
    color: var(--wp--preset--color--foreground-light);
}

/* -------------------------------------------------------------------------
 * 14. Cart and checkout blocks
 *
 * This section used to replace the float grid that woocommerce-layout.css
 * supplied for the CLASSIC cart/checkout shortcodes (.cart-collaterals,
 * form.checkout > #customer_details / #order_review).
 *
 * WooCommerce now ships the Cart and Checkout BLOCKS by default, and this
 * site renders them: the cart shows the coupon accordion, quantity stepper
 * and "Estimated total"; the checkout shows Contact information, Payment
 * options and an Order summary panel. None of the classic ids or classes that
 * section targeted are present in that DOM, and the blocks lay themselves out,
 * so the layout rules were dead weight and were removed.
 *
 * What IS needed is the handful of places where the blocks' own stylesheets
 * disagree with the theme's type scale and border colour. theme.json cannot
 * reach these: `styles.blocks` writes one rule against the block's wrapper,
 * and every value below lives on a descendant.
 *
 * If a site is deliberately switched back to the classic shortcodes, restore
 * the float grid from version control rather than re-deriving it - the two
 * grids and their sibling-degradation rules were non-obvious.
 * ---------------------------------------------------------------------- */

/* Field borders.
 *
 * checkout.css draws every input border as
 *   color-mix(in srgb, currentcolor 80%, transparent)
 * — 80% of the *text* colour. Against this theme's dark navy body text that
 * lands as a heavy near-black rule, where the reference (and the theme's own
 * classic fields in section 4) use a light hairline.
 *
 * Woo's selector is `.wc-block-components-form .wc-block-components-text-input
 * input[type="email"]` and friends, at 0-3-1. The class is doubled below to
 * clear it outright rather than tie and depend on stylesheet order —
 * `rivoframe-woocommerce` declares no dependency on the Woo block sheets. */
.wc-block-components-form .wc-block-components-text-input.wc-block-components-text-input input,
.wc-block-components-form .wc-block-components-textarea.wc-block-components-textarea,
.wc-block-components-form .wc-blocks-components-select__select.wc-blocks-components-select__select,
.wc-block-components-address-form .wc-block-components-text-input.wc-block-components-text-input input {
    border-color: var(--wp--preset--color--border);
}

.wc-block-components-form .wc-block-components-text-input.wc-block-components-text-input input:focus,
.wc-block-components-form .wc-blocks-components-select__select.wc-blocks-components-select__select:focus {
    border-color: var(--wp--preset--color--primary);
}

/* The chosen payment method. Like the field borders above, Woo draws this
   from `currentcolor`, so the "selected" ring reads as body text rather than
   as the accent — the one place on the page where the selection state has to
   be unmistakable. */
.wc-block-components-radio-control-accordion-option--checked-option-highlighted {
    border-color: var(--wp--preset--color--primary);
}

/* Step and panel headings ("Contact information", "Order summary").
 *
 * checkout.css pins these to `--wp--preset--font-size--medium` — the theme's
 * body size, 16px — so they land level with the copy beneath them instead of
 * a step above it. Woo writes that rule as
 * `.wc-block-components-title.wc-block-components-title` (0-2-0), already
 * using the doubling trick itself, so clearing it needs a third repeat. */
.wc-block-components-title.wc-block-components-title.wc-block-components-title {
    color: var(--wp--preset--color--foreground);
    font-size: 20px;
    font-weight: 500;
    line-height: 1.4;
}

/* The primary action on cart and checkout is a full-width 48px bar, taller
   and lighter than the theme's default inline button. Scoped to these two
   buttons so `styles.elements.button` still governs everything else. */
.wc-block-cart__submit-button,
.wc-block-components-checkout-place-order-button {
    min-height: 48px;
    font-size: var(--wp--preset--font-size--medium);
    font-weight: 400;
}

/* -------------------------------------------------------------------------
 * 15. Product card equal heights
 *
 * woocommerce/product-template renders each product as
 * <li class="... product ... wc-block-product"> inside a grid container, so
 * the <li> is already stretched to the row height. The card group inside it
 * is not, which is what leaves the buttons at ragged heights.
 *
 * The button uses margin-block-start, not margin-top: the card group's own
 * blockGap emits `> * + * { margin-block-start: ... }`, and overriding the
 * same longhand makes the cascade decide on specificity rather than on source
 * order.
 * ---------------------------------------------------------------------- */

/* flex-direction is not optional here. The theme's own product cards wrap
   their fields in a .wp-block-group, so a bare `display: flex` made that
   group the single flex child and worked by accident. Core patterns such as
   woocommerce-blocks/related-products have NO wrapper group - their fields
   are direct children of the <li> - so a row-direction flex laid image,
   title, price and button out side by side, collapsing each to roughly one
   character wide. Stacking explicitly is correct for both shapes. */
.wc-block-product-template > li.wc-block-product {
    display: flex;
    flex-direction: column;
    /* Core patterns centre their card text; the theme's own grid is left
       aligned. Left wins so both grids read as one system. align-items is
       deliberately left at stretch - flex-start would shrink the images to
       their intrinsic width. */
    text-align: left;
}

.wc-block-product-template > li.wc-block-product > .wp-block-group {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-width: 0;
}

.wc-block-product-template > li.wc-block-product > .wp-block-group > .wp-block-button.wc-block-components-product-button {
    margin-block-start: auto;
    padding-block-start: var(--wp--preset--spacing--30);
}

/* assets/js/product-button-cart.js folds the block's separate "N in cart" /
   "View cart" link back into the button itself: spinner while adding, then
   the button's own label becomes "View Cart". The block always renders its
   own view-cart link as a sibling — hide it here so only the button shows.
   No fallback for browsers without :has() support; the redundant link would
   just stay visible there, no worse than the theme's un-styled default. */
.wc-block-product-template .wc-block-components-product-button > span:has(> a.added_to_cart) {
    display: none;
}

.wc-block-product-template .wc-block-components-product-button.is-loading .wc-block-components-product-button__button [data-wp-text] {
    visibility: hidden;
}

.wc-block-product-template .wc-block-components-product-button.is-loading .wc-block-components-product-button__button {
    position: relative;
}

.wc-block-product-template .wc-block-components-product-button.is-loading .wc-block-components-product-button__button::after {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    width: 18px;
    height: 18px;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: rivoframe-spin 0.6s linear infinite;
}

@keyframes rivoframe-spin {
    to {
        transform: rotate(360deg);
    }
}

/* Uniform image boxes so cards start from a common baseline too. The 4:3
   box is cropped from the square source by object-fit, so no thumbnail
   regeneration is needed. */
.wc-block-product-template > li.wc-block-product .wc-block-components-product-image img {
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
    object-fit: cover;
}

/* -------------------------------------------------------------------------
 * 16. Small screens
 *
 * Replaces woocommerce-smallscreen.css: collapse the data tables into
 * stacked rows using each cell's data-title attribute as its label.
 * ---------------------------------------------------------------------- */

@media (max-width: 781px) {
    .woocommerce table.shop_table_responsive thead {
        display: none;
    }

    .woocommerce table.shop_table_responsive tr {
        display: block;
        margin-bottom: var(--wp--preset--spacing--40);
        border: var(--rivoframe-wc-border);
        border-radius: var(--rivoframe-wc-radius);
    }

    .woocommerce table.shop_table_responsive tr td {
        display: flex;
        justify-content: space-between;
        gap: var(--wp--preset--spacing--30);
        text-align: right;
        border-bottom: var(--rivoframe-wc-border);
    }

    .woocommerce table.shop_table_responsive tr td:last-child {
        border-bottom: 0;
    }

    .woocommerce table.shop_table_responsive tr td::before {
        content: attr(data-title) ": ";
        font-weight: 600;
        text-align: left;
    }

    .woocommerce table.shop_table_responsive tr td.product-remove::before,
    .woocommerce table.shop_table_responsive tr td.actions::before {
        display: none;
    }

    .woocommerce table.cart td.actions,
    .woocommerce table.cart td.actions .coupon {
        float: none;
        max-width: none;
        text-align: left;
        flex-wrap: wrap;
    }

    .woocommerce .woocommerce-result-count,
    .woocommerce .woocommerce-ordering {
        float: none;
        display: block;
    }

    /* The My Account small-screen collapse lives with the rest of the account
       layout in section 6, which owns the flex context these rules used to
       unfloat. */
}

/* -------------------------------------------------------------------------
 * 17. Block archive chrome
 *
 * The product archives render from wp:woocommerce/product-collection, so the
 * classic recipes in sections 7 and 8 never apply to them. Everything the
 * block markup needs and theme.json cannot express lives here: the grid
 * track list, pagination boxes, badge geometry and the stock overlay.
 * ---------------------------------------------------------------------- */

/* Grid geometry. Woo's own rule is
     .wc-block-product-template__responsive { grid-gap: 1.25em }
     .wc-block-product-template__responsive.columns-4 {
         grid-template-columns:
             repeat(auto-fill, minmax(max(150px, calc(25% - .9375em)), 1fr)) }
   Overriding the gap alone is not enough: auto-fill sizes its minimum track
   against the container, then fits as many as will go at the *real* gap, so a
   wider gap than Woo assumes silently drops a column. The track list has to be
   replaced outright. Doubling the class gives 0-2-0, which beats Woo's 0-1-0
   without reaching for !important.

   Four 300px cards with three 30px gutters is exactly the 1290px wide size.
   `columns-3` is kept alongside so a hand-placed three-column collection —
   the core related-products pattern, for one — still gets a real track list
   rather than falling back to Woo's auto-fill. */
.wc-block-product-template.wc-block-product-template__responsive.columns-4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 30px;
}

.wc-block-product-template.wc-block-product-template__responsive.columns-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 30px;
}

/* Badges. theme.json carries the sale badge's colour, type and padding, but
   it has no min-width and cannot move Woo's 4px corner offset. */
.wc-block-components-product-image .wc-block-components-product-sale-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    min-width: 55px;
    height: 28px;
    top: 15px;
    inset-inline-start: 15px;
    inset-inline-end: auto;
}

/* Stock overlay. ProductStockIndicator::render() emits its wrapper even when
   the product is in stock, so the base class must be hidden and only the
   out-of-stock variant shown. Backorder stays hidden, matching the
   reference design. */
.wc-block-product-template .wc-block-components-product-stock-indicator {
    display: none;
}

.wc-block-product-template .wc-block-components-product-stock-indicator--out-of-stock {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    align-self: flex-start;
    box-sizing: border-box;
    min-width: 55px;
    height: 28px;
    margin: 3px 0 0 3px; /* the image inner container already pads 12px; 12 + 3 = 15 */
    padding: 5px 10px;
    border-radius: var(--rivoframe-wc-radius);
    background-color: #24292e;
    color: #fff;
    font-size: var(--wp--preset--font-size--x-small);
    font-weight: 600;
    line-height: 1.1;
    text-align: center;
    text-transform: uppercase;
}

/* Pagination. The block emits
     nav.wp-block-query-pagination
       > div.wp-block-query-pagination-numbers
           > span.page-numbers.current | a.page-numbers
       > a.wp-block-query-pagination-next
   None of which theme.json can select. Numbers carry a transparent border so
   they occupy the same box as the bordered previous/next controls. */
.wp-block-query-pagination {
    margin-top: var(--wp--preset--spacing--60);
    font-size: var(--wp--preset--font-size--small);
    font-weight: 600;
}

.wp-block-query-pagination-numbers {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 10px;
}

.wp-block-query-pagination-numbers .page-numbers,
.wp-block-query-pagination-next,
.wp-block-query-pagination-previous {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    height: 40px;
    border: 2px solid transparent;
    border-radius: var(--rivoframe-wc-radius);
    color: var(--wp--preset--color--foreground-light);
    text-decoration: none;
    transition: var(--wp--custom--transition);
}

.wp-block-query-pagination-numbers .page-numbers {
    flex: 0 0 41px;
    width: 41px;
}

.wp-block-query-pagination-numbers .page-numbers.current {
    background-color: var(--wp--preset--color--primary);
    border-color: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--background);
}

.wp-block-query-pagination-next,
.wp-block-query-pagination-previous {
    gap: 8px;
    padding: 0 17px;
    border-color: var(--wp--preset--color--border);
    font-size: var(--wp--preset--font-size--x-small);
    text-transform: uppercase;
    white-space: nowrap;
}

.wp-block-query-pagination-numbers a.page-numbers:hover,
.wp-block-query-pagination-next:hover,
.wp-block-query-pagination-previous:hover {
    border-color: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--primary);
}

/* Grid breakpoints. The block grid had none; these mirror the reference
   theme's 1000px / 690px stops. Four columns steps down through three before
   it reaches two, so cards never jump more than one track at a stop. */
@media (max-width: 1199.98px) {
    .wc-block-product-template.wc-block-product-template__responsive.columns-4 {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 999.98px) {
    .wc-block-product-template.wc-block-product-template__responsive.columns-4,
    .wc-block-product-template.wc-block-product-template__responsive.columns-3 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 689.98px) {
    .wc-block-product-template.wc-block-product-template__responsive.columns-4,
    .wc-block-product-template.wc-block-product-template__responsive.columns-3 {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* -------------------------------------------------------------------------
 * 18. Buttons core does not reach
 *
 * theme.json's `styles.elements.button` is emitted against `.wp-element-button`
 * / `.wp-block-button__link`. WooCommerce tags most of its buttons with
 * `wp-element-button` and so inherits it for free — but not all of them: the
 * account notice's "Confirm email address" action, for one, ships as a bare
 * `a.button` and renders as an unstyled text link.
 *
 * This is NOT the Woo button CSS the theme deliberately declines to write.
 * That exclusion is about Woo's *own* stylesheet, which Woo switches off as
 * soon as a theme declares `styles.elements.button` (the
 * `woocommerce-block-theme-has-button-styles` body class). Here nothing is
 * switched off and nothing is competing — core simply supplies no style for
 * these elements, so the theme does. The `:not(.wp-element-button)` guard
 * keeps this off every button core already handles.
 * ---------------------------------------------------------------------- */

.woocommerce a.button:not(.wp-element-button),
.woocommerce button.button:not(.wp-element-button),
.woocommerce input.button:not(.wp-element-button),
.wc-block-components-notice-banner a.button:not(.wp-element-button) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* theme.css boxes `.wp-element-button`; these buttons carry neither that
       class nor `.wp-block-button__link`, so without this the 5px padding is
       added to the 40px and they stand 50px beside a 40px one — visible on
       the Orders screen, where "Confirm email address" sits directly above
       "Browse products". */
    box-sizing: border-box;
    min-height: 40px;
    padding: 5px 20px;
    background-color: var(--wp--preset--color--primary);
    border: 0;
    border-radius: var(--wp--custom--border--radius);
    color: var(--wp--preset--color--background);
    font-family: inherit;
    font-size: 15px;
    font-weight: 500;
    line-height: 1.5;
    text-decoration: none;
    cursor: pointer;
    transition: var(--wp--custom--transition);
}

.woocommerce a.button:not(.wp-element-button):hover,
.woocommerce button.button:not(.wp-element-button):hover,
.woocommerce input.button:not(.wp-element-button):hover,
.wc-block-components-notice-banner a.button:not(.wp-element-button):hover {
    background-color: var(--wp--preset--color--primary-dark);
    color: var(--wp--preset--color--background);
}

/* -------------------------------------------------------------------------
 * 19. Legacy product grid (wc-block-grid)
 *
 * The empty cart renders `woocommerce/empty-cart-block`, whose "New in store"
 * shelf is a `woocommerce/product-new` block. That block predates
 * `product-collection` and emits the older `wc-block-grid` markup:
 *
 *   ul.wc-block-grid__products
 *     > li.wc-block-grid__product
 *         > a.wc-block-grid__product-link
 *             > .wc-block-grid__product-image > img
 *             > .wc-block-grid__product-title
 *         > .wc-block-grid__product-price
 *         > .wp-block-button.wc-block-grid__product-add-to-cart
 *
 * None of it carries a class section 15 or 17 can reach, and Woo's own
 * all-products.css lays it out centred, on a flex row whose gutters are
 * transparent borders. Left alone the shelf reads as a different theme from
 * every other product grid on the site. These rules restate the theme's card:
 * the same four-track grid and 30px gutters, the same 4:3 image box, the same
 * left-aligned title / price / button stack.
 *
 * The class is doubled throughout for 0-3-0. Woo's small-screen rules reach
 * the same elements at 0-2-0 from inside media queries, so equal specificity
 * would leave the outcome to stylesheet order, which is not guaranteed.
 * ---------------------------------------------------------------------- */

.wc-block-grid.wc-block-grid .wc-block-grid__products {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 30px;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Woo draws this card's gutters as transparent borders and centres it. Both
   have to go before the grid gap and the theme's alignment can apply. */
.wc-block-grid.wc-block-grid .wc-block-grid__product {
    display: flex;
    flex-direction: column;
    max-width: none;
    margin: 0;
    padding: 0;
    border: 0;
    /* all-products.css shrinks the whole card with
       `.wc-block-grid.has-4-columns:not(.alignwide):not(.alignfull)
        .wc-block-grid__product { font-size: .75em }`.
       Everything the theme sets in px ignores it, but the add-to-cart link is
       sized in `em` by Woo and came out at 12px. Reset the card's own font
       size and the em chain resolves from the body again. */
    font-size: var(--wp--preset--font-size--medium);
    text-align: left;
}

.wc-block-grid.wc-block-grid .wc-block-grid__product-link {
    display: block;
    color: inherit;
    text-decoration: none;
}

.wc-block-grid.wc-block-grid .wc-block-grid__product-image {
    display: block;
    margin: 0 0 10px;
    border-radius: var(--rivoframe-wc-radius);
    overflow: hidden;
}

/* Same 4:3 box as section 15, cropped from the square thumbnail by
   object-fit rather than by regenerating an image size. */
.wc-block-grid.wc-block-grid .wc-block-grid__product-image img {
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
    object-fit: cover;
}

.wc-block-grid.wc-block-grid .wc-block-grid__product-title {
    margin: 0 0 10px;
    color: var(--wp--preset--color--foreground);
    font-size: 17px;
    font-weight: 600;
    line-height: 1.5;
}

.wc-block-grid.wc-block-grid .wc-block-grid__product-link:hover .wc-block-grid__product-title {
    color: var(--wp--preset--color--primary);
}

/* Matches `styles.blocks.woocommerce/product-price` in theme.json, which only
   reaches the product-collection block's own price element. */
.wc-block-grid.wc-block-grid .wc-block-grid__product-price {
    margin: 0 0 10px;
    color: var(--wp--preset--color--foreground-light);
    font-size: 15px;
    font-weight: 600;
}

.wc-block-grid.wc-block-grid .wc-block-grid__product-price del {
    opacity: 0.6;
}

.wc-block-grid.wc-block-grid .wc-block-grid__product-price ins {
    text-decoration: none;
}

/* The category eyebrow, added by `rivoframe_product_grid_item_categories()`
   in functions.php — this markup is not a block, so the `is-style-eyebrow`
   variation cannot reach it and its type spec is repeated here. */
.wc-block-grid.wc-block-grid .wc-block-grid__product-categories {
    margin: 0 0 10px;
    color: var(--wp--preset--color--foreground-light);
    font-size: var(--wp--preset--font-size--x-small);
    font-weight: 600;
    line-height: 1.5;
    text-transform: uppercase;
}

.wc-block-grid.wc-block-grid .wc-block-grid__product-categories a {
    color: inherit;
    text-decoration: none;
}

.wc-block-grid.wc-block-grid .wc-block-grid__product-categories a:hover {
    color: var(--wp--preset--color--primary);
    text-decoration: underline;
}

/* Buttons sit on a common baseline across the row, as in section 15, and at
   the same size — `styles.elements.button` reaches this link through
   `.wp-element-button`, but Woo re-declares `font-size: 1em` on it and
   `theme.css`'s `min-height` only covers `.wp-block-button__link` in the
   abstract, so both are restated against the card. */
.wc-block-grid.wc-block-grid .wc-block-grid__product-add-to-cart {
    margin: auto 0 0;
    padding-block-start: var(--wp--preset--spacing--30);
    text-align: left;
}

.wc-block-grid.wc-block-grid .wc-block-grid__product-add-to-cart .wp-block-button__link {
    min-height: 40px;
    padding: 5px 20px;
    font-size: 15px;
    font-weight: 500;
}

/* The sale badge is Woo's older `__product-onsale`, not the
   `product-sale-badge` section 17 styles; same geometry, different class. */
.wc-block-grid.wc-block-grid .wc-block-grid__product-onsale {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    min-width: 55px;
    height: 28px;
    top: 15px;
    right: auto;
    left: 15px;
    padding: 5px 10px;
    background-color: var(--wp--preset--color--primary);
    border: 0;
    border-radius: 3px;
    color: var(--wp--preset--color--background);
    font-size: var(--wp--preset--font-size--x-small);
    font-weight: 600;
    line-height: 1.1;
    text-transform: uppercase;
}

/* The same stops as section 17, so the two grids step down together. */
@media (max-width: 1199.98px) {
    .wc-block-grid.wc-block-grid .wc-block-grid__products {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 999.98px) {
    .wc-block-grid.wc-block-grid .wc-block-grid__products {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 689.98px) {
    .wc-block-grid.wc-block-grid .wc-block-grid__products {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* -------------------------------------------------------------------------
 * 20. Product filters (block)
 *
 * The Product Filters block ships almost unstyled: every one of its own rules
 * is wrapped in `:where()`, so it carries zero specificity and a single class
 * selector here wins. Where WooCommerce exposes a custom property we set the
 * property rather than writing a rule — that keeps the re-skin on the block's
 * supported surface and lets the style variations recolour the sidebar for
 * free, exactly like the token bridge in section 1.
 *
 * The headings inside the sidebar come from plain `core/heading` blocks that
 * the Site Editor inserts at h2/h3, which resolve to the 30px and 25px
 * presets — display sizes, far too loud for a 25% rail. They are stepped down
 * here rather than in the template so the cascade still holds if a merchant
 * re-inserts or re-levels a heading in the editor.
 * ---------------------------------------------------------------------- */

.wc-block-product-filters {
    /* Woo's own tokens, remapped onto theme presets. */
    --wc-product-filters-text-color: var(--wp--preset--color--foreground);
    --wc-product-filter-block-spacing: var(--wp--preset--spacing--40);

    --wc-product-filter-checkbox-list-label-element: var(--wp--preset--color--foreground-light);
    --wc-product-filter-checkbox-list-option-element: var(--wp--preset--color--background);
    --wc-product-filter-checkbox-list-option-element-border: var(--wp--preset--color--border);
    --wc-product-filter-checkbox-list-option-element-selected: var(--wp--preset--color--background);

    --wc-product-filter-price-slider: var(--wp--preset--color--primary);
    --wc-product-filter-price-slider-handle: var(--wp--preset--color--background);
    --wc-product-filter-price-slider-handle-border: var(--wp--preset--color--primary);

    --wc-product-filter-removable-chips-background: var(--wp--preset--color--surface);
    --wc-product-filter-removable-chips-border: var(--wp--preset--color--border);
    --wc-product-filter-removable-chips-text: var(--wp--preset--color--foreground-light);

    color: var(--wp--preset--color--foreground);
    font-size: var(--wp--preset--font-size--small);
}

/* `display: inline-flex` is the block's mobile default and survives into the
   desktop media query as `flex`. In a 25% column the rail should just be a
   normal block, and the overlay padding is only meaningful in the drawer. */
@media (min-width: 601px) {
    .wc-block-product-filters,
    .wc-block-product-filters.is-overlay-opened {
        display: block;
    }

    .wc-block-product-filters .wc-block-product-filters__overlay-content {
        padding: 0;
    }
}

/* 20.1 Headings
 *
 * "Filters" is the rail's masthead and reads as an eyebrow — the same 11px
 * uppercase spec as `is-style-eyebrow` and the results count it sits beside.
 * The per-group titles (Price, Brand, Category…) stay sentence-case at the
 * medium preset so the hierarchy is title 16px / option 14px. */

.wc-block-product-filters .wp-block-heading {
    font-family: inherit;
    letter-spacing: normal;
}

.wc-block-product-filters .wc-block-product-filters__overlay-content > .wp-block-heading:first-child {
    border-bottom: var(--rivoframe-wc-border);
    color: var(--wp--preset--color--foreground-light);
    font-size: var(--wp--preset--font-size--xx-small);
    font-weight: 600;
    letter-spacing: 0.08em;
    line-height: 1.1;
    padding-bottom: var(--wp--preset--spacing--30);
    text-transform: uppercase;
}

.wc-block-product-filters [data-block-name^="woocommerce/product-filter-"] .wp-block-heading {
    color: var(--wp--preset--color--foreground);
    font-size: var(--wp--preset--font-size--medium);
    font-weight: 600;
    line-height: var(--wp--custom--line-height--small);
    /* The template writes `margin-bottom: 0.625rem` inline, which the block
       comment also declares — so it cannot be dropped without invalidating
       the block. Overriding here keeps both in step with the theme scale. */
    margin: 0 0 var(--wp--preset--spacing--30);
}

/* 20.2 Filter groups
 *
 * A hairline between groups gives the rail the same structure the archive
 * chrome uses (section 17). `:not([hidden])` matters: the Rating and Active
 * groups render but hide themselves when they have nothing to show, and a
 * bare sibling selector would leave their rule behind as a stray line. */

.wc-block-product-filters [data-block-name^="woocommerce/product-filter-"]:not([hidden]):not(.wc-block-product-filter--hidden)
    ~ [data-block-name^="woocommerce/product-filter-"]:not([hidden]):not(.wc-block-product-filter--hidden) {
    border-top: var(--rivoframe-wc-border);
    padding-top: var(--wp--preset--spacing--40);
}

/* 20.3 Checkbox lists — brand, category, availability, rating
 *
 * The block sizes the box at `1em` and the label at `.875em`, both relative
 * to the list. Pinning the list to the medium preset is what yields a 16px
 * control against 14px text; setting a px size on the label instead would
 * desynchronise the two. */

.wc-block-product-filters .wc-block-product-filter-checkbox-list {
    font-size: var(--wp--preset--font-size--medium);
}

.wc-block-product-filters .wc-block-product-filter-checkbox-list__items {
    display: flex;
    flex-direction: column;
    gap: var(--wp--preset--spacing--20);
}

.wc-block-product-filters .wc-block-product-filter-checkbox-list__label {
    cursor: pointer;
    gap: var(--wp--preset--spacing--20);
    transition: var(--wp--custom--transition);
}

.wc-block-product-filters .wc-block-product-filter-checkbox-list__text-wrapper {
    font-size: var(--wp--preset--font-size--small);
    line-height: var(--wp--custom--line-height--medium);
}

.wc-block-product-filters .wc-block-product-filter-checkbox-list__label:hover {
    --wc-product-filter-checkbox-list-label-element: var(--wp--preset--color--foreground);
}

/* The block paints a 10%-opacity square behind the input as a stand-in for a
   box it never draws. With a real border and background below, that ghost
   only muddies the unchecked state. */
.wc-block-product-filters .wc-block-product-filter-checkbox-list__input-wrapper::before {
    display: none;
}

.wc-block-product-filters input[type="checkbox"].wc-block-product-filter-checkbox-list__input {
    border-radius: var(--rivoframe-wc-radius);
    transition: var(--wp--custom--transition);
}

.wc-block-product-filters input[type="checkbox"].wc-block-product-filter-checkbox-list__input:hover {
    border-color: var(--wp--preset--color--primary);
}

/* Woo only swaps the tick glyph on `:checked`; the box itself keeps its
   resting colours. Filling it is what makes a selection readable at a
   glance, and the tick is already mapped to the background colour above. */
.wc-block-product-filters input[type="checkbox"].wc-block-product-filter-checkbox-list__input:checked {
    background: var(--wp--preset--color--primary);
    border-color: var(--wp--preset--color--primary);
}

.wc-block-product-filters input[type="checkbox"].wc-block-product-filter-checkbox-list__input:focus-visible {
    outline: 2px solid var(--wp--preset--color--primary);
    outline-offset: 2px;
}

.wc-block-product-filters .wc-block-product-filter-checkbox-list__count {
    color: var(--wp--preset--color--foreground-light);
    font-size: var(--wp--preset--font-size--xx-small);
    opacity: 0.85;
}

.wc-block-product-filters .wc-block-product-filter-checkbox-list__show-more-button,
.wc-block-product-filters .wc-block-product-filter__show-more {
    background: none;
    border: 0;
    color: var(--wp--preset--color--primary);
    cursor: pointer;
    font-size: var(--wp--preset--font-size--x-small);
    font-weight: 600;
    padding: 0;
    text-decoration: underline;
}

/* 20.4 Price slider
 *
 * The handle hover and focus states are the one place the block hardcodes a
 * colour (#1e1e1e) instead of reading its own custom property, so they have
 * to be restated per vendor pseudo-element — they cannot be grouped, as one
 * unrecognised selector would void the whole rule. */

.wc-block-product-filters .wc-block-product-filter-price-slider__range input[type="range"]:hover::-webkit-slider-thumb,
.wc-block-product-filters .wc-block-product-filter-price-slider__range input[type="range"]:focus::-webkit-slider-thumb {
    background: var(--wp--preset--color--primary);
    border-color: var(--wp--preset--color--background);
}

.wc-block-product-filters .wc-block-product-filter-price-slider__range input[type="range"]:hover::-moz-range-thumb,
.wc-block-product-filters .wc-block-product-filter-price-slider__range input[type="range"]:focus::-moz-range-thumb {
    background: var(--wp--preset--color--primary);
    border-color: var(--wp--preset--color--background);
}

/* The two price fields are the same control as every other text input on the
   site, so they take the shared field spec from section 4 rather than the
   block's 4px-radius default. `max-width` is Woo's, and 60px truncates a
   four-figure amount once the currency suffix is appended. */
.wc-block-product-filters .wc-block-product-filter-price-slider .text input[type="text"] {
    background: var(--wp--preset--color--background);
    border: var(--rivoframe-wc-border);
    border-radius: var(--rivoframe-wc-radius);
    color: var(--wp--preset--color--foreground);
    font-size: var(--wp--preset--font-size--small);
    max-width: 96px;
    padding: 6px 8px;
    text-align: center;
}

.wc-block-product-filters .wc-block-product-filter-price-slider .text input[type="text"]:focus {
    border-color: var(--wp--preset--color--primary);
    outline: none;
}

/* 20.5 Active filters — chips and the clear action */

.wc-block-product-filters .wc-block-product-filter-removable-chips__items {
    display: flex;
    flex-wrap: wrap;
    gap: var(--wp--preset--spacing--20);
    list-style: none;
    margin: 0;
    padding: 0;
}

.wc-block-product-filters .wc-block-product-filter-removable-chips__item {
    align-items: center;
    background: var(--wp--preset--color--surface);
    border: var(--rivoframe-wc-border);
    border-radius: var(--rivoframe-wc-radius);
    color: var(--wp--preset--color--foreground-light);
    display: inline-flex;
    font-size: var(--wp--preset--font-size--x-small);
    gap: 6px;
    padding: 3px 8px;
}

.wc-block-product-filters .wc-block-product-filter-removable-chips__remove {
    background: none;
    border: 0;
    color: inherit;
    cursor: pointer;
    display: inline-flex;
    padding: 0;
}

.wc-block-product-filters .wc-block-product-filter-removable-chips__remove:hover {
    color: var(--wp--preset--color--foreground);
}

.wc-block-product-filters .wc-block-product-filter-removable-chips__remove-icon {
    height: 12px;
    width: 12px;
}

/* The clear action is a `core/button` in the outline style, which the theme
   already sizes for page-level actions. In the rail it is a secondary link,
   so it drops to the eyebrow scale. */
.wc-block-product-filters .wc-block-product-filter-clear-button .wp-block-button__link {
    font-size: var(--wp--preset--font-size--x-small);
    padding: 4px 10px;
}

/* 20.6 Mobile drawer
 *
 * Below 601px the block collapses into a bottom sheet behind a trigger
 * button. The trigger is the only filter affordance on a phone, so it is
 * given the weight of a real secondary button rather than the bare
 * `background: transparent` the block ships. */

@media (max-width: 600.98px) {
    .wc-block-product-filters .wc-block-product-filters__open-overlay {
        border: var(--rivoframe-wc-border);
        border-radius: var(--rivoframe-wc-radius);
        color: var(--wp--preset--color--foreground);
        font-size: var(--wp--preset--font-size--small);
        font-weight: 600;
        gap: 4px;
        padding: 8px 14px;
    }

    .wc-block-product-filters .wc-block-product-filters__overlay-dialog {
        border-top-left-radius: var(--rivoframe-wc-radius);
        border-top-right-radius: var(--rivoframe-wc-radius);
    }

    .wc-block-product-filters .wc-block-product-filters__overlay-header {
        border-bottom: var(--rivoframe-wc-border);
        padding-bottom: var(--wp--preset--spacing--30);
    }

    .wc-block-product-filters .wc-block-product-filters__close-overlay {
        font-size: var(--wp--preset--font-size--small);
    }
}
