/* Testimonials carousel — a slow, tasteful crossfade between quote cards.
   Each .testimonial-slide IS a .quote.media-object (bindings.css owns that
   card's look: portrait-cell, details, attribution weight); this file only
   adds the stacking/crossfade mechanics and the dot navigation. */
@layer components {

  .testimonials { text-align: center; }

  /* CSS-grid stack: every slide occupies the same cell (grid-area: 1 / 1), so
     the viewport's height auto-sizes to the tallest quote and slides overlay
     each other for the opacity crossfade — no JS height measuring needed.
     A definite width + margin-inline:auto here (not left to the grid's own
     auto-sized column) is what keeps the photo at a fixed position: every
     slide stretches to fill this ONE stable cell, instead of each slide
     computing its own width from its own quote's length. 715px matches the
     existing single (Swyx) quote's own rendered card width, so this reads as
     the same "size" of card, just with 15 quotes cycling through it. */
  .testimonials-viewport {
    display: grid;
    width: 100%;
    max-width: 715px;
    margin-inline: auto;
  }

  .testimonial-slide {
    grid-area: 1 / 1;
    opacity: 0;
    pointer-events: none;
    transition: opacity 900ms ease;
  }
  .testimonial-slide.is-active {
    opacity: 1;
    pointer-events: auto;
  }

  /* Match the existing Swyx quote's proportions exactly — same portrait size
     (clamp(...,141px) is what his currently renders at desktop widths), same
     gap (inherited, unchanged), same ~52ch reading measure — but sized from
     the VIEWPORT rather than the quote's own text height/length. Swyx's card
     can get away with shrink-to-content sizing because there's only the one,
     fixed quote; with 15 quotes from one line to four, shrink-to-content made
     the photo+text pair a different width every time (the original bug the
     fixed grid-template-columns below fixes) — clamp(90px, 12vw, 141px) gives
     the same "size" at typical desktop widths without depending on content. */
  .testimonial-slide.quote.media-object {
    grid-template-columns: clamp(90px, 12vw, 141px) 1fr;
    align-items: center;
    justify-content: start;
  }
  .testimonial-slide .portrait-cell {
    width: clamp(90px, 12vw, 141px);
    height: clamp(90px, 12vw, 141px);
    align-self: center;
  }
  .testimonial-slide .details {
    /* bindings.css's `.quote .details { width:auto }` doesn't reliably
       stretch to fill the 1fr column once there's real content in it (shrinks
       instead, and — empirically — drifts left/right doing so); an explicit
       100% pins the box to the column exactly, and max-width:52ch (same as
       Swyx's) caps the reading measure on wide screens. text-align:left
       overrides the center alignment `.testimonials` sets for the heading/dots
       — this is where it actually matters, since without it the text (like
       Swyx's) would centre outward from the photo instead of hugging it. */
    width: 100%;
    max-width: 52ch;
    text-align: left;
  }

  @media (max-width: 720px) {
    /* Match bindings.css's own narrow-screen .quote treatment: stack photo
       over text, both centred — consistent with Swyx's quote at this width. */
    .testimonial-slide.quote.media-object {
      grid-template-columns: 1fr;
      justify-items: center;
      max-width: 100%;
    }
    .testimonial-slide .portrait-cell {
      width: clamp(96px, 28vw, 150px);
      height: auto;
    }
    .testimonial-slide .details {
      width: auto;
      max-width: 100%;
      text-align: center;
    }
  }

  .testimonial-dots {
    display: flex;
    justify-content: center;
    gap: 0.6rem;
    margin-block-start: 1.75rem;
  }
  .testimonial-dot {
    width: 10px;
    height: 10px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--color-rule);
    cursor: pointer;
  }
  .testimonial-dot.is-active {
    background: var(--color-accent);
  }
  .testimonial-dot:focus-visible {
    outline: 2px solid var(--link);
    outline-offset: 2px;
  }

  @media (prefers-reduced-motion: reduce) {
    .testimonial-slide { transition: none; }
  }
}
