/* ==========================================================================
   KF Elements — Testimonials
   --------------------------------------------------------------------------
   Alternating portrait + quote cards. Designed dark-first (the classic
   prestige treatment) but every colour flips cleanly on light grounds.
   ========================================================================== */

.kfe .kfe-testimonials { overflow: hidden; }
/* The frame's head alignment, with this widget's own centring as the fallback. */
.kfe .kfe-testimonials .head { text-align: var(--kfe-head-align, center); margin-bottom: 70px; }
.kfe .kfe-testimonials .head .kfe-label { color: var(--kfe-highlight); }

/* The head title's level is a control (header_size). At h2 — the released
   default — the widget still prints a BARE <h2> with no class, so every rule
   here pairs the tag with the class the other levels carry, and the two must
   stay IN STEP (ADR-0002 decision 7; hero.css has the same pairing).

   The class-only rules below restate what base.css's `.kfe h2` gives the bare
   tag, including the dark-ground flip `.kfe .kfe-dark h2` — they are listed
   separately, and never merged into the paired rule, because a merged rule
   would outrank that flip and repaint every dark testimonials head. */
.kfe .kfe-testimonials .head h2,
.kfe .kfe-testimonials .head .kfe-testimonials-title { font-size: var(--kfe-title-size, var(--kfe-h2-size, clamp(2rem, 4.4vw, 3.4rem))); }
.kfe .kfe-testimonials .head .kfe-testimonials-title {
  font-family: var(--kfe-font-heading);
  font-weight: var(--kfe-heading-weight);
  letter-spacing: -0.01em;
  color: var(--kfe-heading, var(--kfe-primary));
  margin: 0;
}
.kfe .kfe-testimonials.kfe-dark .head .kfe-testimonials-title { color: #fff; }

.kfe .kfe-testimonials .tcard {
  display: grid; grid-template-columns: 0.85fr 1.15fr; gap: 5vw;
  align-items: center; margin-bottom: 90px;
}
.kfe .kfe-testimonials .tcard:last-child { margin-bottom: 0; }
.kfe .kfe-testimonials .tcard:nth-child(odd) { grid-template-columns: 1.15fr 0.85fr; }
.kfe .kfe-testimonials .tcard:nth-child(odd) .portrait { order: 2; }

/* ---------- one column, because the row has no portrait (#122) ----------
   The counterpart to `kfe_split_media`'s `.no-media` (split-media.css:98), in
   the same shape, so the two widgets behave alike rather than each having its
   own idea: #106 emptied the image default and the render's collapse started
   firing, and the CARD went on declaring two tracks with nothing in the second.
   Measured on the sweep lane's harness at 1440 against a 967px card: the two
   rows of ONE widget did not agree with each other — 380px and 515px of text in
   the alternating layout, 747px and 615px in the card layout.

   `:nth-child(odd)` is restated so the pair reads as one unit and neither half
   can be moved above line 38 without the other. At equal specificity the source
   order already decides it: `.tcard:nth-child(odd)` (line 38) and
   `.tcard.no-media` are BOTH (0,4,0), and this rule stands after it, so the odd
   rows would collapse without the restatement. (The first draft of this comment
   said the restatement was load-bearing and gave arithmetic that is not true.
   The restatement inside the 820px block at the foot of this sheet IS
   load-bearing and its comment there is correct: the desktop
   `.layout-card .tcard.no-media` rule is (0,5,0) and outranks the media block's
   (0,4,0) `.tcard`, so its 44px would otherwise carry into the phone.) The 820px
   block below already gives every row one column, so nothing here reaches the
   phone. */
.kfe .kfe-testimonials .tcard.no-media,
.kfe .kfe-testimonials .tcard.no-media:nth-child(odd) { grid-template-columns: 1fr; }

/* HARD-FIXED portrait box — every image normalises to this */
.kfe .kfe-testimonials .portrait {
  width: 100%;
  aspect-ratio: 4 / 5;          /* fixed shape for all portraits */
  object-fit: cover;            /* fill the box, crop overflow */
  object-position: top;         /* favour the top (faces) when cropping */
  border-radius: 6px;
  display: block;
  background: rgba(127, 127, 127, 0.08);   /* tint while loading */
}

.kfe .kfe-testimonials .role {
  font-size: 12px; letter-spacing: 0.26em; text-transform: uppercase;
  color: var(--kfe-highlight); margin-bottom: 20px;
}
.kfe .kfe-testimonials h3 { font-size: clamp(1.4rem, 2.6vw, 2rem); line-height: 1.25; margin-bottom: 24px; }
.kfe .kfe-testimonials .desc { color: var(--kfe-muted); margin-bottom: 24px; }
.kfe .kfe-testimonials blockquote {
  font-family: var(--kfe-font-heading);
  font-weight: var(--kfe-heading-weight);
  font-size: clamp(1.25rem, 2.1vw, 1.7rem);
  line-height: 1.5;
  color: var(--kfe-ink);
  border-left: 2px solid var(--kfe-highlight);
  padding-left: 28px;
  margin: 0;
  letter-spacing: 0.005em;
}
.kfe .kfe-testimonials cite {
  display: block; margin-top: 20px; font-style: normal;
  font-size: 13px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--kfe-muted);
}

/* dark-ground flips.

   `.role` joined this list in w2.reveal.1 (#246). Every other run that goes
   dark had a flip — `.desc`, `blockquote` and `cite` here, and `blockquote`
   and `cite` again inside `layout-card`'s own painted card — and the
   attribution line did not, so it kept `var(--kfe-highlight)`, an ACCENT token
   chosen for a light ground, wherever the band went dark. Measured on the
   EuroEyes preview: `rgb(30, 65, 154)` on `rgb(47, 94, 140)`, **1.36:1**,
   against a reference whose own body prose measures 7.41:1.

   `--kfe-on-dark` rather than the `--kfe-on-dark-soft` that `kfe_facts_card`
   gives the same class, because this run is the attribution beside a quote
   rather than a label above one, and on the pack's own deep ground on-dark
   measures 3.29:1 against on-dark-soft's 2.92:1 — both figures composited,
   since on-dark is `rgba(255,255,255,0.8)` and measuring the declaration
   instead of what is shown overstates it (4.18:1).

   It is flipped HERE and not in `base.css` on purpose. `base.css` carries the
   dark flips for the SHARED primitives Widget_Base renders — `.kfe-label`,
   `.kfe-list`, `.kfe-more`, `h2`/`h3` — and `.role` is not one of them: it is
   a class two widgets happen to share, each painting it from its own sheet at
   (0,3,0). A `.kfe .kfe-dark .role` rule in `base.css` is (0,2,0) and is
   OUTRANKED by the rule at :52 on every page it would be written for, so it
   would read as a fix and move nothing. `kfe_facts_card` flips its own at
   `facts-card.css:209` for exactly this reason.

   And it is not #102's rule extended: #102 is about anchors whose colour falls
   through to the theme (`a:not([class])`), and `.role` is a `<p>` the pack
   itself paints — no anchor rule could have reached it. */
.kfe .kfe-testimonials.kfe-dark .desc { color: var(--kfe-on-dark-soft); }
.kfe .kfe-testimonials.kfe-dark blockquote { color: #eaf0fb; }
.kfe .kfe-testimonials.kfe-dark cite { color: rgba(255, 255, 255, 0.7); }
.kfe .kfe-testimonials.kfe-dark .role { color: var(--kfe-on-dark); }
.kfe .kfe-testimonials.kfe-dark .portrait { background: rgba(255, 255, 255, 0.04); }

/* RTL: the quote bar swaps sides */
html[dir="rtl"] body .kfe .kfe-testimonials blockquote {
  border-left: 0; padding-left: 0;
  border-right: 2px solid var(--kfe-highlight); padding-right: 28px;
}
/* `card` has no bar on either side, so it restates its RTL form: the block
   above is (0,3,3) and outranks the card's own (0,3,1) reset at :140-152. */
html[dir="rtl"] body .kfe .kfe-testimonials.layout-card blockquote {
  border-right: 0; padding-right: 0;
}
html[dir="rtl"] body .kfe .kfe-testimonials .role { letter-spacing: 0; text-transform: none; }
html[dir="rtl"] body .kfe .kfe-testimonials cite { letter-spacing: 0; text-transform: none; }

@media (max-width: 820px) {
  .kfe .kfe-testimonials .tcard,
  .kfe .kfe-testimonials .tcard:nth-child(odd) { grid-template-columns: 1fr; gap: 30px; margin-bottom: 70px; }
  .kfe .kfe-testimonials .tcard:nth-child(odd) .portrait { order: 0; }
  .kfe .kfe-testimonials .portrait { aspect-ratio: 16 / 10; object-position: center; }  /* wider crop on mobile */
}

/* ==========================================================================
   layout=card — the reference's founder quote (spec §3.6)
   --------------------------------------------------------------------------
   One card, painted by card_color (or the primary token when no colour is
   set — never a hex), with the portrait cut out and standing on the card's
   bottom edge while it rises above the top one. The 4:5 box, the highlight
   bar and the alternating grid are all turned off here; `alternating` matches
   none of these selectors and is untouched.

   The geometry — the 22px radius, the 410px portrait, the 144px rise — is
   this layout's own, as the reference draws it, and every one of the four is
   a control an instance can move.

   The rise is one custom property, `--kfe-card-rise`, because two rules read
   it: the portrait's negative margin, and, at 820px and below, the space the
   card keeps free above itself for the head (wp-eedk#368, the rule in the
   820px block at the foot of this sheet). The `portrait_overlap` control
   writes the property, so both follow an instance's value.
   ========================================================================== */
.kfe .kfe-testimonials.layout-card { overflow: visible; --kfe-card-rise: 144px; }

.kfe .kfe-testimonials.layout-card .tcard,
.kfe .kfe-testimonials.layout-card .tcard:nth-child(odd) {
  grid-template-columns: auto minmax(0, 1fr);
  gap: 24px;
  align-items: end;
  margin-bottom: 40px;
  background-color: var(--kfe-primary);
  border-radius: 22px;
  padding-block: 0;
  padding-inline: 28px 44px;
}
.kfe .kfe-testimonials.layout-card .tcard:last-child { margin-bottom: 0; }
.kfe .kfe-testimonials.layout-card .tcard:nth-child(odd) .portrait { order: 0; }

/* A CARD WITH NO PORTRAIT IS A PLAIN QUOTE CARD, and that is the design answer
   #122 asked for rather than a consequence of the collapse. The `auto
   minmax(0, 1fr)` track list sizes its first track to the cut-out portrait, and
   the `28px 44px` asymmetry is that portrait's gutter: 28px of card before the
   cut-out, 44px of card after the text. With the picture gone there is no
   cut-out to sit against, so the asymmetry has nothing left to describe and the
   card keeps the padding the TEXT already had on the side it had it — 44px,
   both sides. Everything else this layout draws is unchanged: the 22px radius,
   the ground, the inner 34px block padding and the italic quote are the card's
   own and have nothing to do with the picture.

   `minmax(0, 1fr)` rather than `1fr` so a long unbroken word cannot push the
   card wider, exactly as the two-track rule above it does. */
.kfe .kfe-testimonials.layout-card .tcard.no-media,
.kfe .kfe-testimonials.layout-card .tcard.no-media:nth-child(odd) {
  grid-template-columns: minmax(0, 1fr);
  padding-inline: 44px;
}

.kfe .kfe-testimonials.layout-card .portrait {
  width: 410px;
  max-width: 100%;
  aspect-ratio: auto;
  object-fit: contain;
  object-position: bottom;
  border-radius: 0;
  background: none;
  margin-top: calc(-1 * var(--kfe-card-rise));
  align-self: end;
}

.kfe .kfe-testimonials.layout-card > .kfe-wrap > .tcard > div { padding-block: 34px; }
.kfe .kfe-testimonials.layout-card blockquote {
  border: 0;
  padding: 0;
  font-family: var(--kfe-font-body);
  font-style: italic;
  font-weight: 400;
  font-size: 23px;
  line-height: 1.5;
  color: #fff;
  letter-spacing: 0;
}
.kfe .kfe-testimonials.layout-card cite {
  margin-top: 16px;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--kfe-on-dark);
}
/* The card's own ground is dark whatever the SECTION's is — `.tcard` is painted
   `card_color`, or `var(--kfe-primary)` when no colour is set — so this layout
   needs the flip even on a `kfe-bg-white` band, and `.kfe-dark` is not set on
   it. This is the shape the 8 filed pages actually rendered (#246): the section
   reads `kfe-section kfe-testimonials layout-card kfe-bg-white`, and the ink
   under measurement was on the CARD. `cite` above has carried the flip since
   the layout shipped; `.role` is the run beside it. */
.kfe .kfe-testimonials.layout-card .role { color: var(--kfe-on-dark); }

@media (max-width: 820px) {
  .kfe .kfe-testimonials.layout-card .tcard,
  .kfe .kfe-testimonials.layout-card .tcard:nth-child(odd) {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
    justify-items: center;
    padding-inline: 22px;
  }
  /* The phone's 22px is the card's, portrait or not: the desktop `.no-media`
     rule above is (0,5,0)/(0,6,0) and would otherwise carry its 44px in here. */
  .kfe .kfe-testimonials.layout-card .tcard.no-media,
  .kfe .kfe-testimonials.layout-card .tcard.no-media:nth-child(odd) { padding-inline: 22px; }
  .kfe .kfe-testimonials.layout-card { --kfe-card-rise: 90px; }
  .kfe .kfe-testimonials.layout-card .portrait {
    width: 68%;
    aspect-ratio: auto;
    object-position: bottom;
  }
  /* THE CARD KEEPS THE HEAD'S ROOM FREE (wp-eedk#368). One column puts the
     portrait at the top of the card and its rise goes straight up, out of the
     card and over whatever stands above it: the section's own head, the card
     before it, or the last line of the section before this one. At 1440 the
     two sections' paddings happened to absorb 144px; at 820 and 390 the
     consuming theme's 52px paddings leave 107px, and the head covered the
     line above on 27 of 29 pages (on ee-build, 2026-09-25). A negative
     margin reserves nothing, so the card reserves the rise itself: a
     margin-top of exactly `--kfe-card-rise` above every card that has a
     portrait. The head now starts where the card would have started, and the
     painted card stays where it was relative to the portrait.

     The wrap becomes a flex column so that margin ADDS to what stands above
     instead of collapsing into it: the head's 70px, and the 40px between two
     cards, are kept as clear space above the portrait. A flex column stretches
     each child to the wrap's width, as the block flow did. */
  .kfe .kfe-testimonials.layout-card > .kfe-wrap { display: flex; flex-direction: column; }
  .kfe .kfe-testimonials.layout-card .tcard:not(.no-media) { margin-top: var(--kfe-card-rise); }
  .kfe .kfe-testimonials.layout-card blockquote { font-size: 19px; }
  .kfe .kfe-testimonials.layout-card > .kfe-wrap > .tcard > div { padding-block: 10px 30px; }
}
