/* ==========================================================================
   Recommendations popup — floating testimonial card
   Design tokens mirror the PeachTouch / Citizen Café system:
   Poppins, #FFE300 brand yellow, #0A0A0A ink, 20px radius, soft shadow.
   All custom properties are namespaced (--rp-*) so the host page's :root
   is never touched and nothing here can leak into site styles.
   ========================================================================== */

.rp-root {
  --rp-brand: #FFE300;
  --rp-ink: #0A0A0A;
  --rp-ink-soft: #55565A;
  --rp-white: #FFFFFF;
  --rp-line: #E6E6E6;
  --rp-tint: #F3F3F4;
  --rp-dot: #C9CACE;

  /* Kept for host pages that theme the component; nothing in here reads them
     any more — the card, the pill and its icon are all square corners. */
  --rp-radius: 20px;
  --rp-radius-sm: 12px;
  --rp-shadow: 0 2px 6px rgba(0, 0, 0, 0.06), 0 18px 44px rgba(0, 0, 0, 0.22);
  --rp-ease: cubic-bezier(0.390, 0.575, 0.565, 1.000);

  --rp-width: 300px;          /* desktop card width (max. 300px) */
  --rp-gap: 20px;             /* distance from the viewport edges */
  --rp-card-pad: 1.35rem;     /* left / right */
  --rp-card-pad-y: var(--rp-head-gap);  /* top == bottom, see --rp-head-gap */
  /* The header row: what the removed "Kind words from clients" heading used to
     occupy (0.95rem × 1.35 line box, 0.9rem below it). The dots row now fills
     it, and the X is centred on it, so nothing below moved when it went. */
  --rp-head-h: calc(0.95rem * 1.35);
  --rp-head-gap: 0.9rem;

  /* Paragraph gap inside a testimonial, and the value it replaced. Both are in
     rem — not em — so the compensation below resolves against the same basis as
     the gap itself, which is set on text at 0.95rem. */
  --rp-para-gap: 0.33rem;     /* ~0.35em at the quote's size */
  --rp-para-gap-was: 0.7125rem;  /* the old 0.75em */

  position: fixed;
  z-index: 99999;
  right: calc(var(--rp-gap) + env(safe-area-inset-right, 0px));
  /* One token for how far the root sits off the bottom edge, so the pill can
     cancel exactly that and sit flush without re-deriving the value — the mobile
     block overrides this to 16px, which --rp-gap alone would not capture. */
  --rp-bottom: calc(var(--rp-gap) + env(safe-area-inset-bottom, 0px));
  bottom: var(--rp-bottom);
  width: var(--rp-width);
  max-width: calc(100vw - (var(--rp-gap) * 2));

  font-family: 'Poppins', system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--rp-ink);
  line-height: 1.6;
  /* The wrapper is only a positioning anchor — clicks pass through to the page
     everywhere except on the card / button themselves. */
  pointer-events: none;
}

.rp-root *,
.rp-root *::before,
.rp-root *::after { box-sizing: border-box; }

/* --------------------------------------------------------------------------
   State machine: hidden (nothing on screen) / open (card) / min (pill button)
   -------------------------------------------------------------------------- */

.rp-card,
.rp-fab {
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition:
    opacity 0.32s var(--rp-ease),
    transform 0.32s var(--rp-ease),
    visibility 0s linear 0.32s;
}

.rp-root[data-state="open"] .rp-card,
.rp-root[data-state="min"] .rp-fab {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition-delay: 0s, 0s, 0s;
  pointer-events: auto;
}

/* Both children share the same bottom-right anchor so the swap never nudges
   layout; the card is in flow, the pill is absolutely pinned to the corner. */
.rp-fab {
  position: absolute;
  right: 0;
  /* -1px against the viewport's bottom edge: cancel the root's own inset, then
     take a further 1px, so the pill's bottom border sits just off-screen and no
     hairline shows under it. The card is anchored to the root itself, so it does
     not move. */
  bottom: calc(-1px - var(--rp-bottom));
}

/* --------------------------------------------------------------------------
   Card
   -------------------------------------------------------------------------- */

.rp-card {
  position: relative;
  background: var(--rp-white);
  border: 1px solid rgba(0, 0, 0, 0.06);
  box-shadow: var(--rp-shadow);
  padding: var(--rp-card-pad-y) var(--rp-card-pad);
  overflow: hidden;
}

/* X / minimise --------------------------------------------------------------- */

/* Centred on the header row: the card's top padding, plus half that row, minus
   half the 44px target. Derived from the tokens, so a padding change keeps
   them level. */
.rp-close {
  position: absolute;
  top: calc(var(--rp-card-pad-y) + (var(--rp-head-h) / 2) - 22px);
  right: 4px;
  width: 44px;               /* full 44×44 touch target … */
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--rp-ink-soft);
  opacity: 0.7;
  cursor: pointer;
  border-radius: 50%;
  transition: opacity 0.24s var(--rp-ease), transform 0.24s var(--rp-ease);
}

.rp-close::before {           /* … with a small, unobtrusive 28px visual disc */
  content: "";
  position: absolute;
  inset: 8px;
  border-radius: 50%;
  background: var(--rp-tint);
  /* Grows in from 80% rather than appearing at full size — the disc reads as
     settling under the cursor instead of blinking on. */
  opacity: 0;
  transform: scale(0.8);
  transition:
    opacity 0.24s var(--rp-ease),
    transform 0.24s var(--rp-ease);
}

.rp-close:hover,
.rp-close:focus-visible { opacity: 1; }

.rp-close:hover::before,
.rp-close:focus-visible::before {
  opacity: 1;
  transform: scale(1);
}

.rp-close:active { transform: scale(0.92); }
.rp-close svg { position: relative; width: 13px; height: 13px; }

/* Slide stage ---------------------------------------------------------------- */

/* Every slide sits in the same grid cell, so the stage is always as tall as the
   tallest slide — crossfades cannot shift the layout under the pointer. */
.rp-stage {
  display: grid;
  touch-action: pan-y;        /* leaves vertical page scroll to the browser */
  /* A click anywhere here moves to the next recommendation, so the pointer says
     so. e-resize is the fallback where a custom cursor is refused. */
  cursor: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='28'%20height='28'%20viewBox='0%200%2028%2028'%3E%3Cg%20fill='none'%20stroke='%23FFFFFF'%20stroke-width='4.5'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M6%2014h15M15%208l6%206-6%206'/%3E%3C/g%3E%3Cg%20fill='none'%20stroke='%230A0A0A'%20stroke-width='2.2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M6%2014h15M15%208l6%206-6%206'/%3E%3C/g%3E%3C/svg%3E") 14 14, e-resize;
}

.rp-slide {
  grid-area: 1 / 1;
  /* Three rows, and only the first one flexes: it absorbs every difference in
     quote length, so the person block, the separator and the tag/CTA row below
     it hold the same height on every slide and in either language — the
     crossfade never moves anything. The quote is centred in that flexible row,
     so a short one sits in the middle of the space rather than at the top. */
  display: grid;
  grid-template-rows: 1fr auto auto;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.32s var(--rp-ease),
    visibility 0s linear 0.32s;
}

.rp-slide[data-active="true"] {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s, 0s;
}

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

/* Same overlay trick one level down: the English and Hebrew paragraphs occupy
   one cell, so toggling language cannot resize the card either. */
.rp-quote-wrap {
  display: grid;
  align-content: center;        /* the quote is centred in the flexible row … */
  align-self: stretch;          /* … so the row keeps all of its slack */
  margin: 0;
  /* Keeps the card exactly the height the old gap gave it. The tallest
     testimonial is the three-paragraph one, so it lost 2 × (was − now) when the
     gap shrank; padding-block puts that back, half at each edge. Shorter
     testimonials grow by the same amount but stay well under the tallest, so
     the stage — and the card — do not move. */
  padding-block: calc(var(--rp-para-gap-was) - var(--rp-para-gap));
  max-height: 15em;           /* guard rail for future long testimonials */
  overflow-y: auto;
  overscroll-behavior: contain;
}

.rp-quote {
  grid-area: 1 / 1;
  /* The box hugs its text (fit-content, capped by the card) and is centred in
     the cell; the lines are centred inside it. A quote long enough to wrap ends
     up full width, where hugging is a no-op and only the centring shows. */
  /* Both languages share this cell, so the row is as tall as the longer of the
     two and each box stretches to it. Without this the shorter language hangs
     from the top of that row — which is what a three-paragraph English quote
     did to its one-paragraph Hebrew. */
  display: grid;
  align-content: center;
  justify-self: center;
  width: fit-content;
  max-width: 100%;
  text-align: center;
  margin: 0;
  font-size: var(--rp-quote-size, 0.95rem);   /* per entry via `quoteSize` */
  font-weight: 500;
  font-style: italic;           /* real face: poppins-latin-500-italic.woff2 */
  line-height: 1.65;
  color: var(--rp-ink);
  overflow-wrap: anywhere;
  quotes: "\201C" "\201D";      /* curly double quotes, both languages */
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.24s var(--rp-ease), visibility 0s linear 0.24s;
}

.rp-quote[data-shown="true"] {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s, 0s;
}

/* One <p> per paragraph; the gap is the only thing separating them. */
.rp-para { margin: 0; }
.rp-para + .rp-para { margin-top: var(--rp-para-gap); }

/* Generated, so the marks stay out of the testimonial data and cannot be
   half-copied when only one language is on screen. They hang off the first and
   last paragraph rather than the quote box, so a multi-paragraph testimonial
   opens once at the very start and closes once at the very end. */
.rp-quote .rp-para:first-child::before { content: open-quote; }
.rp-quote .rp-para:last-child::after   { content: close-quote; }

/* Assistant is self-hosted (Hebrew subset); Heebo / Arial Hebrew are only there
   for a host page that does not ship it. Assistant has no italic face and
   Hebrew has no italic tradition, so the quote's italic is switched off here —
   the English quote keeps its real drawn italic. direction stays RTL so the
   bidi order is right; the centring is shared. */
.rp-quote[lang="he"] {
  direction: rtl;
  font-style: normal;
  font-family: "Assistant", "Heebo", "Arial Hebrew", system-ui, sans-serif;
  /* Assistant runs small next to Poppins, so Hebrew keeps its +0.05rem step
     whatever size the entry asks for. */
  font-size: calc(var(--rp-quote-size, 0.95rem) + 0.05rem);
}

/* Translation tag + CTA — the last row, under the separator ------------------ */

.rp-meta {
  align-self: end;
  display: flex;
  align-items: center;
  justify-content: center;      /* the pair sits centred under the separator */
  flex-wrap: wrap;
  gap: 0.5rem 0.7rem;
  margin-top: 0.9rem;
  margin-bottom: -6px;
  padding-top: 0.3rem;          /* .rp-cta's -0.6rem carries the rest of the gap */
  border-top: 1px solid var(--rp-line);
}

/* Both labels share one cell, so the pill is as wide as the longer of them in
   either state — "Translated" and "Original" are the same size — and the label
   crossfades rather than being swapped in place. */
.rp-tag {
  display: inline-grid;
  place-items: center;
  height: 22px;
  padding: 0 0.6rem;
  border-radius: 999px;
  background: var(--rp-tint);
  color: var(--rp-ink-soft);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.rp-tag-label,
.rp-cta-label {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.24s var(--rp-ease), visibility 0s linear 0.24s;
}

.rp-tag-label[data-shown="true"],
.rp-cta-label[data-shown="true"] {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s, 0s;
}

.rp-cta {
  display: inline-grid;
  /* The wider label sets the width, and both centre inside it — otherwise the
     narrower "Translate" would sit off-centre in a box kept wide by
     "Show original", and the centred row would look misaligned in Hebrew. */
  place-items: center;
  min-height: 44px;            /* touch target … */
  margin: -0.6rem 0;           /* … without inflating the visual row */
  padding: 0 0.15rem;
  border: 0;
  background: none;
  font: inherit;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--rp-ink-soft);   /* same grey as the card title */
  cursor: pointer;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: var(--rp-dot);
  transition: text-decoration-color 0.2s var(--rp-ease);
  white-space: nowrap;
}

.rp-cta:hover { text-decoration-color: var(--rp-brand); }

/* Person — sits directly under the quote, above the separator ---------------- */

/* One more overlay: the English and the mirrored Hebrew details occupy the same
   cell, so switching language crossfades the whole row — ring, name and role —
   and the card cannot resize around it. */
.rp-person-wrap {
  display: grid;
  align-self: end;
  margin-top: 0.85rem;          /* minimum gap when a long quote fills the row */
}

.rp-person {
  grid-area: 1 / 1;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.24s var(--rp-ease), visibility 0s linear 0.24s;
}

.rp-person[data-shown="true"] {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s, 0s;
}

/* dir="rtl" on the Hebrew copy puts the ring on the right and starts the name
   and role from the right edge, so the two rows read as a mirror pair. */
.rp-person[data-lang="he"] .rp-name,
.rp-person[data-lang="he"] .rp-role {
  font-family: "Assistant", "Heebo", "Arial Hebrew", system-ui, sans-serif;
}

/* Assistant runs lighter than Poppins at the same weight, so the Hebrew role
   takes 500 where the English one sits at 400. */
.rp-person[data-lang="he"] .rp-role {
  font-weight: 500;
}

.rp-avatar {                   /* yellow ring around the portrait */
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--rp-brand);
  padding: 3px;
  display: grid;
  place-items: center;
}

.rp-avatar > * {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  display: grid;
  place-items: center;
}

.rp-initials {                 /* fallback when no portrait is supplied */
  background: #F6F6F7;
  color: var(--rp-ink);
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1;
}

/* A role that wraps to two lines ("Head of Product · Citizen Café Tel Aviv")
   would otherwise make that slide's person block taller and nudge everything
   above it. Reserve the two-line height and cap at two lines, so the block is
   the same height on every slide. */
.rp-person-text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 54px;
}

.rp-name {
  display: block;
  font-size: 0.88rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--rp-ink);
}

/* Each part is unbreakable, and the single space between them is the only
   break opportunity — so a role line that does not fit wraps there and nowhere
   else, putting the company on its own line. */
.rp-role-title,
.rp-role-org { white-space: nowrap; }

.rp-role {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 0.78rem;
  font-weight: 400;
  line-height: 1.4;
  color: var(--rp-ink-soft);
}

/* Pagination dots ------------------------------------------------------------ */

.rp-dots {
  display: flex;
  justify-content: center;
  align-items: center;         /* 44px targets centre on the shorter row … */
  gap: 0;
  height: var(--rp-head-h);    /* … the heading's line box, inherited as-is */
  margin: 0 0 var(--rp-head-gap);
}

.rp-dot {
  width: 1rem;                 /* 16 × 44 target — narrower than the 44px
                                  recommendation, at the user's request */
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.rp-dot::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--rp-dot);
  transition: background-color 0.25s var(--rp-ease);
}

.rp-dot:hover::before { background: var(--rp-ink-soft); }

.rp-dot[data-active="true"]::before {
  /* Brand yellow at the same 7px as the others — the size step that used to
     back it up was dropped at the user's request, so hue is now the only thing
     marking the active dot. Yellow on white is roughly 1.2:1. */
  background: var(--rp-brand);
}

/* --------------------------------------------------------------------------
   Minimised pill
   -------------------------------------------------------------------------- */

/* Surface: white by default. Over a dark backdrop the script measures the
   colour behind the pill and writes it to --rp-surface, so the pill takes that
   same gray and its label flips to white — it sits on the panel instead of
   punching a white hole in it. Every value falls back to the light treatment,
   so the pill is unchanged with no JS. */
.rp-fab {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  height: 48px;
  padding: 0 1rem 0 0.5rem;
  border: 1px solid var(--rp-surface-line, rgba(0, 0, 0, 0.06));
  background: var(--rp-surface, var(--rp-white));
  box-shadow: var(--rp-shadow);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--rp-surface-ink, var(--rp-ink));
  white-space: nowrap;
  cursor: pointer;
}

.rp-root[data-surface="dark"] {
  --rp-surface-ink: var(--rp-white);
  --rp-surface-line: rgba(255, 255, 255, 0.16);
}

.rp-root[data-state="min"] .rp-fab:hover { transform: translateY(-2px); }

.rp-fab-icon {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  background: var(--rp-brand);
  display: grid;
  place-items: center;
}

.rp-fab-icon svg { width: 14px; height: 14px; }

/* --------------------------------------------------------------------------
   Responsive — mobile keeps safe margins and clears the browser chrome
   -------------------------------------------------------------------------- */

@media (max-width: 480px) {
  .rp-root {
    --rp-gap: 12px;
    --rp-width: 100%;
    left: calc(var(--rp-gap) + env(safe-area-inset-left, 0px));
    right: calc(var(--rp-gap) + env(safe-area-inset-right, 0px));
    --rp-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    width: auto;
    max-width: none;
  }

  .rp-root { --rp-card-pad: 1.15rem; }
  .rp-card { padding: var(--rp-card-pad-y) var(--rp-card-pad); }
  .rp-quote-wrap { max-height: 11em; }
  .rp-fab { height: 46px; }
}

/* Short viewports (landscape phones): keep the card from filling the screen. */
@media (max-height: 520px) {
  .rp-quote-wrap { max-height: 7.5em; }
  .rp-person-wrap { margin-top: 0.7rem; }
  .rp-meta { margin-top: 0.7rem; }
}

/* --------------------------------------------------------------------------
   Reduced motion — autoplay is disabled in JS; here we drop the transitions
   but keep every element's shown/hidden end state intact.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .rp-card,
  .rp-fab,
  .rp-slide,
  .rp-quote,
  .rp-person,
  .rp-tag,
  .rp-tag-label,
  .rp-cta-label,
  .rp-dot::before,
  .rp-close,
  .rp-close::before,
  .rp-cta {
    transition-duration: 0s !important;
    transition-delay: 0s !important;
  }

  .rp-card,
  .rp-close,
  .rp-close::before,
  .rp-fab { transform: none; }
  .rp-root[data-state="min"] .rp-fab:hover { transform: none; }
}
