/* Jeje Labs cursor companion — the brand mark trails the pointer, and a click
   drops a bare quote right where you clicked. Shared by the Astro home page and
   the static app pages, so all of it is plain CSS with no build step. */

.jj-companion {
  position: fixed;
  top: 0;
  left: 0;
  width: 34px;
  height: 34px;
  margin: -17px 0 0 -17px;
  z-index: 9000;
  pointer-events: none;
  opacity: 0;
  will-change: transform;
  transition: opacity 0.35s ease;
}
.jj-companion.is-awake { opacity: 1; }

.jj-companion-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.18));
  transform-origin: 50% 60%;
  transition: transform 0.28s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.jj-companion.is-poked .jj-companion-img { transform: scale(0.78); }

.jj-review-layer {
  position: fixed;
  inset: 0;
  z-index: 8990;
  pointer-events: none;
}

/* The app pages hardcode their colours instead of exposing CSS variables, so the
   layer carries the current theme itself and everything below keys off that.
   On dark the quote is the Jeje Labs gold (#FEC302) at full strength. On the
   near-white page that same gold is unreadable as running text, so it steps back
   to ink there and the gold stays where it belongs — the mark, the dots, the
   period after the tagline. */
.jj-review-layer[data-theme="light"] { --jj-quote: #1a1a17; --jj-scrim: rgba(250, 249, 246, 0.94); }
.jj-review-layer[data-theme="dark"]  { --jj-quote: oklch(0.88 0.175 87); --jj-scrim: rgba(12, 12, 10, 0.92); }

/* No card, no bubble — the quote sits straight on the page. Opacity is driven by
   --jj-fade (set per card in JS) so earlier quotes linger as a trail instead of
   vanishing the moment the next one lands. */
.jj-review {
  position: absolute;
  top: 0;
  left: 0;
  width: min(30ch, calc(100vw - 40px));
  pointer-events: auto;
  opacity: 0;
  will-change: opacity;
  transition: opacity 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}
.jj-review.is-in { opacity: var(--jj-fade, 1); }

/* An edgeless wash so the line stays readable over live page content. It fades
   to nothing at every edge, so it reads as haze rather than a bubble. */
.jj-review::before {
  content: "";
  position: absolute;
  inset: -38px -44px;
  background: radial-gradient(closest-side, var(--jj-scrim) 55%, transparent 100%);
  pointer-events: none;
}
.jj-review.is-leaving {
  opacity: 0;
  transition: opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: none;
}

.jj-review-quote {
  position: relative; /* paints above the wash */
  margin: 0;
  font-style: italic;
  font-size: 17px;
  line-height: 1.42;
  letter-spacing: -0.015em;
  text-align: center;
  text-wrap: balance;
  color: var(--jj-quote, oklch(0.68 0.16 98));
}
.jj-review-quote::before { content: "\201C"; }
.jj-review-quote::after  { content: "\201D"; }

@media (hover: none) {
  /* No pointer to trail on touch — the mark is never shown. Taps still pop
     quotes, and the JS skips building the mark entirely. */
  .jj-companion { display: none; }
  .jj-review-quote { font-size: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .jj-companion,
  .jj-companion-img { transition: none; }
  .jj-review,
  .jj-review.is-leaving { transition-duration: 0.01s; }
}
