/*
 * Stilts Google Reviews display.
 *
 * Two disjoint prefixed roots, and nothing outside them: .sgr-reviews for
 * the review grid (everything down to the attribution rule) and .sgr-badge
 * for the compact rating badge (the last section of this file). Nothing
 * here uses an unprefixed global selector, and every color/radius/spacing
 * value is read from a CSS custom property set inline per shortcode
 * instance (see Renderer::container() and BadgeRenderer::styleVars()), so
 * this file never has to be edited to match a site's settings. Font is
 * inherited from the surrounding theme.
 *
 * One file and one registered handle on purpose: a page showing both a
 * grid and a badge should download one stylesheet, not two.
 */

.sgr-reviews {
    box-sizing: border-box;
    font-family: inherit;
    color: var(--sgr-text, #202124);

    /* The grid and the carousel size their columns off THIS element's own
       inline size, not the browser viewport, which is the whole point of
       the 1.5.0 layout fix: an Elementor editor preview iframe is often
       narrower than 600px while the container the user actually sized is
       wide, and a narrow sidebar column can sit inside a 1400px viewport.
       Viewport media queries got both of those backwards.

       width:100% is load-bearing next to container-type, not decoration.
       container-type: inline-size applies inline-size containment, so this
       element reports a 0 intrinsic width. Dropped straight into a flex
       row as a flex item with an auto width, it would resolve its base
       size from that 0 and collapse. A percentage width is definite, comes
       from the parent, and never consults the contents, so the collapse
       cannot happen. For a normal block in flow (the usual case, including
       inside an Elementor widget wrapper) it resolves to exactly what
       width:auto already gave, so nothing moves on existing installs. */
    container-type: inline-size;
    container-name: sgr-reviews;
    width: 100%;
}

.sgr-reviews *,
.sgr-reviews *::before,
.sgr-reviews *::after {
    box-sizing: inherit;
}

/* --- Header ----------------------------------------------------- */

.sgr-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    background: var(--sgr-header-bg, #f7f7f7);
    border-radius: calc(var(--sgr-radius, 16px) * 1.25);
    padding: 1.25rem 1.5rem;
    margin-bottom: var(--sgr-spacing, 20px);
}

.sgr-header-title {
    font-size: 1.25rem;
    font-weight: 700;
}

.sgr-google-logo {
    font-weight: 700;
}

.sgr-header-aggregate {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.sgr-average {
    font-size: 1.5rem;
    font-weight: 700;
}

.sgr-count {
    color: var(--sgr-muted, #5f6368);
}

.sgr-count-label {
    flex-basis: 100%;
    font-size: 0.8rem;
    color: var(--sgr-muted, #5f6368);
}

.sgr-no-reviews {
    color: var(--sgr-muted, #5f6368);
}

.sgr-review-button {
    display: inline-block;
    background: var(--sgr-btn-bg, #fbbc04);
    color: var(--sgr-btn-text, #202124);
    text-decoration: none;
    font-weight: 700;
    padding: 0.75rem 1.5rem;
    border-radius: 999px;
    white-space: nowrap;
}

.sgr-review-button:hover,
.sgr-review-button:focus {
    filter: brightness(0.95);
}

/* --- Grid (CSS Grid, container-query columns) ---------------------
 * Was `column-count` multi-column masonry with inline-block children
 * through 1.4.0. Two things were wrong with that and both are fixed
 * here.
 *
 * 1. The step-downs keyed off the VIEWPORT. See the note on .sgr-reviews
 *    above; they now key off the container's own inline size.
 * 2. Multi-column flow with inline-block children is fragile inside a
 *    flex or grid ancestor, which is precisely Elementor's container
 *    model. It could collapse to a single column even when no media
 *    query was involved. CSS Grid is defined on the element itself and
 *    is unaffected by what its ancestors are laid out with.
 *
 * The tradeoff taken deliberately: cards in a row are now equal height
 * instead of masonry-packed. Ragged masonry columns can be rebuilt on
 * top of grid, but only with either absolute positioning or JS
 * measurement, and both reintroduce exactly the ancestor-sensitivity
 * that defect 2 was. Equal-height rows are the honest, sturdy version.
 *
 * minmax(0, 1fr) rather than 1fr because a grid track's default minimum
 * is auto (min-content), so one long unbroken word or URL in a review
 * would otherwise widen its track and push the others out of shape.
 */

.sgr-grid {
    display: grid;
    grid-template-columns: repeat(var(--sgr-columns, 4), minmax(0, 1fr));
    gap: var(--sgr-spacing, 20px);
}

.sgr-grid-item {
    display: flex;
    min-width: 0;
}

/* Container-query step-downs. The user-selected column count is a
   CEILING: these only ever reduce it, never raise a 2-column shortcode
   to 3 because the container happens to be wide.

   Thresholds are chosen off readable card width (roughly 210px of text
   plus padding and gaps), not off device classes, since a container is
   not a device:
     >= 900px  user-selected count, up to 4
     640-899px at most 3
     420-639px at most --sgr-columns-tablet, which Renderer emits as
               min(2, columns), so at most 2
     < 420px   always 1 */

@container sgr-reviews (max-width: 899px) {
    /* Only a 4-column instance has anything to give up here; 3 and below
       already fit, and capping them would be raising nothing and lowering
       nothing. Matching on the emitted count is deliberate: repeat()
       takes a literal <integer>, so min(var(--sgr-columns), 3) is not
       expressible inside it. */
    .sgr-reviews[data-sgr-columns="4"] .sgr-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* The narrower tiers carry the same [data-sgr-columns] specificity as the
   899px rule above on purpose. A container query adds no specificity of
   its own, so a bare `.sgr-grid` here would lose to that rule's
   `.sgr-reviews[data-sgr-columns="4"] .sgr-grid` and a 4-column instance
   would stall at 3 columns however narrow the container got. Equal
   specificity plus source order gives the narrower tier the win. */

@container sgr-reviews (max-width: 639px) {
    .sgr-reviews[data-sgr-columns] .sgr-grid {
        grid-template-columns: repeat(var(--sgr-columns-tablet, 2), minmax(0, 1fr));
    }
}

@container sgr-reviews (max-width: 419px) {
    .sgr-reviews[data-sgr-columns] .sgr-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Graceful degradation for engines with no container query support:
   fall back to the 1.4.0 viewport breakpoints. Those are wrong in an
   Elementor preview iframe, but they are what those browsers have always
   done here, so old browsers get the old behavior rather than a grid
   frozen at 4 columns. */
@supports not (container-type: inline-size) {
    @media (max-width: 900px) {
        .sgr-grid {
            grid-template-columns: repeat(var(--sgr-columns-tablet, 2), minmax(0, 1fr));
        }
    }

    @media (max-width: 600px) {
        .sgr-grid {
            grid-template-columns: minmax(0, 1fr);
        }
    }
}

/* --- Carousel (display="carousel") -------------------------------
 * Everything that makes this a carousel rather than a grid is scoped
 * under .sgr-js, which display.js adds. With no JavaScript, the track is
 * just a .sgr-grid (it carries both classes) and the controls are
 * hidden, so the visitor gets the ordinary grid plus the ordinary
 * server-rendered pagination links and no review is stranded behind a
 * control that cannot move.
 *
 * Selector weights here are deliberate, not accidental. A container
 * query adds no specificity of its own, so these rules have to out-weigh
 * the grid's own container-query tiers above
 * (`.sgr-reviews[data-sgr-columns] .sgr-grid`, three class-level parts)
 * on specificity alone, rather than relying on source order.
 */

.sgr-reviews:not(.sgr-js) .sgr-carousel-controls,
.sgr-reviews:not(.sgr-js) .sgr-carousel-status {
    display: none;
}

.sgr-carousel-viewport {
    overflow: hidden;
}

.sgr-reviews.sgr-js .sgr-carousel-viewport:focus-visible {
    outline: 2px solid var(--sgr-link, #1a73e8);
    outline-offset: 2px;
}

/* One row of equal-width cards, translated sideways a whole slide at a
   time. --sgr-per-view is the carousel's echo of the grid's column
   ceiling; unlike repeat(), grid-auto-columns takes a calc(), so the
   step-downs below can simply reassign the variable. */
.sgr-reviews.sgr-js .sgr-grid.sgr-carousel-track {
    --sgr-per-view: var(--sgr-columns, 4);
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: calc((100% - (var(--sgr-per-view) - 1) * var(--sgr-spacing, 20px)) / var(--sgr-per-view));
    transform: translateX(var(--sgr-carousel-offset, 0px));
    transition: transform 0.35s ease;
    will-change: transform;
}

@container sgr-reviews (max-width: 899px) {
    .sgr-reviews.sgr-js[data-sgr-columns="4"] .sgr-grid.sgr-carousel-track {
        --sgr-per-view: 3;
    }
}

/* Same equal-specificity-plus-source-order arrangement as the grid tiers:
   without the attribute selector these would lose to the 899px rule and a
   4-per-view carousel would stall at 3 in a phone-width container. */
@container sgr-reviews (max-width: 639px) {
    .sgr-reviews.sgr-js[data-sgr-columns] .sgr-grid.sgr-carousel-track {
        --sgr-per-view: var(--sgr-columns-tablet, 2);
    }
}

@container sgr-reviews (max-width: 419px) {
    .sgr-reviews.sgr-js[data-sgr-columns] .sgr-grid.sgr-carousel-track {
        --sgr-per-view: 1;
    }
}

@supports not (container-type: inline-size) {
    @media (max-width: 900px) {
        .sgr-reviews.sgr-js .sgr-grid.sgr-carousel-track {
            --sgr-per-view: var(--sgr-columns-tablet, 2);
        }
    }

    @media (max-width: 600px) {
        .sgr-reviews.sgr-js .sgr-grid.sgr-carousel-track {
            --sgr-per-view: 1;
        }
    }
}

/* Cards outside the current slide are clipped by the viewport's overflow
   rather than hidden with visibility, so they stay animatable while they
   slide in and out. display.js marks them aria-hidden and inert, which is
   what actually takes them out of the accessibility tree and the tab
   order; a purely clipped card is still reachable by Tab, and focusing
   one would scroll the viewport out from under the transform. */

.sgr-carousel-controls {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    margin-top: var(--sgr-spacing, 20px);
}

.sgr-carousel-arrow {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    flex: 0 0 auto;
    background: var(--sgr-btn-bg, #fbbc04);
    color: var(--sgr-btn-text, #202124);
    border: none;
    border-radius: 999px;
    font: inherit;
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
}

.sgr-carousel-arrow:hover,
.sgr-carousel-arrow:focus-visible {
    filter: brightness(0.95);
}

.sgr-carousel-arrow[disabled] {
    opacity: 0.4;
    cursor: default;
}

.sgr-carousel-dots {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.sgr-carousel-dot {
    width: 0.625rem;
    height: 0.625rem;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--sgr-muted, #5f6368);
    opacity: 0.35;
    cursor: pointer;
}

.sgr-carousel-dot[aria-current="true"] {
    background: var(--sgr-star, #fbbc04);
    opacity: 1;
}

/* Visually hidden, still announced. The position counter is useful to a
   screen reader whether or not the dots are switched on. */
.sgr-carousel-status {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

@media (prefers-reduced-motion: reduce) {
    .sgr-reviews.sgr-js .sgr-grid.sgr-carousel-track {
        transition: none;
    }
}

/* --- Card -----------------------------------------------------------
 * The whole card (stars, text, read more, avatar, name, date) is one
 * self-contained block on --sgr-card-bg, with its own customizable
 * border/shadow, so adjacent cards in the masonry grid never visually
 * merge into each other. The reviewer row used to render outside/below
 * this block on the page background, which is exactly what made cards
 * blend together; it is now inside it. The old speech-tail (a small
 * triangle pointing from the text bubble down at the reviewer row) only
 * made sense when the reviewer sat outside the bubble as a separate
 * element it could point at; with both inside one bordered block, a
 * triangle cutting into that border/shadow reads as a rendering glitch,
 * not a design element, so it has been removed rather than kept.
 */

/* A column flex box, not a plain block, so a short review's card still
   fills its grid cell and the reviewer row sits on the card's bottom edge
   instead of floating mid-card next to a taller neighbor. min-width:0
   stops a long unbroken word from widening the card past its track. */
.sgr-card {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-width: 0;
    overflow-wrap: break-word;
    background: var(--sgr-card-bg, #f7f7f7);
    border: var(--sgr-card-border-width, 1px) solid var(--sgr-card-border-color, #dadce0);
    border-radius: var(--sgr-radius, 16px);
    box-shadow: var(--sgr-card-shadow, none);
    padding: 1rem 1.25rem;
}

.sgr-card-bubble {
    flex: 1 1 auto;
    margin-bottom: 0.75rem;
}

.sgr-stars {
    display: inline-block;
    color: var(--sgr-star, #fbbc04);
    letter-spacing: 0.1em;
    margin-bottom: 0.35rem;
}

.sgr-card-text {
    line-height: 1.5;
}

.sgr-read-more {
    display: inline;
    background: none;
    border: none;
    padding: 0;
    margin: 0 0 0 0.25rem;
    color: var(--sgr-link, #1a73e8);
    font: inherit;
    font-weight: 400;
    text-decoration: underline;
    cursor: pointer;
}

.sgr-read-more:hover,
.sgr-read-more:focus {
    filter: brightness(0.85);
}

/* Progressive enhancement: with no JS, the full text is always shown
   and the excerpt/button are never displayed at all. Once display.js
   runs, it adds .sgr-js to the container and these rules take over. */
.sgr-reviews:not(.sgr-js) .sgr-card-text-excerpt,
.sgr-reviews:not(.sgr-js) .sgr-read-more {
    display: none;
}

/* Only hide the full text when there is an excerpt in front of it to
   reveal; a short review with no excerpt renders only .sgr-card-text-full
   on its own and must stay visible once JS runs. */
.sgr-reviews.sgr-js .sgr-card-text-excerpt + .sgr-card-text-full {
    display: none;
}

.sgr-reviews.sgr-js .sgr-card-text-full.sgr-expanded {
    display: inline;
}

.sgr-reviews.sgr-js .sgr-card-text-excerpt.sgr-collapsed-hidden {
    display: none;
}

/* --- Reviewer (inside the same card block as the bubble above) --- */

.sgr-reviewer {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.sgr-avatar {
    flex-shrink: 0;
    width: 2.25rem;
    height: 2.25rem;
}

.sgr-avatar-photo {
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    object-fit: cover;
    display: block;
}

.sgr-avatar-initial {
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    background: var(--sgr-muted, #5f6368);
}

.sgr-reviewer-meta {
    display: flex;
    flex-direction: column;
    line-height: 1.3;
}

.sgr-reviewer-name {
    font-weight: 700;
}

.sgr-reviewer-date {
    font-size: 0.8rem;
    color: var(--sgr-muted, #5f6368);
}

/* --- Pagination fallback / load more ------------------------------- */

.sgr-pagination-fallback {
    margin-top: var(--sgr-spacing, 20px);
    text-align: center;
}

.sgr-pagination-fallback a {
    color: var(--sgr-link, #1a73e8);
    margin: 0 0.5rem;
}

.sgr-reviews.sgr-js .sgr-pagination-fallback {
    display: none;
}

.sgr-load-more {
    display: none;
    margin: var(--sgr-spacing, 20px) auto 0;
    background: #eee;
    border: none;
    border-radius: 999px;
    padding: 0.75rem 1.75rem;
    font: inherit;
    font-weight: 700;
    cursor: pointer;
}

.sgr-reviews.sgr-js .sgr-load-more {
    display: block;
}

.sgr-load-more[disabled] {
    opacity: 0.6;
    cursor: default;
}

.sgr-load-more-error {
    text-align: center;
    color: #a8324a;
    margin-top: 0.75rem;
}

/* --- Attribution ----------------------------------------------------- */

.sgr-attribution {
    font-size: 0.75rem;
    color: var(--sgr-muted, #5f6368);
    text-align: center;
    margin-top: var(--sgr-spacing, 20px);
}

/* =====================================================================
 * Compact rating badge: [stilts_google_reviews_badge]
 *
 * Same file, same style handle, and the same rules as everything above:
 * scoped entirely under its own prefixed root (.sgr-badge), no unprefixed
 * global selector, and every customizable value read from a CSS custom
 * property set inline per instance (see BadgeRenderer::styleVars()).
 *
 * .sgr-badge and .sgr-reviews are disjoint roots, so nothing in this
 * section can reach the review grid and nothing in the grid section can
 * reach the badge. No JavaScript is involved; the badge is static markup.
 * ===================================================================== */

.sgr-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    box-sizing: border-box;
    max-width: 100%;
    padding: 0.5rem 0.875rem;
    background: var(--sgr-badge-bg, #ffffff);
    border: var(--sgr-badge-border-width, 1px) solid var(--sgr-badge-border-color, #dadce0);
    border-radius: var(--sgr-badge-radius, 8px);
    box-shadow: var(--sgr-badge-shadow, none);
    color: var(--sgr-badge-text, #202124);
    font-family: inherit;
    font-size: 0.9375rem;
    line-height: 1.2;
    text-align: left;
    text-decoration: none;
    vertical-align: middle;
}

.sgr-badge *,
.sgr-badge *::before,
.sgr-badge *::after {
    box-sizing: inherit;
}

.sgr-badge-logo {
    display: inline-flex;
    flex: 0 0 auto;
    line-height: 0;
}

.sgr-badge-g {
    display: block;
    width: 18px;
    height: 18px;
}

.sgr-badge-body {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

.sgr-badge-rating {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    white-space: nowrap;
}

.sgr-badge-average {
    font-weight: 700;
    font-size: 1.0625rem;
    letter-spacing: -0.01em;
}

/* Five stars as a muted track with a colored overlay clipped to the real
   average, so a 4.6 reads as 4.6 and not as a rounded 5. The track is
   what reserves the width; the fill is absolutely positioned on top of it
   and therefore contributes none. */
.sgr-badge-stars {
    position: relative;
    display: inline-block;
    color: #dadce0;
    font-size: 0.9375rem;
    line-height: 1;
    letter-spacing: 0.06em;
    white-space: nowrap;
}

.sgr-badge-stars-fill {
    position: absolute;
    top: 0;
    left: 0;
    overflow: hidden;
    color: var(--sgr-badge-star, #fbbc04);
    white-space: nowrap;
}

.sgr-badge-count {
    color: var(--sgr-badge-text, #202124);
    opacity: 0.72;
    font-size: 0.8125rem;
    white-space: nowrap;
}

/* --- layout="inline" -------------------------------------------------
 * One horizontal row: logo, rating, count. min-width:0 on the body plus
 * the shrinkable count is what keeps a long count string from forcing the
 * badge wider than a narrow container.
 */

.sgr-badge--inline .sgr-badge-count {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* --- layout="stacked" ------------------------------------------------
 * Logo on top, rating and stars below it, count underneath. Still
 * shrink-wrapped to its content rather than stretched across the column,
 * just on its own line, which is what a sidebar or footer column wants.
 */

.sgr-badge--stacked {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.375rem;
    width: -moz-fit-content;
    width: fit-content;
    padding: 0.75rem 1rem;
    text-align: center;
}

.sgr-badge--stacked .sgr-badge-body {
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
}

/* --- Link state ------------------------------------------------------
 * Only applies when the badge is actually a link; a non-clickable badge
 * is a <span> and picks up none of this.
 */

a.sgr-badge {
    transition: box-shadow 0.15s ease, border-color 0.15s ease;
}

a.sgr-badge:hover,
a.sgr-badge:focus-visible {
    box-shadow: 0 1px 3px rgba(60, 64, 67, 0.16), 0 2px 8px rgba(60, 64, 67, 0.1);
}

a.sgr-badge:focus-visible {
    outline: 2px solid var(--sgr-link, #1a73e8);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    a.sgr-badge {
        transition: none;
    }
}
