/* ==========================================================================
   TeamTrek V4 — Micro-interactions that make the mocks feel live
   --------------------------------------------------------------------------
   Loaded only by index-v4.html. index.html (v1) and index-v3.html load the
   same css/ directory, so every selector here is either new or scoped to a
   v4-only hook (.tourv, [data-live-*]) — neither backup renders markup that
   this file can reach.

   Everything here is a hover or focus state. The resting page is unchanged,
   so a reader who never moves the pointer sees exactly what shipped before.
   Nothing reflows: only opacity, colour, shadow and transform change, and
   the readout text swaps inside a slot that already had text in it.

   Hover states are wrapped in @media (hover: hover) and (pointer: fine).
   On a touch screen `:hover` sticks after a tap, which would leave a bar
   dimmed and a tooltip stranded until the next tap elsewhere.
   ========================================================================== */

/* --------------------------------------------------------------------------
   The one tooltip
   Fixed position, so no transformed or sticky ancestor can displace it —
   the tour stage is a sticky pin and the hero dashboard is inside a
   translate3d parallax host. js/live-v4.js sets --x and --y in viewport
   coordinates and clamps them.
   -------------------------------------------------------------------------- */
.livetip {
  position: fixed; z-index: 90;
  left: 0; top: 0;
  transform: translate3d(calc(var(--x, 0px) - 50%), calc(var(--y, 0px) - 100%), 0);
  max-width: 17rem;
  border-radius: var(--r-sm);
  background: var(--neutral-900);
  padding: .5rem .625rem;
  font-size: .75rem; line-height: 1.35; color: #fff;
  box-shadow: var(--shadow-03);
  opacity: 0; visibility: hidden;
  transition: opacity .13s var(--ease-ui), visibility .13s var(--ease-ui);
  pointer-events: none;   /* never eats the hover that produced it */
}
.livetip.is-on { opacity: 1; visibility: visible; }

.livetip b { display: block; font-weight: var(--weight-semi); color: #fff; }
.livetip span { display: block; color: var(--neutral-300); font-variant-numeric: tabular-nums; }
.livetip em { font-style: normal; color: var(--primary-200); }

/* The pointer, drawn as a rotated square so it inherits the bubble colour. */
.livetip::after {
  content: ''; position: absolute; left: 50%; bottom: -3px;
  width: 8px; height: 8px;
  transform: translateX(-50%) rotate(45deg);
  background: var(--neutral-900);
}
/* Flipped when the host sits too close to the top of the viewport. */
.livetip.is-below { transform: translate3d(calc(var(--x, 0px) - 50%), var(--y, 0px), 0); }
.livetip.is-below::after { top: -3px; bottom: auto; }

@media (prefers-reduced-motion: reduce) {
  .livetip { transition: none; }
}

@media (hover: hover) and (pointer: fine) {

  /* ------------------------------------------------------------------------
     1. Hero weekly activity — crosshair readout, not a floating box
     The chart head already carries the date range, so the day being probed
     is written into that slot. Nothing overlaps the frame, nothing moves,
     and the answer appears where the reader is already looking for a label.
     ------------------------------------------------------------------------ */
  .hero-dash__chart-head [data-live-read] {
    font-variant-numeric: tabular-nums;
    transition: color var(--dur-ui) var(--ease-ui);
  }
  .hero-dash__chart.is-probing [data-live-read] { color: var(--primary-700); font-weight: var(--weight-semi); }

  .hero-dash__bars span {
    position: relative;
    cursor: default;
    transition: height var(--dur-figure) var(--ease-brand),
                opacity .16s var(--ease-ui),
                background-color .16s var(--ease-ui);
  }
  /* Peers step back rather than the probed bar stepping forward: growing the
     hovered bar would misreport its value, which is the one thing a chart
     may not do. */
  .hero-dash__bars.is-probing span { opacity: .34; }
  .hero-dash__bars.is-probing span.is-peek { opacity: 1; }
  .hero-dash__bars span.is-peek { background: var(--primary-700); }
  .hero-dash__bars span[data-tone="soft"].is-peek { background: var(--primary-500); }
  .hero-dash__bars span[data-tone="quiet"].is-peek { background: var(--neutral-400); }

  /* The guide line. Height is the container's fixed 108px, so this needs no
     measuring and cannot disagree with the bar it sits under. */
  .hero-dash__bars span.is-peek::before {
    content: ''; position: absolute; left: 50%; bottom: 0;
    width: 1px; height: 108px;
    transform: translateX(-50%);
    background: linear-gradient(to top, var(--primary-300), transparent);
    pointer-events: none;
  }
  /* A cap on the probed bar, so the eye lands on the top of the column —
     which is the part that carries the value. */
  .hero-dash__bars span.is-peek::after {
    content: ''; position: absolute; left: 0; right: 0; top: -3px;
    height: 2px; border-radius: 2px;
    background: var(--primary-700);
  }
  /* The day label under the probed bar comes forward with it. */
  .hero-dash__days span { transition: color .16s var(--ease-ui), font-weight .16s var(--ease-ui); }
  .hero-dash__days span.is-peek { color: var(--primary-700); font-weight: var(--weight-semi); }

  /* ------------------------------------------------------------------------
     2. Tour figures that answer a question on hover
     ------------------------------------------------------------------------ */
  .tourv [data-live-tip] { cursor: default; }

  /* Reports: fourteen day bars. Same rule as the hero — peers dim, the
     probed bar keeps its height and darkens. */
  .tourv__bars.is-probing > span { opacity: .38; transition: opacity .16s var(--ease-ui); }
  .tourv__bars.is-probing > span.is-peek { opacity: 1; }
  .tourv__bars > span.is-peek i { background: var(--primary-700); }

  /* Monthly heat map: the probed day lifts out of the grid by a ring rather
     than by a transform, because 35 cells at 6px gaps have no room to grow. */
  .tourv__cal-c { transition: box-shadow .16s var(--ease-ui); }
  .tourv__cal-c.is-peek {
    box-shadow: 0 0 0 2px var(--primary-600);
    position: relative; z-index: 1;
  }

  /* Screenshots: a real gallery zooms. The tile is small, so the meta line
     gets the emphasis and the tile gets the shadow. */
  .tourv__shot { transition: transform .18s var(--ease-brand); }
  .tourv__shot:hover { transform: translateY(-2px) scale(1.03); }
  .tourv__shot:hover .tourv__shot-win {
    border-color: var(--primary-300);
    box-shadow: var(--shadow-02);
  }
  .tourv__shot .tourv__shot-m { transition: color .16s var(--ease-ui); }
  .tourv__shot:hover .tourv__shot-m { color: var(--neutral-800); }

  /* ------------------------------------------------------------------------
     3. Rows read as rows you could click
     Visual only — no invented copy. A 2px inset edge rather than a border,
     so the grid columns never shift by a pixel.
     ------------------------------------------------------------------------ */
  .tourv .dtable__row,
  .pm__row:not(.pm__row--head),
  .ppl__row:not(.ppl__row--head) {
    transition: background-color .14s var(--ease-ui), box-shadow .14s var(--ease-ui);
  }
  .tourv .dtable__row:hover,
  .pm__row:not(.pm__row--head):hover,
  .ppl__row:not(.ppl__row--head):hover {
    background: var(--neutral-50);
    box-shadow: inset 2px 0 0 var(--primary-500);
  }
  /* The figure in the row is why the row exists, so it is what sharpens. */
  .tourv .dtable__row:hover .dtable__pos { color: var(--primary-800); }
  .tourv .dtable__row:hover b { color: var(--neutral-900); }

  /* ------------------------------------------------------------------------
     4. Avatars: the stack fans, the person is named
     ------------------------------------------------------------------------ */
  .mock-avatar[data-live-who] { cursor: default; transition: transform .16s var(--ease-brand), box-shadow .16s var(--ease-ui); }
  .mock-avatar[data-live-who]:hover {
    transform: translateY(-1px) scale(1.06);
    box-shadow: var(--shadow-02);
    z-index: 2;
  }
  /* Overlapped stacks sit at -8px. Opening the gap to -4px on hover shows
     the reader there are separate people under there. */
  .pm__stack:hover .mock-avatar + .mock-avatar { margin-left: -.25rem; }
  .pm__stack .mock-avatar { transition: margin-left .18s var(--ease-brand), transform .16s var(--ease-brand); }

  /* ------------------------------------------------------------------------
     5. Press state. Its absence is most of why a mock reads as a picture.
     ------------------------------------------------------------------------ */
  .tourv .ppl__view:active,
  .tourv .ins__period:active,
  .trail__item:active { transform: scale(.985); }
  .trail__item { transition: transform .09s var(--ease-ui); }
}

/* Reduced motion keeps every readout and every colour change, and drops the
   transforms — the information is the point, the movement is not. */
@media (prefers-reduced-motion: reduce) {
  .tourv__shot:hover,
  .mock-avatar[data-live-who]:hover,
  .tourv .ppl__view:active,
  .tourv .ins__period:active,
  .trail__item:active { transform: none; }
  .hero-dash__bars span,
  .tourv__shot,
  .mock-avatar[data-live-who],
  .pm__stack .mock-avatar { transition: none; }
}
