/* ==========================================================================
   ReviewCard, ReviewCollection — 07 §11.13, §11.15
   ========================================================================== */

/* Confirmed on a real iPhone (Teo, 2026-08-04) — same bug and same fix as
   .portfolio-carousel: .review-collection's own overflow-x:auto scrolls its
   content, but nothing above it clipped the grid's inflated outer box, so
   the overflow chained up to <html> and dragged the whole page sideways on
   swipe. This wrapper (includes/components/reviews.php) is the containment
   boundary; harmless at desktop width where the grid no longer overflows. */
.review-collection-wrap {
  overflow-x: hidden;
}

/* Desktop: three visible in a row. Mobile: manual scroll-snap, one card and
   part of the next — same non-JS-carousel, non-autoplay pattern as
   PortfolioCarousel and MediaGallery. */
.review-collection {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(85%, 22rem);
  gap: var(--space-5);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--space-3);
  scrollbar-width: thin;
}

@media (min-width: 64rem) {
  .review-collection {
    grid-auto-flow: initial;
    grid-template-columns: repeat(3, 1fr);
    overflow-x: visible;
    scroll-snap-type: none;
  }
}

.review-collection__item {
  scroll-snap-align: start;
}

/* Three cards deliberately do not read as identical (landing v8, Bloque 5:
   "no utilizar tres tarjetas perfectamente idénticas") — the first carries
   slightly more visual weight via padding and border, not different data. */
.review-card {
  /* Confirmed on a real iPhone (Teo, 2026-08-04): .review-card__rating's
     .visually-hidden span is position:absolute with no top/left/right set,
     so with no positioned ancestor anywhere up this chain, its containing
     block became the initial containing block — its static position (where
     it would have sat in normal flow) landed at this card's actual offset
     inside the un-scrolled carousel row, which can be hundreds of px past
     the viewport for the 2nd/3rd card, inflating <html>'s own scrollWidth
     by that amount even though the span itself renders at 1x1px. Giving the
     card its own positioning context keeps any absolutely-positioned
     descendant's containing block local, regardless of what visual
     containment (like .review-collection-wrap's overflow-x:hidden) already
     exists further up — defense in depth, not reliance on one layer. */
  position: relative;
  height: 100%;
  padding: var(--space-6);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-card);
  background-color: var(--surface-base);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.review-card--featured {
  border-color: var(--border-active);
  background-color: var(--surface-raised);
}

/* Added 2026-08-04 (point 2, pre-launch pass) — the single-review section
   on a project ficha (portfolio/proyecto.php), replacing the old QuoteBlock
   rendering there. Same warm surface + terracotta border as --featured
   (Home's own visual identity, not a new look), but standalone rather than
   one of three matched-height grid cells, so no height:100% and room to be
   noticeably wider than the ~680px reading column the narrative text
   around it uses — the section wrapper (portfolio/proyecto.php) puts it in
   a wider container, this only removes the height constraint that doesn't
   apply outside a grid. */
.review-card--wide {
  height: auto;
  border-color: var(--border-active);
  background-color: var(--surface-raised);
  padding: var(--space-7);
}

.review-card--wide .review-card__avatar {
  background-color: var(--surface-base);
}

/* Fraunces for the quote itself, larger than body text — the one thing
   that makes this read as a spotlighted, editorial quote rather than a
   grid card. review-card__author (name + source) stays DM Sans, unchanged
   below, matching Home. */
.review-card--wide .review-card__quote p {
  font-family: var(--font-display);
  font-size: var(--text-md);
  line-height: 1.5;
}

.review-card__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-pill);
  background-color: var(--surface-raised);
  color: var(--text-strong);
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: 600;
}

.review-card--featured .review-card__avatar {
  background-color: var(--surface-base);
}

.review-card__rating {
  margin: 0;
  color: var(--color-acento-editorial);
  letter-spacing: 0.1em;
}

.review-card__quote {
  margin: 0;
  flex: 1;
}

.review-card__quote p {
  margin: 0;
  color: var(--text-body);
}

/* Real quotation marks, added 2026-08-04 — until now an excerpt read as
   plain unmarked text, indistinguishable from the review being shown in
   full. Generated content, not stored in the excerpt itself, so it never
   leaks into plain-text contexts (page <title>, meta description, etc.)
   that might reuse review data. */
.review-card__quote p::before {
  content: "«";
}

.review-card__quote p::after {
  content: "»";
}

.review-card__author {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.review-collection__link {
  margin-top: var(--space-6);
}
