/**
 * AIEO Star Ratings — interactive widget + read-only aggregate.
 *
 * Colors + size come from CSS variables injected inline by AIEO_Ratings::enqueue_assets()
 * (mirrors the wishlist-heart pattern). The aggregate uses a two-layer technique:
 * a full empty-color background (5 stars) overlaid by a percentage-width clip
 * of filled-color stars — gives free half-star fidelity without storing
 * fractional ratings.
 */
:root {
    --aieo-rating-empty:     #d4d4d8;
    --aieo-rating-filled:    #F46767;   /* post-vote color (the viewer's own rating) */
    --aieo-rating-hover:     #F46767;
    --aieo-rating-pre-rated: #000000;   /* placeholder 5-stars before viewer has rated */
    --aieo-rating-size:      20px;
}

/* ------------------------------------------------------------------------
 * Interactive widget
 * --------------------------------------------------------------------- */

.aieo-rating-stars {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 4px 0;
    line-height: 1;
    /* On archive cards we don't want the wrapper stretching with the card —
       it'd inflate the row's gap budget. inline-flex on the wrapper +
       max-content on the row below pin it to its intrinsic width. */
    max-width: 100%;
}

.aieo-rating-stars__row {
    display: inline-flex;
    align-items: center;
    /* Operator-configurable spacing — `--aieo-rating-gap` is injected by
       AIEO_Ratings::enqueue_assets() from the Appearance panel ("Star gap
       — desktop / mobile" fields). 2px default matches the reference
       roosterx-theme rendering. */
    gap: var(--aieo-rating-gap, 2px);
    /* Pin to intrinsic width so even when a parent flex/grid stretches us,
       the buttons don't redistribute the slack into massive gaps. */
    width: max-content;
    max-width: 100%;
}

.aieo-rating-star {
    /* Defensive button reset — themes ship `.woocommerce .button { width:
       100% }`, `.product li button { min-width: 200px }`, etc. that win
       the specificity battle against our plain `.aieo-rating-star`. The
       60-px-wide / 14-px-tall buttons reported by DevTools on the test
       site are proof. We use `!important` on the dimensional properties
       to defeat those theme overrides — `!important` is justified here
       because these are corrective overrides against theme bugs, not
       cosmetic preferences, and there is no legitimate downstream
       caller that should win.
       min-width: 0 stops the implicit `min-width: auto` on flex items
       from inheriting the theme's `min-width: 200px`. */
    box-sizing: border-box !important;
    width: var(--aieo-rating-size) !important;
    min-width: unset !important;
    max-width: var(--aieo-rating-size) !important;
    height: var(--aieo-rating-size) !important;
    min-height: unset !important;
    max-height: var(--aieo-rating-size) !important;
    flex: 0 0 var(--aieo-rating-size) !important;
    padding: 0 !important;
    margin: 0 !important;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: transparent;
    color: var(--aieo-rating-empty);
    cursor: pointer;
    transition: color 120ms ease, transform 100ms ease;
    line-height: 1;
}
.aieo-rating-star:focus-visible { outline: 2px solid var(--aieo-rating-hover); outline-offset: 2px; border-radius: 2px; }
.aieo-rating-star:active { transform: scale(0.92); }
.aieo-rating-star.is-filled { color: var(--aieo-rating-filled); }

/* Pre-rated state: viewer hasn't voted yet AND `display_full_until_rated`
 * is on. PHP paints all 5 with `is-filled` so this rule wins via specificity. */
.aieo-rating-stars.is-unrated-full .aieo-rating-star.is-filled { color: var(--aieo-rating-pre-rated); }
.aieo-rating-aggregate.is-unrated-full .aieo-rating-aggregate__fg { color: var(--aieo-rating-pre-rated); }

/* Hover/focus paints stars 1..N filled. We paint the hovered star + every
 * preceding sibling on the same row. */
.aieo-rating-stars__row:hover .aieo-rating-star {
    color: var(--aieo-rating-empty);
}
.aieo-rating-stars__row .aieo-rating-star:hover,
.aieo-rating-stars__row .aieo-rating-star:hover ~ .aieo-rating-star {
    /* sibling combinator: hovered + all later — but stars are LTR so we want
     * hovered + all earlier. CSS has no "previous sibling", so we flip the
     * approach: paint everything by default on hover, then un-paint after. */
}
/* Trick for "hover paints up to and including N":
 * - on hover anywhere in the row, paint everything filled
 * - then for each star hovered, un-paint everything that comes after it
 */
.aieo-rating-stars__row:hover .aieo-rating-star {
    color: var(--aieo-rating-hover);
}
.aieo-rating-stars__row .aieo-rating-star:hover ~ .aieo-rating-star {
    color: var(--aieo-rating-empty);
}

.aieo-rating-stars.is-loading {
    opacity: 0.6;
    pointer-events: none;
}

.aieo-rating-stars.is-readonly .aieo-rating-star {
    cursor: default;
    pointer-events: none;
}

/* ───────────────────────────────────────────────────────────────────────
 * High-specificity override against the Botiga / femme-fatale-V2 mobile
 * button-sizing rule:
 *
 *   @media (max-width: 1025px) {
 *       button:not(.components-button):not(.pswp__button):not(.has-background) {
 *           height: 60px;
 *           min-width: 60px;
 *       }
 *   }
 *
 * That selector is (0,3,1). The prior override here was also (0,3,1) and
 * relied solely on `!important` — fragile against minifier-shuffled stylesheet
 * order. We mirror the theme's three `:not()` exclusions AND chain the wrapper
 * class to land at (0,7,1), then keep `!important` as belt-and-suspenders.
 *
 * Specificity:
 *   `.aieo-rating-stars.aieo-rating-stars` = (0,2,0)
 *   `.aieo-rating-stars__row`              = (0,1,0)
 *   `button.aieo-rating-star`              = (0,1,1)
 *   `:not(.components-button) :not(.pswp__button) :not(.has-background)`
 *                                          = (0,3,0)
 *   ───────────────────────────────────────  total (0,7,1)
 * ─────────────────────────────────────────────────────────────────────── */
@media (max-width: 1025px) {
    .aieo-rating-stars.aieo-rating-stars .aieo-rating-stars__row button.aieo-rating-star:not(.components-button):not(.pswp__button):not(.has-background) {
        box-sizing: border-box !important;
        width: var(--aieo-rating-size) !important;
        min-width: unset !important;
        max-width: var(--aieo-rating-size) !important;
        height: var(--aieo-rating-size) !important;
        min-height: unset !important;
        max-height: var(--aieo-rating-size) !important;
        flex: 0 0 var(--aieo-rating-size) !important;
        padding: 0 !important;
        margin: 0 !important;
    }
    .aieo-rating-stars.aieo-rating-stars .aieo-rating-stars__row button.aieo-rating-star:not(.components-button):not(.pswp__button):not(.has-background) .aieo-rating-star-icon {
        width: var(--aieo-rating-size) !important;
        max-width: var(--aieo-rating-size) !important;
        min-width: unset !important;
        height: var(--aieo-rating-size) !important;
        max-height: var(--aieo-rating-size) !important;
        min-height: unset !important;
    }
    /* Pin the row itself so a parent flex container can't stretch it (and
       give the buttons more space to redistribute via flex-grow inheritance).
       Same exclusion + wrapper-class chain as above to keep specificity high. */
    .aieo-rating-stars.aieo-rating-stars .aieo-rating-stars__row {
        width: max-content !important;
        max-width: 100% !important;
        flex: 0 0 auto !important;
        gap: var(--aieo-rating-gap, 2px) !important;
    }
}

/* Star-icon SVG inherits color via fill="currentColor".
 * Same defensive sizing as the button — `!important` to defeat theme
 * rules like `.product img, .product svg { width: 100% }` which would
 * otherwise stretch the icon inside an already-correct button box. */
.aieo-rating-star-icon {
    width: var(--aieo-rating-size) !important;
    max-width: var(--aieo-rating-size) !important;
    min-width: unset !important;
    height: var(--aieo-rating-size) !important;
    max-height: var(--aieo-rating-size) !important;
    min-height: unset !important;
    flex: 0 0 var(--aieo-rating-size) !important;
    display: block;
}

/* Caption — numeric "4.6 (128)" style label next to the row.
 * `white-space: nowrap` is desktop-only: long unrated-prompts like
 * "Ψηφίστε για να δείτε τη βαθμολογία" must wrap inside a 50%-width
 * mobile archive card; the mobile rule below overrides this. */
.aieo-rating-caption {
    font-size: var(--aieo-rating-cap-fs, 13px);
    color: #4b5563;
    line-height: 1;
    white-space: nowrap;
}

/* Mobile — caption wraps so it stays inside its card across every variant
 * (archive, single, …). Without this the `inline-flex` wrapper expands to
 * the unwrapped caption's intrinsic width and overflows the card. The
 * companion `min-width: 0` on the wrapper kills the implicit
 * `min-width: auto` on flex children that would re-inflate it. */
@media (max-width: 768px) {
    .aieo-rating-caption {
        white-space: normal !important;
        max-width: 100%;
        overflow-wrap: anywhere;
    }
    .aieo-rating-stars {
        max-width: 100%;
        min-width: 0;
    }
}

/* Variant: archive card — lands directly under the buy button as the last
 * element of the tile. Stars on top, caption stacked below them, both
 * horizontally centered with the rest of the card content.
 *
 * Size + gap are NOT redefined here — both follow `--aieo-rating-size` /
 * `--aieo-rating-gap` injected on `:root` by AIEO_Ratings::enqueue_assets()
 * from the operator's Appearance settings. Earlier versions hardcoded
 * `--aieo-rating-size: 16px` / `14px` on this variant, which silently
 * overrode the operator's "Star size — desktop/mobile" fields. */
.aieo-rating-stars--archive {
    flex-direction: column;
    align-items: center;
    gap: 4px;
    margin: 10px 0 4px;
}
.aieo-rating-stars--archive .aieo-rating-caption {
    font-size: var(--aieo-rating-cap-fs-arch, 12px);
    text-align: center;
}

/* Mobile — tighten the column gap + caption rhythm; size and inter-star gap
 * still come from operator settings via the CSS variables. */
@media (max-width: 768px) {
    .aieo-rating-stars--archive {
        gap: 3px;
        margin: 8px 0 4px;
    }
    .aieo-rating-stars--archive .aieo-rating-caption {
        /* font-size comes from --aieo-rating-cap-fs-arch (operator setting,
           swapped to the mobile value by the injected media query). */
        line-height: 1.2;
        white-space: normal;
    }
}

/* Variant: single product page — sits between title and price.
 * Generous vertical space so the row breathes under the product title. */
.aieo-rating-stars--single {
    margin: 18px 0 22px;
}

/* Mobile single-product page — caption stacks UNDER the stars instead of
 * floating to the right of them. On narrow viewports the inline-row layout
 * with `flex-direction: row` would push the caption past the product
 * image's column edge. Column stacking keeps the row + caption inside the
 * container; the caption stays `white-space: nowrap` (NOT wrapped — wrapping
 * is what was causing the overflow in the first place because it forced the
 * caption to expand into the next line while still beside the stars).
 * Both children are horizontally centered to match the visual rhythm of
 * the rest of the mobile PDP (centred price, centred add-to-cart, etc.). */
@media (max-width: 768px) {
    .aieo-rating-stars--single {
        flex-direction: column;
        align-items: center;
        gap: 6px;
        margin: 14px 0 16px;
        min-width: 0;
        /* The wrapper itself spans the available width so its centred
           children land in the middle of the product summary column.
           Otherwise the inline-flex container is only as wide as its
           content and `align-items: center` is a no-op for sub-content
           that's narrower than its parent column. */
        display: flex;
        width: 100%;
    }
    .aieo-rating-stars--single .aieo-rating-caption {
        text-align: center;
    }
}

/* ------------------------------------------------------------------------
 * Read-only aggregate (half-star fidelity via percentage fill)
 * --------------------------------------------------------------------- */

.aieo-rating-aggregate {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 4px 0;
    line-height: 1;
}

.aieo-rating-aggregate__stars {
    position: relative;
    display: inline-block;
    line-height: 0;
}

.aieo-rating-aggregate__bg,
.aieo-rating-aggregate__fg {
    display: inline-flex;
    gap: 2px;
}

.aieo-rating-aggregate__bg {
    color: var(--aieo-rating-empty);
}

.aieo-rating-aggregate__fg {
    position: absolute;
    inset: 0;
    overflow: hidden;
    color: var(--aieo-rating-filled);
    /* width is set inline (e.g. style="width:92%") */
}

.aieo-rating-aggregate__bg-star,
.aieo-rating-aggregate__fg-star {
    width: var(--aieo-rating-size);
    height: var(--aieo-rating-size);
    display: block;
    flex-shrink: 0;
}

/* WC compat: ensure archive cards have a positioned containing block so
 * absolutely-positioned siblings (e.g. wishlist heart) keep their layout
 * even when the rating widget is added. We don't use absolute positioning
 * ourselves but keep this as a safety net. */
ul.products li.product,
.products .product,
.wc-block-product,
.wp-block-woocommerce-product,
.wc-block-product-template > li,
.wp-block-woocommerce-product-template > li,
.wc-block-grid__product,
:where(li, div).type-product {
    position: relative;
}
