/* ==========================================================================
   TeamTrek V4 — Product tour
   --------------------------------------------------------------------------
   The rail is the product's sidebar; the stage shows the one component each
   page is about. Structure ported from index-v2.html's tour, rebuilt on v4's
   tokens because v2's sheets share 65 class names and seven token names with
   this one and would have repainted the rest of the page.

   Loaded only by index-v4.html. Every selector here is new to this project
   except .trail*, which index-v2.html also uses — but v2's sheets are never
   loaded alongside these, so there is nothing to collide with.
   ========================================================================== */

/* ---- The section -------------------------------------------------------
   Pinned for the length of its scroll track, the same pattern the workspace
   assembly and the how-it-works stepper use. Twelve steps at roughly 27vh
   each, plus the viewport the stage occupies.
   ------------------------------------------------------------------------ */
/* One scale for the whole section, declared here so every rule below
   reads as a step on it rather than as a number someone picked. Six steps
   covered what were eleven sizes (9, 10, 11, 12, 13, 14, 15, 17, 18, 20 and
   24px) across two font families.

   All of it is Manrope: the rail labels, the counter, the badge, the view
   meta and the chart axes used to be --font-mono, a system monospace stack.
   Figures keep their alignment through Manrope's own tabular-figure
   feature, applied wherever numbers sit in a column. */
.tour {
  --tt-label: .6875rem;   /* 11px - uppercase labels, meta, axes, sub-text */
  --tt-body:  .8125rem;   /* 13px - table rows, caption body */
  --tt-row:   .875rem;    /* 14px - menu rows, the app's own sidebar size */
  --tt-title: .9375rem;   /* 15px - view titles */
  --tt-lead:  1.0625rem;  /* 17px - caption title, the ring figure */
  --tt-fig:   1.25rem;    /* 20px - stat figures */

  background: var(--neutral-50); border-block: 1px solid var(--neutral-200);
}
.tour__scroll { position: relative; height: 424vh; }
.tour__pin {
  position: sticky; top: 0;
  min-height: 100vh;
  display: flex; flex-direction: column; justify-content: center;
  /* 3.25rem, not 3.5: at 900px tall the head (200px), the layout (552px)
     and two 56px paddings came to 904px and the pin spilled 4px past the
     viewport it is pinned to. */
  padding-block: 3.25rem;
}
/* stretch, not start: the rail column and the stage card are the two
   halves of one screenshot, and one ending 127px above the other was the
   most visible thing in the section. Both now end on the same line, and
   whichever side is taller sets the height. */
.tour__layout {
  margin-top: 2.5rem;
  display: grid; grid-template-columns: 19rem minmax(0, 1fr); gap: 3rem;
  align-items: stretch;
}
.tour__layout > * { min-width: 0; }

/* The rail holds the top of its column and the slack falls below it,
   which is where a sidebar's slack falls in the product too. */
.tour__aside { display: flex; flex-direction: column; }
.tour__aside .trail { flex: none; }

/* Card, then caption. The card takes the slack, so both columns end on the
   same line whatever the caption's length. */
.tour__main { display: flex; flex-direction: column; min-width: 0; }

.tour__count {
  font-size: var(--tt-label); font-weight: var(--weight-semi);
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--neutral-500); font-variant-numeric: tabular-nums;
  margin-bottom: .875rem;
}
.tour__count b { color: var(--primary-700); }

/* Reserved for the longest of the twelve captions at this width, so the
   card below it never resizes as the steps change. */
.tour__caption { margin-top: 1.125rem; min-height: 4.5rem; }
.tour__caption-title {
  font-size: var(--tt-lead); font-weight: var(--weight-bold);
  letter-spacing: -.02em; color: var(--neutral-900);
}
/* A measure, not the full 848px: 70-odd characters is a line you read
   rather than scan across. */
.tour__caption-body { max-width: 62ch; }
.tour__caption-body {
  margin-top: .375rem; font-size: var(--tt-body); line-height: 1.55;
  color: var(--neutral-600);
}

/* ---- The rail is the product's menu ------------------------------------
   Styled as the app's sidebar, not as a stepper: the same grouping, the
   same indent, the same pill on the current page. Entries the tour does not
   visit are present but inert — a menu missing half its entries stops being
   the product's menu and becomes a list of marketing steps.
   ------------------------------------------------------------------------ */
.trail {
  position: relative;
  background: #fff;
  border: 1px solid var(--neutral-200); border-radius: var(--r-md);
  padding: .5rem;
  display: flex; flex-direction: column; gap: 1px;
  /* Reserved for the rail's open state. Groups expand and collapse as the
     steps change, which took the rail between 408px and 520px and moved the
     whole row with it - the card resized every time a group opened. Holding
     the taller of the two costs some space under the last entry and keeps
     both columns on one height for all twelve steps. */
  min-height: 32.5rem;
}
/* Filled from --p, written by the scroll driver every frame. No transition:
   it is already following the finger, and easing a value that updates each
   frame only adds lag behind it. */
.trail__progress {
  position: absolute; left: 0; top: .5rem; width: 2px;
  height: calc(var(--p, 0) * (100% - 1rem));
  border-radius: var(--r-pill);
  background: linear-gradient(180deg, var(--primary-400), var(--primary-600));
}

.trail__grp {
  font-size: var(--tt-label); font-weight: var(--weight-bold);
  text-transform: uppercase; letter-spacing: .09em; color: var(--neutral-500);
  padding: .75rem .5rem .375rem;
}
.trail__grp:first-child { padding-top: .25rem; }

.trail__item {
  display: flex; align-items: center; gap: .625rem;
  width: 100%; text-align: left;
  padding: .5rem .625rem;
  border-radius: var(--r-sm);
  font-size: var(--tt-row); font-weight: var(--weight-medium); color: var(--neutral-700);
  transition: background-color var(--dur-micro) var(--ease-ui),
              color var(--dur-micro) var(--ease-ui);
}
.trail__item > span { flex: 1; min-width: 0; }
.trail__item .icon { flex: none; color: var(--neutral-500); }
.trail__item--sub { padding-left: 2.25rem; font-size: var(--tt-body); }

button.trail__item:hover { background: var(--neutral-100); color: var(--neutral-900); }
button.trail__item:hover .icon { color: var(--primary-600); }
button.trail__item:focus-visible { outline: 2px solid var(--primary-400); outline-offset: 2px; }

/* The current page, exactly as the app marks it. */
.trail__item.is-on,
button.trail__item.is-on:hover {
  background: var(--primary-600); color: #fff; font-weight: var(--weight-semi);
}
.trail__item.is-on .icon,
button.trail__item.is-on:hover .icon { color: #fff; }

/* The open group's header warms without claiming to be the current page. */
.trail__item--parent.is-soft { color: var(--neutral-900); }
.trail__item--parent.is-soft .icon { color: var(--primary-600); }

/* Pages the tour does not stop at: legible, and clearly not a control. */
.trail__item.is-inert { color: var(--neutral-500); cursor: default; }
.trail__item.is-inert .icon { color: var(--neutral-300); }
.trail__badge {
  flex: none;
  font-size: var(--tt-label); font-weight: var(--weight-bold);
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--primary-800); background: var(--primary-50);
  border-radius: var(--r-pill); padding: .0625rem .375rem;
}

.trail__chev { color: var(--neutral-400); transition: transform var(--dur-ui) var(--ease-brand); }
.trail__item--parent[aria-expanded="true"] .trail__chev { transform: rotate(180deg); }

/* Collapsing without measuring: a 0fr → 1fr grid row animates to the
   content's own height, so nothing has to be told how tall a group is. */
.trail__sub {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-ui) var(--ease-brand);
}
.trail__sub > div { overflow: hidden; display: flex; flex-direction: column; gap: 1px; }
.trail__sub.is-open { grid-template-rows: 1fr; }

/* ---- The stage --------------------------------------------------------- */
/* One surface. The stage used to be a --neutral-100 canvas with the view
   inset inside it, which put two borders and two radii between the reader
   and the content. The view now fills the card to its edges, so the section
   shows a single card. */
.tour__view {
  flex: 1 1 auto;
  display: flex; flex-direction: column;
  background: #fff;
  border: 1px solid var(--neutral-200); border-radius: var(--r-lg);
  box-shadow: var(--shadow-02);
  overflow: hidden;
}
/* The twelve screens share one grid cell, so the card is as tall as the
   tallest view and nothing jumps as the steps change. Capped against the
   viewport as well: this card is pinned, and a pinned card taller than the
   screen it is pinned to has a bottom nobody can reach. */
.tour__screens {
  position: relative; display: grid;
  flex: 1 1 auto;
  /* Flush to the card, not centred: now that the card and the view are one
     white surface, the view's head has to sit on the card's top edge to
     read as the window's title bar. Centring left a white band above it. */
  align-content: stretch;
  max-height: calc(100vh - 22rem);
  overflow: hidden;
}
.tour__screen {
  grid-area: 1 / 1;
  /* A scale, not a lift. The stage clips (it has to, to stay inside the
     viewport), and a translated screen extends past the box — which cut the
     bottom 10px off every incoming view for the length of the swap. A scale
     stays within its own bounds. */
  opacity: 0; transform: scale(.99);
  transition: opacity var(--dur-ui) var(--ease-ui), transform var(--dur-ui) var(--ease-brand);
  pointer-events: none;
}
.tour__screen.is-active { opacity: 1; transform: none; pointer-events: auto; }

/* ---- A focused view ---------------------------------------------------
   One page's component, not a whole screen: the menu is in the rail, so
   these carry no sidebar and the content can be read at a real size.
   ------------------------------------------------------------------------ */
.tourv { display: flex; flex-direction: column; }
.tourv__head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  padding: .875rem 1.125rem;
  border-bottom: 1px solid var(--neutral-200);
  background: var(--neutral-25);
}
.tourv__title { font-size: var(--tt-title); font-weight: var(--weight-bold); letter-spacing: -.015em; color: var(--neutral-900); }
.tourv__meta {
  font-size: var(--tt-label); font-weight: var(--weight-medium);
  color: var(--neutral-600); font-variant-numeric: tabular-nums;
}
.tourv__body { padding: 1.125rem; display: grid; gap: 1rem; align-content: start; }

/* Dashboard greeting */
.tourv__greet {
  display: flex; align-items: center; justify-content: space-between; gap: 1.25rem;
  border-radius: var(--r-md); padding: 1.125rem 1.25rem;
  background: var(--brand-gradient); color: #fff;
}
.tourv__greet-day {
  display: flex; align-items: center; gap: .375rem;
  font-size: var(--tt-label); font-weight: var(--weight-bold);
  text-transform: uppercase; letter-spacing: .09em; color: rgba(255, 255, 255, .8);
}
.tourv__greet-name { margin-top: .25rem; font-size: var(--tt-fig); font-weight: var(--weight-bold); letter-spacing: -.02em; }
.tourv__greet-sub { margin-top: .25rem; font-size: var(--tt-body); color: rgba(255, 255, 255, .82); }
.tourv__ring { flex: none; text-align: right; }
.tourv__ring b { display: block; font-size: var(--tt-fig); font-weight: var(--weight-bold); letter-spacing: -.025em; font-variant-numeric: tabular-nums; }
.tourv__ring span { font-size: var(--tt-label); color: rgba(255, 255, 255, .8); }

/* Daily timeline */
.tourv__bar {
  margin-top: .75rem; display: flex; height: 26px;
  border-radius: var(--r-xs); overflow: hidden; background: var(--neutral-100);
}
.tourv__bar > span { background: var(--primary-500); }
.tourv__axis {
  margin-top: .375rem; display: flex; justify-content: space-between;
  font-size: var(--tt-label); font-weight: var(--weight-medium); color: var(--neutral-500);
}

/* Monthly calendar — a five-week grid of activity, not a date picker. */
.tourv__cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.tourv__cal + .tourv__cal { margin-top: 4px; }
.tourv__cal-hd {
  font-size: var(--tt-label); font-weight: var(--weight-medium); text-transform: uppercase;
  letter-spacing: .06em; color: var(--neutral-500); text-align: center;
}
.tourv__cal-c {
  height: 30px; border-radius: var(--r-xs);
  background: var(--neutral-100);
  display: flex; align-items: flex-end; overflow: hidden;
}
.tourv__cal-c--out { background: transparent; }
.tourv__cal-c.is-on { background: var(--primary-50); }
.tourv__cal-c > i { display: block; width: 100%; background: var(--primary-500); border-radius: var(--r-xs); }

/* Screenshot gallery */
/* Six across, one row. Three across made each tile 270px wide and the view
   650px tall — and since the twelve screens are stacked in one grid cell,
   the tallest one sets the card height for all of them, so this single view
   was adding 200px of empty space to the other eleven. */
.tourv__shots { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: .5rem; }
.tourv__shot { display: block; min-width: 0; }
.tourv__shot-win {
  display: flex; flex-direction: column; justify-content: center; gap: 5px;
  aspect-ratio: 16 / 10; border-radius: var(--r-xs);
  border: 1px solid var(--neutral-200); background: var(--neutral-100);
  padding: 0 14%;
}
.tourv__shot-win > i { display: block; height: 5px; border-radius: 2px; background: var(--neutral-300); }
.tourv__shot-win > i:nth-child(2) { width: 72%; }
.tourv__shot-win > i:nth-child(3) { width: 84%; background: var(--primary-200); }
.tourv__shot-m {
  margin-top: .375rem; display: flex; justify-content: space-between;
  font-size: var(--tt-label); font-weight: var(--weight-medium); color: var(--neutral-500);
}
.tourv__shot-m b { color: var(--primary-700); }

/* Reports: hours per day */
.tourv__bars { margin-top: .875rem; display: flex; align-items: flex-end; gap: 5px; height: 110px; }
.tourv__bars > span { flex: 1; display: flex; align-items: flex-end; height: 100%; }
.tourv__bars i {
  display: block; width: 100%; height: 0;
  border-radius: 2px 2px 0 0; background: var(--primary-600);
  transition: height .62s var(--ease-brand);
}

/* Insights meters */
.tourv__meters { display: flex; flex-direction: column; gap: .75rem; }

/* People / invite identity cell */
.tourv__who { display: flex; align-items: center; gap: .5rem; min-width: 0; }
.tourv__who .mock-avatar { width: 26px; height: 26px; font-size: 9px; }
.tourv__id { min-width: 0; }
.tourv__id b { display: block; font-weight: var(--weight-semi); color: var(--neutral-900); }
.tourv__id span { display: block; font-size: var(--tt-label); color: var(--neutral-500); }

/* ---- Below 1024px -----------------------------------------------------
   The pin is released and the rail collapses to a horizontal strip of the
   twelve stops: a 19-row sidebar stacked above the stage is most of a
   scroll before the product is even visible.
   ------------------------------------------------------------------------ */
@media (max-width: 1023px) {
  .tour__scroll { height: auto; }
  .tour__pin { position: static; min-height: 0; padding-block: var(--section-y, 4rem); }
  .tour__layout { grid-template-columns: minmax(0, 1fr); gap: 1.5rem; }

  .trail {
    /* Horizontal chips here, so there is no open state to reserve for. */
    min-height: 0;
    flex-direction: row; overflow-x: auto; gap: .5rem;
    padding: .5rem; scrollbar-width: none; overscroll-behavior-x: contain;
  }
  .trail::-webkit-scrollbar { display: none; }
  .trail__grp,
  .trail__item.is-inert,
  .trail__item--parent,
  .trail__chev { display: none; }
  .trail__sub,
  .trail__sub > div { display: contents; }
  .trail__item {
    width: auto; flex: none; white-space: nowrap;
    padding: .5rem .875rem;
    border: 1px solid var(--neutral-200); border-radius: var(--r-pill);
  }
  .trail__item--sub { padding-left: .875rem; font-size: .875rem; }
  .trail__item.is-on { border-color: var(--primary-600); }

  .tour__caption { margin-top: 1rem; min-height: 0; }
  /* Six tiles in a 340px column would be 45px each. Three rows of two. */
  .tourv__shots { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* No pin, so no viewport cap to respect. */
  .tour__screens { max-height: none; }
}

@media (prefers-reduced-motion: reduce) {
  .tour__scroll { height: auto; }
  .tour__pin { position: static; min-height: 0; }
  .tour__screen { transition: none; }
  .tourv__bars i { transition: none; }
}

/* ==========================================================================
   Tour views — entry motion
   --------------------------------------------------------------------------
   Before this, two of the twelve views moved: the reports bars and the
   insights meters. Roughly 38 figures and 30 rows simply appeared.

   Everything here plays on mount. The views are inserted when their step is
   first reached, so a CSS animation on a fresh element runs once by itself —
   no observer, no JS trigger, and nothing to re-arm when the reader scrolls
   back past a step.

   --i comes from the builders and carries the element's index, so each
   stagger holds however many rows or cells a view turns out to have.
   ========================================================================== */

@keyframes tourIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
@keyframes tourRow {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
@keyframes tourCell {
  from { opacity: 0; transform: scale(.82); }
  to   { opacity: 1; transform: none; }
}
@keyframes tourWipe {
  from { transform: scaleX(0); }
  to   { transform: none; }
}

.tourv__greet { animation: tourIn .5s var(--ease-brand) both; }

.tourv .ins__stat {
  animation: tourIn .46s var(--ease-brand) both;
  animation-delay: calc(var(--i, 0) * .06s + .04s);
}

.tourv .dtable__head { animation: tourRow .36s var(--ease-ui) both; }
.tourv .dtable__row {
  animation: tourRow .42s var(--ease-brand) both;
  animation-delay: calc(var(--i, 0) * .05s + .14s);
}

.tourv .ppl__view {
  animation: tourIn .4s var(--ease-brand) both;
  animation-delay: calc(var(--i, 0) * .05s);
}
.tourv .ppl__view:nth-child(1) { --i: 0; }
.tourv .ppl__view:nth-child(2) { --i: 1; }
.tourv .ppl__view:nth-child(3) { --i: 2; }

.tourv__shot {
  animation: tourIn .44s var(--ease-brand) both;
  animation-delay: calc(var(--i, 0) * .05s + .1s);
}
.tourv__shot:nth-child(1) { --i: 0; }
.tourv__shot:nth-child(2) { --i: 1; }
.tourv__shot:nth-child(3) { --i: 2; }
.tourv__shot:nth-child(4) { --i: 3; }
.tourv__shot:nth-child(5) { --i: 4; }
.tourv__shot:nth-child(6) { --i: 5; }

/* The day's blocks wipe out from the left rather than appearing whole, so
   the bar reads as a day being recorded. */
.tourv__bar > span {
  transform-origin: left;
  animation: tourWipe .5s var(--ease-brand) both;
  animation-delay: .12s;
}

/* ---- Monthly: an activity heat map ------------------------------------
   Cells were one flat teal at a height. Banded to the product's own
   thresholds — low under 20, medium to 50, high above — a month reads at a
   glance instead of as a row of identical bars.
   ------------------------------------------------------------------------ */
.tourv__cal-c.is-on {
  animation: tourCell .34s var(--ease-brand) both;
  animation-delay: calc(var(--i, 0) * .012s + .08s);
}
.tourv__cal-c > i {
  height: 0;
  transition: height .5s var(--ease-brand);
  transition-delay: calc(var(--i, 0) * .012s + .2s);
}
.tourv__cal-c.is-on > i { height: var(--h); }
/* One hue, three steps — intensity, not judgement. The first version used
   the activity palette (red / amber / teal), which put 17 of this month's
   19 working days in amber: a perfectly ordinary month rendered as a wall
   of warnings, because colour that means "medium activity" in a badge
   means "something is wrong" in a calendar. Amber and red stay for actual
   exceptions elsewhere. */
.tourv__cal-c.is-on { background: var(--primary-50); }
.tourv__cal-c--low  > i { background: var(--primary-200); }
.tourv__cal-c--med  > i { background: var(--primary-400); }
.tourv__cal-c--high > i { background: var(--primary-600); }

/* ---- Dashboard ring ---------------------------------------------------
   The share of a weekly target, drawn as one. --p sets the dash offset, so
   the sweep is a single transition rather than a script stepping a stroke.
   ------------------------------------------------------------------------ */
.tourv__ring { position: relative; flex: none; width: 76px; height: 76px; }
.tourv__ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.tourv__ring circle { fill: none; stroke-width: 7; }
.tourv__ring-bg { stroke: rgba(255, 255, 255, .22); }
.tourv__ring-fg {
  stroke: #fff; stroke-linecap: round;
  /* 2πr for r=32 */
  stroke-dasharray: 201.06;
  stroke-dashoffset: 201.06;
  animation: tourRing .9s var(--ease-brand) .18s both;
}
@keyframes tourRing { to { stroke-dashoffset: calc(201.06 * (1 - var(--p, 0))); } }
.tourv__ring-t {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; line-height: 1.1;
}
.tourv__ring-t b { font-size: var(--tt-lead); font-weight: var(--weight-bold); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.tourv__ring-t span { font-size: .625rem; color: rgba(255, 255, 255, .8); }

/* ---- Within-step drift ------------------------------------------------
   A few pixels across each step, taken from the fraction within it, so the
   card is not frozen between two highlights. Deliberately not a
   cross-dissolve between views: these are dense cards, and holding two of
   them at half opacity turns two sets of rows into one illegible pile.

   It lands on the body rather than the screen, because .tour__screen owns
   the swap's own transform and two rules writing one property fight.
   ------------------------------------------------------------------------ */
.tour__screen.is-active .tourv__body {
  transform: translateY(calc(var(--step-frac, 0) * -5px));
}

@media (prefers-reduced-motion: reduce) {
  .tourv__greet,
  .tourv .ins__stat,
  .tourv .dtable__head,
  .tourv .dtable__row,
  .tourv .ppl__view,
  .tourv__shot,
  .tourv__bar > span,
  .tourv__cal-c.is-on,
  .tourv__ring-fg { animation: none !important; opacity: 1 !important; transform: none !important; }
  .tourv__ring-fg { stroke-dashoffset: calc(201.06 * (1 - var(--p, 0))); }
  .tourv__cal-c > i { transition: none !important; }
  .tour__screen.is-active .tourv__body { transform: none; }
  .trail__progress { display: none; }
}

@media (max-width: 1023px) {
  /* No scroll driver here — the pin is released and the chips are the
     control — so --p never advances and a progress line would sit at zero
     forever. The active chip is the position indicator instead. */
  .trail__progress { display: none; }
}
