/**
 * woocommerce/cart block styles.
 *
 * Hand-written plain CSS: no Tailwind source and no build step. This file is
 * enqueued as-is for the cart block from inc/class-groceria.php, so edit it
 * directly -- do not add it to the css:* scripts in package.json.
 *
 * There is no `!important` in this file, and none should be added. WooCommerce
 * ships its own stylesheet for this block (assets/client/blocks/cart.css) and
 * load order between two block stylesheets is not guaranteed, so every override
 * below wins on specificity alone. Two roots do that:
 *
 *   - the sidebar, at `.wp-block-woocommerce-cart .wc-block-cart
 *     .wc-block-cart__sidebar` -- three classes, against core's deepest
 *     frontend selector of two;
 *   - the items table, at the same three plus `table.wc-block-cart-items`.
 *
 * The table needs the extra step because core ships every one of its cart-items
 * rules twice: once as `table.wc-block-cart-items .wc-block-cart-items__row .X`
 * for the front end, and once with `.editor-styles-wrapper` in front of it for
 * the block editor. That editor copy is a class heavier, so a root that clears
 * the frontend rule still loses inside the editor -- which is what silently
 * collapsed this layout there before the table was added to the root. Keep both
 * roots when adding rules, and check any new one against the editor copy.
 *
 * Colours come from theme.json presets (`var(--wp--preset--color--…)`) and
 * sizes from literal rems, with one exception: the struck-through regular
 * price reads `--color-gray-400`, a Tailwind default that assets/css/output.css
 * puts on `:root`. There is no grey that light in the palette, and output.css
 * is enqueued on every page, so the reference resolves wherever the cart does.
 * Prefer a preset for anything else.
 *
 * Sections:
 *   1. Page frame
 *   2. Cart items (main column)
 *   3. Order summary (sidebar)
 *   4. Empty cart
 *   5. Responsive -- every media and container query in the file lives
 *      down there
 */

/* --------------------------------------------------------------------------
 * 1. Page frame
 *
 * Nothing here. The frame -- the page title's width and its margins above and
 * below the cart -- is block markup in templates/page-cart.html, so an editor
 * can see and change it.
 *
 * There used to be two rules here, on `.wp-block-post-content` and
 * `.wp-block-post-title`. Neither ever matched: they were written for a cart
 * page rendered through post-content, while page-cart.html of the day rendered
 * a hardcoded pattern instead and had no post-content block at all. The
 * template now does render post-content, so rather than wake those rules up
 * next to the block markup that already carries the same spacing, keep one
 * owner per property -- frame in the template, cart-block internals below.
 * ----------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
 * 2. Cart items (main column)
 *
 * The design (Figma 9195:7754) lays the line items out in six columns --
 * remove, image, name, price, quantity, subtotal -- inside one bordered,
 * rounded card. Core's markup only carries three cells per row (image,
 * product, total), with the price and the quantity stacked inside the middle
 * one, so the six columns are built by turning each `tr` into a grid and
 * flattening the product cell and its two wrapper divs with
 * `display: contents`. Core does the same thing to the same `tr` for its own
 * narrow layout, so the grid is its pattern, not a new one.
 *
 * Everything that reshapes the row therefore lives in section 4 behind the
 * same `@container (min-width: 700px)` that core uses to switch the desktop
 * table on. Below it core hides the header row and lays the row out its own
 * way; leaving the grid out of that range keeps the narrow layout core's.
 *
 * The `<table>`, `<thead>`, `<tbody>` and the image and total cells keep
 * their table display, and the product cell that is flattened carries an
 * explicit `role="rowheader"`, so the table's semantics survive the reshape.
 * ----------------------------------------------------------------------- */

/*
 * Every `@container` in section 4 asks whether the columns fit the table, so
 * the table's own column is what they have to measure. Core puts the only
 * container on `.wp-block-woocommerce-cart`, which spans the sidebar too: once
 * the two sit side by side core hands the main column 65%, and that reads as a
 * cart of 912px against a table of 570px. The six columns were switching on for
 * a table that could not hold them, and the product name collapsed to one
 * character per line at around 1024px.
 *
 * A container here re-bases the cart-items queries -- core's as well as this
 * file's -- onto the width they are actually about. The layout-level rules are
 * unaffected: an element is never its own query container, so the ones that
 * size this column still resolve against the cart.
 */
.wp-block-woocommerce-cart .wc-block-cart .wc-block-components-main {
    container-type: inline-size;
}

.wp-block-woocommerce-cart .wc-block-cart .wc-block-components-main table.wc-block-cart-items {
    /*
     * The one track list, shared by the header row and every item row so the
     * labels sit exactly over the values they head. The name column takes the
     * slack, because the theme's main column is fluid and the design's 894px
     * frame is not.
     *
     * These three are the tightened set, for tables narrower than the design.
     * Section 4 swaps in the design's own widths from 56rem up.
     */
    --groceria-cart-col-price: 6.875rem;
    --groceria-cart-col-quantity: 6.875rem;
    --groceria-cart-col-subtotal: 5.625rem;
    --groceria-cart-columns: 0.625rem 6.875rem minmax(0, 1fr) var(--groceria-cart-col-price) var(--groceria-cart-col-quantity) var(--groceria-cart-col-subtotal);
    --groceria-cart-gap: 0.9375rem;
    --groceria-cart-padding-inline: 1.25rem 1.875rem;

    /*
     * Core: `table.wc-block-cart-items` and `.wc-block-cart__main …-items`.
     *
     * `border-collapse` has to be reset alongside the radius. Tables collapse
     * their borders by default, and a collapsed table draws no corner curve at
     * all -- the radius computes to 8px and renders square. Separating the
     * borders is what makes it visible; `border-spacing: 0` then keeps the
     * cells flush, which is what collapsing was doing for us.
     *
     * A radius on a table clips only the table's own border and background,
     * never its rows, so the header row carries the matching top corners of
     * its own down in section 4. Item rows need none -- they have no
     * background to spill past the curve.
     */
    border: 1px solid var(--wp--preset--color--pale-gray);
    border-radius: 0.5rem;
    border-collapse: separate;
    border-spacing: 0;

    /*
     * Core widths the image and total headers in pixels for its own table
     * layout; as grid items those widths stop them stretching to their track,
     * so they are handed back to the track list.
     */
    .wc-block-cart-items__header th {
        width: auto;
        padding: 0;
        border: 0;
        font-size: 1.125rem;
        line-height: calc(1.875 / 1.125);
        font-weight: 600;
        color: var(--wp--preset--color--primary);
        text-align: start;
        text-transform: capitalize;
        white-space: nowrap;
    }

    /* Core: `.is-large.wc-block-cart .wc-block-cart-items td` in older
     * releases, `.wc-block-cart__main .wc-block-cart-items td` in 11.x. */
    tbody tr td {
        padding: 0;
        border: 0;
    }

    /*
     * The design frames the thumbnail in a 110px square that insets a 70px
     * image. Sized as a ratio rather than in pixels so the frame still fits
     * the narrow layout, where core gives the image column 80px; section 4
     * pins it to the design's 110px for the wide one.
     */
    .wc-block-cart-item__image a {
        display: flex;
        align-items: center;
        justify-content: center;
        aspect-ratio: 1;
        border: 1px solid var(--wp--preset--color--pale-gray);
        border-radius: 0.5rem;
    }

    .wc-block-cart-item__image img {
        width: calc(70 / 110 * 100%);
        height: auto;
        aspect-ratio: 1;
        object-fit: cover;
    }

    .wc-block-components-product-name {
        display: block;
        font-size: 0.938rem;
        line-height: calc(1.5 / 0.938);
        font-weight: 600;
        color: var(--wp--preset--color--primary);
    }

    .wc-block-components-product-price {
        font-size: 0.938rem;
        line-height: calc(1.5 / 0.938);
        font-weight: 600;
        color: var(--wp--preset--color--primary);
    }

    /*
     * On a sale line core prints the struck-through regular price beside the
     * discounted one. It sets no colour of its own, so without this the two
     * read at the same weight and the sale price stops standing out.
     */
    .wc-block-components-product-price__regular {
        color: var(--color-gray-400);
    }

    /*
     * The design shows the name alone under it. Only the short description is
     * dropped -- variation attributes stay, because a variable product's cart
     * row is unreadable without them.
     */
    .wc-block-components-product-metadata__description {
        display: none;
    }

    /* Pill: the radius only has to outrun half the badge's height to round. */
    .wc-block-components-product-badge {
        padding: 0.25rem 0.75rem;
        border-radius: 9999px;
        background-color: var(--wp--preset--color--treachery);
        font-size: 0.813rem;
        font-weight: 500;
        line-height: 1;
        color: var(--wp--preset--color--white);
        text-transform: capitalize;
    }

    .wc-block-components-quantity-selector {
        display: flex;
        align-items: center;
        justify-content: space-between;
        width: 5.625rem;
        height: 2.5rem;
        padding: 0.625rem;
        border: 1px solid var(--wp--preset--color--primary);
        border-radius: 0.5rem;

        .wc-block-components-quantity-selector__input {
            order: 2;
            width: 1.25rem;
            padding: 0;
            font-size: 0.875rem;
            font-weight: 500;
            color: var(--wp--preset--color--primary);

            &:focus {
                outline: none;
                box-shadow: none;
            }

            &:active {
                box-shadow: none;
            }
        }

        /* Minus, value, plus. Core's markup runs input, minus, plus, so the
         * three are ordered rather than moved. */
        .wc-block-components-quantity-selector__button {
            min-width: 0.875rem;
            padding: 0;
            font-size: 0.875rem;
            font-weight: 400;
            line-height: 1;
            color: var(--wp--preset--color--primary);

            &:focus {
                box-shadow: none;
            }
        }

        .wc-block-components-quantity-selector__button--minus {
            order: 1;
        }

        .wc-block-components-quantity-selector__button--plus {
            order: 3;
        }
    }

    /*
     * Core draws the remove control as a labelled trash button under the
     * quantity; the design is a bare 10px cross leading the row. The button
     * keeps its `aria-label`, so masking core's icon out costs nothing to a
     * screen reader. The mask is the design's own exported cross.
     */
    .wc-block-cart-item__quantity .wc-block-cart-item__remove-link {
        width: 0.625rem;
        height: 0.625rem;
        min-width: 0;
        padding: 0;
        border: 0;
        background-color: var(--wp--preset--color--primary);
        mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10"><path d="M0.49 10C0.39 10 0.3 9.97 0.22 9.92C0.14 9.86 0.07 9.79 0.04 9.7C0 9.61 -0.01 9.51 0.01 9.42C0.03 9.32 0.07 9.23 0.14 9.17L9.17 0.14C9.26 0.05 9.38 0 9.51 0C9.64 0 9.77 0.05 9.86 0.14C9.95 0.23 10 0.36 10 0.49C10 0.62 9.95 0.74 9.86 0.83L0.83 9.86C0.79 9.9 0.73 9.94 0.68 9.96C0.62 9.99 0.55 10 0.49 10Z M9.51 10C9.45 10 9.38 9.99 9.32 9.96C9.27 9.94 9.21 9.9 9.17 9.86L0.14 0.83C0.05 0.74 0 0.62 0 0.49C0 0.36 0.05 0.23 0.14 0.14C0.23 0.05 0.36 0 0.49 0C0.62 0 0.74 0.05 0.83 0.14L9.86 9.17C9.93 9.23 9.97 9.32 9.99 9.42C10.01 9.51 10 9.61 9.96 9.7C9.93 9.79 9.86 9.86 9.78 9.92C9.7 9.97 9.61 10 9.51 10Z"/></svg>');
        mask-position: center;
        mask-repeat: no-repeat;
        mask-size: contain;
        font-size: 0;
        text-decoration: none;

        svg {
            display: none;
        }
    }
}

/* --------------------------------------------------------------------------
 * 3. Order summary (sidebar)
 * ----------------------------------------------------------------------- */

.wp-block-woocommerce-cart .wc-block-cart .wc-block-cart__sidebar {
    /*
     * The gap the design leaves between a summary row and the rule under it,
     * and half the leading that has to come out of it on a row of text. A
     * 15px/26px row shows about 11px of cap height, so 7.5px of the line box
     * is leading at each end -- see the wrapper rules below.
     */
    --groceria-totals-gap: 1.25rem;
    --groceria-totals-half-leading: 0.46875rem;

    height: fit-content;
    padding: 1.875rem;
    border: 1px solid var(--wp--preset--color--pale-gray);
    border-radius: 0.5rem;

    /*
     * The design leaves 36px from the title's cap to the cap of the first row
     * under it. 8px of that is leading below the title's own cap (26px type on
     * a 36px line box), and about 6px sits above the cap of the row below, so
     * 22px is margin.
     */
    .wp-block-woocommerce-cart-order-summary-heading-block {
        margin-bottom: calc(2.25rem - 0.5rem - 0.375rem);
        padding: 0;
        font-size: 1.625rem;
        font-weight: 600;
        line-height: calc(2.25 / 1.625);
        text-transform: capitalize;
    }

    /*
     * The summary rows (Figma 9191:8155). Core wraps every row -- the coupon
     * panel included -- in a `…totals-wrapper` carrying a top rule and 16px of
     * padding. The design keeps that rule between rows but opens it to 20px,
     * and shows none above the first row or below the last.
     */
    .wc-block-components-totals-wrapper {
        padding-block: var(--groceria-totals-gap);
        border-top: 1px solid var(--wp--preset--color--pale-gray);
    }

    /*
     * The design's 20px is measured off the cap height of the text, not off its
     * line box -- Figma trims the leading away, so a row of 15/26 type reads as
     * an 11px box there and a 26px one here. Padding the line box by the full
     * 20px therefore sets the rules 7.5px further out than the design at each
     * end. Rows that hold text take the half-leading back out of the gap; the
     * coupon panel above keeps the whole 20px, because a 53px field is the
     * height it says it is.
     *
     * Matched at any depth, not as a direct child: the shipping row nests its
     * item inside a `…totals-shipping` wrapper of its own, and a `>` here left
     * that one row 15px taller than the rest.
     */
    .wc-block-components-totals-wrapper:has(.wc-block-components-totals-item) {
        padding-block: calc(var(--groceria-totals-gap) - var(--groceria-totals-half-leading));
    }

    /*
     * The design leaves 36px between the total and the button, measured off the
     * cap like every other gap in this card. That row sets 20px/28px type, so
     * 6.5px of the 36 is already leading below its cap and 29.5px is padding.
     * It carries the whole gap, so the summary block above needs no margin of
     * its own.
     */
    .wc-block-components-totals-wrapper:has(.wc-block-components-totals-footer-item) {
        padding-bottom: calc(2.25rem - 0.40625rem);
    }

    .wc-block-components-totals-coupon,
    .wc-block-components-text-input {
        input {
            height: 3.25rem;
            padding-inline: 1rem;
            padding-block: 0.75rem;
            border: 1px solid var(--wp--preset--color--pale-gray);
            border-radius: 0.5rem;
            font-size: 0.875rem;
            line-height: calc(1.25 / 0.875);
            font-weight: 500;
            color: var(--wp--preset--color--primary);

            &:focus {
                outline: none;
            }
        }
    }

    .wc-block-components-totals-coupon {
        button {
            height: 3.25rem;
            padding-inline: 1.625rem;
            padding-block: 1rem;
            border: 1px solid var(--wp--preset--color--primary);
            background-color: transparent;
            box-shadow: none;
            font-size: 0.875rem;
            line-height: calc(1.25 / 0.875);
            color: var(--wp--preset--color--primary);
            transition:
                color 0.15s cubic-bezier(0.4, 0, 0.2, 1),
                background-color 0.15s cubic-bezier(0.4, 0, 0.2, 1),
                border-color 0.15s cubic-bezier(0.4, 0, 0.2, 1),
                box-shadow 0.15s cubic-bezier(0.4, 0, 0.2, 1);
        }

    }

    /* Core: `.wc-block-cart .wp-block-woocommerce-cart-order-summary-block …`. */
    .wc-block-components-totals-coupon,
    .wc-block-components-totals-item {
        padding: 0;
    }

    .wc-block-components-totals-coupon .wc-block-components-panel__button,
    .wp-block-woocommerce-cart-order-summary-subtotal-block,
    .wc-block-components-totals-item__label,
    .wc-block-components-totals-item__value,
    .wc-block-components-totals-item__value strong {
        font-size: 0.938rem;
        font-weight: 600;
    }

    /* The design sets the amounts a weight lighter than the labels. */
    .wc-block-components-totals-item__value,
    .wc-block-components-totals-item__value strong {
        line-height: calc(1.625 / 0.938);
        font-weight: 500;
    }

    /* Core: `.wc-block-components-totals-shipping …__options …__label`. */
    .wc-block-components-radio-control__label {
        font-size: 0.875rem;
        line-height: calc(1.25 / 0.875);
    }

    .wc-block-components-radio-control__description {
        margin: 0;
        font-size: 0.813rem;
    }

    /* The wrapper's own padding is the gap the design asks for. */
    .wc-block-components-totals-footer-item {
        margin-bottom: 0;

        strong {
            text-transform: capitalize;
        }

        .wc-block-components-totals-item__label,
        .wc-block-components-totals-item__value {
            font-size: 1.25rem;
            line-height: calc(1.75 / 1.25);
            font-weight: 600;
        }
    }

    .wc-block-components-totals-shipping .wc-block-components-totals-shipping-address-summary {
        font-size: 0.938rem;
    }

    /*
     * The shipping calculator's fields. The coupon field is excluded rather
     * than out-specified: this rule and the coupon block at the foot of the
     * section otherwise land on the same specificity, and a tie settled by
     * source order is a trap for whoever reorders the file next.
     */
    .wc-block-components-text-input:not(.wc-block-components-totals-coupon__input) input[type="text"],
    .wc-blocks-components-select .wc-blocks-components-select__select {
        height: 3.5rem;
        padding-inline: 1rem;
        padding-block: 1rem;
        border: 1px solid var(--wp--preset--color--pale-gray);
        border-radius: 0.5rem;
        font-size: 0.875rem;
        line-height: calc(1.25 / 0.875);
        font-weight: 500;
        color: var(--wp--preset--color--primary);
        transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
    }

    /*
     * The shipping calculator stacks its fields, so they want space above
     * them. The coupon field is the one text input in the sidebar that sits on
     * a row of its own next to a button, and the margin was dropping it half a
     * field below that button.
     */
    .wc-block-components-text-input:not(.wc-block-components-totals-coupon__input) {
        margin-top: 2rem;
    }

    .wp-block-woocommerce-proceed-to-checkout-block {
        margin-bottom: 0;
    }

    /* Same 53px as the coupon button beside it, per the design. */
    .wc-block-cart__submit-button {
        height: 3.3125rem;
    }

    /*
     * Core strips the rule and the bottom padding off the wrappers inside the
     * totals block, which runs Subtotal, Shipping and Tax together in one
     * undivided column. The design rules between all four rows alike, so the
     * whole border is restated above rather than only its colour.
     *
     * The rows themselves then carry no margin of their own: the wrapper's
     * 20px is the whole gap, and core's 12px on top of it is what made the
     * three read so far apart.
     */
    .wc-block-components-totals-item {
        margin-bottom: 0;
    }

    /*
     * The shipping row's label. Core titles this row with the name of the
     * selected shipping rate whenever there is exactly one -- "Flat rate", the
     * title the store gave the method -- and says "Shipping" only when several
     * packages disagree, where the rate names then move to a `…__via` line
     * underneath it. The design leads with the word either way, so the
     * single-rate row draws the label core omits on a pseudo-element and drops
     * its own text to the size of that `…__via` line beneath it.
     *
     * The rate name is not replaced, only moved under the added word, and it
     * still reads exactly as WooCommerce writes it. A `content` string cannot
     * be translated, so `cart_label_styles()` in inc/class-groceria.php hands
     * the word in as a custom property built from the theme's own translated
     * string. It is declared for the front end and for the editor canvas both,
     * so the `""` fallback should never be reached; if it ever is, the row
     * keeps the rate name and loses only the line above it.
     *
     * Skipped on the row that has a `…__via` description, which is the one
     * core has already titled "Shipping" itself -- without the guard the word
     * would appear twice. The cart block renders no other shape: it drops the
     * whole row unless a rate is available, so the "Calculated at checkout"
     * placeholder core also titles "Shipping" never reaches the page.
     */
    .wc-block-components-totals-shipping:not(:has(.wc-block-components-totals-shipping__via)) {
        /*
         * Core centres the row. With two lines of label the amount belongs
         * beside the first of them.
         */
        .wc-block-components-totals-item {
            align-items: flex-start;
        }

        .wc-block-components-totals-item__label {
            font-size: 0.813rem;
            font-weight: 500;
            line-height: calc(1.25 / 0.813);

            &::before {
                display: block;
                content: var(--groceria-cart-label-shipping, "");
                font-size: 0.938rem;
                font-weight: 600;
                line-height: calc(1.625 / 0.938);
            }
        }
    }

    /*
     * Core lays the row out as a wrapping flex line with a 4px gap and always
     * prints the description element, empty or not. An empty one still counts
     * as a flex item, so it wraps to a second line and drags that 4px onto the
     * bottom of every row. Dropped only while it is empty, so a row that does
     * carry a note keeps its gap.
     */
    .wc-block-components-totals-item__description:empty {
        display: none;
    }

    /*
     * The totals block is a container of rows, not a row. It carries a rule and
     * padding of its own on top of what its rows have: the rule doubles up with
     * the first row's to draw the 2px line under the coupon panel, and the
     * padding lands as a 16px step between the last row and the footer total.
     */
    .wp-block-woocommerce-cart-order-summary-totals-block {
        padding-bottom: 0;
        border-top: 0;
    }

    /*
     * The first row, whichever it is -- the coupon panel when coupons are on,
     * the first total when they are off. The heading is an `h2`, so the wrapper
     * is still the first div among its siblings.
     */
    .wp-block-woocommerce-cart-order-summary-block > .wc-block-components-totals-wrapper:first-of-type {
        padding-top: 0;
        border-top: 0;
    }

    /* The rule the design does not draw under the last row. */
    .wp-block-woocommerce-cart-order-summary-block {
        margin-bottom: 0;
        border-bottom: 0;
    }

    /*
     * The coupon form (Figma 9191:8147): a 53px field beside an outlined
     * button, 10px apart, the button hugging its label and a 14px arrow.
     *
     * Last among the sidebar rules on purpose. Both blocks above it -- the
     * shared `.wc-block-components-text-input` sizing and the shipping
     * calculator's `input[type="text"]` -- also reach the coupon field, and
     * source order is what settles the overlap between the three.
     */
    .wc-block-components-totals-coupon__form {
        align-items: flex-start;
        gap: 0.625rem;

        /* Core: `…__form .wc-block-components-totals-coupon__input`. */
        .wc-block-components-totals-coupon__input {
            flex: 1 1 8rem;
            min-width: 0;

            input {
                height: 3.3125rem;
                padding-block: 0;
                padding-inline: 0.9375rem;
                border-width: 1px;
            }

            /*
             * Core floats this label out of the field on focus and keeps it
             * there once the field has a value, so only the things that do not
             * move are set here -- its resting offset stays core's.
             */
            label {
                left: 0.9375rem;
                font-size: 0.875rem;
                font-weight: 500;
            }
        }

        /* Core: `…__form .wc-block-components-totals-coupon__button`. */
        .wc-block-components-totals-coupon__button {
            flex: 0 0 auto;
            gap: 0.4375rem;
            height: 3.3125rem;
            padding-inline: 1.875rem;
            padding-block: 0;
            font-weight: 500;

            /* The arrow the design's button component carries. */
            &::after {
                content: "";
                width: 0.875rem;
                height: 0.875rem;
                background-color: currentcolor;
                mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14" fill="none" stroke="black" stroke-linecap="round" stroke-linejoin="round"><path d="M7.33 3.06L11.27 7L7.33 10.94M10.72 7H2.73"/></svg>');
                mask-position: center;
                mask-repeat: no-repeat;
                mask-size: contain;
            }
        }
    }
}

/* --------------------------------------------------------------------------
 * 4. Empty cart
 *
 * With nothing in the cart, core swaps the whole sidebar layout out for the
 * blocks saved inside `woocommerce/empty-cart-block`. On the cart page
 * WooCommerce ships that is a heading, a dotted rule, a second heading, and a
 * `woocommerce/product-new` grid -- so the section the design calls
 * "sale-product" (Figma 9191:15420) is drawn here out of core's oldest product
 * markup, not out of the product-collection blocks the rest of the theme uses.
 *
 * That legacy grid is `ul.wc-block-grid__products` of `li.wc-block-grid__product`,
 * and each item holds only four things: a link wrapping the sale badge, the
 * image and the title, then the price, then the add-to-cart button. It carries
 * no category, weight or rating, so the three lines the design puts above the
 * price are not available to draw here -- what follows is the card the block
 * can render, at the design's proportions.
 *
 * The block's own markup and its two headings are core's; only their styling
 * belongs to the theme.
 *
 * Root: `.wp-block-woocommerce-cart .wp-block-woocommerce-empty-cart-block`,
 * with everything inside the row nested one class deeper again under
 * `.wc-block-grid__products`. Core's heaviest selector on this grid is a
 * three-part one (`.wc-block-grid__product .wc-block-grid__product-image:not(…)`),
 * which a two-class root only ties -- and a tie is decided by load order,
 * which this file cannot rely on. Four classes clears it outright.
 * ----------------------------------------------------------------------- */

.wp-block-woocommerce-cart .wp-block-woocommerce-empty-cart-block {
    /*
     * The design's gaps are measured off the cap height, because Figma trims
     * the leading away: the 30px heading reads as a 21px box there and a 45px
     * one here, so 12px of every gap below it is already leading. The 15px
     * type on the card reads as 10.5px against a 24px line box, leaving 6.75px
     * at each end. Both come back out of the design's spacing below.
     */
    --groceria-empty-cart-heading-half-leading: 0.75rem;
    --groceria-empty-cart-card-half-leading: 0.421875rem;

    /*
     * The dotted rule sets its three glyphs in the middle of a line box as
     * tall as their own type, so half of that box is air at each end -- the
     * same correction as a cap, and taken out of the gaps around it the same
     * way.
     */
    --groceria-empty-cart-dots-half-leading: 0.75rem;

    /* The rhythm the whole block is spaced on, cap to cap. */
    --groceria-empty-cart-gap: 1.875rem;

    /*
     * "Your cart is currently empty!" -- the statement the empty state opens
     * with, and the icon core hangs off it.
     *
     * Core sets `font-size: inherit` here, so the heading renders at body size:
     * 16px, under a 36px page title, which reads as a caption rather than as
     * the message of the page. It comes up to the same 30px as the section
     * heading below -- both are `h2` and WordPress gives them the same level --
     * and the icon above it is what carries the extra weight. No capitalizing,
     * unlike that heading: this one is a sentence.
     *
     * NOTE: these are the theme's own conventions -- the 30px heading, the
     * 1.875rem rhythm the cart card already keeps -- and not measurements off
     * a design frame, which is the one thing in this file that is not. Worth
     * checking against Figma before release.
     */
    .wc-block-cart__empty-cart__title {
        /*
         * 100px above and 120px below, both asked for directly rather than
         * derived from the rhythm above -- so this heading, alone in the
         * block, is not spaced cap to cap. The top margin opens the state off
         * the page title and lands above the icon, not above the text, because
         * core draws the icon as this heading's own `::before`.
         */
        margin: 6.25rem 0 7.5rem;
        font-size: 1.875rem;
        line-height: calc(2.8125 / 1.875);
        font-weight: 600;
        color: var(--wp--preset--color--primary);
        text-align: center;
    }

    /*
     * Core sizes the icon in `em` off that inherited 16px. Raising the heading
     * to 30px would take it from 80px to 150px, so it is pinned in rem at the
     * 80px it already drew at. The `0 auto` core centres it with survives --
     * only the bottom margin is replaced.
     */
    .wc-block-cart__empty-cart__title.with-empty-cart-icon::before {
        width: 5rem;
        height: 5rem;
        margin-bottom: calc(var(--groceria-empty-cart-gap) - var(--groceria-empty-cart-heading-half-leading));
        mask-size: 5rem;
    }

    /*
     * The dotted rule between the two. theme.json already gives every
     * separator the palette's pale grey, and core's dots inherit it; what is
     * left is the spread. Core tracks a 24px glyph out by 48px, which throws
     * the three dots across the full width of the row -- at the theme's
     * 1400px they read as three unrelated marks rather than as one rule. A
     * tracking of one em draws them as the single mark they are meant to be,
     * with the matching `padding-left` that keeps them centred against the
     * trailing space the last one still carries.
     */
    .wp-block-separator.is-style-dots {
        margin-block: 0 calc(var(--groceria-empty-cart-gap) - var(--groceria-empty-cart-dots-half-leading) - var(--groceria-empty-cart-heading-half-leading));

        &::before {
            padding-left: 1em;
            font-size: 1.5rem;
            letter-spacing: 1em;
        }
    }

    /*
     * "New in store". The other heading in this block is the empty-cart title,
     * which carries a class of its own and is styled above.
     *
     * Matched at any depth rather than as a direct child: on the front end it
     * is one, but the editor renders inner blocks inside two wrappers of its
     * own and a `>` here would leave the heading unstyled there. Nothing else
     * in this block is an `h2`.
     *
     * 30px below it in the design, less the leading under its own cap -- the
     * same 30px the rest of the block is spaced on.
     */
    h2:not(.wc-block-cart__empty-cart__title) {
        margin-bottom: calc(var(--groceria-empty-cart-gap) - var(--groceria-empty-cart-heading-half-leading));
        font-size: 1.875rem;
        line-height: calc(2.8125 / 1.875);
        font-weight: 600;
        color: var(--wp--preset--color--primary);
        text-align: center;
        text-transform: capitalize;
    }

    /* Core: `.wc-block-grid`, which centres the whole section. */
    .wc-block-grid {
        margin: 0;
        text-align: start;
    }

    /*
     * The column count is the block's own `columns` attribute, which core
     * prints as a class. It is read here rather than hardcoded so that editing
     * the block in the cart page keeps working; section 5 clamps it down as
     * the row narrows.
     */
    .wc-block-grid.has-1-columns { --groceria-empty-cart-columns: 1; }
    .wc-block-grid.has-2-columns { --groceria-empty-cart-columns: 2; }
    .wc-block-grid.has-3-columns { --groceria-empty-cart-columns: 3; }
    .wc-block-grid.has-4-columns { --groceria-empty-cart-columns: 4; }
    .wc-block-grid.has-5-columns { --groceria-empty-cart-columns: 5; }
    .wc-block-grid.has-6-columns { --groceria-empty-cart-columns: 6; }

    .wc-block-grid__products {
        /*
         * Core lays the row out with flex and gutters it by hanging the list
         * on negative side margins and giving every item transparent 8px side
         * borders and a 16px bottom one. The design's card has a border of its
         * own, so those have to go -- which takes core's column widths with
         * them, since they are percentages of a flex basis. A grid with a
         * plain 20px gap replaces both.
         */
        display: grid;
        grid-template-columns: repeat(var(--groceria-empty-cart-columns, 4), minmax(0, 1fr));
        gap: 1.25rem;
        margin: 0;

        /*
         * The card. Two columns, because the design's last row sets the price
         * against the button and core gives them no wrapper to share -- the
         * link above them spans both.
         *
         * 5px of padding at the top and 20px at the sides is what insets the
         * design's 224px image frame in its 264px card; the row gap is its
         * 20px less the leading above the title's cap.
         */
        .wc-block-grid__product {
            display: grid;
            grid-template-columns: minmax(0, 1fr) auto;
            align-items: center;
            gap: calc(1.25rem - var(--groceria-empty-cart-card-half-leading)) 0.9375rem;

            /*
             * Whether the price still fits beside the button is a question
             * about this card, not about the window: it depends on the column
             * count as much as the width. Section 5 asks it here.
             */
            container-type: inline-size;

            /*
             * Core's column width, `max-width: 25%` of a flex basis it no
             * longer has. Left in place it caps the card at a quarter of its
             * own track.
             */
            max-width: none;
            margin: 0;
            padding: 0.3125rem 1.25rem 1.25rem;
            border: 1px solid var(--wp--preset--color--pearl);
            border-radius: 0.5rem;
            background-color: var(--wp--preset--color--white);
            text-align: start;
        }

        /*
         * Core wraps the badge, the image and the title in one link and leaves
         * it `inline-block`; the design stacks them, 20px apart less the
         * leading above the title's cap. They are nested here rather than
         * listed beside the price and the button because that is where the
         * markup puts them -- and because the image rule needs the depth: an
         * `img` a class shallower than the cart item's own reads to stylelint
         * as a specificity that descends, which the ratchet counts.
         */
        a.wc-block-grid__product-link {
            display: flex;
            flex-direction: column;
            gap: calc(1.25rem - var(--groceria-empty-cart-card-half-leading));
            grid-column: 1 / -1;
            margin: 0;
            text-decoration: none;

            /*
             * The image sits in a square frame and fills 190 of its 224px.
             * Kept as a ratio of the frame rather than in pixels, because the
             * theme's main column is fluid and the design's 264px card is not.
             *
             * `contain` rather than the design's `cover`: these are catalogue
             * thumbnails on white, and cropping one that is not square would
             * lose part of the product.
             */
            .wc-block-grid__product-image {
                display: flex;
                align-items: center;
                justify-content: center;
                aspect-ratio: 1;
                margin: 0;
            }

            .wc-block-grid__product-image img {
                width: calc(190 / 224 * 100%);
                height: calc(190 / 224 * 100%);
                object-fit: contain;
            }

            /*
             * Core styles this badge as a white outlined pill in the top
             * right. The design's card is not on sale and shows none, so it
             * follows the badge the theme's own product grids draw instead --
             * solid secondary, top left, inside the frame.
             */
            .wc-block-grid__product-onsale {
                top: 0.625rem;
                right: auto;
                left: 0.625rem;
                padding: 0.4375rem 0.625rem;
                border: 0;
                border-radius: 0.5rem;
                background-color: var(--wp--preset--color--secondary);
                font-size: 0.8125rem;
                line-height: 1;
                font-weight: 400;
                color: var(--wp--preset--color--white);
                text-transform: capitalize;
            }

            /* Core: `.wc-block-grid__product-title`, at 700 and 1.2. */
            .wc-block-grid__product-title {
                margin: 0;
                font-size: 0.9375rem;
                line-height: calc(1.5 / 0.9375);
                font-weight: 600;
                color: var(--wp--preset--color--primary);
            }
        }

        /*
         * On a sale item core prints the struck-through regular price first and
         * the current one second; the design reads the other way round, so the
         * row is reversed rather than the markup reordered. The screen-reader
         * spans between them are absolutely positioned and take no part in it.
         *
         * Reversed, `flex-end` is the left edge -- this row is left-aligned in
         * its track like everything else on the card.
         */
        .wc-block-grid__product-price {
            display: flex;
            flex-direction: row-reverse;
            flex-wrap: wrap;
            align-items: center;
            justify-content: flex-end;
            gap: 0.4375rem;
            margin: 0;
            font-size: 0.9375rem;
            line-height: calc(1.5 / 0.9375);
            font-weight: 600;
            color: var(--wp--preset--color--primary);
        }

        /*
         * The one colour on the card that is not a preset. There is no grey
         * this light in the palette, and `--color-gray-400` is the same
         * Tailwind default the cart items and the theme's product grids
         * already read for this price -- see the note at the top of the file.
         */
        .wc-block-grid__product-price del {
            font-size: 0.6875rem;
            line-height: calc(1.125 / 0.6875);
            font-weight: 500;
            color: var(--color-gray-400);
            text-decoration-line: line-through;
        }

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

        /*
         * theme.json fills every button with secondary. The design draws this
         * one as an outline that fills on hover, which is how the theme's own
         * product grids draw it too (`product-style v1`); the hover pair is in
         * section 5 with the rest of the queries.
         */
        .wc-block-grid__product-add-to-cart.wp-block-button {
            grid-column: 2;
            margin: 0;

            /*
             * The design's button is a fixed 35px tall with 15px at the
             * sides, so it is sized rather than padded: core already makes the
             * link an `inline-flex` that centres its label, and a min-height
             * holds the 35px whatever the label is. `nowrap` is what keeps it
             * there -- core sets `word-break: break-word` on this link, and
             * "Add to cart" is a longer label than the design's "Add".
             */
            .wp-block-button__link {
                min-height: 2.1875rem;
                align-items: center;
                padding: 0 0.9375rem;
                border: 1px solid var(--wp--preset--color--secondary);
                border-radius: 0.5rem;
                background-color: transparent;
                box-shadow: none;
                font-size: 0.8125rem;
                line-height: 1.2;
                font-weight: 500;
                color: var(--wp--preset--color--secondary);
                white-space: nowrap;
            }

            /*
             * Keyboard and touch reach the button without ever hovering the
             * card, so the filled state is repeated off the button's own
             * focus and active.
             */
            .wp-block-button__link:focus-visible,
            .wp-block-button__link:active {
                border-color: var(--wp--preset--color--secondary);
                background-color: var(--wp--preset--color--secondary);
                color: var(--wp--preset--color--white);
            }
        }
    }
}

/* --------------------------------------------------------------------------
 * 5. Responsive
 *
 * Every media and container query in this file lives here, grouped by the
 * condition it tests and kept last so each one wins over the base rule it
 * narrows.
 *
 * The cart items use `@container`, not a viewport width: core switches
 * between its narrow and wide cart layouts on `@container (min-width: 700px)`
 * against `.wp-block-woocommerce-cart`, and the six-column grid has to turn
 * on and off exactly where core's own desktop table does. The sidebar keeps
 * the theme's viewport breakpoints, which is where it has always been.
 * ----------------------------------------------------------------------- */

/*
 * Below 82rem (1312px) -- the two columns stack.
 *
 * They stack this late because the items table needs about 700px of its own to
 * hold the six columns, and side by side it only gets 65% of the cart minus a
 * gutter. Stacking below 1312px is what keeps the designed table on screen from
 * roughly 820px up instead of only on the widest desktops.
 *
 * Stacked, the two cards are siblings in core's flex layout with nothing
 * between them, so their borders meet; the row gap is what separates them. The
 * main column's side gutter goes with it, otherwise the table would sit a
 * gutter's width narrower than the summary below it.
 */
@media not all and (min-width: 82rem) {
    .wp-block-woocommerce-cart .wc-block-cart {
        row-gap: 1.875rem;

        .wc-block-components-main,
        .wc-block-cart__sidebar {
            width: 100%;
        }

        .wc-block-components-main {
            padding-right: 0;
        }
    }
}

/*
 * The narrow cart. Core lays the row out itself down here and gives it
 * `padding: 16px 0` -- no side gutters, because core's table has no frame to
 * clear. The theme's does, so without gutters the thumbnail and the sale badge
 * sit right on the card's border. The row takes the same 20px the wide layout
 * uses, on all four sides.
 *
 * Core's second track is a fixed 132px, which together with its image column
 * and the total's own column is wider than a phone once the card's gutters are
 * taken off it. Making that track flexible is what lets the row fit.
 */
@container (max-width: 699px) {
    .wp-block-woocommerce-cart .wc-block-cart .wc-block-components-main table.wc-block-cart-items {
        .wc-block-cart-items__row {
            grid-template-columns: 5rem minmax(0, 1fr);
            padding: 1.25rem;
            border-bottom: 1px solid var(--wp--preset--color--pale-gray);
        }

        .wc-block-cart-items__row:last-child {
            border-bottom: 0;
        }
    }
}

/*
 * On a phone the row runs out of width. Core keeps the line total on the first
 * grid row beside the product, and once the card's gutters and a sale badge are
 * taken off there is nothing left for the name -- it breaks mid-word. Dropping
 * the total to the second row, next to the quantity core already puts there,
 * gives the name the full measure back.
 */
@container (max-width: 30rem) {
    .wp-block-woocommerce-cart .wc-block-cart .wc-block-components-main table.wc-block-cart-items .wc-block-cart-item__total {
        grid-column: 2;
        grid-row: 2;
    }
}

/*
 * The wide cart -- the six-column card from the design. Core shows the header
 * row and its own three-column table from this width up, so this is where the
 * reshape belongs.
 */
@container (min-width: 700px) {
    .wp-block-woocommerce-cart .wc-block-cart .wc-block-components-main table.wc-block-cart-items {
        .wc-block-cart-items__header,
        .wc-block-cart-items__row {
            display: grid;
            grid-template-columns: var(--groceria-cart-columns);
            align-items: center;
            column-gap: var(--groceria-cart-gap);
            padding-inline: var(--groceria-cart-padding-inline);
        }

        .wc-block-cart-items__header {
            min-height: 3.75rem;
            background-color: var(--wp--preset--color--gray);
            border-radius: calc(0.5rem - 1px) calc(0.5rem - 1px) 0 0;
        }

        /*
         * Core gives the header three cells: a visible "Product", a
         * screen-reader-only "Details" and a visible "Total". The design asks
         * for four labels over the six columns, so "Product" spans the remove,
         * image and name tracks and the "Details" cell carries the price and
         * quantity labels. Nothing WooCommerce renders is replaced -- the two
         * labels are added where core shows none, and "Total" keeps its own
         * wording even though the design reads "Subtotal".
         *
         * They are `content` values, so they cannot be translated from a
         * stylesheet. `cart_column_label_styles()` in inc/class-groceria.php
         * hands them in as custom properties built from the theme's own
         * translated strings.
         */
        .wc-block-cart-items__header th.wc-block-cart-items__header-image {
            grid-column: 1 / 4;
            padding-left: 0.625rem;
        }

        .wc-block-cart-items__header th.wc-block-cart-items__header-product {
            display: grid;
            grid-column: 4 / 6;
            grid-template-columns: var(--groceria-cart-col-price) var(--groceria-cart-col-quantity);
            column-gap: var(--groceria-cart-gap);

            &::before {
                content: var(--groceria-cart-label-price, "");
            }

            &::after {
                content: var(--groceria-cart-label-quantity, "");
            }
        }

        /*
         * The design calls this column Subtotal; core calls it Total and
         * WooCommerce's own wording is what ships. See the note above.
         */
        .wc-block-cart-items__header th.wc-block-cart-items__header-total {
            grid-column: 6;
            text-align: start;
        }

        /*
         * The design puts a 20px gutter above and below every row's content
         * and a rule between them, with nothing under the last row.
         */
        .wc-block-cart-items__row {
            padding-block: 1.25rem;
            border-bottom: 1px solid var(--wp--preset--color--pale-gray);
        }

        .wc-block-cart-items__row:last-child {
            border-bottom: 0;
        }

        /*
         * Flatten the product cell so the name, price and quantity it wraps
         * become columns of the row instead of a stack inside one cell. The
         * two wrappers are plain divs; the cell itself carries an explicit
         * `role="rowheader"`, which is what keeps it in the accessibility
         * tree once it stops generating a box.
         */
        .wc-block-cart-item__product,
        .wc-block-cart-item__wrap,
        .wc-block-cart-item__quantity {
            display: contents;
        }

        /*
         * Column 3 is the fallback: anything core adds to the wrap that is not
         * placed below stacks under the name rather than landing in a column
         * it does not belong to.
         */
        .wc-block-cart-item__wrap > * {
            grid-column: 3;
        }

        /*
         * The name sits on the first grid row so any metadata can follow it;
         * every other column spans whatever rows that produces so it stays
         * vertically centred against the image.
         */
        .wc-block-cart-item__remove-link,
        .wc-block-cart-item__image,
        .wc-block-cart-item__prices,
        .wc-block-components-quantity-selector,
        .wc-block-cart-item__total {
            grid-row: 1 / -1;
        }

        .wc-block-cart-item__quantity .wc-block-cart-item__remove-link {
            grid-column: 1;
        }

        .wc-block-cart-item__image {
            grid-column: 2;
        }

        .wc-block-cart-item__image a {
            width: 6.875rem;
            height: 6.875rem;
        }

        .wc-block-components-product-name {
            grid-column: 3;
            grid-row: 1;
        }

        .wc-block-cart-item__prices {
            grid-column: 4;
        }

        .wc-block-components-quantity-selector {
            grid-column: 5;
        }

        .wc-block-cart-item__total {
            grid-column: 6;
            justify-content: flex-start;
        }

        /*
         * A row is one grid row unless the product carries variation data,
         * which opens a second underneath the name. Every other column spans
         * both, so the two rows meet in the middle of the row: pinning the
         * name to the end of the first and the data to the start of the second
         * sets them against each other there instead of leaving one adrift at
         * the top and the other at the bottom.
         *
         * The `:has()` guard is what keeps a simple product out of it. Core
         * renders the metadata wrapper either way, and with the description
         * hidden it collapses to nothing -- so the name would otherwise be
         * pinned to the end of a row that is the whole height.
         */
        .wc-block-cart-items__row:has(.wc-block-components-product-metadata > *:not(.wc-block-components-product-metadata__description)) {
            grid-template-rows: 1fr 1fr;

            .wc-block-components-product-name {
                align-self: end;
            }

            .wc-block-components-product-metadata {
                align-self: start;
            }
        }
    }
}

/*
 * The design's own column widths, from the width it was drawn at. Below this
 * the price, quantity and subtotal tracks tighten (see section 2) so the name
 * keeps a usable measure -- at the design's widths on a ~700px table it was
 * left with 72px and broke product names mid-word.
 */
@container (min-width: 56rem) {
    .wp-block-woocommerce-cart .wc-block-cart .wc-block-components-main table.wc-block-cart-items {
        --groceria-cart-col-price: 8.3125rem;
        --groceria-cart-col-quantity: 9.375rem;
        --groceria-cart-col-subtotal: 6.25rem;
    }
}

/*
 * The empty cart's product row, narrowing.
 *
 * The block asks for four columns and the design draws five, both against the
 * theme's 1400px layout, where a quarter of the row is 335px against the
 * design's 264px card. Each step is set where the card would otherwise get
 * too narrow to hold the price beside the button -- that is what the container
 * query below tests, and dropping a column is the better answer to it while
 * there is still a column to drop.
 *
 * Each step only ever lowers the count, so a grid already narrower than the
 * step is left alone. Same specificity as the base rule that reads the block's
 * own class -- these win by sitting after it.
 */
@media not all and (min-width: 72rem) {
    .wp-block-woocommerce-cart .wp-block-woocommerce-empty-cart-block .wc-block-grid:is(.has-4-columns, .has-5-columns, .has-6-columns) {
        --groceria-empty-cart-columns: 3;
    }
}

@media not all and (min-width: 54rem) {
    .wp-block-woocommerce-cart .wp-block-woocommerce-empty-cart-block .wc-block-grid:is(.has-3-columns, .has-4-columns, .has-5-columns, .has-6-columns) {
        --groceria-empty-cart-columns: 2;
    }
}

/*
 * A card too narrow to set the price beside the button -- the price and the
 * "Add to cart" label want about 205px between them. Asked of the card and not
 * of the window, because the same window gives a different card at every
 * column count above.
 *
 * Both cells span the whole track list, which drops each onto a row of its
 * own; the button then goes back to the width of its label rather than the
 * width of the card.
 */
@container (max-width: 13rem) {
    .wp-block-woocommerce-cart .wp-block-woocommerce-empty-cart-block .wc-block-grid__products {
        .wc-block-grid__product-price,
        .wc-block-grid__product-add-to-cart.wp-block-button {
            grid-column: 1 / -1;
        }

        .wc-block-grid__product-add-to-cart.wp-block-button .wp-block-button__link {
            width: fit-content;
        }
    }
}

/* Pointing devices that can hover. */
@media (hover: hover) {
    :where(.group):hover .wp-block-woocommerce-cart .wc-block-cart .wc-block-components-main table.wc-block-cart-items .wc-block-components-product-name {
        text-decoration-line: underline;
    }

    .wp-block-woocommerce-cart .wc-block-cart .wc-block-cart__sidebar .wc-block-components-totals-coupon button:hover {
        background-color: var(--wp--preset--color--primary);
        color: var(--wp--preset--color--white);
    }

    /*
     * The design's Add button fills on hover, and the theme's own product
     * grids underline the title with it -- both off the card, not off the
     * control, so the whole card reads as one target.
     */
    .wp-block-woocommerce-cart .wp-block-woocommerce-empty-cart-block .wc-block-grid__products .wc-block-grid__product:hover {
        .wc-block-grid__product-title {
            text-decoration-line: underline;
        }

        .wc-block-grid__product-add-to-cart.wp-block-button .wp-block-button__link {
            border-color: var(--wp--preset--color--secondary);
            background-color: var(--wp--preset--color--secondary);
            color: var(--wp--preset--color--white);
        }
    }
}
