/* =============================================================================
   Module: reviews  (modules/reviews.php)
   -----------------------------------------------------------------------------
   Patient testimonials: a headline and the Google rating side by side, then an
   endlessly wrapping row of quote cards.

   Two states, and both have to work:

     no JavaScript   the viewport scrolls natively (overflow-x + scroll-snap),
                     quotes are shown in full, the arrows stay hidden
     .is-enhanced    assets/js/modules/reviews.js takes over: the track is moved
                     with transform, quotes are clamped and the arrows appear

   Everything below the .is-enhanced selector therefore belongs to the second
   state only - the base rules must stand on their own.
   ============================================================================= */

.reviews {

    /* How many cards fit at once. The card width is derived from this, so the
       breakpoints below are the only place the number has to change. */
    --reviews-per-view: 1;
    --reviews-gap: var(--space-lg);

    /* >= 44px, the minimum touch target. */
    --reviews-arrow-size: var(--space-xl);

    /* A step is a deliberate movement, slower than a hover. Local to this
       module; the shared transition tokens are all shorter than this. */
    --reviews-duration: 420ms;
}

@media (min-width: 768px) {
    .reviews {
        --reviews-per-view: 2;
    }
}

@media (min-width: 1024px) {
    .reviews {
        --reviews-per-view: 3;
        --reviews-gap: var(--space-2xl);
    }
}

/* --- Head: headline | rating ------------------------------------------------
   Headline, rule and the two columns are the shared .section-head - see
   base/components.css. Only what is particular to the rating is below.
   -------------------------------------------------------------------------- */

/* From three cards up the headline no longer needs the room, so the rating
   column widens: that carries the rule towards the middle and opens the gap
   between it and the right-aligned stars, as in the design. Below this the
   headline would start wrapping badly, so the narrower default stays. */
@media (min-width: 1024px) {
    .reviews__head {
        --section-head-aside: 26rem;
    }
}

/* --- Rating ------------------------------------------------------------------
   The star row is a fixed 4.7-of-5 graphic, so it is decorative: the caption
   next to it is what carries the value.
   -------------------------------------------------------------------------- */

.reviews__rating {
    display: flex;
    flex-direction: column;
    gap: var(--space-2xs);

    /* Muted rather than accent: at caption size the light blue does not carry
       enough contrast on white. The value itself keeps the accent. */
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

@media (min-width: 768px) {
    .reviews__rating {
        justify-content: center;
        align-items: flex-end;
        text-align: end;
    }
}

.reviews__stars {
    width: 100%;
    max-width: 13rem;
}

@media (min-width: 768px) {
    .reviews__stars {
        margin-inline-start: auto;
    }
}

.reviews__rating-value {
    color: var(--color-accent);
    font-weight: var(--font-weight-bold);
}

/* --- Slider ------------------------------------------------------------------
   Source order is prev, viewport, next. Below 768px the arrows are re-ordered
   underneath the cards, from 768px they flank them, and once the window is wide
   enough to have margin left over they move outside the column entirely - which
   is where the design puts them.
   -------------------------------------------------------------------------- */

.reviews__slider {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--space-md);
    margin-block-start: var(--space-2xl);
}

.reviews__viewport {
    order: 1;
    flex: 1 1 100%;
    min-width: 0;

    /* Without JavaScript this is the whole interaction: a natively scrollable,
       swipeable row. .is-enhanced turns it off again. */
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
}

.reviews__arrow--prev { order: 2; }
.reviews__arrow--next { order: 3; }

@media (min-width: 768px) {
    .reviews__slider {
        flex-wrap: nowrap;
    }

    .reviews__viewport {
        flex: 1 1 auto;
    }

    .reviews__arrow--prev { order: 0; }
}

/* One-off breakpoint, not one of the site's four: it is the width at which the
   1300px column finally leaves enough page margin for an arrow plus its gap
   (1300 + 2 x (48 + 24) ~= 1450). Narrower than this and the arrows would be
   clipped, so they stay inside the column. */
@media (min-width: 1460px) {
    .reviews__arrow {
        position: absolute;
        inset-block-start: 50%;
        margin-block-start: calc(var(--reviews-arrow-size) / -2);
    }

    .reviews__arrow--prev {
        inset-inline-end: 100%;
        margin-inline-end: var(--space-md);
    }

    .reviews__arrow--next {
        inset-inline-start: 100%;
        margin-inline-start: var(--space-md);
    }
}

/* --- Arrows ----------------------------------------------------------------- */

.reviews__arrow {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: var(--reviews-arrow-size);
    height: var(--reviews-arrow-size);
    padding: 0;
    color: var(--color-primary);
    transition: color var(--transition-fast);
}

/* JavaScript removes the attribute; until then there is no dead control. */
.reviews__arrow[hidden] {
    display: none;
}

.reviews__arrow:hover,
.reviews__arrow:focus-visible {
    color: var(--color-accent);
}

.reviews__chevron {
    width: auto;
    height: var(--space-lg);
    transition: transform var(--transition-base);
}

.reviews__arrow--prev:hover .reviews__chevron {
    transform: translateX(calc(var(--space-3xs) * -1));
}

.reviews__arrow--next:hover .reviews__chevron {
    transform: translateX(var(--space-3xs));
}

/* --- Track and cards -------------------------------------------------------- */

.reviews__track {
    display: flex;
    align-items: stretch;
    gap: var(--reviews-gap);
}

/* The card width is the viewport minus the gaps, divided by the number of cards
   on screen. Percentages resolve against the track, whose width is the
   viewport's - the items simply overflow it. */
.reviews__item {
    display: flex;
    flex: 0 0 calc((100% - (var(--reviews-per-view) - 1) * var(--reviews-gap)) / var(--reviews-per-view));
    scroll-snap-align: start;
}

.review {
    display: flex;
    flex-direction: column;
    width: 100%;
}

/* blockquote carries a rule and a muted colour by default (base/elements.css);
   here the quote is the content, not an aside. */
.review__quote {
    margin: 0;
    padding-inline-start: 0;
    border-inline-start: 0;
    color: inherit;
}

.review__text {
    margin: 0;
}

.review__more {
    align-self: flex-start;
    margin-block-start: var(--space-2xs);
    padding: 0;
    color: var(--color-text);
    text-align: start;
}

.review__more[hidden] {
    display: none;
}

.review__more:hover,
.review__more:focus-visible {
    color: var(--color-primary);
}

/* margin-block-start: auto pins the names to the bottom, so they line up across
   cards of unequal length. */
.review__author {
    margin-block-start: auto;
    padding-block-start: var(--space-md);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

/* --- Enhanced state ----------------------------------------------------------
   Set by assets/js/modules/reviews.js once it has taken control.
   -------------------------------------------------------------------------- */

.reviews__slider.is-enhanced .reviews__viewport {
    overflow: hidden;
    scroll-snap-type: none;
}

.reviews__slider.is-enhanced .reviews__track {
    transition: transform var(--reviews-duration) cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform;
}

/* Five lines is the length at which the three columns still read as a row.
   line-clamp has no standard equivalent that works without the -webkit- prefix,
   which every target browser supports. */
.reviews__slider.is-enhanced .review__text {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 5;
    overflow: hidden;
}

.reviews__slider.is-enhanced .review__text.is-expanded {
    display: block;
    overflow: visible;
}
