/**
 * The guided tour overlay — public/js/tour.js, docs/build/plan-tutorial.md.
 *
 * One `<dialog>` per tour, not the usual `.dialog` shape from app.css: this
 * one needs a hole in the middle, over whatever it is explaining right now,
 * and `.dialog`'s own backdrop (app.css:1992-1996) darkens evenly with no
 * way to cut a hole in it. So `.tour-dialog` fills the whole viewport itself
 * and the darkness is drawn by `.tour-spot` — a small div positioned over the
 * target with a `box-shadow` large enough to cover the rest of the screen.
 * Wrapping that in `showModal()` rather than a bare fixed div is what still
 * gets the platform's inertness (the real page behind stays genuinely
 * unclickable, so the spotlight cannot be pressed through), focus trap and
 * Escape handling for free — see dialog.js's own header comment for the
 * fuller argument against a hand-rolled overlay in this codebase.
 */
.tour-dialog {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  max-width: 100vw;
  max-height: 100vh;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  overflow: hidden;
  /* Not a theme token on purpose — a spotlight has to read as "dark" in both
     light and dark mode, the same reason `--select-bg` is the one other
     deliberate break from the custom-property rule (research-frontend.md's
     CSS table). Scoped to this component rather than added to app.css's
     shared `:root` block.

     0.78, not the 0.6 it started at. At 0.6 the page behind stayed legible
     enough to read, so the eye kept wandering back to it and the lit element
     did not read as *the* thing being talked about — which is the entire job
     of a spotlight. Dark enough that the rest is plainly out of play, not so
     dark that you lose your bearings on where you are. */
  --tour-scrim: rgba(8, 9, 12, 0.78);
  --tour-ring: rgba(255, 255, 255, 0.92);
}
.tour-dialog::backdrop {
  /* `.tour-spot` already draws the darkness, with a hole in it. A second,
     opaque backdrop under it would just be extra paint with no hole. */
  background: transparent;
}

/**
 * The lit area.
 *
 * Three things happen here and each fixes a way the old single `box-shadow`
 * failed to isolate anything:
 *
 *   - the scrim, as before, but darker;
 *   - a bright ring on the edge, so the boundary between lit and unlit is a
 *     line rather than a gradient — without it a pale control on a pale page
 *     had no visible edge at all and the "highlight" was just an absence of
 *     darkness;
 *   - a soft outer glow, which is what makes it read as lit rather than as a
 *     hole cut in a sheet.
 */
.tour-spot {
  position: fixed;
  border-radius: var(--radius);
  box-shadow:
    0 0 0 9999px var(--tour-scrim),
    0 0 0 2px var(--tour-ring),
    0 0 0 6px rgba(255, 255, 255, 0.14),
    0 0 24px 8px rgba(255, 255, 255, 0.10);
  /* Lets a click over the lit area fall through to `.tour-dialog` itself,
     which is how "clicking the dark area closes it" and "the target stays
     unclickable during the tour" both come out of one rule. */
  pointer-events: none;
  opacity: 0;
  transition:
    top 220ms cubic-bezier(0.32, 0.72, 0, 1),
    left 220ms cubic-bezier(0.32, 0.72, 0, 1),
    width 220ms cubic-bezier(0.32, 0.72, 0, 1),
    height 220ms cubic-bezier(0.32, 0.72, 0, 1),
    opacity 160ms;
}

/* A second, breathing ring just outside the first. It is the only moving thing
   on a screen that is otherwise held still, so the eye finds the target
   without being told where to look. Slow and low-contrast on purpose: this is
   a pointer, not an alarm. */
.tour-spot::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: inherit;
  border: 2px solid var(--tour-ring);
  opacity: 0;
  animation: tour-pulse 2.4s ease-out infinite;
}
@keyframes tour-pulse {
  0%   { opacity: 0.55; transform: scale(1); }
  70%  { opacity: 0;    transform: scale(1.06); }
  100% { opacity: 0;    transform: scale(1.06); }
}

.tour-panel {
  position: fixed;
  width: min(340px, calc(100vw - 24px));
  padding: 18px 18px 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  /* A heavier shadow than `--shadow-popover`: this sits over a near-black
     scrim rather than over the page, and the usual popover shadow vanishes
     against it, leaving the panel looking pasted on. */
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.28),
    0 12px 32px rgba(0, 0, 0, 0.44),
    0 2px 8px rgba(0, 0, 0, 0.22);
  opacity: 0;
  transition:
    top 220ms cubic-bezier(0.32, 0.72, 0, 1),
    left 220ms cubic-bezier(0.32, 0.72, 0, 1),
    opacity 160ms;
}
.tour-dialog.is-in .tour-spot,
.tour-dialog.is-in .tour-panel {
  opacity: 1;
}

/* The little arrow joining panel to target. Purely to say "this panel is about
   *that* thing" — with several controls close together, a floating box near
   two of them is ambiguous. Hidden when the panel had to be centred, because
   then it is pointing at nothing. */
.tour-panel::before {
  content: "";
  position: absolute;
  width: 12px;
  height: 12px;
  background: var(--bg-raised);
  border-left: 1px solid var(--border);
  border-top: 1px solid var(--border);
  transform: rotate(45deg);
}
.tour-panel[data-placement="below"]::before { top: -7px; left: 24px; }
.tour-panel[data-placement="above"]::before {
  bottom: -7px; left: 24px; transform: rotate(225deg);
}
.tour-panel[data-placement="center"]::before { display: none; }

.tour-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.tour-title {
  margin: 0;
  font-size: 15px;
  font-weight: 620;
  line-height: 1.35;
  color: var(--fg);
  letter-spacing: -0.01em;
}
.tour-count {
  flex: 0 0 auto;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--fg-subtle);
  white-space: nowrap;
}
.tour-body {
  margin: 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--fg-secondary);
}

/* One dot per step, so the length of the thing is visible from the first
   panel. A tour of unknown length is one people close. */
.tour-dots {
  display: flex;
  gap: 5px;
  align-items: center;
}
.tour-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--border-strong);
  transition: background 160ms, width 160ms;
}
.tour-dot.is-done { background: var(--fg-subtle); }
.tour-dot.is-current {
  width: 14px;
  border-radius: 3px;
  background: var(--accent);
}

.tour-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 2px;
}
/* Dots on the left, buttons on the right, on one line. Two rows for six small
   things made the panel taller than most of what it points at. */
.tour-actions .tour-dots { margin-right: auto; }

.tour-help-btn { font-size: 15px; font-weight: 600; }

/* The launcher's own copy of the button. `buildHeader()` — and so
   `.app-actions`, where the studio's copy lives — never runs for that view
   (see research-frontend.md), so this is the "equivalent place" the plan
   asks for: a small row above the title, right-aligned, added in
   `renderLauncher()`. */
.launcher-topbar {
  display: flex;
  justify-content: flex-end;
  margin-bottom: -8px;
}

@media (max-width: 560px) {
  /* On a narrow screen the panel is nearly the width of the viewport, so the
     arrow rarely lines up with anything and the extra width is worth more. */
  .tour-panel { width: calc(100vw - 16px); }
  .tour-panel::before { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  /* app.css's blanket rule (app.css:177-184) already flattens the transitions.
     The pulse is an animation rather than a transition, so it is not covered
     by that and has to be stopped here — a ring throbbing forever is exactly
     what someone who asked for less motion is asking to be spared. */
  .tour-spot, .tour-panel { transition-duration: 0.01ms; }
  .tour-spot::after { animation: none; opacity: 0.55; }
}
