/* Stillhaven — the testimonial gate.
 *
 * A file of its own, and this is the reason: the /lp/* landing pages deliberately do NOT load
 * site.css. They inline a lean stylesheet so an ad click renders without pulling the whole site's
 * CSS. The gate ships on the home page AND on every landing page, so its styles have to live
 * somewhere both can reach without either one duplicating them.
 *
 * Copying these rules into lp.php's inline <style> was the obvious alternative and is exactly the
 * mistake this codebase keeps paying for — prices drifted across four files twice, once quoting a
 * customer $86 for a $79 plan. One file, linked twice, cannot drift.
 *
 * Loaded by views/layout.php (every normal page) and by views/lp.php (the landing pages).
 */

/* ============================================================
   The gate  (partials/testimonials-gate.php)
   ============================================================
   Testimonials as frames of film advancing past a FIXED sprocket rail. The rail never travels with
   the content — it holds still and the quotes move through it, which is exactly what a projector
   gate does. The sprockets themselves pull by two perforation pitches on each advance, so the strip
   is visibly running rather than the frames merely fading.

   The track is a 1x1 grid with every slide in the same cell, so the frame is naturally as tall as
   the longest quote. No JS height measuring, and no clipping when a quote wraps differently at a
   different width. */

/* Held to a readable measure. Left to the full 1080px inner the quote ran to ~17 words a line,
   which is well past the 65-ish the brand guide asks for and past what anyone actually reads. */
.tmg { --tmg-pitch: 46px; --tmg-dur: 520ms; max-width: 74ch; margin-inline: auto; }

.tmg-frame { position: relative; border: 1px solid var(--sage-100, #E8EDD9); border-left: 0;
  padding: 28px 30px 24px 46px; overflow: hidden; }

/* The gate. Its own position is fixed; only the sprocket pattern moves. */
.tmg-rail { position: absolute; left: 0; top: 0; bottom: 0; width: 18px; z-index: 2;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='46' viewBox='0 0 18 46'%3E%3Cmask id='n'%3E%3Crect width='18' height='46' fill='%23fff'/%3E%3Crect x='5' y='12' width='8' height='22' rx='3' fill='%23000'/%3E%3C/mask%3E%3Crect width='18' height='46' fill='%23849B54' mask='url(%23n)'/%3E%3C/svg%3E") repeat-y left top;
  transition: background-position var(--tmg-dur) cubic-bezier(.22,.61,.36,1); }

.tmg-track { display: grid; }

/* A hand-off, not a cross-fade. Both frames occupy the same grid cell, so overlapping them at
   partial opacity renders two paragraphs of body text on top of each other — legible as neither.
   The outgoing frame clears in 200ms; the incoming one waits for it before starting. Film leaves
   the gate before the next frame arrives, which is also just what film does. */
.tmg-slide { grid-area: 1 / 1; margin: 0; min-width: 0;
  transform: translateY(14%); opacity: 0; visibility: hidden; pointer-events: none;
  transition: transform var(--tmg-dur) cubic-bezier(.22,.61,.36,1),
              opacity 200ms ease,
              visibility 0s linear var(--tmg-dur); }
.tmg-slide.is-current { transform: none; opacity: 1; visibility: visible; pointer-events: auto;
  transition: transform var(--tmg-dur) cubic-bezier(.22,.61,.36,1),
              opacity 300ms ease 210ms,
              visibility 0s; }
/* Outgoing frame leaves upward — film runs one way through a gate. */
.tmg-slide.is-leaving { transform: translateY(-14%); opacity: 0; }

.tmg-quote { margin: 0; }
.tmg-quote p { margin: 0; font-size: 17.5px; line-height: 1.68; color: var(--ink, #1A1A1A); }

.tmg-by { display: flex; align-items: center; gap: 14px; margin: 22px 0 0; padding: 18px 0 0;
  border-top: 1px solid var(--sage-100, #E8EDD9); }
.tmg-face { width: 52px; height: 52px; border-radius: 50%; flex: 0 0 52px; object-fit: cover;
  background: var(--sage-50, #F5F7EF); }
.tmg-who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tmg-name { font-size: 15px; font-weight: 600; color: var(--ink, #1A1A1A); }
.tmg-role { font-size: 13px; font-weight: 500; color: var(--gray, #888); }
/* The company name IS the link — a bare domain on its own line was a second, weaker copy of what
   the company name already says. Underlined from rest, because a link that only announces itself on
   hover is a link most people never find. */
.tmg-site { color: var(--sage-600, #6C7F43); text-decoration: underline;
  text-decoration-color: var(--sage-300, #B7C691); text-underline-offset: 2px; }
.tmg-site:hover, .tmg-site:focus-visible { color: var(--sage-700, #556231);
  text-decoration-color: currentColor; }
.tmg-site:focus-visible { outline: 2px solid var(--sage-600, #6C7F43); outline-offset: 2px; }

/* Controls, styled as film hardware rather than as generic carousel chrome. */
.tmg-controls { display: flex; align-items: center; gap: 10px; margin: 16px 0 0; padding-left: 46px; }

.tmg-arrow, .tmg-pause { display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0; border: 1px solid var(--sage-200, #D3DCB8);
  background: transparent; color: var(--sage-700, #556231); cursor: pointer;
  transition: background-color .16s ease, border-color .16s ease, color .16s ease; }
.tmg-arrow svg, .tmg-pause svg { width: 17px; height: 17px; }
.tmg-pause svg { fill: currentColor; }
.tmg-arrow:hover, .tmg-pause:hover { background: var(--sage-100, #E8EDD9); border-color: var(--sage-300, #B7C691); }
.tmg-arrow:focus-visible, .tmg-pause:focus-visible, .tmg-dot:focus-visible {
  outline: 2px solid var(--sage-600, #6C7F43); outline-offset: 2px; }

.tmg-pause { margin-left: auto; }
.tmg-ico-play { display: none; }
.tmg[data-paused="true"] .tmg-ico-pause { display: none; }
.tmg[data-paused="true"] .tmg-ico-play { display: block; }

/* Frame markers cut to the sprocket hole's own shape — a rounded rect, not the usual circle. */
.tmg-frames { display: flex; align-items: center; gap: 7px; }
.tmg-dot { width: 9px; height: 22px; padding: 0; border: 0; border-radius: 3px; cursor: pointer;
  background: var(--sage-200, #D3DCB8);
  transition: background-color .2s ease, transform .2s ease; }
.tmg-dot:hover { background: var(--sage-300, #B7C691); }
.tmg-dot.is-current { background: var(--sage-600, #6C7F43); transform: scaleY(1.14); }

/* Mono, because the brand reserves it for specs and data — and a frame counter is data. */
.tmg-count { font-family: 'Space Mono', ui-monospace, monospace; font-size: 12px; font-weight: 700;
  letter-spacing: 1px; color: var(--n-400, #A6A69D); }

.tmg-live { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0);
  clip-path: inset(50%); white-space: nowrap; margin: 0; }

@media (max-width: 860px) {
  .tmg-frame { padding: 22px 20px 20px 36px; }
  .tmg-quote p { font-size: 16.5px; }
  .tmg-controls { padding-left: 36px; }
}

/* Motion is the point here, so removing it has to leave something that still works: frames swap
   instantly, the strip does not travel, and the auto-advance never starts (handled in site.js). */
@media (prefers-reduced-motion: reduce) {
  .tmg-rail, .tmg-slide { transition: none; }
  .tmg-slide { transform: none; }
  .tmg-slide.is-leaving { transform: none; }
}
