/* ============================================================
   07 — Testimonial wall  (.voices)

   Structure: one editorial lead panel, then a single 8-card wall.
   The wall is one multi-column run (never split), so the balancer
   has eight boxes to work with instead of four: at 3 columns it
   settles on 2 / 3 / 3 with the two longest cards paired in the
   first column. No column-span, no fragmentation, no lone card.

   Three card treatments, not one: plain white (the default voice),
   tinted --lg (short remarks, read as quiet interjections), and
   --note with a coral edge (the qualified endorsement).
   ============================================================ */

/* ============================================================
   Featured lead panel
   ============================================================ */

.voices__featured {
  /* isolate: .mark::after is z-index:-1 and would otherwise hoist to
     the root stacking context and paint behind the page background.
     tokens.css gives .btn the same treatment for the same reason. */
  isolation: isolate;
  margin: clamp(var(--s-10), 4vw, var(--s-16)) 0 0;
  padding: clamp(var(--s-6), 3.4vw, var(--s-14));
  border-radius: var(--r-xl);
  /* White ground so the panel out-contrasts the wall it leads;
     the brand wash is a bounded top-left light, not the fill. */
  background:
    radial-gradient(115% 135% at 0% 0%,
      color-mix(in srgb, var(--accent-soft) 96%, transparent) 0%,
      color-mix(in srgb, var(--coral-100) 26%, transparent) 40%,
      transparent 70%),
    var(--surface);
  box-shadow: inset 0 0 0 1px var(--border-strong), var(--sh-md);
  display: grid;
  gap: var(--s-8);
}

.voices__featured-quote {
  margin: 0;
  max-width: var(--maxw-prose);
  font-family: var(--font-serif);
  font-weight: var(--fw-regular);
  font-size: calc(var(--fs-h2) * 0.86);
  line-height: calc(var(--lh-snug) + 0.16);
  letter-spacing: var(--tracking-normal);
  color: var(--text);
  overflow-wrap: break-word;
  text-wrap: pretty;
}

/* Oversized opening mark. On narrow widths it sets as a block above
   the quote — floated, it would eat a fifth of a 240px measure.
   `/ ""` suppresses the alt text so SRs don't read a stray quote. */
.voices__featured-quote::before {
  content: "\201C" / "";
  display: block;
  font-size: 2.4em;
  line-height: 0.62;
  margin: 0 0 0.06em -0.06em;
  color: color-mix(in srgb, var(--accent) 30%, transparent);
  pointer-events: none;
  user-select: none;
}

@media (min-width: 34em) {
  /* Wide enough to set around: the mark hangs and the first lines
     wrap past it. Offsets are in its own em, so nothing clips. */
  .voices__featured-quote::before {
    display: inline;
    float: left;
    margin: 0.02em 0.1em -0.08em -0.06em;
  }
}

/* ============================================================
   Wall
   ============================================================ */

.voices__wall {
  margin: clamp(var(--s-10), 4vw, var(--s-16)) 0 calc(var(--s-6) * -1);
  columns: 1;
  column-gap: var(--s-6);
}

@media (min-width: 40em) {
  .voices__wall { columns: 2; }
}

@media (min-width: 64em) {
  .voices__wall {
    columns: 3;
    column-gap: var(--s-8);
    margin-bottom: calc(var(--s-8) * -1);
  }
}

/* The <li> is the column item — breaking and spacing live here */
.voices__item {
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  page-break-inside: avoid;
  margin: 0 0 var(--s-6);
}

@media (min-width: 64em) {
  .voices__item { margin-bottom: var(--s-8); }
}

/* ---------- Card (composes .card .card--hover) ----------
   Lift and hairline come from .card--hover in tokens.css; only the
   two variants below restate a box-shadow, because their resting
   shadow isn't the default card's. */

.voices__card {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  padding: clamp(var(--s-5), 2.2vw, var(--s-8));
}

/* ---------- Quote typography ---------- */

.voices__quote {
  margin: 0;
  max-width: 62ch;
  color: var(--text);
  font-size: var(--fs-sm);
  line-height: var(--lh-relaxed);
  letter-spacing: var(--tracking-normal);
  overflow-wrap: break-word;
  text-wrap: pretty;
}

/* Real hanging punctuation: the opening mark sits in the card's
   padding so every line of text starts on the same optical edge.
   `/ ""` keeps the glyphs out of the accessibility tree. */
.voices__quote p {
  text-indent: -0.42em;
}

.voices__quote p::before { content: "\201C" / ""; }
.voices__quote p::after  { content: "\201D" / ""; }

/* ---------- Variant: quiet interjection (short quotes) ----------
   Tinted, flat, no elevation — reads as an aside between the
   white cards rather than another object in the stack. */

.voices__card--lg {
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 14%, transparent);
}

.voices__card--lg:hover {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent);
}

.voices__card--lg .voices__quote {
  font-size: var(--fs-body);
  line-height: var(--lh-normal);
  letter-spacing: var(--tracking-tight);
}

.voices__card--lg .voices__who { border-top-color: color-mix(in srgb, var(--accent) 16%, transparent); }
.voices__card--lg .voices__chip--quiet { background: var(--surface); }

/* ---------- Variant: the qualified endorsement ----------
   One coral edge marks the review that argues with itself. */

.voices__card--note {
  box-shadow:
    inset var(--s-1) 0 0 0 var(--accent-2),
    inset 0 0 0 1px var(--border),
    var(--sh-sm);
}

.voices__card--note:hover {
  box-shadow:
    inset var(--s-1) 0 0 0 var(--accent-2),
    inset 0 0 0 1px var(--border-strong),
    var(--sh-lg);
}

/* ---------- Meta row ---------- */

.voices__meta {
  margin: calc(var(--s-2) * -1) 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
}

/* Same pill as .chip, quieter weight — one meta component, two levels */
.voices__chip--quiet {
  background: var(--surface-2);
  color: var(--text-muted);
  font-weight: var(--fw-medium);
}

.voices__glyph {
  flex: none;
  width: 1.15em;
  height: 1.15em;
  color: var(--accent);
}

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

.voices__who {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding-top: var(--s-5);
  border-top: 1px solid var(--border);
}

.voices__avatar {
  flex: none;
  width: var(--s-12);
  height: var(--s-12);
  border-radius: var(--r-md);
}

.voices__avatar text {
  font-family: var(--font-display);
  font-size: var(--fs-body);
  font-weight: var(--fw-bold);
  letter-spacing: 0.01em;
}

.voices__id {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.voices__name {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-normal);
  letter-spacing: var(--tracking-tight);
  color: var(--text);
}

.voices__role {
  font-size: var(--fs-xs);
  line-height: var(--lh-normal);
  color: var(--text-muted);
  text-wrap: pretty;
}

/* ---------- Per-person avatar tints ---------- */

.voices__avatar--violet rect { fill: var(--violet-100); }
.voices__avatar--violet text { fill: var(--violet-700); }

.voices__avatar--iris rect { fill: var(--violet-050); }
.voices__avatar--iris text { fill: var(--violet-600); }

.voices__avatar--coral rect { fill: var(--coral-100); }
.voices__avatar--coral text { fill: color-mix(in srgb, var(--coral-600) 60%, var(--ink-900)); }

.voices__avatar--mint rect { fill: var(--mint-100); }
.voices__avatar--mint text { fill: color-mix(in srgb, var(--mint-500) 52%, var(--ink-900)); }

.voices__avatar--amber rect { fill: var(--amber-100); }
.voices__avatar--amber text { fill: color-mix(in srgb, var(--amber-500) 46%, var(--ink-900)); }

.voices__avatar--ink rect { fill: var(--ink-100); }
.voices__avatar--ink text { fill: var(--ink-700); }

/* ---------- Featured attribution ---------- */

.voices__who--featured {
  padding-top: var(--s-6);
  border-top-color: var(--border-strong);
}

.voices__who--featured .voices__avatar {
  width: var(--s-14);
  height: var(--s-14);
  border-radius: var(--r-lg);
}

.voices__who--featured .voices__name { font-size: var(--fs-body); }
.voices__who--featured .voices__role { font-size: var(--fs-sm); }

@media (min-width: 58em) {
  /* Quote takes the free width; the attribution becomes a slim
     signature column whose rule runs the full height of the panel. */
  .voices__featured {
    grid-template-columns: minmax(0, 1fr) minmax(0, var(--s-40));
    gap: var(--s-12);
  }

  .voices__who--featured {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-end;
    align-self: stretch;
    gap: var(--s-4);
    padding-top: 0;
    padding-left: var(--s-8);
    border-top: 0;
    border-left: 1px solid var(--border-strong);
  }
}
