/* ═══════════════════════════════════════════════════════════
   SCENE 10 — WHAT THEY SAY

   CARDS IN A ROW, TWO AT A TIME, STEPPED BY TWO ARROWS.

   THIS REPLACED A STACK, AND THE STACK IS WHY. The quotes used to
   sit one on top of another in a single grid cell with only opacity
   separating them — which works exactly as long as every frame of
   every transition sets the opacity of every quote correctly. Any
   moment where two of them are visible puts two paragraphs through
   each other and the section becomes unreadable, which is what
   happened. Cards in a row cannot do that: each one occupies its own
   space, and nothing has to be hidden for the section to be right.

   IT IS A SCROLLER, NOT A SWITCHER, and that also comes from the
   same fix. Once the cards are side by side the browser's own
   overflow does the work — the arrows only nudge it — so there is
   no state to get wrong and it still works with the script disabled.

   THE CARDS ARE TYPE AND A RULE, NOTHING ELSE. The projects section
   already has bordered cards with photographs in them; if these
   carried the same weight the two rows would read as the same
   component holding different things. A testimonial has no image
   worth showing, so the card is a quote, a line, and a name.

   IT SITS AFTER THE INVITATION, not before it. That is the less
   obvious order — proof usually comes before the ask — but the panel
   above asks a question, and these are the answers somebody goes
   looking for once it has been put to them.
   ═══════════════════════════════════════════════════════════ */

.rv {
  position: relative;
  /* ABOVE THE TRAVELLING PICTURE at z-index 5, like every section
     after the hero. */
  z-index: 6;
  /* Paper above the invitation, blue below it - one token, switched
     on <html>. See css/core.css. */
  background: var(--page);
  transition: background-color .9s var(--ease);
  padding-block: 8rem 13rem;
  overflow: hidden;
}

/* ── The head ────────────────────────────────────────────
   THE CLAIM, THEN THE CONTROLS. A paragraph used to sit between them
   explaining who the five families were — the sort of line that
   reads as a caption for a section rather than as part of it, and it
   was holding a column the button and the arrows wanted. Everything
   on the right is now something to press.

   auto ON THE SECOND TRACK, so the tools take the width they need
   and the claim takes the rest. A fraction there would set the gap
   between the two by arithmetic instead of by what is in them. */
.rv-head {
  grid-column: content;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--gap);
  align-items: end;
  margin-bottom: 6rem;
}

/* The button and the arrows read as one group, so they share a
   baseline and a single gap. */
.rv-tools {
  display: flex;
  align-items: center;
  gap: 2rem;
}

/* Matched to .wk-all on the projects row: the same button doing the
   same job on the same page should be the same size. */
.rv-all { --h: 4.6rem; padding: 0 2rem; font-size: 1.15rem; }

.rv-eyebrow {
  display: flex;
  align-items: center;
  gap: 1.4rem;
  margin-bottom: 2.2rem;
  font-family: var(--font-sans);
  font-size: 1.2rem;
  font-weight: 500;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--gold-deep);
}
.rv-eyebrow i { width: 3.4rem; height: var(--hair); background: currentColor; opacity: .5; }

.rv-title {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 5.6rem;
  line-height: 1.1;
  letter-spacing: -.024em;
}

.rv-nav { display: flex; gap: 1.2rem; }

.rv-arrow {
  width: 4.6rem;
  height: 4.6rem;
  display: grid;
  place-items: center;
  border: var(--hair) solid var(--line-light-lift);
  border-radius: 100vmax;
  background: none;
  color: var(--ink);
  cursor: pointer;
  transition: border-color .4s var(--ease), color .4s var(--ease);
}
.rv-arrow svg { width: 1.8rem; height: 1.8rem; display: block; }
.rv-arrow:hover { border-color: var(--gold); color: var(--gold-deep); }
.rv-arrow:focus-visible { outline: 2px solid var(--gold); outline-offset: .5rem; }

/* No disabled state: the arrows wrap. Five cards is a loop, not a
   run with two ends, and an arrow greying out would say otherwise. */

/* ── The row ─────────────────────────────────────────────
   ON THE CONTENT COLUMN, NOT FULL BLEED. It ran to the right edge of
   the window so the row would visibly continue past it, and the
   price was a third card sliced down the middle by the screen edge.
   Three whole cards read as a set; two and a slice reads as a layout
   that did not fit. There are five, so the row still scrolls —
   nothing is lost but the sliver. */
.rv-rail {
  grid-column: content;
  display: flex;
  gap: var(--gap);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  /* ONE PIXEL EACH SIDE, and the snapport inset to match. A card's
     border lands exactly on the scrollport's clip boundary, so a
     fractional scroll position cuts whichever side falls on the
     wrong half of a device pixel — and scroll-padding is what moves
     the line the snap aligns to, since padding alone just makes the
     row rest one pixel further along. The projects row carries the
     same two lines for the same reason. */
  padding-inline: 2px;
  margin-inline: -2px;
  scroll-padding-inline: 2px;
  /* The scrollbar is furniture the arrows already replace. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.rv-rail::-webkit-scrollbar { display: none; }

/* ── A card ──────────────────────────────────────────────
   EXACTLY THREE ACROSS, so every card on screen is a whole one. Two
   gaps between three cards, which is why the divisor and the gap
   count differ by one — getting that wrong is what leaves a card
   hanging a few pixels over the edge. */
.rv-card {
  flex: 0 0 calc((100% - 2 * var(--gap)) / 3);
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  padding: 4.4rem 4rem 3.6rem;
  background: #fff;
  border: var(--hair) solid var(--line-light);
  transition: border-color .5s var(--ease-out),
              background-color .9s var(--ease);
}
.rv-card:hover { border-color: rgba(217, 179, 120, .55); }

.rv-text {
  flex: 1;
  margin: 0;
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 2.05rem;
  line-height: 1.5;
  letter-spacing: -.008em;
  color: var(--ink);
}

.rv-by {
  margin-top: 3.4rem;
  padding-top: 2.2rem;
  /* Gold, because it is the one coloured thing on a card of nothing
     but type — and it separates the voice from the person the way
     the rule under a signature does. */
  border-top: var(--hair) solid rgba(217, 179, 120, .5);
  font-family: var(--font-sans);
  font-size: 1.15rem;
  font-weight: 500;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--on-light-mute);
}
.rv-by b { display: block; margin-bottom: .5rem; color: var(--ink); font-weight: 500; }

/* ── The pre-JS state ────────────────────────────────────
   Guarded, so a browser without GSAP shows the row rather than
   hiding it for good. Nothing here needs the script to be readable:
   the rail is an ordinary horizontal scroller. */
.has-gsap .rv:not(.is-in) .rv-head,
.has-gsap .rv:not(.is-in) .rv-rail { opacity: 0; }

/* ── Responsive ──────────────────────────────────────────── */
@media (max-width: 1200px) {
  .rv-title { font-size: 4.6rem; }
  /* Two at this width: three would set each quote to about thirty
     characters a line, which is a column, not a card. */
  .rv-card { flex-basis: calc((100% - var(--gap)) / 2); }
}

@media (max-width: 991px) {
  .rv { padding-block: 7rem 10rem; }
  /* The tools drop under the claim rather than squeezing a second
     column out of a row that no longer has the width for one. */
  .rv-head { grid-template-columns: 1fr; gap: 3rem; margin-bottom: 4.5rem; }
  .rv-tools { justify-content: space-between; }
  .rv-title { font-size: 3.9rem; }
  .rv-card {
    flex-basis: calc((100% - var(--gap)) / 2);
    padding: 3.8rem 3.4rem 3.2rem;
  }
  .rv-text { font-size: 1.95rem; }
}

@media (max-width: 767px) {
  .rv { padding-block: 5.5rem 8rem; }
  .rv-title { font-size: 3.2rem; }
  .rv-card {
    flex-basis: 100%;
    padding: 3.4rem 2.8rem 2.8rem;
  }
  .rv-text { font-size: 1.85rem; }
  .rv-by { margin-top: 2.8rem; padding-top: 1.8rem; }
  /* The button and the arrows have to come down together, or the
     group sits on two different heights. */
  .rv-arrow { width: 4.2rem; height: 4.2rem; }
  .rv-all { --h: 4.2rem; padding: 0 1.7rem; }
}

/* ── After the page turns ────────────────────────────────
   THE ONLY SECTION BELOW THE INVITATION, so it is the only one that
   has to be legible on both grounds. The switch is a class on <html>
   written by js/sections/cta.js; everything here is the same block
   in the other register, not a second design.

   THE CARD LIFTS RATHER THAN INVERTS. On paper it is white against a
   warm ground — a sheet on a table. The night equivalent is a step
   UP from the page, not a step down, so it keeps being an object
   sitting on the ground rather than a hole cut into it.

   THE BUTTON IS NOT RESTYLED HERE. The site already has one answer
   for a control on a dark surface — .on-dark .btn in core.css — and
   the same script that turns the page puts that class on the
   section. A second set of button colours in this file would be a
   second owner of the same decision.

   EVERY COLOUR TRANSITIONS ON THE SAME .9s AS THE GROUND. If the
   type snapped while the background faded, the section would read as
   two changes rather than one. */
html.is-night .rv-title,
html.is-night .rv-text,
html.is-night .rv-by b { color: var(--paper); }

html.is-night .rv-by { color: var(--on-dark-mute); }

html.is-night .rv-card {
  /* Sampled off the page value: light enough to separate at a
     glance, dark enough that five of them in a row do not read as a
     band of panels with a background behind them. */
  background: #141d2e;
  border-color: rgba(251, 250, 247, .10);
}
html.is-night .rv-card:hover { border-color: rgba(217, 179, 120, .5); }

html.is-night .rv-arrow {
  border-color: var(--line-dark-lift);
  color: var(--paper);
}
html.is-night .rv-arrow:hover { border-color: var(--gold); color: var(--gold); }

/* The gold darkened for paper is too low-contrast on navy; the
   lifted one is the value the rest of the site uses on dark. */
html.is-night .rv-eyebrow { color: var(--gold-lift); }

.rv-title,
.rv-text,
.rv-by,
.rv-by b,
.rv-eyebrow { transition: color .9s var(--ease); }
